最近用sanic的搭建一个服务,与寻常业务不同的是,要求请求发送之后 立即响应,同时后台异步处理业务,又要求支持并发,又不想添加消息队列的中间件。
多方查询,最后找到了两种方案:
方案一:
在业务层代码是这么写的:
async def post(self,request):
myloop = request.app.loop
myloop.create_task(testFunc(request.json))
return json({'msg':'执行成功'})
查找过很多方案的小伙伴,应该知道这块内容,创建一个loop将任务放进loop中,然后执行,当遇到IO操作时,执行其它任务。这里有一个问题,如果不遇到IO操作,第一个请求 会一直处理,此时第二个请求过来之后 需要等第一个请求处理完 才会返回。最后pass掉了 这个方案。
方案二:
代码一:在sanic服务启动时,创建一个队列对象,dada
class client(object):
def __init__(self,queue):
self.queue = queue
def send(self,param):
self.queue.put_nowait(param)
@app.main_process_start
async def start(app):
manager = Mananger()
app.shared_ctx.queue = manager.Queue()
@app.main_process_ready
async def ready(app):
app.manager.manage('worker',testFunc,{'queue':app.shared_ctx.queue})
@app.after_server_start
async def setup_client(app):
app.ctx.client = client(app.shared_ctx.queue)
代码二:接收到请求后,往队列发送消息,然后立即返回
class TestFunc(HTTPMethodView):
async def post(self,request):
request.app.ctx.client.send(request.json)
return json({'msg':'hello process'})
代码三:sanic服务启动时候,执行testFunc方法,写个死循环,不停的遍历queue队列。
def testFunc(queue):
while True:
if not queue.empty():
#执行的内容
pass
return None
看懂了吧