2022腾讯全球数字生态大会已圆满落幕,大会以“数实创新、产业共进”为主题,聚焦数实融合,探索以全真互联的数字技术助力实体经济高质量发展。大会设有29个产品技术主题专场、18个行业主题专场和6个生态主题专场,各业务负责人与客户、合作伙伴共同总结经验、凝结共识,推动数实融合新发展。
今年6月,腾讯宣布内部海量自研业务实现全面上云,成为国内最大规模的云原生实践,累计节省IT成本超过30亿元,充分显示腾讯云的产品、技术和综合服务能力。
云原生技术在云计算 PaaS 的应用已经迈入深水区,腾讯云微服务和中间件产品基于客户业务落地实践,在产品能力、可用性和可运维性等多个方面进行了深入的优化和落地。本次大会设立了微服务与中间件专场,本专场从产品研发、运维等最佳落地实践出发,详细阐述云原生时代,企业在开发微服务和构建云原生中间件过程中应该怎样少走弯路,聚焦业务需求,助力企业发展创新。本篇为微服务与中间件专场第一个演讲议题的干货集锦,欢迎大家收看!
本文将从以下五个方面展开,对微服务架构下路由、多活、灰度、限流的探索与挑战进行深入解析。
1、微服务概述
2、测试阶段最佳实践
3、发布阶段最佳实践
4、生产阶段最佳实践
5、微服务架构总结
https://www.bilibili.com/video/BV1iM411B7M7/?spm_id_from=333.999.0.0&vd_source=479307cf5f3abfaabd9d90eb33158e29
最早的应用架构,也就是IT系统通常都是一个单体架构,随着技术的发展与进步,出现了 SOV 这种面向服务的架构,一直发展到现如今,最流行的架构就是微服务架构。
单体架构:
SOA架构包括接口层、逻辑层和数据层:
微服务架构:
随着应用层的发展,资源层的发展也随之改变,对应单体架构的时候,大家都还是 IDC 基础设施,这是第一阶段;到了第二阶段,大家开始慢慢上云,就有了云计算与虚拟化技术;到了第三阶段,大家开始探索怎么去做容器化;随之到了第四阶段也就是现在,大家又开始探索怎么去做 Severless 无服务器的这种方式。
到了微服务架构之后,大家又想要去实现更多的场景,比如 Devops、架构的可扩展性、架构的高可用以及多环境路由、发布等,接踵而至的就是层出不穷的挑战。
如何做流量路由?
如何保证多活容灾?
如何实现金丝雀、蓝绿发布?
如何实现全链路灰度?
如何扛住流量洪峰?
接下来,我们就探讨一下在以上挑战之下的微服务实践。
微服务系统中,在开发测试时,如果有多团队同时开发,或者多系统需要联调,每次都需要部署全量服务来进行测试。如何做到仅部署本次有变更的服务,其他服务通过流量动态路由的方式复用基线环境服务资源,成为这种微服务测试阶段的一大痛点。
1、节约资源成本,开发/测试按需申请,用完即弃;
2、提升研发效率,摆脱大量的本地化配置的工作;
3、实现跨环境的联调,不用争抢不同的测试环境。
为了实现这个方案,需要用到微服架构里面的两个组件,一个是入口层的网关,另一个是服务治理框架例如服务网格等。
如何实现呢?
如下图所示,在测试环境里面通常会有多个环境,分为基线环境和特性环境,在测试的过程中,团队1想要去测左边蓝色的特性环境,团队2想要去测右边绿色的特性环境,这个时候就可以通过服务治理的框架来实现。
1、实例打标
K8s注册场景:在workload上通过添加annotation打上环境标签。
微服务框架注册场景:对服务下所有实例进⾏分组,通过标签能够区分部署的环境。
2、流量染色
入口网关对流量特性进⾏染色。例如:给特定uin的请求进行染色。
3、网关到后端服务的流量路由
入口网关通过标签路由,按照请求中的测试环境信息进行动态路由。
4、后端服务与服务间的路由
治理中心根据请求流量特征对不同测试环境中的服务进⾏动态路由。
微服务架构下,会涉及到发布的问题。
目前有三种流行的发布方式,一种是金丝雀发布,一种是滚动发布,一种是蓝绿发布,这三种常见的发布策略原理都是一样,都是期望在发布的过程中,把要发布的新的版本都做到绝对的测试,让所有的用户用的过程中,避免新版本有任何问题影响到所有的用户。但是在发布的过程中,这三种发布方式的策略会有一些不一样。
金丝雀发布就是对于本次的发布,按比例去升级,一定的实例,没有问题的话,再逐步的放开这个比例,直到最终所有的流量都到了V2版本,这就实现了一个金丝雀。
对于本次发布的服务,先升级一个/批实例,测试没问题了,再分批升级剩余实例,直到所有实例都升级到V2版本。
蓝绿发布是把实例分为两个阵营,一个绿阵营和一个蓝阵营,正在运行的实例是V一版本,把它放到绿阵营,这个时候部署了新的实例V2版本到蓝阵营里面。然后对V2版本进行全面的测试,测试没问题了之后再通过负载均衡,把流量从V1切到V2,这样就实现了一个无缝的发布,同时保证新版本线上环境的全面测试.
如下图所示,利用 API 网关和注册配置中心来实现指定流量比例进行灰度发布。在入口层,用 API 网关访问服务A,然后对服务A升级了一个V2版本,通过 API 网关调节10%的流量,从V1切到V2版本,这就实现了入口层的按流量比例的灰度。V2版本测试没问题后,再把百分百的流量切到V2版本来。
那在服务间调用的时候是怎么做呢?可以看到下图的下半部分,用服务B去调用服务C,这个过程中,对服务C进行升级,升级到V2版本,那么服务C里面就会有一个V2的实例,然后通过注册配置中心调节10%的流量,从服务B去调用服务C,就实现了服务间调用的按流量比例的灰度。
1、网关调节比例
将一定比例的流量导向到V2版本。
2、注册配置中心调节比例
将一定比例的流量导向到V2版本。
如右下图所示,在入口层服务A发布了V2版本,然后通过网关对想要进行灰度的条件进行设置,那么网关就可以根据设置的条件,比如 Header 里面带有某个参数,或者是 Pass 里面带有某个参数,根据这样的设置条件,特定的用户就可以访问到V2版本,实现入口层的流量切换。
在服务间调用的时候,如果想要实现条件灰度,就需要用到服务治理的框架,比如服务网格里带的标签路由,可以对服务C进行打标,然后再去做流量路由的时候,按照这个条件路由到V2版本的服务C里面,这样就实现服务网格的流量路由了。
1、网关调节比例
将一定比例的流量导向到V2版本。
2、服务网格设置条件路由
按条件将流量导向到V2版本。
全链路灰度是什么意思呢?就是在发布正式版本之前,有一个灰度环境能够去测试所有功能,端到端的测试,为了保证功能发布上线之后,不会影响其他的客户,先在小范围内进行测试,没问题了再全量发布。
如下图所示,首先对环境进行区分,比如说在生产环境里面,有一个正式环境,有一个灰度环境,当要发布一个新功能的时候,就把对应的新功能的实例部署到灰度环境里面去;然后通过服务治理框架对这个实例进行打标,加上标签,区分它是灰度环境的实例;接着在网关层路由这个流量的时候,对流量进行灰度染色,通常会有动态染色或者静态染色两种方式,但不管哪种方式,目的都是为了把流量做出区分。普通流量全部进入正式环境,对于想要灰度的流量就标记为V2,就可以从V2版本进入到灰度环境里面,在灰度环境里,用户中心到积分中心的时候会回到正式环境,因为积分中心没有灰度环境的实例,这时就需要用到服务治理框架,对流量进行路由,同样的正式环境访问灰度环境,也是通过这样的路由线路实现的。
1、实例打标
K8s 注册场景:在 Workload 上通过添加 Pod lables 打上版本标签。
微服务框架注册场景:对服务下的所有实例进⾏分组,通过标签能够区分版本。
2、流量染色
网关对流量特性进⾏灰度染色。有动态染色与静态染色两种方式。
3、网关到后端服务的流量路由
通过标签路由,按照请求中的服务版本信息进行流量转发。
4、后端服务与服务间的路由
在链路上各服务能够根据请求流量特征进⾏动态路由。
多活容灾是一个云原生的多活容灾架构解决⽅案。
众所周知,同一个地域通常会有多个可用区。如下图所示,有可用区1和可用区2,在两个可用区部署同一个服务A,然后服务A会读写底层的数据库,而数据库会有主备之分,主数据库在可用区1,备用数据库在可用区2。那么这时,在网关层就可以对流量按比例进行分发,可以进入可用区1也可以进入可用区2,可用区1的服务A可以对主数据库进行读写操作,而可用区2的服务对主数据库只会进行写操作,它的读操作会从备份数据库来。同时主数据库会实时的把数据同步到备份数据库里面,这样就做到了同城多活容灾的架构场景。
在微服务中,通常一个应用的多个节点会部署在不同的可用区,然后注册到同一个服务下,这样就实现注册中心的多活。
在微服务架构下的多活容灾,除了服务实例本身以外,还会涉及到网关、注册配置中心等相关组件。
如下图所示,入口层网关通常都要跨可用区部署,红色的线隔离的是不同的可用区,假如有一区、二区、三区,在这个过程中,网关就可以变成3个节点部署到三个区。注册配置中心也是一样的,分三个节点来部署到3个可用区,然后对应的服务就可以自动的部署到3个可用区,这样做的好处在于,如果任何一个可用区挂掉,服务还能够正常的响应,来保证整个架构的高可用。
在生产阶段,如何去做接入层的多活容灾呢?
如果想要在接入层实现多活,通常需要做到几个事情:
这就需要用到一个功能比较强大的网关,比如现在流行的 Kong 网关或者是 Nginx,来实现类似的操作。所有的网关应该都支持流量比例切换,只需要调节不同的流量比例到不同的可用区就可以了,如下图所示,广州一区的服务挂了,可以从网关手动的切换流量比例到广州二区,也可以实现自动的切换。要做到同城的容灾切换,只要把流量切到广州二区来响应同城的容灾。假如整个广州区都挂掉了,还可以从网关层直接把所有的流量全部切换到上海二区来实现这种跨城的容灾。
如何在这个服务间实现多活容灾和就近访问?
就近访问是什么意思呢?
比如现在有一个服务有两个实例,同时在广州部署了一个实例,也在上海部署了一个实例,有个上海的用户想要访问这个服务,如果他访问到的是广州的实例,整个访问的链路就会变得更长,延时也会增加,所以就近访问到上海的实例是最好的。
就近访问怎么做呢?
通过服务治理框架配置服务的地域信息,比如两个实例,第一个实例配置在广州地域,第二个实例在上海地域,当用户在访问的时候,服务框架就可以识别上海的用户应该到上海地域,来实现就近访问。
服务间的多活容灾区怎么做呢?
其实原理和接入层是差不多的,如下图所示,有一个广州一区的积分中心,想要去访问活动中心,但这个时候活动中心挂掉了,那通常服务治理框架就会去主动探活,发现活动中心挂了,它就会主动的去做同城的容灾切换,把积分中心切换到广州二区的活动中心来访问,这样就做到同城的容灾。如果广州区全部挂掉了,那么服务治理框架就可以把服务的流量自动切换到上海区来实现跨城容灾,黎明觉醒这个游戏就是通过这样的方式来实现跨城容灾架构的。
1、实例打标:对服务下的所有实例按照单元(SET)进⾏分组,通过标签能够区分单元(SET)。
2、动态路由:根据请求流量特征对不同单元模块(SET)中的服务进⾏动态路由。
3、隔离:SET 间服务调用的强隔离。
具体怎么操作呢?
在服务治理的框架里面对不同的实例进行分组,如下图所示,有个用户中心有6个实例,把左边的3个实例归为单元1,右边的3个实例标记为单元2,这样就实现了按实例的分组,对应的所有访问的服务都把它归到单元1里面,这样做的好处就是在整个访问的过程中,可以保证流量都在这个单元内,这就实现单元与单元之间的隔离操作。这样的过程主要依赖于注册配置中心以及服务治理框架,来对实例进行打标,进行分组,来实现的单元化。微信支付就是通过单元化的架构来实现对金融级的安全可靠的交易系统架构的保障。
1.接入层流量限流
2.服务间调用限流
1.服务/接口/标签的限流
2.秒、分钟、小时、天等时间微服的限流
1.单机限流:针对单个被调实例的级别的限流,流量限额只针对当前被调实例生效,不共享。
2.分布式限流:针对服务下所有实例级别的限流,多个服务实例共享同一个全局流量限额
不同的限流会在不同的阶段去做。如下图所示,在入口层的限流通常是由网关来做,配置一定的限流规则后,当大量的流量请求进来,触发了限流规则,通常会做丢弃或者排队两件事,针对攻击的场景,通常会把这无效的请求全部丢弃;针对正常的访问,比如抢购、秒杀等场景,就会对它进行排队,去访问后端的服务,来保证后端的服务不被击穿。在服务间调用的时候,比如用户中心去调用积分中心,当流量变大的时候触发了积分中心的限流规则,积分中心就会根据服务治理框架配置的限流规则去进行丢弃或者排队,通常在服务间的调用都会进行匀速排队来做到限流的作用。
王者荣耀以及腾讯视频每年会做大量的营销活动,做活动的时候流量就会突增,这样的流量突增,为了保护后端服务不被击穿,数据库不被击穿,一定会在入口层服务间做限流规则,他们就是利用网关以及服务治理的框架来实现的这种限流的场景。
请求从前端进来之后会进到网关,腾讯云主要使用的是云原生网关,它具有 CLB 负载均衡能力、安全路由能力以及限流能力,可以把请求转发到后端的服务,后端的服务主要是指腾讯云微服务,每个服务都会有多个弹性实例来响应不同的业务的波峰波谷,它会自动弹性伸缩来支撑高流量时资源不足的情况,同时也会在低流量的时候不造成资源浪费的情况。这么多服务的管理一定会有注册中心来保证服务的注册与发现,以及配置中心来管理所有服务的配置,再配合服务治理中心来实现动态路由熔断限流等,还包括底层的链路追踪和监控来实现完整的微服务架构。
那么要实现一个典型的微服务架构,腾讯云这边是用什么样的产品来支撑呢?那就是微服务引擎 TSE。
微服务引擎 TSE 提供开源增强的云原生网关、注册配置中心、服务治理平台和弹性微服务,帮助用户快速构建轻量、高可用和易伸缩的微服务架构。微服务引擎的使用方式完全兼容开源版本,在功能、可用性和可运维性等多个方面进行增强。