Python-based RabbitMQ and pythonrabbitmq

Source: Internet
Author: User

Python-based RabbitMQ and pythonrabbitmq
RabbitMQ is a complete and reusable enterprise Message System Based on AMQP. He complies with the Mozilla Public License open-source protocol. MQ is called Message Queue. MQ is a communication method for applications. Applications communicate by reading and writing messages in and out of the queue (for Application Data) without dedicated connections. Message transmission refers to the communication between programs by sending data in messages, rather than by directly calling each other. Direct calls are usually used for such remote process calls. Queuing means that applications communicate through queues. The use of the queue removes the need to receive and send applications simultaneously. Install RabbitMQ:

Install configure epel source :( see http://www.cnblogs.com/ernest-zhang/p/5714434.html) install erlang: yum-y install erlang Note: Error: Package: erlang-erts-R14B-04.3.el6.i686 (epel) Requires: libz when installing erlang. so.1 (ZLIB_1.2.2) [root @ localhost ~] # Yum whatprovides libz. so.1Loaded plugins: rhnpluginThis system is not registered with RHN. RHN support will be disabled. zlib-1.2.3-25.el6.i686: The zlib compression and decompression library # provides The compression and decompression library Repo: localMatched from: Other: libz. so.1 check found that it should be the zlib version too old, download the latest zlib-1.2.8-10.fc24.i686 from the Internet, and then use RPM after installation to solve. : Http://www.zlib.net/# http://rpmfind.net/linux/rpm2html/search.php zlib official website? Query = zlib # download the website to install rabbitMQ: yum-y install rabbitmq-server
Service rabbitmq-server start/stop start and stop the rabbitmq installation API, and then you can operate rabbitmq Based on the API
Pip install pikaoreasy_install pikaor source https://pypi.python.org/pypi/pika
Python operation on RabbitMQ release end:
Import pikaconnection = pika. blockingConnection (pika. connectionParameters (host = '2017. 168.0.74 ') # server address channel = connection. channel () channel. queue_declare (queue = 'Hi') # skip this step if a queue exists. If no queue exists, create a queue channel. basic_publish (exchange = '', routing_key = 'cc', body = 'Hello! World !!! ') Print ("[x] sent' hello, world! '") Connection. close ()

Acceptor:

Import pika # create a connection object and bind IPconnection = pika of rabbitmq. blockingConnection (pika. connectionParameters (host = '2017. 168.0.74 ') # create a channel object channel = connection. channel () # specify the queue in the channel. If no queue is specified in MQ, the queue is created. If yes, the channel is skipped. queue_declare (queue = 'Hi') # define the callback function def callback (ch, method, properties, body): print ('[x] Recieved % R' % body) # channel. close () # no_ack = Fales: indicates that you do not actively notify rabbitmq about the status after consumption. callback: callback function, queue: Specifies the queue channel. basic_consume (callback, queue = 'hi', no_ack = True) # channel. basic_consume (callback, queue = 'cc') print ('[*] Waiting for msg') channel. start_consuming ()

1. acknowledgment messages are not lost

No-ack = False. If the consumer fails (its channel is closed, connection is closed, or TCP connection is lost, rabbitMQ adds the task to the queue again.

  • In the callback functionch.basic_ack(delivery_tag=method.delivery_tag)
  • In basic_comsumeno_ack=False
Import pikaconnection = pika. blockingConnection (pika. connectionParameters (host = '2017. 168.0.74 ') channel = connection. channel () channel. queue_declare (queue = 'Hi') # define the callback function def callback (ch, method, properties, body): print ('[x] Recieved % R' % body) # channel. close () ch. basic_ack (delivery_tag = method. delivery_tag) # no_ack = Fales: indicates that the status notification rabbitmqchannel is not automatically notified after consumption. basic_consume (callback, queue = 'hi', no_ack = False) print ('[*] Waiting for msg') channel. start_consuming ()View Codedurable message is not lost

The producer end fails to send the message and the consumer fails to receive the message. The following method will allow RabbitMQ to re-Add the message to the queue:

  • In the callback functionch.basic_ack(delivery_tag=method.delivery_tag),What the consumer needs to do
  • In basic_comsumeno_ack=False,What the consumer needs to do
  • Add the parameter basic_publish at the message publishing end.properties=pika.BasicProperties(delivery_mode=2),What the producer needs to do
Import pikaconnection = pika. blockingConnection (pika. connectionParameters (host = '2017. 168.0.74 ') channel = connection. channel () channel. queue_declare (queue = 'Hi') # If yes, skip it. If no, create a queue channel. basic_publish (exchange = '', routing_key = 'hi', body = 'Hello! World !!! ', Properties = pika. BasicProperties (delivery_mode = 2) # message persistence print ("[x] sent 'hello, world! '") Connection. close ()Producer import pikaconnection = pika. blockingConnection (pika. connectionParameters (host = '2017. 168.0.74 ') channel = connection. channel () channel. queue_declare (queue = 'Hi') # define the callback function def callback (ch, method, properties, body): print ('[x] Recieved % R' % body) # channel. close () ch. basic_ack (delivery_tag = method. delivery_tag) # no_ack = Fales: indicates that the status notification rabbitmqchannel is not automatically notified after consumption. basic_consume (callback, queue = 'hi', no_ack = True) print ('[*] Waiting for msg') channel. start_consuming ()Order of obtaining consumer messages

By default, the data in the message queue is taken by the consumer in order. For example, consumer 1 gets the odd sequence from the queue and consumer 2 gets the even sequence from the queue. However, in most cases, the processing capabilities of consumer servers at the backend of the message queue are different. In this case, some servers are idle for a long time and resources are wasted, we need to change the order of obtaining the default message queue!

channel.basic_qos(prefetch_count=1)It indicates who gets the data and no longer sorts it by parity,This is what the consumer needs to do.

Import pikaconnection = pika. blockingConnection (pika. connectionParameters (host = '2017. 168.0.74 ') channel = connection. channel () channel. queue_declare (queue = 'Hi') # define the callback function def callback (ch, method, properties, body): print ('[x] Recieved % R' % body) # channel. close () ch. basic_ack (delivery_tag = method. delivery_tag) channel. basic_qos (prefetch_count = 1) # change the default acquisition order. Who will fetch it? # no_ack = Fales: indicates that rabbitmqchannel is not notified of the status after consumption. basic_consume (callback, queue = 'hi', no_ack = True) print ('[*] Waiting for msg') channel. start_consuming ()Consumer publishing and subscription

The difference between publishing and subscription is that publishing and subscription will send messages to all subscribers, and the data in the message queue will disappear once it is consumed. Therefore, when RabbitMQ implements publishing and subscription, a queue is created for each subscriber, and when the publisher publishes a message, the message is placed in all related queues.

In RabbitMQ, all messages submitted by the producer are accepted by Exchange, and then Exchange forwards messages to the Queue for storage according to specific policies. RabbitMQ provides four types of Exchange: fanout, direct, topic, and headerheader modes, which are rarely used in actual use. Only the first three modes are compared.

exchange type = fanout

Any message sent to Fanout Exchange will be forwardedExchangeAll the Queue of the Binding.

1. It can be understood as the route table mode.

2. RouteKey is not required in this mode.

3. In this mode, you need to bind Exchange and Queue in advance. One Exchange can bind multiple Queue and one Queue can be bound to multiple exchanges.

4. If the Exchange receiving the message is not bound to any Queue, the message will be discarded.

Import pikaconnection = pika. blockingConnection (pika. connectionParameters (host = '2017. 168.0.74 ') channel = connection. channel () channel. exchange_declare (exchange = 'logs _ fanout', type = 'fanout') msg = '000000' channel. basic_publish (exchange = 'logs _ fanout', routing_key = '', body = msg) print ('start sending: % s' % msg) connection. close ()Producer import pikaconnection = pika. blockingConnection (pika. connectionParameters (host = '2017. 168.0.74 ') channel = connection. channel () channel. exchange_declare (exchange = 'logs _ fanout', type = 'fanout') # randomly create a queue result = channel. queue_declare (exclusive = True) queue_name = result. method. queue # bind the relevant queue name channel. queue_bind (exchange = 'logs _ fanout', queue = queue_name) def callback (ch, method, properties, body): print ('[x] % R' % body) channel. basic_consume (callback, queue = queue_name, no_ack = True) channel. start_consuming ()Consumer

Keywords

Any message sent to Direct Exchange will be forwarded to the specified Queue in RouteKey. 1. In general, you can use the Exchange: "(the Exchange name is an empty string, which is called default Exchange below) that comes with rabbitMQ ). 2. In this mode, you do not need to bind Exchange to any binding operation. 3. A "RouteKey" is required for message transmission, which can be simply understood as the name of the queue to be sent. 4. If the queue name specified in RouteKey does not exist in the vhost, the message will be discarded. Import pikaconnection = pika. blockingConnection (pika. connectionParameters (host = '2017. 168.0.74 ') channel = connection. channel () channel. exchange_declare (exchange = 'logs _ direct_test1 ', type = 'direct') serverity = 'error' msg = '000000' channel. basic_publish (exchange = 'logs _ direct_test1 ', routing_key = serverity, body = msg) print ('start sending: % r: % R' % (serverity, msg) connection. close ()Producer import pikaconnection = pika. blockingConnection (pika. connectionParameters (host = '2017. 168.0.74 ') channel = connection. channel () channel. exchange_declare (exchange = 'logs _ direct_test1 ', type = 'direct') # randomly create a queue result = channel. queue_declare (exclusive = True) queue_name = result. method. queueserties = ['error', 'info', 'warning',] for serverity in serverities: channel. queue_bind (exchange = 'logs _ direct_test1 ', queue = que Ue_name, routing_key = serverity) print ('[***] start to accept messages! ') Def callback (ch, method, properties, body): print (' [x] % r: % R' % (method. routing_key, body) channel. basic_consume (callback, queue = queue_name, no_ack = True) channel. start_consuming ()Consumer 1 import pikaconnection = pika. blockingConnection (pika. connectionParameters (host = '2017. 168.0.74 ') channel = connection. channel () channel. exchange_declare (exchange = 'logs _ direct_test1 ', type = 'direct') # randomly create a queue result = channel. queue_declare (exclusive = True) queue_name = result. method. queueserties = ['error',] for serverity in serverities: channel. queue_bind (exchange = 'logs _ direct_test1 ', queue = queue_name, routing _ Key = serverity) print ('[***] start to accept the message! ') Def callback (ch, method, properties, body): print (' [x] % r: % R' % (method. routing_key, body) channel. basic_consume (callback, queue = queue_name, no_ack = True) channel. start_consuming ()Consumer 2

Fuzzy subscription

Any messages sent to Topic Exchange will be forwarded to all Queue that care about the specified Topic in RouteKey. this mode is complicated. In short, each queue has a topic of interest, and all messages carry a "RouteKey ), exchange will forward messages to all queues whose followers can be fuzzy matched with RouteKey. 2. This mode requires RouteKey. You may need to bind Exchange and Queue in advance. 3. when binding, you must provide a topic that the queue cares about, such as "#. log. # "indicates that the queue cares about all messages involving logs (one RouteKey is" MQ. log. the error message is forwarded to the queue ). 4. "#" indicates 0 or several keywords, and "*" indicates a keyword. For example, "log. *" can match "log. warn" and cannot match "log. warn. timeout", but "log. #" can match the two. 5. Similarly, if Exchange does not find a Queue that can match RouteKey, the message will be discarded. #! /Usr/bin/env pythonimport pikaimport sysconnection = pika. blockingConnection (pika. connectionParameters (host = '2017. 168.0.74 ') channel = connection. channel () channel. exchange_declare (exchange = 'topic _ logs', type = 'topic ') routing_key = sys. argv [1] if len (sys. argv)> 1 else 'Anonymous. info 'message = ''. join (sys. argv [2:]) or 'Hello World! 'Channel. basic_publish (exchange = 'topic _ logs', routing_key = routing_key, body = message) print ("[x] Sent % r: % r" % (routing_key, message) connection. close ()Producer #! /Usr/bin/env pythonimport pikaimport sysconnection = pika. blockingConnection (pika. connectionParameters (host = '2017. 168.0.74 ') channel = connection. channel () channel. exchange_declare (exchange = 'topic _ logs', type = 'topic ') result = channel. queue_declare (exclusive = True) queue_name = result. method. queuebinding_keys = sys. argv [1:] if not binding_keys: sys. stderr. write ("Usage: % s [binding_key]... \ n "% sys. argv [0]) sys. exit (1) for binding_key in binding_keys: channel. queue_bind (exchange = 'topic _ logs', queue = queue_name, routing_key = binding_key) print ('[*] Waiting for logs. to exit press CTRL + C') def callback (ch, method, properties, body): print ("[x] % r: % r" % (method. routing_key, body) channel. basic_consume (callback, queue = queue_name, no_ack = True) channel. start_consuming ()Good consumer recommended: http://hwcrazy.com/b5fce358672411e3baa0000d601c5586/group/free_open_source_project/

 

 

  

  

 

 

 

 

  

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.