
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 |
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 |
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 |