7

チェリーピー (web.py をフレームワークとして使用) とトルネードでインターネットから Web ページを取得するテストを実行しました。

サーバーにリクエストを送信するために使用する3つのテストケースがありsiegeます(-cはユーザー数を意味し、-tはテスト時間です)。コードはテスト結果の下にあります。

1. web.py (チャーピー)

  siege ip -c20 -t100s             server can handle 2747requests  
  siege ip -c200 -t30s             server can handle 1361requests
  siege ip -c500 -t30s             server can handle 170requests

2.トルネードシンクロ

  siege ip -c20 -t100s             server can handle 600requests  
  siege ip -c200 -t30s             server can handle 200requests
  siege ip -c500 -t30s             server can handle 116requests

3.トルネード非同期

  siege ip -c20 -t100s             server can handle 3022requests  
  siege ip -c200 -t30s             server can handle 2259requests
  siege ip -c500 -t30s             server can handle 471requests

パフォーマンス分析:

竜巻同期 < web.py (cherrypy) < 竜巻非同期

質問1:

非同期アーキテクチャを使用すると、Web サーバーのパフォーマンスが劇的に向上することはわかっています。

tornado非同期アーキテクチャとweb.py(cherry)の違いが気になる。

tornado 同期モードはリクエストを 1 つずつ処理すると思いますが、cherrypy は複数のスレッドを使用してどのように機能しますか? しかし、メモリの大幅な増加は見られませんでした。Cherrypy は複数のリクエストを同時に処理する場合があります。プログラムのブロックをどのように解決しますか?

質問2:

非同期技術を使用せずに tornado 同期モードのパフォーマンスを向上させることはできますか? 竜巻の方がうまくいくと思います。

Web.py コード:

import web
import tornado.httpclient
urls = (
    '/(.*)', 'hello'
)
app = web.application(urls, globals())

class hello:
    def GET(self, name):
        client = tornado.httpclient.HTTPClient()
        response=client.fetch("http://www.baidu.com/")
        return response.body

if __name__ == "__main__":
    app.run()

竜巻同期:

import tornado.ioloop
import tornado.options
import tornado.web
import tornado.httpclient
from tornado.options import define, options
define("port", default=8000, help="run on the given port", type=int)
class IndexHandler(tornado.web.RequestHandler):
    def get(self):
        client = tornado.httpclient.HTTPClient()
        response = client.fetch("http://www.baidu.com/" )
        self.write(response.body)


if __name__=='__main__':
    tornado.options.parse_command_line()
    app=tornado.web.Application(handlers=[(r'/',IndexHandler)])
    http_server=tornado.httpserver.HTTPServer(app)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()

トルネード非同期:

import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
import tornado.httpclient
from tornado.options import define, options
define("port", default=8001, help="run on the given port", type=int)
class IndexHandler(tornado.web.RequestHandler):
    @tornado.web.asynchronous
    def get(self):
        client = tornado.httpclient.AsyncHTTPClient()
        response = client.fetch("http://www.baidu.com/" ,callback=self.on_response)

    def on_response(self,response):
        self.write(response.body)
        self.finish()

if __name__=='__main__':
    tornado.options.parse_command_line()
    app=tornado.web.Application(handlers=[(r'/',IndexHandler)])
    http_server=tornado.httpserver.HTTPServer(app)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()
4

2 に答える 2

2

質問1に答えるには...

Tornado はシングル スレッドです。同期の例のようにメイン スレッドをブロックすると、その単一のスレッドは、ブロック呼び出しが戻るまで何もできません。これにより、同期の例は一度に 1 つの要求に制限されます。

私は特に web.py に精通していませんが、その HTTP サーバーのソースを見ると、スレッド化 mixin を使用しているように見えます。これは、一度に 1 つの要求を処理することに制限されていないことを示唆しています。最初のリクエストが来ると、それは単一のスレッドによって処理されます。そのスレッドは、HTTP クライアント呼び出しが戻るまでブロックされますが、他のスレッドはそれ以降の着信要求を自由に処理できます。これにより、より多くのリクエストを一度に処理できます。

これを Tornado でエミュレートした場合、たとえば、HTTP クライアント要求をスレッド プールに渡すことで、同様のスループットが得られるのではないかと思います。

于 2012-12-04T10:56:07.120 に答える