为什么 nameko 投递消息的速度这么慢?

使用 kombu 投递消息,哪怕开了消息持久化,单连接投递速度也在 1w+/s

但是 nameko,慢的离谱,不开持久化 1k+/s;开了消息持久化,100+/s

为什么呢?

后来研究了一下,这个和 amqp 的消息确认(confirm_publish)选项有关系。

参考:Kombu实现RabbitMQ的可靠消息发布(confirm机制)

如何开启 confirm_publish 呢?

创建连接的时候,带上 'confirm_publish': True 就是开启了 confirm_publish

with Connection(amqp_uri, transport_options={'confirm_publish': True}) as conn:
    with conn.channel() as channel:
        started_at = time.time()
        for i in range(10000):
            message = Message(channel=channel, body=data)

            producer = Producer(
                channel,
                exchange=refresh_exchange
            )

            res = producer.publish(
                body=message.body,
                routing_key='to_imdb',
                headers=message.headers,
                delivery_mode=2
                # serializer='pickle'
            )
        ended_at = time.time()
        logger.debug(f'pay time {ended_at-started_at} s')

来看看 nameko 是源码:

可以看到,默认是 confirms=True, 意味着消息确认是默认开启的

amqp/publish.py

@contextmanager
def get_producer(
    amqp_uri, confirms=True, ssl=None, login_method=None, transport_options=None
):
    if transport_options is None:
        transport_options = DEFAULT_TRANSPORT_OPTIONS.copy()
    transport_options['confirm_publish'] = confirms
    conn = Connection(
        amqp_uri, transport_options=transport_options, ssl=ssl,
        login_method=login_method
    )

    with producers[conn].acquire(block=True) as producer:
        yield producer

那如果要在 nameko 中关闭 confirm_publish 呢?可以使用 use_confirms 参数,示例如下:

import time
from nameko.constants import NON_PERSISTENT, PERSISTENT
from nameko.standalone.events import event_dispatcher
import settings
from loguru import logger


config = {
    'AMQP_URI': f'amqp://{settings.RABBITMQ_CONFIG.username}:'
                f'{settings.RABBITMQ_CONFIG.password}@{settings.RABBITMQ_CONFIG.host}:'
                f'{settings.RABBITMQ_CONFIG.port}/{settings.RABBITMQ_CONFIG.vhost}'
}
logger.debug(config)


data = {
    'name': 'jike',
    'age': 18,
    'score': {
        'math': 100,
        'science': 99.5,
        'english': 59
    }
}

dispatch = event_dispatcher(
    config, delivery_mode=PERSISTENT, use_confirms=False)

for _ in range(10000):
    # logger.debug(f'投递任务')
    dispatch(
        'productor_service',
        'a',
        data
    )

你可能感兴趣的:(python)