<?xml version="1.0" encoding="gb2312"?>
<rss version="2.0">
<channel>
<title><![CDATA[inJava]]></title>
        <image>
        <title>http://hi.baidu.com</title>
        <link>http://hi.baidu.com</link>
        <url>http://img.baidu.com/img/logo-hi.gif</url>
        </image>
<description><![CDATA[]]></description>
<link>http://hi.baidu.com/injava</link>
<language>zh-cn</language>
<generator>www.baidu.com</generator>
<ttl>5</ttl>


<item>
        <title><![CDATA[Linux查看硬件系统命令]]></title>
        <link><![CDATA[http://hi.baidu.com/injava/blog/item/6211dd139194c429dc540108.html]]></link>
        <description><![CDATA[
		
		<h4>查看linux 版本</h4>
<div class="tpc_content">uname -a<br>
<br>
lsb_release -a <br>
<br>
<br>
2)cat  /proc/version <br>
3)cat /etc/issue<br>
<br>
//--redhat有效<br>
rpm -q  redhat-release<br>
<br>
cat /etc/redhat-release</div>
<p>1,  主板信息<br>
.查看主板的序列号<br>
--------------------------------------------------<br>
#使用命令<br>
dmidecode  | grep -i 'serial number'<br>
#查看板卡信息<br>
cat  /proc/pci<br>
--------------------------------------------------<br>
2,  cpu信息<br>
--------------------------------------------------<br>
#通过/proc文件系统<br>
1)  cat /proc/cpuinfo<br>
#通过查看开机信息<br>
2) dmesg | grep -i 'cpu'<br>
#<br>
3)dmidecode  -t processor<br>
--------------------------------------------------<br>
3,  硬盘信息<br>
--------------------------------------------------<br>
#查看分区情况<br>
fdisk  -l<br>
#查看大小情况<br>
df -h<br>
#查看使用情况<br>
du -h<br>
#<br>
hdparm -I  /dev/sda<br>
#<br>
dmesg | grep  sda<br>
--------------------------------------------------<br>
4,  内存信息<br>
--------------------------------------------------<br>
1) cat  /proc/meminfo<br>
2) dmesg | grep mem<br>
3) free -m<br>
4) vmstat<br>
5) dmidecode  | grep -i mem<br>
--------------------------------------------------<br>
5,  网卡信息<br>
--------------------------------------------------<br>
1) dmesg | grep -i  'eth'<br>
2) cat /etc/sysconfig/hwconf | grep -i eth<br>
3) lspci | grep -i  'eth'<br>
--------------------------------------------------<br>
6,  鼠标键盘和USB信息<br>
查看键盘和鼠标：cat /proc/bus/input/devices<br>
查看USB设备：cat  /proc/bus/usb/devices<br>
查看各设备的中断请求(IRQ):cat /proc/interrupts<br>
7,  显卡信息<br>
--------------------------------------------------<br>
1)lspci |grep -i  'VGA'<br>
2)dmesg | grep -i  'VGA'<br>
--------------------------------------------------<br>
8,  声卡信息<br>
--------------------------------------------------<br>
1)lspci |grep -i  'VGA'<br>
2)dmesg | grep -i  'VGA'<br>
--------------------------------------------------<br>
7,  其他命令<br>
.用硬件检测程序kuduz探测新硬件：service kudzu start ( or restart)<br>
.dmesg  (查看所有启动时检测到的硬件信息)<br>
.lspci (显示外设信息, 如usb，网卡等信息)<br>
.cat  /etc/sysconfig/hwconf<br>
.mpstat<br>
8,  需要手动安装的工具<br>
lshw,hwinfo,hal-device-manager<br>
9,  Solaris如何检测硬件参数<br>
俺从别处发现了些有意思的东西：<br>
Solaris的硬件相关命令<br>
发表：2004-3-8 11:20:36  出处：你的博客网(yourblog.org)<br>
--------------------------------------------------------------------------------<br>
1)．查看当前处理器的类型和速度(主频)<br>
#  psrinfo –v<br>
Status of processor 1 as of: 11/24/01 10:34:41<br>
Processor has  been on-line since 11/24/01 10:18:20.<br>
The sparcv9 processor operates at 432  MHz,<br>
and has a sparcv9 floating point processor.<br>
Status of processor 3 as  of: 11/24/01 10:34:41<br>
Processor has been on-line since 11/24/01  10:18:22.<br>
The sparcv9 processor operates at 432 MHz,<br>
and has a sparcv9  floating point processor.<br>
2)．打印当前的OBP版本号<br>
# prtconf –V<br>
OBP 3.20.0  2000/10/24 10:47<br>
# /usr/platform/sun4u/sbin/prtdiag –v | grep OBP<br>
OBP  3.20.0 2000/10/24 10:47 POST 6.1.0 2000/10/24 10:49<br>
ok. .version<br>
Release  3.20 Version 0 created 2000/10/24 10:47<br>
OBP 3.20.0 2000/10/24 10:47<br>
POST  6.1.0 2000/10/24 10:49<br>
OBDIAG 4.5.1 2000/10/24 10:48<br>
3)．查看硬盘物理信息(vendor,  RPM, Capacity)<br>
# iostat –E<br>
sd0 &#160;&#160; Soft Errors: 0 Hard Errors: 0 Transport  Errors: 0<br>
Vendor: SEAGATE Product: ST34371W SUN4.2G Revision: 7462 Serial  No:<br>
JDX394220KW EBC<br>
Size: 4.29GB ;<br>
Media Error: 0 Device Not Ready: 0  No Device: 0 Recoverable: 0<br>
Illegal Request: 0 Predictive Failure Analysis:  0<br>
sd2 &#160;&#160; Soft Errors: 0 Hard Errors: 0 Transport Errors: 0<br>
Vendor: FUJITSU  Product: MAJ3364M SUN36G Revision: 0804 Serial No: 01M18144<br>
Size: 36.42GB  ;<br>
Media Error: 0 Device Not Ready: 0 No Device: 0 Recoverable: 0<br>
Illegal  Request: 0 Predictive Failure Analysis: 0<br>
sd3 &#160;&#160; Soft Errors: 0 Hard Errors:  0 Transport Errors: 0<br>
Vendor: FUJITSU Product: MAJ3364M SUN36G Revision: 0804  Serial No: 01M16199<br>
Size: 36.42GB ;<br>
Media Error: 0 Device Not Ready: 0 No  Device: 0 Recoverable: 0<br>
Illegal Request: 0 Predictive Failure Analysis:  0<br>
sd21 &#160;&#160;&#160; Soft Errors: 0 Hard Errors: 0 Transport Errors: 0<br>
Vendor:  TOSHIBA Product: DVD-ROM SD-M1401 Revision: 1007 Serial No: 06/22/00<br>
Size:  18446744073.71GB ;<br>
Media Error: 0 Device Not Ready: 0 No Device: 0  Recoverable: 0<br>
Illegal Request: 0 Predictive Failure Analysis:  0<br>
4)．查看磁盘的几何参数和分区信息<br>
# prtvtoc /dev/rdsk/c0t0d0s0<br>
* /dev/rdsk/c0t0d0s0  partition map<br>
*<br>
* Dimensions:<br>
* &#160;&#160;&#160; 512 bytes/sector<br>
* &#160;&#160;&#160; 135  sectors/track<br>
* &#160;&#160; 16 tracks/cylinder<br>
* 2160 sectors/cylinder<br>
* 3882  cylinders<br>
* 3880 accessible cylinders<br>
*<br>
* Flags:<br>
* 1:  unmountable<br>
* 10: read-only<br>
*<br>
* Unallocated space:<br>
* &#160;&#160; First &#160;&#160;&#160;  Sector Last<br>
* &#160;&#160; Sector &#160;&#160;&#160; Count Sector<br>
* &#160;&#160;&#160; 8277120 103680  8380799<br>
*<br>
* &#160;&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;&#160;&#160; First &#160;&#160;&#160; Sector Last<br>
* Partition  Tag Flags &#160;&#160;&#160; Sector &#160;&#160;&#160; Count Sector Mount Directory<br>
0 &#160;&#160; 2 00 &#160;&#160; &#160;&#160; 0  2049840 2049839 /<br>
1 &#160;&#160; 3 01 2049840 615600 2665439<br>
2 &#160;&#160; 5 00 &#160;&#160; &#160;&#160; 0  8380800 8380799<br>
5 &#160;&#160; 0 00 2665440 2458080 5123519 /opt<br>
6 &#160;&#160; 4 00 5123520  3073680 8197199 /usr<br>
7 &#160;&#160; 8 00 8197200 &#160;&#160;&#160; 79920 8277119  /export/home<br>
5)．显示已经使用和未使用的i-node数目<br>
# df –F ufs –o i<br>
Filesystem &#160;&#160; &#160;&#160;  &#160;&#160; iused ifree %iused Mounted on<br>
/dev/dsk/c0t0d0s0 &#160;&#160; 7859 479821 &#160;&#160;&#160; 2%  /<br>
/dev/dsk/c0t0d0s6 &#160;&#160; 37763 339517 10% /usr<br>
/dev/dsk/c0t0d0s5 &#160;&#160; &#160;&#160;&#160; 722  301102 &#160;&#160;&#160; 0% /opt<br>
/dev/dsk/c0t0d0s7 &#160;&#160; &#160;&#160; 4 24380 &#160;&#160;&#160; 0%  /export/home<br>
6).显示cpu使用率最高的进程<br>
# ps –eo pid,pcpu,args | sort  +1n<br>
该命令输出当前系统进程的pid, CPU占用率及命令描述，并以pcpu来排序<br>
7)．显示内存占用率最高的进程<br>
# ps –eo  pid,vsz,args | sort  +1n<br>
该命令输出当前系统进程的pid，内存占用率及命令描述，并以vsz来排序<br>
8)．查看及启动系统的32位或64位内核模式<br>
64位模式<br>
#  isalist –v<br>
sparcv9+vis sparcv9 sparcv8plus+vis sparcv8plus sparcv8  sparcv8-fsmuld sparcv7<br>
sparc<br>
# isainfo –v<br>
64-bit sparcv9  applications<br>
32-bit sparc applications<br>
# isainfo  –b<br>
64<br>
启动64位内核模式<br>
ok. boot kernel/sparcv9/unix<br>
32位模式<br>
# isalist  –v<br>
sparcv8plus+vis sparcv8plus sparcv8 sparcv8-fsmuld sparcv7 sparc<br>
#  isainfo –v<br>
32-bit sparc applications<br>
# isainfo –b<br>
32<br>
启动32位模式<br>
ok.  boot kernel/unix<br>
9)．查看当前的OpenWindows版本<br>
# showrev –w<br>
OpenWindows  version:<br>
X11 Version 6.4.1 5 November 2001<br>
10)．查看当前CDE的版本<br>
#  /usr/ccs/bin/what /usr/dt/bin/dtmail<br>
/usr/dt/bin/dtmail:<br>
CDE Version  1.4.6_06<br>
CDEVersion1.4.6_06<br>
11)．测定当前的显示器刷新频率<br>
/usr/sbin/ffbconfig –rev  \?<br>
Valid values for -res option are:<br>
1024x768x60 [1]<br>
1024x768x70  [1]<br>
1024x768x75 [1]  [2]<br>
1024x768x77<br>
1024x800x84<br>
1152x900x66<br>
1152x900x76<br>
1280x800x76  [1] [2]<br>
1280x1024x60 [1] [2]<br>
1280x1024x67<br>
1280x1024x76<br>
1280x1024x85  [1] [2]<br>
960x680x112s<br>
960x680x108s<br>
640x480x60 [1] [2]<br>
640x480x60i  [1]<br>
768x575x50i [1]<br>
1440x900x76 [1] [2]<br>
1600x1000x66 [1]  [2]<br>
1600x1000x76 [1] [2]<br>
1600x1280x76 [1] [2]<br>
1920x1080x72 [1]  [2]<br>
1920x1080x76 [1] [2]<br>
1920x1200x70 [1] [2]<br>
1920x1200x75 [1]  [2]<br>
svga [1]<br>
1152<br>
1280<br>
stereo<br>
vga [1] [2]<br>
ntsc [1]<br>
pal  [1]<br>
none<br>
Notes:<br>
[1] monitor does not support this resolution.<br>
[2]  this version of FFB (FFB1) does not support this resolution<br>
12)．查看系统配置<br>
#  /usr/platform/sun4u/sbin/prtdiag –v<br>
System Configuration: Sun Microsystems  sun4u Sun Enterprise 450 (2 X<br>
UltraSPAR<br>
C-II 432MHz)<br>
System clock  frequency: 86 MHz<br>
Memory size: 1024 Megabytes<br>
=========================  CPUs =========================<br>
Run Ecache CPU CPU<br>
Brd CPU Module MHz &#160;&#160;&#160;  MB Impl. Mask<br>
--More--<br>
--- --- ------- ----- ------ ------ ----<br>
SYS &#160;&#160;&#160;  1 &#160;&#160;&#160; 1 &#160;&#160; 432 &#160;&#160;&#160; 4.0 US-II 10.0<br>
SYS &#160;&#160;&#160; 3 &#160;&#160;&#160; 3 &#160;&#160; 432 &#160;&#160;&#160; 4.0 US-II  10.0<br>
========================= Memory =========================<br>
Interlv.  Socket Size<br>
Bank Group &#160;&#160;&#160; Name (MB) Status<br>
---- ----- ------ ----  ------<br>
0 &#160;&#160; none &#160;&#160; 1901 256 &#160;&#160; OK<br>
0 &#160;&#160; none &#160;&#160; 1902 256 &#160;&#160; OK<br>
0 &#160;&#160;  none &#160;&#160; 1903 256 &#160;&#160; OK<br>
0 &#160;&#160; none &#160;&#160; 1904 256 &#160;&#160; OK<br>
0 &#160;&#160; none &#160;&#160; 1701 256  &#160;&#160; OK<br>
0 &#160;&#160; none &#160;&#160; 1702 256 &#160;&#160; OK<br>
========================= IO Cards  =========================<br>
No failures found in  System<br>
===========================<br>
========================= Environmental  Status =========================<br>
System Temperatures  (Celsius):<br>
------------------------------<br>
AMBIENT 20<br>
CPU 1 &#160;&#160; 40<br>
CPU  3 &#160;&#160; 40<br>
=================================<br>
Front Status  Panel:<br>
-------------------<br>
Keyswitch position is in On mode.<br>
System LED  Status: POWER &#160;&#160;&#160; GENERAL ERROR &#160;&#160; ACTIVITY<br>
[ ON] &#160;&#160; &#160;&#160; [OFF] &#160;&#160; &#160;&#160; &#160;&#160;&#160; [  ON]<br>
DISK ERROR THERMAL ERROR POWER SUPPLY ERROR<br>
[OFF] &#160;&#160; &#160;&#160; [OFF] &#160;&#160; &#160;&#160;  &#160;&#160;&#160; [OFF]<br>
Disk LED Status: &#160;&#160; &#160;&#160;&#160; OK = GREEN &#160;&#160; ERROR = YELLOW<br>
DISK 2:  [OK] &#160;&#160; &#160;&#160;&#160; DISK 3: [OK]<br>
DISK 0: [OK] &#160;&#160; &#160;&#160;&#160; DISK 1:  [EMPTY]<br>
=================================<br>
Fans:<br>
-----<br>
Fan Bank Speed  Status<br>
-------- ----- ------<br>
CPU &#160;&#160; &#160;&#160; 49 &#160;&#160; OK<br>
PWR &#160;&#160; &#160;&#160; 31 &#160;&#160;  OK<br>
Power Supplies:<br>
---------------<br>
Supply &#160;&#160;&#160; Rating Temp  Status<br>
------ &#160;&#160;&#160; ------ ---- ------<br>
0 &#160;&#160; &#160;&#160; 550 W &#160;&#160;&#160; 33 &#160;&#160; OK<br>
1 &#160;&#160; &#160;&#160;  550 W &#160;&#160;&#160; 33 &#160;&#160; OK<br>
========================= HW Revisions  =========================<br>
ASIC Revisions:<br>
---------------<br>
STP2223BGA:  Rev 4<br>
STP2223BGA: Rev 4<br>
STP2223BGA: Rev 4<br>
STP2003QFP: Rev  1<br>
STP2205BGA: Rev 1<br>
System PROM  revisions:<br>
----------------------<br>
OBP 3.20.0 2000/10/24 10:47 POST 6.1.0  2000/10/24 10:49<br>
# sysdef<br>
*<br>
* Hostid<br>
*<br>
80fee99b<br>
*<br>
* sun4u  Configuration<br>
*<br>
*<br>
* Devices<br>
*<br>
packages (driver not  attached)<br>
terminal-emulator (driver not attached)<br>
deblocker (driver not  attached)<br>
obp-tftp (driver not attached)<br>
disk-label (driver not  attached)<br>
SUNW,builtin-drivers (driver not attached)<br>
sun-keyboard (driver  not attached)<br>
ufs-file-system (driver not attached)<br>
chosen (driver not  attached)<br>
openprom (driver not attached)<br>
client-services (driver not  attached)<br>
options, instance #0<br>
aliases (driver not attached)<br>
memory  (driver not attached)<br>
virtual-memory (driver not attached)<br>
associations  (driver not attached)<br>
slot2disk (driver not attached)<br>
slot2led (driver not  attached)<br>
slot2dev (driver not attached)<br>
pci, instance #0<br>
ebus,  instance #0<br>
auxio (driver not attached)<br>
……<br>
# prtconf –D<br>
System  Configuration: Sun Microsystems sun4u<br>
Memory size: 1024 Megabytes<br>
System  Peripherals (Software  Nodes):<br>
SUNW,Ultra-4<br>
packages<br>
terminal-emulator<br>
deblocker<br>
obp-tftp<br>
disk-label<br>
SUNW,builtin-drivers<br>
sun-keyboard<br>
ufs-file-system<br>
chosen<br>
openprom<br>
client-services<br>
options,  instance #0 (driver name:  options)<br>
aliases<br>
memory<br>
virtual-memory<br>
associations<br>
slot2disk<br>
slot2led<br>
slot2dev<br>
pci,  instance #0 (driver name: pcipsy)<br>
ebus, instance #0 (driver name:  ebus)<br>
auxio<br>
power (driver name: power)<br>
SUNW,pll<br>
sc<br>
se, instance  #0 (driver name: se)<br>
su, instance #0 (driver name:  su)<br>
…..<br>
13)．查看当前系统中已经应用的补丁<br>
# showrev –p<br>
Patch: 109618-01 Obsoletes:  Requires: Incompatibles: Packages: SUNWeuxwe,<br>
SUN<br>
Weuezt, SUNWeudlg,  SUNWeudda<br>
Patch: 109889-01 Obsoletes: 109353-04 Requires: Incompatibles:  Packages:<br>
SUNWk<br>
vmx, SUNWkvm, SUNWmdb, SUNWhea, SUNWpstl,  SUNWpstlx<br>
Patch: 110369-05 Obsoletes: 110709-02 Requires: Incompatibles:  Packages:<br>
SUNWk<br>
vmx, SUNWcarx, SUNWcsr<br>
Patch: 110370-03 Obsoletes:  111643-01 Requires: Incompatibles: Packages:<br>
SUNWk<br>
vmx, SUNWkvm, SUNWmdb,  SUNWhea, SUNWpstl, SUNWpstlx<br>
Patch: 110373-04 Obsoletes: 111508-01 Requires:  Incompatibles: Packages:<br>
SUNWk<br>
vmx, SUNWcarx, SUNWcsr<br>
Patch: 110374-08  Obsoletes: 110136-02, 110516-02 Requires: Incompatibles:<br>
Pack<br>
ages:  SUNWkvmx, SUNWcarx, SUNWcar, SUNWcsr, SUNWmdbx<br>
…..<br>
14)．显示当前的运行级别<br>
# who  –rH<br>
NAME &#160;&#160; LINE &#160;&#160; &#160;&#160; TIME &#160;&#160; &#160;&#160; IDLE PID COMMENTS<br>
. &#160;&#160; run-level 3 Nov  24 10:18 &#160;&#160;&#160; 3 &#160;&#160; 0 S<br>
15)．查找一个文件所从属的包<br>
# pkgchk –lp  /usr/lib/sendmail<br>
Pathname: /usr/lib/sendmail<br>
Type: regular  file<br>
Expected mode: 4555<br>
Expected owner: root<br>
Expected group:  bin<br>
Expected file size (bytes): 761368<br>
Expected sum(1) of contents:  41707<br>
Expected last modification: Sep 24 03:13:13 2001<br>
Referenced by the  following packages:<br>
SUNWsndmu<br>
Current status:  installed<br>
16)．查看当前的bind版本信息<br>
# nslookup –class=chaos –q=txt  version.bind<br>
Server: ns.lnpta.net.cn<br>
Address: 202.96.64.68</p> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/injava/blog/category/unix%2Blinux">unix+linux</a>&nbsp;<a href="http://hi.baidu.com/injava/blog/item/6211dd139194c429dc540108.html#comment">查看评论</a>]]></description>
        <pubDate>2009-11-25  19:03</pubDate>
        <category><![CDATA[unix+linux]]></category>
        <author><![CDATA[macaque1101]]></author>
		<guid>http://hi.baidu.com/injava/blog/item/6211dd139194c429dc540108.html</guid>
</item>

<item>
        <title><![CDATA[NGiNX HTTP Push Module，Nginx 的扩展模块]]></title>
        <link><![CDATA[http://hi.baidu.com/injava/blog/item/96911c55f3c42bceb645aeed.html]]></link>
        <description><![CDATA[
		
		<a href="http://pushmodule.slact.net/">NGiNX_HTTP_Push_Module</a> 是一个 Nginx 的扩展模块，它实现了 HTTP Push 和Comet server的功能。HTTP Push 被经常用在网页上主动推的技术，例如一些聊天室啊，更新信息非常频繁的应用场合。<br>
<br>
<p>查看代码示例：<a href="http://pushmodule.slact.net/js/dumbchat.js">http://pushmodule.slact.net/js/dumbchat.js</a></p>
<p>&#160;</p>
<p><br>
Nginx介绍：<br>
Nginx是俄罗斯人编写的十分轻量级的HTTP服务器,Nginx，它的发音为“engine X”， 是一个高性能的HTTP和反向代理服务器，同时也是一个IMAP/POP3/SMTP 代理服务器。<br>
<br>
因为它的稳定性、丰富的功能集、 示例配置文件和低系统资源的消耗而闻名。目前国内各大门户网站已经部署了Nginx，如新浪、网易、腾讯等；国内几个重要的视频分享网站也部署了Nginx，如六房间、酷6等。<br>
<br>
nginx做为HTTP服务器，有以下几项基本特性：</p>
<p> </p>
<ul>
    <li>处理静态文件，索引文件以及自动索引；打开文件描述符缓冲</li>
    <li>无缓存的反向代理加速，简单的负载均衡和容错</li>
    <li>FastCGI，简单的负载均衡和容错</li>
    <li>模块化的结构。包括gzipping, byte ranges, chunked responses,以及 SSI-filter等filter。如果由FastCGI或其它代理服务器处理单页中存在的多个SSI，则这项处理可以并行运行，而不需要相互等待</li>
    <li>支持SSL 和 TLSSNI</li>
</ul> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/injava/blog/category/%CD%F8%D5%BE%BA%CD%BC%DC%B9%B9">网站和架构</a>&nbsp;<a href="http://hi.baidu.com/injava/blog/item/96911c55f3c42bceb645aeed.html#comment">查看评论</a>]]></description>
        <pubDate>2009-11-21  12:57</pubDate>
        <category><![CDATA[网站和架构]]></category>
        <author><![CDATA[macaque1101]]></author>
		<guid>http://hi.baidu.com/injava/blog/item/96911c55f3c42bceb645aeed.html</guid>
</item>

<item>
        <title><![CDATA[防火墙和交换机相结合实现内外网隔离]]></title>
        <link><![CDATA[http://hi.baidu.com/injava/blog/item/9dae1af35f67c5c10b46e03d.html]]></link>
        <description><![CDATA[
		
		<span class="a14c">
<p style="text-indent: 2em;">随着网络技术和因特网技术的成 熟和高速发展，越来越多的企事业单位开始组建网络来实现办公自动化和共享因特网的信息。但是， 安全问题也突现出来，iMaxNetworks(记忆网络公司)根据电子政务网络的特点提出了以交换机、防火墙和交换机相结合实现内外网隔离的解决方案。</p>
<p style="text-indent: 2em;"> </p>
<p style="text-indent: 2em;">方案一：交换机实现内外网的物理隔离</p>
<p style="text-indent: 2em;"> </p>
<p style="text-indent: 2em;">网络系统由内部局域网和外部因特网两个相对独立又相互关联的部分组成，均采用星形拓 扑结构和100M交换式快速以太网技术。内部网与外部网之间不存在物理上的连接，使来自Internet的入侵者无法通过计算机从外部网进入内部网，从而 最有效地保障了内部网重要数据的安全，内部局域网和外部因特网实现物理隔离。</p>
<p style="text-indent: 2em;"> </p>
<p style="text-indent: 2em;">imaxnetworks终端提供了经济安全的内外网物理隔离功能，它通过物理开关 进行内外网的切换，在物理上信息终端只与其中一个网络连通，所以黑客即使侵入其中一个网络也无法越过物理屏障侵入另一个网络。建立内外网隔离方案需要在内 网和外网各安装至少一台终端服务器。</p>
<p style="text-indent: 2em;"> </p>
<p style="text-indent: 2em;">方案二：防火墙和交换机结合，实现内外网隔离</p>
<p style="text-indent: 2em;"> </p>
<p style="text-indent: 2em;">VLAN隔离内外网：电子政务网络中存在多种业务，要实现多网的统一互联，同时又要 保证各个网络的安全，除了在应用层上通过加密、签名等手段避免数据泄漏和篡改外，在局域网的交换机上采用VLAN技术进行，将不同业务网的设备放置在不同 的VLAN中进行物理隔离，彻底避免各网之间的不必要的任意相互访问。在实现VLAN的技术中，以基于以太网交换机端口的VLAN(IEEE 802.1Q)最为成熟和安全。防火墙访问控制保证。</p>
<p style="text-indent: 2em;"> </p>
<p style="text-indent: 2em;">网络核心安全：为了网络构建简单，避免采用太多的设备使管理复杂化，从而降低网络的 安全性，可以放置一个高速防火墙，如图所示，通过这个这个防火墙，对所有出入中心的数据包进行安全控制及过滤，保证访问核心的安全。另外，为保证业务主机 及数据的安全，不允许办公网及业务网间的无控制互访，应在进行VLAN划分的三层交换机内设置ACL。</p>
<p style="text-indent: 2em;"> </p>
<p style="text-indent: 2em;">数据加密传输：对于通过公网(宽带城域网)进行传输的数据及互联，数据加密是必须的，在对关键业务做加密时，可以考虑采用更强的加密算法。</p>
<p style="text-indent: 2em;"> </p>
<p style="text-indent: 2em;">设置DMZ区进行外部访问：通常对于外部网络的接入，必须采取的安全策略是拒绝所有 接受特殊的原则。即对所有的外部接入，缺省认为都是不安全的，需要完全拒绝，只有一些特别的经过认证和允许的才能进入网络内部。与网络中心及其它内部局域 网之间的互连采用停火区(DMZ)，设置集中认证点对接入用户进行安全认证，认证及相关服务器位于停火区，业务通过代理服务器进行交换，不允许外部网络直 接访问内部系统。</p>
</span> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/injava/blog/category/%CD%F8%C2%E7%BC%BC%CA%F5">网络技术</a>&nbsp;<a href="http://hi.baidu.com/injava/blog/item/9dae1af35f67c5c10b46e03d.html#comment">查看评论</a>]]></description>
        <pubDate>2009-11-20  16:44</pubDate>
        <category><![CDATA[网络技术]]></category>
        <author><![CDATA[macaque1101]]></author>
		<guid>http://hi.baidu.com/injava/blog/item/9dae1af35f67c5c10b46e03d.html</guid>
</item>

<item>
        <title><![CDATA[使用tmpfs文件系统加速linux服务器]]></title>
        <link><![CDATA[http://hi.baidu.com/injava/blog/item/1896b9c33998b45fb219a831.html]]></link>
        <description><![CDATA[
		
		&#160;tmpfs是一种基于虚拟内存(VM)的文件系统，tmpfs就是虚拟磁盘(ramdisk)，tmpfs既可以使用内存，也可以使用交换分区(swap)，因为tmpfs使用虚拟内存，所以tmpfs的文件都驻留在内存，所以读写的速度非常快。<br>
<br>
<br>
\它最大的特点就是它的存储空间在VM（virtual memory）里面。Linux系统中VM主要由RM(Real Memory)和swap组成，因此tmpfs最大的存储空间可达（The size of RM + The size ofSwap）。 但是对于tmpfs本身而言，它并不知道自己使用的空间是RM还是Swap，这一切都是由内核的vm子系统管理的。<br>
<br>
使用tmpfs:<br>
#mount&#160; -t tmpfs -o size=32m&#160; tmpfs&#160; /mnt/tmp<br>
上面这条命令分配了上限为32m的VM到/mnt/tmp目录下，用df命令查看一下就知道了。<br>
<br>
简单介绍下tmpfs的优缺点；<br>
优点：<br>
<a><span>1）动态文件系统的大小<br>
</span>您可能以为我们前面在 /mnt/tmp 安装的tmp  文件系统空间的大小是32M。其实不然，/mnt/tmp最初的空间很小，它是随着文件的复制、创建和删除动态增减的。tmpfs能自动处理空间问题，以确保VM资源的循环使用。<br>
上面的参数32m只是告诉内核这个挂载点最大可用的VM为32m，如果不加上这个参数，tmpfs默认的大小是RM的一半，假如你的物理内存是512M，那么tmpfs默认的大小就是256M。<br>
2）速度<br>
由于tmpfs使用的是VM，它是是完全驻留在RAM中的，因此它比硬盘的速度要快许多。<br>
3）</a>没有持久性<br>
因为虚拟内存本质上就是易失的，tmpfs 数据在重新启动之后不会保留。<a> 它让 tmpfs 成为一个保存不需保留的数据（如临时文件，可以在 /tmp 中找到，还有 /var 文件系统树的某些部分）的卓越的文件系统。<br>
<br>
缺点：<br>
1）</a><a><span>低 VM 情况<br>
2）</span></a><a><span>在现存的安装点上安装问题</span></a><a><br>
</a><br>
linux系统中的/dev/shm就是虚拟内存目录，我们可以使用绑定的方法，如下：<br>
<br>
mkdir /dev/shm/tmp<br>
chmod 1777 /dev/shm/tmp<br>
mount –bind /dev/shm/tmp /tmp<br>
<br>
创建tmp目录，并且修改目录权限为1777，然后将/dev/shm/tmp绑定到/tmp。/tmp下原有的文件都不存在了。<br>
<br>
还有另一种方法,修改/etc/fstab文件如下：<br>
<br>
none /tmp tmpfs size=64M,nodev,nosuid,noexec 0 0 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/injava/blog/category/unix%2Blinux">unix+linux</a>&nbsp;<a href="http://hi.baidu.com/injava/blog/item/1896b9c33998b45fb219a831.html#comment">查看评论</a>]]></description>
        <pubDate>2009-11-20  16:39</pubDate>
        <category><![CDATA[unix+linux]]></category>
        <author><![CDATA[macaque1101]]></author>
		<guid>http://hi.baidu.com/injava/blog/item/1896b9c33998b45fb219a831.html</guid>
</item>

<item>
        <title><![CDATA[高并发高流量的大型网站架构设计(二)]]></title>
        <link><![CDATA[http://hi.baidu.com/injava/blog/item/8ff9332d4efe953e359bf7e4.html]]></link>
        <description><![CDATA[
		
		<font color="#0000cc" style="line-height: 1.3em;">4.3&#160;硬盘级缓存&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">硬盘级别的缓存是指将需要动态生成的内容暂时缓存在硬盘上，在一个可接受的延迟时间范围内，同样的请求不再动态生成，以达到节约系统资源，提高网站承受能力的目的。Linux环境下硬盘级缓存一般使用Squid［27］。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">Squid 是一个高性能的代理缓存服务器。和一般的代理缓存软件不同，Squid用一个单独的、非模块化的、I/O驱动的进程来处理所有的客户端请求。它接受来自客 户端对目标对象的请求并适当地处理这些请求。比如说，用户通过浏览器想下载（即浏览）一个web页面，浏览器请求Squid为它取得这个页面。Squid 随之连接到页面所在的原始服务器并向服务器发出取得该页面的请求。取得页面后，Squid再将页面返回给用户端浏览器，并且同时在Squid本地缓存目录 里保存一份副本。当下一次有用户需要同一页面时，Squid可以简单地从缓存中读取它的副本，直接返回给用户，而不用再次请求原始服务器。当前的 Squid可以处理HTTP，&#160;FTP，&#160;GOPHER，&#160;SSL和WAIS等协议。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">Squid 默认通过检测HTTP协议头的Expires和&#160;Cache-Control字段来决定缓存的时间。在实际应用中，可以显式的在服务器端脚本中输出 HTTP头，也可以通过配置apache的mod_expires模块，让apache自动的给每一个网页加上过期时间。对于静态内容，如图片，视频文 件，供下载的软件等，还可以针对文件类型（扩展名），用&#160;Squid&#160;的&#160;refresh_pattern&#160;来指定缓存时间。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">Squid&#160;运 行的时候，默认会在硬盘上建两层hash目录，用来存储缓存的Object。它还会在内存中建立一个Hash&#160;Table，用来记录硬盘中Object分 布的情况。如果Squid配置成为一个Squid集群中的一个的话，它还会建立一个&#160;Digest&#160;Table(摘要表)，用来存储其它&#160;Squid&#160;上 的Object摘要。当用户端想要的资料本地硬盘上没有时，可以很快的知道应该去集群中的哪一台机器获得。在硬盘空间快要达到配置限额的时候，可以配置使 用某种策略（默认使用LRU：Least&#160;Recently&#160;Used-最近最少用）删除一些Object，从而腾出空间［28］［29］。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">集 群中的Squid&#160;Server&#160;之间可以有两种关系：第一种关系是：Child&#160;和&#160;Parent。当&#160;Child&#160;Squid&#160;Server&#160;没有资 料时，会直接向&#160;Parent&#160;Squid&#160;Server&#160;要资料，然后一直等，直到&#160;Parent&#160;给它资料为止。&#160;第二种关系 是：Sibling&#160;和&#160;Sibling。当&#160;Squid&#160;Server&#160;没有资料时，会先向&#160;Sibling&#160;的&#160;Squid&#160;Server&#160;要资料， 如果&#160;Sibling&#160;没资料，就跳过它向&#160;Parent&#160;要或直接上原始网站去拿。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">默 认配置的Squid，没有经过任何优化的时候，一般可以达到&#160;50%&#160;的命中率［30］（图4）。如果需要，还可以通过参数优化，拆分业务，优化文件系统 等办法，使得Squid达到&#160;90%&#160;以上的缓存命中率。&#160;Squid处理TCP连接消耗的服务器资源比真正的HTTP服务器要小的多，当Squid分担 了大部分连接，网站的承压能力就大大增强了。&#160;</font><br>
<br>
<br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">4&#160;某网站使用MRTG工具检测到的Squid命中率&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">蓝线表示Squid的流量，绿色部分表示Apache流量&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">4.4&#160;内存级缓存&#160;<br>
内存级别的缓存是指将需要动态生成的内容暂时缓存在内存里，在一个可接受的延迟时间范围内，同样的请求不再动态生成，而是直接从内存中读取。Linux环境下内存级缓存Memcached［31］是一个不错的选择。</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">Memcached 是danga.com（运营Live&#160;Journal［32］的技术团队）开发的一套非常优秀的分布式内存对象缓存系统，用于在动态系统中减少数据库负 载，提升性能。和&#160;Squid&#160;的前端缓存加速不同，它是通过基于内存的对象缓存来减少数据库查询的方式改善网站的性能，而其中最吸引人的一个特性就是支 持分布式部署；也就是说可以在一群机器上建立一堆&#160;Memcached&#160;服务，每个服务可以根据具体服务器的硬件配置使用不同大小的内存块，这样，理论上 可以建立一个无限大的基于内存的缓存系统。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">Memcached&#160;是 以守护程序方式运行于一个或多个服务器中，随时接受客户端的连接操作，客户端可以由各种语言编写，目前已知的客户端&#160;API&#160;包括&#160;Perl/PHP /Python/Ruby/Java/C#/C&#160;等等[附录1]。客户端首先与&#160;Memcached&#160;服务建立连接，然后存取对象。每个被存取的对象都有 一个唯一的标识符&#160;key，存取操作均通过这个&#160;key&#160;进行，保存的时候还可以设置有效期。保存在&#160;Memcached&#160;中的对象实际上是放置在内存中 的，而不是在硬盘上。Memcached&#160;进程运行之后，会预申请一块较大的内存空间，自己进行管理，用完之后再申请一块，而不是每次需要的时候去向操作 系统申请。Memcached将对象保存在一个巨大的Hash表中，它还使用NewHash算法来管理Hash表，从而获得进一步的性能提升。所以当分配 给Memcached的内存足够大的时候，Memcached的时间消耗基本上只是网络Socket连接了［33］。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">Memcached 也有它的不足。首先它的数据是保存在内存当中的，一旦服务进程重启（进程意外被关掉，机器重启等），数据会全部丢失。其次Memcached以root权 限运行，而且Memcached本身没有任何权限管理和认证功能，安全性不足。第一条是Memcached作为内存缓存服务使用无法避免的，当然，如果内 存中的数据需要保存，可以采取更改Memcached的源代码，增加定期写入硬盘的功能。对于第二条，我们可以将Memcached服务绑定在内网IP 上，通过Linux防火墙进行防护。</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">4.5&#160;CPU与IO均衡&#160;<br>
在 一个网站提供的所有功能中，有的功能可能需要消耗大量的服务器端IO资源，像下载，视频播放等，而有的功能则可能需要消耗大量的服务器CPU资源，像视频 格式转换，LOG统计等。在一个服务器集群中，当我们发现某些机器上CPU和IO的利用率相差很大的时候，例如CPU负载很高而IO负责很低，我们可以考 虑将该服务器上的某些耗CPU资源的进程换成耗IO的进程，以达到均衡的目的。均衡每一台机器的CPU和IO消耗，不仅可以获得更充分的服务器资源利用， 而且还能够支持暂时的过载，遇到突发事件，访问流量剧增的时候，&#160;实现得体的性能下降 (Graceful&#160;performance&#160;degradation)［34］，而不是立即崩溃。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">4.6&#160;读写分离&#160;<br>
如 果网站的硬盘读写性能是整个网站性能提升的一个瓶颈的话，可以考虑将硬盘的读，写功能分开，分别进行优化。在专门用来写的硬盘上，我们可以在Linux下 使用软件RAID-0（磁盘冗余阵列0级）［35］。RAID-0在获得硬盘IO提升的同时，也会增加整个文件系统的故障率——它等于RAID中所有驱动 器的故障率之和。如果需要保持或提高硬盘的容错能力，就需要实现软件RAID-1，4或5，它们能在某一个（甚至几个）磁盘驱动器故障之后仍然保持整个文 件系统的正常运行［36］，但文件读写效率不如RAID-0。而专门用来读的硬盘，则不用如此麻烦，可以使用普通的服务器硬盘，以降低开销。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">一 般的文件系统，会综合考虑各种大小和格式的文件的读，写效率，因而对特定的文件读或写的效率不是最优。如果有必要，可以通过选择文件系统，以及修改文件系 统的配置参数来达到对特定文件的读或写的效率最大化。比如说，如果文件系统中需要存储大量的小文件，则可以使用ReiserFS［37］来替代Linux 操作系统默认的ext3系统，因为ReiserFS是基于平衡树的文件系统结构，尤其对于大量文件的巨型文件系统，搜索速度要比使用局部的二分查找法的 ext3快。&#160;ReiserFS里的目录是完全动态分配的，因此不存在ext3中常见的无法回收巨型目录占用的磁盘空间的情况。ReiserFS里小文件 （&lt;&#160;4K）可以直接存储进树，小文件读取和写入的速度更快，树内节点是按字节对齐的，多个小文件可共享同一个硬盘块，节约大量空间。ext3使用 固定大小的块分配策略，也就是说，不到4K的小文件也要占据4K的空间，导致的空间浪费比较严重［38］。&#160;但ReiserFS对很多Linux内核支持 的不是很好，包括2.4.3、2.4.9&#160;甚至相对较新的&#160;2.4.16，如果网站想要使用它，就必须要安装与它配合的较好的2.4.18内核——一般管 理员都不是很乐意使用太新的内核，因为在它上面运行的软件，都还没有经过大量的实践测试，也许有一些小的bug还没有被发现，但对于服务器来说，再小的 bug也是不能接受的。ReiserFS还是一个较为年轻的，发展迅速的文件系统，它相对于ext3来说有一个很大的缺陷就是，每次ReiserFS文件 系统升级的时候，必须完全重新格式化整个磁盘分区。所以在选择使用的时候，需要权衡取舍［39］。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">5&#160;应用程序层优化&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">5.1&#160;网站服务器程序的选择&#160;<br>
经 统计［40］，当前互联网上有超过50%的网站主机使用Apache［41］服务器程序。&#160;Apache是开源界的首选Web服务器，因为它的强大和可 靠，而且适用于绝大部分的应用场合。但是它的强大有时候却显得笨重，配置文件复杂得让人望而生畏，高并发情况下效率不太高。而轻量级的Web服务器 Lighttpd［42］却是后起之秀，基于单进程多路复用技术，其静态文件的响应能力远高于Apache。&#160;Lighttpd对PHP的支持也很好，还 可以通过Fastcgi方式支持其他的语言，比如Python等。&#160;虽然Lighttpd是轻量级的服务器，功能上不能跟Apache比，某些复杂应用无 法胜任，但即使是大部分内容动态生成的网站，仍免不了会有一些静态元素，比如图片、JS脚本、CSS等等，可以考虑将Lighttpd放在Squid的前 面，构成&#160;Lighttpd-&gt;Squid-&gt;Apache的一条处理链，Lighttpd在最前面，专门处理静态内容的请求，把动态内容请 求通过Proxy模块转发给Squid，如果Squid中有该请求的内容且没有过期，则直接返回给Lighttpd。新请求或者过期的页面请求交由 Apache中的脚本程序来处理。经过Lighttpd和Squid的两级过滤，Apache需要处理的请求大大减少，减少了Web应用程序的压力。同时 这样的构架，便于把不同的处理分散到多台计算机上进行，由Lighttpd在前面统一分发。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">在 这种架构下，每一级都是可以进行单独优化的，比如Lighttpd可以采用异步IO方式，Squid可以启用内存来缓存，Apache可以启用 MPM（Multi&#160;-Processing&#160;Modules，多道处理模块）等，并且每一级都可以使用多台机器来均衡负载，伸缩性好。&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">著名视频分享网站YouTube就是选择使用Lighttpd作为网站的前台服务器程序。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">5.2&#160;数据库选择&#160;<br>
MySQL［43］是一个快速的、多线程、多用户和健壮的SQL数据库服务器，支持关键任务、重负载系统的使用，是最受欢迎的开源数据库管理系统，是Linux下网站开发的首选。它由MySQL&#160;AB开发、发布和提供支持。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">MySQL数据库能为网站提供：&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">高性能。MySQL支持海量，快速的数据库存储和读取。还可以通过使用64位处理器来获取额外的一些性能，因为MySQL在内部里很多时候都使用64位的整数处理。&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">易用性。MySQL的核心是一个小而快速的数据库。它的快速连接，快速存取和安全可靠的特性使MySQL非常适合在互联网站上使用。&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">开放性。MySQL提供多种后台存储引擎的选择，如MyISAM，&#160;Heap，&#160;InnoDB，Berkeley&#160;Db等。缺省格式为MyISAM。&#160;MyISAM&#160;存储引擎与磁盘兼容的非常好［44］。&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">支 持企业级应用。MySQL有一个用于记录数据改变的二进制日志。因为它是二进制的，这一日志能够快速地将数据的更改从一台机器复制 （replication）到另一台机器上。即使服务器崩溃，这一二进制日志也能够保持完整。这一特性通常被用来搭建数据库集群，以支持更大的流量访问要 求［30］（图5）。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;"><br>
<br>
5&#160;MySQL主辅库模式集群示意&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">MySQL也有一些它自身的缺陷，如缺乏图形界面，缺乏存储过程，&#160;还不支持触发器，参照完整性，子查询和数据表视图等，但这些功能都在开发者的TO-DO列表当中。这就是开源的力量：你永远可以期待更好。&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">国外的Yahoo!，国内的新浪，搜狐等很多大型商业网站都使用MySQL&#160;作为后台数据库。对于一般的网站系统，无论从成本还是性能上考虑，MySQL应该是最佳的选择。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">5.3&#160;服务器端脚本解析器的选择&#160;<br>
目前最常见的服务器端脚本有三种：ASP(Active&#160;Server&#160;Pages)，JSP(Java&#160;Server&#160;Pages)，PHP&#160;(Hypertext&#160;Preprocessor)［45］［46］。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">ASP 全名Active&#160;Server&#160;Pages，以及它的升级ASP.NET，是微软公司出品的一个WEB服务器端的开发环境，利用它可以产生和运行动态 的、交互的、高性能的WEB服务应用程序。ASP采用脚本语言VBScript（C#）作为自己的开发语言。&#160;但因为只能运行在Windows环境下，这 里我们不讨论它。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">PHP 是一种跨平台的服务器端的嵌入式脚本语言。它大量地借用C，Java和Perl语言的语法，&#160;并耦合PHP自己的特性，使WEB开发者能够快速地写出动态 生成页面。它支持目前绝大多数数据库。PHP也是开源的，它的发行遵从GPL开源协议，你可以从&#160;PHP官方站点(</font><a href="http://www.php.net/" target="_blank"><font color="#0000cc" style="line-height: 1.3em;">http://www.php.net</font></a><font color="#0000cc" style="line-height: 1.3em;">)自由下载到它的二进制安装文件及全部的源代码。如果在Linux平台上与MySQL搭配使用，PHP是最佳的选择。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">JSP 是Sun公司推出的新一代站点开发语言，是Java语言除Java应用程序和Java&#160;Applet之外的第三个应用。Jsp可以在Serverlet和 JavaBean的支持下，完成功能强大的站点程序。&#160;作为采用Java技术家族的一部分，以及Java&#160;2（企业版体系结构）的一个组成部分，JSP技 术拥有Java技术带来的所有优点，包括优秀的跨平台性，高度可重用的组件设计，健壮性和安全性等，能够支持高度复杂的基于Web的应用。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">除 了这三种常见的脚本之外，在Linux下我们其实还有很多其他的选择：Python（Google使用），Perl等，如果作为CGI调用，那么可选择范 围就更广了。使用这些不太常见的脚本语言的好处是，它们对于某些特殊的应用有别的脚本所不具有的优势；不好的地方是，这些脚本语言在国内使用的人比较少， 当碰到技术上的问题的时候，能找到的资料也较少。</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">5.4&#160;可配置性&#160;<br>
在大型网站开发过程中，不管使用什么技术，网站的可配置性是必须的。在网站的后期运营过程中，肯定会有很多的需求变更。如果每一次的需求变更都会导致修改源代码，那么，这个网站的开发可以说是失败的。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">首 先，也是最重要的一点，功能和展示必须分开。PHP和JSP都支持模板技术，如PHP的Smarty，Phplib，JSP的 JSTL（JSP&#160;Standard&#160;Tag&#160;Library）等。核心功能使用脚本语言编写，前台展示使用带特殊标签的HTML，不仅加快了开发速度， 而且方便以后的维护和升级［47］。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">其次，对于前台模板，一般还需要将页面的头，尾单独提取出来，页面的主体部分也按模块或者功能拆分。对CSS，JS等辅助性的代码，也建议以单独的文件形式存放。这样不仅方便管理，修改，而且还可以在用户访问的时候进行缓存，减少网络流量，减轻服务器压力。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">再次，对于核心功能脚本，必须将与服务器相关的配置内容，如数据库连接配置，脚本头文件路径等，与代码分离开。尤其当网站使用集群技术，CDN加速等技术的时候，每一台服务器上的配置可能都会不一样。如果不使用配置文件，则需要同时维护几份不同的代码，很容易出错。&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">最后，应该尽量做到修改配置文件后能实时生效，避免修改配置文件之后需要重启服务程序的情况。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">5.5&#160;封装和中间层思想&#160;<br>
在功能块层次，如果使用JSP，基于纯面向对象语言Java的面向对象思想，类似数据库连接，会话管理等基本功能都已经封装成类了。如果使用PHP，则需要在脚本代码中显式的封装，将每一个功能块封装成一个函数，一个文件或者一个类。&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">在 更高的层次，可以将网站分为表示层，逻辑层，持久层，分别进行封装，做到当某一层架构发生变化时，不会影响到其他层。比如新浪播客在一次升级的时候，将持 久层的数据库由原来的集中式改为分布式架构，因为封装了数据库连接及所有操作[附录2]，做到了不修改任何上层代码，平稳的实现了过渡。近来流行的MVC 架构，将整个网站拆分成Model（模型/逻辑）、View（视图/界面）、Controller（控制/流程）三个部分，而且有很多优秀的代码框架可供 选择使用，&#160;像JSP的Structs，Spring，PHP的php.MVC，&#160;Studs&#160;等。使用现成的代码框架，可以使网站开发事半功倍。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">6&#160;扩容、容错处理&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">6.1&#160;扩容&#160;<br>
一 个大型网站，在设计架构的时候，必须考虑到以后可能的容量扩充。新浪播客在设计时充分地考虑了这一点。对于视频分享类网站来说，视频存储空间消耗是巨大 的。新浪播客在主存储服务器上，采用配置文件形式指定每一个存储盘柜上存储的视频文件的ID范围。当前台服务器需要读取一个视频的时候，首先通过询问主存 储服务器上的接口获得该视频所在的盘柜及目录地址，然后再去该盘柜读取实际的视频文件。这样如果需要增加存储用的盘柜，只需要修改配置文件即可，前台程序 丝毫不受影响。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">新浪播客采用MySQL数据库集群，在逻辑层封装了所有的数据库连接及操作。当数据库存储架构发生改变的时候，如增加一台主库，将某些数据表独立成库，增加读取数据用的从库等，都只需要修改封装了的数据库操作类，上层代码不用修改。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">新浪播客的前台页面服务器使用F5公司的硬件第四层交换机，网通，电信分别导向不同的虚拟IP，每一个虚拟IP后面又有多个服务器提供服务。当访问流量增大的时候，可以很方便往虚拟IP后面增加服务器，分担压力。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">6.2&#160;容错&#160;<br>
对于商业性网站来说，可用性是非常重要的。7*24的访问要求网站具有很强的容错能力。错误包括网络错误，服务器错误以及应用程序错误。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">2006 年12月27日台湾东部外海发生里氏7.6级地震，造成途径台湾海峡的多条海底电缆中断，导致许多国外网站，像MSN，&#160;NBA，&#160;Yahoo！（英文主 站）等国内无法访问，但也有例外，以Google为代表的在国内建设有分布式数据节点的很多网站却仍然可以访问。虽然说地震造成断网是不可抗原因，但如果 在这种情况下网站仍然可以访问，无疑能给网站用户留下深刻的印象。这件事情给大型商业网站留下的教训是：网站需要在用户主要分布区域保持数据存在，以防止 可能的网络故障。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">对 于服务器错误，一般采取冗余设计的方法来避免。对于存储服务器（主要是负责写入的服务器），可以使用RAID（冗余磁盘阵列）；对于数据库（主要是负责写 入的主库），可以采用双主库设计［30］；对于提供服务的前台，则可以使用第四层交换的集群，由多台服务器同时提供服务，不仅分担了流量压力，同时还可以 互相作为备份。&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">在应用层程序中，也要考虑“用户友好”的出错设计。典型例子如HTTP&#160;404&#160;出错页面，程序内部错误处理，错误返回提示等，尽可能的做到人性化。</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">7&#160;总结及展望&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">7.1&#160;总结&#160;<br>
</font><br>
<font color="#0000cc" style="line-height: 1.3em;"><br>
对 于一个高并发高流量的网站来说，任何一个环节的瓶颈都会造成网站性能的下降，影响用户体验，进而造成巨大的经济损失。在全互联网层面，应该使用分布式设 计，缩短网站与用户的网络距离，减少主干网上的流量，以及防止在网络意外情况下网站无法访问的问题。在局域网层面，应该使用服务器集群，一方面可以支撑更 大的访问量，另一方面也作为冗余备份，防止服务器故障导致的网站无法访问。在单服务器层面，应该配置操作系统，文件系统及应用层软件，均衡各种资源的消 耗，消除系统性能瓶颈，充分发挥服务器的潜能。在应用层，可以通过各种缓存来提升程序的效率，减少服务器资源消耗（图6）。另外，还需要合理设计应用层程 序，为以后的需求变更，扩容做好准备。&#160;<br>
<br>
</font><font color="#0000cc" style="line-height: 1.3em;">在每一个层次，都需要考虑容错的问题，严格消除单点故障，做到无论应用层程序错误，服务器软件错误，服务器硬件错误，还是网络错误，都不影响网站服务。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">7.2展望&#160;<br>
当 前Linux环境下有著名的LAMP（Linux＋Apache＋MySQL＋PHP/PERL/PYTHON）网站建设方案，但只是针对一般的中小网站 而言。对于高并发高流量的大型商业网站，还没有一个完整的，性价比高的解决方案。除去服务器，硬盘，带宽等硬件投资外，还需要花费大量的预算和时间精力在 软件解决方案上。&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;"><br>
随 着互联网的持续发展，Web2.0的兴起，在可以预见的未来里，互联网的用户持续增多，提供用户参与的网站不断增加，用户参与的内容日益增长，越来越多的 网站的并发量，访问量会达到一个新的高度，这就会促使越来越多的个人，公司以及研究机构来关注高并发高流量的网站架构问题。就像Web1.0成就了无数中 小网站，成就了LAMP一样，Web2.0注定也会成就一个新的，高效的，成本较低的解决方案。这个方案应该包括透明的第三方CDN网络加速服务，价格低 廉的第四层甚至更高层网络交换设备，优化了网络性能的操作系统，优化了读写性能，分布式，高可靠的文件系统，揉合了内存，硬盘等各个级别缓存的HTTP服 务器，更为高效的服务器端脚本解析器，以及封装了大部分细节的应用层设计框架。 </font> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/injava/blog/category/%CD%F8%D5%BE%BA%CD%BC%DC%B9%B9">网站和架构</a>&nbsp;<a href="http://hi.baidu.com/injava/blog/item/8ff9332d4efe953e359bf7e4.html#comment">查看评论</a>]]></description>
        <pubDate>2009-11-20  11:51</pubDate>
        <category><![CDATA[网站和架构]]></category>
        <author><![CDATA[macaque1101]]></author>
		<guid>http://hi.baidu.com/injava/blog/item/8ff9332d4efe953e359bf7e4.html</guid>
</item>

<item>
        <title><![CDATA[高并发高流量的大型网站架构设计(一)]]></title>
        <link><![CDATA[http://hi.baidu.com/injava/blog/item/3ba723facd19c6839f51461b.html]]></link>
        <description><![CDATA[
		
		<font color="#0000cc" style="line-height: 1.3em;">Web2.0的兴起，掀起了互联网新一轮的网络 创业大潮。以用户为导向的新网站建设概念，细分了网站功能和用户群，不仅成功的造就了一大批新生的网站，也极大的方便了上网的人们。但Web2.0以用户 为导向的理念，使得新生的网站有了新的特点——高并发，高流量，数据量大，逻辑复杂等，对网站建设也提出了新的要求。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">&#160;&#160;&#160;&#160;本文围绕高并发高流量的网站架构设计问题，主要研究讨论了以下内容：&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">&#160;&#160;&#160;&#160;首 先在整个网络的高度讨论了使用镜像网站，CDN内容分发网络等技术对负载均衡带来的便利及各自的优缺点比较。然后在局域网层次对第四层交换技术，包括硬件 解决方案F5和软件解决方案LVS，进行了简单的讨论。接下来在单服务器层次，本文着重讨论了单台服务器的Socket优化，硬盘级缓存技术，内存级缓存 技术，CPU与IO平衡技术（即以运算为主的程序与以数据读写为主的程序搭配部署），读写分离技术等。在应用层，本文介绍了一些大型网站常用的技术，以及 选择使用该技术的理由。最后，在架构的高度讨论了网站扩容，容错等问题。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">&#160;&#160;&#160;&#160;本文以理论与实践相结合的形式，结合作者实际工作中得到的经验，具有较广泛的适用性。&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">&#160;&#160;&#160;&#160;1&#160;引言&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">&#160;&#160;&#160;&#160;1.1&#160;互联网的发展&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">&#160;&#160;&#160;&#160;最 近十年间，互联网已经从一个单纯的用于科研的，用来传递静态文档的美国内部网络，发展成了一个应用于各行各业的，传送着海量多媒体及动态信息的全球网络。 从规模上看，互联网在主机数、带宽、上网人数等方面几乎一直保持着指数增长的趋势，2006年7月，互联网上共有主机439，286，364 台，WWW&#160;站点数量达到&#160;96，854，877个&#160;［1］。全球上网人口在2004&#160;年达到&#160;7&#160;亿&#160;2900万&#160;［2］，中国的上网人数 在&#160;2006&#160;年&#160;12&#160;月达到了约&#160;1亿3700&#160;万［3］。另一方面，互联网所传递的内容也发生了巨大的变化，早期互联网以静态、文本的公共信息为主 要内容，而目前的互联网则传递着大量的动态、多媒体及人性化的信息，人们不仅可以通过&#160;互联网阅读到动态生成的信息，而且可以通过它使用电子商务、即时通 信、网上游戏等交互性很强的服务。因此，可以说互联网已经不再仅仅是一个信息共享网络，而已经成为了一个无所不在的交互式服务的平台。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">&#160;&#160;&#160;&#160;1.2&#160;互联网网站建设的新趋势&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">&#160;&#160;&#160;&#160;互联网不断扩大的规模，日益增长的用户群，以及web2.0［4］的兴起，对互联网网站建设提出了新的要求:&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">&#160;&#160;&#160;&#160;高 性能和高可扩展性。2000&#160;年&#160;5&#160;月，访问量排名世界第一（统计数据来源［5］）的Yahoo&#160;［6］声称其日页浏览数达到&#160;6&#160;亿&#160;2500&#160;万， 即每秒约&#160;30，000&#160;次HTTP&#160;请求(按每个页面浏览平均产生&#160;4&#160;次请求计算)&#160;。这样大规模的访问量对服务的性能提出了非常高的要求。更为重要 的是，&#160;互联网受众的广泛性，使得成功的互联网服务的访问量增长潜力和速度非常大，因此服务系统必须具有非常好的可扩展性，以应付将来可能的服务增长。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">&#160;&#160;&#160;&#160;支 持高度并发的访问。高度并发的访问对服务的存储与并发能力提出了很高的要求，当前主流的超标量和超流水线处理器能处理的并发请求数是有限的，因为随着并发 数的上升，进程调度的开销会很快上升。互联网广域网的本质决定了其访问的延迟时间较长，因此一个请求完成时间也较长，按从请求产生到页面下载完成&#160;3&#160;秒 计算，&#160;Yahoo&#160;在&#160;2000&#160;年&#160;5&#160;月时平均有&#160;90，000&#160;个并发请求。而且对于较复杂的服务，服务器往往要维护用户会话的信息，例如一个互 联网网站如果每天有&#160;100&#160;万次用户会话，每次&#160;20分钟的话，那平均同时就会有约&#160;14000&#160;个并发会话。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">&#160;&#160;&#160;&#160;高 可用性。互联网服务的全球性决定了其每天&#160;24&#160;小时都会有用户访问，因此任何服务的停止都会对用户造成影响。而对于电子商务等应用，暂时的服务中止则意 味着客户的永久失去及大量的经济损失，例如ebay.com［7］1999&#160;年&#160;6&#160;月的一次&#160;22小时的网站不可访问，对此网站的&#160;380万用户的忠诚 度造成巨大影响，使得&#160;Ebay&#160;公司不得不支付了近500万美元用于补偿客户的损失，而该公司的市值同期下降了&#160;40&#160;亿美元［8］。因此，关键互联网 应用的可用性要求非常高。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">&#160;&#160;&#160;&#160;1.3&#160;新浪播客的简介&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">&#160;&#160;&#160;&#160;以 YouTube［9］为代表的微视频分享网站近来方兴未艾，仅2006年一年，国内就出现近百家仿YouTube的微视频分享网站［10］，试图复制 YouTube的成功模式。此类网站可以说是Web2.0概念下的代表网站，具有Web2.0网站所有典型特征：高并发，高流量，数据量大，逻辑复杂，用 户分散等等。新浪［11］作为国内最大的门户网站，在2005年成功运作新浪博客的基础上，于2006年底推出了新浪播客服务。新浪播客作为国内门户网站 中第一个微视频分享服务的网站，依靠新浪网站及新浪博客的巨大人气资源，在推出后不到半年的时间内，取得了巨大的成功：同类网站中上传视频数量第一、流量 增长最快、用户数最多［12］，所有这些成绩的取得的背后，是巨大的硬件投入，良好的架构支撑和灵活的应用层软件设计。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">2.1&#160;镜像网站技术&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">镜 像网站是指将一个完全相同的站点放到几个服务器上，分别有自己的URL，这些服务器上的网站互相称为镜像网站［13］。镜像网站和主站并没有太大差别，或 者可以视为主站的拷贝。镜像网站的好处是：如果不能对主站作正常访问（如服务器故障，网络故障或者网速太慢等），仍能通过镜像服务器获得服务。不便之处 是：更新网站内容的时候，需要同时更新多个服务器；需要用户记忆超过一个网址，或需要用户选择访问多个镜像网站中的一个，而用户选择的，不一定是最优的。 在用户选择的过程中，缺乏必要的可控性。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">在 互联网发展的初期，互联网上的网站内容很少，而且大都是静态内容，更新频率底。但因为服务器运算能力低，带宽小，网速慢，热门网站的访问压力还是很大。镜 像网站技术在这种情况下作为一种有效解决方案，被广泛采用。随着互联网的发展，越来越多的网站使用服务器端脚本动态生成内容，同步更新越来越困难，对可控 性要求越来越高，镜像技术因为不能满足这类网站的需要，渐渐的淡出了人们的视线。但有一些大型的软件下载站，因为符合镜像网站的条件——下载的内容是静态 的，更新频率较低，对带宽，速度要求又比较高，如国外的SourceForge&#160;（</font><a target="_blank" href="http://www.sourceforge.net/"><font color="#0000cc" style="line-height: 1.3em;">http://www.SourceForge.net</font></a><font color="#0000cc" style="line-height: 1.3em;">，著名开源软件托管网站），Fedora（</font><a target="_blank" href="http://fedoraproject.org/"><font color="#0000cc" style="line-height: 1.3em;">http://fedoraproject.org</font></a><font color="#0000cc" style="line-height: 1.3em;">，RedHat赞助的Linux发行版），国内的华军软件园（</font><a target="_blank" href="http://www.on%3cwbr%3elinedown.net/"><font color="#0000cc" style="line-height: 1.3em;">http://www.on<wbr></wbr>linedown.net</font></a><font color="#0000cc" style="line-height: 1.3em;">），天空软件站（</font><a target="_blank" href="http://www.skycn.com/"><font color="#0000cc" style="line-height: 1.3em;">http://www.skycn.com</font></a><font color="#0000cc" style="line-height: 1.3em;">）等，还在使用这项技术（图1）。&#160;</font><br>
<br>
<br>
<br>
<br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">图1&#160;上图：天空软件站首页的镜像选择页面&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">下图：SourceForge下载时的镜像选择页面&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">在网站建设的过程中，可以根据实际情况，将静态内容作一些镜像，以加快访问速度，提升用户体验。&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">2.2&#160;CDN内容分发网络&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">&#160;&#160;&#160;&#160;CDN 的全称是Content&#160;Delivery&#160;Network，即内容分发网络。其目的是通过在现有的互联网中增加一层新的网络架构，将网站的内容发布到最 接近用户的网络“边缘”，使用户可以就近取得所需的内容，分散服务器的压力，解决互联网拥挤的状况，提高用户访问网站的响应速度。从而解决由于网络带宽 小、用户访问量大、网点分布不均等原因所造成的用户访问网站响应速度慢的问题［14］。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">&#160;&#160;&#160;&#160;CDN 与镜像网站技术的不同之处在于网站代替用户去选择最优的内容服务器，增强了可控制性。CDN其实是夹在网页浏览者和被访问的服务器中间的一层镜像或者说缓 存，浏览者访问时点击的还是服务器原来的URL地址，但是看到的内容其实是对浏览者来说最优的一台镜像服务器上的页面缓存内容。这是通过调整服务器的域名 解析来实现的。使用CDN技术的域名解析服务器需要维护一个镜像服务器列表和一份来访IP到镜像服务器的对应表。当一个用户的请求到来的时候，根据用户的 IP，查询对应表，得到最优的镜像服务器的IP地址，返回给用户。这里的最优，需要综合考虑服务器的处理能力，带宽，离访问者的距离远近等因素。当某个地 方的镜像网站流量过大，带宽消耗过快，或者出现服务器，网络等故障的时候，可以很方便的设置将用户的访问转到另外一个地方（图2）。这样就增强了可控制 性。&#160;</font><br>
<br>
<br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">图2&#160;CDN原理示意图&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">CDN 网络加速技术也有它的局限性。首先，因为内容更新的时候，需要同步更新多台镜像服务器，所以它也只适用于内容更新不太频繁，或者对实时性要求不是很高的网 站；其次，DNS解析有缓存，当某一个镜像网站的访问需要转移时，主DNS服务器更改了IP解析结果，但各地的DNS服务器缓存更新会滞后一段时间，这段 时间内用户的访问仍然会指向该服务器，可控制性依然有不足。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">目前，国内访问量较高的大型网站如新浪、网易等的资讯频道，均使用CDN网络加速技术（图3），虽然网站的访问量巨大，但无论在什么地方访问，速度都会很快。但论坛，邮箱等更新频繁，实时性要求高的频道，则不适合使用这种技术。&#160;</font><br>
<br>
<br>
<br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">2.1&#160;镜像网站技术&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">镜 像网站是指将一个完全相同的站点放到几个服务器上，分别有自己的URL，这些服务器上的网站互相称为镜像网站［13］。镜像网站和主站并没有太大差别，或 者可以视为主站的拷贝。镜像网站的好处是：如果不能对主站作正常访问（如服务器故障，网络故障或者网速太慢等），仍能通过镜像服务器获得服务。不便之处 是：更新网站内容的时候，需要同时更新多个服务器；需要用户记忆超过一个网址，或需要用户选择访问多个镜像网站中的一个，而用户选择的，不一定是最优的。 在用户选择的过程中，缺乏必要的可控性。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">在 互联网发展的初期，互联网上的网站内容很少，而且大都是静态内容，更新频率底。但因为服务器运算能力低，带宽小，网速慢，热门网站的访问压力还是很大。镜 像网站技术在这种情况下作为一种有效解决方案，被广泛采用。随着互联网的发展，越来越多的网站使用服务器端脚本动态生成内容，同步更新越来越困难，对可控 性要求越来越高，镜像技术因为不能满足这类网站的需要，渐渐的淡出了人们的视线。但有一些大型的软件下载站，因为符合镜像网站的条件——下载的内容是静态 的，更新频率较低，对带宽，速度要求又比较高，如国外的SourceForge&#160;（</font><a target="_blank" href="http://www.sourceforge.net/"><font color="#0000cc" style="line-height: 1.3em;">http://www.SourceForge.net</font></a><font color="#0000cc" style="line-height: 1.3em;">，著名开源软件托管网站），Fedora（</font><a target="_blank" href="http://fedoraproject.org/"><font color="#0000cc" style="line-height: 1.3em;">http://fedoraproject.org</font></a><font color="#0000cc" style="line-height: 1.3em;">，RedHat赞助的Linux发行版），国内的华军软件园（</font><a target="_blank" href="http://www.on%3cwbr%3elinedown.net/"><font color="#0000cc" style="line-height: 1.3em;">http://www.on<wbr></wbr>linedown.net</font></a><font color="#0000cc" style="line-height: 1.3em;">），天空软件站（</font><a target="_blank" href="http://www.skycn.com/"><font color="#0000cc" style="line-height: 1.3em;">http://www.skycn.com</font></a><font color="#0000cc" style="line-height: 1.3em;">）等，还在使用这项技术（图1）。&#160;</font><br>
<br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">图1&#160;上图：天空软件站首页的镜像选择页面&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">下图：SourceForge下载时的镜像选择页面&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">在网站建设的过程中，可以根据实际情况，将静态内容作一些镜像，以加快访问速度，提升用户体验。&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">2.2&#160;CDN内容分发网络&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">&#160;&#160;&#160;&#160;CDN 的全称是Content&#160;Delivery&#160;Network，即内容分发网络。其目的是通过在现有的互联网中增加一层新的网络架构，将网站的内容发布到最 接近用户的网络“边缘”，使用户可以就近取得所需的内容，分散服务器的压力，解决互联网拥挤的状况，提高用户访问网站的响应速度。从而解决由于网络带宽 小、用户访问量大、网点分布不均等原因所造成的用户访问网站响应速度慢的问题［14］。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">&#160;&#160;&#160;&#160;CDN 与镜像网站技术的不同之处在于网站代替用户去选择最优的内容服务器，增强了可控制性。CDN其实是夹在网页浏览者和被访问的服务器中间的一层镜像或者说缓 存，浏览者访问时点击的还是服务器原来的URL地址，但是看到的内容其实是对浏览者来说最优的一台镜像服务器上的页面缓存内容。这是通过调整服务器的域名 解析来实现的。使用CDN技术的域名解析服务器需要维护一个镜像服务器列表和一份来访IP到镜像服务器的对应表。当一个用户的请求到来的时候，根据用户的 IP，查询对应表，得到最优的镜像服务器的IP地址，返回给用户。这里的最优，需要综合考虑服务器的处理能力，带宽，离访问者的距离远近等因素。当某个地 方的镜像网站流量过大，带宽消耗过快，或者出现服务器，网络等故障的时候，可以很方便的设置将用户的访问转到另外一个地方（图2）。这样就增强了可控制 性。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">图2&#160;CDN原理示意图&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">CDN 网络加速技术也有它的局限性。首先，因为内容更新的时候，需要同步更新多台镜像服务器，所以它也只适用于内容更新不太频繁，或者对实时性要求不是很高的网 站；其次，DNS解析有缓存，当某一个镜像网站的访问需要转移时，主DNS服务器更改了IP解析结果，但各地的DNS服务器缓存更新会滞后一段时间，这段 时间内用户的访问仍然会指向该服务器，可控制性依然有不足。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">目前，国内访问量较高的大型网站如新浪、网易等的资讯频道，均使用CDN网络加速技术（图3），虽然网站的访问量巨大，但无论在什么地方访问，速度都会很快。但论坛，邮箱等更新频繁，实时性要求高的频道，则不适合使用这种技术。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">图3&#160;新浪网使用ChinaCache&#160;CDN服务。&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">ChinaCache的服务节点全球超过130个，&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">其中中国节点超过80个，&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">覆盖全国主要6大网络的主要省份［15］。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">2.3&#160;应用层分布式设计&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">新 浪播客为了获得CDN网络加速的优点，又必须避免CDN的不足，在应用层软件设计上，采取了一个替代的办法。新浪播客提供了一个供播放器查询视频文件地址 的接口。当用户打开视频播放页面的时候，播放器首先连接查询接口，通过接口获得视频文件所在的最优的镜像服务器地址，然后再到该服务器去下载视频文件。这 样，用一次额外的查询获得了全部的控制性，而这次查询的通讯流量非常小，几乎可以忽略不计。CDN中由域名解析获得的灵活性也保留了下来：由接口程序维护 镜像网站列表及来访IP到镜像网站的对应表即可。镜像网站中不需要镜像所有的内容，而是只镜像更新速度较慢的视频文件。这是完全可以承受的。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">2.4&#160;网络层架构小结&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">从整个互联网络的高度来看网站架构，努力的方向是明确的：让用户就近取得内容，但又要在速度和可控制性之间作一个平衡。对于更新比较频繁内容，由于难以保持镜像网站之间的同步，则需要使用其他的辅助技术。</font>&#160;<br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">3&#160;交换层架构&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">3.1&#160;第四层交换简介&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">按 照OSI［16］七层模型，第四层是传输层。传输层负责端到端通信，在IP协议栈中是TCP和UDP所在的协议层。TCP和UDP数据包中包含端口号 （port&#160;number），它们可以唯一区分每个数据包所属的协议和应用程序。接收端计算机的操作系统根据端口号确定所收到的IP包类型，并把它交给合 适的高层程序。IP地址和端口号的组合通常称作“插口（Socket）”。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">第 四层交换的一个简单定义是：它是一种传输功能，它决定传输不仅仅依据MAC地址(第二层网桥)或源/目标IP地址(第三层路由)，而且依据IP地址与 TCP/UDP&#160;(第四层)&#160;应用端口号的组合（Socket）［17］。第四层交换功能就像是虚拟IP，指向实际的服务器。它传输的数据支持多种协议， 有HTTP、FTP、NFS、Telnet等。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">以HTTP协议为例，在第四层交换中为每个服务器组设立一个虚拟IP（Virtue&#160;IP，VIP），每组服务器支持某一个或几个域名。在域名服务器（DNS）中存储服务器组的VIP，而不是某一台服务器的真实地址。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">当 用户请求页面时，一个带有目标服务器组的VIP连接请求发送给第四层交换机。第四层交换机使用某种选择策略，在组中选取最优的服务器，将数据包中的目标 VIP地址用实际服务器的IP地址取代，并将连接请求传给该服务器。第四层交换一般都实现了会话保持功能，即同一会话的所有的包由第四层交换机进行映射 后，在用户和同一服务器间进行传输［18］。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">第四层交换按实现分类，分为硬件实现和软件实现。&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">3.2&#160;硬件实现&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">第 四层交换的硬件实现一般都由专业的硬件厂商作为商业解决方案提供。常见的有Alteon［19］，F5［20］等。这些产品非常昂贵，但是能够提供非常优 秀的性能和很灵活的管理能力。Yahoo中国当初接近2000台服务器使用了三四台Alteon就搞定了［21］。鉴于条件关系，这里不展开讨论。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">3.3&#160;软件实现&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">第 四层交换也可以通过软件实现，不过性能比专业硬件稍差，但是满足一定量的压力还是可以达到的，而且软件实现配置起来更灵活。&#160;软件四层交换常用的有 Linux上的LVS（Linux&#160;Virtual&#160;Server），它提供了基于心跳（heart&#160;beat）的实时灾难应对解决方案，提高了系统的鲁 棒性，同时提供了灵活的VIP配置和管理功能，可以同时满足多种应用需求［22］。</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">4&#160;服务器优化&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">4.1&#160;服务器整体性能考虑&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">对 于价值昂贵的服务器来说，怎样配置才能发挥它的最大功效，又不至于影响正常的服务，这是在设计网站架构的时候必须要考虑的。常见的影响服务器的处理速度的 因素有：网络连接，硬盘读写，内存空间，CPU速度。如果服务器的某一个部件满负荷运转仍然低于需要，而其他部件仍有能力剩余，我们将之称为性能瓶颈。服 务器想要发挥最大的功效，关键的是消除瓶颈，让所有的部件都被充分的利用起来。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">4.2&#160;Socket优化&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">以 标准的&#160;GNU/Linux&#160;为例。GNU/Linux&#160;发行版试图对各种部署情况都进行优化，这意味着对具体服务器的执行环境来说，标准的发行版可能并 不是最优化的［23］。GNU/Linux&#160;提供了很多可调节的内核参数，可以使用这些参数为服务器进行动态配置，包括影响&#160;Socket&#160;性能的一些重 要的选项。这些选项包含在&#160;/proc&#160;虚拟文件系统中。这个文件系统中的每个文件都表示一个或多个参数，它们可以通过&#160;cat&#160;工具进行读取，或使 用&#160;echo&#160;命令进行修改。这里仅列出一些影响TCP/IP&#160;栈性能的可调节内核参数［24］：&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">/proc/sys/net/ipv4/tcp_window_scaling&#160;“1”（1表示启用该选项，0表示关闭，下同）&#160;启用&#160;RFC［25］&#160;1323［26］&#160;定义的&#160;window&#160;scaling；要支持超过&#160;64KB&#160;的窗口，必须启用该值。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">/proc /sys/net/ipv4/tcp_sack&#160;“1”启用有选择的应答（Selective&#160;Acknowledgment），通过有选择地应答乱序接 收到的报文来提高性能（这样可以让发送者只发送丢失的报文段）；对于广域网通信来说，这个选项应该启用，但是这也会增加对&#160;CPU&#160;的占用。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">/proc/sys/net/ipv4/tcp_timestamps&#160;“1”&#160;以一种比重发超时更精确的方法（参阅&#160;RFC&#160;1323）来启用对&#160;RTT&#160;的计算；为了实现更好的性能应该启用这个选项。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">/proc /sys/net/ipv4/tcp_mem&#160;“24576&#160;32768&#160;49152”&#160;确定&#160;TCP&#160;栈应该如何反映内存使用；每个值的单位都是内存页 （通常是&#160;4KB）。第一个值是内存使用的下限。第二个值是内存压力模式开始对缓冲区使用应用压力的上限。第三个值是内存上限。超过这个上限时可以将报文 丢弃，从而减少对内存的使用。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">/proc /sys/net/ipv4/tcp_wmem&#160;“4096&#160;16384&#160;131072”&#160;为自动调优定义每个&#160;socket&#160;使用的内存。第一个值是 为&#160;socket&#160;的发送缓冲区分配的最少字节数。第二个值是默认值（该值会被&#160;wmem_default&#160;覆盖），缓冲区在系统负载不重的情况下可以增 长到这个值。第三个值是发送缓冲区空间的最大字节数（该值会被&#160;wmem_max&#160;覆盖）。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">/proc/sys/net/ipv4/tcp_westwood&#160;“1”&#160;启用发送者端的拥塞控制算法，它可以维护对吞吐量的评估，并试图对带宽的整体利用情况进行优化；对于&#160;WAN&#160;通信来说应该启用这个选项。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">与 其他调优努力一样，最好的方法实际上就是不断进行实验。具体应用程序的行为、处理器的速度以及可用内存的多少都会影响到这些参数对性能作用的效果。在某些 情况中，一些认为有益的操作可能恰恰是有害的（反之亦然）。因此，需要逐一试验各个选项，然后检查每个选项的结果，最后得出最适合具体机器的一套参数。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">如果重启了&#160;GNU/Linux&#160;系统，设置的内核参数都会恢复成默认值。为了将所设置的值作为这些参数的默认值，可以使用&#160;/etc/rc.local&#160;文件，在系统每次启动时自动将这些参数配置成所需要的值。&#160;</font><br>
<br>
<font color="#0000cc" style="line-height: 1.3em;">在检测每个选项的更改带来的效果的时候，GNU/Linux上有一些非常强大的工具可以使用：&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">ping&#160;这是用于检查主机的可用性的最常用的工具，也可以用于计算网络带宽延时。&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">traceroute&#160;打印连接到特定网络主机所经过的一系列路由器和网关的路径（路由），从而确定每个&#160;hop&#160;之间的延时。&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">netstat&#160;确定有关网络子系统、协议和连接的各种统计信息。&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">tcpdump&#160;显示一个或多个连接的协议级的报文跟踪信息，其中包括时间信息，可以使用这些信息来研究不同协议的报文时间。&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">Ethereal&#160;以一个易于使用的图形化界面提供&#160;tcpump&#160;（报文跟踪）的信息，支持报文过滤功能。&#160;</font><br>
<font color="#0000cc" style="line-height: 1.3em;">iperf&#160;测量&#160;TCP&#160;和&#160;UDP&#160;的网络性能；测量最大带宽，并汇报延时和数据报的丢失情况。 <br>
<br>
</font> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/injava/blog/category/%CD%F8%D5%BE%BA%CD%BC%DC%B9%B9">网站和架构</a>&nbsp;<a href="http://hi.baidu.com/injava/blog/item/3ba723facd19c6839f51461b.html#comment">查看评论</a>]]></description>
        <pubDate>2009-11-20  11:50</pubDate>
        <category><![CDATA[网站和架构]]></category>
        <author><![CDATA[macaque1101]]></author>
		<guid>http://hi.baidu.com/injava/blog/item/3ba723facd19c6839f51461b.html</guid>
</item>

<item>
        <title><![CDATA[iframe传值和自适应高度]]></title>
        <link><![CDATA[http://hi.baidu.com/injava/blog/item/6876317ffd69be0228388a96.html]]></link>
        <description><![CDATA[
		
		<p>用于跳转页面的同时，向多个框架传值</p>
&lt;body onload=&quot;document.paimai.location.href='paimai_frame_all.asp?id=&lt;%=request(&quot;id&quot;)%&gt;'&quot; &gt;
<p>paimai为框架标识</p>
<p><strong><font color="red">iframe自适应高度</font></strong></p>
<p>&lt;script&gt;</p>
<p>function SetWinHeight(obj)<br>
{<br>
var win=obj;<br>
if (document.getElementById)<br>
{<br>
if (win &amp;&amp; !window.opera)<br>
{<br>
if (win.contentDocument &amp;&amp; win.contentDocument.body.offsetHeight)</p>
<p>&#160;&#160;&#160;&#160;&#160; win.height = win.contentDocument.body.offsetHeight; <br>
else if(win.Document &amp;&amp; win.Document.body.scrollHeight)<br>
win.height = win.Document.body.scrollHeight;<br>
}<br>
}<br>
}</p>
<p>&lt;/script&gt;<br>
用法:win 为iframe标识<br>
&lt;iframe width=&quot;778&quot; align=&quot;center&quot; height=&quot;200&quot; id=&quot;win&quot; name=&quot;win&quot; onload=&quot;Javascript:SetWinHeight(this)&quot; frameborder=&quot;0&quot; scrolling=&quot;no&quot;&gt;&lt;/iframe&gt;</p> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/injava/blog/category/ajax%2Bjs%2Bflex%2Bas3">ajax+js+flex+as3</a>&nbsp;<a href="http://hi.baidu.com/injava/blog/item/6876317ffd69be0228388a96.html#comment">查看评论</a>]]></description>
        <pubDate>2009-11-18  16:10</pubDate>
        <category><![CDATA[ajax+js+flex+as3]]></category>
        <author><![CDATA[macaque1101]]></author>
		<guid>http://hi.baidu.com/injava/blog/item/6876317ffd69be0228388a96.html</guid>
</item>

<item>
        <title><![CDATA[javascript为什么尽量用局部变量代替全局变量]]></title>
        <link><![CDATA[http://hi.baidu.com/injava/blog/item/205c0817e8f51c0b4b90a747.html]]></link>
        <description><![CDATA[
		
		<p>在如何提高JavaScript性能这个问题上，大家最常听到的建议应该就是尽量使用局部变量（local variables）来代替全局变量（global variables）。在我从事Web开发工作的九年时间里，这条建议始终萦绕在我的耳边，并且从来没有质疑过，而这条建议的基础，则来自于 JavaScript处理作用域（scoping）和标识符解析（identifier resolution）的方法。</p>
<p>首先我们要明确，函数在JavaScript中具体表现为对象，创建一个函数的过程，其实也就是创建一个对象的过程。每个函数对象都有一个叫做 [[Scope]]的内部属性，这个内部属性包含创建函数时的作用域信息。实际上，[[Scope]]属性对应的是一个对象（Variable Objects）列表，列表中的对象是可以从函数内部访问的。比如说我们建立一个全局函数A，那么A的[[Scope]]内部属性中只包含一个全局对象 （Global Object），而如果我们在A中创建一个新的函数B，那么B的[[Scope]]属性中就包含两个对象，函数A的Activation Object对象在前面，全局对象（Global Object）排在后面。</p>
<p>当一个函数被执行的时候，会自动创建一个可以执行的对象（Execution Object），并同时绑定一个作用域链（Scope Chain）。作用域链会通过下面两个步骤来建立，用于进行标识符解析。</p>
<ol>
    <li>首先将函数对象[[Scope]]内部属性中的对象，按顺序复制到作用域链中。</li>
    <li>其次，在函数执行时，会创建一个新的Activation Object对象，这个对象中包含了this、参数（arguments）、局部变量（包括命名的参数）的定义，这个Activation Object对象会被置于作用域链的最前面。</li>
</ol>
<p>在执行JavaScript代码的过程中，当遇到一个标识符，就会根据标识符的名称，在执行上下文（Execution Context）的作用域链中进行搜索。从作用域链的第一个对象（该函数的Activation Object对象）开始，如果没有找到，就搜索作用域链中的下一个对象，如此往复，直到找到了标识符的定义。如果在搜索完作用域中的最后一个对象，也就是 全局对象（Global Object）以后也没有找到，则会抛出一个错误，提示用户该变量未定义（undefined）。这是在ECMA-262标准中描述的函数执行模型和标识 符解析（Identifier Resolution）的过程，事实证明，大部分的JavaScript引擎确实也是这样实现的。需要注意的是，ECMA-262并没有强制要求采用这种 结构，只是对这部分功能加以描述而已。</p>
<p>了解标识符解析（Identifier Resolution）的过程以后，我们就能明白为什么局部变量的解析速度要比其他作用域的变量快，主要是由于搜索过程被大幅缩短了。但是，具体会快多少 呢？为了回答这个问题，我模拟了一系列的测试，来测试不同作用域深度中变量的性能。</p>
<p>第一个测试是向一个变量中写入一个最简单的值（这里使用字面量的数值1），结果如下图显示，很有趣：</p>
<p align="center"><img width="400" height="271" border="0" src="http://www.webw3c.com/Article/UploadFiles/200903/2009030618393556.jpg"></p>
<p>从结果中不难看出，当标识符解析的过程需要进行深度搜索时，会伴随性能损失，而且性能损失的程度会随着标识符深度的增加而递增。意料之中的 是，Internet Explorer表现的是最差的（但公平的说，IE 8还是有一些改善的）。值得注意的是，这里有一些例外情况，Google Chrome和最新的WebKit午夜版在访问变量的时间保持得很稳定，不会随着作用域深度的递增而增长。当然，这应该归功于它们所使用的下一代 JavaScript引擎，V8和SquirrelFish。这些引擎在执行代码时进行了优化，而且很明显，这些优化使访问变量的速度比以往更快。 Opera表现的也很不错，比IE、Firefox和当前版本的Safari要快的多，但比基于V8和Squirrelfish的浏览器要慢。 Firefox 3.1 Beta 2的表现有点出人意料，对于局部变量执行的效率非常高，但随着作用域层数的增加，效率便大打折扣。需要注意的是，我这里使用的都是默认设置，也就是说 Firefox是没有开启Trace功能的。</p>
<p>上面的结果是通过对变量执行写操作而得出的，其实我很好奇，读取变量时的情况会不会有什么不同，于是接着做了下面的测试。结果发现，读的速度要比写的速度快一些，但是性能变化的趋势是一致的。</p>
<p align="center"><img width="400" height="271" border="0" src="http://www.webw3c.com/Article/UploadFiles/200903/2009030618393733.jpg"></p>
<p>和上个测试一样，Internet Explorer和Firefox还是最慢的，Opera表现了非常抢眼的性能，而同样的，Chrome和最新版本的Webkit午夜版显示了和作用域深 度无关的性能趋势，同样需要注意的是，Firefox 3.1 Beta 2的变量访问时间还是会伴随着深度出现一个奇怪的跳跃。</p>
<p>在测试的过程中，我发现一个有趣的现象，就是Chrome在访问全局变量的时候会有额外的性能损失。访问全局变量的时间和作用域层数没有关系，但是会比访问同样层数的局部变量的时间多出50%。</p>
<p>这两个测试可以给我们带来什么启示呢？首先是验证了那个古老的观点，就是要尽可能的使用局部变量。在所有的浏览器下，访问局部变量都比访问跨作用域的变量要快，当然也包括全局变量。下面这几点应该是通过这个测试得出的经验吧：</p>
<ul>
    <li>仔细检查函数中所有使用的变量，如果有一个变量不是当前作用域定义的，而且使用了不止一次，那么我们就应该把这个变量保存在 局部变量中，而使用这个局部变量来进行读写操作。这样可以帮助我们将作用域外的变量的搜索深度减少到1.这对全局变量尤为重要，因为全局变量总是被放到作 用域链的最后位置来搜索。</li>
    <li>避免使用with语句。因为它会修改执行上下文（Execution Context）的作用域链，在最前面添加一个对象（Variable Object）。这就意味着在执行with的过程中，实际上的局部变量都被移到作用域链上的第二个位置，这会带来性能上的损失。</li>
    <li>如果你确定一段代码肯定会抛出异常，那么就要避免使用try-catch，因为catch分支在作用域链上的处理方法和with是一样的。但try分支的代码是没有性能损失的，所以还是建议用try-catch来捕获那些不可预知的错误。</li>
</ul>
<p>如果你想围绕这个话题展开更多的讨论，我在上个月的 <a target="_blank" href="http:// .meetup.com/9/">Mountain View JavaScript Meetup</a> 中曾经发表了一个小演讲。可以在SlideShare上下载 <a target="_blank" href="http://www.slideshare.net/nzakas/java-script-variable-performance-presentation">幻灯片</a>，或者观看聚会的 <a target="_blank" href="http://www.youtube.com/watch?v=MHBbK9dt0Kg">完整视频</a>，我的演讲大概从11分钟左右时开始。</p> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/injava/blog/category/ajax%2Bjs%2Bflex%2Bas3">ajax+js+flex+as3</a>&nbsp;<a href="http://hi.baidu.com/injava/blog/item/205c0817e8f51c0b4b90a747.html#comment">查看评论</a>]]></description>
        <pubDate>2009-11-11  17:15</pubDate>
        <category><![CDATA[ajax+js+flex+as3]]></category>
        <author><![CDATA[macaque1101]]></author>
		<guid>http://hi.baidu.com/injava/blog/item/205c0817e8f51c0b4b90a747.html</guid>
</item>

<item>
        <title><![CDATA[JSP生成静态HTML页面的几种方法详解]]></title>
        <link><![CDATA[http://hi.baidu.com/injava/blog/item/7782640eaca872c07acbe163.html]]></link>
        <description><![CDATA[
		
		一、从数据库中取相应数据并替换掉模板中的对应标签，下面是一个简单的示例<br>
<br>
<br>
1.buildhtml.jsp
<p style="margin: 1em 1em 0pt; font-weight: bold;">CODE:</p>
<code style="border: 1px solid rgb(204, 204, 204); margin: 0pt 1em 1em; padding: 0.5em; display: block;  font-style: normal; font-variant: normal; font-weight: normal; font-size: 12px; font-size-adjust: none; font-stretch: normal; line-height: 1.8em;">&lt;%@ page contentType=&quot;text/html; charset=gb2312&quot; import=&quot;java.util.*,java.io.*&quot;%&gt;<br>
&lt;%<br>
try{<br>
String title=&quot;This is Title&quot;;<br>
String content=&quot;This is Content Area&quot;;<br>
String editer=&quot;LaoMao&quot;;<br>
String filePath = &quot;&quot;;<br>
filePath = request.getRealPath(&quot;/&quot;)+&quot;test/template.htm&quot;;<br>
//out.print(filePath+&quot;&lt;br&gt;&quot;);<br>
String templateContent=&quot;&quot;;<br>
FileInputStream fileinputstream = new FileInputStream(filePath);//读取模块文件<br>
int lenght = fileinputstream.available();<br>
byte bytes[] = new byte[lenght];<br>
fileinputstream.read(bytes);<br>
fileinputstream.close();<br>
templateContent = new String(bytes);<br>
//out.print(templateContent);<br>
templateContent=templateContent.replaceAll(&quot;###title###&quot;,title);<br>
templateContent=templateContent.replaceAll(&quot;###content###&quot;,content);<br>
templateContent=templateContent.replaceAll(&quot;###author###&quot;,editer);//替换掉模块中相应的地方<br>
//out.print(templateContent);<br>
// 根据时间得文件名<br>
Calendar calendar = Calendar.getInstance();<br>
String fileame = String.valueOf(calendar.getTimeInMillis()) +&quot;.html&quot;;<br>
fileame = request.getRealPath(&quot;/&quot;)+fileame;//生成的html文件保存路径<br>
FileOutputStream fileoutputstream = new FileOutputStream(fileame);//建立文件输出流<br>
byte tag_bytes[] = templateContent.getBytes();<br>
fileoutputstream.write(tag_bytes);<br>
fileoutputstream.close();<br>
}<br>
catch(Exception e){<br>
out.print(e.toString());<br>
}<br>
%&gt;</code>2. template.htm
<p style="margin: 1em 1em 0pt; font-weight: bold;">CODE:</p>
<code style="border: 1px solid rgb(204, 204, 204); margin: 0pt 1em 1em; padding: 0.5em; display: block;  font-style: normal; font-variant: normal; font-weight: normal; font-size: 12px; font-size-adjust: none; font-stretch: normal; line-height: 1.8em;">&lt;html&gt;<br>
&lt;head&gt;<br>
&lt;title&gt;###title###&lt;/title&gt;<br>
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=gb2312&quot;&gt;<br>
&lt;LINK href=&quot;../css.css&quot; rel=stylesheet type=text/css&gt;<br>
&lt;/head&gt;<br>
<br>
&lt;body&gt;<br>
&lt;table width=&quot;500&quot; border=&quot;0&quot; align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;2&quot;&gt;<br>
&lt;tr&gt; <br>
&lt;td align=&quot;center&quot;&gt;###title###&lt;/td&gt;<br>
&lt;/tr&gt;<br>
&lt;tr&gt; <br>
&lt;td align=&quot;center&quot;&gt;author：###author###&lt;/td&gt;<br>
&lt;/tr&gt;<br>
&lt;tr&gt;<br>
&lt;td&gt;###content###&lt;/td&gt;<br>
&lt;/tr&gt;<br>
&lt;/table&gt;<br>
&lt;/body&gt;<br>
&lt;/html&gt;</code>=======================================================<br>
<br>
二、从动态页的URL获取相应页面内容并写入到文件
<p style="margin: 1em 1em 0pt; font-weight: bold;">CODE:</p>
<code style="border: 1px solid rgb(204, 204, 204); margin: 0pt 1em 1em; padding: 0.5em; display: block;  font-style: normal; font-variant: normal; font-weight: normal; font-size: 12px; font-size-adjust: none; font-stretch: normal; line-height: 1.8em;">/*<br>
* Created on 2006-3-4<br>
* To change the template for this generated file go to<br>
* Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments<br>
*/<br>
package com.easydone.cn.tools.utils;<br>
<br>
import java.io.BufferedReader;<br>
import java.io.File;<br>
import java.io.FileOutputStream;<br>
import java.io.InputStream;<br>
import java.io.InputStreamReader;<br>
import java.io.PrintWriter;<br>
import java.net.HttpURLConnection;<br>
import java.net.URL;<br>
import java.util.Date;<br>
<br>
/**<br>
* @author Administrator<br>
* To change the template for this generated type comment go to<br>
* Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments<br>
*/<br>
public class MakeHtml {<br>
private static long star = 0;<br>
private static long end = 0;<br>
private static long ttime = 0;<br>
<br>
//返回html代码<br>
public static String getHtmlCode(String httpUrl){<br>
Date before = new Date();<br>
star = before.getTime();<br>
String htmlCode = &quot;&quot;;<br>
try {<br>
InputStreamin;<br>
URL url = new java.net.URL(httpUrl);<br>
HttpURLConnection connection = (HttpURLConnection)url.openConnection();<br>
connection = (HttpURLConnection) url.openConnection();<br>
connection.setRequestProperty(&quot;User-Agent&quot;,&quot;Mozilla/4.0&quot;);<br>
connection.connect();<br>
in = connection.getInputStream();<br>
java.io.BufferedReader breader = new BufferedReader(new InputStreamReader(in , &quot;GBK&quot;));<br>
String currentLine;<br>
while((currentLine=breader.readLine())!=null){<br>
htmlCode+=currentLine;<br>
}<br>
} catch (Exception e) {<br>
e.printStackTrace();<br>
}finally{<br>
Date after = new Date();<br>
end = after.getTime();<br>
ttime = end-star ;<br>
System.out.println(&quot;执行时间:&quot;+ttime +&quot;秒&quot;);<br>
}<br>
return htmlCode;<br>
}<br>
//存储文件<br>
public static synchronized void writeHtml(String filePath,String info,String flag) {<br>
<br>
PrintWriter pw = null;<br>
try {<br>
File writeFile = new File(filePath);<br>
boolean isExit = writeFile.exists();<br>
if (isExit != true) {<br>
writeFile.createNewFile();<br>
} else {<br>
if (!flag.equals(&quot;NO&quot;)) {<br>
writeFile.delete();<br>
writeFile.createNewFile();<br>
} <br>
}<br>
pw = new PrintWriter(new FileOutputStream(filePath, true));<br>
pw.println(info);<br>
pw.close();<br>
} catch (Exception ex) {<br>
System.out.println(ex.getMessage());<br>
}finally{<br>
pw.close();<br>
}<br>
}<br>
<br>
public static void main(String[] args) {<br>
String url = &quot;http://www.easydone.cn/index.htm&quot;;<br>
writeHtml(&quot;c:/demo.htm&quot;,getHtmlCode(url),&quot;NO&quot;);<br>
}<br>
}</code>三、利用Filter和定制Response，把<a class="UBBWordLink" href="http://idc.zmke.com/" target="_blank">服务器</a>返回的JSP响应输出到我们自己的Response中，就可以将响应快速写入Html文件，然后再发送给客户。
<p style="margin: 1em 1em 0pt; font-weight: bold;">CODE:</p>
<code style="border: 1px solid rgb(204, 204, 204); margin: 0pt 1em 1em; padding: 0.5em; display: block;  font-style: normal; font-variant: normal; font-weight: normal; font-size: 12px; font-size-adjust: none; font-stretch: normal; line-height: 1.8em;">import java.io.*;<br>
import javax.servlet.*;<br>
import javax.servlet.http.*;<br>
import java.util.Calendar;<br>
<br>
public class CacheFilter implements Filter {<br>
ServletContext sc;<br>
FilterConfig fc;<br>
long cacheTimeout = Long.MAX_VALUE;<br>
<br>
public void doFilter(ServletRequest req,<br>
ServletResponse res,<br>
FilterChain chain)<br>
throws IOException, ServletException {<br>
HttpServletRequest request =<br>
(HttpServletRequest) req;<br>
HttpServletResponse response =<br>
(HttpServletResponse) res;<br>
<br>
// check if was a resource that shouldn't be cached.<br>
String r = sc.getRealPath(&quot;&quot;);<br>
String path = <br>
fc.getInitParameter(request.getRequestURI());<br>
if (path!= null &amp;&amp; path.equals(&quot;nocache&quot;)) {<br>
chain.doFilter(request, response);<br>
return;<br>
}<br>
path = r+path;<br>
<br>
String id = request.getRequestURI() + <br>
request.getQueryString();<br>
File tempDir = (File)sc.getAttribute(<br>
&quot;javax.servlet.context.tempdir&quot;);<br>
<br>
// get possible cache<br>
String temp = tempDir.getAbsolutePath();<br>
File file = new File(temp+id);<br>
<br>
// get current resource<br>
if (path == null) {<br>
path = sc.getRealPath(request.getRequestURI());<br>
}<br>
File current = new File(path);<br>
<br>
try {<br>
long now =<br>
Calendar.getInstance().getTimeInMillis();<br>
//set timestamp check<br>
if (!file.exists() || (file.exists() &amp;&amp;<br>
current.lastModified() &gt; file.lastModified()) ||<br>
cacheTimeout &lt; now - file.lastModified()) {<br>
String name = file.getAbsolutePath();<br>
name =<br>
name.substring(0,name.lastIndexOf(&quot;/&quot;));<br>
new File(name).mkdirs();<br>
ByteArrayOutputStream baos =<br>
new ByteArrayOutputStream();<br>
CacheResponseWrapper wrappedResponse =<br>
new CacheResponseWrapper(response, baos);<br>
chain.doFilter(req, wrappedResponse);<br>
<br>
FileOutputStream fos = new FileOutputStream(file);<br>
fos.write(baos.toByteArray());<br>
fos.flush();<br>
fos.close();<br>
}<br>
} catch (ServletException e) {<br>
if (!file.exists()) {<br>
throw new ServletException(e);<br>
}<br>
}<br>
catch (IOException e) {<br>
if (!file.exists()) {<br>
throw e;<br>
}<br>
}<br>
<br>
FileInputStream fis = new FileInputStream(file);<br>
String mt = sc.getMimeType(request.getRequestURI());<br>
response.setContentType(mt);<br>
ServletOutputStream sos = res.getOutputStream();<br>
for (int i = fis.read(); i!= -1; i = fis.read()) {<br>
sos.write((byte)i);<br>
}<br>
}<br>
<br>
public void init(FilterConfig filterConfig) {<br>
this.fc = filterConfig;<br>
String ct =<br>
fc.getInitParameter(&quot;cacheTimeout&quot;);<br>
if (ct != null) {<br>
cacheTimeout = 60*1000*Long.parseLong(ct);<br>
}<br>
this.sc = filterConfig.getServletContext();<br>
}<br>
<br>
public void destroy() {<br>
this.sc = null;<br>
this.fc = null;<br>
}<br>
}</code>参考文章：<br>
<br>
使用Filter实现静态HTML缓冲(一种折中方法) <br>
缓冲是Web应用中必须考虑的一个提高性能的重要手段。对于基于JSP/Servlet技术的站点，常用的缓冲有持久层的数据库连接池缓冲，内存中的值对象缓冲，JSP页面缓冲，以及各种各样的缓冲框架等等，无不是为了提高系统的吞吐量。<br>
<br>
然而对于大型站点来说，将JSP页面转换为静态Html也许是最高效的方法，特别适合于数据不经常变化但是页面访问量特别大的站点，如新闻等，通过把 JSP动态页面预先转换为静态Html页面，当用户请求此页面时，系统自动导向到对应的Html页面，从而避免解析JSP请求，调用后台逻辑以及访问数据 库等操作所带来的巨大开销。<br>
<br>
如何将一个已有的JSP站点的动态JSP页面转化为静态Html呢？我们希望在不用更改现有Servlet，JSP的前提下让系统自动将这些JSP转换为Html页。幸运的是，Filter为我们提供了一种实现方案。<br>
<br>
Filter是Servlet 2.2规范中最激动人心的特性。Filter能过滤特定URL如/admin/*并进行必要的预处理，如修改Request和Response，从而实现 定制的输入输出。更强大的是，Filter本身是一个责任链模式，它能一个接一个地传递下去，从而将实现不同功能的Filter串起来，并且可以动态组 合。<br>
<br>
要自动生成静态页面，用Filter截获jsp请求并先进行预处理，自动生成Html，是个不错的主意。一个很容易想到的方法是在Filter截获Request后，导向一个Servlet，在这个Servlet中向本机发送一个http请求，然后将响应写入一个文件：<br>
<br>
URLConnection urlConn = URLConnection.open(http://localhost/req); <br>
<br>
注意要避免递归。<br>
<br>
另一个方法是不模拟http，而是定制Response，把<a class="UBBWordLink" href="http://idc.zmke.com/" target="_blank">服务器</a>返回的JSP响应输出到我们自己的Response中，就可以将响应快速写入Html文件，然后再发送给客户。而且，由于没有http模拟请求，直接读取<a class="UBBWordLink" href="http://idc.zmke.com/" target="_blank">服务器</a>响应速度非常快。<br>
<br>
截获Response的关键便是实现一个WrappedResponse，让<a class="UBBWordLink" href="http://idc.zmke.com/" target="_blank">服务器</a>将响应写入我们的WrappedResponse中。这类似于一个代理模式，Servlet 2.x已经提供了一个WrappedResponse类，我们只需要复写其中的一些关键方法即可。<br>
<br>
WrappedResponse实现了Response接口，它需要一个Response作为构造函数的参数，事实上这正是代理模式的应 用：WrappedResponse充当了代理角色，它会将JSP/Servlet容器的某些方法调用进行预处理，我们需要实现自己的方法。<br>
<br>
综上：用Filter实现HTML缓冲的步骤是：<br>
<br>
1. 用Filter截获请求，如/a.jsp?id=123，映射到对应的html文件名为/html/a.jsp$id=123.htm。<br>
2. 查找是否有/html/a.jsp$id=123.htm，如果有，直接forward到此html，结束。<br>
3. 如果没有，实现一个WrappedResponse，然后调用filterChain(request, wrappedResponse)。<br>
4. 将返回的WrappedResponse写入文件/html/a.jsp$id=123.htm，然后返回响应给用户。<br>
5. 下一次用户发送相同的请求时，到第2步就结束了。 <br>
<br>
使用这个方法的好处是不用更改现有的Servlet，JSP页，限制是，JSP页面结果不能与Session相关，需要登陆或用户定制的页面不能用这种方法缓冲。 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/injava/blog/category/J2ee">J2ee</a>&nbsp;<a href="http://hi.baidu.com/injava/blog/item/7782640eaca872c07acbe163.html#comment">查看评论</a>]]></description>
        <pubDate>2009-11-11  16:46</pubDate>
        <category><![CDATA[J2ee]]></category>
        <author><![CDATA[macaque1101]]></author>
		<guid>http://hi.baidu.com/injava/blog/item/7782640eaca872c07acbe163.html</guid>
</item>

<item>
        <title><![CDATA[增加javascript的trim函数]]></title>
        <link><![CDATA[http://hi.baidu.com/injava/blog/item/4b626b1ee797adfe1ad57653.html]]></link>
        <description><![CDATA[
		
		去除字符串左右两端的空格，在vbscript里面可以轻松地使用 trim、ltrim 或 rtrim，但在js中却没有这3个内置方法，需要手工编写。下面的实现方法是用到了正则表达式，效率不错，并把这三个方法加入String对象的内置方法中去。<br>
写成类的方法格式如下：（str.trim();）<br>
&lt;script language=&quot;javascript&quot;&gt;<br>
String.prototype.trim=function(){<br>
return this.replace(/(^\s*)|(\s*$)/g, &quot;&quot;);<br>
}<br>
String.prototype.ltrim=function(){<br>
return this.replace(/(^\s*)/g,&quot;&quot;);<br>
}<br>
String.prototype.rtrim=function(){<br>
return this.replace(/(\s*$)/g,&quot;&quot;);<br>
}<br>
&lt;/script&gt;<br>
写成函数可以这样：(trim(str))<br>
&lt;script type=&quot;text/javascript&quot;&gt;<br>
function trim(str){ //删除左右两端的空格<br>
return str.replace(/(^\s*)|(\s*$)/g, &quot;&quot;);<br>
}<br>
function ltrim(str){ //删除左边的空格<br>
return str.replace(/(^\s*)/g,&quot;&quot;);<br>
}<br>
function rtrim(str){ //删除右边的空格<br>
return str.replace(/(\s*$)/g,&quot;&quot;);<br>
}<br>
&lt;/script&gt; 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/injava/blog/category/ajax%2Bjs%2Bflex%2Bas3">ajax+js+flex+as3</a>&nbsp;<a href="http://hi.baidu.com/injava/blog/item/4b626b1ee797adfe1ad57653.html#comment">查看评论</a>]]></description>
        <pubDate>2009-11-10  23:31</pubDate>
        <category><![CDATA[ajax+js+flex+as3]]></category>
        <author><![CDATA[macaque1101]]></author>
		<guid>http://hi.baidu.com/injava/blog/item/4b626b1ee797adfe1ad57653.html</guid>
</item>


</channel>
</rss>