资深架构师是如何处理微信公众号的系统压力

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

大家平时会关注很多微信公众号,公众号会借助于红包奖励、卡券分享、消息通知、微信分享等手段,通过好的内容,好的活动、好的产品以及相应的精准营销来增强用户的粘性和活跃度。

在微信公众号推送消息的期间,10分钟后流量会逐步上升,30分钟左右到达峰值,1个小时后会显著下降。在这个时间段内,系统的压力会很大。这个时候,系统的很多场景使用异步进行实现,一方面能缩短主流程的时间处理,另一方面能够通过异步队列进行一定程度的削峰。今天重点介绍单个JVM内的异步优化实践,不涉及分布式时的异步优化实践。在异步执行时,可以调用远程的服务集群来实现一定的任务分解。

部署示意图

整个系统都部署在公有云上,虚拟机上有部署1个Nginx,4个Tomcat,Nginx使用随机的方式负载均衡到Tomcat上面。虚机之间通过LB将客户请求转发到Nginx上面负载均衡,Nginx再将请求分配到tomcat应用服务器上。

资深架构师是如何处理微信公众号的系统压力_第1张图片

由多台应用服务器,对外服务提供Rest服务,在每个Tomcat内部使用异步队列。同时由一台控制服务器,进行异步任务的补偿任务和管理功能。Tomcat和Redis使用多级缓存来降低对Redis的压力,并减少依赖。

为什么要在虚机上部署Nginx将请求转发到Tomcat,而不是由LB直接转发到Tomcat。这是因为LB能够支持的IP个数是有限的。

典型的用户场景

在公众号的运营过程中,典型的事件包括:

1.发送短信验证码

2.购买成功或者抽奖成功短信通知

3.订单流程处理

4.卡券或优惠券发放

5.微信消息通知

6.发放微信红包

7.微信消息通知

8.定时批处理(比如数据同步)

9.工作流性质的异步任务(未完成异步任务补偿)

.......

详细说明 的原因:

1.不同场景(用户注册,用户购买产品等)下的短信验证码发送,可以使用异步方式发送: 一方面是因为客户这个时效性要求没有那样高,另一方面在特定时间范围内用户没有收到验证码,用户可以点击再次发送验证码。

2.购买成功或者抽奖成功后短信或者邮件通知,可以通过异步的方式进行。 因为涉及用户的利益,要谨慎对待。一方面一定要把数据先存到数据库或者日志里面(注意信息安全^-^,别存敏感明文信息或者加密存储),然后再放入到异步队列中执行。

3.微信红包,因为需要跟微信进行交互,并且微信会通知客户红包的情况,可以使用异步的方式进行。 当涉及资金或者礼品时,一定要谨慎对待设计,并且需要有方便进行异步任务停止和启动的功能。

4.另一个方面,要考虑到应用服务意外停止时,没有发送成功数据的补偿机制。 这种情况不常见,并且为了减少耦合和当前异步程序的复杂度。我们使用单独的服务上部署异步任务补偿程序,来扫描未完成的任务,并且进行重放(一定要注意严谨性)。

5.订单流程处理,可以使用异步,因为涉及到后续步骤可以使用简单工作流来完成。有几个开源的框架可以参考。

6.优惠券和卡券的发放,跟购买成功或抽奖成功的方式类似。\u000b可以在当前活动高峰后延时发放,并且使用异步的方式进行。

7.微信消息通知,因为跟微信进行交互,成功后微信进行通知,可以使用异步。 这个跟短信验证码类似。

数据同步或者异步任务补偿,因为是延时处理,可以使用异步进行处理。在使用时,可以配合定时任务,比如cron4j来周期性的进行补偿。适合后面总-分-总的任务处理模式。

无处不在的异步

下图包含了4种典型的异步队列模型(图片来源于网络):

资深架构师是如何处理微信公众号的系统压力_第2张图片

一个生产者生产数据,一个消费者消费数据,一般用在后台处理的业务逻辑中。

1.一个生产者生产数据,多个消费者消费数据(这里面有两种情况:同一个消息,可以被多个消费者分别消费。或者多个消费者组成一个组,一个消费者消费一个数据)。

2.多个生产者生产数据,单个消费者消费数据,可以用在限流或者排队等候单一资源处理的场景中。

3.多个生产者分别生产数据,多个消费者消费数据(这里面有两种情况:同一个消息,可以被多个消费者分别消费。或者多个消费者组成一个组,一个消费者消费一个数据)。

资深架构师是如何处理微信公众号的系统压力_第3张图片

总分总任务模型:特别适第一个线程取出一批数据放到队列中(比如select);由多个线程分别执行业务逻辑;执行后的结果由一个线程来执行(比如update操作,这样能够防止数据库锁)

使用异步后的烦恼

烦恼一:怎样队列长设置和消费者数量

解决方式:使用实际的压力测试来获得队列长度。或者使用排队论的数学公式得到初步的值,然后进行实际压测。

烦恼二: 数据丢失的风险

解决方式:先写日志或数据库,后放入异步队列.

烦恼三:数据保存后异步任务未执行

解决方式:使用异步任务补偿的方式,定期从数据库中获取数据,放到队列中进行执行,执行后更新数据状态位。

烦恼四:对其他系统的压力变大

解决方式:使用一定的限流和熔断,对其他系统进行保护。

想学习交流Java知识的可以加入交流学习群号: 744642380, 里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构等这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良

除了微信公众号还有微信群消息的高速发展

15246401709519c59dcedaa

上图是群消息投递业务的简化流程示意。随着微信群消息体量的高速膨胀,其带来的成本压力越来越大,业务同学提出了批量并行化的优化方式。简单来说,就是将每个步骤中产生的 RPC 访问按实际访问机器聚合成一系列的批量操作,然后并行化执行。

类 MapReduce 任务处理框架

其实,深入分析群消息投递的优化需求,可以看到:

  • 一次批量并行化操作本质上是一次 MapReduce 过程;

  • 整个群消息投递的处理过程是多次 MapReduce 过程的串联和并联;

所以,为了从根本上解决这一类问题,MQ 为业务提供了类 MapReduce 任务处理框架。

资深架构师是如何处理微信公众号的系统压力_第4张图片

该框架提供封装了通用的 MR 过程,以及并发的调度过程,同时提供并发池隔离能力,解决了并发池饿死的问题。让业务同学可以从冗繁的代码中解放出来,将更多的精力投入到实际业务中。

流式任务处理框架

除了批量并行化的需求,业务经常提到的一个需求是,任务处理时会产生一些新的任务需要加到队列中。一般来说是走一次 RPC 来执行任务入队。在 MQ 2.0 下,流式任务可以帮忙完成这个事情。

所谓流式任务,就是在任务处理结束时,除了返回任务结果,还可以返回一系列新的任务。这些任务通过 MQ 内部框架流转入队,更轻量,事务性更强。

资深架构师是如何处理微信公众号的系统压力_第5张图片

相比常规的同步处理模型,它提供了一种轻量的逻辑异步化模型。一个冗长的逻辑可以切分为很多小的功能块进行串联和复用,每一级之间都有 MQ 去充当缓冲和调度。

虽然这种处理模式并不适用于所有逻辑,但作为组件功能的一部分,它提供了一种新的解决问题的能力。

最后分享一下项目中的经验:

l 具备丰富的一线大中型开发项目的整体规划、方案设计及技术队伍管理经验。

l 具备软件行业工作经验,熟悉业务领域的技术应用和发展。

l 具有项目管理理论基础,并在应用系统开发平台和项目管理上有实践经验。

l 对相关的技术标准有深刻的认识,对软件工程标准规范有良好的把握。 具备C/S或B/S体系结构或特定领域软件产品开发及架构和设计的经验。

l 具有面向对象分析(Object-Oriented Analysis, OOA)、设计(OOD)、开发(OOP)能力,精通UML和XML等,熟练使用Rational Rose、PowerDesigner等CASE工具进行设计开发。

l 对相关编程技术及整个解决方案有深刻的理解及熟练的应用,并且精通架构和设计模式,并在此基础上设计产品框架。

l 精通大型数据库如Oracle、Sql Server、MySQL等的开发。l 对计算机系统、网络和安全、应用系统架构等有全面的认识。

l 良好的团队意识和写作精神,有较强的内外沟通能力

想学习交流Java知识的可以加入交流学习群号: 744642380, 里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构等这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良

转载于:https://my.oschina.net/u/3833719/blog/1800992

你可能感兴趣的:(资深架构师是如何处理微信公众号的系统压力)