Python3.7 asyncio启动Web服务器(FastAPI)和aio_pika使用者

时间:2019-12-05 13:50:01

标签: python-3.x python-asyncio fastapi hypercorn

在我的项目中,我尝试启动REST API(使用FastAPI构建并使用Hypercorn运行),此外,我还想在启动时启动RabbitMQ Consumer(使用aio_pika):

Aio Pika提供了可靠的连接,该连接会在发生故障时自动重新连接。如果我使用hypercorn app:app运行下面的代码,则使用者和其余接口将正确启动,但是从aio_pika进行的重新连接不再起作用。如何在两个不同的进程(或线程)中归档生产稳定的RabbitMQ Consumer和RestAPI?我的python版本是3.7,请注意,如果我的方法不是Python方式,我实际上是Java and Go开发人员:-)

@app.on_event("startup")
def startup():
   loop = asyncio.new_event_loop()
    asyncio.ensure_future(main(loop))


@app.get("/")
def read_root():
   return {"Hello": "World"}


async def main(loop):
connection = await aio_pika.connect_robust(
    "amqp://guest:guest@127.0.0.1/", loop=loop
)

async with connection:
    queue_name = "test_queue"

    # Creating channel
    channel = await connection.channel()  # type: aio_pika.Channel

    # Declaring queue
    queue = await channel.declare_queue(
        queue_name,
        auto_delete=True
    )  # type: aio_pika.Queue

    async with queue.iterator() as queue_iter:
        # Cancel consuming after __aexit__
        async for message in queue_iter:
            async with message.process():
                print(message.body)

                if queue.name in message.body.decode():
                    break

1 个答案:

答案 0 :(得分:0)

在@pgjones的帮助下,我设法将消费开始改为:

@app.on_event("startup")
def startup():
    loop = asyncio.get_event_loop()
    asyncio.ensure_future(main(loop))

然后以job开始asyncio.ensure_future,并将当前事件循环作为参数传递,从而解决了问题。

如果有人采用不同/更好的方法,那将很有趣 谢谢!