我没有确切的计划要把这篇文章写多长,所以暂时先写第一篇。

因为工作需要所以才做一个聊天服务器,但随着工作的深入也有了一些体会。同样也是作为g-chat-server的广告。

第一个实现

用C#写成,借鉴了一个貌似名叫FlexSocket的开源项目。排除掉所有的bug后基本性能指标如下:

指标
检测最大连接数 300+
最大稳定运行时间 10天
常见故障 连接时:Connection Refused
CPU占用 很低
内存占用 10-20M
压力测试情况 超过500连接后无故down机后未做更多测试

设计原理:采用单线程方式,主线程负责处理一切事务。

瓶颈:由于单线程,所以无论是客户端的管理还是消息的处理以及IO处理都由一个线程完成,最终导致代码本身就很不合理,并且bug较多。

初始模型

唯一的一个类,看起来太弱不禁风了。

第二个实现

吸取第一款产品的经验和教训,采用多线程。其中单例的ServerThread负责Socket的接入(accept()),单例的ProcessThread负责消息的逻辑处理和转发。InputThread和OutputThread负责网络的IO和消息的装箱/拆箱。详情请参见:http://code.google.com/p/g-chat-server/

第二个设计

产品规格最终如下:

指标
检测最大连接数 15000+
最大稳定运行时间 21天
常见故障
CPU占用 低-高
内存占用 128M-256M
空负载情况 连接数超出18000+后部分连接会出现ConnectionRefused,CPU低于10%,内存使用低于128M
满负载情况 在每个连接每3秒发送全局广播情况下,连接数超出1200+后部分连接会出现ConnectionRefused,在双核CPU机器上,能够稳定运行在800客户端线程,内存占用256M,CPU使用55%-60%,每秒接收消息800/3,发送消息200000+。

总结一下两款实现的经验:

1. 当线程数量不足时导致网络I/O延迟会在Windows系统中产生很高的CPU占用率。

2. 要把线程按职责分开使之拥有高度空闲率才能够保证整个系统的稳定和高效。

3. 在第二款实现中消息处理线程由于使用单例模式所以在高负载的情况下只能使用有限的资源(CPU)。

4. G-chat-server在线程通信、缓存管理以及消息处理线程上处理的不够理想。