TCP/IP 异步 多线程 数据同步程序的优化,喜欢优化方案的朋友过来看看

风之影子 2012-08-28 05:34:48
估计很快就会被列入标题党了。

入正题了,项目说明:一个基于TCP/IP的通讯程序(可以理解为变种QQ),C端负责发送订单(单客户端数据量60条/分,客户端数量预计上万,因为是全国范围),S端接收后,先存,再处理,再分发给其它在线C端。

S端异步+线程进行监测连接和数据包到达;
C与S的连接目前是一个端口,考虑到粘包情况,S端独立线程收包,随后独立线程判断包的完整性,再提交给处理线程进行处理(判断完整性和处理用了数据同步),再接着提交给分发线程(负责入库和分发)。


附加说明:数据在内存的存储用了hashtable。每个订单的数据大概是200-300个汉字。

程序运行于外网。



问题:就目前这种情况,这种方案有什么可优化的。或是有什么好的方案。望坛友讨论一下。
...全文
344 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
风之影子 2012-08-31
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 的回复:]

libinguest,你的框架最后确定没?
[/Quote]

你说说吧,是不是有什么好的方案呢?

基本上确定了,后期还有些优化工作。
wirner 2012-08-30
  • 打赏
  • 举报
回复
libinguest,你的框架最后确定没?
showjim 2012-08-29
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 的回复:]
漏看这个功能了:
数据是必须即时转发还是可以适当延时?
每次都要转发所有在线用户还是只转给该用户的好友?
如果我来做
我可能不会使用服务端转发,也不会使用P2P
服务端转发会让服务端更加繁忙
P2P会增加开发的难度,而且P2P环境各异,P2P失败率不低啊
我的做法:
各客户端增加一个心跳命令,心跳时隔可以适当延长
如果需要更新数据,就在心跳包里返回给客户端
客户端主动去服务端更新数据
这样做还有一个好处,可以在服务端控制同时更新的客户端数据
例如,每次只能100个客户端同时更新
处理完这100个客户端,才进行下一轮
[/Quote]
真有这么大数据量,延时发送能降低网络流量吗?掩耳盗铃而已。

数据流量大却不分流的话,只能想到批量处理并压缩的办法。
风之影子 2012-08-29
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 的回复:]

我没有做过TCP/IP的,但是接触过CANOpen的,我觉得会不会适合“总线型结构”?
1)C端发送订单,发送的时候在订单前加上目标地址(可以是客户端的IP或MAC地址),然后发到总线上(因特网);
2)每个客户端都可以在总线上监听到这帧报文,但是只有与这帧报文里的报头(预定义客户端的MAC地址)相匹配的客户端才会接受,其他的客户端则不接受;
3)这个收到报文的S端开始处理数据,于此同时,……
[/Quote]

恩:类似模式。
现在想要优化方案。
风之影子 2012-08-29
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 的回复:]

我没有做过TCP/IP的,但是接触过CANOpen的,我觉得会不会适合“总线型结构”?
1)C端发送订单,发送的时候在订单前加上目标地址(可以是客户端的IP或MAC地址),然后发到总线上(因特网);
2)每个客户端都可以在总线上监听到这帧报文,但是只有与这帧报文里的报头(预定义客户端的MAC地址)相匹配的客户端才会接受,其他的客户端则不接受;
3)这个收到报文的S端开始处理数据,于此同时,……
[/Quote]

恩:类似模式。
现在想要优化方案。
beijixiong2000 2012-08-29
  • 打赏
  • 举报
回复
我没有做过TCP/IP的,但是接触过CANOpen的,我觉得会不会适合“总线型结构”?
1)C端发送订单,发送的时候在订单前加上目标地址(可以是客户端的IP或MAC地址),然后发到总线上(因特网);
2)每个客户端都可以在总线上监听到这帧报文,但是只有与这帧报文里的报头(预定义客户端的MAC地址)相匹配的客户端才会接受,其他的客户端则不接受;
3)这个收到报文的S端开始处理数据,于此同时,总线已经空闲,于是C端此时可以继续给其他的MAC地址的客户端发送报文;
4)第一个S端处理完数据之后,将带有目标MAC地址的报文发送出去,目标地址便接受这帧报文;
但是这里就存在了一个问题:就是第二个目标地址可以接受总的发送端C端给它发送的报文,也可以接受其他处理数据完毕后中转的S端给他发送的报文;
这就必须要定义一个优先级,比如可以定义成S端总优先接受来自C端的报文,接受完了之后,才会接受来自其他S端的报文;

我是个菜鸟,TCP不懂,仅仅是来占个座,帮顶一下而已

顶贴
风之影子 2012-08-29
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 的回复:]

我对这个话题很感兴趣,libinguest,SocketUpEx望指点!
[/Quote]

意思是返回给客户端的心跳包里含有“是否更新”命令,客户端接收到含有“更新”的命令返回值后,主动发送请求更新客户端的数据到服务器?

至于交互的协议你可以自己定。
不过后面你理解反了,是C与S有心跳机制,S是被动下发,C是主要去要。当然上面还有人提到,可以采用分批处理客户端的主要申请
wirner 2012-08-29
  • 打赏
  • 举报
回复
我对这个话题很感兴趣,libinguest,SocketUpEx望指点!
wirner 2012-08-29
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 的回复:]
引用 7 楼 的回复:
再分发给其它在线C端


漏看这个功能了:
数据是必须即时转发还是可以适当延时?
每次都要转发所有在线用户还是只转给该用户的好友?
如果我来做
我可能不会使用服务端转发,也不会使用P2P
服务端转发会让服务端更加繁忙
P2P会增加开发的难度,而且P2P环境各异,P2P失败率不低啊
我的做法:
各客户端增加一个心跳命令,心跳时隔可以适当延长
如果需要……
[/Quote]

请教一个问题:
1. “如果需要更新数据,就在心跳包里返回给客户端
客户端主动去服务端更新数据”。意思是返回给客户端的心跳包里含有“是否更新”命令,客户端接收到含有“更新”的命令返回值后,主动发送请求更新客户端的数据到服务器?

2. 客户端采用你之前说的“用SocketAsyncEventArgs

一组线程收包,直接扔到组包缓存队列
一组线程组包,直接扔到回调缓存队列
一条线程回调返回给上层
”方式更新到服务器上?
风之影子 2012-08-29
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]

我又看了一下我们的框架,大概是这样的:
用SocketAsyncEventArgs

一组线程收包,直接扔到组包缓存队列
一组线程组包,直接扔到回调缓存队列
一条线程回调返回给上层

最后
你的客户端数不是很多
命令包数也不多
服务器没压力
数据库会不会是瓶颈呢?
[/Quote]

数据库有瓶颈目前不是问题。

因为这个数据量如你所说, 不太大,主要体现在C与S的实时通讯。交互方面。S端是统一操作数据库,只会延时,或是批量入库。
风之影子 2012-08-29
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 的回复:]

引用楼主 的回复:
单客户端数据量60条/分,客户端数量预计上万

是否需要每秒处理10000条数据?单机不太适合做这事。
如果需要删改,单机数据库肯定受不了。
就算只增加数据,也只能批量写入,单机硬盘受不了每秒几万次的读写。

引用楼主 的回复:
每个订单的数据大概是200-300个汉字

那么处理数据网络流量接近10M/s,这个没问题,但是下面的问题大了。

引用……
[/Quote]


恩:可以考虑,用心跳机制来实现即时数据的客户端交互。
SocketUpEx 2012-08-28
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 的回复:]
再分发给其它在线C端
[/Quote]

漏看这个功能了:
数据是必须即时转发还是可以适当延时?
每次都要转发所有在线用户还是只转给该用户的好友?
如果我来做
我可能不会使用服务端转发,也不会使用P2P
服务端转发会让服务端更加繁忙
P2P会增加开发的难度,而且P2P环境各异,P2P失败率不低啊
我的做法:
各客户端增加一个心跳命令,心跳时隔可以适当延长
如果需要更新数据,就在心跳包里返回给客户端
客户端主动去服务端更新数据
这样做还有一个好处,可以在服务端控制同时更新的客户端数据
例如,每次只能100个客户端同时更新
处理完这100个客户端,才进行下一轮

showjim 2012-08-28
  • 打赏
  • 举报
回复
[Quote=引用楼主 的回复:]
单客户端数据量60条/分,客户端数量预计上万
[/Quote]
是否需要每秒处理10000条数据?单机不太适合做这事。
如果需要删改,单机数据库肯定受不了。
就算只增加数据,也只能批量写入,单机硬盘受不了每秒几万次的读写。

[Quote=引用楼主 的回复:]
每个订单的数据大概是200-300个汉字
[/Quote]
那么处理数据网络流量接近10M/s,这个没问题,但是下面的问题大了。

[Quote=引用楼主 的回复:]
再分发给其它在线C端
[/Quote]
其他在线C端如果预计上万,那么网络流量10000*10M/s=100G/s。
需要确认这数据一定要分发吗?还是让C端自己根据需要来取数据?
如果一定要分发,就需要使用P2P技术,让在线C端相互发数据。
wirner 2012-08-28
  • 打赏
  • 举报
回复
SocketUpEx, libinguest,能介绍点相关的资料吗?我一个项目也是和libinguest的类似,还不知道如何着手呢。
SocketUpEx 2012-08-28
  • 打赏
  • 举报
回复

每秒才400-500个包啊
我以为每秒会有1W个包呢
这样算来,数据库也没压力了


SocketUpEx 2012-08-28
  • 打赏
  • 举报
回复
我又看了一下我们的框架,大概是这样的:
用SocketAsyncEventArgs

一组线程收包,直接扔到组包缓存队列
一组线程组包,直接扔到回调缓存队列
一条线程回调返回给上层

最后
你的客户端数不是很多
命令包数也不多
服务器没压力
数据库会不会是瓶颈呢?

风之影子 2012-08-28
  • 打赏
  • 举报
回复
也在考虑用queue

之后放弃了,因为包不一定什么时候删除。

也不是按顺序来的。
风之影子 2012-08-28
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]

单客户端数据量60条/分,客户端数量预计上万
每秒峰值多少个包呢?
几台服务器?
hashtable换成Queue是不是好点呢?
[/Quote]
峰值有400-500个包

单台服务器

也在考虑用queue


有什么好的建议吗?
SocketUpEx 2012-08-28
  • 打赏
  • 举报
回复
单客户端数据量60条/分,客户端数量预计上万
每秒峰值多少个包呢?
几台服务器?
hashtable换成Queue是不是好点呢?


110,533

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧