业务场景

上上周新启动了一个项目,是和支付宝合作的,活动流程大概是这样:支付宝侧会开发一个H5活动——品牌密室,用户可以在支付宝中搜到该活动,然后进行游戏互动,游戏后就可以领取券码,关注并进入生活号中进行券码的查看以及门店核销。

我负责的部分主要是在用户领券并进入生活号的时候,我会收到支付宝的订阅消息请求,其中有支付宝用户id及其他信息,我需要给该用户分配一张数据库已有的券码并保存该数据,然后推送生活号模板消息给该用户,提醒他中奖。

项目难点

1.发券并发问题

由于券码不是在发放的时候随机生成的,在未发放的时候就已经生成并存在数据库中。

所以如果按照正常思维,先查询一张未发放的券码,然后将它与用户绑定,其实就是在表中增加一条领取记录然后将改券码状态修改为已发放。这样的话在并发状态下由于查询数据库是没有锁的,那么可能多个用户查到同一张券码,然后去绑定信息也就是修改数据库是加锁,第一个人将这个券码绑定之后,后面的人也会对这个券码绑定,这样就导致这个券码被多个人领取,出现业务差错。

2.支付宝技术对接

因为游戏方面是支付宝开发,那么用户领券关注公众号之后会跳转到公众号查看券码,这里就需要支付宝开发文档的蚂蚁消息订阅API,就是支付宝会推送用户领券数据到我们的后台,我们再进行券码绑定以及模板消息的发送。

但是支付宝的API也是给我们定制开发的,他们那边流程太麻烦,在钉钉群里回复消息总是很慢,而且数据比较严谨,不能随意测试。

3.服务器升级繁琐

该项目是SpringMVC项目,代码提交也是使用SVN,所以线上代码升级还需要替换相关class文件,还有一些查看实例状态以及日志的Linux命令,我之前都是没有接触的,所以刚开始确实有点困难。

4.线上并发问题

既然是与支付宝合作的项目,流量就可能很大,公司之前好像都是与微信以及支付宝小程序合作,并没有尝试过并发量这么大的开发,居然丢给我一个刚来公司的新人了,真看得起我哈哈。

解决方案

1.发券并发问题

对于这个问题,首先我想到的是乐观锁,我们先去查询数据库未发放状态的券码,然后更新操作时再判断该券码状态是否是未发放,如果不是未发放,当然就代表在这个过程中券码已经被别人领取了,就更新失败。

但是因为并发量很大,而且查询未发放券码一般都是默认第一个,这样会导致出现这个并发问题是只有一个用户可以领券成功,其他用户全部失败,虽然业务没有纰漏,但是非常影响用户体验,当然是不可取的。

然后又想那就从一百万张券码中随机查询一条未发放的券码,这样就会减少查询到同一条券码的概率,百度可以找到这个比较复杂的sql,但是经理感觉这样还是会有冲突几率,所以也没有采用。

最后的解决方案是既然先查询再更新不行,那就先更新在查询,因为支付宝的请求中有一个参数是用来控制幂等性的,这个数据也是要和券码绑定的,这个参数假定是ref_key。

那么具体做法是update table set status = 2 and ref_key = 'ref_key' limit 1;因为更新是有行锁的,所以并发状态下也不会更新同一条数据,然后我们再select code from table where ref_key = 'ref_key';这样就能得到被更新的券码是哪个。

2.redis队列

对于高并发情景,请求接收到之后,还要快速有效的处理并给出响应,对于支付宝这边的这种高流量,我们的做法是先将请求存储起来,然后再慢慢的去处理这些请求。就是典型的生产者消费者模式,我们的接口中收到请求,只是将请求放入队列中就算这个请求处理完成了。因为活动时间比较紧急,而且项目中没有mq基础,就决定先使用redis队列。

3.线程池异步

对于代码中比较费时又不影响总体流程的业务,可以做异步或者用线程池去单独处理,比如我们这里给用户绑定券码之后需要给用户发送支付宝生活号消息,是调用支付宝的API,每次调用还需要等待相应结果是否发送成功,这里就可以单独抽出去做异步处理。

4.多实例负载均衡

上述几点处理都是在请求接受成功之后的处理,但是请求要全部接收到才是高并发中最重要的内容。

这里并不是代码层面可以解决的问题,因为这个项目是部署在tomcat上,那么就取决于tomcat处理请求的能力以及服务器性能。

所以我们的做法有1.tomcat参数调优。
2.启动了8个tomcat实例,用Nginx做负载均衡
3.服务器扩容

项目收获

做这个项目其实压力蛮大的,因为之前并没有和支付宝有相关对接,当经理发给我一堆支付宝文档链接,将我拉进两个和支付宝对接的钉钉群里的时候,我都蒙了。不知道该怎么进行下一步,跟别人交流也很谨小慎微,生怕问出什么比较愚蠢的问题。

和支付宝联调测试也是比较麻烦,支付宝上班的人都这么拼么?要么就是凌晨我还在等他们,要么就是我刚起床就看到艾特我的消息,可太难了!!

虽然累,但是收获还是很大的,比如看文档的能力,解决问题的能力,沟通交流的能力,还有最大就是技术上的收获。

领导虽然在开发过程中有时长督促我,但是这也是作为一个领导该做的。在联调测试的时候,公司两个测试的妹子以及领导都是陪我一起的,领导还专门给我买了盒饭。

本来是31号上线的,但是支付宝那边LBS系统出了点问题,所以虽然也上线了,但是支付宝对此进行了限流,目前也才两万用户领券。

文章刚刚要写完,结果支付宝那边好像搞好了:

不说了,我要去看日志啦!

大家也可以参与哦

活动入口:支付宝首页滑动banner——选择开学季——派派任务——玩游戏抽大奖即可进入活动哦

Last modification:September 2nd, 2020 at 03:50 pm
如果觉得我的文章对你有用,请随意赞赏
评论打卡也可以哦,您的鼓励是我最大的动力!