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:
Import geventfrom gevent import Monkey.patch_all () code snippet ... 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:prin T "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 <= 1024:print "port number please 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: - 88 18# description: Osyw# processname: osyw# config: # config: /home/bottle/osyw/# pidfile: /var/run/osyw.pid#### begin init info# provides: osyw# short-description: start and stop osyw http server# description: the osyw http server is an 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个端口 #pidfile= '/var/run/osyw.pid ' pro_path= '/var/www/osyw/osyw.py ' #程序路径log_path = '/var/www/osyw/log/access.log ' #访问日志路径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 else action "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 "osyw ${i} stop  ..." /bin/true else action "osyw ${i} stop  ..." /bin/false fi rm -f ${pidfile} else action "osyw ${i} has 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-restart) 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
:
650) this.width=650; "class=" wp-image-532 "src=" Http://www.linuxyw.com/wp-content/uploads/2015/05/shell.png "alt=" Shell bottle "width=" 681 "height=" 555 "style=" margin:0px;padding:0px;border:0px none;width:auto;height:auto; "/>
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 (): "" "to convert this script to daemon" "" try: pid=os.fork () if pid>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 snippets ... if __name__ == ' __main__ ': try: from oscore import setting #导入配置文件 if setting.status == ' online ': #如果配置中是线上的, The program goes into the background run &NBSP;&NBSP;&NBSP;&NBsp; daemonize () except Exception: pass app = default_app () app = Sessionmiddleware (app, session_opts) #sessionMiddleware是session插件 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 80; 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
This article from "Jiangjiang" blog, please be sure to keep this source http://drfdai.blog.51cto.com/3825228/1653306
Python bottle uses multiple ports (multiple processes) to increase the number of concurrent