您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

Python的Tornado框架的异步任务与AsyncHTTPClient

5b51 2022/1/14 8:19:02 python 字数 13163 阅读 446 来源 www.jb51.cc/python

高性能服务器Tornado Python的web框架名目繁多,各有千秋。正如光荣属于希腊,伟大属于罗马。Python的优雅结合WSGI的设计,让web框架接口实现千秋一统。WSGI把应用(Application)和服务器(Server)结合起来。Djang

概述

class SyncHandler(tornado.web.RequestHandler):

  def get(self,*args,**kwargs):
    # 耗时的代码
    os.system("ping -c 2 www.google.com")
    self.finish('It works')

ab -c 5 -n 5 http://127.0.0.1:5000/sync

Server Software:    TornadoServer/4.3
Server Hostname:    127.0.0.1
Server Port:      5000

Document Path:     /sync
Document Length:    5 bytes

Concurrency Level:   5
Time taken for tests:  5.076 seconds
Complete requests:   5
Failed requests:    0
Total transferred:   985 bytes
HTML transferred:    25 bytes
Requests per second:  0.99 [#/sec] (mean)
Time per request:    5076.015 [ms] (mean)
Time per request:    1015.203 [ms] (mean,across all concurrent requests)
Transfer rate:     0.19 [Kbytes/sec] received

class AsyncHandler(tornado.web.RequestHandler):
  @tornado.web.asynchronous
  @tornado.gen.coroutine
  def get(self,**kwargs):

    tornado.ioloop.IOLoop.instance().add_timeout(1,callback=functools.partial(self.ping,'www.google.com'))

    # do something others

    self.finish('It works')

  @tornado.gen.coroutine
  def ping(self,url):
    os.system("ping -c 2 {}".format(url))
    return 'after'

Document Path:     /async
Document Length:    5 bytes

Concurrency Level:   5
Time taken for tests:  0.009 seconds
Complete requests:   5
Failed requests:    0
Total transferred:   985 bytes
HTML transferred:    25 bytes
Requests per second:  556.92 [#/sec] (mean)
Time per request:    8.978 [ms] (mean)
Time per request:    1.796 [ms] (mean,across all concurrent requests)
Transfer rate:     107.14 [Kbytes/sec] received

class AsyncTaskHandler(tornado.web.RequestHandler):
  @tornado.web.asynchronous
  @tornado.gen.coroutine
  def get(self,**kwargs):
    # yield 结果
    response = yield tornado.gen.Task(self.ping,' www.google.com')
    print 'response',response
    self.finish('hello')

  @tornado.gen.coroutine
  def ping(self,url):
    os.system("ping -c 2 {}".format(url))
    return 'after'

Server Software:    TornadoServer/4.3
Server Hostname:    127.0.0.1
Server Port:      5000

Document Path:     /async/task
Document Length:    5 bytes

Concurrency Level:   5
Time taken for tests:  0.049 seconds
Complete requests:   5
Failed requests:    0
Total transferred:   985 bytes
HTML transferred:    25 bytes
Requests per second:  101.39 [#/sec] (mean)
Time per request:    49.314 [ms] (mean)
Time per request:    9.863 [ms] (mean,across all concurrent requests)
Transfer rate:     19.51 [Kbytes/sec] received

from concurrent.futures import ThreadPoolExecutor

class FutureHandler(tornado.web.RequestHandler):
  executor = ThreadPoolExecutor(10)

  @tornado.web.asynchronous
  @tornado.gen.coroutine
  def get(self,**kwargs):

    url = 'www.google.com'
    tornado.ioloop.IOLoop.instance().add_callback(functools.partial(self.ping,url))
    self.finish('It works')

  @tornado.concurrent.run_on_executor
  def ping(self,url):
    os.system("ping -c 2 {}".format(url))

Document Path:     /future
Document Length:    5 bytes

Concurrency Level:   5
Time taken for tests:  0.003 seconds
Complete requests:   5
Failed requests:    0
Total transferred:   995 bytes
HTML transferred:    25 bytes
Requests per second:  1912.78 [#/sec] (mean)
Time per request:    2.614 [ms] (mean)
Time per request:    0.523 [ms] (mean,across all concurrent requests)
Transfer rate:     371.72 [Kbytes/sec] received

class Executor(ThreadPoolExecutor):
  _instance = None

  def __new__(cls,**kwargs):
    if not getattr(cls,'_instance',None):
      cls._instance = ThreadPoolExecutor(max_workers=10)
    return cls._instance


class FutureResponseHandler(tornado.web.RequestHandler):
  executor = Executor()

  @tornado.web.asynchronous
  @tornado.gen.coroutine
  def get(self,**kwargs):

    future = Executor().submit(self.ping,'www.google.com')

    response = yield tornado.gen.with_timeout(datetime.timedelta(10),future,quiet_exceptions=tornado.gen.TimeoutError)

    if response:
      print 'response',response.result()

  @tornado.concurrent.run_on_executor
  def ping(self,url):
    os.system("ping -c 1 {}".format(url))
    return 'after'

Concurrency Level:   5
Time taken for tests:  0.043 seconds
Complete requests:   5
Failed requests:    0
Total transferred:   960 bytes
HTML transferred:    0 bytes
Requests per second:  116.38 [#/sec] (mean)
Time per request:    42.961 [ms] (mean)
Time per request:    8.592 [ms] (mean,across all concurrent requests)
Transfer rate:     21.82 [Kbytes/sec] received

class SyncHandler(tornado.web.RequestHandler):
  def get(self,**kwargs):

    url = 'https://api.github.com/'
    resp = requests.get(url)
    print resp.status_code

    self.finish('It works')

Document Path:     /sync
Document Length:    5 bytes

Concurrency Level:   5
Time taken for tests:  10.255 seconds
Complete requests:   5
Failed requests:    0
Total transferred:   985 bytes
HTML transferred:    25 bytes
Requests per second:  0.49 [#/sec] (mean)
Time per request:    10255.051 [ms] (mean)
Time per request:    2051.010 [ms] (mean,across all concurrent requests)
Transfer rate:     0.09 [Kbytes/sec] received

class AsyncHandler(tornado.web.RequestHandler):
  @tornado.web.asynchronous
  def get(self,**kwargs):

    url = 'https://api.github.com/'
    http_client = tornado.httpclient.AsyncHTTPClient()
    http_client.fetch(url,self.on_response)
    self.finish('It works')

  @tornado.gen.coroutine
  def on_response(self,response):
    print response.code

Document Path:     /async
Document Length:    5 bytes

Concurrency Level:   5
Time taken for tests:  0.162 seconds
Complete requests:   5
Failed requests:    0
Total transferred:   985 bytes
HTML transferred:    25 bytes
Requests per second:  30.92 [#/sec] (mean)
Time per request:    161.714 [ms] (mean)
Time per request:    32.343 [ms] (mean,across all concurrent requests)
Transfer rate:     5.95 [Kbytes/sec] received

class AsyncResponseHandler(tornado.web.RequestHandler):
  @tornado.web.asynchronous
  @tornado.gen.coroutine
  def get(self,**kwargs):

    url = 'https://api.github.com/'
    http_client = tornado.httpclient.AsyncHTTPClient()
    response = yield tornado.gen.Task(http_client.fetch,url)
    print response.code
    print response.body

headers = self.request.headers
body = json.dumps({'name': 'rsj217'})
http_client = tornado.httpclient.AsyncHTTPClient()

resp = yield tornado.gen.Task(
  self.http_client.fetch,url,method="POST",headers=headers,body=body,validate_cert=False)

body = urllib.urlencode(params)
req = tornado.httpclient.HTTPRequest(
 url=url,method='POST',validate_cert=False) 

http_client.fetch(req,self.handler_response)

def handler_response(self,response):

  print response.code

@router.Route('/api/v2/account/upload')
class ApiAccountUploadHandler(helper.BaseHandler):
  @tornado.gen.coroutine
  @helper.token_require
  def post(self,**kwargs):
    upload_type = self.get_argument('type',None)

    files_body = self.request.files['file']

    new_file = 'upload/new_pic.jpg'
    new_file_name = 'new_pic.jpg'

    # 写入文件
    with open(new_file,'w') as w:
      w.write(file_['body'])

    logging.info('user {} upload {}'.format(user_id,new_file_name))

    # 异步请求 上传图片
    with open(new_file,'rb') as f:
      files = [('image',new_file_name,f.read())]

    fields = (('api_key',KEY),('api_secret',SECRET))

    content_type,body = encode_multipart_formdata(fields,files)

    headers = {"Content-Type": content_type,'content-length': str(len(body))}
    request = tornado.httpclient.HTTPRequest(config.OCR_HOST,validate_cert=False)

    response = yield tornado.httpclient.AsyncHTTPClient().fetch(request)

def encode_multipart_formdata(fields,files):
  """
  fields is a sequence of (name,value) elements for regular form fields.
  files is a sequence of (name,filename,value) elements for data to be
  uploaded as files.
  Return (content_type,body) ready for httplib.HTTP instance
  """
  boundary = '----------ThIs_Is_tHe_bouNdaRY_$'
  crlf = '\r\n'
  l = []
  for (key,value) in fields:
    l.append('--' + boundary)
    l.append('Content-Disposition: form-data; name="%s"' % key)
    l.append('')
    l.append(value)
  for (key,value) in files:
    filename = filename.encode("utf8")
    l.append('--' + boundary)
    l.append(
        'Content-Disposition: form-data; name="%s"; filename="%s"' % (
          key,filename
        )
    )
    l.append('Content-Type: %s' % get_content_type(filename))
    l.append('')
    l.append(value)
  l.append('--' + boundary + '--')
  l.append('')
  body = crlf.join(l)
  content_type = 'multipart/form-data; boundary=%s' % boundary
  return content_type,body


def get_content_type(filename):
  import mimetypes

  return mimetypes.guess_type(filename)[0] or 'application/octet-stream'

files = {}
f = open('/Users/ghost/Desktop/id.jpg')
files['image'] = f
data = dict(api_key='KEY',api_secret='SECRET')
resp = requests.post(url,data=data,files=files)
f.close()
print resp.status_Code

总结

以上是编程之家为你收集整理的Python的Tornado框架的异步任务与AsyncHTTPClient全部内容,希望文章能够帮你解决Python的Tornado框架的异步任务与AsyncHTTPClient所遇到的程序开发问题。


如果您也喜欢它,动动您的小指点个赞吧

除非注明,文章均由 laddyq.com 整理发布,欢迎转载。

转载请注明:
链接:http://laddyq.com
来源:laddyq.com
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


联系我
置顶