百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术资源 > 正文

实战 | 基于“Nginx+Lua”组件的应用系统灰度发布

off999 2025-02-16 22:27 25 浏览 0 评论

文 / 中国人寿保险股份有限公司研发中心? 熊军军 彭晓刚 郑晓勇 宣军法

近年来,随着公司业务快速发展和客户要求的不断提高,中国人寿IT系统建设逐渐呈现出两个特点。一是系统版本数量增长快,由于部分版本质量不高可能影响系统可用性,研发运维人员需要在版本上线后投入大量精力保障系统稳定。二是业务创新质量要求高,系统需要将某类新特性投放给特定用户,在预定验证周期内及早获得用户反馈,快速验证产品设计理念,促进产品快速迭代优化。为做稳做优应用系统产品,支持业务快速创新,研发中心统一制订了基于“Nginx+Lua”组件的技术方案,对关键系统进行架构改造,使其具备灰度发布能力。

工作目标

制订统一灰度发布技术方案,通过技术改造,使20余个关键系统具备灰度发布条件,进而实现以下目标。

1.提高系统可用性。按部署策略,控制某类新特性的投放范围,避免该新特性的缺陷影响所有用户,避免发生全局性系统故障。

2.提升应用产品迭代能力。将某类新特性投放给特定用户,在预定验证周期内及早获得用户反馈,快速验证产品设计理念,促进产品快速迭代完善。

技术方案

1.灰度发布的含义。灰度发布是一种将特定产品功能投放给特定用户的系统版本发布方式,有利于保障系统稳定,提高产品迭代效率。应用系统灰度发布基本原理如图1所示,其中,正式环境上部署了应用系统当前版本1,灰度环境部署应用系统新版本2,服务路由控制集群上配置访问这两个环境的策略。当用户请求到达服务路由控制集群时,控制节点会根据服务访问策略,将用户请求转发至正式或灰度环境,访问灰度环境的用户将体验系统新功能。

2.灰度发布的主要实现方式。根据需要灰度发布的内容,我们将灰度发布分为服务端灰度和客户端灰度。服务端灰度是指应用系统的服务端程序的灰度发布;客户端灰度是指应用系统的客户端程序及静态资源的灰度发布,如APP升级包、JS文件、图片等静态资源的发布。

根据灰度发布的技术实现方式,我们进一步将灰度发布实现方式分为:“通用路由组件实现灰度”“开发框架路由组件实现灰度”“其他实现灰度方式”及“客户端升级服务组件实现灰度”。具体如图2所示。

(1)“通用路由组件实现灰度”。借助Nginx、HAproxy等通用路由组件,将部分用户请求分发到灰度环境。

本文采用的Nginx,是一种轻量级的开源软件,可用来搭建反向代理服务器、Web服务器和邮件代理服务器,具有并发性能好、资源效率低的优点,其架构特点是“事件驱动、异步化和非阻塞”。即:通过事件驱动方式动态地申请或释放资源,提高CPU、内存等资源利用率,并通过高效的多路复用IO技术,显著提高程序在大量并发连接中的CPU利用率,使得多个线程可以并发执行而不被阻塞。

为扩展Nginx能力,通常会引入Lua脚本语言。Lua是一种轻量级的脚本语言,其设计目的是通过灵活地嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能,具有“功能强大、代码简洁、易于集成、运行速度快、易于扩展”等特点。一个完整的Lua解释器不超过200KB,其中LuaJIT具备即时编译能力,通过安装LuaJIT、Lua-nginx-module、nginx_devel_kit,就可以在Nginx的11个处理阶段使用Lua指令。基于Nginx+Lua的两个开源软件OpenResty和ABTestingGateway,都可以用来快速搭建灰度环境。

(2)“开发框架路由组件实现灰度”。Dubbo、Spring Cloud等开发框架均提供了支持灰度发布的路由组件。

Dubbo的灰度路由机制:服务注册服务器将服务提供者信息推送给服务消费方,服务消费方在调用服务时,先由Router根据一定的路由规则,从本地服务器列表中选择一组合适的服务提供者,然后由LoadBalance根据自定义的负载均衡策略从中选择一个服务提供者。这个自定义的策略可以通过实现LoadBalance接口或者继承AbstractLoadBalance类来重写,以实现复杂的灰度控制逻辑。

SpringCloud的灰度路由机制:用户请求统一通过API网关Zuul来访问内部服务,网关接收到请求后,从注册中心获取可用服务列表,然后通过Ribbon中的路由策略选择正式或灰度服务,将请求发送给后端服务。自定义路由策略需要集成AbstractLoadBalanceRule或其子类。

(3)“其他实现灰度方式”。在通过专用路由组件实现灰度之前,有一些较为传统的做法也实现了灰度的效果。例如:通过程序中的硬代码分支来控制被调用的服务;通过将程序分省部属、分批上线来实现灰度发布等等。

(4)“客户端升级服务组件实现灰度”。客户端的APP升级包、JS文件,以及图片等静态资源的发布,一般通过专用的升级服务来实现,升级服务器访问灰度发布配置库获取灰度发布策略。当用户在APP登录时,首先访问升级服务器,判断是否为灰度用户,若是则从内容分发服务器下载升级包或静态资源,实现客户端灰度发布。

项目实践

在对关键系统的改造过程中,我们首先进行技术选型论证,然后组织技术验证,之后分批推进项目实施,取得一定成效。

1.技术选型。为适应不同技术框架应用系统的灰度发布需求,我们采用“通用路由组件实现灰度”的方案。

具体实现上,路由组件采用基于“Nginx+lua”组件的OpenResty工具。同时,引入Keepalived组件,保障OpenResty高可用,具体原理如图3所示。

Keepalived采用虚拟路由冗余协议,将N台相同功能的路由器组成一个路由器组。这个组里面有一个Master和多个Backup,Master上面有一个对外提供服务的VIP。Master会发组播VRRP包,用于告诉Backup自己正常工作。当Backup收不到VRRP包时就认为Master不可用,这时就需要根据VRRP的优先级来选举一个Backup当Master。以此保障路由器的高可用,保证业务的连续性,接管速度最快可以小于1秒。

2.技术验证。为确保上述方案可行,项目组采用“Keepalived+OpenResty”方案开展验证测试,主要评集群的并发性能、高可用性及对后端服务的影响。

(1)并发性能。挡板测试表明,针对单支交易,在并发用户数从50增加到1500的场景下,OpenResty集群处理能力保持在9800笔/秒以上,CPU使用率维持在17.17%左右,内存使用率维持在23.48%左右,并发性能良好,系统资源占用率较低。

(2)高可用性。以200用户并发执行两支交易(配比为100:100),待场景稳定运行几分钟之后,手动关闭一个Openresty服务器节点,观察所有用户请求能否被快速分发到剩余运行的一台Openresty服务器节点。通过查看Keepalived日志,手动关闭一个节点后,用户请求快速切换到另一节点,场景继续稳定运行。

(3)转发对后端服务的影响。选取4支典型交易,按50用户并发,分别直连或通过OpenResty访问后端服务。通过比较2组数据,可以看到OpenResty转发对后端服务的吞吐量和响应时间影响比较小,增加Open Resty转发后,后端服务性能下降在2%以内。

3.系统改造。按照上述方案,我们对20余个关键系统进行了架构改造,增加灰度路由层,灰度控制对象,主要选择用户请求的Httpheader中的“IP、角色、机构、系统来源”。

灰度发布实施的过程中,需关注以下问题。

(1)灰度控制对象从Httpheader获取,一般不解析HttpBody中的数据,因为性能消耗较大。如果Header中暂时没有需要用来控制路由的数据元素,则上下游对对服务报文头进行联动调整即可。

(2)灰度对象当前仅限客户端资源或服务端应用,不包括服务端数据库。数据库的灰度,因涉及正式与灰度数据的合并等问题,暂无较好的整体性解决方案。但针对个别字段的调整,可以通过新增字段,并使新程序逻辑同时写新、老字段的方式,使数据库能同时兼容新老应用程序,且保证数据完整性。

(3)每个应用系统独立实现各自的灰度路由控制层,并未建立一个集中的、供各系统共用的灰度路由控制服务器。因为类似集中的路由控制,可能会跟ESB等设施一样,成为性能瓶颈。

(4)Keepalived能很好地保障OpenResty集群的高可用,在业界应用也比较广泛。但部分研发人员仍担心,主备模式仅能保证某个时点只有Master一个节点在转发服务,所有服务压力靠一个节点承载,不利于扩展。事实上,一个长的服务链路中,最前端的路由设备始终无法避免单点的问题,因为其前面没有路由设备为其分流。这时,我们可以考虑另外的服务分流方式,例如:再建立一套Keepalived主从机制,从而对外虚拟出两个VIP,使两个OpenResty集群互为主备,不同的应用访问不同的VIP即可。这个路由可以通过DNS、ESB注册订阅等机制实现,实际上体现了一种多层路由分担任务的思路。

系统的灰度能力,可以应用到不同的场景,例如:服务接口扩展,Webservice服务改为ResTFUL,ResTFUL服务从虚拟机迁移到容器等等。

4.工作成效。根据各系统特点,灵活使用基于“Nginx+Lua”的灰度发布技术组件,建立统一的架构层——服务路由层,推动“可灰度”理念成为一种架构设计共识,取得了以下成效。

(1)公司20余个关键系统全部具备灰度发布条件,其中6个系统在生产环境发布灰度版本,3个系统实现常态化灰度发布。

(2)大幅提高系统稳定性,降低新版本上线影响,防范生产事件,部分系统可白天升级,减少夜间加班升级、凌晨紧急解决问题的情况。

(3)有效提高系统迭代效率,有利于快速适应一线需求,快速发布新功能,快速试错,快速获得一线反馈。

(4)通过“Keepalived+Nginx”实现Nginx集群的高可用,探索硬负载均衡向软负载均衡切换的路径,有利于降低硬件采购成本。

总结展望

通过上述实践,我们已经积累了一定经验,包括Openresty组件使用,nginx参数配置,灰度对象选择,灰度版本发布流程等方面。为进一步完善灰度发布技术,支持更多场景实现“可灰度”的目标,可以从以下几个方面考虑后续工作。

1.全链路灰度发布。当前随着分工的细化,服务的调用链逐渐加长,一个功能改造可能涉及多个服务。如何实现用户请求发出后,全链路一致灰度,需要结合服务治理统筹考虑。

2.多种灰度方式融合。在实现完备的全链路灰度方案前,要结合各系统现状,灵活选择适用的技术方案,相互融合起来达到灰度发布的效果。实时交易类服务可用Nginx等通用路由组件实现灰度;异步消息驱动的服务,可通过建立相对隔离的灰度环境来保障灰度数据仅在灰度环境流转。此外,也需注意到新技术对灰度发布带来的影响,例如ServiceMesh框架中使用Istio实现灰度发布。

3.数据库灰度。其难点是正式环境和灰度环境数据的整合,以及异常灰度数据的回滚。需要巧妙的数据库设计或者灵活的数据迁移,可以从数据库SQL解析引擎、库表设计、分区设计等角度深入分析。

相关推荐

Python进阶教程:如何自定义异常(附电商库存管理案例)

在Python中,你可以使用异常(exceptions)来预期和处理那些干扰程序正常执行流程的错误。Python内置了许多常见的异常,例如ValueError、TypeError和KeyError,但...

Python 中使用try来处理异常的方法

六二,直方大,不习无不利。在学习python中会经常遇到各种异常事件;现归纳一下如何捕捉并处理这些异常;今天来给大家整理一下。一、异常的概念什么是异常?异常即是一个事件,该事件会在程序执行过程中发生,...

python入门-day3:异常处理(异常处理方法及流程python)

异常处理的内容,包括try、except、finally的用法,介绍常见异常类型,最后通过一个练习(处理用户输入的非法数字)帮你把知识点串起来。我会用简单易懂的语言,确保新手也能轻松掌握。Da...

16-Python的异常(python的异常类型及处理)

1-异常介绍1-2-什么是异常异常是程序运行时发生的错误或异常情况,它会中断正常的程序执行流程;Python使用异常处理机制来处理这些运行时错误。1-4-为什么要捕获异常异常会中断程序的执行;1-3-...

Python 异常处理详解(python中异常)

一、什么是异常?核心定义在程序运行过程中,当Python解释器检测到无法继续执行的操作时,会立即创建异常对象并中断当前流程。此时若不处理异常,程序将直接崩溃退出。典型场景与原理用户输入无效数据nu...

掌握这些 Python 异常处理技巧,代码稳如老狗!

在Python中,异常处理不仅可以帮助我们捕获和处理错误,还能让我们更清晰地了解错误发生的背景。1.异常层次结构Python内置了许多异常,我们在编程时可能会经常遇到,例如ZeroDivisi...

python异常处理机制最佳实践(python异常处理总结)

Python异常处理的最佳实践需要兼顾代码健壮性、可读性和性能。以下是经过工程验证的10个核心原则和技巧:一、精准捕获原则避免裸except禁止使用except:或exceptExce...

python之异常处理(python异常处理过程可以概括为三个步骤)

异常语法try:<代码块>except<异常类型>:<代码块>捕获通用异常try:<代码块>exceptExceptionas...

一天学一点,今天学习掌握Python:异常处理与文件操作全攻略

这一笔记记录了我学习python的异常和文件的操作,这也是针对Python异常和文件操作教程的进一步优化建议和注意事项:异常处理优化1.避免过度捕获异常o不要为了捕获异常而捕获异常,应根据实际需求...

新手学Python避坑,学习效率狂飙! 十二、Python 异常处理

异常处理系统分享在Python里,异常指的是程序运行期间出现的错误。当异常发生时,正常的程序流程会被中断,Python会抛出异常对象。为了防止程序因异常而崩溃,你可以使用异常处理机制捕获并处理这...

Python异常处理全攻略:从入门到精通,轻松应对代码“翻车”时刻

喜欢的条友记得关注、点赞、转发、收藏,你们的支持就是我最大的动力源泉。引言:异常处理——代码世界的“保险丝”在编程的世界里,错误和异常就像路上的“坑”,稍不留神就会让你的程序“翻车”。而异常处理,就是...

Python异常处理全面指南(python异常处理步骤)

Python异常处理完全指南异常处理是编写健壮程序的关键技术。Python提供了灵活的语法和丰富的内置异常类型,能够有效管理程序运行时的错误。以下是Python异常处理的全面指南:一、异常处理...

进阶突破python——异常处理机制(异常处理用什么语句python)

Python的异常处理机制是其健壮性设计的核心,通过清晰的语法结构和灵活的处理策略实现错误管理。以下从核心语法、异常对象、高级特性和最佳实践四个维度详解:一、核心语法结构Python使用try-...

Python基础编程——详细介绍Python的异常捕获示例代码

这篇文章主要为大家详细介绍了python的异常捕获,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助①捕捉一个异常捕捉一个异常以用0作为除数会得到Ze...

Python学习 -- 异常捕获技巧(python怎么捕获异常)

在编写Python代码时,异常处理是确保程序稳定性的关键。Python提供了灵活的异常捕获机制,包括try...except语句、try...except...else语句和try...except....

取消回复欢迎 发表评论: