#IT star is not a dream # [0] to start real development Python Python integration ActiveMQ

table of Contents:

1.  Python integration ActiveMQ

2.  Packaging Services mq_service.py

3. The  reception processing message mq_listener.py

4.  Start the message listener service mq.py

The  unit tests test_mq_serivce.py

6.  Send Message function calls

7.  Common Problems and Solutions


ActiveMQ is a very popular service middleware message queues, implements the JMS specification (port 61613) to support Python-based access STOMP protocol. Integrated Python ActiveMQ use stomp.py, simply arranged, this article further encapsulated in Django framework services mq_service.py


JMS:Java Message Service

STOMP: Simple (or Streaming) Text Orientated Messaging Protocol, Simple (Flow) text message oriented protocol


A typical system architecture diagram and message queues:

image.png

The timing is as follows:

image.png

Sample Code: https://github.com/rickding/HelloPython/tree/master/hello _activemq

├── settings.py

├── sq.m.

│   └── mq_service.py

│   └── mq_listener.py

├── tests

│   └── test_mq_service.py

├── management

│   └── commands

│        └── mq.py


一,Python集成ActiveMQ


代码文件

功能要点

Python集成ActiveMQ

requirements.txt

安装stomp.py:

stomp.py >= 5.0.1

封装服务

mq_serivce.py

封装ActiveMQ的消息发送和处理功能。在Django框架下,将地址等配置在settings.py中集中管理,注意端口为61613

接收处理消息

mq_listener.py

增加消息接收处理类,继承stomp.ConnectionListener

启动消息监听服务

mq.py

在Django框架下,将启动服务代码封装成command,方便调用和维护。

单元测试

test_mq_serivce.py

测试封装的功能函数

功能调用

views.py

增加REST接口/chk/mq,调用mq_service发送消息


1. 新建Django项目,运行:django-admin startproject hello_activemq

2. 进到目录hello_activemq,增加应用:python manage.py startapp app

image.png

项目的目录文件结构如下:

image.png

3. 安装stomp.py,pip install stomp.py >= 5.0.1


二,封装服务mq_service.py,调用ActiveMQ发送消息

1. 增加mq_service.py:

import json
import logging
import stomp
from django.conf import settings

log = logging.getLogger(__name__)

def send_msg(msg_dict, queue_or_topic=settings.MQ_QUEUE):
    conn = stomp.Connection10([(settings.MQ_URL, settings.MQ_PORT)])
    conn.connect(settings.MQ_USER, settings.MQ_PASSWORD)

    msg_str = json.dumps(msg_dict)
    log.info('Send msg: %s, %s, %s' % (type(msg_dict), type(msg_str), msg_str))
    conn.send(queue_or_topic, msg_str)
    conn.disconnect()

2. 打开settings.py,配置ActiveMQ信息:

MQ_URL = '127.0.0.1'
MQ_PORT = 61613
MQ_USER = 'admin'
MQ_PASSWORD = 'admin'
MQ_QUEUE = '/queue/SampleQueue'
MQ_TOPIC = '/topic/SampleTopic'

3. 为了增加代码的兼容和容错能力,封装get_conn(), close_conn()等辅助函数,详见代码文件mq_service.py


三,接收处理消息mq_listener.py

1. 增加mq_listener.py,声明消息处理类,继承stomp.ConnectionListener

import json
import logging
import stomp

log = logging.getLogger(__name__)

class MqListener(stomp.ConnectionListener):
    def on_message(self, headers, msg_str):
        log.info('Receive msg: %s, %s, %s' % (type(msg_str), msg_str, headers))

        msg_dict = None
        try:
            msg_dict = json.loads(msg_str)
        except Exception as e:
            log.warning('Exception when parse msg: %s' % str(e))

        log.info('Parsed msg: {}, {}'.format(type(msg_dict), msg_dict))

    def on_error(self, headers, msg_str):
        log.info('Error msg: %s, %s, %s' % (type(msg_str), msg_str, headers))

2. on_message()函数中,将消息字符串解析为json,方便业务处理

3. 声明on_error()函数处理错误信息。


四,启动消息监听服务mq.py

1. 将循环接收消息代码封装成函数consume_msg(),增加在服务中mq_serivce.py:

import logging
import time
import stomp
from django.conf import settings

log = logging.getLogger(__name__)

def consume_msg(listener, queue=settings.MQ_QUEUE, topic=settings.MQ_TOPIC):
    conn = stomp.Connection10([(settings.MQ_URL, settings.MQ_PORT)])
    conn.connect(settings.MQ_USER, settings.MQ_PASSWORD)
    
    conn.set_listener('', listener)
    conn.subscribe(queue)
    conn.subscribe(topic)

    while 1:
        time.sleep(1000)  # secs

    conn.disconnect()

2. 调用set_listener()设置消息接收类实例,使用之前创建的MqListener

3. 调用subscribe()订阅消息,启动循环监听。

4. 我们将启动服务代码封装成command,在目录management/commands中增加mq.py

import logging
from django.core.management.base import BaseCommand
from hello_activemq.mq import mq_service as mq
from hello_activemq.mq.mq_listener import MqListener

log = logging.getLogger(__name__)


class Command(BaseCommand):
    help = 'mq starts listener'

    def handle(self, *args, **options):
        log.info("mq starts")
        return mq.consume_msg(MqListener())

5. 运行命令python manage.py mq,看到消息提示,启动监听服务成功。

image.png

五,单元测试test_mq_service.py

增加测试函数,发送消息:

import logging
from django.test import TestCase
from hello_activemq.mq import mq_service as mq

log = logging.getLogger(__name__)

class MQServiceTest(TestCase):
    def test_send_msg(self):
        msg_dict = {'content': 'test msg dict', 'msg': 'msg from python'}
        mq.send_msg_to_queue(msg_dict)
        mq.send_msg_to_topic({'msg': "test msg from python"})

运行python manage.py test,同时看到监听服务收到并处理消息:

image.png

六,发送消息功能调用

1. views.py中发送消息,调用mq_servcie.py

import json
from django.http import HttpResponse
from hello_activemq.mq import mq_service as mq

def chk_mq(req):
    msg_dict = {
        'url': req.get_raw_uri(),
        'path': req.get_full_path(),
        'host': req.get_host(),
    }

    mq.send_msg_to_queue(msg_dict)
    mq.send_msg_to_topic(msg_dict)

    return HttpResponse(json.dumps(msg_dict))

2. urls.py中配置路由

from django.urls import path
from app.views import chk_mq

urlpatterns = [
    path('', chk_mq, name='chk'),
]

3. 运行命令启动服务:python manage.py runserver 0.0.0.0:8001

image.png

4. REST接口发送消息

image.png

七,常见问题和解决方法

1. 启动服务错误:[transport.py: 787, attempt_connection] Could not connect to host 127.0.0.1, port 61613

解决:检查ActiveMQ是否正常启动,特别注意是否开启STOMP协议端口61613

原因:Python连接ActiveMQ使用STOMP协议,端口默认61613


2. 接收到的消息内容不正确

Resolution: The message content is serialized to JSON, call json.dumps send () call json.loads () is received

Reason: the Python connection ActiveMQ STOMP protocol is used, as a simple text message format.


Note: the JMS specification class definition message 5:

String TextMessage,

Key-value pairs MapMessage,

Serialized object ObjectMessage

Byte stream BytesMessage

Data flow StreamMessage

image.png

ActiveMQ JMS messaging support Category 5, an increase of binary large file messages BlobMessage:

image.png

Guess you like

Origin blog.51cto.com/13851865/2471132