-
Notifications
You must be signed in to change notification settings - Fork 425
/
Copy pathh5.html
1728 lines (1474 loc) · 73 KB
/
h5.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>1.2. 多维度架构之网站HTML</title><link rel="stylesheet" type="text/css" href="docbook.css" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="home" href="index.html" title="Netkiller Architect 手札" /><link rel="up" href="多维度架构设计.html" title="第 1 章 多维度架构设计" /><link rel="prev" href="多维度架构设计.html" title="第 1 章 多维度架构设计" /><link rel="next" href="多维度架构之网络延迟.html" title="1.3. 多维度架构之网络延迟" /></head><body><a xmlns="" href="//www.netkiller.cn/">Home</a> | <a xmlns="" href="//netkiller.github.io/">简体中文</a> | <a xmlns="" href="http://netkiller.sourceforge.net/">繁体中文</a> | <a xmlns="" href="/journal/index.html">杂文</a>
| <a xmlns="" href="https://github.com/netkiller">Github</a> | <a xmlns="" href="https://zhuanlan.zhihu.com/netkiller">知乎专栏</a> | <a xmlns="" href="https://www.facebook.com/bg7nyt">Facebook</a> | <a xmlns="" href="http://cn.linkedin.com/in/netkiller/">Linkedin</a> | <a xmlns="" href="https://www.youtube.com/user/bg7nyt/videos">Youtube</a> | <a xmlns="" href="//www.netkiller.cn/home/donations.html">打赏(Donations)</a> | <a xmlns="" href="//www.netkiller.cn/home/about.html">About</a><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">1.2. 多维度架构之网站HTML</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="多维度架构设计.html">上一页</a> </td><th width="60%" align="center">第 1 章 多维度架构设计</th><td width="20%" align="right"> <a accesskey="n" href="多维度架构之网络延迟.html">下一页</a></td></tr></table><hr /></div><table xmlns=""><tr><td><iframe src="//ghbtns.com/github-btn.html?user=netkiller&repo=netkiller.github.io&type=watch&count=true&size=large" height="30" width="170" frameborder="0" scrolling="0" style="width:170px; height: 30px;" allowTransparency="true"></iframe></td><td><iframe src="//ghbtns.com/github-btn.html?user=netkiller&repo=netkiller.github.io&type=fork&count=true&size=large" height="30" width="170" frameborder="0" scrolling="0" style="width:170px; height: 30px;" allowTransparency="true"></iframe></td><td><iframe src="//ghbtns.com/github-btn.html?user=netkiller&type=follow&count=true&size=large" height="30" width="240" frameborder="0" scrolling="0" style="width:240px; height: 30px;" allowTransparency="true"></iframe></td><td></td><td><a href="https://zhuanlan.zhihu.com/netkiller"><img src="/images/logo/zhihu-card-default.svg" height="25" /></a></td><td valign="middle"><a href="https://zhuanlan.zhihu.com/netkiller">知乎专栏</a></td><td></td><td></td><td></td><td></td></tr></table><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="h5"></a>1.2. 多维度架构之网站HTML</h2></div><div><h3 class="subtitle"></h3></div></div></div>
<pre class="screen">
.---> media [mp3, wma, wmv, rmvb, asf, divx]-\
/ +------------+
.-----> photo [gif, jpg, png, swf] ----> | Raid Array | <--.
/------------------- <---------\/ +------------+ \
user -> dns -> load balancing -> squid -> [cache] <----[html]----\ / |
\ \ \______<______/\ +-------------+ / |
\ \ \-----> web app ----> | html |--------^ |
\ \____________________________/\ | php,jsp,cgi | |
\ \ +-------------+ |
\ `-----> memcached [node1, node2, node(n)] |
\__________________________________________/\ |
`------> Database cluster |
+--------------------------------------+ \ |
| Author: neo chen <openunix#163.com> | `-------------+
| Nickname: netkiller |
| Homepage: http://netkiller.github.io |
+--------------------------------------+
</pre>
<div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="id777"></a>1.2.1. 网站的历史演变</h3></div></div></div>
<div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="id771"></a>1.2.1.1. 常用软硬件组成</h4></div></div></div>
<p>一个网站由下面几部分组成:</p>
<div class="orderedlist"><p class="title"><strong>网站组成</strong></p><ol class="orderedlist" type="1"><li class="listitem">
<p>硬件 hardware</p>
</li><li class="listitem">
<p>操作系统 operation system</p>
</li><li class="listitem">
<p>应用软件 application software</p>
</li><li class="listitem">
<p>网站程序以及开发语言 web program and script</p>
</li></ol></div>
<div class="orderedlist"><p class="title"><strong>硬件包括</strong></p><ol class="orderedlist" type="1"><li class="listitem">
<p>网络硬件(路由器 route, 交换机 switch)</p>
</li><li class="listitem">
<p>服务器 server</p>
</li><li class="listitem">
<p>KVM over IP</p>
</li><li class="listitem">
<p>其他包括,机柜等</p>
</li></ol></div>
<div class="orderedlist"><p class="title"><strong>操作系统包括</strong></p><ol class="orderedlist" type="1"><li class="listitem">
<p>Windows Server</p>
</li><li class="listitem">
<p>Linux</p>
</li><li class="listitem">
<p>FreeBSD</p>
</li><li class="listitem">
<p>Other(Sun,Novell,Sco...)</p>
</li></ol></div>
<p>其中应用软件按平台分类</p>
<div class="orderedlist"><p class="title"><strong>Windows 应用软件包括</strong></p><ol class="orderedlist" type="1"><li class="listitem">
<p>dns (dns)</p>
</li><li class="listitem">
<p>web (IIS)</p>
</li><li class="listitem">
<p>ftp (IIS)</p>
</li><li class="listitem">
<p>mail (Exchange)</p>
</li><li class="listitem">
<p>database (SQL Server)</p>
</li><li class="listitem">
<p>ldap (Active Directory)</p>
</li></ol></div>
<div class="orderedlist"><p class="title"><strong>Unix like 应用软件包括</strong></p><ol class="orderedlist" type="1"><li class="listitem">
<p>dns (bind)</p>
</li><li class="listitem">
<p>web (apache, lighttpd, tomcat)</p>
</li><li class="listitem">
<p>ftp (proftpd, pureftpd, wu-ftp, vsftpd)</p>
</li><li class="listitem">
<p>mail (sendmail,postfix, qmail)</p>
</li><li class="listitem">
<p>database (PostgreSQL, MySQL)</p>
</li><li class="listitem">
<p>ldap (OpenLDAP)</p>
</li></ol></div>
<div class="orderedlist"><p class="title"><strong>其他应用软件包括</strong></p><ol class="orderedlist" type="1"><li class="listitem">
<p>cache (squid, nginx, memcached...)</p>
</li><li class="listitem">
<p>web (jboss, weblogic...)</p>
</li><li class="listitem">
<p>database (Oracle, DB2...)</p>
</li></ol></div>
<div class="orderedlist"><p class="title"><strong>网站程序以及开发语言</strong></p><ol class="orderedlist" type="1"><li class="listitem">
<p>php</p>
</li><li class="listitem">
<p>java (jsp)</p>
</li><li class="listitem">
<p>.net (aspx)</p>
</li><li class="listitem">
<p>fastcgi (python,perl,rubby,c/c++ ...)</p>
</li></ol></div>
<p>怎样定义多大的网站叫大型网站呢?我也不知道,但凡大型网站都具备本文所提的几点。</p>
<div class="orderedlist"><p class="title"><strong>门户网站的需求</strong></p><ol class="orderedlist" type="1"><li class="listitem">
<p>海量用户访问</p>
</li><li class="listitem">
<p>海量用户存储</p>
</li><li class="listitem">
<p>国内外互通及南北互通</p>
</li><li class="listitem">
<p>快速响应</p>
</li><li class="listitem">
<p>7×24不间断运行</p>
</li><li class="listitem">
<p>易于维护</p>
</li></ol></div>
<div class="orderedlist"><p class="title"><strong>门户网站的几个技术要点</strong></p><ol class="orderedlist" type="1"><li class="listitem">
<p>智能域名服务器 Smart DNS</p>
</li><li class="listitem">
<p>集群负载均衡 Cluster</p>
</li><li class="listitem">
<p>缓存技术 Cache</p>
</li><li class="listitem">
<p>静态化</p>
</li><li class="listitem">
<p>图片服务器分离</p>
</li><li class="listitem">
<p>压缩数据传输</p>
</li><li class="listitem">
<p>时间同步</p>
</li><li class="listitem">
<p>数据存储</p>
</li></ol></div>
</div>
<div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="id772"></a>1.2.1.2. 第一代纯静态网站</h4></div></div></div>
<p>ftp/rsync 同步</p>
</div>
<div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="id773"></a>1.2.1.3. 第二代纯文本文件采用分隔符做数据存储网站</h4></div></div></div>
<p>这是出现了cgi/isapi/nsapi技术,perl 成为主流</p>
</div>
<div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="id774"></a>1.2.1.4. 第三代数据库存储网站</h4></div></div></div>
<p>出现动态脚本语言如php,asp,coldfusion,这个时期 php成为主流</p>
<p>出现所见即所得网页工具</p>
<p>256色gif 动画</p>
</div>
<div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="id775"></a>1.2.1.5. 第四代DNS负载均衡加反向代理</h4></div></div></div>
<p>开发语言则百花齐放php,asp.net,java,三大主流三足鼎立。perl慢慢没落。</p>
<p>flash 动画</p>
</div>
<div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="id776"></a>1.2.1.6. 第五代负载均衡集群</h4></div></div></div>
<p>ajax, css+div, xhtml</p>
</div>
</div>
<div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="cluster"></a>1.2.2. 集群(Cluster)</h3></div></div></div>
<div class="orderedlist"><p class="title"><strong>集群有很多实现方法,分为硬件和软件,集群可以在不同网络层面上实现</strong></p><ol class="orderedlist" type="1"><li class="listitem">
<p>实现IP轮循(Bind DNS)</p>
</li><li class="listitem">
<p>硬件四层交换(硬件负载均衡设备 F5 BIG IP)</p>
</li><li class="listitem">
<p>软件四层交换(linux virtual server)</p>
</li><li class="listitem">
<p>应用层上实现(tomcat)</p>
</li></ol></div>
<p>越是低层性能越好,越是上层功能更强</p>
<div class="orderedlist"><p class="title"><strong>集群的分类</strong></p><ol class="orderedlist" type="1"><li class="listitem">
<p>高可用性集群</p>
</li><li class="listitem">
<p>负载均衡集群</p>
</li><li class="listitem">
<p>超级计算集群</p>
</li></ol></div>
<p>网站一般用到两种集群分别是高可用性集群和负载均衡集群</p>
<div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="id781"></a>1.2.2.1. 负载均衡</h4></div></div></div>
<div class="section"><div class="titlepage"><div><div><h5 class="title"><a id="id778"></a>DNS负载均衡</h5></div></div></div>
<p>这是早期出现的负载均衡技术,直到现在,很多网站仍然使用DNS负载均衡。</p>
<p>你可通过ping命令观看它是如何工作的,例如你可反复ping个网域名。</p>
<pre class="screen">
C:\>ping www.163.com
Pinging www.cache.split.netease.com [220.181.28.52] with 32 bytes of data:
Reply from 220.181.28.52: bytes=32 time=226ms TTL=53
Reply from 220.181.28.52: bytes=32 time=225ms TTL=53
Reply from 220.181.28.52: bytes=32 time=226ms TTL=53
Reply from 220.181.28.52: bytes=32 time=226ms TTL=53
Ping statistics for 220.181.28.52:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 225ms, Maximum = 226ms, Average = 225ms
C:\>ping www.163.com
Pinging www.cache.split.netease.com [220.181.28.53] with 32 bytes of data:
Reply from 220.181.28.53: bytes=32 time=52ms TTL=52
Reply from 220.181.28.53: bytes=32 time=53ms TTL=52
Reply from 220.181.28.53: bytes=32 time=52ms TTL=52
Reply from 220.181.28.53: bytes=32 time=52ms TTL=52
Ping statistics for 220.181.28.53:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 52ms, Maximum = 53ms, Average = 52ms
C:\>ping www.163.com
Pinging www.cache.split.netease.com [220.181.28.50] with 32 bytes of data:
Reply from 220.181.28.50: bytes=32 time=51ms TTL=53
Reply from 220.181.28.50: bytes=32 time=52ms TTL=53
Reply from 220.181.28.50: bytes=32 time=52ms TTL=53
Reply from 220.181.28.50: bytes=32 time=51ms TTL=53
Ping statistics for 220.181.28.50:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 51ms, Maximum = 52ms, Average = 51ms
C:\>
</pre>
<div class="orderedlist"><p class="title"><strong>DNS负载均衡主要优点</strong></p><ol class="orderedlist" type="1"><li class="listitem">
<p>技术简单,容易实现,灵活,方便,成本低</p>
</li><li class="listitem">
<p>Web服务器可以位于互联网的任意位置上,无地理限制。</p>
</li><li class="listitem">
<p>DNS的主从结构非常稳定</p>
</li><li class="listitem">
<p>可以有效的分散DDOS攻击。</p>
</li><li class="listitem">
<p>你甚至可以在DNS服务商那里实现,自己不需要添加设备。而且没有带宽开销。</p>
</li></ol></div>
<div class="orderedlist"><p class="title"><strong>DNS负载均衡主要缺点</strong></p><ol class="orderedlist" type="1"><li class="listitem">
<p>DNS负载均衡采用的是简单的轮循负载算法,不能够按照服务器节点的处理能力分配负载。</p>
</li><li class="listitem">
<p>不支持故障转移(failover)和自动恢复failback ,如果某台服务器拓机,DNS仍会将用户解析到这台故障服务器上,导致不能响应客户端。</p>
</li><li class="listitem">
<p>如果添加节点或撤出节点,不能即时更新到省市级DNS,可导致部分地区不能访问。</p>
</li><li class="listitem">
<p>占用大量静态IP。</p>
</li></ol></div>
</div>
<div class="section"><div class="titlepage"><div><div><h5 class="title"><a id="id779"></a>软件四层交换负载均衡</h5></div></div></div>
<div class="orderedlist"><p class="title"><strong>软件四层交换负载均衡为我们解决了几个问题</strong></p><ol class="orderedlist" type="1"><li class="listitem">
<p>能够按照服务器节点的处理能力分配负载。</p>
</li><li class="listitem">
<p>支持故障转移(failover)和自动恢复failback ,如果某节点拓机,调度器自动将它剔除,不响应客户端访问,当节点故障排除调度器立即恢复节点。</p>
</li><li class="listitem">
<p>可以随时添加节点或撤出节点,即时生效,方便网站扩容。</p>
</li></ol></div>
<div class="orderedlist"><p class="title"><strong>软件四层交换负载均衡优点</strong></p><ol class="orderedlist" type="1"><li class="listitem">
<p>仅仅需要一个静态IP。</p>
</li><li class="listitem">
<p>节点位于私有网络上与WAN隔离,用户面对的只是调度器。</p>
</li><li class="listitem">
<p>可以随时添加节点或撤出节点。</p>
</li><li class="listitem">
<p>通过端口可以组建多个集群。</p>
</li></ol></div>
</div>
<div class="section"><div class="titlepage"><div><div><h5 class="title"><a id="id780"></a>应用层负载均衡</h5></div></div></div>
<p>Tomcat balancer</p>
<p>mod_proxy_balancer.so ,tomcat mod_jk.so</p>
<p>MySQL proxy / MySQL-LB</p>
</div>
</div>
<div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="id782"></a>1.2.2.2. 高可用性集群</h4></div></div></div>
<p>俗称:双机热备份</p>
<p>关键词:心跳线</p>
<p>两部服务器,或多部服务器,形成一个集群,当主服务器崩溃是,立即切换到其它节点上。</p>
<p>两部服务器要做到,内容实时同步,保持数据一直。</p>
<p>一般用 heartbeat + DRBD 实现。heartbeat负责切换服务器,DRBD用于同步数据。</p>
</div>
<div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="id783"></a>1.2.2.3. 负载均衡设备</h4></div></div></div>
<div class="orderedlist"><p class="title"><strong>负载均衡成熟产品</strong></p><ol class="orderedlist" type="1"><li class="listitem">
<p>F5 Big IP</p>
</li><li class="listitem">
<p>Array</p>
</li></ol></div>
<p>这些设备可提供3,4,7层负载均衡HA,硬件已经压缩,HTTP头改写,URL改写...</p>
<p>其中3层交换部分多采用硬件实现。</p>
<p>
<a class="ulink" href="/intranet/index.html" target="_top">更多关于F5 与 Array 资料点击进入</a>
</p>
</div>
<div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="id784"></a>1.2.2.4. 会话保持</h4></div></div></div>
</div>
<div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="id785"></a>1.2.2.5. 健康状态检查</h4></div></div></div>
</div>
</div>
<div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="cache"></a>1.2.3. 缓存技术</h3></div></div></div>
<p>首先要说明,很多缓存技术依赖静态化。下面展示了缓存可能出现的位置。</p>
<p>用户user -> 浏览器缓存 IE/Firefox Cache -> 逆向代理缓存 Reverse proxy Cache -> WEB服务器缓存 Apache cache -> 应用程序缓存 php cache -> 数据库缓存 database cache</p>
<p>当然交换机,网络适配器,硬盘上也有Cache 但这不是我们要讨论的范围。</p>
<p>缓存存储方式主要是内存和文件两种,后者是存于硬盘中。</p>
<div class="orderedlist"><p class="title"><strong>网站上使用的缓存主要包括五种:</strong></p><ol class="orderedlist" type="1"><li class="listitem">
<p>浏览器 缓存</p>
</li><li class="listitem">
<p>逆向代理/CDN缓存</p>
</li><li class="listitem">
<p>WEB服务器缓存</p>
</li><li class="listitem">
<p>应用程序缓存</p>
</li><li class="listitem">
<p>数据库缓存</p>
</li></ol></div>
<p>将上面的缓存合理地,有选择性的使用可大大提高网站的访问能力。</p>
<p>总之,想让你的网站更快,更多并发,答案是cache,cache 再 cache</p>
<div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="id792"></a>1.2.3.1. 浏览器缓存</h4></div></div></div>
<div class="section"><div class="titlepage"><div><div><h5 class="title"><a id="id788"></a>Cache-Control</h5></div></div></div>
<p>通过 Cache-Control 设置页面缓存时间</p>
<pre class="screen">
max-age
max-age 格式写为:max-age=n,n是以秒为单位, 这个值是告知客户端GMT + N 后页面过期,缓存服务器在s-maxage值为空的时候也会使用这个参数的值。
s-maxage
s-maxage的格式跟max-age一样,只不过他是给缓存服务器使用的。
must-revalidate
这个参数用来告知客户端和缓存服务器,在GET请求的时候必须与源服务器验证实体是否为最新版本。
Cache-Control:max-age=1200,s-maxage=3600
</pre>
<pre class="screen">
Last-Modified
这个参数提供了实体最近一次被修改的时间。这个名字起得不错,当实体被修改了之后,这个参数也就会被修改.
</pre>
<p>ETag</p>
<pre class="screen">
ETag
ETag是根据内容生成的一段hash字符串,采用信息摘要算法,保证每一个页面有一个唯一字串。
</pre>
<p>expires</p>
<p>expires 是HTTP 1.0 中定义的,已经不能满足用户的需要在 HTTP 1.1 加入了max-age,建议使用 max-age替代expires</p>
<pre class="screen">
指令 含义
public 可以在任何地方缓存
private 只能被浏览器缓存
no-cache 不能在任何地方缓存
must-revalidate 缓存必须检查更新版本
proxy-revalidate 代理缓存必须检查更新版本
max-age 内容能够被缓存的时期,以秒表示
s-maxage 覆盖共享缓存的max-age设置
</pre>
<p>在Squid, Varnish, Apache, Lighttpd, Nginx 中都可是实现HTTP Cache-Control推送,每次修改都需要重新加载,不太灵活。</p>
<pre class="screen">
ExpiresActive On
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType text/css "access plus 1 month"
ExpiresByType text/javascript "access plus 1 month"
ExpiresByType application/x-javascript "access plus 1 month"
ExpiresByType application/x-shockwave-flash "access plus 1 month"
server.modules = (
...
"mod_expire",
...
)
$HTTP["url"] =~ "^/images/" {
expire.url = ( "" => "access 30 days" )
}
</pre>
<p>我喜欢自己控制TTL时间,且每个页面单独设置,可以随时调整设置。</p>
<div class="section"><div class="titlepage"><div><div><h6 class="title"><a id="id786"></a>在程序中灵活操作 Cache-Control</h6></div></div></div>
<p>在MVC框架中每个控制器下的方法都可以单独操作Cache</p>
<pre class="screen">
Class blog extend Controller{
blog(){
header('Cache-Control: max-age=28800');
}
list(){
header('Cache-Control: max-age=3600');
}
details(){
header('Cache-Control: max-age=160');
}
}
</pre>
<p>你还可以封装到Controller中</p>
<pre class="screen">
Class blog extend Controller{
blog(){
this->cache('28800');
}
list(){
this->cache('3600');
}
details(){
this->cache('160');
}
}
</pre>
</div>
<div class="section"><div class="titlepage"><div><div><h6 class="title"><a id="id787"></a>非程序文件缓存处理</h6></div></div></div>
<p>首先做一个Rewrite让程序接管所有图片请求</p>
<pre class="screen">
url.rewrite = ( "^/(.+)" => "/index.php/$1" )
</pre>
<p>然后程序通过PATHINFO取出图片URL</p>
<pre class="screen">
http://images.example.com/your/dir/test.jpg => http://images.example.com/index.php/your/dir/test.jpg
</pre>
<p>程序取出 /your/dir/test.jpg 设置 Content-type 并输出二进制流</p>
<p>详细参考</p>
<pre class="screen">
<?php
// Test image.
$images = '/test/foo.png';
$headers = apache_request_headers();
if (isset($headers['If-Modified-Since']) && (strtotime($headers['If-Modified-Since']) == filemtime($images))) {
header('Last-Modified: '.gmdate('D, d M Y H:i:s', filemtime($images)).' GMT', true, 304);
} else {
header('Content-Type: image/png');
print file_get_contents($fn);
if (file_exists($images)) {
header('Last-Modified: '.gmdate('D, d M Y H:i:s', filemtime($images)).' GMT', true, 200);
header("Cache-Control: max-age=3600, must-revalidate");
header('Content-Length: '.filesize($images));
header('Content-type: ' .mime_content_type($images));
flush();
readfile($images);
exit;
}
}
</pre>
<p>javascript 文件也可以使用类似方法处理</p>
<pre class="screen">
private function js($file){
if (file_exists($file)) {
header("Cache-Control: max-age=3600, must-revalidate");
header('Content-type: text/javascript');
flush();
readfile($file);
exit;
}
}
</pre>
</div>
</div>
<div class="section"><div class="titlepage"><div><div><h5 class="title"><a id="id789"></a>Expires</h5></div></div></div>
<p>只要向浏览器输出过期时间HTTP协议头,不论是html还是动态脚本,都能被缓存。</p>
<p>HTML META</p>
<pre class="screen">
<meta http-equive="Expires" content=" Mon, 10 Jan 2000 00:00:00 GMT"/>
<meta http-equive="Cache-Control" content="max-age=300"/>
<meta http-equive="Cache-Control" content="no-cache"/>
</pre>
<p>动态脚本</p>
<pre class="screen">
Expires: Mon, 10 Jan 2000 00:00:00 GMT
Cache-Control: max-age=300
Cache-Control: no-cache
header("Expires: " .gmdate ("D, d M Y H:i:s", time() + 3600 * 24 * 7). " GMT");
header("Cache-Control: max-age=300");
header("Cache-Control: no-cache");
</pre>
<p>很多web server都提供 Expires 模块</p>
<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Tip"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[提示]" src="/graphics/tip.png" /></td><th align="left">提示</th></tr><tr><td align="left" valign="top">
<p>有些浏览器可能不支持。</p>
</td></tr></table></div>
</div>
<div class="section"><div class="titlepage"><div><div><h5 class="title"><a id="id790"></a>If-Modified-Since / Last-Modified</h5></div></div></div>
<p>If-Modified-Since 小于 Last-Modified 返回 200</p>
<pre class="screen">
neo@neo-OptiPlex-780:/tmp$ curl -I http://www.163.com/
HTTP/1.1 200 OK
Server: nginx
Content-Type: text/html; charset=GBK
Transfer-Encoding: chunked
Vary: Accept-Encoding
Expires: Mon, 16 May 2011 08:12:05 GMT
Cache-Control: max-age=80
Vary: User-Agent
Vary: Accept
Age: 38
X-Via: 1.1 ls100:8106 (Cdn Cache Server V2.0), 1.1 lydx156:8106 (Cdn Cache Server V2.0)
Connection: keep-alive
Date: Mon, 16 May 2011 08:11:23 GMT
</pre>
<p>If-Modified-Since 大于 Last-Modified 返回 304</p>
<pre class="screen">
neo@neo-OptiPlex-780:/tmp$ curl -H "If-Modified-Since: Fri, 12 May 2012 18:53:33 GMT" -I http://www.163.com/
HTTP/1.0 304 Not Modified
Content-Type: text/html; charset=GBK
Cache-Control: max-age=80
Age: 41
X-Via: 1.0 ls119:80 (Cdn Cache Server V2.0), 1.0 lydx154:8106 (Cdn Cache Server V2.0)
Connection: keep-alive
Date: Mon, 16 May 2011 08:11:14 GMT
Expires: Mon, 16 May 2011 08:11:14 GMT
</pre>
</div>
<div class="section"><div class="titlepage"><div><div><h5 class="title"><a id="id791"></a>ETag / If-None-Match</h5></div></div></div>
<pre class="screen">
neo@neo-OptiPlex-780:/tmp$ curl -I http://images.example.com/test/test.html
HTTP/1.1 200 OK
Cache-Control: s-maxage=7200, max-age=900
Expires: Mon, 16 May 2011 09:48:45 GMT
Content-Type: text/html
Accept-Ranges: bytes
ETag: "1984705864"
Last-Modified: Mon, 16 May 2011 09:01:07 GMT
Content-Length: 22
Date: Mon, 16 May 2011 09:33:45 GMT
Server: lighttpd/1.4.26
</pre>
<pre class="screen">
neo@neo-OptiPlex-780:/tmp$ curl -H 'If-None-Match: "1984705864"' -I http://images.example.com/test/test.html
HTTP/1.1 304 Not Modified
Cache-Control: s-maxage=7200, max-age=900
Expires: Mon, 16 May 2011 09:48:32 GMT
Content-Type: text/html
Accept-Ranges: bytes
ETag: "1984705864"
Last-Modified: Mon, 16 May 2011 09:01:07 GMT
Date: Mon, 16 May 2011 09:33:32 GMT
Server: lighttpd/1.4.26
</pre>
</div>
</div>
<div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="id796"></a>1.2.3.2. CDN (Content Delivery Network) 与反向代理缓存</h4></div></div></div>
<p>
</p><div><img src="../images/workflow/user-browser-server.png" /></div><p>
</p>
<div class="orderedlist"><p class="title"><strong>具有代表性的逆向代理服务器:</strong></p><ol class="orderedlist" type="1"><li class="listitem">
<p>Squid</p>
</li><li class="listitem">
<p>Nginx</p>
</li><li class="listitem">
<p>Varnish</p>
</li><li class="listitem">
<p>Apache cache module</p>
</li></ol></div>
<div class="orderedlist"><p class="title"><strong>其它逆向代理服务器</strong></p><ol class="orderedlist" type="1"><li class="listitem">
<p>一些提供cache的硬件设备</p>
</li><li class="listitem">
<p>最近几年出现了的 China Cache 服务商,也称CDN</p>
</li></ol></div>
<p>很多CDN厂商使用Squid 二次开发做为CDN节点,通过全球负载均衡使用分发</p>
<div class="orderedlist"><p class="title"><strong>这些CDN厂商主要做了一下二次开发</strong></p><ol class="orderedlist" type="1"><li class="listitem">
<p>logs 日志集中</p>
</li><li class="listitem">
<p>流量限制</p>
</li><li class="listitem">
<p>push,pull操作</p>
</li><li class="listitem">
<p>url 刷新</p>
</li></ol></div>
<p>s-maxage 与 max-age用法类似,s-maxage针对代理服务器缓存。同样适用于CDN</p>
<p>s-maxage 与 max-age 组合使用可以提高CDN性能</p>
<div class="section"><div class="titlepage"><div><div><h5 class="title"><a id="id793"></a>CDN接口API</h5></div></div></div>
<p>与CDN有关的开发工作</p>
<p>CDN 内容更新,一般厂商会提供一个SOAP接口,你可以通过接口刷新你的内容。但接口有限制,不能随意使用,一般是多少秒可以刷新一次,或者一天可以刷新几次</p>
</div>
<div class="section"><div class="titlepage"><div><div><h5 class="title"><a id="id794"></a>方向代理页面过期处理</h5></div></div></div>
<p>方向代理一般都支持PURGE协议,Squid,Varnish等等向管理端口发送 PURGE 即可是使用页面刷新</p>
<pre class="screen">
PURGE http://netkiller.github.net/index.html
</pre>
<p>有些方向代理如:Varnish 可以使用正则表达式</p>
<p>同时这些代理服务器都承受管理命令</p>
<p>squid: squidclient </p>
<p>varnish: varnishadm</p>
</div>
<div class="section"><div class="titlepage"><div><div><h5 class="title"><a id="id795"></a>内容版本化</h5></div></div></div>
<p>例如这样的URL</p>
<pre class="screen">
http://images.example.com/logo.gif
http://images.example.com/product.jpg
</pre>
<p>我们可以通过Rewrite或PATHINFO等技术做为静态化。例如首次版本</p>
<pre class="screen">
http://images.example.com/logo.1.gif => logo.gif
http://images.example.com/product.1.jpg => product.jpg
</pre>
<p>原图发生变化后,版本递增</p>
<pre class="screen">
http://images.example.com/logo.2.gif => logo.gif
http://images.example.com/product.2.jpg => product.jpg
</pre>
<p>就的URL将丢弃</p>
<pre class="screen">
http://images.example.com/logo.1.gif
http://images.example.com/product.1.jpg
</pre>
<p>CDN 就回源去下面的URL,并且取到的是新图</p>
<pre class="screen">
http://images.example.com/logo.2.gif
http://images.example.com/product.2.jpg
</pre>
</div>
</div>
<div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="id797"></a>1.2.3.3. 负载均衡设备</h4></div></div></div>
<p>F5 Big-IP, Array 等设备都提供硬件加速,其原理与squid, apache提供的功能大同小异</p>
<p>其中Array 页面压缩采用硬件压缩卡实现,SSL加速也采用硬件实现</p>
</div>
<div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="id798"></a>1.2.3.4. WEB服务器缓存</h4></div></div></div>
<p>例如,通过配置apache实现自身 cache</p>
</div>
<div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="id799"></a>1.2.3.5. 应用程序缓存</h4></div></div></div>
<p>在这个领域百花齐放,相信你一定能找到适合你的。这些cache会为你提供一些api,来访问它。</p>
<p>代表性的 memcached 据我所是sina广泛使用,腾讯也曾经使用过后来开发了TC(Tencent Cache),台湾雅虎则使用APC Cache。</p>
<p>另外模板引擎也有自己的缓存系统</p>
</div>
<div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="id800"></a>1.2.3.6. 数据库缓存</h4></div></div></div>
<p>数据库本身就有这个配置选项,如果需要你仍然可以在数据库前面加一道Cache。</p>
<p>例如PostgreSQL, MySQL 都提供参数可以将memcached编译到它内部</p>
</div>
</div>
<div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="h5.static"></a>1.2.4. 网站静态内容出版</h3></div></div></div>
<div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="id801"></a>1.2.4.1. 架构总览</h4></div></div></div>
<p>www 负责静态文件浏览, 台数不定, 可以采用零成本的DNS轮询, 或者4层LVS, 或者7层HAProxy, 还可以用F5, Array 等负载均衡设备.</p>
<p>cms 负责静态文件生成. 生成后的文件要同步到www中, 或者采用网络共享, 再者使用分布式文件系统, 总之将生成的文件交给www服务器, 根据你压力横向扩展即可</p>
<p>img 负责图片文件浏览. 通过给图片加版本号, 结局图片更新问题, 这样更新网站不用频繁刷新 CDN</p>
<p>
这里不谈论负载均衡, 以及存储方案, 有情绪可以延伸阅读:
<a class="ulink" href="http://netkiller.github.com/architect/index.html" target="_top">http://netkiller.github.com/architect/index.html</a>
</p>
<p>你掌握了这个方案, 你可以很容易实现 向"京东商城", "VANCL凡客诚品", "走秀网" 这样的网站</p>
<p>这些网站的特点是: 浏览量大, 数据存储主要是图片, 登录/注册与购物车,用户中心 访问量只占到 5% 使用负责均衡很容易解决.</p>
<p>静态化网站可不避免的使用ajax做局部更新, ajax请求也要考虑缓存问题</p>
<p>静态化另一个目的是改善SEO</p>
<p>首次访问服务器</p>
<div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem">
<p>访问www服务器</p>
</li><li class="listitem">
<p>nginx 判断文件是否存在,如果存在将文件显示出来</p>
</li><li class="listitem">
<p>如果文件不存在,去cms服务器上查找, 如果存在便返回给www服务器,并显示出来</p>
</li><li class="listitem">
<p>如果cms上文件不存在,cms服务器便使用rewrite生成该文件, 同时将内容返回给www服务器,www将内容缓存在自己的服务器上,并将内容显示出来</p>
</li></ol></div>
<p>第二次访问</p>
<div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem">
<p>访问www服务器</p>
</li><li class="listitem">
<p>nginx 判断文件是否存在,如果存在将文件显示出来</p>
</li><li class="listitem">
<p>如果文件不存在,去cms服务器上查找, 如果存在便返回给www服务器,并显示出来</p>
</li><li class="listitem">
<p>如果cms上文件不存在,cms服务器便使用rewrite生成该文件, 同时将内容返回给www服务器,www将内容缓存在自己的服务器上,并将内容显示出来</p>
</li></ol></div>
</div>
<div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="id807"></a>1.2.4.2. 静态化实现手段有哪些?</h4></div></div></div>
<div class="orderedlist"><p class="title"><strong>静态化方法包括:</strong></p><ol class="orderedlist" type="1"><li class="listitem">
<p>生成方式</p>
</li><li class="listitem">
<p>抓取方式</p>
</li><li class="listitem">
<p>伪静态化</p>
</li><li class="listitem">
<p>混合方式</p>
</li></ol></div>
<div class="section"><div class="titlepage"><div><div><h5 class="title"><a id="id802"></a>生成方式</h5></div></div></div>
<p>主要由程序实现</p>
<p>例如</p>
<pre class="programlisting">
content = "<html><title>my static</title><body>hello world</body></html>"
file = open( your static file)
file.write(content)
file.close()
</pre>
</div>
<div class="section"><div class="titlepage"><div><div><h5 class="title"><a id="id803"></a>抓取方式</h5></div></div></div>
<p>主要由程序实现</p>
<p>程序中抓取</p>
<pre class="programlisting">
content = get_url('http://netkiller.8800.org/index.php')
file = open( index.html)
file.write(content)
file.close()
</pre>
<p>使用软件抓取,不仅限于wget。</p>
<pre class="programlisting">
wget http://netkiller.8800.org/index.php -O index.html
</pre>
<p>这时只给出简单例子,使用复杂参数实现更复杂的拾取,然后将脚本加入crontab中可。</p>
</div>
<div class="section"><div class="titlepage"><div><div><h5 class="title"><a id="id804"></a>伪静态化</h5></div></div></div>
<p>伪静态化是主要是通过在URL上做一些手脚,使你看去是静态的,实质上它是动态脚本。</p>
<div class="orderedlist"><p class="title"><strong>伪静态化实现主要包括两种方法:</strong></p><ol class="orderedlist" type="1"><li class="listitem">
<p>Rewrite rule</p>
</li><li class="listitem">
<p>path_info</p>
</li></ol></div>
<p>下面是一个PATH_INFO例子</p>
<p>http://netkiller.8800.org/zh-cn/photography/browse/2009.html</p>
<p>根本就不存在这个目录'zh-cn/photography/browse/'和文件'2009.html'</p>
<p></p>
<p>下面是一个Rewrite例子</p>
<p>http://example.org/bbs/thread-1003872-1-1.html</p>
</div>
<div class="section"><div class="titlepage"><div><div><h5 class="title"><a id="id805"></a>混合方式</h5></div></div></div>
<p>其实目前网站使用的基本上都是上面几种方法混合方式。</p>
<p>例如首先将动态url(example.org/news.php?cid=1&id=1) 通过rewrite转换为 (example.org/new_1_1.html)</p>
<p>接下来就比较容易解决了,一种方法是使用wget example.org/new_1_1.html,另一种方法你无需静态化,直接使用squid规则配置让他永不过期</p>
</div>
<div class="section"><div class="titlepage"><div><div><h5 class="title"><a id="id806"></a>静态化中的动态内容</h5></div></div></div>
<p>在静态化页面中有一些内容是无法实现静态的。像登录信息,用户评论等等</p>
<div class="orderedlist"><p class="title"><strong>我们用三种方法实现静态中嵌入动态内容:</strong></p><ol class="orderedlist" type="1"><li class="listitem">
<p>iframe - 灵活性差</p>
</li><li class="listitem">
<p>SSI - 消耗web服务器资源</p>
</li><li class="listitem">
<p>Ajax - 依赖浏览器,稳定性差</p>
</li></ol></div>
</div>
</div>
<div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="id808"></a>1.2.4.3. cdn</h4></div></div></div>
<p>如何使用 cdn 来缓存你的网站内容</p>
<p>让你的网页缓存在 cdn 节点上的方式有下面几种</p>
<div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem">
<p>让cdn的客服帮你配置缓存的规则, 他们很喜欢一刀切, 例如所有html都缓存2小时</p>
</li><li class="listitem">
<p>在他们管理后台自行使用正则配置缓存的时间, 这个他们一般不会提供, 某些公司的CDN会提供这个功能. 非常方便.</p>
</li><li class="listitem">
<p>通过HTTP头自行控制缓存时间, 一般是使用 max-age / s-maxage / Last-Modified 判断缓存时间</p>
</li></ol></div>
<p>
我比较喜欢最后一种, 通常我们使用max-age 与 s-maxage 同时使用, 这样我可以按照我的意向来决定文件的缓存时间
<a class="ulink" href="http://netkiller.github.com/architect/architecture/cache.html" target="_top">这里有更详细的解释说明.</a>
</p>
</div>
<div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="id809"></a>1.2.4.4. www 服务器</h4></div></div></div>
<p>下面给出一个精简后的配置例子</p>
<p>如果文件不存在就会连接后端cms服务器生成文件,并且显示出来,同时加上缓存. 生成的文件会从cms中同步到www服务器上. </p>
<div class="orderedlist"><p class="title"><strong>你可以采用</strong></p><ol class="orderedlist" type="1"><li class="listitem">
<p>rsync同步方案</p>
</li><li class="listitem">
<p>nfs/samba/gluster 共享方案</p>
</li><li class="listitem">
<p>iscsi 共享存储方案</p>
</li><li class="listitem">
<p>分布式文件系统方案</p>
</li></ol></div>
<p>
参考阅读:
<a class="ulink" href="http://netkiller.github.com/architect/architecture/dfs.html" target="_top">分布式文件系统</a>
,
<a class="ulink" href="http://netkiller.github.com/storage/index.html" target="_top">Netkiller Linux Storage 手札</a>
</p>
<pre class="screen">
upstream cms.mydomain.com {
server 192.168.2.11 weight=5 max_fails=3 fail_timeout=30s;
server 192.168.2.21 weight=5 max_fails=3 fail_timeout=30s;
server 192.168.2.23 backup;
server 192.168.2.23 down;
}
server {
listen 80;
server_name www.mydomain.com;
charset utf-8;
access_log /var/log/nginx/www.mydomain.com.access.log main;
location / {
root /www/mydomain.com/www.mydomain.com;
index index.html index.htm;
if ($request_uri ~* "\.(ico|css|js|gif|jpe?g|png|html)$") {
expires 1d;
}
if ($request_uri ~* "\.(xml|json)$") {
expires 1m;
}
valid_referers none blocked *.mydomain.com;
if ($invalid_referer) {
#rewrite ^(.*)$ http://www.mydomain.com/cn/$1;
return 403;
}
proxy_intercept_errors on;
if (!-f $request_filename) {
proxy_pass http://cms.mydomain.com;
break;
}
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
</pre>
</div>
<div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="id810"></a>1.2.4.5. cms 服务器</h4></div></div></div>
<div class="orderedlist"><p class="title"><strong>CMS 内容管理系统的主要功能</strong></p><ol class="orderedlist" type="1"><li class="listitem">
<p>内容分类管理</p>
</li><li class="listitem">
<p>内容模板管理</p>
</li><li class="listitem">
<p>内容编辑与发布</p>
</li><li class="listitem">
<p>内容生成</p>
</li></ol></div>
<div class="orderedlist"><p class="title"><strong>服务应该实现</strong></p><ol class="orderedlist" type="1"><li class="listitem">
<p>当发现目录中文件不存, 通过rewrite生成html, 这样可能根据需要生成html页面</p>
</li><li class="listitem">
<p>当页面更新的时候,应该通过api 刷新cdn的缓存, 图片的版本好应该加一</p>
</li><li class="listitem">
<p>将页面分成多个模块, 通过SSI拼装页面, 避免有重大改版时, 整站生成HTML.</p>
</li><li class="listitem">
<p>避免使用seesion技术, 这样在负载均衡的时候可以使用最小连接数算法</p>
</li></ol></div>
<p>例如:</p>
<pre class="screen">
rewrite ^/product/(phone|notebook)/(\d+).html /product/$1.php?id=$2 last;
</pre>
<p>URL 唯一, url设计要考虑唯一性, 不要出现同一个url处理两个任务, 例如下面的例子, 每个用户的profile一个URL, 当被访问的时候便可以缓存在CDN或者用户浏览器上.</p>
<pre class="screen">
http://www.mydomain.com/profile/neo.html
http://www.mydomain.com/profile/jam.html
</pre>
<pre class="screen">
server {
listen 80;
server_name www.mydomain.com;
#charset koi8-r;
access_log /var/log/nginx/www.mydomain.com.access.log main;
location / {
root /www/mydomain.com/www.mydomain.com;
index index.html;
}
}
server {
listen 80;
server_name cms.mydomain.com;
charset utf-8;
access_log /var/log/nginx/cms.mydomain.com.access.log main;
location / {
root /www/mydomain.com/cms.mydomain.com;
index index.html index.php;
}
location ~ ^/(cn|tw)/(comment|affiche)/.*\.html {
root /www/mydomain.com/www.mydomain.com;
if (!-f $request_filename) {
rewrite ^/(cn|tw)/(comment|affiche)/(\d+).html /publish/$2.php?id=$3&lang=$1 last;
}
}
location /xml/ {
root /www/mydomain.com/www.mydomain.com/xml;
}
location ~ ^/(config|include|crontab)/ {
deny all;
break;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php$ {
root /www/mydomain.com/cms.mydomain.com;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /www/mydomain.com/cms.mydomain.com$fastcgi_script_name;
include fastcgi_params;