標籤:啟動 red lse epo pytho sign port local cells
Nginx是一個高效的Web伺服器及Proxy 伺服器,Tornado是一個基於epoll的非同步Web開發架構,通常使用Nginx做為Web伺服器時,都會以FastCGI模式,而我們從開發、調試、營運的角度考慮,使用了反向 Proxy的模式,同時Nginx可以做一些特殊業務和負載平衡的處理。
其實反向 Proxy模式很簡單,Nginx監聽在80連接埠,做為Web服務連接埠,而Tornado的Web服務進程監聽在808*的內部連接埠(可以啟動多個進程),使用supervisor對Nginx、Tornado服務進程進行統一的管理。
首先看supervisor的配置:
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647 |
# supervisor自己的配置及日誌切割等 [supervisord] logfile = /opt/logs/supervisord .log logfile_maxbytes = 200MB logfile_backups=10 loglevel = warn pidfile = /opt/logs/supervisord .pid nodaemon = false minfds = 1024 minprocs = 200 umask = 022 identifier = supervisor directory = %(here)s nocleanup = true strip_ansi = false [unix_http_server] file = /opt/logs/supervisord .sock [supervisorctl] serverurl = unix: ///opt/logs/supervisord .sock [rpcinterface:supervisor] supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface # 服務進程的啟動及多連接埠 [program:MyWeb] command = /opt/bin/python %(here)s /server .py --port=808%(process_num)01d process_name = 808%(process_num)01d numprocs = 4 numprocs_start = 1 autostart = true autorestart = true redirect_stderr = true stdout_logfile = /opt/logs/stdout .log stderr_logfile = /opt/logs/stdout .log # Nginx的管理配置 [program:Nginx] command = /opt/sbin/nginx -c %(here)s /nginx .conf process_name = Nginx numprocs = 1 autostart = true autorestart = true redirect_stderr = true stdout_logfile = /opt/logs/nginx_stdout .log stderr_logfile = /opt/logs/nginx_stdout .log |
啟動指令碼(可以放到start.sh中):
1 |
/opt/bin/supervisord /opt/conf/supervisor .conf |
重啟指令碼(可以放到restart.sh中)
12345678 |
#逐個啟動MyWeb每個連接埠進程,不中斷服務 for i in "8081 8082 8083 8084" : do /opt/bin/supervisorctl /opt/conf/supervisor .conf restart MyWeb:$i; done #重新載入nginx的配置 /opt/sbin/nginx /opt/conf/nginx .conf -s reload; |
Nginx的部分配置(啟動4個服務進程,監聽在80連接埠,並反向 Proxy負載到Tornado的808*連接埠上):
123456789101112131415161718192021222324 |
worker_processes 4; daemon off; #nginx不能以daemon模式啟動 user nobody; http { upstream myweb { server 127.0.0.1:8081; server 127.0.0.1:8082; server 127.0.0.1:8083; server 127.0.0.1:8084; } server { listen 80; server_name localhost; location / { proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Scheme $scheme; proxy_read_timeout 300s; proxy_pass http: //myweb ; } } } |
現在Nginx已經反向 Proxy到Tornado的服務進程監聽的連接埠了,那麼MyWeb的服務進程如何構建、並如何優雅的重啟呢,略過其他代碼,介紹一下主進程採用訊號停止服務,並重新啟動的方法。主進程的啟動參數會指定此進程監聽的連接埠,這樣supervisor檢測到服務進程結束後,會自動啟動對應的服務進程。
1234567891011121314151617181920212223242526272829303132333435363738394041 |
import signal import tornado.ioloop import tornado.httpserver http_server = None def sig_handler(sig, frame): """訊號處理函數 """ tornado.ioloop.IOLoop.instance().add_callback(shutdown) def shutdown(): """進程關閉處理 """ # 停止接受Client串連 global http_server http_server.stop() io_loop = tornado.ioloop.IOLoop.instance() deadline = time.time() + 10 #設定最長強制結束時間 def stop_loop(): now = time.time() if now < deadline: io_loop.add_timeout(now + 1 , stop_loop) else : io_loop.stop() stop_loop() if __name__ = = ‘__main__‘ : # 等待supervisor發送進程結束訊號 signal.signal(signal.SIGTERM, sig_handler) signal.signal(signal.SIGINT, sig_handler) app = Application() http_server = tornado.httpserver.HTTPServer(app, xheaders = True ) http_server.listen(tornado.options.options.port) tornado.ioloop.IOLoop.instance().start() |
生產環境優雅的重啟基於Nginx、Tornado的Web服務進程