RabbitMQ and PHP (2) -- Related service installation and how to use PHP as the daemon mode to process messages

Source: Internet
Author: User
Tags php multithreading
In the previous section, the concepts such as exchange, routingkey, and queue of RabbitMQ are described in detail, and the code for sending and processing messages using PHP is illustrated. This section describes how to use PHP multithreading to process messages in real time in the project, and briefly introduces the installation of RabbitMQ. If you are familiar with it, skip this part. 1. RabbitMQ installation:

In the previous section, the concepts such as exchange, routingkey, and queue of RabbitMQ are described in detail, and the code for sending and processing messages using PHP is illustrated. This section describes how to use PHP multithreading to process messages in real time in the project, and briefly introduces the installation of RabbitMQ. If you are familiar with it, skip this part.

1. RabbitMQ installation:

Install erlang first

# Install jdk environment sudo apt-get install openjdk-7-jdk # install related classes library and toolkit sudo apt-get install libncurses5-dev m4 fop freeglut3-dev libwxgtk2.8-dev g + + libssl-dev unzip tproc build-essential tk8.5 unixodbc unixodbc-dev libxml2-utils # Download the erlang installation package and install wget http://www.erlang.org/download/otp_src_R16B03-1.tar.gztar-xzvf otp_src_R16B03-1.tar.gzcd otp_src_R16B03-1. /configure -- prefix =/usr/local/erlangmakesudo make install

Note :? Here, erlang is installed in the specified directory :? /Usr/local/erlang instead of using the default path. This is a good habit and will be good for version control. But this will cause the following? RabbitMQ error: Cannot find erl? The execution file must be processed.

Update environment variables:

sudo vi /etc/profile


export PATH=/usr/local/erlang/bin:$PATH

Save and exit

source /etc/profile

Enter erl in the command line to check whether the installation is successful.

Install RabbitMQ

wget http://www.rabbitmq.com/releases/rabbitmq-server/v3.2.3/rabbitmq-server-generic-unix-3.2.3.tar.gztar -xzvf rabbitmq-server-generic-unix-3.2.3.tar.gzmv rabbitmq_server-3.2.3/ /usr/local/cd /usr/local/rabbitmq_server-3.2.3/sbin./rabbitmq-server

If an error message is displayed :?. /Rabbitmq-server :? Line? 86 :? Erl :? Command? Not? Found ?? This is because erlang specifies the installation PATH and cannot be found in the system PATH. As long as export? PATH = $ PATH:/usr/local/erlang/bin? You can.

For the convenience of rc. local startup? Export? PATH = $ PATH:/usr/local/erlang/bin? This row is written? Rabbitmq-server? File:

After Execution, ps? -Aux? See the process in/usr/local/erlang/lib/erlang/erts-5.10.1/bin/epmd? -Daemon? And? /Usr/local/erlang/lib/erlang/erts-5.10.1/bin/beam. smp? OK.

There is a script in the sbin Directory :? Rabbitmqctl? It is also very common, and? Rabbitmq-server? Similarly, you must specify the erlang path to work correctly.

Common methods:

Rabbitmqctl? Start_app? After the instance is started, run the following command to compare the Insurance Information: rabbitmqctl? List_exchanges? Show all current vswitches rabbitmqctl? List_queue? View the current valid queue status

2. PHP? Extension installation:

The PHP operation of rabbitmq requires the support of AMQP extension. Download extension :? Http://pecl.php.net/package/amqp ?, The installation process is the same as general extension,

/usr/local/php/bin/phpize./configure?--with-php-config=/usr/local/php/bin/php-configsudo make?&&?make?install

If an error is reported during compilation and installation, refer to this article: Problems and solutions to the PHP extension for installing RabbitMQ in Ubuntu 12.04.

Then edit php. ini? Insert:


Restart apache or nginx and check the anqp section in phpinfo.

III. how to use PHP for real-time backend message processing

First, ensure that the php file can correctly handle messages in blocking mode. For the code, see the previous section RabbitMQ and PHP (1 ).

Then, we use Python to implement a multi-threaded daemon, which calls PHP and uses PHP as the working thread.

Startup script: start_jobs.py

# _ * _ Coding: UTF-8 _ * _ ''' yoka at daemon on @ author: xwarrior @ update: jimmy.dong@gmail.com ''' # introduce the package required by the project here from MyJobs import MyJobsfrom MyThread import MyThreadimport loggingimport timedef main (): logger = logging. getLogger ('main () ') logger.info ('server start! ') Worker_threads = 2 # define the number of threads to be started. timeline = 2 # thread check interval. The second thread_pool ={} for I in range (0, worker_threads ): param = 'some param' job = MyJobs (param) thread = MyThread (job, I) thread. setDaemon = True thread. start () logger.info ('Start thread % s' % (thread. getName () thread_pool [I] = thread # End mode when finished # for eachKey in thread_pool.keys (): # thread_pool [eachKey]. join () # keep the thread count mode while 1: time. sl Eep (timeline) # check every thread for eachKey in thread_pool.keys (): if thread_pool [eachKey]. isAlive (): print 'thread alive: '+ str (I) else: print 'thread down:' + str (I) thread_pool [eachKey]. run () logger.info ('main exist! ') Returnif _ name _ =' _ main _ ': # init config format FORMAT =' % (asctime)-15 s % (name) s % (levelname) s file % (filename) s: lineno % (lineno) s-% (message) s 'logging. basicConfig (format = FORMAT, level = logging. INFO) main () pass

Thread script :? MyThread. py

# _ * _ Coding: UTF-8 _ * _ ''' Created on 2013-03-25 @ author: jimmy.dong@gmail.com ''' from threading import Threadclass MyThread (Thread ): ''' create thread ''' def _ init _ (self, job, thread_id): ''' Constructor ''' self. job = job Thread. _ init _ (self, name = 'My _ thread _ % s' % (thread_id) def run (self): self. job. run () def stop (self): self. job. exit ()

Task script :? MyJobs. py

# _ * _ Coding: UTF-8 _ * _ ''' Created on 2013-03-25 @ author: jimmy.dong@gmail.com ''' import osimport urllib2class MyJobs (object): def _ init _ (self, param): # do something self. param = param def _ del _ (self): ''' destruct ''' self. exit () def exit (self): ''' exit ''' self. quit = True def run (self): ''' start to process ''' # Use shell mode # cmd = '/usr/bin/curl "http://at.yoka.com/try/amqp_consume.php? Key = '+ str (self. param) + '"'cmd ='/usr/local/php/bin/php-c/usr/local/php/lib/nginx. ini/home/jimmy/at/DocumentRoot/try/amqp_consume.php '+ str (self. param) re = OS. system (cmd) # Use web mode # req = urllib2.Request ('http: // at.yoka.com/try/amqp_consume.php? Key = '+ str (self. param) # response = urllib2.urlopen (req) # re = response. read () # print re

In task scheduling (start_jobs.py), two working modes are designed:

One mode is to start N threads to work in total, which is suitable for completing a large task as soon as possible;

The other is to keep the number of processes. when a process is found to be completed, restart the process. Obviously, the user daemon is suitable for message processing.

The specific work is in MyJob. py, which provides two methods: System Shell call and URL call. We recommend that you use shell to directly call php, so that you can flexibly control Php. ini, such as adding auto_prepend_file and increasing max_execution_time.

In actual projects, assuming there are five types of messages, you can start 20 threads and pass thread_id as a parameter to PHP. PHP regards thread_id % 5 as the type to be processed, and then it can obtain the scenario where four threads are working for each type.

Considering the PHP execution time limit and memory leakage, you can set consume. the php script is improved to exit every time the PHP script processes a specified number of messages. The Python multi-threaded framework restarts the thread to ensure stable and reliable running. In addition, change the response to manual response to ensure that the message is correctly and effectively processed.

/$ Q-> consume ('processmessage'); // manual response required/*** consumption callback function */function processMessage ($ envelope, $ queue) {global $ counter; $ msg = $ envelope-> getBody (); echo $ msg. "\ n"; // process the message $ queue-> ack ($ envelope-> getDeliveryTag (); // manually send an ACK response if ($ counter ++> 5) return FALSE; // process 5 messages and exit}

Use? Two threads, check interval 2 seconds, SHELL mode? Test result:

It can be seen that after running, check that both threads are active and correctly process the messages. after processing a certain number of threads, the PHP program ends, the parent process checks that a process is in the completed state and restarts it (the second green box ). Exactly as expected.

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.