怎样在IM系统中实现用户在线状态的实时显示

337 views
Skip to first unread message

wyu...@gmail.com

unread,
Jan 18, 2007, 8:08:20 PM1/18/07
to 高性能网络编程邮件列表
据我所知,在MSN系统中,Client首先会连接一个固定的服务器,此服务器会返回一个新的连接服务器地址给Client,而后Client会重新连接到新的服务器地址并开始登录。我想这样做是服务器端做到一个负载平衡的功能,也就是说有一个负载平衡服务器,有多个登录服务器。最终Client保持连接的是登录服务器。
但是如果ClientA连接的是登录服务器A,而CientB连接的是登录服务器B,而ClientA和ClientB是好友,他们的在线状态是怎么得到的?
如果Client的数量比较少,那么登录服务器之间可以传递消息告知对方。但是当上万或者更多的时候。就不应该这样处理了。
那么有什么方式来实现类似的服务器网络结构中Client之间在线状态的实时显示呢?

bluez

unread,
Jan 18, 2007, 9:19:57 PM1/18/07
to dev4s...@googlegroups.com
正是我现在要面对的问题.

我现在准备采取的策略是:
由客户端主动通知好友。

A 连接到 Login Server A 后。

我们假设A已经从主服务器获得了 好友列表,以及好友状态。

那么A可以主动发送LoginServerA 通知 在线好友B。

LoginServer的通知过程可以用如下方法:
ServerA,检索到好友B的登陆服务器(可以向主服务器请求Client B的登陆服务器,或者可以采用特定的ID算法,根据用户的ID计算出用户B的登陆服务器)
ServerA 发送一个ClientA登陆的消息给Server B,要求ServerB将该消息,转发给 Client B

大家给点意见。

wyu...@gmail.com

unread,
Jan 18, 2007, 9:36:21 PM1/18/07
to 高性能网络编程邮件列表
通过服务器进行传送效率太低了,如果客户不断切换状态,那么服务器之间的消息太频繁了,要知道服务器可能不仅仅只是对另外服务器发送消息,应该是多台。
应该不能使用这种方式。

Simple Lee

unread,
Jan 18, 2007, 10:13:02 PM1/18/07
to dev4s...@googlegroups.com
我感觉多服务器是都到同一个数据去取状态信息!往往最简单的方法最有效.


 
在07-1-19,wyu...@gmail.com <wyu...@gmail.com> 写道:
通过服务器进行传送效率太低了,如果客户不断切换状态,那么服务器之间的消息太频繁了,要知道服务器可能不仅仅只是对另外服务器发送消息,应该是多台。
应该不能使用这种方式。


Simple Lee

wyu...@gmail.com

unread,
Jan 19, 2007, 12:19:24 AM1/19/07
to 高性能网络编程邮件列表
>我感觉多服务器是都到同一个数据去取状态信息
这个"同一数据"指的是什么?要考虑到如果是百万级别的用户量"同一数据"能支持到吗?使用数据库是不显示的!

Jiang Zhiqiang

unread,
Jan 19, 2007, 1:04:56 AM1/19/07
to dev4s...@googlegroups.com
目前我做的IM系统是通过服务器之间转发实现的,想想也没什么更好的办法,理论上每个Server可以达到几万,不过现实中,只有几十个用户/台。


On 1/19/07, wyu...@gmail.com < wyu...@gmail.com> wrote:
>我感觉多服务器是都到同一个数据去取状态信息
这个"同一数据"指的是什么?要考虑到如果是百万级别的用户量"同一数据"能支持到吗?使用数据库是不显示的!






--
Yours: Aaron.Jiang

动物园墙垮

unread,
Jan 19, 2007, 7:31:59 AM1/19/07
to 高性能网络编程邮件列表
其实这个问题并不复杂。
大家想一想,IM就是要支持聊天的。假设这个IM系统没有使用P2P,全部由服务器来转发聊天的信息。
那么,同样的,不同服务器上的好友交流必然会经过服务器之间转发数据。
大家试想一下,到底聊天信息量大还是更新好友状态的信息量大?
如果你的服务器连更新好友的状态都不能很好的支持,那对聊天的支持还从何谈起?
所以反过来想,如果你设计的系统,无论采用什么方法,能很好的支持大量用户的聊天消息转发。那么这个已然对于聊天转发的成熟平台难道还不能支持好友状态更新吗?

wyu...@gmail.com

unread,
Jan 24, 2007, 8:19:16 AM1/24/07
to 高性能网络编程邮件列表
说了半天不是讨论能不能支持,而是怎样支持?有什么方式来支持。

On 1月19日, 下午8时31分, "动物园墙垮"

zhang yin

unread,
Jan 25, 2007, 4:18:50 AM1/25/07
to dev4s...@googlegroups.com
我提个方案:
首先做以下假设:
(1)维护100万在线用户的状态需要多大的内存空间?
(2)从100万在线用户中检索出自己需要的数据需要多少时间?
 
第一个问题我们可以这样来定性:
设每用户占用的内存空间为:
SessionID会话标识(int)+AccountID用户账号ID(int)+loginTime登录时间(long)+其它状态(假设用4个byte型来标明4个状态)=20字节
100万用户*20字节=20,000,000(字节)=19,531.25K==19M(约)
注:一条记录就表示一个在线用户;
 
(我靠,我的计算是不是有错误,一台386的内存都够了.....)
看上去,似乎用一台服务器做状态服务器是没有什么问题的;
 
第二个问题,我们这样来定性:
假设在服务器端的内存中使用如hashTable这样的存储结构来保存用户的会话状态,hashTable的读操作为0/m复杂度,从100万个记录中读取一条记录的寻址时间那是相当的快的,快到无法用毫秒来计算,只能用tick(一个CPU的时钟滴答)来计算。1个毫秒=10,000个tick(毫微秒),(hashTable的操作平均值是多少我没有统计过不好意思。我就猜个值吧:假设平均为100个tick),如果每次存取hashtable要花费100Tick,另外在加上一些业务处理的时间,就按操作一次数据表要1个毫秒来计算吧。
那么1秒钟的时间内就可以处理1000次用户的查询操作;
问题是如果100万用户同时来查询我们该怎么办?
我想可以做负载均衡及服务器集群,当然还要涉汲到网络接口的流量限制,说来就话很长了。
总之,第二个问题看起来,似乎是我们可以通过其它的手段将单台服务器无法处理的工作量分摊到多台服务器中去进行;
 
于是可以得出第一个背景结论:
设置一台服务器将其做为用户状态服务器,用于记录系统中所有用户是否在线等状态信息;通过对服务器制作集群来分摊访问压力;
 
现在我们就可以做以下比较形象的结论和假设了:
(1)一个用户要查询自己所有好友的在线状态,那么这个用户向刚才所说到的状态服务器发送一条查询消息,服务器可以很快的返回用户的状态给客户;
(2)用户在登录系统后通知状态服务器自己已经登陆了。
(3)用户如果从某台具体的功能服务器掉线后,则由这台服务器通知状态服务器用户掉线;
(4)用户可能会在多台功能服务器中来回切换,由客户端与服务器端共同协作以判断用户是为否掉线;
(5)用户定期向状态服务器报告自己的存活状态,如果长时间不报告,则状态服务器把用户从自己的内存状态表中删除;
 
以上我的瞎解,不一定对,必竞自己没有做过,仅供参考。
 

iceboundrock

unread,
Jan 25, 2007, 8:49:14 AM1/25/07
to 高性能网络编程邮件列表
在客户端保存一些冗余数据,也许会简化这个问题。
服务器发给客户端的状态信息中可以包含该用户所连接的服务器,那么客户端就可以知道每个在线好友所在的服务器。可以在客户端改变状态时,只向好友所在服务器发送信息即可。

On 1月25日, 下午5时18分, "zhang yin" <zhangy...@gmail.com> wrote:
> 我提个方案:
> 首先做以下假设:
> (1)维护100万在线用户的状态需要多大的内存空间?
> (2)从100万在线用户中检索出自己需要的数据需要多少时间?
>
> 第一个问题我们可以这样来定性:
> 设每用户占用的内存空间为:

> SessionID会话标识(int)+AccountID用户账号ID(int)+loginTime登录时间(long)+其它状态(假设用4个byte型-来标明4个状态)=20字节


> 100万用户*20字节=20,000,000(字节)=19,531.25K==19M(约)
> 注:一条记录就表示一个在线用户;
>
> (我靠,我的计算是不是有错误,一台386的内存都够了.....)
> 看上去,似乎用一台服务器做状态服务器是没有什么问题的;
>
> 第二个问题,我们这样来定性:

> 假设在服务器端的内存中使用如hashTable这样的存储结构来保存用户的会话状态,hashTable的读操作为0/m复杂度,从100万个记录中读取一条-记录的寻址时间那是相当的快的,快到无法用毫秒来计算,只能用tick(一个CPU的时钟滴答)来计算。1个毫秒=10,000个tick(毫微秒),(has-hTable的操作平均值是多少我没有统计过不好意思。我就猜个值吧:假设平均为100个tick),如果每次存取hashtable要花费100Tick,另-外在加上一些业务处理的时间,就按操作一次数据表要1个毫秒来计算吧。

bluez

unread,
Jan 25, 2007, 8:26:38 PM1/25/07
to dev4s...@googlegroups.com
我想对于服务器来说,目前的硬件已经能够支持大量的并发访问了。
 
而问题的瓶颈,我认为应该是带宽。
 
我比较认同zhang yin的看法。事实上,这种架构也被采用过。而且其本身就是一个拥有良好扩展性的架构

在用户量增加的时候,我只需要添加状态服务器就可以了

sunway

unread,
Jan 26, 2007, 12:27:06 AM1/26/07
to 高性能网络编程邮件列表
对于IM这类应用,瓶颈还有一块是DB。

On 1月26日, 上午9时26分, "bluez" <keo...@gmail.com> wrote:
> 我想对于服务器来说,目前的硬件已经能够支持大量的并发访问了。
>
> 而问题的瓶颈,我认为应该是带宽。
>
> 我比较认同zhang yin的看法。事实上,这种架构也被采用过。而且其本身就是一个拥有良好扩展性的架构
>
> 在用户量增加的时候,我只需要添加状态服务器就可以了
>
>
>
> ----- Original Message -----
> From: zhang yin
> To: dev4s...@googlegroups.com
> Sent: Thursday, January 25, 2007 5:18 PM
> Subject: Re: 怎样在IM系统中实现用户在线状态的实时显示
>
> 我提个方案:
> 首先做以下假设:
> (1)维护100万在线用户的状态需要多大的内存空间?
> (2)从100万在线用户中检索出自己需要的数据需要多少时间?
>
> 第一个问题我们可以这样来定性:
> 设每用户占用的内存空间为:

> SessionID会话标识(int)+AccountID用户账号ID(int)+loginTime登录时间(long)+其它状态(假设用4个byte型-来标明4个状态)=20字节


> 100万用户*20字节=20,000,000(字节)=19,531.25K==19M(约)
> 注:一条记录就表示一个在线用户;
>
> (我靠,我的计算是不是有错误,一台386的内存都够了.....)
> 看上去,似乎用一台服务器做状态服务器是没有什么问题的;
>
> 第二个问题,我们这样来定性:

> 假设在服务器端的内存中使用如hashTable这样的存储结构来保存用户的会话状态,hashTable的读操作为0/m复杂度,从100万个记录中读取一条-记录的寻址时间那是相当的快的,快到无法用毫秒来计算,只能用tick(一个CPU的时钟滴答)来计算。1个毫秒=10,000个tick(毫微秒),(has-hTable的操作平均值是多少我没有统计过不好意思。我就猜个值吧:假设平均为100个tick),如果每次存取hashtable要花费100Tick,另-外在加上一些业务处理的时间,就按操作一次数据表要1个毫秒来计算吧。


> 那么1秒钟的时间内就可以处理1000次用户的查询操作;
> 问题是如果100万用户同时来查询我们该怎么办?
> 我想可以做负载均衡及服务器集群,当然还要涉汲到网络接口的流量限制,说来就话很长了。
> 总之,第二个问题看起来,似乎是我们可以通过其它的手段将单台服务器无法处理的工作量分摊到多台服务器中去进行;
>
> 于是可以得出第一个背景结论:
> 设置一台服务器将其做为用户状态服务器,用于记录系统中所有用户是否在线等状态信息;通过对服务器制作集群来分摊访问压力;
>
> 现在我们就可以做以下比较形象的结论和假设了:
> (1)一个用户要查询自己所有好友的在线状态,那么这个用户向刚才所说到的状态服务器发送一条查询消息,服务器可以很快的返回用户的状态给客户;
> (2)用户在登录系统后通知状态服务器自己已经登陆了。
> (3)用户如果从某台具体的功能服务器掉线后,则由这台服务器通知状态服务器用户掉线;
> (4)用户可能会在多台功能服务器中来回切换,由客户端与服务器端共同协作以判断用户是为否掉线;
> (5)用户定期向状态服务器报告自己的存活状态,如果长时间不报告,则状态服务器把用户从自己的内存状态表中删除;
>

> 以上我的瞎解,不一定对,必竞自己没有做过,仅供参考。- 隐藏被引用文字 -- 显示引用的文字 -

bluez

unread,
Jan 28, 2007, 8:18:17 PM1/28/07
to dev4s...@googlegroups.com
对!DB也是瓶颈!

呵呵:)
----- Original Message -----
From: "sunway" <sunh...@gmail.com>
To: "高性能网络编程邮件列表" <dev4s...@googlegroups.com>

sunway

unread,
Jan 28, 2007, 10:18:24 PM1/28/07
to 高性能网络编程邮件列表
DB如何hash,在那一层次加Cache都是值得探讨的问题。我最近就在琢磨这一块的开发,感觉难点很多,不过很有意思。

> >> SessionID会话标识(int)+AccountID用户账号ID(int)+loginTime登录时间(long)+其它状态(假设用4个byte型--来标明4个状态)=20字节


> >> 100万用户*20字节=20,000,000(字节)=19,531.25K==19M(约)
> >> 注:一条记录就表示一个在线用户;
>
> >> (我靠,我的计算是不是有错误,一台386的内存都够了.....)
> >> 看上去,似乎用一台服务器做状态服务器是没有什么问题的;
>
> >> 第二个问题,我们这样来定性:

> >> 假设在服务器端的内存中使用如hashTable这样的存储结构来保存用户的会话状态,hashTable的读操作为0/m复杂度,从100万个记录中读取一条--记录的寻址时间那是相当的快的,快到无法用毫秒来计算,只能用tick(一个CPU的时钟滴答)来计算。1个毫秒=10,000个tick(毫微秒),(ha-s-hTable的操作平均值是多少我没有统计过不好意思。我就猜个值吧:假设平均为100个tick),如果每次存取hashtable要花费100Tick-,另-外在加上一些业务处理的时间,就按操作一次数据表要1个毫秒来计算吧。


> >> 那么1秒钟的时间内就可以处理1000次用户的查询操作;
> >> 问题是如果100万用户同时来查询我们该怎么办?
> >> 我想可以做负载均衡及服务器集群,当然还要涉汲到网络接口的流量限制,说来就话很长了。
> >> 总之,第二个问题看起来,似乎是我们可以通过其它的手段将单台服务器无法处理的工作量分摊到多台服务器中去进行;
>
> >> 于是可以得出第一个背景结论:
> >> 设置一台服务器将其做为用户状态服务器,用于记录系统中所有用户是否在线等状态信息;通过对服务器制作集群来分摊访问压力;
>
> >> 现在我们就可以做以下比较形象的结论和假设了:
> >> (1)一个用户要查询自己所有好友的在线状态,那么这个用户向刚才所说到的状态服务器发送一条查询消息,服务器可以很快的返回用户的状态给客户;
> >> (2)用户在登录系统后通知状态服务器自己已经登陆了。
> >> (3)用户如果从某台具体的功能服务器掉线后,则由这台服务器通知状态服务器用户掉线;
> >> (4)用户可能会在多台功能服务器中来回切换,由客户端与服务器端共同协作以判断用户是为否掉线;
> >> (5)用户定期向状态服务器报告自己的存活状态,如果长时间不报告,则状态服务器把用户从自己的内存状态表中删除;
>

> >> 以上我的瞎解,不一定对,必竞自己没有做过,仅供参考。- 隐藏被引用文字 -- 显示引用的文字 -- 隐藏被引用文字 -- 显示引用的文字 -

Jiang Zhiqiang

unread,
Jan 29, 2007, 12:07:43 AM1/29/07
to dev4s...@googlegroups.com
使用内存数据库cache,把常用的,不需要经常更新数据cache。

sunway

unread,
Jan 29, 2007, 1:23:27 AM1/29/07
to 高性能网络编程邮件列表

谢谢Jiang Zhiqiang的提醒,

On 1月29日, 下午1时07分, "Jiang Zhiqiang" <zhiqia...@gmail.com> wrote:
> 使用内存数据库cache,把常用的,不需要经常更新数据cache。
>
> > SessionID会话标识(int)+AccountID用户账号ID(int)+loginTime登录时间(long)+其它状态(假设用4个byte型---来标明4个状态)=20字节

> > > >> 100万用户*20字节=20,000,000(字节)=19,531.25K==19M(约)
> > > >> 注:一条记录就表示一个在线用户;
>
> > > >> (我靠,我的计算是不是有错误,一台386的内存都够了.....)
> > > >> 看上去,似乎用一台服务器做状态服务器是没有什么问题的;
>
> > > >> 第二个问题,我们这样来定性:
>
> > 假设在服务器端的内存中使用如hashTable这样的存储结构来保存用户的会话状态,hashTable的读操作为0/m复杂度,从100万个记录中读取一条---记录的寻址时间那是相当的快的,快到无法用毫秒来计算,只能用tick(一个CPU的时钟滴答)来计算。1个毫秒=10,000个tick(毫微秒),(h-a-s-hTable的操作平均值是多少我没有统计过不好意思。我就猜个值吧:假设平均为100个tick),如果每次存取hashtable要花费100Ti-ck-,另-外在加上一些业务处理的时间,就按操作一次数据表要1个毫秒来计算吧。

> > > >> 那么1秒钟的时间内就可以处理1000次用户的查询操作;
> > > >> 问题是如果100万用户同时来查询我们该怎么办?
> > > >> 我想可以做负载均衡及服务器集群,当然还要涉汲到网络接口的流量限制,说来就话很长了。
> > > >> 总之,第二个问题看起来,似乎是我们可以通过其它的手段将单台服务器无法处理的工作量分摊到多台服务器中去进行;
>
> > > >> 于是可以得出第一个背景结论:
> > > >> 设置一台服务器将其做为用户状态服务器,用于记录系统中所有用户是否在线等状态信息;通过对服务器制作集群来分摊访问压力;
>
> > > >> 现在我们就可以做以下比较形象的结论和假设了:
>
> > (1)一个用户要查询自己所有好友的在线状态,那么这个用户向刚才所说到的状态服务器发送一条查询消息,服务器可以很快的返回用户的状态给客户;
> > > >> (2)用户在登录系统后通知状态服务器自己已经登陆了。
> > > >> (3)用户如果从某台具体的功能服务器掉线后,则由这台服务器通知状态服务器用户掉线;
> > > >> (4)用户可能会在多台功能服务器中来回切换,由客户端与服务器端共同协作以判断用户是为否掉线;
> > > >> (5)用户定期向状态服务器报告自己的存活状态,如果长时间不报告,则状态服务器把用户从自己的内存状态表中删除;
>
> > > >> 以上我的瞎解,不一定对,必竞自己没有做过,仅供参考。- 隐藏被引用文字 -- 显示引用的文字 -- 隐藏被引用文字 --
> > 显示引用的文字 ---
> Yours: Aaron.Jiang- 隐藏被引用文字 -- 显示引用的文字 -

wyu...@gmail.com

unread,
Jan 29, 2007, 4:31:35 AM1/29/07
to 高性能网络编程邮件列表
大家讨论忽略了一个问题,那就是我提出的问题是基于MSN的那种网络结构方式。也即是Client可能连接的服务器不是同一个。而Client的好友不
可能都连接到同一个服务器上,那么才有讨论这个问题的必要,如果仅仅是一个服务器的话,问题就简单了。

sunway

unread,
Jan 29, 2007, 5:53:44 AM1/29/07
to 高性能网络编程邮件列表
MSN看一些协议分析是把再讨论的一对好友拉到一个单独的机器上,然后他们进行沟通。
QQ这类大部分情况下是P2P,如果不能P2P可能需要服务器转发。服务器如何转发可以
去用户状态服务器查目的方的服务器,然后转发。

> > > > SessionID会话标识(int)+AccountID用户账号ID(int)+loginTime登录时间(long)+其它状态(假设用4个byte型----来标明4个状态)=20字节


> > > > > >> 100万用户*20字节=20,000,000(字节)=19,531.25K==19M(约)
> > > > > >> 注:一条记录就表示一个在线用户;
>
> > > > > >> (我靠,我的计算是不是有错误,一台386的内存都够了.....)
> > > > > >> 看上去,似乎用一台服务器做状态服务器是没有什么问题的;
>
> > > > > >> 第二个问题,我们这样来定性:
>

> > > > 假设在服务器端的内存中使用如hashTable这样的存储结构来保存用户的会话状态,hashTable的读操作为0/m复杂度,从100万个记录中读取一条----记录的寻址时间那是相当的快的,快到无法用毫秒来计算,只能用tick(一个CPU的时钟滴答)来计算。1个毫秒=10,000个tick(毫微秒),(-h-a-s-hTable的操作平均值是多少我没有统计过不好意思。我就猜个值吧:假设平均为100个tick),如果每次存取hashtable要花费100-Ti-ck-,另-外在加上一些业务处理的时间,就按操作一次数据表要1个毫秒来计算吧。


> > > > > >> 那么1秒钟的时间内就可以处理1000次用户的查询操作;
> > > > > >> 问题是如果100万用户同时来查询我们该怎么办?
> > > > > >> 我想可以做负载均衡及服务器集群,当然还要涉汲到网络接口的流量限制,说来就话很长了。
> > > > > >> 总之,第二个问题看起来,似乎是我们可以通过其它的手段将单台服务器无法处理的工作量分摊到多台服务器中去进行;
>
> > > > > >> 于是可以得出第一个背景结论:
> > > > > >> 设置一台服务器将其做为用户状态服务器,用于记录系统中所有用户是否在线等状态信息;通过对服务器制作集群来分摊访问压力;
>
> > > > > >> 现在我们就可以做以下比较形象的结论和假设了:
>
> > > > (1)一个用户要查询自己所有好友的在线状态,那么这个用户向刚才所说到的状态服务器发送一条查询消息,服务器可以很快的返回用户的状态给客户;
> > > > > >> (2)用户在登录系统后通知状态服务器自己已经登陆了。
> > > > > >> (3)用户如果从某台具体的功能服务器掉线后,则由这台服务器通知状态服务器用户掉线;
> > > > > >> (4)用户可能会在多台功能服务器中来回切换,由客户端与服务器端共同协作以判断用户是为否掉线;
> > > > > >> (5)用户定期向状态服务器报告自己的存活状态,如果长时间不报告,则状态服务器把用户从自己的内存状态表中删除;
>
> > > > > >> 以上我的瞎解,不一定对,必竞自己没有做过,仅供参考。- 隐藏被引用文字 -- 显示引用的文字 -- 隐藏被引用文字 --
> > > > 显示引用的文字 ---

> > > Yours: Aaron.Jiang- 隐藏被引用文字 -- 显示引用的文字 -- 隐藏被引用文字 -- 显示引用的文字 -

Fwolf

unread,
Jan 28, 2007, 10:30:54 PM1/28/07
to dev4s...@googlegroups.com
能否参考在web方面应用广泛的集群分流方式
1台主,用于写,N台从,与主同步
正常的读都用从服务器,分流

On Sun, Jan 28, 2007 at 07:18:24PM -0800, sunway wrote:
> DB如何hash,在那一层次加Cache都是值得探讨的问题。我最近就在琢磨这一块的开发,感觉难点很多,不过很有意思。
>

--
http://www.fwolf.com/
"You have been in Afghanistan, I perceive."
-- Sir Arthur Conan Doyle, "A Study in Scarlet"

signature.asc

sunway

unread,
Jan 29, 2007, 8:03:55 PM1/29/07
to 高性能网络编程邮件列表
IM和WEB应用的区别还是比较大的。对于DB方案数据不能放一台机器上,现在流行的做法是HASH到不同数据库,然后在外层加独立的
cacheserver。

On 1月29日, 上午11时30分, Fwolf <fwol...@gmail.com> wrote:
> 能否参考在web方面应用广泛的集群分流方式
> 1台主,用于写,N台从,与主同步
> 正常的读都用从服务器,分流
>

> signature.asc
> 1K下载


>
> On Sun, Jan 28, 2007 at 07:18:24PM -0800, sunway wrote:

> > DB如何hash,在那一层次加Cache都是值得探讨的问题。我最近就在琢磨这一块的开发,感觉难点很多,不过很有意思。--http://www.fwolf.com/

sunbi...@gmail.com

unread,
Jan 30, 2007, 9:32:10 PM1/30/07
to 高性能网络编程邮件列表
zhang yin 的方法基本已经说全了,我在稍加补充说明一下通知好友的流程:

server基本上是这样的结构

client
|
login server 用户登录服务器,保持和用户的回话,要求快速响应。
|
status server 登录状态服务器。维护用户登录信息(用户状态、用户登录的session server)
|
friend notify proc 用户状态通知进程。将用户状态的变迁通知其好友。


要点:
1. 登录状态集中维护。 登录状态不是单个login server自己维护,而是由后台status server(s)来集中维护的,因此数据全
程唯一。
2. 当用户登录时,status server 在修改完状态后,可以通知friend notify proc,由此进程来通知各个好友所在的
login server,login server在通知各client。
3. status server和 friend notify proc 之前采用通知/应答的通信策略,friend notify proc
将通知请求放入请求队列中即返回,status server无需等待所有好友的通知。


On 1月29日, 下午5时31分, "wyu2...@gmail.com" <wyu2...@gmail.com> wrote:

> > > > SessionID会话标识(int)+AccountID用户账号ID(int)+loginTime登录时间(long)+其它状态(假设用4个byte型----来标明4个状态)=20字节


> > > > > >> 100万用户*20字节=20,000,000(字节)=19,531.25K==19M(约)
> > > > > >> 注:一条记录就表示一个在线用户;
>
> > > > > >> (我靠,我的计算是不是有错误,一台386的内存都够了.....)
> > > > > >> 看上去,似乎用一台服务器做状态服务器是没有什么问题的;
>
> > > > > >> 第二个问题,我们这样来定性:
>

> > > > 假设在服务器端的内存中使用如hashTable这样的存储结构来保存用户的会话状态,hashTable的读操作为0/m复杂度,从100万个记录中读取一条----记录的寻址时间那是相当的快的,快到无法用毫秒来计算,只能用tick(一个CPU的时钟滴答)来计算。1个毫秒=10,000个tick(毫微秒),(-h-a-s-hTable的操作平均值是多少我没有统计过不好意思。我就猜个值吧:假设平均为100个tick),如果每次存取hashtable要花费100-Ti-ck-,另-外在加上一些业务处理的时间,就按操作一次数据表要1个毫秒来计算吧。


> > > > > >> 那么1秒钟的时间内就可以处理1000次用户的查询操作;
> > > > > >> 问题是如果100万用户同时来查询我们该怎么办?
> > > > > >> 我想可以做负载均衡及服务器集群,当然还要涉汲到网络接口的流量限制,说来就话很长了。
> > > > > >> 总之,第二个问题看起来,似乎是我们可以通过其它的手段将单台服务器无法处理的工作量分摊到多台服务器中去进行;
>
> > > > > >> 于是可以得出第一个背景结论:
> > > > > >> 设置一台服务器将其做为用户状态服务器,用于记录系统中所有用户是否在线等状态信息;通过对服务器制作集群来分摊访问压力;
>
> > > > > >> 现在我们就可以做以下比较形象的结论和假设了:
>
> > > > (1)一个用户要查询自己所有好友的在线状态,那么这个用户向刚才所说到的状态服务器发送一条查询消息,服务器可以很快的返回用户的状态给客户;
> > > > > >> (2)用户在登录系统后通知状态服务器自己已经登陆了。
> > > > > >> (3)用户如果从某台具体的功能服务器掉线后,则由这台服务器通知状态服务器用户掉线;
> > > > > >> (4)用户可能会在多台功能服务器中来回切换,由客户端与服务器端共同协作以判断用户是为否掉线;
> > > > > >> (5)用户定期向状态服务器报告自己的存活状态,如果长时间不报告,则状态服务器把用户从自己的内存状态表中删除;
>
> > > > > >> 以上我的瞎解,不一定对,必竞自己没有做过,仅供参考。- 隐藏被引用文字 -- 显示引用的文字 -- 隐藏被引用文字 --
> > > > 显示引用的文字 ---

> > > Yours: Aaron.Jiang- 隐藏被引用文字 -- 显示引用的文字 -- 隐藏被引用文字 -
>
> - 显示引用的文字 -

sunway

unread,
Jan 30, 2007, 10:35:36 PM1/30/07
to 高性能网络编程邮件列表
当然IM的登陆流程和你描述的都差不太多,但是实际应用要根据负载的在线人数和具体硬件情况,
多服务器的功能可能由一个服务器来实现也未尝不可。

On 1月31日, 上午10时32分, "sunbird...@gmail.com" <sunbird...@gmail.com>
wrote:

> > > > > SessionID会话标识(int)+AccountID用户账号ID(int)+loginTime登录时间(long)+其它状态(假设用4个byte型-----来标明4个状态)=20字节


> > > > > > >> 100万用户*20字节=20,000,000(字节)=19,531.25K==19M(约)
> > > > > > >> 注:一条记录就表示一个在线用户;
>
> > > > > > >> (我靠,我的计算是不是有错误,一台386的内存都够了.....)
> > > > > > >> 看上去,似乎用一台服务器做状态服务器是没有什么问题的;
>
> > > > > > >> 第二个问题,我们这样来定性:
>

> > > > > 假设在服务器端的内存中使用如hashTable这样的存储结构来保存用户的会话状态,hashTable的读操作为0/m复杂度,从100万个记录中读取一条-----记录的寻址时间那是相当的快的,快到无法用毫秒来计算,只能用tick(一个CPU的时钟滴答)来计算。1个毫秒=10,000个tick(毫微秒),-(-h-a-s-hTable的操作平均值是多少我没有统计过不好意思。我就猜个值吧:假设平均为100个tick),如果每次存取hashtable要花费1-00-Ti-ck-,另-外在加上一些业务处理的时间,就按操作一次数据表要1个毫秒来计算吧。

Reply all
Reply to author
Forward
0 new messages