flask 框架开发 api 接口,当 wsgi 服务器层返回失败时该如何处理业务.

2017-04-06 11:01:16 +08:00
 abxialiang

业务是这样:

服务端有个任务队列,我提供了一个接口,客户端每调一次,返回队列的头任务后并移除该任务,理想情况下是每个任务都被客户端正常获取到.

但是我用 gevent(wsgi 服务器)+flask 来实现这样的接口时遇到一个问题,就是不能确定是否成功返回了数据,客户端可能压根没收到,万一出现这样的情况,这个任务任务就也被移除并丢失了,比如下面这样的代码.

@app.route("/gettask", methods=['GET', 'POST'])
def gettask():
    return 'task' #这里不是函数,我不知道最后没有有成功返回给客户端

目前思路:

1.直接用 socket 开发接口,比如调用其 sendall(),这种是可以判断成功与否的,但这是最后的选择

2.客户端要在成功取到一个任务后再通知服务端,然后接口才移除该任务(这里需要超时机制,客户端也需要确保通知被服务端成功收到了)

3.不管,听天由命了-_-!

2489 次点击
所在节点    Python
12 条回复
sagaxu
2017-04-06 11:20:35 +08:00
1. socket 的 sendall 并不能保证对方已经收到,所以你第一个思路行不通
2. 这是比较可行的方式,但是也要考虑一种情况,客户端收到了,但是应答的时候出故障了
prasanta
2017-04-06 11:29:46 +08:00
这个任务队列是什么东西
abxialiang
2017-04-06 11:55:19 +08:00
@sagaxu
socket 层面出现数据丢失的问题可以不考虑了,就认为 TCP 协议是可靠的,否则用第 2 个思路也是死循环了
abxialiang
2017-04-06 11:56:00 +08:00
@prasanta
可以理解为
[1,2,3,4,5,6,7,8,9,....]
est
2017-04-06 12:00:17 +08:00
你这个需求跟 flask 、 api 和 wsgi 服务器 都没关系。

新开一个 API 接受回调吧。
sagaxu
2017-04-06 12:07:58 +08:00
@abxialiang TCP 协议是可靠的,然而 sendall 只是把数据从应用的 buf 复制到内核 buf 就返回了,还没开始 TCP 层面的传输呢
abxialiang
2017-04-06 13:27:29 +08:00
@est
@sagaxu
看来需要在应用层增加确认
guyskk
2017-04-06 14:05:41 +08:00
分成 2 个接口:
1. 获取队列头,如果客户端获取失败可以不断重试
2. 根据任务 ID 删除队列中的任务,如果删除失败也可以不断重试

然后就没法保证一个任务只被一个客户端拿到了。。。
Luckyray
2017-04-06 14:10:22 +08:00
新开 API 接受回调+ 1
abxialiang
2017-04-06 14:38:56 +08:00
@guyskk
@Luckyray
知道怎么做了,谢谢各位大佬
Immortal
2017-04-06 14:42:17 +08:00
新开 API 接受回调+ 2
ryd994
2017-04-07 09:14:47 +08:00
其实你要关注的不是客户端有没有收到,而是有没有处理
如果客户端收到之后崩了呢?要不要重试?
直接和重试机制做到一起就 OK 了
多少时间内没有收到处理完成的确认就让其他人重试,当然任务本身得是幂等的

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/352877

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX