2019独角兽企业重金招聘Python工程师标准>>>
大家平时会关注很多微信公众号,公众号会借助于红包奖励、卡券分享、消息通知、微信分享等手段,通过好的内容,好的活动、好的产品以及相应的精准营销来增强用户的粘性和活跃度。
在微信公众号推送消息的期间,10分钟后流量会逐步上升,30分钟左右到达峰值,1个小时后会显著下降。在这个时间段内,系统的压力会很大。这个时候,系统的很多场景使用异步进行实现,一方面能缩短主流程的时间处理,另一方面能够通过异步队列进行一定程度的削峰。今天重点介绍单个JVM内的异步优化实践,不涉及分布式时的异步优化实践。在异步执行时,可以调用远程的服务集群来实现一定的任务分解。
部署示意图
整个系统都部署在公有云上,虚拟机上有部署1个Nginx,4个Tomcat,Nginx使用随机的方式负载均衡到Tomcat上面。虚机之间通过LB将客户请求转发到Nginx上面负载均衡,Nginx再将请求分配到tomcat应用服务器上。
由多台应用服务器,对外服务提供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种典型的异步队列模型(图片来源于网络):
一个生产者生产数据,一个消费者消费数据,一般用在后台处理的业务逻辑中。
1.一个生产者生产数据,多个消费者消费数据(这里面有两种情况:同一个消息,可以被多个消费者分别消费。或者多个消费者组成一个组,一个消费者消费一个数据)。
2.多个生产者生产数据,单个消费者消费数据,可以用在限流或者排队等候单一资源处理的场景中。
3.多个生产者分别生产数据,多个消费者消费数据(这里面有两种情况:同一个消息,可以被多个消费者分别消费。或者多个消费者组成一个组,一个消费者消费一个数据)。
总分总任务模型:特别适第一个线程取出一批数据放到队列中(比如select);由多个线程分别执行业务逻辑;执行后的结果由一个线程来执行(比如update操作,这样能够防止数据库锁)
使用异步后的烦恼
烦恼一:怎样队列长设置和消费者数量
解决方式:使用实际的压力测试来获得队列长度。或者使用排队论的数学公式得到初步的值,然后进行实际压测。
烦恼二: 数据丢失的风险
解决方式:先写日志或数据库,后放入异步队列.
烦恼三:数据保存后异步任务未执行
解决方式:使用异步任务补偿的方式,定期从数据库中获取数据,放到队列中进行执行,执行后更新数据状态位。
烦恼四:对其他系统的压力变大
解决方式:使用一定的限流和熔断,对其他系统进行保护。
想学习交流Java知识的可以加入交流学习群号: 744642380, 里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构等这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良
除了微信公众号还有微信群消息的高速发展
上图是群消息投递业务的简化流程示意。随着微信群消息体量的高速膨胀,其带来的成本压力越来越大,业务同学提出了批量并行化的优化方式。简单来说,就是将每个步骤中产生的 RPC 访问按实际访问机器聚合成一系列的批量操作,然后并行化执行。
类 MapReduce 任务处理框架
其实,深入分析群消息投递的优化需求,可以看到:
-
一次批量并行化操作本质上是一次 MapReduce 过程;
-
整个群消息投递的处理过程是多次 MapReduce 过程的串联和并联;
所以,为了从根本上解决这一类问题,MQ 为业务提供了类 MapReduce 任务处理框架。
该框架提供封装了通用的 MR 过程,以及并发的调度过程,同时提供并发池隔离能力,解决了并发池饿死的问题。让业务同学可以从冗繁的代码中解放出来,将更多的精力投入到实际业务中。
流式任务处理框架
除了批量并行化的需求,业务经常提到的一个需求是,任务处理时会产生一些新的任务需要加到队列中。一般来说是走一次 RPC 来执行任务入队。在 MQ 2.0 下,流式任务可以帮忙完成这个事情。
所谓流式任务,就是在任务处理结束时,除了返回任务结果,还可以返回一系列新的任务。这些任务通过 MQ 内部框架流转入队,更轻量,事务性更强。
相比常规的同步处理模型,它提供了一种轻量的逻辑异步化模型。一个冗长的逻辑可以切分为很多小的功能块进行串联和复用,每一级之间都有 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性能优化、分布式架构等这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良