Python bottle uses multiple ports (multiple processes) to increase concurrency

Source: Internet
Author: User
Tags svn update nginx reverse proxy

My program was written in Python in conjunction with the Bottle framework, but the Bottle comes with Wsgi, which was originally a single-process single-threaded run mode (Bottle runs on the built-in Wsgiref server by default. This single-threaded HTTP server is particularly useful when developing, but its performance is low and may be a performance bottleneck when the server load is increasing, responding to only one request at a time. In order to improve the processing power of the program, it is first to enable multi-threading, that is, to use Gevent in the program (the thread pool for most servers limits the number of threads in the threading pools, avoiding the cost of creating and switching threads.) Although the thread is quite cheap compared to the process (fork). But it's not cheap. You can accept creating a thread for each request. The Gevent module adds support for Greenlet. Greenlet are similar to traditional threads, but they are created with minimal resources. Gevent-based servers can generate thousands of greenlet, and there is no pressure to assign a greenlet to each connection. Blocking the Greenlet does not affect the server accepting new requests. There is theoretically no limit to the number of connections processed at the same time. )。 Just add server= ' gevent ' to run, as follows:

1 import Gevent2 from gevent import         Code Snippet ... 4 run (host= ' 0.0.0.0 ', port=8080, server= ' gevent ')  

Although multithreaded mode is used, but these threads are running in a process, it is necessary to open multiple processes to further improve the concurrency processing power, so when the script is enabled, in Run (port=), the port number can not be written dead, you should use the variable to pass, the following code (when the script executes, the need to take a parameter , this parameter is an integer greater than 1024, or the error stops the script):

Import gevent,sysfrom gevent import  monkey.patch_all () #获取端口号try:    portnum = Int (sys.argv[1]) Except exception,e:    print "Please start this program with the port number of the integer type" logging.error ("Please start this program with the port number of the integer type") sys.exit (1) if Portnum <= 1024x768: print "port number is greater than 1024! " Logging.error (" The port number is greater than 1024!) ") Sys.exit (1) code snippet ... run (host= ' 0.0.0.0 ', Port=portnum, server= ' gevent '   )   

Execute as follows (osyw.py is my Python program name):

Python osyw.py 1124

If the purely manual operation of these, in the production, very inconvenient, so I wrote a shell to manage, the shell defines a number of port numbers, and then to loop to enable or stop the Python process, the script is probably as follows (is rewritten with httpd):

#!/bin/bash## osyw Startup script for the osyw HTTP server## chkconfig:-The 18# description:osyw# Processname:os yw# config: # config:/home/bottle/osyw/# pidfile:/var/run/osyw.pid#### BEGIN INIT info# provides:osyw# short-descriptio N:start and Stop Osyw http server# description:the osyw HTTP Server is a extensible server # implementing the current HTTP standards.### END INIT info# Source function Library: /etc/rc.d/init.d/functions# Path to the Apachectl script, server binary, and short-form for messages.port_list= (8811 8812 8813) #设置了3个端 Port #pidfile= '/var/run/osyw.pid ' pro_path= '/var/www/osyw/osyw.py ' #程序路径log_path = '/var/www/osyw/log/access.log ' # Access log Path retval=0start () {for i in ${port_list[*]} do p= '/usr/sbin/lsof-i: ${i} |WC-L ' If [${p}-ge 2] then action "Osyw ${i} already exists!"/bin/False Else/usr/bin/python ${pro_path} ${i} &>>${log_path} retval=$? if [${retval} = =0] Then action "Osyw ${i} start ..."/bin/True ElseAction "Osyw ${i} start ..."/bin/False fi fi done return$RETVAL}stop () {for i in ${port_list[*]} do pidfile= "/var/run/osyw_${i}.pid" if [-F ${pidfile}] then pid=' Cat ${pidfile} ' kill-9 ${pid} retval=$? If [${retval} = = 0] then action "O Syw ${i} stop ... "/bin/true Else action" Osyw ${i} stop ... "/bin/false fi rm-f ${pidfile} else acti On "Osyw ${i} have stopped!"/bin/false fi done}# See how we were Called.case "$" in start) start; stop) stop;; Status) status-p ${pidfile} ' osyw ' retval=$?;; restart) Stop sleep 2 start; condrestart|try-Restar T) if Status-p ${pidfile} ' osyw ' >&/dev/null; then stop start fi;; force-reload|  reload) reload;; *) echo $ "Usage: $prog {start|stop|restart|condrestart|try-restart|force-reload|reload|status|fullstatus| Graceful|help|configtest} " retval=2esacexit $RETVAL        

My code is managed with SVN, so after uploading the code, the SVN hook will invoke the shell script to restart these programs, the following is the SVN hook code:

Export Lang=en_us. UTF-8/USR/BIN/SVN update--username xxxx--password xxxxxxxx/var/bottle/bin/bash/etc/init.d/osyw Restart

Of course, in order to combine the Shell,python program to do some processing, such as automatically turn the program into the daemon, and then write the process ID to the file, the following is the key Python code:

#定义PID路径 Pid_path = '/var/run/osyw_%s.pid '%portnum def daemonize (): "" "Convert this script to daemon" "Try: pid=os.fork () if pid><  C4>0:sys.exit (0) except exception,e:logging.error (E) sys.exit (1) Os.chdir ('/') os.umask (0) Os.setsid () Try: pid=os.fork () if pid>0:sys.exit (0) except exception,e:logging.error (e) sys.exit (1) pid = str (os.getpid ()) with open (Pid_path, ' W ') as F:f.write (PID) Other code snippet ... if __name__ = = ' __main__ ' 
                 
                   try
                  : from oscore import setting #导入配置文件 if Setting.status = = ' online ': #如果配置中是线上的, the program is running in the background daemonize () excep T exception:pass app = Default_app () app = Sessionmiddleware (app, session_opts) # Sessionmiddleware is session plugin run (app=app,host= ' 0.0.0.0 ', port=portnum,server= ' gevent ')    
                 

Best, with Nginx proxy to load these ports, my nginx and Python programs are installed on the same server:

The above is the Nginx reverse proxy part of the code:

Upstream MyWeb {#ip_hash; server 192.168.1.240:8811 weight=4 max_fails=2 fail_timeout= 30s;server 192.168.1.240:8812 weight=4 max_fails=2 fail_timeout=30s;server 192.168.1.240:8813 weight=4 max_fails=2 Fail_ timeout=30s;} server {    listen       ;        server_name  192.168.1.240; location/ {proxy_pass/http/myweb; proxy_set_header Host $host; proxy_ Set_header x-forwarded-for$remote _addr; Proxy_cache_key $host $uri$is_args$args;} access_log off; }

After these, when access to 80 port, Nginx will be the average wheel xun assigned to each port up, the implementation of multi-process, multi-threaded operation mode, more effective to enhance the concurrency processing power

Python bottle uses multiple ports (multiple processes) to increase concurrency

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.