﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>IT博客-学而不思则罔，思而不学则殆-随笔分类-集群,分布式,并行</title><link>http://www.cnitblog.com/schkui/category/4310.html</link><description>有其事必有其理，
有其理必有其事 </description><language>zh-cn</language><lastBuildDate>Mon, 22 Apr 2013 10:39:28 GMT</lastBuildDate><pubDate>Mon, 22 Apr 2013 10:39:28 GMT</pubDate><ttl>60</ttl><item><title>[转]NoSQL数据库笔谈</title><link>http://www.cnitblog.com/schkui/archive/2013/04/20/87327.html</link><dc:creator>易道</dc:creator><author>易道</author><pubDate>Sat, 20 Apr 2013 12:30:00 GMT</pubDate><guid>http://www.cnitblog.com/schkui/archive/2013/04/20/87327.html</guid><wfw:comment>http://www.cnitblog.com/schkui/comments/87327.html</wfw:comment><comments>http://www.cnitblog.com/schkui/archive/2013/04/20/87327.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/schkui/comments/commentRss/87327.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/schkui/services/trackbacks/87327.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: databases , appdir , node , paper颜开 , v0.2 , 2010.2 序思想篇 CAP最终一致性 变体 BASE其他 I/O的五分钟法则不要删除数据RAM是硬盘,硬盘是磁带Amdahl定律和Gustafson定律万兆以太网 手段篇 一致性哈希 亚马逊的现状算法的选择 Quorum NRWVector clockVirtual nod...&nbsp;&nbsp;<a href='http://www.cnitblog.com/schkui/archive/2013/04/20/87327.html'>阅读全文</a><img src ="http://www.cnitblog.com/schkui/aggbug/87327.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/schkui/" target="_blank">易道</a> 2013-04-20 20:30 <a href="http://www.cnitblog.com/schkui/archive/2013/04/20/87327.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Centos4.3   安装DR模式Lvs集群</title><link>http://www.cnitblog.com/schkui/archive/2007/05/16/27065.html</link><dc:creator>易道</dc:creator><author>易道</author><pubDate>Wed, 16 May 2007 06:14:00 GMT</pubDate><guid>http://www.cnitblog.com/schkui/archive/2007/05/16/27065.html</guid><wfw:comment>http://www.cnitblog.com/schkui/comments/27065.html</wfw:comment><comments>http://www.cnitblog.com/schkui/archive/2007/05/16/27065.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/schkui/comments/commentRss/27065.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/schkui/services/trackbacks/27065.html</trackback:ping><description><![CDATA[<p>Centos4.3&nbsp;&nbsp;&nbsp;安装DR模式Lvs集群</p>
<p>&nbsp;</p>
<p>1. 环境描述：本文在配置LVS时使用三台linux
(Centos)，一台做Directorserver(192.168.200.72)&nbsp;,两台做 realserver(192.168.200.70 , 192.168.200.71)
,对外虚拟VIP:192.168.200.73&nbsp;</p>
<p>&nbsp;</p>
<p>2.&nbsp; 软件列表：2.6内核已经集成IPVS内核补订了，所以不再需要重新编译内核.</p>
<p>&nbsp;</p>
<p>3.&nbsp; DS安装lvs的管理软件 ipvsadm&nbsp; </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 利用centos的yum命令，
能自动的从他的镜像网站搜索软件，下载并安装。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; yum
install ipvsadm</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Setting up Install Process</p>
<p>Setting up repositories</p>
<p>update&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100%
|=========================|&nbsp; 951 B&nbsp;&nbsp;&nbsp; 00:00&nbsp;&nbsp;&nbsp;&nbsp;
</p>
<p>base&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100%
|=========================| 1.1 kB&nbsp;&nbsp;&nbsp;
00:00&nbsp; &nbsp;&nbsp;&nbsp;</p>
<p>addons&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100%
|=========================|&nbsp; 951 B&nbsp;&nbsp;&nbsp; 00:00&nbsp;&nbsp;&nbsp;&nbsp;
</p>
<p>extras&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100%
|=========================| 1.1 kB&nbsp;&nbsp;&nbsp;
00:00&nbsp;&nbsp;&nbsp;&nbsp; </p>
<p>Reading repository metadata in from local
files</p>
<p>Parsing package install arguments</p>
<p>Resolving Dependencies</p>
<p>--&gt; Populating transaction set with
selected packages. Please wait.</p>
<p>---&gt; Downloading header for ipvsadm to
pack into transaction set.</p>
<p>ipvsadm-1.24-6.i386.rpm&nbsp;&nbsp; 100% |=========================| 5.8 kB&nbsp;&nbsp;&nbsp; 00:00&nbsp;&nbsp;&nbsp;&nbsp;
</p>
<p>---&gt; Package ipvsadm.i386 0:1.24-6 set to
be updated</p>
<p>--&gt; Running transaction check</p>
<p>Dependencies Resolved</p>
<p>=============================================================================</p>
<p>&nbsp;Package&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Arch&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Version&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Repository&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Size </p>
<p>=============================================================================</p>
<p>Installing:</p>
<p>&nbsp;ipvsadm&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i386&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.24-6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; extras&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 30 k</p>
<p>Transaction Summary</p>
<p>=============================================================================</p>
<p>Install&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
1 Package(s)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
<p>Update&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
0 Package(s)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
<p>Remove&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
0 Package(s)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
<p>Total download size: 30 k</p>
<p>Is this ok [y/N]:<strong> y&nbsp; </strong><strong>选择</strong><strong> Y</strong></p>
<p>Downloading Packages:</p>
<p>(1/1): ipvsadm-1.24-6.i38 100%
|=========================|&nbsp; 30 kB&nbsp;&nbsp;&nbsp; 00:01&nbsp;&nbsp;&nbsp;&nbsp;
</p>
<p>Running Transaction Test</p>
<p>Finished Transaction Test</p>
<p>Transaction Test Succeeded</p>
<p>Running Transaction</p>
<p>&nbsp;
Installing: ipvsadm&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
######################### [1/1] </p>
<p>Installed: ipvsadm.i386 0:1.24-6 </p>
<p>&nbsp;</p>
<p><!--[if !supportLists]-->4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<!--[endif]-->前端调度器
在 DR 模式下的配置脚本</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #/bin/sh</p>
<p>#file: config_vs.sh 这里默认使用网卡eth0,如果想用其它网卡请自行替换即可。</p>
<p>VIP=192.168.200.73 &nbsp;&nbsp;#DR的虚拟服务IP</p>
<p>DIP=192.168.200.72&nbsp; &nbsp;#DR的eth0真实地址</p>
<p>RS1=192.168.200.71 &nbsp;&nbsp;#real server1的真实地址</p>
<p>RS2=192.168.200.70&nbsp; &nbsp;#real
server2的真实地址</p>
<p>GW=192.168.200.1&nbsp;&nbsp; &nbsp;#DR使用的网关或路由的地址</p>
<p>SERVICE=80&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;#web服务的端口</p>
<p>SERVICE_UDP= 800&nbsp;&nbsp;&nbsp; #UDP 服务程序的端口</p>
<p>&nbsp;</p>
<p>cat /proc/sys/net/ipv4/ip_forward &nbsp;&nbsp;#脚本调试信息</p>
<p>echo "1"
&gt;/proc/sys/net/ipv4/ip_forward</p>
<p>echo "1"
&gt;/proc/sys/net/ipv4/conf/all/send_redirects &nbsp;&nbsp;</p>
<p>cat
/proc/sys/net/ipv4/conf/all/send_redirects &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#脚本调试信息</p>
<p>echo "1"
&gt;/proc/sys/net/ipv4/conf/default/send_redirects</p>
<p>cat
/proc/sys/net/ipv4/conf/default/send_redirects&nbsp;&nbsp;&nbsp;&nbsp; #脚本调试信息</p>
<p>echo "1"
&gt;/proc/sys/net/ipv4/conf/eth0/send_redirects</p>
<p>cat
/proc/sys/net/ipv4/conf/eth0/send_redirects &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#脚本调试信息</p>
<p>&nbsp;</p>
<p>/sbin/ifconfig eth0 ${DIP} &nbsp;&nbsp;&nbsp;&nbsp;#配置所使用的网卡IP</p>
<p>#配置虚拟服务IP</p>
<p>/sbin/ifconfig eth0:0 ${VIP} broadcast
${VIP} netmask 255.255.255.255</p>
<p>/sbin/route add -host ${VIP} dev eth0:0 &nbsp;&nbsp;#添加虚拟IP的路由</p>
<p>/sbin/route add default gw ${GW} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#添加本地路由</p>
<p>/sbin/ifconfig eth0:0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;#脚本调试信息, 显示虚拟IP配置</p>
<p>#/bin/ping -b ${VIP}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;#脚本调试信息, 看看虚拟IP是否可以ping通</p>
<p>/sbin/route -n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#脚本调试信息,显示路由信息</p>
<p>&nbsp;</p>
<p>/sbin/ipvsadm &#8211;C &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#清除虚拟服务器表,也就是清除IPVS的原配置</p>
<p>#添加服务及轮调调度算法,-t:tcp服务,-A:添加服务; -s rr:指定调度算法为轮调</p>
<p>/sbin/ipvsadm -A -t ${VIP}:${SERVICE} -s rr&nbsp; -p 600</p>
<p>#添加real
server, -a:添加一台RS, -t:tcp服务,-r: RS的地址,-g:直接路由模式。</p>
<p>#这里语句个数随real
server的个数而定</p>
<p>/sbin/ipvsadm -a -t ${VIP}:${SERVICE} -r
${RS1} -g </p>
<p>/sbin/ipvsadm -a -t ${VIP}:${SERVICE} -r
${RS2} &#8211;g</p>
<p>&nbsp;</p>
<p>/sbin/ipvsadm -A &#8211;u &nbsp;${VIP}:${ SERVICE_UDP } -s rr &nbsp;&#8211;p 600</p>
<p>/sbin/ipvsadm -a &#8211;u&nbsp; ${VIP}:${ SERVICE_UDP } -r ${RS1} -g </p>
<p>/sbin/ipvsadm -a &#8211;u&nbsp;&nbsp; ${VIP}:${ SERVICE_UDP } -r ${RS2} &#8211;g</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>ping -c 1 ${RS1} &nbsp;&nbsp;&nbsp;#脚本调试信息</p>
<p>ping -c 1 ${RS2}&nbsp;&nbsp; &nbsp;#脚本调试信息</p>
<p>/sbin/ipvsadm &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#脚本调试信息</p>
<p>#end of config_vs.sh</p>
<p>&nbsp;</p>
<p><!--[if !supportLists]-->5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<!--[endif]-->后台节点
在 DR 模式下的配置脚本</p>
<p>&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #/bin/sh</p>
<p>#file: config_rs.sh这里默认使用网卡eth0,如果想用其它网卡请自行替换即可。</p>
<p>VIP=192.168.200.73 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#DR的虚拟服务IP</p>
<p>#DR的eth0真实地址，作用是在配置时测试DR的IP是否有效。但是DR切换后，DIP变了，所以这项取消了。</p>
<p>LOCALIP=192.168.200.71 &nbsp;#real server1的真实地址</p>
<p>GW=192.168.200.1 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#real server使用的网关或路由的地址</p>
<p>/sbin/ifconfig eth0 ${LOCALIP} #配置eth0的本地IP</p>
<p>/sbin/route add default gw ${GW} #添加默认路由</p>
<p>/bin/netstat -rn #脚本调试信息</p>
<p>ping -c 1 ${GW} #脚本调试信息,是否可以ping通网关</p>
<p>echo "0"
&gt;/proc/sys/net/ipv4/ip_forward</p>
<p>cat /proc/sys/net/ipv4/ip_forward #脚本调试信息,ip_forward是否配置正确</p>
<p>ping -c 1 ${DIP} #脚本调试信息, 是否可以ping通DR的真实地址</p>
<p>ping &#8211;c 1 ${VIP} #是否可以ping通虚拟DR的IP</p>
<p>#按照real
server的虚拟IP</p>
<p>/sbin/ifconfig lo:0 ${VIP} broadcast ${VIP}
netmask 0xffffffff up</p>
<p>#配置出口</p>
<p>/sbin/ifconfig lo:0</p>
<p>#在lo:0上添加去虚拟IP的路由</p>
<p>/sbin/route add -host ${VIP} dev lo:0</p>
<p>/bin/netstat -rn #脚本调试信息</p>
<p>#使realserver不响应arp请求，</p>
<p>echo&nbsp;"1"&nbsp;&gt;/proc/sys/net/ipv4/conf/lo/arp_ignore
<br>
echo&nbsp;"2"&nbsp;&gt;/proc/sys/net/ipv4/conf/lo/arp_announce <br>
echo&nbsp;"1"&nbsp;&gt;/proc/sys/net/ipv4/conf/all/arp_ignore <br>
echo&nbsp;"2"&nbsp;&gt;/proc/sys/net/ipv4/conf/all/arp_announce&nbsp;
<br>
sysctl&nbsp;-p </p>
<p>#end of config_rs.sh</p>
<p>&nbsp;</p>
<p>6&nbsp;&nbsp; 测试：分别启动realserver上的httpd服务 <br>
在realserver1&nbsp;执行&nbsp;&nbsp;echo&nbsp;"This&nbsp;is&nbsp;realserver1"&nbsp;&nbsp;/var/www/html/index.html
<br>
在realserver2&nbsp;执行&nbsp;&nbsp;echo&nbsp;"This&nbsp;is&nbsp;realserver2"&nbsp;&nbsp;/var/www/html/index.html
<br>
<br>
打开IE浏览器输入http://192.168.200.73&nbsp;应该可以分别看到:This&nbsp;is&nbsp;realserver1&nbsp;和&nbsp;This&nbsp;is&nbsp;realserver1.</p>
<br> <img src ="http://www.cnitblog.com/schkui/aggbug/27065.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/schkui/" target="_blank">易道</a> 2007-05-16 14:14 <a href="http://www.cnitblog.com/schkui/archive/2007/05/16/27065.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>LVS DR  Udp</title><link>http://www.cnitblog.com/schkui/archive/2007/05/16/27059.html</link><dc:creator>易道</dc:creator><author>易道</author><pubDate>Wed, 16 May 2007 03:51:00 GMT</pubDate><guid>http://www.cnitblog.com/schkui/archive/2007/05/16/27059.html</guid><wfw:comment>http://www.cnitblog.com/schkui/comments/27059.html</wfw:comment><comments>http://www.cnitblog.com/schkui/archive/2007/05/16/27059.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/schkui/comments/commentRss/27059.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/schkui/services/trackbacks/27059.html</trackback:ping><description><![CDATA[<h1 class="title">
<div class="content">
<p>http://zh.linuxvirtualserver.org/node/551<br></p>
<p>在LVS/DR下real ser上的udp程序回复udp包的源地址是real ser的真是IP，为什么不是vip？<br></p>
<p>我找到简单的方法了,就是在服务端的程序绑定上vip, 就可以了.. 呵呵</p>
<p>看看 LVS-DR UDP Service probem<br>http://archive.linuxvirtualserver.org/html/lvs-users/2004-08/msg00112.html</p>
</div>
<br></h1>
<br><img src ="http://www.cnitblog.com/schkui/aggbug/27059.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/schkui/" target="_blank">易道</a> 2007-05-16 11:51 <a href="http://www.cnitblog.com/schkui/archive/2007/05/16/27059.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转  Linux Enterprise Cluster选译</title><link>http://www.cnitblog.com/schkui/archive/2007/04/24/26114.html</link><dc:creator>易道</dc:creator><author>易道</author><pubDate>Tue, 24 Apr 2007 08:42:00 GMT</pubDate><guid>http://www.cnitblog.com/schkui/archive/2007/04/24/26114.html</guid><wfw:comment>http://www.cnitblog.com/schkui/comments/26114.html</wfw:comment><comments>http://www.cnitblog.com/schkui/archive/2007/04/24/26114.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/schkui/comments/commentRss/26114.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/schkui/services/trackbacks/26114.html</trackback:ping><description><![CDATA[<h4 style="margin-bottom: 0px;" class="TextColor1" id="subjcns!153C2D72AF27EB1C!723">Linux Enterprise Cluster选译</h4>
http://aoqingy.spaces.live.com/<br><br>
<div id="msgcns!153C2D72AF27EB1C!723" class="bvMsg">
<div>
<p>高有效性系统没有单故障点。所谓的单故障点是指某个系统构件，它的故障会导致整个系统瘫痪。
</p>
<p>Heartbeat的工作原理是：你告诉Heartbeat哪台计算机（即主服务器，primary
server）拥有特定资源，另一台计算机将自动成为备份服务器（backup
server）。然后配置运行在备份服务器上的Heartbeat进程，让它监听来自主服务器的&#8220;心博&#8221;。如果备份服务器没有听到主服务器的心博，就启动
失败接管，即接管资源的所有权。
</p>
<p>运行在备份服务器上的Heartbeat程序可以通过正常的以太网连接检查来自主服务器的心博。但是通常在两台服务器之间将Heartbeat配置成工作于独立的物理连接。这个独立的物理连接可以是串口线，或者另一个以太网连接（通过交叉线或者集线器）。
</p>
<p>Heartbeat可以使用一个或多个这样的物理连接。只要有任何一个物理连接上接收到心博，就认为主节点是活动的。高有效性的最佳实践表明应该在多个相互独立的通信路径上传送心博，这有助于防止通信路径成为单故障点。
</p>
<ul>
    <li>串口连接要比以太网连接更加安全，但是，串口线非常短，两台服务器必须靠得很近，常常放在同一个计算机间。
    </li>
    <li>使用一个新的以太网络（或以太交叉线）消除了服务器之间的距离限制。事实上，交叉线要比小型集线器更简便，也更可靠，因为前者不需要外部电源。</li>
</ul>
<p>使用两个物理路径连接主服务器和备份服务器提供了heartbeat控制信息的冗余度，这是非单故障点配置的需要。服务器之间使用的两个物理路径并不需要是同一种类型，在一种配置中可以将以太网连接和串口线连接放在一起使用。
</p>
<p>两个物理连接可以防止由于网络或连接线故障导致的情形，这时两个节点都试图拥有同一资源的所有权。这种情况被称为裂脑（split-brain）。为了避免裂脑，通常采取下面的预防措施：
</p>
<ul>
    <li>在heartbeat节点之间采用冗余、可靠的物理连接（最好同时使用串口线连接和以太网连接）以传送心博控制消息。
    </li>
    <li>第二种措施被称为&#8220;shoot the other node in the head&#8221;，缩写为STONITH。使用特别的硬件设备可以通过（串口线或网线发送）软件命令切断节点电源。</li>
</ul>
<p>通常来说，客户机知道提供它们所需资源的服务器的名字（例如mail.mydomain.com或<a href="http://www.mydomain.com/">www.mydomain.com</a>），它们使用域名系统（DNS）来查询服务器的IP地址。在Internet或WAN上路由报文时，IP地址被转换为物理网卡地址，即Media Access Control（MAC）地址。
</p>
<p>这时，路由器或本地连接的客户机使用地址解析协议（ARP）发出询问：&#8220;Who owns this IP
address?&#8221;。在接收到使用这个IP地址的计算机的响应后，路由器或本地计算机将IP地址和对应的MAC地址加到内存中所谓的ARP表中，这样就无
须在每次用到这个IP地址时进行询问。一段时间后，大多数计算机都会让未用到的ARP表项过期，保证内存中没有保存未使用（或不精确）的地址。
</p>
<p>为了将资源（服务、进程以及相关的IP地址）从一台计算机迁移到另一台计算机，我们需要将IP地址从主服务器迁移到备份服务器。
</p>
<p>Heartbeat常使用的方法被称为IP地址接管（有时记为IPAT）。为了实现IPAT，Heartbeat用到从IP地址（在旧版本的Linux内核中称为IP别名）和Gratuitous ARP广播。
</p>
<p>前面已经提到，客户机通常使用地址解析协议（ARP）来确认哪个硬件地址拥有特定IP地址，并保存在ARP表中。在主服务器故障时，
Heartbeat程序使用一点小窍门，称为无故ARP（Gratuitous
ARP，GARP）广播，来强制修改这些客户机的ARP表，替换成新的硬件（MAC）地址，从而使客户机能够和备份服务器进行会话。
</p>
<p>GARP广播是sneaky ARP广播(broadcasts, remember, are only seen by
locally connected nodes)。GARP广播询问每个连接在网络上的节点，&#8220;Who owns this IP
address?&#8221;。实际上，这时的ARP请求报文头中的源（回复）IP地址等于要请求的IP地址。这样强制连接到网络的所有节点将ARP表项更换成新的
源地址。
</p>
<p>在Heartbeat控制之下的所有脚本称为资源脚本。Heartbeat应该总是可以向资源脚本传递start和stop参数来启动和
停止资源。Heartbeat还应该了解哪台计算机拥有资源。如果计算机拥有资源，则以status参数运行脚本时，返回OK、Running或
running；否则可以返回DOWN或STOPPED。
</p>
<p>Stonith，或者称为&#8220;shoot the other node in the
head&#8221;，（在某些其它的高有效性解决方案中，将这称为Stomith，或者是&#8220;shoot the other machine in the
head&#8221;。）是Heartbeat包的一个组件，允许系统用连接到健在服务器的一个远程或&#8220;智能&#8221;电源设备自动复位故障服务器的电源。Stonith设
备可以响应软件命令，切断服务器的电源。在高有效性系统中的一个服务器通过串口线或网线连接到这种设备，服务器上运行Heartbeat，可以控制另一台
服务器的电源供应。换句话说，主服务器可以复位备份服务器的电源，备份服务器也可以复位主服务器的电源。通过复位电源强制让主服务器重启是一种残酷的手
段，但确实是避免裂脑的最安全方式。
</p>
<p>Stonith时间发生在备份服务器没有接收到心博信号时：
</p>
<ul>
    <li>备份服务器发送一个Stonith复位命令到Stonith设备。
    </li>
    <li>Stonith设备切断主服务器的电源供应。
    </li>
    <li>一旦主服务器的电源被切断，它就不再能够访问集群资源，也不能透过网络向客户机提供资源。这保证客户机不能访问主服务器上的资源，从而消除了裂脑的可能性。
    </li>
    <li>备份服务器然后获取主服务器的资源。Heartbeat带start参数运行合适的资源脚本，同时进行Gratuitous ARP广播，这样客户机客户机开始将请求发送到备份服务器的网络接口卡。
    </li>
    <li>一旦主服务器完成重启，它将尝试要求备份服务器放弃资源的所有权，重新收回它们，除非两个服务器都禁用了auto_failback功能。</li>
</ul>
<p>即使做了这么多工作，我们还没有完全消除两台服务器的Heartbeat设计中的单故障点。例如，如果只是主服务器失去了和客户机在生成网络上的连接呢？
</p>
<p>这时，即便Heartbeat配置一切完好，心博信号会继续传送到备份服务器，不需要发生失败接管。然后，客户机确无法访问主服务器上的资源进程（集群资源）。
</p>
<p>我们可以用两种方式来解决这个问题：
</p>
<ul>
    <li>在主服务器上运行一个外部的监视包，例如Perl程序Mon，并观察公共NIC上的故障情况。如果检测到这个NIC的故障，它应该杀死主服务器上的Heartbeat进程（或者强制让服务器转入standby模式）。备份服务器然后会接管资源。
    </li>
    <li>使用ipfail
    API插件，该插件在Heartbeat配置文件中指定一个或多个ping服务器。如果主服务器突然无法ping通其中的一个服务器，它就问备份服务器：
    &#8220;Did you see that ping server go down
    too?&#8221;如果备份服务器还能够ping到这个服务器，则备份服务器知道主服务器的网络通信不正常了，它就应该接管资源的所有权。</li>
</ul>
</div>
</div>
<br><img src ="http://www.cnitblog.com/schkui/aggbug/26114.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/schkui/" target="_blank">易道</a> 2007-04-24 16:42 <a href="http://www.cnitblog.com/schkui/archive/2007/04/24/26114.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> 负载均衡技术全攻略(转)</title><link>http://www.cnitblog.com/schkui/archive/2006/12/08/20230.html</link><dc:creator>易道</dc:creator><author>易道</author><pubDate>Fri, 08 Dec 2006 09:36:00 GMT</pubDate><guid>http://www.cnitblog.com/schkui/archive/2006/12/08/20230.html</guid><wfw:comment>http://www.cnitblog.com/schkui/comments/20230.html</wfw:comment><comments>http://www.cnitblog.com/schkui/archive/2006/12/08/20230.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/schkui/comments/commentRss/20230.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/schkui/services/trackbacks/20230.html</trackback:ping><description><![CDATA[nternet的规模每一百天就会增长一倍，客户希望获得7天24小时的不间断可用性及较快的系统反应时间，而不愿屡次看到某个站点“Server Too Busy”及频繁的系统故障。<p>　
　网络的各个核心部分随着业务量的提高、访问量和数据流量的快速增长，其处理能力和计算强度也相应增大，使得单一设备根本无法承担。在此情况下，如果扔掉
现有设备去做大量的硬件升级，这样将造成现有资源的浪费，而且如果再面临下一次业务量的提升，这又将导致再一次硬件升级的高额成本投入，甚至性能再卓越的
设备也不能满足当前业务量的需求。于是，负载均衡机制应运而生。</p><p>　　负载均衡（Load Balance）建立在现有网络结构之上，它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。</p><p>　　负载均衡有两方面的含义：首先，大量的并发访问或数据流量分担到多台节点设备上分别处理，减少用户等待响应的时间；其次，单个重负载的运算分担到多台节点设备上做并行处理，每个节点设备处理结束后，将结果汇总，返回给用户，系统处理能力得到大幅度提高。</p><p>　　本文所要介绍的负载均衡技术主要是指在均衡服务器群中所有服务器和应用程序之间流量负载的应用，目前负载均衡技术大多数是用于提高诸如在Web服务器、FTP服务器和其它关键任务服务器上的Internet服务器程序的可用性和可伸缩性。 </p><p>负载均衡技术分类 </p><p>　　目前有许多不同的负载均衡技术用以满足不同的应用需求，下面从负载均衡所采用的设备对象、应用的网络层次（指OSI参考模型）及应用的地理结构等来分类。</p><p>软/硬件负载均衡 <br />　
　软件负载均衡解决方案是指在一台或多台服务器相应的操作系统上安装一个或多个附加软件来实现负载均衡，如DNS Load
Balance，CheckPoint Firewall-1
ConnectControl等，它的优点是基于特定环境，配置简单，使用灵活，成本低廉，可以满足一般的负载均衡需求。</p><p>　　软件解决方案
缺点也较多，因为每台服务器上安装额外的软件运行会消耗系统不定量的资源，越是功能强大的模块，消耗得越多，所以当连接请求特别大的时候，软件本身会成为
服务器工作成败的一个关键；软件可扩展性并不是很好，受到操作系统的限制；由于操作系统本身的Bug，往往会引起安全问题。</p><p>　　硬件负载均衡解决方案是直接在服务器和外部网络间安装负载均衡设备，这种设备我们通常称之为负载均衡器，由于专门的设备完成专门的任务，独立于操作系统，整体性能得到大量提高，加上多样化的负载均衡策略，智能化的流量管理，可达到最佳的负载均衡需求。</p><p>　　负载均衡器有多种多样的形式，除了作为独立意义上的负载均衡器外，有些负载均衡器集成在交换设备中，置于服务器与Internet链接之间，有些则以两块网络适配器将这一功能集成到PC中，一块连接到Internet上，一块连接到后端服务器群的内部网络上。</p><p>　　一般而言，硬件负载均衡在功能、性能上优于软件方式，不过成本昂贵。 </p><p>本地/全局负载均衡<br />　
　负载均衡从其应用的地理结构上分为本地负载均衡(Local Load Balance)和全局负载均衡(Global Load
Balance，也叫地域负载均衡)，本地负载均衡是指对本地的服务器群做负载均衡，全局负载均衡是指对分别放置在不同的地理位置、有不同网络结构的服务
器群间作负载均衡。</p><p>　　本地负载均衡能有效地解决数据流量过大、网络负荷过重的问题，并且不需花费昂贵开支购置性能卓越的服务器，充分利用
现有设备，避免服务器单点故障造成数据流量的损失。其有灵活多样的均衡策略把数据流量合理地分配给服务器群内的服务器共同负担。即使是再给现有服务器扩充
升级，也只是简单地增加一个新的服务器到服务群中，而不需改变现有网络结构、停止现有的服务。</p><p>　　全局负载均衡主要用于在一个多区域拥有自己服务器的站点，为了使全球用户只以一个IP地址或域名就能访问到离自己最近的服务器，从而获得最快的访问速度，也可用于子公司分散站点分布广的大公司通过Intranet（企业内部互联网）来达到资源统一合理分配的目的。</p><p>　　全局负载均衡有以下的特点： </p><p>实现地理位置无关性，能够远距离为用户提供完全的透明服务。 <br />除了能避免服务器、数据中心等的单点失效，也能避免由于ISP专线故障引起的单点失效。 <br />解决网络拥塞问题，提高服务器响应速度，服务就近提供，达到更好的访问质量。 <br />网络层次上的负载均衡<br />　　针对网络上负载过重的不同瓶颈所在，从网络的不同层次入手，我们可以采用相应的负载均衡技术来解决现有问题。</p><p>　　随着带宽增加，数据流量不断增大，网络核心部分的数据接口将面临瓶颈问题，原有的单一线路将很难满足需求，而且线路的升级又过于昂贵甚至难以实现，这时就可以考虑采用链路聚合（Trunking）技术。</p><p>　　链路聚合技术（第二层负载均衡）将多条物理链路当作一条单一的聚合逻辑链路使用，网络数据流量由聚合逻辑链路中所有物理链路共同承担，由此在逻辑上增大了链路的容量，使其能满足带宽增加的需求。</p><p>　
　现代负载均衡技术通常操作于网络的第四层或第七层。第四层负载均衡将一个Internet上合法注册的IP地址映射为多个内部服务器的IP地址，对每次
TCP连接请求动态使用其中一个内部IP地址，达到负载均衡的目的。在第四层交换机中，此种均衡技术得到广泛的应用，一个目标地址是服务器群VIP（虚拟
IP，Virtual IP
address）连接请求的数据包流经交换机，交换机根据源端和目的IP地址、TCP或UDP端口号和一定的负载均衡策略，在服务器IP和VIP间进行映
射，选取服务器群中最好的服务器来处理连接请求。</p><p>　　第七层负载均衡控制应用层服务的内容，提供了一种对访问流量的高层控制方式，适合对HTTP服务器群的应用。第七层负载均衡技术通过检查流经的HTTP报头，根据报头内的信息来执行负载均衡任务。</p><p>　　第七层负载均衡优点表现在如下几个方面： </p><p>通过对HTTP报头的检查，可以检测出HTTP400、500和600系列的错误信息，因而能透明地将连接请求重新定向到另一台服务器，避免应用层故障。 <br />可根据流经的数据类型（如判断数据包是图像文件、压缩文件或多媒体文件格式等），把数据流量引向相应内容的服务器来处理，增加系统性能。 <br />能根据连接请求的类型，如是普通文本、图象等静态文档请求，还是asp、cgi等的动态文档请求，把相应的请求引向相应的服务器来处理，提高系统的性能及安全性。 <br />　　第七层负载均衡受到其所支持的协议限制（一般只有HTTP），这样就限制了它应用的广泛性，并且检查HTTP报头会占用大量的系统资源，势必会影响到系统的性能，在大量连接请求的情况下，负载均衡设备自身容易成为网络整体性能的瓶颈。</p><p>负载均衡策略 </p><p>　
　在实际应用中，我们可能不想仅仅是把客户端的服务请求平均地分配给内部服务器，而不管服务器是否宕机。而是想使Pentium
III服务器比Pentium
II能接受更多的服务请求，一台处理服务请求较少的服务器能分配到更多的服务请求，出现故障的服务器将不再接受服务请求直至故障恢复等等。</p><p>　　选择合适的负载均衡策略，使多个设备能很好的共同完成任务，消除或避免现有网络负载分布不均、数据流量拥挤反应时间长的瓶颈。在各负载均衡方式中，针对不同的应用需求，在OSI参考模型的第二、三、四、七层的负载均衡都有相应的负载均衡策略。 </p><p>　　负载均衡策略的优劣及其实现的难易程度有两个关键因素：一、负载均衡算法，二、对网络系统状况的检测方式和能力。</p><p>　　考虑到服务请求的不同类型、服务器的不同处理能力以及随机选择造成的负载分配不均匀等问题，为了更加合理的把负载分配给内部的多个服务器，就需要应用相应的能够正确反映各个服务器处理能力及网络状态的负载均衡算法：</p><p>轮循均衡（Round Robin）：每一次来自网络的请求轮流分配给内部中的服务器，从1至N然后重新开始。此种均衡算法适合于服务器组中的所有服务器都有相同的软硬件配置并且平均服务请求相对均衡的情况。 </p><p><br />权
重轮循均衡（Weighted Round
Robin）：根据服务器的不同处理能力，给每个服务器分配不同的权值，使其能够接受相应权值数的服务请求。例如：服务器A的权值被设计成1，B的权值是
3，C的权值是6，则服务器A、B、C将分别接受到10%、30％、60％的服务请求。此种均衡算法能确保高性能的服务器得到更多的使用率，避免低性能的
服务器负载过重。 </p><p><br />随机均衡（Random）：把来自网络的请求随机分配给内部中的多个服务器。 </p><p><br />权重随机均衡（Weighted Random）：此种均衡算法类似于权重轮循算法，不过在处理请求分担时是个随机选择的过程。 </p><p><br />响
应速度均衡（Response
Time）：负载均衡设备对内部各服务器发出一个探测请求（例如Ping），然后根据内部中各服务器对探测请求的最快响应时间来决定哪一台服务器来响应客
户端的服务请求。此种均衡算法能较好的反映服务器的当前运行状态，但这最快响应时间仅仅指的是负载均衡设备与服务器间的最快响应时间，而不是客户端与服务
器间的最快响应时间。</p><p><br />最少连接数均衡（Least
Connection）：客户端的每一次请求服务在服务器停留的时间可能会有较大的差异，随着工作时间加长，如果采用简单的轮循或随机均衡算法，每一台服
务器上的连接进程可能会产生极大的不同，并没有达到真正的负载均衡。最少连接数均衡算法对内部中需负载的每一台服务器都有一个数据记录，记录当前该服务器
正在处理的连接数量，当有新的服务连接请求时，将把当前请求分配给连接数最少的服务器，使均衡更加符合实际情况，负载更加均衡。此种均衡算法适合长时处理
的请求服务，如FTP。</p><p><br />处理能力均衡：此种均衡算法将把服务请求分配给内部中处理负荷（根据服务器CPU型号、CPU数量、内存大
小及当前连接数等换算而成）最轻的服务器，由于考虑到了内部服务器的处理能力及当前网络运行状况，所以此种均衡算法相对来说更加精确，尤其适合运用到第七
层（应用层）负载均衡的情况下。 </p><p><br />DNS响应均衡（Flash
DNS）：在Internet上，无论是HTTP、FTP或是其它的服务请求，客户端一般都是通过域名解析来找到服务器确切的IP地址的。在此均衡算法
下，分处在不同地理位置的负载均衡设备收到同一个客户端的域名解析请求，并在同一时间内把此域名解析成各自相对应服务器的IP地址（即与此负载均衡设备在
同一位地理位置的服务器的IP地址）并返回给客户端，则客户端将以最先收到的域名解析IP地址来继续请求服务，而忽略其它的IP地址响应。在种均衡策略适
合应用在全局负载均衡的情况下，对本地负载均衡是没有意义的。 </p><p>尽管有多种的负载均衡算法可以较好的把数据流量分配给服务器去负载，但如
果负载均衡策略没有对网络系统状况的检测方式和能力，一旦在某台服务器或某段负载均衡设备与服务器网络间出现故障的情况下，负载均衡设备依然把一部分数据
流量引向那台服务器，这势必造成大量的服务请求被丢失，达不到不间断可用性的要求。所以良好的负载均衡策略应有对网络故障、服务器系统故障、应用服务故障
的检测方式和能力：</p><p>Ping侦测：通过ping的方式检测服务器及网络系统状况，此种方式简单快速，但只能大致检测出网络及服务器上的操作系统是否正常，对服务器上的应用服务检测就无能为力了。 </p><p><br />TCP Open侦测：每个服务都会开放某个通过TCP连接，检测服务器上某个TCP端口（如Telnet的23口，HTTP的80口等）是否开放来判断服务是否正常。 </p><p><br />HTTP URL侦测：比如向HTTP服务器发出一个对main.html文件的访问请求，如果收到错误信息，则认为服务器出现故障。 <br />　
　负载均衡策略的优劣除受上面所讲的两个因素影响外，在有些应用情况下，我们需要将来自同一客户端的所有请求都分配给同一台服务器去负担，例如服务器将客
户端注册、购物等服务请求信息保存的本地数据库的情况下，把客户端的子请求分配给同一台服务器来处理就显的至关重要了。有两种方式可以解决此问题，一是根
据IP地址把来自同一客户端的多次请求分配给同一台服务器处理，客户端IP地址与服务器的对应信息是保存在负载均衡设备上的；二是在客户端浏览器
cookie内做独一无二的标识来把多次请求分配给同一台服务器处理，适合通过代理服务器上网的客户端。</p><p>　　还有一种路径外返回模式
（Out of Path
Return），当客户端连接请求发送给负载均衡设备的时候，中心负载均衡设备将请求引向某个服务器，服务器的回应请求不再返回给中心负载均衡设备，即绕
过流量分配器，直接返回给客户端，因此中心负载均衡设备只负责接受并转发请求，其网络负担就减少了很多，并且给客户端提供了更快的响应时间。此种模式一般
用于HTTP服务器群，在各服务器上要安装一块虚拟网络适配器，并将其IP地址设为服务器群的VIP，这样才能在服务器直接回应客户端请求时顺利的达成三
次握手。<br /><br /><br /><br />负载均衡实施要素 <br /><br />　　负载均衡方案应是在网站建设初期就应考虑的问题，不过有时随着访问流量
的爆炸性增长，超出决策者的意料，这也就成为不得不面对的问题。当我们在引入某种负载均衡方案乃至具体实施时，像其他的许多方案一样，首先是确定当前及将
来的应用需求，然后在代价与收效之间做出权衡。<br /><br />　　针对当前及将来的应用需求，分析网络瓶颈的不同所在，我们就需要确立是采用哪一类的负载均衡技术，采用什么样的均衡策略，在可用性、兼容性、安全性等等方面要满足多大的需求，如此等等。<br /><br />　　不管负载均衡方案是采用花费较少的软件方式，还是购买代价高昂在性能功能上更强的第四层交换机、负载均衡器等硬件方式来实现，亦或其他种类不同的均衡技术，下面这几项都是我们在引入均衡方案时可能要考虑的问题： <br /><br />性
能：性能是我们在引入均衡方案时需要重点考虑的问题，但也是一个最难把握的问题。衡量性能时可将每秒钟通过网络的数据包数目做为一个参数，另一个参数是均
衡方案中服务器群所能处理的最大并发连接数目，但是，假设一个均衡系统能处理百万计的并发连接数，可是却只能以每秒2个包的速率转发，这显然是没有任何作
用的。
性能的优劣与负载均衡设备的处理能力、采用的均衡策略息息相关，并且有两点需要注意：一、均衡方案对服务器群整体的性能，这是响应客户端连接请求速度的关
键；二、负载均衡设备自身的性能，避免有大量连接请求时自身性能不足而成为服务瓶颈。
有时我们也可以考虑采用混合型负载均衡策略来提升服务器群的总体性能，如DNS负载均衡与NAT负载均衡相结合。另外，针对有大量静态文档请求的站点，也
可以考虑采用高速缓存技术，相对来说更节省费用，更能提高响应性能；对有大量ssl/xml内容传输的站点，更应考虑采用ssl/xml加速技术。 <br /><br /><br />可
扩展性：IT技术日新月异，一年以前最新的产品，现在或许已是网络中性能最低的产品；业务量的急速上升，一年前的网络，现在需要新一轮的扩展。合适的均衡
解决方案应能满足这些需求，能均衡不同操作系统和硬件平台之间的负载，能均衡HTTP、邮件、新闻、代理、数据库、防火墙和
Cache等不同服务器的负载，并且能以对客户端完全透明的方式动态增加或删除某些资源。 <br /><br /><br />灵活性：均衡解决方案应能灵活地提供不同的应用需求，满足应用需求的不断变化。在不同的服务器群有不同的应用需求时，应有多样的均衡策略提供更广泛的选择。 <br /><br /><br />可
靠性：在对服务质量要求较高的站点，负载均衡解决方案应能为服务器群提供完全的容错性和高可用性。但在负载均衡设备自身出现故障时，应该有良好的冗余解决
方案，提高可靠性。使用冗余时，处于同一个冗余单元的多个负载均衡设备必须具有有效的方式以便互相进行监控，保护系统尽可能地避免遭受到重大故障的损失。
<br /><br /><br />易管理性：不管是通过软件还是硬件方式的均衡解决方案，我们都希望它有灵活、直观和安全的管理方式，这样便于安装、配置、维护和
监控，提高工作效率，避免差错。在硬件负载均衡设备上，目前主要有三种管理方式可供选择：一、命令行接口（CLI：Command Line
Interface），可通过超级终端连接负载均衡设备串行接口来管理，也能telnet远程登录管理，在初始化配置时，往往要用到前者；二、图形用户接
口（GUI：Graphical User Interfaces），有基于普通web页的管理，也有通过Java Applet
进行安全管理，一般都需要管理端安装有某个版本的浏览器；三、SNMP（Simple Network Management
Protocol，简单网络管理协议）支持，通过第三方网络管理软件对符合SNMP标准的设备进行管理。<br />负载均衡配置实例 <br /><br />DNS负载均衡 <br />　
　DNS负载均衡技术是在DNS服务器中为同一个主机名配置多个IP地址，在应答DNS查询时，DNS服务器对每个查询将以DNS文件中主机记录的IP地
址按顺序返回不同的解析结果，将客户端的访问引导到不同的机器上去，使得不同的客户端访问不同的服务器，从而达到负载均衡的目的。<br /><br />　　DNS负载均衡的优点是经济简单易行，并且服务器可以位于internet上任意的位置。但它也存在不少缺点： <br /><br />为了使本DNS服务器和其他DNS服务器及时交互，保证DNS数据及时更新，使地址能随机分配，一般都要将DNS的刷新时间设置的较小，但太小将会使DNS流量大增造成额外的网络问题。 <br /><br /><br />一旦某个服务器出现故障，即使及时修改了DNS设置，还是要等待足够的时间（刷新时间）才能发挥作用，在此期间，保存了故障服务器地址的客户计算机将不能正常访问服务器。 <br /><br /><br />DNS负载均衡采用的是简单的轮循负载算法，不能区分服务器的差异，不能反映服务器的当前运行状态，不能做到为性能较好的服务器多分配请求，甚至会出现客户请求集中在某一台服务器上的情况。 <br /><br /><br />要给每台服务器分配一个internet上的IP地址，这势必会占用过多的IP地址。 <br />　
　判断一个站点是否采用了DNS负载均衡的最简单方式就是连续的ping这个域名，如果多次解析返回的IP地址不相同的话，那么这个站点就很可能采用的就
是较为普遍的DNS负载均衡。但也不一定，因为如果采用的是DNS响应均衡，多次解析返回的IP地址也可能会不相同。不妨试试Ping一下
www.yesky.com，www.sohu.com，www.yahoo.com<br /><br />　　现假设有三台服务器来应对www.test.com的请求。在采用BIND 8.x DNS服务器的unix系统上实现起来比较简单，只需在该域的数据记录中添加类似下面的结果： <br /><br />　　www1 IN A 192.1.1.1 <br />　　www2 IN A 192.1.1.2 <br />　　www3 IN A 192.1.1.3 <br />　　www IN CNAME www1<br />　　www IN CNAME www2<br />　　www IN CNAME www3<br /><br />　　在NT下的实现也很简单，下面详细介绍在win2000 server下实现DNS负载均衡的过程，NT4.0类似：<br /><br />打开“管理工具”下的“DNS”，进入DNS服务配置控制台。 <br /><br /><br />打
开相应DNS
服务器的“属性”，在“高级”选项卡的“服务器选项”中，选中“启用循环”复选框。此步相当于在注册表记录HKEY_LOCAL_MACHINE\
SYSTEM\CurrentControlSet\Services\DNS\Parameters中添加一个双字节制值（dword值）
RoundRobin，值为1。 <br /><br /><br />打开正向搜索区域的相应区域（如test.com），新建主机添加主机 (A) 资源记录，记录如下： <br /><br />www IN A 192.1.1.1 <br />www IN A 192.1.1.2 <br />www IN A 192.1.1.3 <br /><br />在这里可以看到的区别是在NT下一个主机名对应多个IP地址记录，但在unix下，是先添加多个不同的主机名分别对应个自的IP地址，然后再把这些主机赋同一个别名（CNAME）来实现的。 <br /><br />在此需要注意的是，NT下本地子网优先级会取代多宿主名称的循环复用，所以在测试时，如果做测试用的客户机IP地址与主机资源记录的IP在同一有类掩码范围内，就需要清除在“高级”选项卡“服务器选项”中的“启用netmask排序”。 <br />NAT负载均衡<br />　
　NAT（Network Address Translation
网络地址转换）简单地说就是将一个IP地址转换为另一个IP地址，一般用于未经注册的内部地址与合法的、已获注册的Internet
IP地址间进行转换。适用于解决Internet
IP地址紧张、不想让网络外部知道内部网络结构等的场合下。每次NAT转换势必会增加NAT设备的开销，但这种额外的开销对于大多数网络来说都是微不足道
的，除非在高带宽有大量NAT请求的网络上。<br /><br />　　NAT负载均衡将一个外部IP地址映射为多个内部IP地址，对每次连接请求动态地转换为一个内部服务器的地址，将外部连接请求引到转换得到地址的那个服务器上，从而达到负载均衡的目的。<br /><br />　　NAT负载均衡是一种比较完善的负载均衡技术，起着NAT负载均衡功能的设备一般处于内部服务器到外部网间的网关位置，如路由器、防火墙、四层交换机、专用负载均衡器等，均衡算法也较灵活，如随机选择、最少连接数及响应时间等来分配负载。 <br /><br />　
　NAT负载均衡可以通过软硬件方式来实现。通过软件方式来实现NAT负载均衡的设备往往受到带宽及系统本身处理能力的限制，由于NAT比较接近网络的低
层，因此就可以将它集成在硬件设备中，通常这样的硬件设备是第四层交换机和专用负载均衡器，第四层交换机的一项重要功能就是NAT负载均衡。 <br /><br />　　下面以实例介绍一下Cisco路由器NAT负载均衡的配置： <br /><br />　
　现有一台有一个串行接口和一个Ethernet接口的路由器，Ethernet口连接到内部网络，内部网络上有三台web服务器，但都只是低端配置，为
了处理好来自Internet上大量的web连接请求，因此需要在此路由器上做NAT负载均衡配置，把发送到web服务器合法Internet
IP地址的报文转换成这三台服务器的内部本地地址。 其具体配置过程如下： <br /><br />做好路由器的基本配置，并定义各个接口在做NAT时是内部还是外部接口。 <br /><br />然后定义一个标准访问列表（standard access list），用来标识要转换的合法IP地址。 <br /><br />再定义NAT地址池来标识内部web服务器的本地地址，注意要用到关键字rotary，表明我们要使用轮循（Round Robin）的方式从NAT地址池中取出相应IP地址来转换合法IP报文。 <br /><br /><br />最后，把目标地址为访问表中IP的报文转换成地址池中定义的IP地址。 <br />　　相应配置文件如下：<br /><br />interface Ethernet0/0<br />ip address 192.168.1.4 255.255.255.248<br />ip nat inside<br />!<br />interface Serial0/0<br />ip address 200.200.1.1 255.255.255.248 <br />ip nat outside<br />! <br />ip access-list 1 permit 200.200.1.2<br />!<br />ip nat pool websrv 192.168.1.1 192.168.1.3 netmask 255.255.255.248 type rotary <br />ip nat inside destination list 1 pool websrv <br /><br /><br /><img alt="" src="http://bbs.gzec.com.cn/temp/qos1.jpg" border="0" /><br /><br /><br />反向代理负载均衡<br />　　普通代理方式是代理内部网络用户访问internet上服务器的连接请求，客户端必须指定代理服务器,并将本来要直接发送到internet上服务器的连接请求发送给代理服务器处理。<br /><br />　　反向代理（Reverse Proxy）方式是指以代理服务器来接受internet上的连接请求，然后将请求转发给内部网络上的服务器，并将从服务器上得到的结果返回给internet上请求连接的客户端，此时代理服务器对外就表现为一个服务器。<br /><br />　　反向代理负载均衡技术是把将来自internet上的连接请求以反向代理的方式动态地转发给内部网络上的多台服务器进行处理，从而达到负载均衡的目的。 <br /><br />　
　反向代理负载均衡能以软件方式来实现，如apache mod_proxy、netscape
proxy等，也可以在高速缓存器、负载均衡器等硬件设备上实现。
反向代理负载均衡可以将优化的负载均衡策略和代理服务器的高速缓存技术结合在一起，提升静态网页的访问速度，提供有益的性能；由于网络外部用户不能直接访
问真实的服务器，具备额外的安全性（同理，NAT负载均衡技术也有此优点）。<br /><br />　　其缺点主要表现在以下两个方面： <br /><br />反向代理是处于OSI参考模型第七层应用的，所以就必须为每一种应用服务专门开发一个反向代理服务器，这样就限制了反向代理负载均衡技术的应用范围，现在一般都用于对web服务器的负载均衡。 <br /><br />针对每一次代理，代理服务器就必须打开两个连接，一个对外，一个对内，因此在并发连接请求数量非常大的时候，代理服务器的负载也就非常大了，在最后代理服务器本身会成为服务的瓶颈。 <br />　　一般来讲，可以用它来对连接数量不是特别大，但每次连接都需要消耗大量处理资源的站点进行负载均衡，如search。 <br /><br />　
　下面以在apache
mod_proxy下做的反向代理负载均衡为配置实例：在站点www.test.com，我们按提供的内容进行分类，不同的服务器用于提供不同的内容服
务，将对http://www.test.com/news的访问转到IP地址为192.168.1.1的内部服务器上处理，对http:
//www.test.com/it的访问转到服务器192.168.1.2上，对http://www.test.com/life的访问转到服务器
192.168.1.3上，对http://www.test.com/love的访问转到合作站点http://www.love.com上，从而减轻
本apache服务器的负担，达到负载均衡的目的。<br /><br />　　首先要确定域名www.test.com在DNS上的记录对应apache服务器接口上具有internet合法注册的IP地址，这样才能使internet上对www.test.com的所有连接请求发送给本台apache服务器。<br /><br />　　在本台服务器的apache配置文件httpd.conf中添加如下设置： <br /><br />　　proxypass /news http://192.168.1.1 <br />　　proxypass /it http://192.168.1.2 <br />　　proxypass /life http://192.168.1.3 <br />　　proxypass /love http://www.love.com <br /><br />　　注意，此项设置最好添加在httpd.conf文件“Section 2”以后的位置，服务器192.168.1.1-3也应是具有相应功能的www服务器，在重启服务时，最好用apachectl configtest命令检查一下配置是否有误.<br /><br /><br />混合型负载均衡<br />　
　在有些大型网络，由于多个服务器群内硬件设备、各自的规模、提供的服务等的差异，我们可以考虑给每个服务器群采用最合适的负载均衡方式，然后又在这多个
服务器群间再一次负载均衡或群集起来以一个整体向外界提供服务（即把这多个服务器群当做一个新的服务器群），从而达到最佳的性能。我们将这种方式称之为混
合型负载均衡。此种方式有时也用于单台均衡设备的性能不能满足大量连接请求的情况下。 <br /><br />　　下图展示了一个应用示例，三个服务器群针对各自的特点，分别采用了不同的负载均衡方式。当客户端发出域名解析请求时，DNS服务器依次把它解析成三个服务器群的VIP，如此把客户端的连接请求分别引向三个服务器群，从而达到了再一次负载均衡的目的。<br /><br />　　在图中大家可能注意到，负载均衡设备在网络拓朴上，可以处于外部网和内部网络间网关的位置，也可以和内部服务器群处于并行的位置，甚至可以处于内部网络或internet上的任意位置，特别是在采用群集负载均衡时，根本就没有单独的负载均衡设备。 <br /><br />　　服务器群内各服务器只有提供相同内容的服务才有负载均衡的意义，特别是在DNS负载均衡时。要不然，这样会造成大量连接请求的丢失或由于多次返回内容的不同给客户造成混乱。<br /><br />　　所以，如图的这个示例在实际中可能没有多大的意义，因为如此大的服务内容相同但各服务器群存在大量差异的网站并不多见。 但做为一个示例，相信还是很有参考意义的.<br /><br /><br /><img alt="" src="http://bbs.gzec.com.cn/temp/qos2.jpg" border="0" /></p><br /><br /><p id="TBPingURL">Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=273385</p><br /><div class="postFoot"><script src="http://localhost:82/PromoteIcon.aspx?id=273385"></script>		[<a href="javascript:d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(saveit=window.open('http://wz.csdn.net/storeit.aspx?t='+escape(d.title)+'&amp;u='+escape(d.location.href)+'&amp;c='+escape(t),'keyit','scrollbars=no,width=590,height=300,left=75,top=20,status=no,resizable=yes'));saveit.focus();" title="功能强大的网络收藏夹，一秒钟操作就可以轻松实现保存带来的价值、分享带来的快乐">收藏到我的网摘</a>]  		Dean发表于		2005年01月29日 18:02:00	</div><!--<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"xmlns:dc="http://purl.org/dc/elements/1.1/"xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/"><rdf:Descriptionrdf:about="http://blog.csdn.net/smartcn/archive/2005/01/29/273385.aspx"dc:identifier="http://blog.csdn.net/smartcn/archive/2005/01/29/273385.aspx"dc:title="负载均衡技术全攻略"trackback:ping="http://tb.blog.csdn.net/TrackBack.aspx?PostId=273385" /></rdf:RDF>--><script><![CDATA[unction hide(){showComment();}]]&gt;</script><br /><div class="post"><div class="postTitle">相关文章：</div><ul class="postText"><li><a target="_blank" href="http://blog.csdn.net/shenghuafen/archive/2005/08/20/459712.aspx">负载均衡技术</a> 2005-08-20 <a target="_blank" href="http://blog.csdn.net/shenghuafen/">shenghuafen</a></li><li><a target="_blank" href="http://blog.csdn.net/liumyong/archive/2005/04/04/336269.aspx">集群的负载均衡技术</a> 2005-04-04 <a target="_blank" href="http://blog.csdn.net/liumyong/">liumyong</a></li><li><a target="_blank" href="http://blog.csdn.net/johnathan/archive/2004/08/22/81255.aspx">使用负载均衡技术建设高负载的网络站点 </a> 2004-08-22 <a target="_blank" href="http://blog.csdn.net/johnathan/">johnathan</a></li><li><a target="_blank" href="http://blog.csdn.net/yhb72/archive/2005/12/02/541671.aspx">基于linux的负载均衡技术</a> 2005-12-02 <a target="_blank" href="http://blog.csdn.net/yhb72/">yhb72</a></li><li><a target="_blank" href="http://blog.csdn.net/halfpro/archive/2003/05/05/19064.aspx">web集群服务的负载均衡方案选择与实现</a> 2003-05-05 <a target="_blank" href="http://blog.csdn.net/halfpro/">halfpro</a></li></ul></div><br /><br /><img src ="http://www.cnitblog.com/schkui/aggbug/20230.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/schkui/" target="_blank">易道</a> 2006-12-08 17:36 <a href="http://www.cnitblog.com/schkui/archive/2006/12/08/20230.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>泡泡堂、QQ堂游戏通信架构分析</title><link>http://www.cnitblog.com/schkui/archive/2006/12/08/20229.html</link><dc:creator>易道</dc:creator><author>易道</author><pubDate>Fri, 08 Dec 2006 09:30:00 GMT</pubDate><guid>http://www.cnitblog.com/schkui/archive/2006/12/08/20229.html</guid><wfw:comment>http://www.cnitblog.com/schkui/comments/20229.html</wfw:comment><comments>http://www.cnitblog.com/schkui/archive/2006/12/08/20229.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/schkui/comments/commentRss/20229.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/schkui/services/trackbacks/20229.html</trackback:ping><description><![CDATA[
		<p>本文作者：sodme<br />本文出处：<a href="http://blog.csdn.net/sodme">http://blog.csdn.net/sodme</a><br />声明：本文可以不经作者同意任意转载、复制、引用。但任何对本文的引用，均须注明本文的作者、出处以及本行声明信息。</p>
		<p>　　提笔注：扫地只是偶的表面工作，偶的真实身份是作MMORPG。^_^</p>
		<p>　　之前，我分析过QQ游戏（特指QQ休闲平台，并非QQ堂，下同）的通信架构（<a href="http://blog.csdn.net/sodme/archive/2005/06/12/393165.aspx">http://blog.csdn.net/sodme/archive/2005/06/12/393165.aspx</a>），分析过魔兽世界的通信架构（<a href="http://blog.csdn.net/sodme/archive/2005/06/18/397371.aspx">http://blog.csdn.net/sodme/archive/2005/06/18/397371.aspx</a>），
似乎网络游戏的通信架构也就是这些了，其实不然，在网络游戏大家庭中，还有一种类型的游戏我认为有必要把它的通信架构专门作个介绍，这便是如泡泡堂、QQ
堂类的休闲类竞技游戏。曾经很多次，被网友们要求能抽时间看看泡泡堂之类游戏的通信架构，这次由于被逼交作业，所以今晚抽了一点的时间截了一下泡泡堂的
包，正巧昨日与网友就泡泡堂类游戏的通信架构有过一番讨论，于是，将这两天的讨论、截包及思考总结于本文中，希望能对关心或者正在开发此类游戏的朋友有所
帮助，如果要讨论具体的技术细节，请到我的BLOG（<a href="http://blog.csdn.net/sodme">http://blog.csdn.net/sodme</a>）加我的MSN讨论..</p>
		<p>　　总体来说，泡泡堂类游戏（此下简称泡泡堂）在大厅到房间这一层的通信架构，其结构与QQ游戏相当，甚至要比QQ游戏来得简单。所以，在房间这一层的通信架构上，我不想过多讨论，不清楚的朋友请参看我对QQ游戏通信架构的分析文章（<a href="http://blog.csdn.net/sodme/archive/2005/06/12/393165.aspx">http://blog.csdn.net/sodme/archive/2005/06/12/393165.aspx</a>）。可以这么说，如果采用与QQ游戏相同的房间和大厅架构，是完全可以组建起一套可扩展的支持百万人在线的游戏系统的。也就是说，通过负载均衡＋大厅＋游戏房间对游戏逻辑的分摊，完全可以实现一个可扩展的百万人在线泡泡堂。</p>
		<p>　　但是，泡泡堂与斗地主的最大不同点在于：泡泡堂对于实时性要求特别高。那么，泡泡堂是如何解决实时性与网络延迟以及大用户量之间矛盾的呢？</p>
		<p>　　阅读以下文字前，请确认你已经完全理解TCP与UDP之间的不同点。</p>
		<p>　
　我们知道，TCP与UDP之间的最大不同点在于：TCP是可靠连接的，而UDP是无连接的。如果通信双方使用TCP协议，那么他们之前必须事先通过监听
＋连接的方式将双方的通信管道建立起来；而如果通信双方使用的是UDP通信，则双方不用事先建立连接，发送方只管向目标地址上的目标端口发送UDP包即
可，不用管对方到底收没收到。如果要说形象点，可以用这样一句话概括：TCP是打电话，UDP是发电报。TCP通信，为了保持这样的可靠连接，在可靠性上
下了很多功夫，所以导致了它的通信效率要比UDP差很多，所以，一般地，在地实时性要求非常高的场合，会选择使用UDP协议，比如常见的动作射击类游戏。</p>
		<p>　　通过载包，我们发现泡泡堂中同时采用了TCP和UDP两种通信协议。并且，具有以下特点：<br />　　1.当玩家未进入具体的游戏地图时，仅有TCP通信存在，而没有UDP通信；<br />　　2.进入游戏地图后，TCP的通信量远远小于UDP的通信量<br />　　3.UDP的通信IP个数，与房间内的玩家成一一对应关系(这一点，应网友疑惑而加，此前已经证实)</p>
		<p>　　以上是几个表面现象，下面我们来分析它的本质和内在。^&amp;^</p>
		<p>　　泡泡堂的游戏逻辑，简单地可以归纳为以下几个方面：<br />　　1.玩家移动<br />　　2.玩家埋地雷（如果你觉得这种叫法比较土，你也可以叫它：下泡泡，呵呵）<br />　　3.地雷爆炸出道具或者地雷爆炸困住另一玩家<br />　　4.玩家捡道具或者玩家消灭/解救一被困的玩家</p>
		<p>　　与MMORPG一样，在上面的几个逻辑中，广播量最大的其实是玩家移动。为了保持玩家画面同步，其他玩家的每一步移动消息都要即时地发给其它玩家。</p>
		<p>　
　通常，网络游戏的逻辑控制，绝大多数是在服务器端的。有时，为了保证画面的流畅性，我们会有意识地减少服务器端的逻辑判断量和广播量，当然，这个减少，
是以“不危及游戏的安全运行”为前提的。到底如何在效率、流畅性和安全性之间作取舍，很多时候是需要经验积累的，效率提高的过程，就是逻辑不断优化的过
程。不过，有一个原则是可以说的，那就是：“关键逻辑”一定要放在服务器上来判断。那么，什么是“关键逻辑”呢？</p>
		<p>　　拿泡泡堂来说，下面的这个逻辑，我认为就是关键逻辑：玩家在某处埋下一颗地雷，地雷爆炸后到底能不能炸出道具以及炸出了哪些道具，这个信息，需要服务器来给。那么，什么又是“非关键逻辑”呢？</p>
		<p>　
　“非关键逻辑”，在不同的游戏中，会有不同的概念。在通常的MMORPG中，玩家移动逻辑的判断，是算作关键逻辑的，否则，如果服务器端不对客户端发过
来的移动包进行判断那就很容易造成玩家的瞬移以及其它毁灭性的灾难。而在泡泡堂中，玩家移动逻辑到底应不应该算作关键逻辑还是值得考虑的。泡泡堂中的玩家
可以取胜的方法，通常是确实因为打得好而赢得胜利，不会因为瞬移而赢得胜利，因为如果外挂要作泡泡堂的瞬移，它需要考虑的因素和判断的逻辑太多了，由于比
赛进程的瞬息万变，外挂的瞬移点判断不一定就比真正的玩家来得准确，所在，在玩家移动这个逻辑上使用外挂，在泡泡堂这样的游戏中通常是得不偿失的（当然，
那种特别变态的高智能的外挂除外）。从目前我查到的消息来看，泡泡堂的外挂多数是一些按键精灵脚本，它的本质还不是完全的游戏机器人，并不是通过纯粹的协
议接管实现的外挂功能。这也从反面验证了我以上的想法。</p>
		<p>　　说到这里，也许你已经明白了。是的！TCP通信负责“关键逻辑”，而UDP通信
负责“非关键逻辑”，这里的“非关键逻辑”中就包含了玩家移动。在泡泡堂中，TCP通信用于本地玩家与服务器之间的通信，而UDP则用于本地玩家与同一地
图中的其他各玩家的通信。当本地玩家要移动时，它会同时向同一地图内的所有玩家广播自己的移动消息，其他玩家收到这个消息后会更新自己的游戏画面以实现画
面同步。而当本地玩家要在地图上放置一个炸弹时，本地玩家需要将此消息同时通知同一地图内的其他玩家以及服务器，甚至这里，可以不把放置炸弹的消息通知给
服务器，而仅仅通知其他玩家。当炸弹爆炸后，要拾取物品时才向服务器提交拾取物品的消息。</p>
		<p>　　那么，你可能会问，“地图上某一点是否存在道具”这个消息，服务器是什么时候通知给客户端的呢？这个问题，可以有两种解决方案：<br />　　1.客户端如果在放置炸弹时，将放置炸弹的消息通知给服务器，服务器可以在收到这个消息后，告诉客户端炸弹爆炸后会有哪些道具。但我觉得这种方案不好，因为这样作会增加游戏运行过程中的数据流量。<br />　
　2.而这第2种方案就是，客户端进入地图后，游戏刚开始时，就由服务器将本地图内的各道具所在点的信息传给各客户端，这样，可以省去两方面的开销：a.
客户端放炸弹时，可以不通知服务器而只通知其它玩家；b.服务器也不用在游戏运行过程中再向客户端传递有关某点有道具的信息。<br />　　<br />　　但是，不管采用哪种方案，服务器上都应该保留一份本地图内道具所在点的信息。因为服务器要用它来验证一个关键逻辑：玩家拾取道具。当玩家要在某点拾取道具时，服务器必须要判定此点是否有道具，否则，外挂可以通过频繁地发拾取道具的包而不断取得道具。</p>
		<p>　
　至于泡泡堂其它游戏逻辑的实现方法，我想，还是要依靠这个原则：首先判断这个逻辑是关键逻辑吗？如果不全是，那其中的哪部分是非关键逻辑呢？对于非关键
逻辑，都可以交由客户端之间（UDP）去自行完成。而对于关键逻辑，则必须要有服务器(TCP)的校验和认证。这便是我要说的。</p>
		<p>　　以上仅
仅是在理论上探讨关于泡泡堂类游戏在通信架构上的可能作法，这些想法是没有事实依据的，所有结论皆来源于对封包的分析以及个人经验，文章的内容和观点可能
跟真实的泡泡堂通信架构实现有相当大的差异，但我想，这并不是主要的，因为我的目的是向大家介绍这样的TCP和UDP通信并存情况下，如何对游戏逻辑的进
行取舍和划分。无论是“关键逻辑”的定性，还是“玩家移动”的具体实施，都需要开发者在具体的实践中进行总结和优化。此文全当是一个引子罢，如有疑问，请
加Msn讨论。<br /></p>
<img src ="http://www.cnitblog.com/schkui/aggbug/20229.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/schkui/" target="_blank">易道</a> 2006-12-08 17:30 <a href="http://www.cnitblog.com/schkui/archive/2006/12/08/20229.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>负载均衡－－大型在线系统实现的关键(下篇)（服务器集群架构的设计与选择）</title><link>http://www.cnitblog.com/schkui/archive/2006/12/08/20228.html</link><dc:creator>易道</dc:creator><author>易道</author><pubDate>Fri, 08 Dec 2006 09:27:00 GMT</pubDate><guid>http://www.cnitblog.com/schkui/archive/2006/12/08/20228.html</guid><wfw:comment>http://www.cnitblog.com/schkui/comments/20228.html</wfw:comment><comments>http://www.cnitblog.com/schkui/archive/2006/12/08/20228.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/schkui/comments/commentRss/20228.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/schkui/services/trackbacks/20228.html</trackback:ping><description><![CDATA[本文作者：sodme<br />本文出处：<a href="http://blog.csdn.net/sodme">http://blog.csdn.net/sodme</a><br />声明：本文可以不经作者同意任意转载，但任何对本文的引用都须注明作者、出处及此声明信息。谢谢！！<br /><br />　　在网络应用中，“负载均衡”已经不能算是什么新鲜话题了，从硬件到软件，也都有了很多的方法来实现负载均衡。我们这里讨论的负载均衡，并不是指依靠DNS转向或其它硬件设备等所作的负载均衡，而是指在应用层所作的负载均衡。<br /><br />　　一般而言，只有在大型在线系统当中才有必要引入负载均衡，那么，多大的系统才能被称为大型系统呢？比如动辄同时在线数十万的网络游戏，比如同时在线数在10万以上的WEB应用，这些我们都可以理解为大型系统，这本身就是一个宽泛的概念。<br /><br />　
　设计再好的服务器程序，其单个程序所能承载的同时访问量也是有限的，面对一个庞大且日益增长的网络用户群，如何让我们的架构能适应未来海量用户访问，这
自然就牵涉到了负载均衡问题。支持百万级以上的大型在线系统，它的架构核心就是如何将“百万”这么大的一个同时在线量分摊到每个单独的服务器程序上去。真
正的逻辑处理应该是在这最终的底层的服务器程序（如QQ游戏平台的游戏房间服务器）上的，而在此之前所存在的那些服务器，都可以被称为“引路者”，它们的
作用就是将客户端一步步引导到这最终的负责真正逻辑的底层服务器上去，我们计算“百万级在线”所需要的服务器数量，也是首先考虑这底层的逻辑服务器单个可
承载的客户端连接量。<br /><br />　　比如：按上篇我们所分析QQ游戏架构而言，假设每个服务器程序最高支持2W的用户在线（假设一台机子只运行一个
服务器程序），那么实现150万的在线量至少需要多少台服务器呢？如果算得简单一点的话，就应该是：150/2=75台。当然，这样算起来，可能并不能代
表真正的服务器数量，因为除了这底层的服务器外，还要包括登录/账号服务器以及大厅服务器。但是，由于登录/账号服务器和大厅服务器，它们与客户端的连接
都属于短连接（即：取得所需要信息后，客户端与服务器即断开连接），所以，客户端给这两类服务器带来的压力相比于长连接（即：客户端与服务器始终保持连
接）而言就要轻得多，它们的压力主要在处理瞬间的并发访问上。<br /><br />　　“短连接”，是实现应用层负载均衡的基本手段！！！如果客户端要始终与登录/账号服务器以及大厅服务器保持连接，那么这样作的分层架构将是无意义的，这也没有办法从根本上解决用户量不断增长与服务器数量有限之间的矛盾。<br /><br />　
　当然，短连接之所以可以被使用并能维护正常的游戏逻辑，是因为在玩家看不到的地方，服务器与服务器之间进行了大量的数据同步操作。如果一个玩家没有登录
到登录服务器上去而是直接连接进了游戏房间服务器并试图进行游戏，那么，由于游戏房间服务器与大厅服务器和登录/账号服务器之间都会有针对于玩家登录的逻
辑维护，游戏房间服务器会检测出来该玩家之前并没有到登录服务器进行必要的账号验证工作，它便会将玩家踢下线。由此看来，各服务器之间的数据同步，又是实
现负载均衡的又一必要条件了。<br /><br />　　服务器之间的数据同步问题，依据应用的不同，也会呈现不同的实现方案。比如，我们在处理玩家登录这个问
题上。我们首先可以向玩家开放一些默认的登录服务器（服务器的IP及PORT信息），当玩家连接到当前的登录服务器后，由该服务器首先判断自己同时连接的
玩家是不是超过了自定义的上限，如果是，由向与该服务器连接着的“登录服务器管理者”（一般是一个内部的服务器，不直接向玩家开放）申请仲裁，由“登录服
务器管理者”根据当前各登录服务器的负载情况选择一个新的服务器IP和PORT信息传给客户端，客户端收到这个IP和PORT信息之后重定向连接到这个新
的登录服务器上去，完成后续的登录验证过程。<br /><br />　　这种方案的一个特点是，在面向玩家的一侧，会提供一个外部访问接口，而在服务器集群的内部，会提供一个“服务器管理者”及时记录各登录服务器的负载情况以便客户端需要重定向时根据策略选择一个新的登录接口给客户端。<br /><br />　
　采用分布式结构的好处是可以有效分摊整个系统的压力，但是，不足点就是对于全局信息的索引将会变得比较困难，因为每个单独的底层逻辑服务器上都只是存放
了自己这一个服务器上的用户数据，它没有办法查找到其它服务器上的用户数据。解决这个问题，简单一点的作法，就是在集群内部，由一个中介者，提供一个全局
的玩家列表。这个全局列表，根据需要，可以直接放在“服务器管理者”上，也可以存放在数据库中。<br /><br />　　对于逻辑相对独立的应用，全局列表的
使用机会其实并不多，最主要的作用就是用来检测玩家是不是重复登录了。但如果有其它的某些应用，要使用这样的全局列表，就会使数据同步显得比较复杂。比
如，我们在超大无缝地图的MMORPG里，如果允许跨服操作(如跨服战斗、跨服交易等)的话，这时的数据同步将会变得异常复杂，也容易使处理逻辑出现不可
预测性。<br /><br />　　我认为，对于休闲平台而言，QQ游戏的架构已经是比较合理的，也可以称之为休闲平台的标准架构了。那么，MMORPG一般的架构是什么样的呢？<br /><br />　
　MMORPG一般是把整个游戏分成若干个游戏世界组，每个组内其实就是一个单独的游戏世界。而不同的组之间，其数据皆是相互独立的，并不象QQ休闲平台
一样所有的用户都会有一个集中的数据存放点，MMORPG的游戏数据是按服务器组的不同而各自存放的。玩家在登录QQ游戏时，QQ游戏相关的服务器会自动
为玩家的登录进行负载均衡，选择相对不忙的服务器为其执行用户验证并最终让用户选择进入哪一个游戏房间。但是，玩家在登录MMORPG时，却没有这样的自
动负载均衡，一般是由玩家人为地去选择要进入哪一个服务器组，之所以这样，是因为各服务器组之间的数据是不相通的。其实，细致想来，MMORPG的服务器
架构思想与休闲平台的架构思想有异曲同工之妙，MMORPG的思想是：可以为玩家无限地开独立的游戏世界（即服务器组），以满足大型玩家在线；而休闲平台
的思想则是：可以为玩家无限地开游戏房间以满足大量玩家在线。这两种应用，可以无限开的都是“具有完整游戏性的游戏世界”，对于MMORPG而言，它的一
个完整的游戏地图就是一个整体的“游戏世界”，而对于休闲平台，它的一个游戏房间就可以描述为一个“游戏世界”。如果MMORPG作成了休闲平台那样的全
服皆通，也不是不可以，但随之而来的，就是要解决众多跨服问题，比如：好友、组队、帮派等等的问题，所有在传统MMORPG里所定义的这些玩家组织形式的
规则可能都会因为“全服皆通”而改变。<br /><br />　　架构的选择是多样性的，确实没有一种可以称得上是最好的所谓的架构，适合于当前项目的，不一定就适合于另一个项目。针对于特定的应用，会灵活选用不同的架构。但有一点，是可以说的：不管你如何架构，你所要作的就是－－要以尽可能简单的方案实现尽可能的稳定、高效！<br /><br />　　&lt;全文完&gt;<img src ="http://www.cnitblog.com/schkui/aggbug/20228.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/schkui/" target="_blank">易道</a> 2006-12-08 17:27 <a href="http://www.cnitblog.com/schkui/archive/2006/12/08/20228.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>负载均衡－－大型在线系统实现的关键(上篇)（再谈QQ游戏百万人在线的技术实现）</title><link>http://www.cnitblog.com/schkui/archive/2006/12/08/20227.html</link><dc:creator>易道</dc:creator><author>易道</author><pubDate>Fri, 08 Dec 2006 09:26:00 GMT</pubDate><guid>http://www.cnitblog.com/schkui/archive/2006/12/08/20227.html</guid><wfw:comment>http://www.cnitblog.com/schkui/comments/20227.html</wfw:comment><comments>http://www.cnitblog.com/schkui/archive/2006/12/08/20227.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/schkui/comments/commentRss/20227.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/schkui/services/trackbacks/20227.html</trackback:ping><description><![CDATA[本文作者：sodme<br />本文出处：<a href="http://blog.csdn.net/sodme">http://blog.csdn.net/sodme</a><br />声明：本文可以不经作者同意任意转载，但任何对本文的引用都须注明作者、出处及此声明信息。谢谢！！<br /><br />　　要了解此篇文章中引用的本人写的另一篇文章，请到以下地址：<br />　　<a href="http://blog.csdn.net/sodme/archive/2004/12/12/213995.aspx">http://blog.csdn.net/sodme/archive/2004/12/12/213995.aspx</a><br />　　以上的这篇文章是早在去年的时候写的了，当时正在作休闲平台，一直在想着如何实现一个可扩充的支持百万人在线的游戏平台，后来思路有了，就写了那篇总结。文章的意思，重点在于阐述一个百万级在线的系统是如何实施的，倒没真正认真地考察过QQ游戏到底是不是那样实现的。<br /><br />　
　近日在与业内人士讨论时，提到QQ游戏的实现方式并不是我原来所想的那样，于是，今天又认真抓了一下QQ游戏的包，结果确如这位兄弟所言，QQ游戏的架
构与我当初所设想的那个架构相差确实不小。下面，我重新给出QQ百万级在线的技术实现方案，并以此展开，谈谈大型在线系统中的负载均衡机制的设计。<br /><br />　　从QQ游戏的登录及游戏过程来看，QQ游戏中，也至少分为三类服务器。它们是：<br />　　第一层：登陆/账号服务器(Login Server)，负责验证用户身份、向客户端传送初始信息，从QQ聊天软件的封包常识来看，这些初始信息可能包括“会话密钥”此类的信息，以后客户端与后续服务器的通信就使用此会话密钥进行身份验证和信息加密；<br />　　第二层：大厅服务器(估且这么叫吧, Game Hall Server)，负责向客户端传递当前游戏中的所有房间信息，这些房间信息包括：各房间的连接IP，PORT，各房间的当前在线人数，房间名称等等。<br />　　第三层：游戏逻辑服务器(Game Logic Server)，负责处理房间逻辑及房间内的桌子逻辑。<br /><br />　　从静态的表述来看，以上的三层结构似乎与我以前写的那篇文章相比并没有太大的区别，事实上，重点是它的工作流程，QQ游戏的通信流程与我以前的设想可谓大相径庭，其设计思想和技术水平确实非常优秀。具体来说，QQ游戏的通信过程是这样的：<br /><br />　
　1.由Client向Login Server发送账号及密码等登录消息，Login
Server根据校验结果返回相应信息。可以设想的是，如果Login Server通过了Client的验证，那么它会通知其它Game Hall
Server或将通过验证的消息以及会话密钥放在Game Hall Server也可以取到的地方。总之，Login Server与Game
Hall Server之间是可以共享这个校验成功消息的。一旦Client收到了Login Server返回成功校验的消息后，Login
Server会主动断开与Client的连接，以腾出socket资源。Login
Server的IP信息，是存放在QQGame\config\QQSvrInfo.ini里的。<br /><br />　　2.Client收到Login
Server的校验成功等消息后，开始根据事先选定的游戏大厅入口登录游戏大厅，各个游戏大厅Game Hall
Server的IP及Port信息，是存放在QQGame\Dirconfig.ini里的。Game Hall
Server收到客户端Client的登录消息后，会根据一定的策略决定是否接受Client的登录，如果当前的Game Hall
Server已经到了上限或暂时不能处理当前玩家登录消息，则由Game Hall
Server发消息给Client，以让Client重定向到另外的Game Hall
Server登录。重定向的IP及端口信息，本地没有保存，是通过数据包或一定的算法得到的。如果当前的Game Hall
Server接受了该玩家的登录消息后，会向该Client发送房间目录信息，这些信息的内容我上面已经提到。目录等消息发送完毕后，Game
Hall Server即断开与Client的连接，以腾出socket资源。在此后的时间里，Client每隔30分钟会重新连接Game Hall
Server并向其索要最新的房间目录信息及在线人数信息。<br /><br />　　3.Client根据列出的房间列表，选择某个房间进入游戏。根据我的抓
包结果分析，QQ游戏，并不是给每一个游戏房间都分配了一个单独的端口进行处理。在QQ游戏里，有很多房间是共用的同一个IP和同一个端口。比如，在斗地
主一区，前50个房间，用的都是同一个IP和Port信息。这意味着，这些房间，在QQ游戏的服务器上，事实上，可能是同一个程序在处理！！！QQ游戏房
间的人数上限是400人，不难推算，QQ游戏单个服务器程序的用户承载量是2万，即QQ的一个游戏逻辑服务器程序最多可同时与2万个玩家保持TCP连接并
保证游戏效率和品质，更重要的是，这样可以为腾讯省多少money呀！！！哇哦！QQ确实很牛。以2万的在线数还能保持这么好的游戏品质，确实不容易！
QQ游戏的单个服务器程序，管理的不再只是逻辑意义上的单个房间，而可能是许多逻辑意义上的房间。其实，对于服务器而言，它就是一个大区服务器或大区服务
器的一部分，我们可以把它理解为一个庞大的游戏地图，它实现的也是分块处理。而对于每一张桌子上的打牌逻辑，则是有一个统一的处理流程，50个房间的
50＊100张桌子全由这一个服务器程序进行处理(我不知道QQ游戏的具体打牌逻辑是如何设计的，我想很有可能也是分区域的，分块的)。当然，以上这些只
是服务器作的事，针对于客户端而言，客户端只是在表现上，将一个个房间单独罗列了出来，这样作，是为便于玩家进行游戏以及减少服务器的开销，把这个大区中
的每400人放在一个集合内进行处理（比如聊天信息，“向400人广播”和“向2万人广播”，这是完全不同的两个概念）。<br /><br />　　4.需要特
别说明的一点。进入QQ游戏房间后，直到点击某个位置坐下打开另一个程序界面，客户端的程序，没有再创建新的socket，而仍然使用原来大厅房间客户端
跟游戏逻辑服务器交互用的socket。也就是说，这是两个进程共用的同一个socket！不要小看这一点。如果你在创建桌子客户端程序后又新建了一个新
的socket与游戏逻辑服务器进行通信，那么由此带来的玩家进入、退出、逃跑等消息会带来非常麻烦的数据同步问题，俺在刚开始的时候就深受其害。而一旦
共用了同一个socket后，你如果退出桌子，服务器不涉及释放socket的问题，所以，这里就少了很多的数据同步问题。关于多个进程如何共享同一个
socket的问题，请去google以下内容：WSADuplicateSocket。<br /><br />　　以上便是我根据最新的QQ游戏抓包结果分析得到的QQ游戏的通信流程，当然，这个流程更多的是客户端如何与服务器之间交互的，却没有涉及到服务器彼此之间是如何通信和作数据同步的。关于服务器之间的通信流程，我们只能基于自己的经验和猜想，得出以下想法：<br /><br />　
　1.Login Server与Game Hall Server之前的通信问题。Login
Server是负责用户验证的，一旦验证通过之后，它要设法让Game Hall
Server知道这个消息。它们之前实现信息交流的途径，我想可能有这样几条：a. Login
Server将通过验证的用户存放到临时数据库中；b.　Login
Server将验证通过的用户存放在内存中，当然，这个信息，应该是全局可访问的，就是说所有QQ的Game Hall
Server都可以通过服务器之间的数据包通信去获得这样的信息。<br /><br />　　2.Game Hall Server的最新房间目录信息的取得。这个信息，是全局的，也就是整个游戏中，只保留一个目录。它的信息来源，可以由底层的房间服务器逐级报上来，报给谁？我认为就如保存的全局登录列表一样，它报给保存全局登录列表的那个服务器或数据库。<br /><br />　　3.在QQ游戏中，同一类型的游戏，无法打开两上以上的游戏房间。这个信息的判定，可以根据全局信息来判定。<br /><br />　
　以上关于服务器之间如何通信的内容，均属于个人猜想，QQ到底怎么作的，恐怕只有等大家中的某一位进了腾讯之后才知道了。呵呵。不过，有一点是可以肯定
的，在整个服务器架构中，应该有一个地方是专门保存了全局的登录玩家列表，只有这样才能保证玩家不会重复登录以及进入多个相同类型的房间。<br /><br />　　在前面的描述中，我曾经提到过一个问题：当登录当前Game Hall Server不成功时，QQ游戏服务器会选择让客户端重定向到另位的服务器去登录，事实上，QQ聊天服务器和MSN服务器的登录也是类似的，它也存在登录重定向问题。<br /><br />　　那么，这就引出了另外的问题，由谁来作这个策略选择？以及由谁来提供这样的选择资源？这样的处理，便是负责负载均衡的服务器的处理范围了。由QQ游戏的通信过程分析派生出来的针对负责均衡及百万级在线系统的更进一步讨论，将在下篇文章中继续。<br /><br />　　在此，特别感谢网友tilly及某位不便透露姓名的网友的讨论，是你们让我决定认真再抓一次包探个究竟。<br /><br />　　&lt;未完待续&gt;<img src ="http://www.cnitblog.com/schkui/aggbug/20227.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/schkui/" target="_blank">易道</a> 2006-12-08 17:26 <a href="http://www.cnitblog.com/schkui/archive/2006/12/08/20227.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>类似于QQ游戏百万人同时在线的服务器架构实现</title><link>http://www.cnitblog.com/schkui/archive/2006/12/08/20226.html</link><dc:creator>易道</dc:creator><author>易道</author><pubDate>Fri, 08 Dec 2006 09:24:00 GMT</pubDate><guid>http://www.cnitblog.com/schkui/archive/2006/12/08/20226.html</guid><wfw:comment>http://www.cnitblog.com/schkui/comments/20226.html</wfw:comment><comments>http://www.cnitblog.com/schkui/archive/2006/12/08/20226.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/schkui/comments/commentRss/20226.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/schkui/services/trackbacks/20226.html</trackback:ping><description><![CDATA[
		<p>本文作者：sodme　本文出处：<a href="http://blog.csdn.net/sodme">http://blog.csdn.net/sodme</a><br />版权声明：本文可以不经作者同意任意转载，但转载时烦请保留文章开始前两行的版权、作者及出处信息。<br /><br />　
　QQ游戏于前几日终于突破了百万人同时在线的关口，向着更为远大的目标迈进，这让其它众多传统的棋牌休闲游戏平台黯然失色，相比之下，联众似乎已经根本
不是QQ的对手，因为QQ除了这100万的游戏在线人数外，它还拥有3亿多的注册量（当然很多是重复注册的）以及QQ聊天软件900万的同时在线率，我们
已经可以预见未来由QQ构建起来的强大棋牌休闲游戏帝国。<br />　　那么，在技术上，QQ游戏到底是如何实现百万人同时在线并保持游戏高效率的呢？<br />　
　事实上，针对于任何单一的网络服务器程序，其可承受的同时连接数目是有理论峰值的，通过C＋＋中对TSocket的定义类型：word，我们可以判定这
个连接理论峰值是65535，也就是说，你的单个服务器程序，最多可以承受6万多的用户同时连接。但是，在实际应用中，能达到一万人的同时连接并能保证正
常的数据交换已经是很不容易了，通常这个值都在2000到5000之间，据说QQ的单台服务器同时连接数目也就是在这个值这间。<br />　　如果要实现
2000到5000用户的单服务器同时在线，是不难的。在windows下，比较成熟的技术是采用IOCP－－完成端口。与完成端口相关的资料在网上和
CSDN论坛里有很多，感兴趣的朋友可以自己搜索一下。只要运用得当，一个完成端口服务器是完全可以达到2K到5K的同时在线量的。但，5K这样的数值离
百万这样的数值实在相差太大了，所以，百万人的同时在线是单台服务器肯定无法实现的。<br />　　要实现百万人同时在线，首先要实现一个比较完善的完成端
口服务器模型，这个模型要求至少可以承载2K到5K的同时在线率（当然，如果你MONEY多，你也可以只开发出最多允许100人在线的服务器）。在构建好
了基本的完成端口服务器之后，就是有关服务器组的架构设计了。之所以说这是一个服务器组，是因为它绝不仅仅只是一台服务器，也绝不仅仅是只有一种类型的服
务器。<br />　　简单地说，实现百万人同时在线的服务器模型应该是：登陆服务器＋大厅服务器＋房间服务器。当然，也可以是其它的模型，但其基本的思想是一样的。下面，我将逐一介绍这三类服务器的各自作用。<br />　
　登陆服务器：一般情况下，我们会向玩家开放若干个公开的登陆服务器，就如QQ登陆时让你选择的从哪个QQ游戏服务器登陆一样，QQ登陆时让玩家选择的六
个服务器入口实际上就是登陆服务器。登陆服务器主要完成负载平衡的作用。详细点说就是，在登陆服务器的背后，有N个大厅服务器，登陆服务器只是用于为当前
的客户端连接选择其下一步应该连接到哪个大厅服务器，当登陆服务器为当前的客户端连接选择了一个合适的大厅服务器后，客户端开始根据登陆服务器提供的信息
连接到相应的大厅上去，同时客户端断开与登陆服务器的连接，为其他玩家客户端连接登陆服务器腾出套接字资源。在设计登陆服务器时，至少应该有以下功能：N
个大厅服务器的每一个大厅服务器都要与所有的登陆服务器保持连接，并实时地把本大厅服务器当前的同时在线人数通知给各个登陆服务器，这其中包括：用户进入
时的同时在线人数增加信息以及用户退出时的同时在线人数减少信息。这里的各个大厅服务器同时在线人数信息就是登陆服务器为客户端选择某个大厅让其登陆的依
据。举例来说，玩家A通过登陆服务器1连接到登陆服务器，登陆服务器开始为当前玩家在众多的大厅服务器中根据哪一个大厅服务器人数比较少来选择一个大厅，
同时把这个大厅的连接IP和端口发给客户端，客户端收到这个IP和端口信息后，根据这个信息连接到此大厅，同时，客户端断开与登陆服务器之间的连接，这便
是用户登陆过程中，在登陆服务器这一块的处理流程。<br />　　大厅服务器：大厅服务器，是普通玩家看不到的服务器，它的连接IP和端口信息是登陆服务器
通知给客户端的。也就是说，在QQ游戏的本地文件中，具体的大厅服务器连接IP和端口信息是没有保存的。大厅服务器的主要作用是向玩家发送游戏房间列表信
息，这些信息包括：每个游戏房间的类型，名称，在线人数，连接地址以及其它如游戏帮助文件URL的信息。从界面上看的话，大厅服务器就是我们输入用户名和
密码并校验通过后进入的游戏房间列表界面。大厅服务器，主要有以下功能：一是向当前玩家广播各个游戏房间在线人数信息；二是提供游戏的版本以及下载地址信
息；三是提供各个游戏房间服务器的连接IP和端口信息；四是提供游戏帮助的URL信息；五是提供其它游戏辅助功能。但在这众多的功能中，有一点是最为核心
的，即：为玩家提供进入具体的游戏房间的通道，让玩家顺利进入其欲进入的游戏房间。玩家根据各个游戏房间在线人数，判定自己进入哪一个房间，然后双击服务
器列表中的某个游戏房间后玩家开始进入游戏房间服务器。<br />　　游戏房间服务器：游戏房间服务器，具体地说就是如“斗地主1”，“斗地主2”这样的游
戏房间。游戏房间服务器才是具体的负责执行游戏相关逻辑的服务器。这样的游戏逻辑分为两大类：一类是通用的游戏房间逻辑，如：进入房间，离开房间，进入桌
子，离开桌子以及在房间内说话等；第二类是游戏桌子逻辑，这个就是各种不同类型游戏的主要区别之处了，比如斗地主中的叫地主或不叫地主的逻辑等，当然，游
戏桌子逻辑里也包括有通用的各个游戏里都存在的游戏逻辑，比如在桌子内说话等。总之，游戏房间服务器才是真正负责执行游戏具体逻辑的服务器。<br />　　
这里提到的三类服务器，我均采用的是完成端口模型，每个服务器最多连接数目是5000人，但是，我在游戏房间服务器上作了逻辑层的限定，最多只允许300
人同时在线。其他两个服务器仍然允许最多5000人的同时在线。如果按照这样的结构来设计，那么要实现百万人的同时在线就应该是这样：首先是大厅，
1000000/5000＝200。也就是说，至少要200台大厅服务器，但通常情况下，考虑到实际使用时服务器的处理能力和负载情况，应该至少准备
250台左右的大厅服务器程序。另外，具体的各种类型的游戏房间服务器需要多少，就要根据当前玩各种类型游戏的玩家数目分别计算了，比如斗地主最多是十万
人同时在线，每台服务器最多允许300人同时在线，那么需要的斗地主服务器数目就应该不少于：100000/300=333，准备得充分一点，就要准备
350台斗地主服务器。<br />　　除正常的玩家连接外，还要考虑到：<br />　　对于登陆服务器，会有250台大厅服务器连接到每个登陆服务器上，这是始终都要保持的连接；<br />　　而对于大厅服务器而言，如果仅仅有斗地主这一类的服务器，就要有350多个连接与各个大厅服务器始终保持着。所以从这一点看，我的结构在某些方面还存在着需要改进的地方，但核心思想是：尽快地提供用户登陆的速度，尽可能方便地让玩家进入游戏中。</p>
		<br />
<img src ="http://www.cnitblog.com/schkui/aggbug/20226.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/schkui/" target="_blank">易道</a> 2006-12-08 17:24 <a href="http://www.cnitblog.com/schkui/archive/2006/12/08/20226.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>