L'exemple dans cet article partage les détails du fonctionnement et du déploiement du framework Web Python Tornado pour votre référence. Le contenu spécifique est le suivant
Opération et déploiement<.>
Parce que Tornado a son propre serveur HTTP intégré, son exécution et son déploiement ne sont pas les mêmes que les autres frameworks Web Python. Au lieu de configurer un conteneur WSGI pour exécuter votre application, vous devez écrire une fonction main() pour démarrer le service :
def main(): app = make_app() app.listen(8888) IOLoop.current().start() if __name__ == '__main__': main()
2. Processus et ports En raison du GIL (Global Interpreter Lock) de Python, afin d'utiliser pleinement les machines multi-CPU, il est nécessaire d'exécuter plusieurs processus Python. . En général, il est préférable d'exécuter un processus par processeur.
def main(): app = make_app() server = tornado.httpserver.HTTPServer(app) server.bind(8888) server.start(0) # forks one process per cpu IOLoop.current().start()
3. Exécuter derrière un équilibreur de charge Lors de l'exécution derrière un équilibreur de charge tel que nginx, il est recommandé de transmettre xheaders=True au constructeur de HTTPServer. Cela indiquera à Tornado d'utiliser des en-têtes HTTP tels que X-Real-IP pour obtenir l'adresse IP de l'utilisateur au lieu de supposer que tout le trafic provient de l'adresse IP de l'équilibreur de charge.
user nginx; worker_processes 1; error_log /var/log/nginx/error.log; pid /var/run/nginx.pid; events { worker_connections 1024; use epoll; } http { # Enumerate all the Tornado servers here upstream frontends { server 127.0.0.1:8000; server 127.0.0.1:8001; server 127.0.0.1:8002; server 127.0.0.1:8003; } include /etc/nginx/mime.types; default_type application/octet-stream; access_log /var/log/nginx/access.log; keepalive_timeout 65; proxy_read_timeout 200; sendfile on; tcp_nopush on; tcp_nodelay on; gzip on; gzip_min_length 1000; gzip_proxied any; gzip_types text/plain text/html text/css text/xml application/x-javascript application/xml application/atom+xml text/javascript; # Only retry if there was a communication error, not a timeout # on the Tornado server (to avoid propagating "queries of death" # to all frontends) proxy_next_upstream error; server { listen 80; # Allow file uploads client_max_body_size 50M; location ^~ /static/ { root /var/www; if ($query_string) { expires max; } } location = /favicon.ico { rewrite (.*) /static/favicon.ico; } location = /robots.txt { rewrite (.*) /static/robots.txt; } location / { proxy_pass_header Server; proxy_set_header Host $http_host; proxy_redirect off; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Scheme $scheme; proxy_pass http://frontends; } } }
4. Fichiers statiques et mise en cache de fichiers Dans Tornado, vous pouvez fournir des services de fichiers statiques en spécifiant un chemin statique spécial dans l'application :
settings = { "static_path": os.path.join(os.path.dirname(__file__), "static"), "cookie_secret": "__TODO:_GENERATE_YOUR_OWN_RANDOM_VALUE_HERE__", "login_url": "/login", "xsrf_cookies": True, } application = tornado.web.Application([ (r"/", MainHandler), (r"/login", LoginHandler), (r"/(apple-touch-icon\.png)", tornado.web.StaticFileHandler, dict(path=settings['static_path'])), ], **settings)
<html> <head> <title>FriendFeed - {{ _("Home") }}</title> </head> <body> <p><img src="{{ static_url("images/logo.png") }}"/></p> </body> </html>
La fonction static_url() traduira le chemin relatif en un URI similaire à /static/images/logo.png?v=aae54. Le paramètre v est le hachage du contenu logo.png, et l'existence de provoque le problème. Service Tornado pour envoyer les en-têtes de cache au navigateur de l'utilisateur, ce qui amènera le navigateur à mettre le contenu en cache indéfiniment. Étant donné que le paramètre v est basé sur le contenu du fichier, si vous mettez à jour un fichier et redémarrez le service, il enverra une nouvelle valeur v, de sorte que le navigateur de l'utilisateur extraira automatiquement le nouveau fichier. Si le contenu du fichier n'a pas changé, le navigateur continuera à utiliser la copie mise en cache localement sans vérifier les mises à jour du serveur, améliorant ainsi considérablement les performances de rendu. En production, vous souhaiterez peut-être servir des fichiers statiques via un meilleur serveur statique, tel que nginx. Vous pouvez configurer n'importe quel serveur Web pour reconnaître la balise de version fournie via static_url() et définir l'en-tête du cache en conséquence. Ce qui suit fait partie de la configuration liée à Nginx que nous utilisons dans FriendFeed :
location /static/ { root /var/friendfeed/static; if ($query_string) { expires max; } }
五、Debug模式和自动重载
如果传递 debug=True 配置给 Application 的构造函数,应用程序将会运行在debug/开发模式。 在这个模式下,为了方便于开发的一些功能将被启用( 每一个也可以作为独立的标签使用,如果它们都被专门指定,那它们都将获得独立的优先级):
1、autoreload=True: 应用程序将会观察它的源文件是否改变,并且当任何文件改变的时候便重载它自己。这减少了在开发中需要手动重启服务的需求。然而,在debug模式下,某些错误(例如import的时候有语法错误)会导致服务 关闭,并且无法自动恢复。
2、compiled_template_cache=False: 模板将不会被缓存。
3、static_hash_cache=False: 静态文件哈希 (被 static_url 函数使用) 将不会被缓存。
4、serve_traceback=True: 当一个异常在 RequestHandler 中没有捕获,将会生成一个包含调用栈信息的错误页。
自动重载(autoreload)模式和 HTTPServer 的多进程模式不兼容,你不能给 HTTPServer.start 传递 1 以外的参数(或者调用 tornado.process.fork_processes) 当你使用自动重载模式的时候。
debug模式的自动重载功能可作为一个独立的模块位于 tornado.autoreload。以下两者可以结合使用,在语法错误之时提供额外的健壮性: 设置 autoreload=True 可以在app运行时检测文件修改,还有启动 python -m tornado.autoreload myserver.py 来捕获任意语法错误或者其他的启动时错误。
重载会丢失任何Python解释器命令行参数(-u). 因为它使用 sys.executable 和 sys.argv 重新执行Python。此外,修改这些变量将造成重载错误。
在一些平台(包括Windows 和Mac OSX 10.6之前),进程不能被“原地”更新,所以当检测到代码更新,旧服务就会退出然后启动一个新服务。这已经被公知来混淆一些IDE。
六、WSGI和Google App Engine
Tornado通常是独立运行的,不需要一个WSGI容器。然而,在一些环境中 (例如Google App Engine),只运行WSGI,应用程序不能独立运行自己的服务。在这种情况下,Tornado支持一个有限制的操作模式,不支持异步操作但允许一个Tornado's功能的子集在仅WSGI环境中。以下功能在WSGI模式下是不支持的,包括协程,@asynchronous 装饰器,AsyncHTTPClient,auth 模块和WebSockets。
你可以使用 tornado.wsgi.WSGIAdapter 把一个Tornado Application 转换成WSGI应用。在这个例子中, 配置你的WSGI容器发 现 application 对象:
import tornado.web import tornado.wsgi class MainHandler(tornado.web.RequestHandler): def get(self): self.write("Hello, world") tornado_app = tornado.web.Application([ (r"/", MainHandler), ]) application = tornado.wsgi.WSGIAdapter(tornado_app)
以上就是本文的全部内容,希望对大家的学习有所帮助。
更多PythonWeb框架Tornado运行和部署详细介绍相关文章请关注PHP中文网!