首页
运维教程
Linux基础
系统服务
系统架构
数据库
shell脚本
虚拟化
大数据
DevOps
企业案例
运维开发
python
go语言
运维安全
行业资讯
网络基础
系统安全
运维面试
学习路线
学习方法
面试题库
职场解惑
软件
运维软件
办公软件
书籍资源
技术陪跑营
重要信息
首页 运维教程系统架构O2O小程序点餐平台架构分享

O2O小程序点餐平台架构分享

本文选自 前1号店首席架构师王友庆的分享:

项目背景

先说下项目的背景。这是一个小程序点餐平台,用户在小程序上点餐并支付完成后,订单会先落到订单库,然后进一步推送到门店的收银系统;

收银系统接单后,推送给后厨系统进行生产;同时返回小程序取餐码,用户可以凭取餐码去门店取餐或收取外卖。

这个项目服务于一家大型的餐饮公司,公司在全国有大量的门店,他们准备搞一个长期的大型线上促销活动,促销的力度很大:用户可以在小程序上先领取优惠券,然后凭券再支付 1 元,就可以购买价值数十元的套餐。

我们预计在高峰时,前端小程序请求将会达到每秒 10 万 QPS,并且预计首日的订单数量会超过 500 万。在这种高并发的情况下,我们为了保证用户的体验,系统整体的可用性要达到 99.99%。

这里呢,我具体说下系统主要的调用过程,以便于你更好地理解它:

  1. 小程序前端通过 Nginx 网关,访问小程序服务端;

  2. 小程序服务端会调用一系列的基础服务,完成相应的请求处理,包括门店服务、会员服务、商品服务、订单服务、支付服务等,每个服务都有自己独立的数据库和 Redis 缓存;

  3. 订单服务接收到新订单后,先在本地数据库落地订单,然后通过 MQ 同步订单给 OMS 履单中心;

  4. 门店的收银系统通过 HTTP 远程访问云端的 OMS 履单中心,拉取新订单,并返回取餐码给 OMS,OMS 再调用小程序订单服务同步取餐码;

  5. 小程序前端刷新页面,访问服务端获得取餐码,然后用户可以根据取餐码到门店取餐或等待外卖。

高可用措施改造

我在前面也介绍了,这次活动的促销力度很大,高峰期流量将达到平时的数十倍,这就要求系统能够在高并发的场景下,保证高可用性

所以,基于访问量、日订单量和可用性的指标,我们对原有系统进行了一系列改造,最终顺利地实现了首日 500 万订单,以及在大促期间,系统 4 个 9 的可用性目标。这个 500 万的订单量,也创造了中国单商户线上交易的历史记录。

在下面的系统架构图中,我标出了具体的改造点,主要有 10 处,接下来我就给你分别具体介绍一下,你可以通过这些具体的改造措施,来真正理解高可用系统的设计手段。

前端接入改造

这里的前端有两个,C 端的小程序和 B 端的门店收银系统。前端部分主要是对三个点进行改造,包括小程序端的 CDN 优化、Nginx 负载均衡,以及收银端的通信线路备份。

小程序端的 CDN 优化

用户点餐前,需要先浏览商品和菜单,这个用户请求的频率很高,数据流量大,会对服务端造成很大的压力。所以,针对这一点,我们通过 CDN 供应商,在全国各地构建了多个 CDN 中心,储存静态的商品数据,特别是图片,这样小程序前端可以就近访问 CDN,流量无需通过小程序服务端,缓解了服务端的压力。

Nginx 负载均衡

这个小程序点餐平台,之前是直接利用云服务商提供的 LB,它只有简单的负载均衡能力。为了能应对这次的高并发流量,现在我们独立搭建了数十台的 Nginx 集群,集群除了负载均衡,还提供限流支持,如果 QPS 总数超过了 10 万,前端的访问请求将会被丢弃掉。

另外,Nginx 在这里还有一个好处,就是可以实时提供每个接口的访问频率和网络带宽占用情况,能够起到很好的接入层监控功能

补充说明:一台 Nginx 一般可以支持数万的并发,本来这里无需这么多台 Nginx,这是因为云服务商对单个 LB 的接入有网络带宽的限制,所以我们要通过提升 Nginx 的数量,来保证接入有足够的带宽。

收银端的通信线路备份

门店的收银系统会通过前置代理服务器,来访问云端的 OMS 系统,这个代理服务器部署在商户自己的 IDC 机房,原来只通过电信线路和云端机房打通。在这次改造中,我们增加了移动线路,这样当电信主线路出问题时,系统就可以快速地切换到移动线路。

应用和服务的水平扩展

首先,针对小程序服务端的部署,我们把实例数从十几台提升到了 100 台,水平扩展它的处理能力。在上面的架构图中,你可以看到,小程序服务端依赖了 7 个基础服务,每个基础服务也做了相应的水平扩展,由于应用和基础服务都是无状态的,因此我们很容易扩充。

这里的基础服务是 Java 开发的,原来是用虚拟机方式部署的,现在我们把基础服务全部迁移到了容器环境,这样在提升资源利用率的同时,也更好地支持了基础服务的弹性扩容。

订单水平分库

在大促情况下,下单高峰期,订单主库的写访问频率很高,一个订单会对应 6~7 次的写操作,包括了创建新订单和订单状态变更;订单的读操作,我们之前通过一主多从部署和读写分离,已经得到了支持。

但负责写入的主库只有一个实例,所以这次我们通过订单的水平分库,扩充了订单主库的实例数,改造后,我们有 4 个主库来负责订单数据写入。数据库的配置,也从原来的 8 核 16G 提升到了 16 核 32G,这样我们通过硬件的垂直扩展,进一步提升了数据库的处理能力。

这里的订单水平分库在实现上比较简单,我们是通过订单 ID 取模进行分库,基于进程内的 Sharding-JDBC 技术,实现了数据库的自动路由。后面的课程中,我会专门介绍电商平台的订单水平分库,它会更加复杂,到时你可以做个比较,如果有需要的话,也可以在实际项目参考落地。

异步化处理

你可以看到,在前台订单中心和后台 OMS 之间,我们需要同步订单数据,所以这两者是紧密耦合的。不过这里,我们通过消息系统对它们进行了解耦。 一方面,前台下单要求比较快,后台 OMS 的订单处理能力比较弱(OMS 库没有进行水平分库),通过消息的异步化处理,我们实现了对订单流量的削峰;另一方面,如果 OMS 有问题,以异步的方式进行数据同步,也不会影响前台用户下单。

还有在小程序服务端,在用户支付完成或者后台生成取餐码后,我们会以微信消息的方式通知用户,这个在代码中,也是通过异步方式实现的,如果微信消息发送不成功,用户还是可以在小程序上看到相关信息,不影响用户取餐。

主动通知,避免轮询

在原来的架构中,前台小程序是通过轮询服务端的方式,来获取取餐码;同样,商户的收银系统也是通过轮询 OMS 系统拉取新订单,这样的收银系统有上万个,每隔 10s 就会拉取一次。这种盲目轮询的方式,不但效率低,而且会对服务端造成很大的压力。

经过改造后,我们落地了消息推送中心,收银系统通过 Socket 方式,和推送中心保持长连接。当 OMS 系统接收到前台的新订单后,会发送消息到消息推送中心;然后,收银系统就可以实时地获取新订单的消息,再访问 OMS 系统拉取新订单。为了避免因消息推送中心出问题(比如消息中心挂掉了),导致收银系统拿不到新订单,收银系统还保持对 OMS 系统的轮询,但频率降低到了 1 分钟一次。

同理,小程序前端会通过 Web Socket 方式,和消息推送中心保持长连接。当 OMS 系统在接收到收银系统的取餐码后,会发送消息到消息推送中心。这样,小程序前端可以及时地获取取餐码信息。

缓存的使用

我们知道,缓存是提升性能十分有效的工具。这里的改造,就有两个地方使用了缓存。

  • 当收银系统向 OMS 拉取新订单时,OMS 不是到数据库里查询新订单,而是把新订单先保存在 Redis 队列里,OMS 通过直接查询 Redis,把新订单列表返回给收银系统。

  • 在商品服务中,菜单和商品数据也是放在了 Redis 中,每天凌晨,我们通过定时任务,模仿前端小程序,遍历访问每个商品数据,实现对缓存的预刷新,进一步保证缓存数据的一致性,也避免了缓存数据的同时失效,导致缓存雪崩。

一体化监控

在前面各个节点可用性优化的基础上,我们也在系统的监控方面做了很多强化。除了常规的 Zabbix 做系统监控、CAT 做应用监控、拉订单曲线做业务监控以外,我们还对系统实现了一体化的监控。

在这里,所有的节点都在一个页面里显示,包括 Web 应用、Redis、MQ 和数据库,页面也会体现节点之间的上下游关系。我们通过采集节点的状态数据,实时监测每个节点的健康程度,并且用红黄绿三种颜色,表示每个节点的健康状况。这样,我们就可以非常直观地识别出,当前的哪些节点有问题。

本文链接:http://www.geekyunwei.com/713.html

网友评论comments

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注

暂无评论

Copyright © 2021 极客运维 公众号《极客运维之家》
扫二维码
扫二维码
返回顶部