记录第一次参与高并发场景业务

业务场景

上上周新启动了一个项目,是和支付宝合作的,活动流程大概是这样:支付宝侧会开发一个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——选择开学季——派派任务——玩游戏抽大奖即可进入活动哦

欢迎访问我的个人小站:我爱吃土豆

已标记关键词 清除标记
“秒杀”这一业务场景在如今已经不是什么新鲜名词,它本质上属于短时突发性高并发访问问题,业务特点如下: 1. 定时触发,流量在瞬间突增 2. 秒杀请求中常常只有部分能够成功 3. 秒杀商品数量往往有限,不能超卖,但能接受少卖 4. 不要求立即返回真实下单结果 秒杀场景下,短时突发大流量的访问很容易对系统造成较大的访问压力,因此我们需要采取一定的措施对系统进行改造或者定制。 解决的思路就是“异步化”。而 RocketMQ 恰恰是实现业务异步化、削峰填谷的利器。 本篇 Chat 就是围绕高并发秒杀的实战场景,通过图解、编码、案例分析等方式对 RocketMQ 如何在实战中落地做一个较为详细的讲解。主要内容如下: 1. 了解“秒杀”业务的特点; 2. 学习“秒杀”业务的流程; 3. 分析“秒杀”业务的解决方案; 4. 使用 RocketMQ 进行“秒杀”收单; 5. 使用 RocketMQ 进行“秒杀”发单; 6. 自定义消息协议; 7. RocketMQ 集群搭建及管控台 console 的使用等。 --- 作者介绍: 李伟,Apache RocketMQ 北京社区联合发起人, RocketMQ 社区 Python 客户端负责人。对分布式系统设计和研发有丰富经验,对消息队列有深刻理解。目前在VIPKIP担任架构师,负责 VIPKID 消息平台的探索、研发和创新。 武文良,Apache RocketMQ 社区核心贡献者,高阳捷迅后端高级工程师。在电商充值、支付等核心交易链路研发经验丰富,尤其擅长商品秒杀等高并发场景系统设计与开发。 *当前内容版权归码字科技所有并授权显示,盗版必究。[阅读原文](http://gitbook.cn/gitchat/activity/5d1d6171bdaa30360df3b138)*
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页