Python bottle uses multiple ports (multiple processes) to increase the number of concurrent

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:

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&nbsp ..."  /bin/true                         else                                  action  "osyw ${i} start&nbsp ..."  / 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&nbsp ..."  /bin/true                     else                     action    "osyw ${i} stop&nbsp ..."  /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

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.