揭秘微信红包:架构、抢红包算法、高并发和降级方案

2023-05-16

编者按

与传统意义上的红包相比,近两年火起来的“红包”,似乎才是如今春节的一大重头戏。历经上千年时代传承与变迁,春节发红包早已成为历史沉淀的文化习俗,融入了民族的血脉。按照各家公布的数据,除夕全天微信用户红包总发送量达到80.8亿个,红包峰值收发量为40.9万个/秒。春晚直播期间讨论春晚的微博达到5191万条,网友互动量达到1.15亿,网友抢微博红包的总次数超过8亿次。

为此,InfoQ策划了“春节红包”系列文章,以期为读者剖析各大平台的红包活动背后的技术细节。本文为微信篇。

微信红包在经过15年春晚摇一摇之后,2015年上半年业务量一度呈指数级增长。尤其是微信红包活跃用户数的大量增长,使得2016除夕跨年红包成为极大挑战。为了应对16年春节可预知的红包海量业务,红包系统在架构上进行了一系列调整和优化。主要包括异地架构、cache系统优化、拆红包并发策略优化、存储优化一系列措施,为迎接2016春节红包挑战做好准备。 下面介绍最主要的一些思路。

架构

微信用户在国内有深圳、上海两个接入点,习惯性称之为南、北(即深圳为南,上海为北)。用户请求接入后,不同业务根据业务特性选择部署方式。微信红包在信息流上可以分为订单纬度与用户纬度。其中订单是贯穿红包发、抢、拆、详情列表等业务的关键信息,属于交易类信息;而用户纬度指的是红包用户的收红包列表、发红包列表,属于展示类信息。红包系统在架构上,有以下几个方面:

南北分布

1、订单层南北独立体系,数据不同步

用户就近接入,请求发红包时分配订单南北,并在单号打上南北标识。抢红包、拆红包、查红包详情列表时,接入层根据红包单号上的南北标识将流量分别引到南北系统闭环。根据发红包用户和抢红包用户的所属地不同,有以下四种情况:

1) 深圳用户发红包,深圳用户抢

订单落在深圳,深圳用户抢红包时不需要跨城,在深圳完成闭环。

2) 深圳用户发红包,上海用户抢

订单落在深圳,上海用户抢红包,在上海接入后通过专线跨城到深圳,最后在深圳闭环完成抢红包。

3) 上海用户发红包,上海用户抢

订单落在上海,上海用户抢红包时不需要跨城,在上海完成闭环。

4) 上海用户发红包,深圳用户抢

订单落在上海,深圳用户抢红包,从深圳接入后通过专线跨城到上海,最后在上海闭环完成抢红包。

系统这样设计,好处是南北系统分摊流量,降低系统风险。

2、用户数据写多读少,全量存深圳,异步队列写入,查时一边跨城

用户数据的查询入口,在微信钱包中,隐藏的很深。这决定了用户数据的访问量不会太大,而且也被视为可旁路的非关键信息,实时性要求不高。因此,只需要在发红包、拆红包时,从订单纬度拆分出用户数据写入请求,由MQ异步写入深圳。后台将订单与用户进行定时对账保证数据完整性即可。

3、支持南北流量灵活调控

红包系统南北分布后,订单落地到深圳还是上海,是可以灵活分配的,只需要在接入层上做逻辑。例如,可以在接入层中,实现让所有红包请求,都落地到深圳(无论用户从上海接入,还是深圳接入),这样上海的红包业务系统将不会有请求量。提升了红包系统的容灾能力。同时,实现了接入层上的后台管理系统,实现了秒级容量调控能力。可根据南北请求量的实时监控,做出对应的调配。

4、DB故障时流量转移能力
基于南北流量的调控能力,当发现DB故障时,可将红包业务流量调到另外一边,实现DB故障的容灾。

预订单

支付前订单落cache,同时利用cache的原子incr操作顺序生成红包订单号。优点是cache的轻量操作,以及减少DB废单。在用户请求发红包与真正支付之间,存在一定的转化率,部分用户请求发红包后,并不会真正去付款。

拆红包入账异步化

信息流与资金流分离。拆红包时,DB中记下拆红包凭证,然后异步队列请求入账。入账失败通过补偿队列补偿,最终通过红包凭证与用户账户入账流水对账,保证最终一致性。

这个架构设计,理论基础是快慢分离。红包的入账是一个分布事务,属于慢接口。而拆红包凭证落地则速度快。实际应用场景中,用户抢完红包,只关心详情列表中谁是“最佳手气”,很少关心抢到的零是否已经到账。因为只需要展示用户的拆红包凭证即可。

发拆落地,其他操作双层cache

1、Cache住所有查询,两层cache

除了使用ckv做全量缓存,还在数据访问层dao中增加本机内存cache做二级缓存,cache住所有读请求。

查询失败或者查询不存在时,降级内存cache;内存cache查询失败或记录不存在时降级DB。

DB本身不做读写分离。

2、DB写同步cache,容忍少量不一致
DB写操作完成后,dao中同步内存cache,业务服务层同步ckv,失败由异步队列补偿,定时的ckv与DB备机对账,保证最终数据一致。

高并发

微信红包的并发挑战,主要在于微信大群,多人同时抢同一个红包。这种情况,存在竞争MySQL行锁。为了控制这种并发,团队做了以下一些事情:

1、请求按红包订单路由,逻辑块垂直sticky,事务隔离

按红包订单划分逻辑单元,单元内业务闭环。服务rpc调用时,使用红包订单号的hash值为key寻找下一跳地址。对同一个红包的所有拆请求、查询请求,都路由到同一台逻辑机器、同一台DB中处理。

2、Dao搭建本机Memcache内存cache,控制同一红包并发个数

在DB的接入机dao中,搭建本机内存cache。以红包订单号为key,对同一个红包的拆请求做原子计数,控制同一时刻能进DB中拆红包的并发请求数。

这个策略的实施,依赖于请求路由按红包订单hash值走,确保同一红包的所有请求路由到同一逻辑层机器。

3、多层级并发量控制
1) 发红包控制

发红包是业务流程的入口,控制了这里的并发量,代表着控制了红包业务整体的并发量。在发红包的业务链路里,做了多层的流量控制,确保产生的有效红包量级在可控范围。

2) 抢红包控制

微信红包领取时分为两个步骤,抢和拆。抢红包这个动作本身就有控制拆并发的作用。因为抢红包时,只需要查cache中的数据,不需要请求DB。对于红包已经领完、用户已经领过、红包已经过期等流量可以直接拦截。而对于有资格进入拆红包的请求量,也做流量控制。通过这些处理,最后可进入拆环节的流量大大减少,并且都是有效请求。

3) 拆时内存cache控制

针对同一个红包并发拆的控制,上文已经介绍。

4、DB简化和拆分

DB的并发能力,有很多影响因素。红包系统结合红包使用情境,进行了一些优化。比较有借鉴意义的,主要有以下两点:

1) 订单表只存关键字段,其他字段只在cache中存储,可柔性。

红包详情的展示中,除了订单关键信息(用户、单号、金额、时间、状态)外,还有用户头像、昵称、祝福语等字段。这些字段对交易来说不是关键信息,却占据大量的存储空间。

将这些非关键信息拆出来,只存在cache,用户查询展示,而订单中不落地。这样可以维持订单的轻量高效,同时cache不命中时,又可从实时接口中查询补偿,达到优化订单DB容量的效果。

2) DB双重纬度分库表,冷热分离

使用订单hash、订单日期,两个纬度分库表,也即db_xxx.t_x_dd这样的格式。其中,x表示订单hash值,dd表示01-31循环日。订单hash纬度,是为了将订单打散到不同的DB服务器中,均衡压力。订单日期循环日纬度,是为了避免单表数据无限扩张,使每天都是一张空表。

另外,红包的订单访问热度,是非常典型的冷热型。热数据集中在一两天内,且随时间急剧消减。线上热数据库只需要存几天的数据,其他数据可以定时移到成本低的冷数据库中。循环日表也使得历史数据的迁移变得方便。

红包算法

首先,如果红包只有一个,本轮直接使用全部金额,确保红包发完。

然后,计算出本轮红包最少要领取多少,才能保证红包领完,即本轮下水位;轮最多领取多少,才能保证每个人都领到,即本轮上水位。主要方式如下:

计算本轮红包金额下水位:假设本轮领到最小值1分,那接下来每次都领到200元红包能领完,那下水位为1分;如果不能领完,那按接下来每次都领200元,剩下的本轮应全部领走,是本轮的下水位。

计算本轮红包上水位:假设本轮领200元,剩下的钱还足够接下来每轮领1分钱,那本轮上水位为200元;如果已经不够领,那按接下来每轮领1分,计算本轮的上水位。

为了使红包金额不要太悬殊,使用红包均值调整上水位。如果上水位金额大于两倍红包均值,那么使用两倍红包均值作为上水位。换句话说,每一轮抢到的红包金额,最高为两倍剩下红包的均值。

最后,获取随机数并用上水位取余,如果结果比下水位还小,则直接使用下水位,否则使用随机金额为本轮拆到金额。

柔性降级方案

系统到处存在发生异常的可能,需要对所有的环节做好应对的预案。下面列举微信红包对系统异常的主要降级考虑。

1、 下单cache故障降级DB

下单cache有两个作用,生成红包订单与订单缓存。缓存故障情况下,降级为直接落地DB,并使用id生成器独立生成订单号。

2、 抢时cache故障降级DB

抢红包时,查询cache,拦截红包已经抢完、用户已经抢过、红包已经过期等无效请求。当cache故障时,降级DB查询,同时打开DB限流保护开关,防止DB压力过大导致服务不可用。

另外,cache故障降级DB时,DB不存储用户头像、用户昵称等(上文提到的优化),此时一并降级为实时接口查询。查询失败,继续降级为展示默认头像与昵称。

3、 拆时资金入账多级柔性

拆红包时,DB记录拆红包单据,然后执行资金转账。单据需要实时落地,而资金转账,这里做了多个层级的柔性降级方案:

大额红包实时转账,小额红包入队列异步转账 所有红包进队列异步转账 实时流程不执行转账,事后凭单据批量入账。

总之,单据落地后,真实入账可实时、可异步,最终保证一致即可。

4、 用户列表降级

用户列表数据在微信红包系统中,属于非关键路径信息,属于可被降级部分。

首先,写入时通过MQ异步写,通过定时对账保证一致性。

其次,cache中只缓存两屏,用户查询超过两屏则查用户列表DB。在系统压力大的情况下,可以限制用户只查两屏。

调整后的系统经过了16年春节的实践检验,平稳地度过了除夕业务高峰,保障了红包用户的体验。

作者介绍

方乐明,2011年毕业于华南理工大学通信与信息系统专业,毕业后就职于财付通科技有限公司。微信支付团队组建后,主要负责微信红包、微信转账、AA收款等支付应用产品的后台架构。

原文:http://www.infoq.com

http://cxy.liuzhihengseo.com/522.html

转载于:https://www.cnblogs.com/8hao/p/5383143.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

揭秘微信红包:架构、抢红包算法、高并发和降级方案 的相关文章

  • React Native工程中TSLint静态检查工具的探索之路

    建立的代码规范没人遵守 xff0c 项目中遍地风格迥异的代码 xff0c 你会不会抓狂 xff1f 通过测试用例的程序还会出现Bug xff0c 而原因仅仅是自己犯下的低级错误 xff0c 你会不会抓狂 xff1f 某种代码写法存在问题导致
  • github hexo常用命令

    61 61 61 安装hexo cd d hexo npm install hexo cli g hexo init blog cd blog npm install hexo g 或者hexo generate hexo s 或者hexo
  • ftp服务器多用文件夹权限,访问ftp服务器文件夹权限设置

    访问ftp服务器文件夹权限设置 内容精选 换一换 媒体处理服务无存储功能 xff0c 您需要先将待转码的原始视频文件上传至OBS桶中 xff0c 才能使用媒体处理服务进行转码 媒体处理只能服务同一区域的OBS桶中的音视频文件 xff0c 如
  • 百度静态资源库

    http cdn code baidu com 转载于 https www cnblogs com mingl12 p 6373088 html
  • InstallShield使用———安装设计界面

    InstallShield 使用 安装设计界面 1 安装设计界面 这里介绍的是 Installation Designer页面的界面 xff08 介绍一些重要的属性 xff09 1 1 Installation Information 1
  • iOS开发之ARC MRC混编

    Xcode5之后 xff0c 新建iOS工程 xff0c 默认都是ARC模式 xff0c 但是有时候我们的项目中需要用到一些第三方框架 xff0c 我们下载下来却发现是非ARC的 xff0c 这时候我们需要进行ARC和MRC混编 第一种方式
  • 二分法猜数字

    二分法 arr 61 range 10000000 start 61 0 end 61 len arr 1 res 61 776575 count 61 0 print arr index res while True count 61 c
  • jenkins报错jdk1.8/jre/lib/amd64/libawt_xawt.so

    环境 Ubuntu14 04 x64 jenkins 2 32 1 错误1 AWT is not properly configured on this server Perhaps you need to run your contain
  • [转载]最小矩形(rec1)的解题报告

    百度之星2009大赛的第二场有一道和此相关的题目 xff0c 如果看透这篇文章应该好写了 xff0c 不过可惜我事后才看到 xff0c 郁闷啊 xff01 xff01 还是要多看看书 原文 xff1a http www pmit com c
  • ftp权限设置大全!!!

    1 xff0e 登录和对匿名用户的设置 write enable 61 YES 是否对登录用户开启写权限 属全局性设置 默认NO local enable 61 YES 是否允许本地用户登录FTP服务器 默认为NO anonymous en
  • Vmware-虚拟中的linux如何增加硬盘(转)

    启动虚拟机软件VMware后 xff0c 点机VM菜单选择Setting xff0c 然后在弹出地菜单中选择 xff1a Add命令进行添加硬盘操作 完成后启动虚拟机 1 建立分区 fdisk l查看磁盘分区情况 此时你会发现多了一个 de
  • depot_tools download CPID client for windows 设置代理

    Downloading CIPD client for windows amd64 from https chrome infra packages appspot com Failed to download the file check
  • linux查看glibc命令,centos怎么看glibc版本 Linux查看glibc版本方法

    日前Linux GNU glibc标准库的 gethostbyname函数爆出缓冲区溢出漏洞 xff0c 影响版本为Glibc 2 2到2 17 xff0c 包含2 2和2 17版本 如果您正在使用Linux服务器的话 xff0c 快看看你
  • 2范数和F范数的区别

    2范数和F范数是不同的 2范数表示矩阵或向量的最大奇异值 xff0c max svd X 而 F范数表示矩阵所有元素平方和的开方根 sqrt x i j X x i j 2 转载于 https www cnblogs com yinwei
  • Ubuntu ftp服务器搭建 + UltraEdit编辑FTP文件

    0 前言 xff1a xff08 请无视 xff09 最近在写一个Linux脚本 xff0c 在电脑装了Ubuntu的虚拟机来测试脚本效果 xff1b 可是用vim编辑脚本实在是太蛋疼 xff0c 于是就想到UltraEdit编写 xff0
  • Windows远程桌面多用户登录的问题

    RDP WRAPPER 同时登录 多用户补丁 解决系统更新导致无法多用户登录的问题 问题描述 xff1a 安装最新的Windows系统更新补丁后 xff0c 使用RDP Wrapper多用户补丁的共享主机不支持多用户登录 系统会提示登录远程
  • mac man汉化方法

    https www jianshu com p 615a0a46193a utm campaign 61 maleskine amp utm content 61 note amp utm medium 61 seo notes amp u
  • 常见开发语言擅长领域

    Python xff1a 机器学习 xff0c 数据科学还有Web开发 JavaScript xff1a Web开发 xff08 前端和后端 xff09 和游戏开发 Java xff1a 移动Android应用程序开发 xff0c 企业应用
  • 【Arch安装】

    Arch安装 不完整 xff0c 凭记忆补充 1 xff0c 制作安装介质 xff08 请跳转链接 xff1a https www archlinux org download xff09 2 xff0c 从UEFI模式启动后 xff0c

随机推荐

  • 关于 systemctl --user status 报错的问题

    关于 systemctl user enable mpd 报错 xff1a Failed to connect to bus No such file or directory 因为arch脚本中 xff0c systemctl 是 sud
  • RNA-Seq比对软件HISAT2的用法

    参考网址 xff1a http blog sciencenet cn blog 759995 990471 html 感谢原作者 转载于 https www cnblogs com lmt921108 p 7442839 html
  • curl: (1) Protocol 'http not supported or disabled in libcurl

    在windows中使用curl的时候 xff0c 命令为 curl 39 http localhost 9200 pretty 39 出现这个报错 curl 1 Protocol 39 http not supported or disab
  • Linux日志服务器配置

    配置日志服务器 环境 xff1a tibet xff1a 10 11 3 57 gaplinux xff08 日志服务器 xff09 xff1a 10 11 3 3 修改tibet上的 etc hosts xff0c 增加如下代码 xff1
  • Ubuntu16.04下配置ssh免密登录

    Ubuntu16 04下配置ssh免密登录 环境准备 xff1a 新建两台虚拟机 xff0c 而且两台虚拟机上都装有Ubuntu16 04的系统 xff0c 使两台虚拟机之间保持互通状态 分别为两台虚拟机命名为A B 假设我们要使A虚拟机免
  • linux slf4j找不到,SLF4J错误消息

    在本章中 xff0c 我们将讨论在使用SLF4J时获得的各种错误消息或警告以及这些消息的原因 含义 无法加载类 org slf4j impl StaticLoggerBinder 这是在类路径中没有提供SLF4J绑定时引起的警告 以下是完整
  • C#使用RabbitMQ

    1 说明 在企业应用系统领域 xff0c 会面对不同系统之间的通信 集成与整合 xff0c 尤其当面临异构系统时 xff0c 这种分布式的调用与通信变得越发重要 其次 xff0c 系统中一般会有很多对实时性要求不高的但是执行起来比较较耗时的
  • 安装rpm的mysql_linux下安装rpm格式的mysql

    1 下载安装包 官网下载 rpm格式安装包 xff0c 需要下面两个文件 xff1a MySQL server 5 0 26 0 i386 rpm MySQL client 5 0 26 0 i386 rpm 注 xff1a 官网下载时 x
  • 我的世界服务器怎么修改合成表,《我的世界》1.8原版自定义合成表教程 怎么自定义合成表...

    我的世界 1 8原版自定义合成方法 xff0c 很多玩家还不了解 xff0c 今天给大家带来玩家 真名 分享的 我的世界 1 8原版自定义合成表教程 xff0c 一起来看看吧 版本要求1 8 优点 xff1a 自定义 合成表数量可以很大 合
  • 题解 化学反应

    化学反应 Description 有 N 种不同的物质 xff0c 每种物质有两个属性 能量 和 活度 N 种中的任意两种物质都可以发生反应 xff1b 反应放热为两种物质的 能量 之差加一再乘上 活度 的较大值 换句话说 xff0c 设第
  • JAVA字符串中的转义字符

    一 在java字符串中如果出现斜杠 xff0c 1 当成转义字符 34 34 时 xff0c 后面必须接八进制数字进行ASCII转义输出成其它字符 xff0c 2 当成字符串字面值斜杠直接输出时 xff0c 必须用双斜杠 34 34 转义为
  • # ES6基础

    ES6基础 let和const 在以前的js中有一个问题 xff0c 就是只存在函数作用域而不存在局部作用域 let xff0c const的出现改变了这个问题 const就是定义常量 this指向 说默认this指向调用它的对象倒不如说函
  • SpringBoot实现定时器定时处理任务

    最近在项目中遇到了一个问题 对于新建的活动 活动设置了开始时间和结束时间 也就是数据库中的一个状态码的改变而已 但是 这里就有问题了 如何去实现到时间更改活动状态呢 1 刚开始的时候 我想了下定时任务 但是怎么也想不出配置的时间问题 对于活
  • 在雪豹10.6.2(Mac OS X)上安装Oracle10g

    1 Install preparation 基本环境 xff1a Snow Leopard10 6 2 xff0c Oracle10 2 0 4 打开Mac的终端 xff0c 执行 xff1a sudo i 创建oinstall组和orac
  • abaqus2016安装过程中出现error:unable to add abaqus command directory to PATH variable

    请问abaqus2016安装过程中出现error unable to add abaqus command directory to PATH variable是什么原因 xff0c 怎么解决啊 xff0c 总是安装失败 这个问题我解决了
  • MySQL中的 DATE_FORMAT 与 SQL 中的 DATEPART()函数使用介绍

    本小白最近学习MySQL xff0c 因为之前是已经有学过微软大佬的SQL Server所以自认为理解的还是稍快的 滑鸡 xff0c 好了说正事 今天在写一个查询语句时 xff0c 需要用到 一个日期函数 xff1a DATEPART 因为
  • ps常见颜色以及其色值

    1 白色 FFFFFF 2 红色 FF0000 3 绿色 00FF00 4 蓝色 0000FF 5 牡丹红 FF00FF 6 青色 00FFFF 7 黄色 FFFF00 8 黑色 000000 9 海蓝 70DB93 10 巧克力色 5C3
  • Python 文件操作Error: binary mode doesn't take an encoding argument

    Python 报错 xff1a ValueError binary mode doesn 39 t take an encoding argument 在运行文件操作相关功能时报错 xff1a ValueError binary mode
  • Mac OS X 完全卸载MySQL

    执行下列命令 sudo rm usr local mysqlsudo rm rf usr local mysql sudo rm rf Library StartupItems MySQLCOMsudo rm rf Library Pref
  • 揭秘微信红包:架构、抢红包算法、高并发和降级方案

    编者按 与传统意义上的红包相比 xff0c 近两年火起来的 红包 xff0c 似乎才是如今春节的一大重头戏 历经上千年时代传承与变迁 xff0c 春节发红包早已成为历史沉淀的文化习俗 xff0c 融入了民族的血脉 按照各家公布的数据 xff