twisted实现轻量高并发http server

来源:互联网 发布:nginx tcp 反向代理 编辑:程序博客网 时间:2024/06/10 01:23

本人使用twisted的一些经验总结及要点

  • twisted使用epoll异步模型,有助于提高性能,这个不啰嗦,大家都应该懂;可以做如下判断
if "Windows" not in platform.system():    from twisted.internet import epollreactor    epollreactor.install()
  • twisted这种异步框架逻辑处理方面,不能够处理比较耗时的操作,不然会造成内存和性能的问题,如果有需要阻塞的操作,可以在逻辑处理之外,单独启动一个线程
from twisted.python import threadablethreadable.init(1)   # 使用twisted安全线程# 在主线程中单独启动一个子线程做事情reactor.callInThread(do_something)
  • 在write数据回客户端并发量上来的时候,可能会遇到notifyFinish 相关的unhandler error错误,需要在write时做如下判断
   if (not request.finished and not request._disconnected):          request.write(str(source))          request.finish()    else:        request.notifyFinish()
  • 很重要的一点,如果有在逻辑处理函数里涉及读写数据库操作,在有大并发要求的时候,数据库的连接需要使用连接池,任何在处理业务逻辑函数里,进行阻塞式操作,都容易引起服务性能问题

如下是一些twisted一些较完整的代码,经过验证,长期稳定(db需要连接池)

import sysreload(sys)sys.setdefaultencoding("utf-8")import platformif "Windows" not in platform.system():    print "Linux System! Use epoll"    from twisted.internet import epollreactor    epollreactor.install()import socketfrom twisted.python import threadablethreadable.init(1)   # 使用twisted安全线程from twisted.internet import reactorfrom twisted.internet.threads import deferToThreadreactor.suggestThreadPoolSize(20000)from twisted.python.logfile import *from twisted.web.resource import Resourcefrom twisted.web.server import Sitefrom twisted.web.server import NOT_DONE_YETfrom twisted.python import logif not os.path.exists('log'):    os.makedirs('log')log.startLogging(DailyLogFile('proxyserver%s_%s' % (time.strftime('%Y_%m_%d'), os.getpid()), "./log"), setStdout=0)socket.setdefaulttimeout(80)class NotFount(Resource):    def getChild(self, name, request):        return self    def render_GET(self, request):        return '404 Not Find'def render_data(request, source):    """    将获取到的srouce字符串 写回客户端    :param request:     :param source:     :return:     """    if (not request.finished and not request._disconnected):  # 这个判断很有必要,不然在并发量上来的时候,会抛notifyFinish相关的异常        request.write(str(source))          request.finish()    else:        request.notifyFinish()class LogicHandler(Resource):    def doSomeThing(self, request):        post_args = request.content.getvalue()        '''            do something            :return str to client        '''        return 'return_str'    def render_POST(self, request):        d = deferToThread(self.save_used_ip_and_get_new_ip, request)        d.addBoth(lambda x: render_data(request, x))        return NOT_DONE_YETclass ServerHandle(Resource):    def getChild(self, path, request):        try:            if path == "qyxx_new":                return LogicHandler()            else:                return NotFount()         except Exception as e:            log.err(u'请求无效的url,[%s]' % e)def do_something():    """    do something    :return:     """if __name__ == '__main__':    reactor.callInThread(do_something)  # 起动子线程,动态刷新配置文件    root = ServerHandle()    factory = Site(root, timeout=60)    HTTPPORT = 8888    reactor.listenTCP(HTTPPORT, factory)    reactor.run()
原创粉丝点击