求助,支付系统的异步通知实现

2016-09-28 13:37:13 +08:00
 klgd

目前的实现方式:
参考支付宝的异步通知,每个订单的异步通知实行分频率发送:15s 3m 10m 30m 30m 1h 2h 6h 15h
脚本每秒请求数据库获取到时间需要发送的通知,返回成功则结束,失败则按下一个时间写入数据库,等待发送
目前的方式虽然实现了但是 1 、每秒请求有点儿浪费资源; 2 、通知方式不稳定; 3 、无法承受大数据量等等

现在想改为使用队列的方式实现,但是不知道如何实现通知返回失败,往队列里写下一次通知?
方案 1 :到下一次发送通知时间时,写入队列,队列实时处理,但不知道该如何实现到指定时间写队列
方案 2 :队列里延迟,也找到了可以实现这个延迟的队列 beanstalk,但是无法实现分布式,单台的方式公司运维不给弄,他建议用 kafka,但是 kafka 好像不可以延迟

想请教大家,异步通知是实现方案,或者上面的问题怎么解决?

11324 次点击
所在节点    程序员
27 条回复
pubby
2016-09-28 13:52:52 +08:00
benstalk 支持分布式的 类似 memcache ,客户端可以同时连几个 beanstalk 服务器
beanstalkd 的队列数据也可以写入磁盘 log 的

但是,如果一个挂掉,磁盘又出故障无法恢复的话,会丢失一部分队列数据
klgd
2016-09-28 14:17:56 +08:00
@pubby 看介绍说支持分布式,我安装了 php 扩展 https://github.com/nil-zhang/php-beanstalk/, phpinfo 里也看到有 beanstalk 扩展了,但是按照示例执行,始终返回 false ,不知道哪里的问题,而且扩展都是好几年前的了
moro
2016-09-28 14:20:19 +08:00
可以用 golang 写服务来处理,自身包含队列,异步发送通知。
klgd
2016-09-28 14:21:50 +08:00
@moro golang 不会啊
pubby
2016-09-28 14:22:56 +08:00
@klgd 不要 so 扩展,不稳定。

我用的是 composer require mrpoundsign/pheanstalk-5.3
xss
2016-09-28 14:28:46 +08:00
rabbitmq 不可以?
pubby
2016-09-28 14:30:07 +08:00
@klgd 不过我用的不支持连多个 server ,你可以其他找找看
moro
2016-09-28 14:38:05 +08:00
用 redis 的有序集合,按时间排序,每次把需要处理的事务插入进去。
处理部分每秒读取一次有序集合,只取出当前时间的进行处理就可以了。
moro
2016-09-28 14:39:19 +08:00
分布式的话可以在 redis 使用 lua 脚本来保证一致性。
pubby
2016-09-28 14:54:06 +08:00
klgd
2016-09-28 15:22:10 +08:00
@xss 不知道是否可以 没用过 rabbitmq
@moro 谢谢,我去尝试一下,每秒请求有没有好的方案?
@pubby 谢谢你的提供,这个包应该是可以用, so 扩展确实不好用,读队列就用死循环?有没有其他好的方案?
TangMonk
2016-09-28 15:28:04 +08:00
rabbitmq 有个插件可以延迟发送
moro
2016-09-28 15:31:45 +08:00
redis 每秒请求无压力,都是内存的。
fansgentle
2016-09-28 15:36:33 +08:00
Python 平台的话 Celery 就很赞 ...
pubby
2016-09-28 16:20:57 +08:00
@klgd 看了一下,这个库在 pool 上 reserve() job 的时候也有问题
它是随机找一个 server 获取的,如果队列很空的话,可能会长时间饿死状态。

put 也是随机找一个 server 写入


可以改变一下应用方案:
1. 生产者 put 的时候可以向所有 pool 里面随机挑选一个写入(内部已经实现)
2. 每个消费者脚本只连一台 beanstalkd 进行任务处理。任务忙,可以多启动几个消费者连接同一台 beanstalkd 。
accacc
2016-09-28 18:24:42 +08:00
使用 redis 的 zset 结构做队列 score 写入时间戳 按照小于当前时间的出队
hankwh
2016-09-28 18:58:12 +08:00
异步通知不好实现的话,你提供查询订单结果的接口就可以了,让接入方主动查询
klgd
2016-09-28 19:35:28 +08:00
@pubby 嗯,今天在试用时发现这个问题了,不过还没来得及思考如何和业务需求结合
@hankwh 查询接口有提供
@accacc redis 的排序功能?这个思路也不错,回头我想想怎么具体实现
@fansgentle python 不会啊
youxiaer
2016-09-28 19:41:03 +08:00
beanstalk 做这个很合适
sherlocktheplant
2016-09-28 19:50:29 +08:00
rabbitmq 好像可以实现你的功能 也支持分布式部署

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

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

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

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

© 2021 V2EX