发红包是目前各大互联网公司最经常使用的营销手段之一,它形式多样,内容丰富。2016 年末苏宁金融开启了红包系统及相关系统的项目开发。前端
本文将对苏宁金融红包系统的架构部署方式、演变过程、技术优化等方面进行详细阐述。数据库
红包系统的技术挑战后端
红包,升级版的秒杀系统,红包系统应当具有秒杀系统所具有的特性。缓存
大量用户抢红包带来了系统的高并发压力;大量用户抢同一红包带来了数据一致性问题:红包不能超发,漏发,重复发;而因为红包涉及到资金,也会带来资金安全问题。安全
由上述可见,一套红包系统,主要的技术挑战在于:系统的高并发,一致性,高响应,安全性等。性能优化
红包系统性能优化(高性能&数据一致性)服务器
流量的削峰填谷网络
削峰填谷:顾名思义,就是在流量洪峰到来以前在系统负载比较低的时候进行数据预热等操做,用来分散红包活动开始后的高并发流量。架构
红包类营销活动的业务特色:定时的洪峰流量,经过“削峰填谷”有效减小瞬间流量对系统形成的冲击。并发
开户:用户参与苏宁抢红包活动,均需提早开通红包帐户,在红包活动开始后,用户瞬时并发大。
短期内大量用户参与活动,开通红包帐号会将访问请求瞬间提交到后端应用,会给后端的业务系统形成很大的开户压力。
为减轻基础服务压力,将流量峰值进行削峰,咱们采起了以下措施:
预热活跃用户
流量削峰填谷
异步化
异步红包充值及订单持久化:在红包发放环节,大量用户红包须要到帐,若是不对峰值进行处理,压力将会直接转嫁给上游系统形成处理压力,间接致使红包系统堵塞。
所以将充值转为异步处理,先将充值任务进行队列存储,而后分摊到多台机器(利用分布式优势)处理,提高系统处理效率,避免单台节点压力过大。
多级缓存(热点数据全局缓存化)
EHCACHE:本地对读取多,修改少的数据作 EHCACHE 本地缓存处理,减小访问数据库、分布式缓存的次数。
数据库缓存:提升数据库热表的数据缓存大小。
Redis:全局 Redis 数据化处理,利用 Redis 单线程,基于内存读写高 QPS 的特性,解决热点数据高并发,线程安全等一系列问题。
热点数据(包括红包订单,用户发,抢记录等)均存储至 Redis 系统中,并进行多分片部署,经过 Redis 高并发读写的特性,提高系统吞吐量。
另外,目前高并发 Java 系统的核心都是分布式微服务集群部署,这种部署状况下 JVM 级别的锁,线程安全的数据类型等都不适用,那么如何保证红包敏感数据在高并发下的线程安全性呢?
答案仍是 Redis,利用 Redis 单线程的处理特性,Redis 在修改数据方面是线程安全的。
如下为红包系统中用到 Redis 存储的部分场景:
Redis Pipeline 管道模式
烟花红包燃放环节对于系统响应时间要求很高。开发初期按照 2000 人参与,5S 响应时间设计,系统已经达到性能需求的要求。
但在活动运营后,易购将活动参与人数提升到了 8888 人,按照原有方案,响应时间变为 13S,耗时大大加长,没法知足性能要求。
在对 Redis 进行大批量的操做时,可使用 Pipeline 模式,经过减小网络传输时间,从而极大的提升系统性能。
在烟花红包发放中须要对 Redis 进行大量查询操做,在实际测试中发如今对接近 1W 个命令进行循环普通同步模式时须要 10S 左右,而改用 Pipeline 模式后处理时间在 100 毫秒之内。
分布式锁组件
回调式的分布式锁组件
在拆红包环节时可能出现同一用户拆两次红包的问题:当用户点击过快时,可能同一用户的两个线程同时经过了是否拆红包的条件校验,在这种状况下,该用户能够拆两次同一个红包。
针对这一问题,咱们经过对红包单号,用户编号两个维度加分布式锁来解决。
目前经常使用的分布式锁大体有三种实现:
基于实际执行效率和实现难度的考虑,在红包系统使用 Redis 实现了分布式锁组件。
加锁:使用高版本 Redis set 命令的 EX,PX 属性,实现加锁,超时时间设置的原子操做。
加锁
释放锁:经过 Lua 脚原本实现锁值判断,释放锁的原子操做。
释放锁
执行入口
抢红包、拆红包前的高效前置校验
拆红包做为红包操做中并发最高,处理步骤比较复杂的部分,如何削减拆红包的流量相当重要。
抢红包是拆红包大并发流量的第一道入口,系统设计要尽量知足快进快出的要求。
抢红包流程图
抢红包时只经过缓存计数器作简单的红包状态检验,能够过滤掉大部分拆红包的流量;计数器设置为仅从主 Redis 读,避免随机读的延迟问题。
红包系统高可用架构实践
分布式任务调度
分布式任务调度包括红包超时退款、异常补偿等,红包超过设定时间未被领取完如何退款?红包发放由于系统、网络等各方面的缘由,致使用户红包到帐失败如何给用户进行补偿?
由于红包涉及到资金问题,因此在红包发放、到帐、退款方面须要万无一失,不然可能会遭到用户的大量投诉,在这里咱们用苏宁统一任务调度平台进行分布式部署系统的定时任务调度。
定时扫描数据库中符合条件的订单,进行超时退款,发放异常重复订单发放等操做。
支付链路&帐户分离
经过设计专用的红包极简收银台、红包帐户实现红包发、抢、拆等过程与普通帐户、支付链路分离,避免在大促时对支付、会员、帐务核心等购物核心主链路形成压力。
高可用部署架构
上图为苏宁金融会员红包系统目前的单集群部署示意图,是典型的苏宁技术体系下的分布式,高可用系统部署结构。
它具有水平扩容,容灾和监控的能力:
服务器使用 Zabbix 平台进行性能监控,统一任务调度平台进行分布式任务的分发,使用云迹平台进行分布式日志的采集与查看。
为同时应对多个渠道,多种类型的红包类大促营销活动,红包系统采用多个集群部署方式部署,在本次双十一大促中同时为集团各产业红包—奖励金红包、体育红包、圈子红包等营销产品提供高性能高可用的服务支撑。
红包系统的大促保障
红包系统做为公司每次大促营销活动的重要参与系统之一,在 818&双十一等大促中须要应对瞬间海量流量,那么咱们如何在大促中监控、保障系统呢?
系统监控
目前在大促活动监控方面,主要分为两大块:
业务监控:苏宁金融自研监控平台,能够细化到服务秒级的调用数、成功率、调用耗时等的监控,能够灵活针对各项维度进行告警设置,在业务异常时进行短信或者邮件告警。
业务监控的意义在于实时监控生产线上的流量状况,在流量接近或者超过业务预期的性能阀值后,应当尽快进行服务降级或者生产扩容等紧急措施。
链路式服务监控
中间件监控:中间件的监控平台较多,Zabbix 平台监控服务器的性能指标,包括 CPU 使用率,内存使用率,磁盘使用率,网络流量等。
Redis 监控使用 Promes 监控平台;数据库监控使用苏宁自研数据库管理平台,可实时查看数据库状态,是否存在慢 SQL 等。
异常监管及日志查看使用苏宁自研分布式日志平台,可实时查看分布式系统日志,系统中的异常状况等。
中间件监控能够发现硬件层面的问题,例如系统压力过大时形成 CPU 太高等,能够根据具体指标进行扩容或者联系系统运维解决硬件问题。
多级流控
在流量洪峰来临时,如何优先保障系统稳定呢?首先,经过性能压测等手段确认系统的最大承受能力,为每一个服务&接口设定具体的流量阀值。
其后在各级流控平台进行流控配置:
为何要配置多种级别的流控服务呢?主要基于如下几点考虑:
系统降级
基于 Zookeeper 的分布式配置平台设置应用开关阀值,在系统压力过大时,经过开启关闭非核心应用功能,保障核心主链路的可用。
例如在发红包、抢红包的流量洪峰到来前,经过在配置平台修改开关值,能够暂时性的关闭红包消费功能(余额提现、兑券等),开关关闭后,消费功能暂时不可用,在流量洪峰消退后,打开开关,便可恢复消费功能。
打开和关闭的操做在半分钟内能够完成,快速保护红包核心主链路和恢复功能完整。
感兴趣的能够本身来个人Java架构群,能够获取免费的学习资料,群号:855801563 对Java技术,架构技术感兴趣的同窗,欢迎加群,一块儿学习,相互讨论。