|  |      1reusFork      2014-09-11 11:03:45 +08:00  1 epoll是用来通知io事件的,和线程无关,和上下文切换也无关。线程的上下文切换也不会产生10秒的差别。epoll不是选举算法,等待io时切换,那是协程负责的工作。 没有具体的代码,没人可以帮你定位bug。 | 
|  |      2pyKun OP @reusFork  怀疑到 epoll 是因为,用 python 的 trace 模块追踪 server 这块的时候,发现消耗时间最多的是: .... 56.894 .... {method 'poll' of 'select.epoll' objects} 56秒那个是这段测试时间,跑 select.epoll.poll 这里总的消耗时间(平均的 * 次数) 在并发5,请求 100 次的时候 epoll.poll 一共消耗了 56 秒 但是顺序请求 100 次的时候,这里只有 3 秒多(另外一个不同时,这个方法被 call 的次数在鬓发的时候 2w 到 4w 不等,顺序的时候,只有 1w;平均消耗时间,并发的时候是 0.03s,顺序的时候 0.00s 就是小于 0.005s) (上文的 25s ~ 35s 只是举例子) 另外,select 模块的位置是 /usr/lib64/python2.6/lib-dynload/selectmodule.so rpm -qf 这个文件发现这个位置的文件是来自于 python-libs 这个包 以上均是客观事实了,能帮我小分析下么 :) | 
|  |      3pyKun OP | 
|      4nybux      2014-09-11 12:30:35 +08:00  1 适合epoll,但是不适合你这样做,mysql调用要调度到一个线程池里面。或者你用pymysql+gevent,把mysql的netio也异步化 | 
|  |      5pyKun OP | 
|  |      6mucid      2014-09-11 13:18:40 +08:00 mysql得用异步驱动才行 | 
|  |      7dafang      2014-09-11 13:24:26 +08:00 连接MySQL的地方,改用nonblocking的库... | 
|      8nybux      2014-09-11 14:31:42 +08:00 你现在的瓶颈在于mysql请求,虽然通过eventlet可以在单线程中并发处理大量请求,但是因为整个程序是单线程的。所以,所有的mysql处理最终还是会排队执行。整个程序的吞吐量就是取决于你的单线程执行mysql的效率。所以把mysql请求放到线程池中,就能缓解状况。 | 
|  |      9leyle      2014-09-11 18:44:49 +08:00 via Android 100次顺序请求都要耗时25秒,首先需要解决的是单次请求的耗时吧,服务端从接到请求到处理完毕,单次千分之一秒的耗时我觉得还算能接受 | 
|  |      10leyle      2014-09-11 18:47:45 +08:00 via Android 并且你对 epoll 的理解是错的,如果想深入正经的理解几种无阻塞 I/O 模型,可以参考 the linux programming interface 64章的内容 | 
|  |      11pyKun OP @leyle  100次请求是实际的,25s和35s是在主贴里大概描述的,顺序的情况下都0.02s左右完成,再优化是之后的任务了,不过千分之一秒这个目标不错,自己之前没啥概念 我遇到的问题还是如之前所说,并发的时候(哪怕并发只有5)会出现诡异情况: 1. 0.2s 2. 0.2s 3. 15s 4. 0.2s ... python的trace结果是select.epoll.poll总耗时太长(顺序的总耗时3s左右,5并发100总请求的情况都有50s了) 正在用大家意见调整mysql到nonblocking再测 | 
|  |      12mengskysama      2014-09-12 09:09:04 +08:00 你这个业务流程就是顺序执行嘛,为啥会用epool。worker模式不用epool,参照php cgi。 异步数据库处理时间不会比现在少,空转和异步cb的时间应该是相当的。 先查查是不是数据库是不是有锁表,还有数据库是不是有连接数或者性能上限制。 | 
|  |      13pyKun OP |