Problem

用Flask写一个处理请求的函数,这个函数本身会再发送一个请求出去(在我这里是发送消息到一个Kafka消息队列,调用的其Python sdk里面的KafkaProducer.send)。在本地运行是没什么问题,放到服务器上跑的时候Kafka那边怎么都接收不到消息。然后我通过log来打点发现Flask的请求处理函数是触发的,并且KafkaProducer.send语句也是被执行了的。再然后我用了remote debugging来调试,发现逐条运行是正常的,但直接运行处理函数是有问题的。

Reason

到此已经非常接近真相了。真相只有一个,凶手就是时间!我在KafkaProducer.send后面添加了time.sleep(60),果然运行没有问题了!

也就是说KafkaProducer.send是异步执行的,而Flask对其请求的处理是用一个新的线程来执行处理函数,当此函数运行结束后线程就被销毁并放回线程池了,而此时KafkaProducer.send还没来得及执行完成(因为是异步的)。

Solution

确保Flask请求函数中所有的异步操作都同步后再离开函数(线程)。