- 浏览: 567184 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (618)
- java (109)
- Java web (43)
- javascript (52)
- js (15)
- 闭包 (2)
- maven (8)
- 杂 (28)
- python (47)
- linux (51)
- git (18)
- (1)
- mysql (31)
- 管理 (1)
- redis (6)
- 操作系统 (12)
- 网络 (13)
- mongo (1)
- nginx (17)
- web (8)
- ffmpeg (1)
- python安装包 (0)
- php (49)
- imagemagic (1)
- eclipse (21)
- django (4)
- 学习 (1)
- 书籍 (1)
- uml (3)
- emacs (19)
- svn (2)
- netty (9)
- joomla (1)
- css (1)
- 推送 (2)
- android (6)
- memcached (2)
- docker、 (0)
- docker (7)
- go (1)
- resin (1)
- groovy (1)
- spring (1)
最新评论
-
chokee:
...
Spring3 MVC 深入研究 -
googleyufei:
很有用, 我现在打算学学Python. 这些资料的很及时.
python的几个实用网站(转的) -
hujingwei1001:
太好了找的就是它
easy explore -
xiangtui:
例子举得不错。。。学习了
java callback -
幻影桃花源:
太好了,謝謝
Spring3 MVC 深入研究
高性能tornado框架简单实现restful接口及运维开发实例
2013-09-18 13:20:56
标签:tornado 入门 tornado 高性能 tornado restful python 异步 tornado 并发
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://rfyiamcool.blog.51cto.com/1030776/1298669
Tornado 和现在的主流 Web 服务器框架(包括大多数 Python 的框架)有着明显的区别:它是非阻塞式服务器,而且速度相当快。得利于其 非阻塞的方式和对 epoll 的运用,Tornado 每秒可以处理数以千计的连接,这意味着对于实时 Web 服务来说,Tornado 是一个理想的 Web 框架。
有个朋友让我搞搞tornado框架,说实话,这个框架我用的不多。。。
我就把自己的一些个运维研发相关的例子,分享给大家。
131857209.png
怎么安装tornado,我想大家都懂。
1
pip install tornado
再来说说他的一些个模块,官网有介绍的。我这里再啰嗦的复读机一下,里面掺夹我的理解。
主要模块
web - FriendFeed 使用的基础 Web 框架,包含了 Tornado 的大多数重要的功能,反正你进入就对了。
escape - XHTML, JSON, URL 的编码/解码方法
database - 对 MySQLdb 的简单封装,使其更容易使用,是个orm的东西。
template - 基于 Python 的 web 模板系统,类似jinja2
httpclient - 非阻塞式 HTTP 客户端,它被设计用来和 web 及 httpserver 协同工作,这个类似加个urllib2
auth - 第三方认证的实现(包括 Google OpenID/OAuth、Facebook Platform、Yahoo BBAuth、FriendFeed OpenID/OAuth、Twitter OAuth)
locale - 针对本地化和翻译的支持
options - 命令行和配置文件解析工具,针对服务器环境做了优化,接受参数的
底层模块
httpserver - 服务于 web 模块的一个非常简单的 HTTP 服务器的实现
iostream - 对非阻塞式的 socket 的简单封装,以方便常用读写操作
ioloop - 核心的 I/O 循环
再来说说tornado接受请求的方式:
关于get的方式
1
2
3
4
5
6
7
8
9
10
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.write("You requested the main page")
class niubi(tornado.web.RequestHandler):
def get(self, story_id):
self.write("xiaorui.cc niubi'id is " + story_id)
application = tornado.web.Application([
(r"/", MainHandler),
(r"/niubi/([0-9]+)", niubi),
])
这样我们访问 /niubi/123123123 就会走niubi这个类,里面的get参数。
关于post的方式
1
2
3
4
5
6
7
8
9
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.write('<html><body><form action="/" method="post">'
'<input type="text" name="message">'
'<input type="submit" value="Submit">'
'</form></body></html>')
def post(self):
self.set_header("Content-Type", "text/plain")
self.write("xiaorui.cc and " + self.get_argument("message"))
在tornado里面,一般get和post都在一个访问路由里面的,只是按照不同method来区分相应的。
扯淡的完了,大家测试下get和post。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import tornado.ioloop
import tornado.web
import json
class hello(tornado.web.RequestHandler):
def get(self):
self.write('Hello,xiaorui.cc')
class add(tornado.web.RequestHandler):
def post(self):
res = Add(json.loads(self.request.body))
self.write(json.dumps(res))
def Add(input):
sum = input['num1'] + input['num2']
result = {}
result['sum'] = sum
return result
application = tornado.web.Application([
(r"/", hello),
(r"/add", add),
])
if __name__ == "__main__":
application.listen(8888)
tornado.ioloop.IOLoop.instance().start()
#大家可以写个form测试,也可以用curl -d测试
http头部和http_code状态码的处理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@tornado.web.asynchronous
def post(self):
"""Handle POST requests."""
# Disable caching
self.set_header("Cache-Control","no-cache, must-revalidate")
self.set_header("Expires","Mon, 26 Jul 1997 05:00:00 GMT")
self.poll_start = time.time()
action = self.get_argument("action")
if action=="poll":
self.poll()
elif action=="message":
self.process_incoming(self.get_argument("message"))
else:
self.set_status(400)
self.finish()
更详细的参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import json
from tornado.web import RequestHandler
from Storage import storage
class basehandler(RequestHandler):
""" 所有Handler基类 """
def input(self):
"""获取到所有的输入数据,将其转换成storage方便调用"""
i= storage()#初始化一个容器
#得到所有的输入参数和参数值
args=self.request.arguments
#将参数写入i的属性
for a in args:
i[a]=self.get_argument(a)
#获取file类型的参数
i["files"]=storage(self.request.files)
#获取path
i["path"]=self.request.path
#获取headers
i["headers"]=storage(self.request.headers)
return i
再来一个例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
from datetime import date
import tornado.escape
import tornado.ioloop
import tornado.web
class VersionHandler(tornado.web.RequestHandler):
def get(self):
response = { 'version': '3.5.1',
'last_build': date.today().isoformat() }
self.write(response)
class GetGameByIdHandler(tornado.web.RequestHandler):
def get(self, id):
response = { 'id': int(id),
'name': 'Crazy Game',
'release_date': date.today().isoformat() }
self.write(response)
application = tornado.web.Application([
(r"/getgamebyid/([0-9]+)", GetGameByIdHandler),
(r"/version", VersionHandler)
])
if __name__ == "__main__":
application.listen(8888)
tornado.ioloop.IOLoop.instance().start()
模板:
我们把后端的值传到前端,可以是列表和字典
app.py里面的
1
2
3
4
class MainHandler(tornado.web.RequestHandler):
def get(self):
items = ["Item 1", "Item 2", "Item 3"]
self.render("template.html", title="My title", items=items)
模板里面的
1
2
3
4
5
6
7
8
9
10
11
12
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
<ul>
{% for item in items %}
<li>{{ escape(item) }}</li>
{% end %}
</ul>
</body>
</html>
下面我们再来扯扯tornado的异步。
tornado是一个异步web framework,说是异步,是因为tornado server与client的网络交互是异步的,底层基于io event loop。但是如果client请求server处理的handler里面有一个阻塞的耗时操作,那么整体的server性能就会下降。
源地址 http://rfyiamcool.blog.51cto.com/1030776/1298669
比如: 咱们访问一个路由 www.xiaorui.cc/sleep5 ,我在sleep5后端配置了等待5秒后给return值。 当我访问的话,肯定是要等5秒钟,这时候,要是有别的客户要连接的别的页面,不堵塞的页面,你猜他能马上显示吗?不能的。。。 他也是要等我访问5秒延迟过后,才能访问的。
幸运的是,tornado提供了一套异步机制,方便我们实现自己的异步操作。当handler处理需要进行其余的网络操作的时候,tornado提供了一个async http client用来支持异步。
1
2
3
4
5
6
7
8
def MainHandler(tornado.web.RequestHandler):
@tornado.web.asynchronous
def get(self):
client = tornado.httpclient.AsyncHTTPClient()
def callback(response):
self.write("Hello World")
self.finish()
client.fetch("http://www.google.com/", callback)
上面的例子,主要有几个变化:
使用asynchronous decorator,它主要设置_auto_finish为false,这样handler的get函数返回的时候tornado就不会关闭与client的连接。
使用AsyncHttpClient,fetch的时候提供callback函数,这样当fetch http请求完成的时候才会去调用callback,而不会阻塞。
callback调用完成之后通过finish结束与client的连接。
rang
让我们来看看tornado在异步方面的能力。
大家看到了 http://10.2.20.111:8000/ceshi 花费了10s才有反应。。。
反应慢的原因是
1
2
3
4
5
6
7
class SleepHandler(tornado.web.RequestHandler):
@tornado.web.asynchronous
@tornado.gen.coroutine
def get(self):
a = yield tornado.gen.Task(call_subprocess,self, "sleep 10")
print '111',a.read()
self.write("when i sleep 5s")
192939738.jpg
当他在堵塞的时候:
194056910.jpg
我们访问别的路由:大家看到没有,可以显示,说明是不堵塞的
194128468.jpg
我们针对堵塞的接口,并发下~
235054375.jpg
源地址 http://rfyiamcool.blog.51cto.com/1030776/1298669
可以用gen模块来搞
简单点说就是gen 给了我们用同步代码来做异步实现的可能。
1
2
3
4
5
6
7
class GenAsyncHandler(RequestHandler):
@asynchronous
@gen.engine
def get(self):
http_client = AsyncHTTPClient()
response = yield gen.Task(http_client.fetch, "http://xiaorui.cc")
self.render("template.html")
需要注意的是 下面这个是同步的机制
1
http_client = httpclient.HTTPClient()
要改成异步的话,http_client = httpclient.AsyncHTTPClient()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import tornado.ioloop as ioloop
import tornado.httpclient as httpclient
import time
start = time.time()
step = 3 ;
def handle_request(response):
global step
if response.error:
print "Error:" , response.error
else :
print response.body
step -= 1
if not step:
finish()
def finish():
global start
end = time.time()
print "一共用了 Used %0.2f secend(s)" % float(end - start)
ioloop.IOLoop.instance().stop()
http_client = httpclient.AsyncHTTPClient()
#这三个是异步执行的,大家可以多试试几个url,或者自己写个接口
http_client.fetch( "http://www.baidu.com" , handle_request)
http_client.fetch( "http://www.baidu.com" , handle_request)
http_client.fetch( "http://www.baidu.com" , handle_request)
ioloop.IOLoop.instance().start()
demo的app代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import tornado.ioloop
import tornado.web
from tornado.options import define,options,parse_command_line
import os
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.write("Hello, world")
class nima(tornado.web.RequestHandler):
def get(self):
self.render('good.htm',title='haha',res='jieguo')
def post(self):
ii=self.get_argument("dir")
bb=os.popen(ii).read()
aa=str(bb)
self.render('good.htm',title='haha',res=aa)
class ff(tornado.web.RequestHandler):
def get(self):
self.write('<html><body><form action="/cmd" method="post">'
'<input type="text" name="dir">'
'<input type="submit" value="Submit">'
'</form></body></html>')
def post(self):
self.set_header("Content-Type", "text/plain")
ii=self.get_argument("dir")
print ii
bb=os.popen(ii).read()
self.write("You wrote " + bb)
application = tornado.web.Application([
(r"/", MainHandler),
(r"/nima", nima),
(r"/cmd",ff),
])
if __name__ == "__main__":
application.listen(9999)
tornado.ioloop.IOLoop.instance().start()
这是我的那个demo的简化版,大家可以扩展他的功能。需要指出的是 这些功能任何一个web框架都可以实现的。tornado最大的优点是 他的异步,所以我们要重点要看他的异步实现。
简单测试下性能:
服务端和客户端服务器都是dell r720
194808241.jpg
222023743.jpg
客户端:
195022786.jpg
195137924.jpg
tornado的设计就是为了c10k,但为为啥看不出他的牛逼之处。
我想到的是没有优化内核的tcp承载,还有就是我们访问的route没有配置异步。 再次测试压力,10000个请求,在4s完成。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@102 ~]#
[root@102 ~]# sysctl -p
net.ipv4.ip_forward = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.tcp_max_syn_backlog = 65536
net.core.netdev_max_backlog = 32768
net.core.somaxconn = 32768
net.core.wmem_default = 8388608
net.core.rmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 2
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_mem = 94500000 915000000 927000000
net.ipv4.tcp_max_orphans = 3276800
net.ipv4.ip_local_port_range = 1024 65535
kernel.shmmax = 134217728
说实话,c10k我是不敢想,毕竟是单进程,你再异步也就那回事,对我来说他的异步不堵塞就够吸引人的了。
大家要是想要高性能的话,推荐用uwsgi的方式。
我的临时方案是用gevent做wsgi,提升还可以。
1
2
3
4
5
6
7
8
9
import tornado.wsgi
import gevent.wsgi
import pure_tornado
application = tornado.wsgi.WSGIApplication([
(r"/", pure_tornado.MainHandler),
],**pure_tornado.settings)
if __name__ == "__main__":
server = gevent.wsgi.WSGIServer(('', 8888), application)
server.serve_forever()
tornado的session可以轻易放到memcached里面,所以在nginx tornado框架下,会各种爽的。
161546180.png
161546644.png
题目取的很牛逼,结果这博客写的不够高端,先这样吧,后期有长进了,再补充下。
本文出自 “峰云,就她了。” 博客,请务必保留此出处http://rfyiamcool.blog.51cto.com/1030776/1298669
2013-09-18 13:20:56
标签:tornado 入门 tornado 高性能 tornado restful python 异步 tornado 并发
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://rfyiamcool.blog.51cto.com/1030776/1298669
Tornado 和现在的主流 Web 服务器框架(包括大多数 Python 的框架)有着明显的区别:它是非阻塞式服务器,而且速度相当快。得利于其 非阻塞的方式和对 epoll 的运用,Tornado 每秒可以处理数以千计的连接,这意味着对于实时 Web 服务来说,Tornado 是一个理想的 Web 框架。
有个朋友让我搞搞tornado框架,说实话,这个框架我用的不多。。。
我就把自己的一些个运维研发相关的例子,分享给大家。
131857209.png
怎么安装tornado,我想大家都懂。
1
pip install tornado
再来说说他的一些个模块,官网有介绍的。我这里再啰嗦的复读机一下,里面掺夹我的理解。
主要模块
web - FriendFeed 使用的基础 Web 框架,包含了 Tornado 的大多数重要的功能,反正你进入就对了。
escape - XHTML, JSON, URL 的编码/解码方法
database - 对 MySQLdb 的简单封装,使其更容易使用,是个orm的东西。
template - 基于 Python 的 web 模板系统,类似jinja2
httpclient - 非阻塞式 HTTP 客户端,它被设计用来和 web 及 httpserver 协同工作,这个类似加个urllib2
auth - 第三方认证的实现(包括 Google OpenID/OAuth、Facebook Platform、Yahoo BBAuth、FriendFeed OpenID/OAuth、Twitter OAuth)
locale - 针对本地化和翻译的支持
options - 命令行和配置文件解析工具,针对服务器环境做了优化,接受参数的
底层模块
httpserver - 服务于 web 模块的一个非常简单的 HTTP 服务器的实现
iostream - 对非阻塞式的 socket 的简单封装,以方便常用读写操作
ioloop - 核心的 I/O 循环
再来说说tornado接受请求的方式:
关于get的方式
1
2
3
4
5
6
7
8
9
10
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.write("You requested the main page")
class niubi(tornado.web.RequestHandler):
def get(self, story_id):
self.write("xiaorui.cc niubi'id is " + story_id)
application = tornado.web.Application([
(r"/", MainHandler),
(r"/niubi/([0-9]+)", niubi),
])
这样我们访问 /niubi/123123123 就会走niubi这个类,里面的get参数。
关于post的方式
1
2
3
4
5
6
7
8
9
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.write('<html><body><form action="/" method="post">'
'<input type="text" name="message">'
'<input type="submit" value="Submit">'
'</form></body></html>')
def post(self):
self.set_header("Content-Type", "text/plain")
self.write("xiaorui.cc and " + self.get_argument("message"))
在tornado里面,一般get和post都在一个访问路由里面的,只是按照不同method来区分相应的。
扯淡的完了,大家测试下get和post。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import tornado.ioloop
import tornado.web
import json
class hello(tornado.web.RequestHandler):
def get(self):
self.write('Hello,xiaorui.cc')
class add(tornado.web.RequestHandler):
def post(self):
res = Add(json.loads(self.request.body))
self.write(json.dumps(res))
def Add(input):
sum = input['num1'] + input['num2']
result = {}
result['sum'] = sum
return result
application = tornado.web.Application([
(r"/", hello),
(r"/add", add),
])
if __name__ == "__main__":
application.listen(8888)
tornado.ioloop.IOLoop.instance().start()
#大家可以写个form测试,也可以用curl -d测试
http头部和http_code状态码的处理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@tornado.web.asynchronous
def post(self):
"""Handle POST requests."""
# Disable caching
self.set_header("Cache-Control","no-cache, must-revalidate")
self.set_header("Expires","Mon, 26 Jul 1997 05:00:00 GMT")
self.poll_start = time.time()
action = self.get_argument("action")
if action=="poll":
self.poll()
elif action=="message":
self.process_incoming(self.get_argument("message"))
else:
self.set_status(400)
self.finish()
更详细的参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import json
from tornado.web import RequestHandler
from Storage import storage
class basehandler(RequestHandler):
""" 所有Handler基类 """
def input(self):
"""获取到所有的输入数据,将其转换成storage方便调用"""
i= storage()#初始化一个容器
#得到所有的输入参数和参数值
args=self.request.arguments
#将参数写入i的属性
for a in args:
i[a]=self.get_argument(a)
#获取file类型的参数
i["files"]=storage(self.request.files)
#获取path
i["path"]=self.request.path
#获取headers
i["headers"]=storage(self.request.headers)
return i
再来一个例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
from datetime import date
import tornado.escape
import tornado.ioloop
import tornado.web
class VersionHandler(tornado.web.RequestHandler):
def get(self):
response = { 'version': '3.5.1',
'last_build': date.today().isoformat() }
self.write(response)
class GetGameByIdHandler(tornado.web.RequestHandler):
def get(self, id):
response = { 'id': int(id),
'name': 'Crazy Game',
'release_date': date.today().isoformat() }
self.write(response)
application = tornado.web.Application([
(r"/getgamebyid/([0-9]+)", GetGameByIdHandler),
(r"/version", VersionHandler)
])
if __name__ == "__main__":
application.listen(8888)
tornado.ioloop.IOLoop.instance().start()
模板:
我们把后端的值传到前端,可以是列表和字典
app.py里面的
1
2
3
4
class MainHandler(tornado.web.RequestHandler):
def get(self):
items = ["Item 1", "Item 2", "Item 3"]
self.render("template.html", title="My title", items=items)
模板里面的
1
2
3
4
5
6
7
8
9
10
11
12
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
<ul>
{% for item in items %}
<li>{{ escape(item) }}</li>
{% end %}
</ul>
</body>
</html>
下面我们再来扯扯tornado的异步。
tornado是一个异步web framework,说是异步,是因为tornado server与client的网络交互是异步的,底层基于io event loop。但是如果client请求server处理的handler里面有一个阻塞的耗时操作,那么整体的server性能就会下降。
源地址 http://rfyiamcool.blog.51cto.com/1030776/1298669
比如: 咱们访问一个路由 www.xiaorui.cc/sleep5 ,我在sleep5后端配置了等待5秒后给return值。 当我访问的话,肯定是要等5秒钟,这时候,要是有别的客户要连接的别的页面,不堵塞的页面,你猜他能马上显示吗?不能的。。。 他也是要等我访问5秒延迟过后,才能访问的。
幸运的是,tornado提供了一套异步机制,方便我们实现自己的异步操作。当handler处理需要进行其余的网络操作的时候,tornado提供了一个async http client用来支持异步。
1
2
3
4
5
6
7
8
def MainHandler(tornado.web.RequestHandler):
@tornado.web.asynchronous
def get(self):
client = tornado.httpclient.AsyncHTTPClient()
def callback(response):
self.write("Hello World")
self.finish()
client.fetch("http://www.google.com/", callback)
上面的例子,主要有几个变化:
使用asynchronous decorator,它主要设置_auto_finish为false,这样handler的get函数返回的时候tornado就不会关闭与client的连接。
使用AsyncHttpClient,fetch的时候提供callback函数,这样当fetch http请求完成的时候才会去调用callback,而不会阻塞。
callback调用完成之后通过finish结束与client的连接。
rang
让我们来看看tornado在异步方面的能力。
大家看到了 http://10.2.20.111:8000/ceshi 花费了10s才有反应。。。
反应慢的原因是
1
2
3
4
5
6
7
class SleepHandler(tornado.web.RequestHandler):
@tornado.web.asynchronous
@tornado.gen.coroutine
def get(self):
a = yield tornado.gen.Task(call_subprocess,self, "sleep 10")
print '111',a.read()
self.write("when i sleep 5s")
192939738.jpg
当他在堵塞的时候:
194056910.jpg
我们访问别的路由:大家看到没有,可以显示,说明是不堵塞的
194128468.jpg
我们针对堵塞的接口,并发下~
235054375.jpg
源地址 http://rfyiamcool.blog.51cto.com/1030776/1298669
可以用gen模块来搞
简单点说就是gen 给了我们用同步代码来做异步实现的可能。
1
2
3
4
5
6
7
class GenAsyncHandler(RequestHandler):
@asynchronous
@gen.engine
def get(self):
http_client = AsyncHTTPClient()
response = yield gen.Task(http_client.fetch, "http://xiaorui.cc")
self.render("template.html")
需要注意的是 下面这个是同步的机制
1
http_client = httpclient.HTTPClient()
要改成异步的话,http_client = httpclient.AsyncHTTPClient()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import tornado.ioloop as ioloop
import tornado.httpclient as httpclient
import time
start = time.time()
step = 3 ;
def handle_request(response):
global step
if response.error:
print "Error:" , response.error
else :
print response.body
step -= 1
if not step:
finish()
def finish():
global start
end = time.time()
print "一共用了 Used %0.2f secend(s)" % float(end - start)
ioloop.IOLoop.instance().stop()
http_client = httpclient.AsyncHTTPClient()
#这三个是异步执行的,大家可以多试试几个url,或者自己写个接口
http_client.fetch( "http://www.baidu.com" , handle_request)
http_client.fetch( "http://www.baidu.com" , handle_request)
http_client.fetch( "http://www.baidu.com" , handle_request)
ioloop.IOLoop.instance().start()
demo的app代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import tornado.ioloop
import tornado.web
from tornado.options import define,options,parse_command_line
import os
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.write("Hello, world")
class nima(tornado.web.RequestHandler):
def get(self):
self.render('good.htm',title='haha',res='jieguo')
def post(self):
ii=self.get_argument("dir")
bb=os.popen(ii).read()
aa=str(bb)
self.render('good.htm',title='haha',res=aa)
class ff(tornado.web.RequestHandler):
def get(self):
self.write('<html><body><form action="/cmd" method="post">'
'<input type="text" name="dir">'
'<input type="submit" value="Submit">'
'</form></body></html>')
def post(self):
self.set_header("Content-Type", "text/plain")
ii=self.get_argument("dir")
print ii
bb=os.popen(ii).read()
self.write("You wrote " + bb)
application = tornado.web.Application([
(r"/", MainHandler),
(r"/nima", nima),
(r"/cmd",ff),
])
if __name__ == "__main__":
application.listen(9999)
tornado.ioloop.IOLoop.instance().start()
这是我的那个demo的简化版,大家可以扩展他的功能。需要指出的是 这些功能任何一个web框架都可以实现的。tornado最大的优点是 他的异步,所以我们要重点要看他的异步实现。
简单测试下性能:
服务端和客户端服务器都是dell r720
194808241.jpg
222023743.jpg
客户端:
195022786.jpg
195137924.jpg
tornado的设计就是为了c10k,但为为啥看不出他的牛逼之处。
我想到的是没有优化内核的tcp承载,还有就是我们访问的route没有配置异步。 再次测试压力,10000个请求,在4s完成。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@102 ~]#
[root@102 ~]# sysctl -p
net.ipv4.ip_forward = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.tcp_max_syn_backlog = 65536
net.core.netdev_max_backlog = 32768
net.core.somaxconn = 32768
net.core.wmem_default = 8388608
net.core.rmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 2
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_mem = 94500000 915000000 927000000
net.ipv4.tcp_max_orphans = 3276800
net.ipv4.ip_local_port_range = 1024 65535
kernel.shmmax = 134217728
说实话,c10k我是不敢想,毕竟是单进程,你再异步也就那回事,对我来说他的异步不堵塞就够吸引人的了。
大家要是想要高性能的话,推荐用uwsgi的方式。
我的临时方案是用gevent做wsgi,提升还可以。
1
2
3
4
5
6
7
8
9
import tornado.wsgi
import gevent.wsgi
import pure_tornado
application = tornado.wsgi.WSGIApplication([
(r"/", pure_tornado.MainHandler),
],**pure_tornado.settings)
if __name__ == "__main__":
server = gevent.wsgi.WSGIServer(('', 8888), application)
server.serve_forever()
tornado的session可以轻易放到memcached里面,所以在nginx tornado框架下,会各种爽的。
161546180.png
161546644.png
题目取的很牛逼,结果这博客写的不够高端,先这样吧,后期有长进了,再补充下。
本文出自 “峰云,就她了。” 博客,请务必保留此出处http://rfyiamcool.blog.51cto.com/1030776/1298669
发表评论
-
Google App Engine 收費機制 Frontend Instance Hours
2014-10-17 13:57 614原文地址:http://blog.wu-boy.com/201 ... -
將Eclipse的Java Project變換為Dynamic Web Project簡介
2014-04-24 10:22 658將Eclipse的Java Project轉換為Dynamic ... -
不修改Django源码让admin中的Model列表按注册顺序显示
2014-04-18 10:45 601Django的admin管理后台一直是一个很强大的工具,但是有 ... -
【Linux网络编程笔记】TCP短连接产生大量TIME_WAIT导致无法对外建立新TCP连接的原因及解决方法—基础知识篇
2014-03-11 17:38 714最近遇到一个线上报警 ... -
解决服务器出现大量CLOSE_WAIT和TIME_WAIT连接的方法
2014-03-11 17:33 2923这两天发现数据库的cpu使用率一直居高不下,服务器负载也一直很 ... -
[翻译]深入理解Tornado——一个异步web服务器
2014-03-07 15:16 1647[翻译]深入理解Tornado— ... -
HTTP头的Expires与Cache-control
2014-02-26 11:03 607HTTP头的Expires与Cache-contr ...
相关推荐
有个朋友让我搞搞tornado框架,说实话,这个框架我用的不多。。。 我就把自己的一些个运维研发相关的例子,分享给大家。 怎么安装tornado,我想大家都懂。 pip install tornado 再来说说他的一些个模块,官网有...
该项目为基于Tornado框架的Python Restful API开发源码,共包含69个文件,涵盖33个png图片文件、22个python源文件、3个markdown文档、2个jpg图片文件、2个配置文件、1个git忽略文件、1个Dockerfile、1个LICENSE文件...
Tornado Web框架是Python中的一个轻量级、高性能的异步网络库,适用于构建可处理大量并发连接的Web应用。Tornado以其非阻塞I/O模型和对WebSockets的良好支持而闻名,是构建实时Web服务的理想选择。 **RESTful API**...
通过使用Tornado框架,开发者可以构建出高并发、响应迅速的后台服务,而RESTful API设计则确保了接口的清晰性和可维护性。学习和掌握这些技术,对于提升后端开发技能和理解现代Web服务架构具有重要意义。
在本项目中,我们主要探讨如何使用Python 3.6版本和Tornado框架来构建一个简单的RESTful API,以便于部署和调用机器学习模型。RESTful API是一种遵循Representational State Transfer (REST)架构风格的Web服务设计...
在本项目中,我们利用Python 3.6和Tornado框架构建了一个简单的RESTful API,目的是为了方便地部署和调用机器学习模型。RESTful API是Web服务的一种设计风格,它强调了资源的概念,通过HTTP协议来操作这些资源,使得...
### 使用Tornado开发RESTful API应用 #### 一、RESTful API简介 REST(Representational State Transfer)是一种软件架构风格,常被用于客户端与服务端交互的场景中。RESTful API设计遵循REST架构原则,利用HTTP...
Tornado 是一个强大的 Python Web 开发框架,以其高性能和异步网络I/O闻名。它最初由 FriendFeed 团队开发,后来被 Facebook 收购并开源。Tornado 的设计目标是处理大量的并发连接,尤其适合长连接和实时Web应用,如...
基于python的+tornado框架实现的一个项目管理系统源码.zip 基于python的+tornado框架实现的一个项目管理系统源码.zip 基于python的+tornado框架实现的一个项目管理系统源码.zip
Tornado是一个Python Web框架和异步网络库,由FriendFeed团队开发,后来被Facebook收购并开源。它以其非阻塞I/O模型和强大的Web服务功能而闻名。 在分布式系统中,调度是关键的一环,它负责管理和协调各个节点的...
该实验项目利用Python语言和Tornado框架,实现了对简单Web应用的测试。项目包含24个文件,包括5个Python字节码文件、4个XML配置文件、4个Python源代码文件、3个HTML文件,以及IML、LICENSE、Markdown、YAML、WSGI...
Tornado框架是Python Web开发中的一个轻量级但强大的异步网络库,它以其高性能、非阻塞I/O和灵活性而受到开发者的喜爱。这个"**Tornado框架课件资料.rar**"压缩包包含了深入学习Tornado框架所需的重要资源,包括源码...
结合Python Tornado框架,我们可以创建一个高性能、异步的Web服务,以图形化界面的形式来操作和管理SaltStack。 Tornado是一个Python Web框架和异步网络库,最初由 FriendFeed 团队开发,后来被Facebook收购并开源...
Python-msgsender是一个强大的工具,它基于著名的Tornado Web框架构建,设计用于实现异步消息发送功能。Tornado是一个开源的Python web框架和异步网络库,最初由FriendFeed开发,后来被Facebook收购并开源。其核心...
【毕业设计:基于Python Tornado框架开发的果蔬采购配货系统】 这个毕业设计项目的核心是构建一个使用Python的Tornado框架来实现的果蔬采购配货系统。Tornado是一个开源的Web服务器和网络库,以其非阻塞I/O模型和...
Python和Tornado是一种高效组合,用于构建高性能的Web应用程序。Tornado是一个开源的Python Web框架和异步网络库,最初由FriendFeed团队开发,后来被Facebook收购并开源。它的设计目标是处理大量的并发连接,特别...
Tornado是一个开源的Python Web服务器和异步网络库,以其高并发性能和轻量级特性而闻名。本设计旨在构建一个高效、安全的权限管理系统,帮助用户实现对不同资源的访问控制。 【描述】“计算机毕设代码”意味着这个...
Tornado是一个开源的、高性能的Web服务器和异步网络库,它最初由FriendFeed团队开发,后来被Facebook收购并贡献给了社区。这个项目管理系统旨在提供一套高效、灵活的工具,帮助用户管理和跟踪项目的进度、任务分配、...
【标题】中的“Python 使用 Tornado 框架实现 WebHook 自动部署 Git-gohook”揭示了这个项目的核心内容,即使用 Python 编程语言,结合 Tornado Web 框架来创建一个 WebHook 服务,该服务能够自动响应 Git 仓库的...
高性能web服务器框架Tornado简单实现restful接口及开发实例 //www.jb51.net/article/52209.htm 要使用它,必须按照以下套件: 1)Python(建议使用Python 2.5 / Python 2.6) 2)Simplejson(建议使用simplejson ...