ag娱乐平台
你好,游客 登录 注册
背景:
阅读新闻

Tornado实现多进程/多线程的HTTP服务

[日期:2019-04-09] 来源:Linux社区  作者:zhichaoma [字体: ]

ag娱乐平台,这段拍摄于11月28日的视频显示,这只猫坐在地上,被冻住的爪子夹在它的身体下面,冷得直颤抖。所幸的是,一对俄罗斯夫妇发现了它,立即用热水使冰融化,帮助它逃离冰坑。

规划共9部分。第一部分为规划背景。简要概括全国技工教育发展现状、存在的问题和面临的形势。第二部分为总体要求。一是明确“十三五”时期技工教育的指导思想,着重强调根本要求、发展导向、培养核心、办学理念和发展目的。二是提出坚持统筹规划、坚持就业导向、坚持内涵发展、培育工匠精神的基本原则。三是明确提出“布局更加合理、功能更加健全、管理更加规范、质量持续提升、特色更加鲜明、环境更加优化”的六大发展目标。第三至八部分为主要措施。主要是对应六大发展目标,分别提出具体措施。在优化布局方面,重点是统筹东、中、西部区域协调发展,优化技工院校结构,大力发展技师学院,支持行业企业办和民办院校发展,稳定学制教育规模。在增强社会服务能力方面,重点是明确技工教育必须服务就业创业、服务技能人才发展、服务脱贫攻坚、强化国际合作交流等要求。在规范管理方面,主要从规范技工院校内部管理、学制、学籍、资助和督导评估等方面提出要求。在提高质量方面,重点是加强专业建设、教材建设、科研教研、师资建设、信息化建设等工作。在增强特色方面,重点是坚持校企合作、高端培养、标准化发展等特色。在优化发展环境方面,主要从政策、资金、项目、宣传等方面,引导各地、各行业加大对技工院校的支持。第九部分为组织实施。主要从加强组织领导、统筹协调、监测评估方面提出具体要求。Uber和Waymo专利诉讼将出结果:或决定自动驾驶未…GTC4 Lusso T的百公里加时速为3.5秒,仅比GTC4 Lusso慢0.1秒。前者的最高时速为199英里(约合320公里)。前者的油耗为24.4英里/加仑(约合11.6升/百公里),二氧化碳排放量为265克/公里。

用Tornado Web服务的基本流程

1.实现处理请求的Handler,该类继承自tornado.web.RequestHandler,实现用于处理请求的对应方法如:get、post等。返回内容用self.write方法输出。

2.实例化一个Application。构造函数的参数是一个Handlers列表,通过正则表达式,将请求与Handler对应起来。通过dict将Handler需要的其他对象以参数的方式传递给Handler的initialize方法。

3.初始化一个tornado.httpserver.HTTPServer对象,构造函数的参数是上一步的Application对象。

4.为HTTPServer对象绑定一个端口。

5.开始IOLoop。

需要用到的特性

由于tornado的亮点是异步请求,所以这里首先想到的是将所有请求都改造为异步的。但是这里遇到一个问题,就是异步函数内一定不能有阻塞调用出现,否则整个IOLoop都会被卡住。这就要求彻底地去改造服务,将所有IO或是用时较长的请求都改造为异步函数。这个工程量是非常大的,需要去修改已有的代码。因此,我们考虑用线程池的方式去实现。当一个线程阻塞在某个请求或IO时,其他线程或IOLoop会继续执行。

另外一个瓶颈就是GIL限制了CPU的并发数量,因此考虑用子进程的方式增加进程数,提高服务能力上限。

综合上面的分析,大致用以下方案:

1.通过子进程的方式复制多个进程,使子进程中的只读页指向同一个物理页。

2.线程池。回避异步改造的工作量,增加IO的并发量。

测试代码

首先测试线程池,测试用例为:

对sleep页面同时发出两个请求:

1.在线程池中运行的函数(这里是self.block_task)能够同时执行。表现为在控制台交替打印出数字。

2.两个get请求几乎同时返回,在浏览器上显示返回的内容。

线程池的测试代码如下:

import os
import sys
import time
 
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
import tornado.gen
from tornado.concurrent import run_on_executor
from concurrent.futures import ThreadPoolExecutor
from tornado.options import define, options
 
class HasBlockTaskHandler(tornado.web.RequestHandler):
    executor = ThreadPoolExecutor(20)  #起线程池,由当前RequestHandler持有
   
    @tornado.gen.coroutine
    def get(self):
        strTime = time.strftime("%Y-%m-%d %H:%M:%S")
        print "in get before block_task %s" % strTime
        result = yield self.block_task(strTime)
        print "in get after block_task"
        self.write("%s" % (result))
 
    @run_on_executor
    def block_task(self, strTime):
        print "in block_task %s" % strTime
        for i in range(1, 16):
            time.sleep(1)
            print "step %d : %s" % (i, strTime)
        return "Finish %s" % strTime
 
if __name__ == "__main__":
    tornado.options.parse_command_line()
    app = tornado.web.Application(handlers=[(r"/sleep", HasBlockTaskHandler)], autoreload=False, debug=False)
    http_server = tornado.httpserver.HTTPServer(app)
    http_server.bind(8888)
    tornado.ioloop.IOLoop.instance().start()

整个代码里有几个位置值得关注:

1.executor = ThreadPoolExecutor(20)。这是给Handler类初始化了一个线程池。其中concurrent.futures不属于tornado,是Python的一个独立模块,在python3中是内置模块,python2.7需要自己安装。

2.修饰符@run_on_executor。这个修饰符将同步函数改造为在executor(这里是线程池)上运行的异步函数,内部实现是将被修饰的函数submit到executor,返回一个Future对象。

3.修饰符@tornado.gen.coroutine。被这个修饰符修饰的函数,是一个以同步函数方式编写的异步函数。原本通过callback方式编写的异步代码,有了这个修饰符,可以通过yield一个Future的方式来写。被修饰的函数在yield了一个Future对象后将会被挂起,Future对象的结果返回后继续执行。

运行代码后,在两个不同浏览器上访问sleep页面,得到了想要的效果。这里有一个小插曲,就是如果在同一浏览器的两个tab上进行测试,是无法看到想要的效果。第二个get请求会被block,直到第一个get请求返回,服务端才开始处理第二个get请求。这让我一度觉得多线程没有生效,用了半天时间查了很多资料,才看到是浏览器把相同的第二个请求block了,具体链接参考这里。

由于tornado很方便地支持多进程模型,多进程的使用要简单很多,在以上例子中,只需要对启动部分稍作改动即可。具体代码如下所示:

if __name__ == "__main__":
    tornado.options.parse_command_line()
    app = tornado.web.Application(handlers=[(r"/sleep", HasBlockTaskHandler)], autoreload=False, debug=False)
    http_server = tornado.httpserver.HTTPServer(app)
    http_server.bind(8888)
    print tornado.ioloop.IOLoop.initialized()
    http_server.start(5)
    tornado.ioloop.IOLoop.instance().start()

需要注意的地方有两点:

app = tornado.web.Application(handlers=[(r"/sleep", HasBlockTaskHandler)], autoreload=False, debug=False),在生成Application对象时,要将autoreload和debug两个参数至为False。也就是需要保证在fork子进程之前IOLoop是未被初始化的。这个可以通过tornado.ioloop.IOLoop.initialized()函数来跟。
http_server.start(5)在启动IOLoop之前通过start函数设置进程数量,如果设置为0表示每个CPU都启动一个进程。

最后的效果是可以看到n+1个进程在运行,且公用同一个端口。

Linux公社的RSS地址/wwwc0b7linuxidcc0b7com/rssFeed.aspx

本文永久更新链接地址/wwwc0b7linuxidcc0b7com/Linux/2019-04/158006.htm

linux
本文评论   查看全部评论 (0)
表情: 表情 姓名: 字数

       

评论声明
  • 尊重网上道德,遵守中华人民共和国的各项有关法律法规
  • 承担一切因您的行为而直接或间接导致的民事或刑事法律责任
  • 本站管理人员有权保留或删除其管辖留言中的任意内容
  • 本站有权在网站内转载或引用您的评论
  • 参与本评论即表明您已经阅读并接受上述条款
篮球培训机构YBDL获5000万元A+轮融资 复星锐正… 牛汇:4月17日外汇交易提醒 网易一季度净收入141.73亿元 周四股票下跌7.46… 金毛撞上兰博基尼车损近40万 车主掏2000带狗治疗 曝鲁能申请终止与助教合同:擅自离队+不服管理 Facebook数据被滥用引起公众质疑:涉及5000万… 走失男孩见警察喊不要抓我:家长平时用警察吓唬 网易高管解读财报:在游戏研发上采取齐头并进策略 空头暂占上风 黄金势创近五年最长连跌纪录 女友崩溃 男子28岁仍和母亲睡一张床 场均3球!皇马2018火力冠绝欧洲 比巴黎曼城都猛 媒体:提高违法成本 以“惩罚性赔偿”保护原创
智能音箱上演价格战:低价扩大市场 产业遭遇透支 莫德斯特恐要坐穿板凳:闹一堆事 没底气和帕托争 有色金属回调 “挺铝派”隐现 长安剑:最高检新规将杜绝“假精神病”司法腐败 外媒称美国对华贸易施压“没道理”:美更需要中国 2亿美元收购糯米?爱奇艺:与百度电影票业务有合作 他成全国首个落马监察委主任 上任1月就被抓(图) 酒泉钢铁将升级牙买加的氧化铝厂 目标200万吨的产能 倡棋杯李万鹏优势懈怠 陈一鸣妙手翻盘(多谱) 进球gif-杀死比赛!伊哈洛碾压贵州后防 挑射戴帽 应急管理部消防局:今年夏季火灾反弹风险大 浙江台州书记:发扬厚着脸皮等“五皮”招商精神
周杰伦作品音乐剧《不能说的秘密》开票 WTI原油跌逾1% 跌破61美元关口 现报60.98美… 尤文传奇:拿阿根廷双星与我跟皮耶罗相比不合适 我军轰6K飞行员谈绕台飞行:用战机航迹丈量大好河山 川航备降航班最小送医者8岁 29名送医者中7人出院 北京发布地质灾害气象风险黄色预警 陶菲克:曾为羽毛球放弃一切 佩服李宗伟仍坚持 女子价值5万钻戒被寄丢 派件员:包裹被风吹走(图) 周末影响市场重要资讯回顾 人民日报评年关讨薪:让农民工劳有所得干有所值 受惠司法轻判 韩国三星家族3代卷入丑闻成功避刑 人民日报评部分城市山寨洋建筑:做到极致也是赝品 起底ICO新乱象:区块链产业链条脆弱 项目方易跑路 ag娱乐平台