1概述
在当今快节奏的软件开发环境中,随着用户需求的不断变化和竞争日益激烈,软件更新和发布的频率已成为常态。然而,与此同时,保证用户体验的稳定性和可靠性也是至关重要的。传统的大规模软件发布往往会面临着线上故障风险,可能导致用户体验下降,甚至影响业务正常运行。
为了解决这一矛盾,在软件开发领域催生出了灰度发布的概念。灰度发布是一种渐进式的软件发布方式,它允许将新功能或更新逐步推送给一部分用户,而不是一次性全部发布。这样的方式能够有效降低线上故障的风险,保障用户体验,同时也为开发团队提供了更多时间和机会在全面发布前进行验证和修复。
然而,随着软件架构的演进,尤其是微服务架构的普及,软件系统往往由多个微服务组成,不同服务的版本升级需要协调和同步。在这种背景下,单一服务的灰度发布已经不能完全适应需求,全链路灰度发布应运而生。
全链路灰度发布考虑到整个软件系统的多个微服务,允许多个微服务同时进行版本控制和升级,以确保整个系统的平稳过渡和稳定性,是一种更为全面和细致的灰度发布方式。通过全链路灰度发布,开发团队能够更加精确地控制不同服务版本的发布比例,降低系统风险,保障线上稳定性,最大程度地满足用户需求。
以图 1 为例,软件系统包含网关和 4 个微服务,通过全链路灰度发布,可以使ServiceB和 ServiceD 进行灰度发布,通过灰线所示的流量进行灰度功能验证,同时不影响蓝线所示的正常访问流量。
2全链路灰度发布核心问题
我们通过图1 可以清晰地看到,在实施全链路灰度发布时,需要部署相关服务的灰度版本,并确保在整个请求的调用链上,网关和微服务组件能够准确识别正式流量和特定版本灰度流量,并根据流量类型动态地将请求路由到正确版本的上游微服务上。所以,我们需要解决以下几个问题:
微服务标识
我们通过给微服务实例添加标识的方式,使微服务实例具有版本信息,针对不同流量对应版本实例提供服务。
传统模式
在传统模式下,一般需要产品根据使用的微服务框架决定添加标识的方式。我们以基于 Spring Cloud 框架 + Nacos注册中心 的微服务为例,一般通过在微服务元数据配置(spring.cloud.nacos.discovery.metadata)中添加标识,配置示例如下:
spring:cloud:nacos:discovery:metadata:version: ${APP-VERSION:v1}
微服务在 Nacos 注册中心中服务信息如下:
云原生模式
在云原生模式下,为微服务实例添加标识更加方便,不需要修改微服务代码配置,一般在微服务 Deployment 的 Pod 模版中添加Labal标识即可,实例如下:
apiVersion: apps/v1kind: Deploymentmetadata:name: demospec:selector:matchLabels:app: demoversion: v1template:metadata:labels:app: demoversion: v1
流量标识
和微服务标识相同,我们也是通过为流量添加不同标识的方式区分流量,流量标识在业界还有一个更专业更形象的叫法叫流量染色。
流量染色分两步:第一步在流量源头染色,第二步在调用链内染色。
第一步比较简单,通过前端或者网关根据流量特点(比如浏览器类型,用户标识,地域标识等)为流量添加标识(比如在HTTP Header中添加version标签)。
第二步是全链路灰度中最核心也是最复杂的部分,需要流量标识在调用链中透传下去,保证调用链上的每个微服务组件都能根据标识识别流量并动态路由。
传统的微服务框架注重基础功能的实现,例如服务注册与发现、负载均衡等,而未将流量标识透传作为核心特性之一,导致在实际应用中难以实现流量标识的无缝传递。
云原生时代的 Kubernetes + Istio 同样无法帮助微服务实现流量标识透传。不少人存在误解,认为 Istio 能对微服务实例的出入流量进行拦截,应该原生支持流量标识透传,但实际上 Istio 本身没有流量标识透传的能力。
Istio Sidecar对微服务入口和出口流量拦截如上图所示,Sidecar 虽然能将入口流量1 拦截后转给微服务容器(入口流量2),也能将微服务容器出口流量 3 拦截并转发到 Pod 外(出口流量4),但 Sidecar 不知道出口流量 3 和入口流量 2 的对应关系,在实际情况中,Sidecar 会拦截很多的出口流量,也会拦截很多的入口流量,但 Sidecar 并不知道某一个出口流量对应哪个入口流量。只有微服务应用知道对应关系,因为微服务应用亲自做了流量处理(微服务应用收到入口流量请求2后,进行业务逻辑处理,然后再发出出口流量3,请求下一级微服务),所以 Istio 虽然能对微服务出入流量拦截,但不知道出入流量的对应关系,无法将入口流量的标识自动添加到出口流量上,无法做流量标识透传。
流量标识透传方式
那么如何进行流量标识透传呢,通常有以下3种方式:
微服务修改源码方式
微服务侧进行业务代码改造,从入口流量请求中获取流量标识,并在出口流量中添加流量标识,代码示例如下:
// 从请求中获取流量标识 versionString versionValue = Request.getHeader("version");// 构造新请求需要的 Header,获取到的流量标识添加到新请求的 Header 中HttpHeaders headers = new HttpHeaders();headers.set("version", versionValue);// 发起出口流量请求
使用基础SDK方式
将从入口流量请求中获取流量标识,并在出口流量中添加流量标识这种共性逻辑封装到基础 SDK 中,其原理通常涉及 SDK 对请求和响应的拦截处理。这种方法的核心在于SDK能够拦截到微服务内部的请求,从请求中获取流量标识,并在微服务发起外部请求时,将这个标识加入请求中,实现流量标识的透传。基础 SDK 的工作机制一般包括以下几个关键步骤:
使用基础Agent方式
使用 Agent 技术实现流量标识透传是一种相对隐式且高度可配置的方式。Agent 是一种可以介入到 JVM 运行时的程序,它可以对 Java 应用程序进行动态的字节码操作和增强。
在实现流量标识透传时,Agent 可以通过动态字节码增强技术,通过字节码操作工具(如ASM、ByteBuddy等)对特定类或方法进行字节码增强,动态地修改微服务应用的字节码,使得在请求处理链路中自动获取到流量标识,并在请求发起时将这些标识添加到外部请求中。这些标识可能包括从HTTP头部、上下文信息、或者其他标识性的数据。
有一些基础Agent开源方案可以选择参考,如:Homer,这是专门为javaweb应用提供了无感知的header透传的开源方案,华为的Sermant,Sermant 是利用JavaAgent技术为Java应用程序提供服务网格功能的开源方案,提供了流量透传插件tag-transmission,可以帮助微服务实现流量透传功能。
三种方式总结
这三种实现流量标识透传的方式各自具有独特的优势和适用场景。总结如下:
流量路由
流量路由和微服务标识类似,由于传统模式和云原生模式都支持,较流量标识简单很多。
在传统微服务框架(如 Spring Cloud)中,实现动态路由通常通过 API 网关(如Spring Cloud Gateway)或负载均衡器(如Netflix Ribbon)等组件,根据特定的策略或规则,对流量进行分发和路由。例如,可以基于请求头中的流量标识信息,利用负载均衡策略,将请求分发到不同版本的微服务实例上,实现动态路由。
而在云原生架构下(例如 Kubernetes + Istio),动态路由更加简单。通过 Istio 中的流量管理功能,定义Gateway、VirtualService、DestinationRule等规则和配置来实现流量的精细化控制和路由。
3全链路灰度发布实践
我们在云原生模式下,对概述部分图1 所示的微服务进行全链路灰度发布实践。微服务版本情况及调用链路和图 1 一致,微服务实例列表如下:
网关采用 Istio Ingress Gateway,流量标识透传采用基础 Agent 方式,可以在微服务调用链路中透传 key 为 et-mark 的 HTTP Request Header ,流量路由通过 Istio 流量管理功能实现,关键Gateway、VirtualService、DestinationRule 规则部分如下:
---apiVersion: networking.istio.io/v1beta1kind: Gatewaymetadata:name: ingress-gatewaynamespace: e2e-canary-releasespec:selector:istio: ingressgatewayservers:- hosts:- 'www.e2e-canary-release.com'port:name: httpnumber: 80protocol: HTTP---apiVersion: networking.istio.io/v1beta1kind: VirtualServicemetadata:name: service-anamespace: e2e-canary-releasespec:gateways:- e2e-canary-release/ingress-gatewayhosts:- 'www.e2e-canary-release.com'http:- route:- destination:host: service-a---apiVersion: networking.istio.io/v1beta1kind: VirtualServicemetadata:name: service-bnamespace: e2e-canary-releasespec:hosts:- service-bhttp:- match:- headers:et-mark:exact: v2route:- destination:host: service-bsubset: v2- route:- destination:host: service-bsubset: v1---apiVersion: networking.istio.io/v1beta1kind: DestinationRulemetadata:name: service-bnamespace: e2e-canary-releasespec:host: service-bsubsets:- labels:version: v1name: v1- labels:version: v2name: v2
实际效果如下,可以看到默认情况下请求流量流经的微服务版本均为正式版本v1,当请求header中包含流量标识时,即流量为灰度流量时,会按照图1 中的灰色路径流转,实现了全链路灰度发布。
4总结
本文首先介绍了全链路灰度发布的概念、作用以及实现全链路灰度发布时需要解决的关键问题,针对每个问题分别从传统模式和云原生模式介绍了对应的解决方案,其中对流量标识透传做了详细的介绍,然后在云原生模式下,对微服务 Demo 进行了全链路灰度发布实践,展示了实践效果。由于能力和时间有限,一些内容仅进行了粗浅介绍,希望后续可以继续深入研究分享,文中存在错误的地方,也望大家指正。
5参考文章及相关链接
作者:张海文,中国移动云能力中心高级软件研发工程师,移动云服务网格负责人,QCon、KubeCon等大会分享者,专注于云原生、微服务、算力网络等。
为什么移动鼠标就总是刷新
什么是鼠标刷新率概念:也叫鼠标的采样频率,指鼠标每秒钟能采集和处理的图像数量,单位是“帧/秒”。 漫谈:可以这么说,即便光电鼠标拥有诸多优点,但刷新率不足乃是它的致命伤,这也是早期光电鼠标没有打入主流市场的主要原因之一。 举个简单的例子,比如在FPS游戏第一人称射击游戏中快速转身,刷新率低的光电鼠标就出现丢失光标指针的问题。 刷新率对于光电鼠标如此重要,那到底怎样理解它呢?不同于机电鼠标通过栅格的转动产生脉动信号而产生移动信息,光电鼠标是靠鼠标下方的一个CMOS传感器来负责分辨鼠标移动的。 我们都有坐车的经历:当汽车起步时,我们可以通过车窗外景物的后移来判断汽车在前移。 而光电鼠标下方的CMOS传感器就是利用了我们人眼观察事物的特点来工作的:当我们移动鼠标时,CMOS传感器就会“观察”鼠标下的采样表面(桌面或鼠标垫)来获得鼠标的移动信息。 CMOS并不是一直“睁着眼”,而是“一眨一眨”的。 也就是说CMOS是以一定的频率对采样表面进行采样,产生离散量后转化为数字信息供计算机处理。 那么这个采样频率即我们说的刷新率为了能产生数字信号,鼠标下的CMOS类似于我们见到的网格,它会把采样回来的图像分成很多紧密排列的小格,再在这些以小格为单位的图像中找出相同的像素点,也就是参照物。 对比两次采样图像的相同像素点,也就知道了鼠标移动的方向。 由于采样频率是固定的,鼠标的移动速度也就能计算出来了。 当鼠标移动速度过快时,鼠标在连续两次扫描所得的图片中找不到相同的像素点,也就无法判断光标移动的速度和方向了,这就是鼠标刷新率不足产生的光标指针丢失的现象。 刷新率和CMOS像素对鼠标的影响怎样才能使鼠标满足我们的移动要求呢?对于鼠标来说可以加大CMOS像素数或提高刷新率。 2002年下半年,罗技开发出了新一代的MX光学引擎,它推出了新的鼠标性能标志:像素处理能力。 像素处理能力=每帧像素数×刷新率,这是综合了刷新率和CMOS像素数的一个指标。 当时罗技极光云貂(MX500)的像素处理能力是470万像素/秒。 而微软的光学银光鲨4.0(IE4.0)有6000帧/秒的刷新率和22×22的CMOS尺寸,我们很容易算出微软这款鼠标的像素处理能力=22×22×6000=290万像素/秒。 其实罗技MX引擎的刷新率并不如微软,大概在5000帧/秒左右,只是罗技提高了CMOS像素数的结果。 什么是鼠标分辨率概念:指鼠标的定位精度,单位是dpi或cpi,指鼠标移动中,每移动一英寸能准确定位的最大信息数。 漫谈:dpi是dots per inch的缩写,意思是每英寸的像素数。 cpi是count per inch的缩写,意思是每英寸的采样率。 dpi和cpi都可以用来表示鼠标的分辨率,但是dpi反应的是个静态指标,用在打印机或扫描仪上显得更为合适。 由于鼠标移动是个动态的过程,用cpi来表示鼠标的分辨率更为恰当。 当我们把鼠标向左移动一英寸时,400cpi的鼠标会向计算机发出400次“左移”信号,而800cpi的鼠标就发送800次。 做个假设,我们把鼠标移动1/800英寸,那么800cpi的鼠标会向计算机传送一次移动信号,而400cpi的鼠标却没有反应,我们必须再移动1/400英寸它才会传送移动信号。 看到这里大家明白了吧,其实800cpi的鼠标在移动开始阶段会比400cpi的鼠标反应快些。 800cpi和400cpi的鼠标只是在显示器分辨率高的情况下性能差异才会表现得明显一点。 800cpi的鼠标虽然定位比较精确,但是价格比较昂贵,除非是专业图形用户或游戏专业玩家,400cpi分辨率的光电鼠标已经足够用了。 如今的鼠标市场已经是光电鼠标的天下。 由于鼠标内部没有了机械运动,所以光电鼠标的使用寿命明显高于机电鼠标,而且我们从此也离开了那令人讨厌的“抠泥”运动。 愿大家怀着愉快的心情,尽情感受那手掌中的旋律。
国内主流的SD-WAN方案包括哪些组件?
SD-WAN方案分为网络连接层、云管理平台、应用层三个层次。
1、网络连接层:通过各种网络设备,采用overlay技术,构建任意链路全网络连接;
2、云管理平台:基于SDN架构的Agile controller,实现设备的统一管理,overlay网络的统一控制和业务自动下发。南向通过netconf管理设备,北向通过restful与应用层实现对接;
3、应用层:包括第三方的BSS/OSS、VAS STORE等,Agile controller提供北向接口功能 ,可被第三方应用集成;
4、连接自动化:通过Agile controller对转发器和业务进行抽象,为北向提供统一、标准的网络级业务接口,实现虚拟网业务的自助发放,按需调整。业务自动驱动隧道创建调整,大大缩短业务上线周期,提升业务发放效率;
5、全网资源分层可视:提供物理拓扑、逻辑拓扑、隧道、虚拟网业务多层视图,自动发现网络资源,借助于实时监控带宽、状态、时延、丢包、抖动、业务连通性等业务SLA信息,变被动运维为主动运维,提升运维效率;
6、网络优化:网络流量实时自动调优、SLA信息采集和呈现;提供基于带宽、时延、cost值,优先级等多维调优能力,实现单业务路径最优和全局网络流量均衡,有效提升带宽利用率,并可降低网络扩容成本。
sdwan解决方案优势特点介绍?
sdwan解决方案切中企业分支接入的各种痛点,引入sdwan技术,重塑企业网络业务开通维护流程,帮企业构建即需即用、性价比高、安全可靠、应用级可视化的网络,让企业网络更加简单高效。
SD-WAN controller是一款针对企业分支接入的轻量级控制器产品,基于自研的UAP-MS微服务框架,具备灵活的部署特性,管理和控制功能合二为一,面向业务轻松部署,大大降低维护难度。 可以灵活满足不同规模的企业分支接入,同时对于企业总部或者一些大型分支,实现SD-WAN相关业务配置的轻松部署。
SD-WAN分支接入方案的优势特点
设备即插即用,业务一键部署,开通简单快捷
在Internet环境,企业用户接收到网关设备,接入网线和连接PC,在推送的界面输入激活码,设备自动完成Call home流程,发现控制器位置,完成CPE设备自动上线。
支持短信开局、邮件开局、U盘开局等多种快速开通方式。
面向业务意图的操作界面,IPSec、VxLAN等各种业务一键轻松部署。
链路状态感知,业务可识别,智能动态选路,提升业务体验
支持完善的探针技术,通过控制器主动发起对指定链路的服务质量检测,实时掌握分支接入链路状态。
企业用户自定义链路质量阈值和全网链路情况,智能进行路径选择和切换,提升分支业务体验。
支持应用识别技术,可根据用户对不同业务应用质量的不同诉求,提供差异化的网络服务,优先保障关键业务应用的体验。
多种安全策略,保障业务安全可靠传送
多重设备准入控制,设备序列号与位置信息绑定,惟一识别设备,防止非法设备接入网络。

CPE设备内置强大的防火墙功能,可以防范各种外部攻击,保护企业内网安全。
支持全面的虚拟网技术、IPSec、GRE、L2TP、VxLAN以及各种技术的叠加应用,充分保障企业业务在Internet网络中安全传送。
可视化运维,全网应用状态轻松掌握,故障快速定位
基于GIS的全局网络视图,站点可视,链路状态可视,网络端到端全路径可视,故障快速定位。
面向业务的配置管理界面,以人为本,可以基于用户意图智能部署业务,减少人为出错的概率,让管理人员更加轻松,网络维护更加高效。
全网应用及业务流量可视,企业用户可根据自身业务需求动态调整带宽和智能选路,降低用户OPEX支出。
发表评论