Python 3 - AsyncIO - несколько типов входящих подключений - PullRequest
0 голосов
/ 05 марта 2020

TL; DR

Существует ли передовая практика, запрещающая микросервису разрешать входящие соединения для нескольких типов соединений? (MQ + HTTP)

Объяснение

Я занимаюсь разработкой системы с архитектурой микросервисов . У меня есть служба, которая получает запросы через asyn c на основе API . (Например, Sani c)

import asyncio
import json
from sanic import Sanic, response
from sanic.request import Request

app = Sanic()


async def do_work(parsed_request): # my service logic
    print(parsed_request)
    await asyncio.sleep(10)


async def parse_request(content):
    return await json.loads(content)  # whatever parses my request


@app.route('/work', methods=["POST"])
async def post_json(request):
    parsed_request = await parse_request(request.body)
    await do_work(parsed_request)
    return response.empty(201)


if __name__ == '__main__':
    app.run(host='127.0.0.1', port=8000)

Мой клиент запросил, чтобы я разрешил службе получать запросы через MQ (используя RabbitMQ), а не только API.

Итак, мне было интересно,
Является ли лучшая практика, запрещающая мне слушать MQ на Asyn c Задаче на том же сервисе?

import asyncio
import json
import aio_pika
from sanic import Sanic, response
from sanic.request import Request

app = Sanic()


async def do_work(parsed_request): # my service logic
    print(parsed_request)
    await asyncio.sleep(10)


async def parse_request(content):
    return json.loads(content)  # whatever parses my request


@app.route('/work', methods=["POST"])
async def post_json(request):
    assert isinstance(request, Request)
    parsed_request = await parse_request(request.body)
    await do_work(parsed_request)
    return response.empty(201)


async def listen_to_mq():
    connection = await aio_pika.connect_robust("amqp://guest:guest@127.0.0.1/", loop=asyncio.get_event_loop())
    queue_name = "work_queue"
    async with connection:
        channel = await connection.channel()
        queue = await channel.declare_queue(queue_name, auto_delete=True)
        async with queue.iterator() as queue_iter:
            async for message in queue_iter:
                parsed_request = await parse_request(message)
                await do_work(parsed_request)
                message.ack()


if __name__ == '__main__':
    app.add_task(listen_to_mq())
    app.run(host='127.0.0.1', port=8000)

Мои инстинкты кричат ​​"Нет !!! Не делай этого". Но я не смог найти в Интернете ничего о шаблонах микросервисов, которые мешали бы мне сделать это.

Я пришел к выводу:

  1. Различия в масштабируемости между протоколами
  2. Я бы не хотел, чтобы ошибка MQ влияла на мой API каким-либо образом
  3. Я чувствую, что это уродливо
...