1
mengskysama 2014-12-18 14:59:47 +08:00
你用ThreadedTCPServer这种线程模型上万台设备肯定不行,现在你几台OK,随着设备数量增多线程将会变多,整个程序效率就会更低,线程模型如果有大量的锁,这个问题变得更复杂,这就是现在基本上没有高并发Server会使用这种模型的原因。
python线程数量是有限制的,在win下面甚至不能超过1K,考虑最坏的情况如果有1K个设备同时建立连接,更多的设备心跳就接收不到。 |
2
EPr2hh6LADQWqRVH 2014-12-18 15:06:53 +08:00
官方文档的参考还不够吗?
官方的smtpd代码可以看一下,就是实例之一。 |
3
nbndco 2014-12-18 15:07:25 +08:00
zeromq?
|
4
mengskysama 2014-12-18 15:10:43 +08:00
别用这货了,现在成熟的异步框架多了去了tornodo twisted之类的...
|
5
mengzhuo 2014-12-18 15:31:48 +08:00
同楼上smtpd,可以理解基本思路
如果上异步的话可以试试我写的gsmtpd https://github.com/34nm/gsmtpd C10K 下 最多7000RPS 一个进程 楼主想更高的话只能上multiprocess了,更高的话找LVS HAPROXY之类的吧 |
6
myrual 2014-12-18 15:37:08 +08:00
如果你的业务逻辑就是建立设备连接的时候开始创建一个记录,然后不断把设备上发的数据存起来,然后链接断开的时候把它删除掉,我建议你直接用twisted就可以。自带的例程就可以帮助你搞定这件事情。
记住打开epoll模式,可以把性能提升很多。 但是twisted里面不要想当然的呼叫引发阻塞的操作,比如数据库写,sleep,io等等,因为如果你需要一个这样的操作,需要查手册里面对于这种需求的对应方案。 如果你不习惯这种编程模式,我建议你使用go 写一个,学习难度和你学twisted 差不多,但是至少你可以用线性的思维写一个性能不错的tcp 服务器。 |
7
myrual 2014-12-18 15:39:45 +08:00
还有一个能用的东西叫做 gevent,也不错。
|
8
20150517 2014-12-18 15:54:48 +08:00 via Android
上万台设备,你得用cassandra,否则怎么撑的住?
|
9
mengskysama 2014-12-18 16:17:08 +08:00
|
10
zaxaca 2014-12-18 16:48:34 +08:00
用twisted吧,用起来相当不错,性能也够用!
|
11
sbmzhcn OP 非常感谢大家的回复, 看到大家的回复都比较专业,看来这样的应用还是应该花钱让公司找人去做,目前并不太可能有超过上百个设备的,那是以后的事了,现在这个问题还没有很好的解决,实现的过程很简陋,虽然也能接收数据,发送数据但感觉不太优雅。
目前如果按照我上面的代码,如何实现把每个连接放在一个列表里,并且可以随时操作其中一个连接。当前连接应该包含设备的id, ip, 等一些信息。 |
12
wog 2014-12-18 18:05:01 +08:00
没用python处理过这么底层的东西,其实做到这么底层了,如果不打算用python现成的三方库,建议直接用c吧,你说的这些用c实现比python复杂不了多少,使用epull模型,可以很方便的实现你要的功能,甚至用c处理链接,然后把数据给python处理也行
|
13
leyle 2014-12-18 18:25:14 +08:00
select() 一般不超过 1024 个文件描述符,先天限制了不可能支持大并发。
想要支持成千上万个客户端,你是在 linux 上写的程序,这个时候,你需要 epoll 来处理 I/O 多路复用的问题,然后你再考虑用多线程或者多进程来处理你的业务逻辑。 你可以参考这个 [[翻译]python调用linux epoll编程指南 - 遗落岛] http://www.leyle.com/archives/how_to_use_linux_epoll_with_python.html |
14
mengskysama 2014-12-18 18:26:51 +08:00
这个属于设计模式的范围了。
用个全局的字典存id和Handler的对应,每个Handler里有2个队列接收一个发送一个,然后一个死循做读写。。 对某个id发送数据只需要在全局字典里面找到Handler,然后往队列里面丢就行了。 |
15
pubby 2014-12-18 18:29:55 +08:00
一台搞不定也没必要死磕嘛,入口IP上做轮询转发到后端多个服务器即可
|
16
datou552211 2014-12-18 23:19:27 +08:00 via iPhone
感觉golang适合你的需求
|
17
bugeye 2014-12-19 09:28:33 +08:00
nodejs天生就是为了你这种情况而生的。
|
18
sbmzhcn OP @mengzhuo 非常感谢你的代码,能具体再和我说说这段代码吗?
with Timeout(self.timeout, ConnectionTimeout): sc = DSCChannel(self, sock, addr, self.data_size_limit) 这段代码是不是必须会超时。我需要服务器一直不停的接收,不中断,但我测试你的代码,无论怎么样总会超时。 |
19
mengzhuo 2014-12-20 22:42:20 +08:00 1
|
20
rcmerci 2014-12-21 22:11:23 +08:00
上erlang
|
21
sbmzhcn OP @mengzhuo 再次提问,不好意思。在示例process_message 中的 process_message, 我如果直接把数据写入mysql会不会出现问题,比如性能问题?
|
22
sbmzhcn OP class DebuggingServer(SMTPServer):
# Do something with the gathered message def process_message(self, peer, mailfrom, rcpttos, data): inheaders = 1 lines = data.split('\n') print '---------- MESSAGE FOLLOWS ----------' for line in lines: # headers first if inheaders and not line: print 'X-Peer:', peer[0] inheaders = 0 print line print '------------ END MESSAGE ------------' 指以上代码中。 |
23
mengzhuo 2014-12-22 22:41:13 +08:00 1
|
24
sbmzhcn OP @mengzhuo 现在已经能跑了,各方面都测试没问题,就差最后的存储数据了。python操作mysql还不清楚哪个好,想用上面有人推荐的txmysql,不知道怎么和你这结合。你有什么推荐的吗?
|
28
sbmzhcn OP @mengskysama 有这方面的代码没?
|
29
wuyadong 2014-12-30 13:25:53 +08:00
存手工写异步的tcpserver,好麻烦的说...找到一个非阻塞的TCPServer的DEMO
https://github.com/JobsDong/SimpleServer |