新一代云原生的微服务架构分享
导读:
伴随云计算的滚滚浪潮,云原生(CloudNative)的概念应运而生。近年来,在企业数字化转型进程不断提速背景下,云原生技术飞速发展,已在众多行业和领域都有了许多成功落地案例,以 kubernetes、微服务、服务网格、serverless、DevOps 为代表的云原生技术已走向成熟和广泛应用,顺势而为全面拥抱即将到来的云原生时代。
云原生为何如此火热?能带来哪些价值,为何如此多的企业青睐于它?本文以运营商 BSS 账务中心系统的云原生微服务架构演进实例,分享云原生架构落地过程遇到的困难及其成果。
01 古老的 tuxedo 之殇
十几年前,weblogic+tuxedo 是运营商账务中心的标准技术架构,tuxedo 服务框架作为核心的服务框架,承载着账务中心的核心服务功能,技术架构如下:
随着运营商业务不断发展,特别是经历了 4G 互联网时代的高速发展,到现在 5G 物联网时代的开启,老旧的 tuxedo 服务架构早已难以满足业务发展的要求,主要存在如下弊端:
有状态,不支持容器化部署,部署繁琐易出错:只能采用传统人工或脚本的升级部署方式,升级过程需要停系统,只能一台主机一台主机的升级,升级过程繁琐耗时,容易出错。
无法水平扩展,可靠性差,系统扩容困难:增加主机需要人工部署应用,修改配置,并将整个系统全部重启。
系统耦合高,可扩展性差:新增交易需要重新编译,修改相关前后端配置文件,重新部署应用,需全量重启 tuxedo 和 weblogic 服务。
缺少服务自治能力,可维护性差:系统难以维护,出现队列积压,进程异常退出、主机故障等问题,缺乏告警机制,且问题定位和排查难度大,故障恢复时间长。
Tuxedo 和 weblogic 均为海外商用软件,在国内核心技术要自主的大背景下,去 IOE 及海外商用软件已上升到政治高度。
02 微服务架构演进之路
2012 年以后,随着移动互联网的兴起,微服务思想就应运而生。2015 年左右国内大厂开始进行项目升级,转战微服务,2017 年传统企业也纷纷踏上了微服务架构升级之路。在这一年,我们也开始了账务中心微服务化演进之路,准备一次性彻底解决掉 tuxedo 这个历史包袱,但迎接我们的并非一番风顺。
帐务中心 dubbo 化改造之苦
当时 Dubbo & Spring Cloud 两大主流的开源微服务框架。鉴于 Dubbo 相对 Spring Cloud 框架的简单和轻量型以及在性能上的优势,我们选择了 Dubbo 框架,然后兴致勃勃的开始了服务 Dubbo 化之路。
账务中心服务 dubbo 化技术架构图如下:
经过长达一年半的服务 dubbo 化改造之后,我们不得不承认当初选择了一条耗费人力的痛苦之路:
跨语言改造之苦:
Dubbo & Spring Cloud 都属于 JAVA 技术栈,对于完全使用 C++开发的 tuxedo 服务,跨语言是我们面临的第一道坎。我们痛苦的选择将 tuxedo 服务使用 JAVA 语言重写,但最终工作量及重写风险,让我们止步于查询功能重写,而大部分核心功能仍然无法摆脱 Tuxedo,只能通过 RocketMQ 来尽量将同步调用改为异步调用的 C++消费者。
服务治理之苦:
Dubbo 服务的治理能力非常弱,面对客户对于安全认证、服务限流、服务熔断、灰度发布、服务在线发布等能力的需求,开源的 Dubbo 服务框架均不支持,于是我们只能通过对 Dubbo 服务调用的泛化接口增强封装或通过 Dubbo 过滤器扩展一些安全认证、灰度发布、服务限流等完善性功能。
性能调优之苦:
由于服务可观测性较弱,缺少服务调用链,在性能压测时只能通过原始的不断增加性能相关日志的方式,性能问题定位和调优工作效率极低,类似线程池大小及数据库连接池参数不合理导致的获取连接超时,以及 SQL 并发执行的超时等异常超时情况,在上线后经过了 2 个月的痛苦周期才将 dubbo 服务性能渐渐调优稳定。
传统微服务框架 Dubbo & Spring Cloud 的局限
• 跨语言问题:均属于 JAVA 技术栈,不支持其他语言的 RPC 调用。对于使用其他语言(如 C++)开发的应用改造为微服务架构无法使用,只能考虑重写。
• 应用耦合高:基于注册中心实现服务动态发现,各自有自己的应用技术框架,业务应用与框架深度绑定,强耦合。应用需要进行框架改造,并且需要配套相关组件及配置。
• 服务治理能力弱:dubbo 服务治理能力最弱,本质上只能算一个分布式 RPC 框架,只有基础的服务发现,限流、熔断、灰度发布、智能路由、追踪等微服务框架能力均需要自行定制完善。
• 缺少部署与运维能力:spring cloud 的服务治理能力需要通过集成各种配套组件实现,并且也缺少灰度发布、服务调度、故障自愈、弹性伸缩这些运维能力。
新一代微服务架构 Istio & Grpc
随着容器化技术的普及,kubernetes 生态的不断完善,基于 kubernetes 的微服务架构也应运而生。在经历了账务中心服务 dubbo 化的痛苦之后,我们也终于找到了新的出路,即基于 k8s 的 Istio & Grpc。
服务网格 Service Mesh 的设计理念
首先,吸引我们的是服务网格的设计理念,Service Mesh 是在网络层 TCP/IP 上建立的一个中间层,接管服务之间的通信流量,将微服务治理能力下沉,从而实现对上层应用透明、不限制语言、无侵入的享受微服务能力。这不正好解决了我们经历的服务 Dubbo 化的痛点问题吗?
通过在应用服务旁边注入一个 SideCar 代理,实现对服务网络流量的拦截。将服务之间的通讯完全交给由 SideCar 代理组成的服务通信网络,将微服务等能力均下沉到 Sidecar 代理中实现,从而对应用透明无侵入。
服务网格 Istio 架构
由于 kubernetes 与 Istio 的天源互补,Isito 是 CNCF 云原生基金会首推的云原生微服务架构,经过几年的发展,Istio 已成为服务网格众多实现方案中当之无愧的最佳开源实践,成为大家在服务网格技术选型时的默认选项。
Istio 主要功能特性:
量管理:为 HTTP、gRPC、TCP 等流量路由和控制,最新版本已支持 Dubbo 协议。
动态路由:通过丰富的路由规则、重试、故障转移和故障注入对流量行为进行细粒度控制。
控制策略:可插拔的策略层和配置 API,支持访问控制、速率限制和配额。
可观察性:服务间流量的自动化度量、日志记录和追踪。
安全:基于身份验证和授权的,实现安全的服务间通信。
Kubernetes+istio 的主要优势:
应用无侵入:服务网格独立部署配置,对应用程序透明无感知、程序语言无关、RPC 框架无关,应用改造量极小即可实现微服务架构。
Istio 与 k8s 天然融合:服务治理、观测及运维平台相关能力完备,开箱即用。Dubbo 框架服务治理能力弱,Spring Cloud 虽通过各种组件补齐服务治理能力,在没有 k8s 的加持下,它们都缺少部署与运维的能力,因此都需要使用 dubbo/Spring Cloud 与 k8s 的融合方案。Istio 也就成为 Dubbo、Spring Cloud 与 k8s 融合的桥梁。
03 账务中心微服务化实践
跨语言解决方案
gRpc 是开源的轻量级跨语言的 RPC 框架,gRpc 是 Istio 的头号公民。
• 使用 Grpc 实现跨语言的 RPC 调用,通过搭建底层 C++的 grpc Server 公共框架替代 tuxedo 服务,在 tuxedo 服务入口做 grpc 服务适配改造,复用现有的 C++业务核心代码,从而将应用的改造工作量控制到最小。
• 引入 Istio 服务网格(service mesh),构建服务通信网络中间层,由 k8s+istio 来实现微服务的服务发现、负载均衡、服务路由、熔断限流、鉴权、灰度发布等微服务能力。
基于业务指标的动态伸缩
K8s 中几种典型的动态伸缩机制:
1) 基于 HPA 的弹性伸缩
• K8s 原生的 HPA 支持基于 CPU、Memory 的自动扩缩容。
• 利用 Prometheus adapter 可获取 prometheus 自定义指标扩展。
• 通过 CronHPA 扩展定时自动扩缩容。
2) 基于 KPA 的弹性伸缩
• Knative Serving 自动扩缩容(KPA):基于服务并发请求指标的秒级扩缩容(仅支持 HTTP/GRPC),支持缩容至 0 和从 0 到 1 的冷启动
• Knative eventing 自动扩缩容(KPA):基于服务并发请求指标的秒级扩缩容,支持 0-1 的冷启动。
账务中心的弹性伸缩应用场景:
1) 账务 HTTP&GRPC 服务采用 KPA,knative 的动态伸缩优点是对于突发流量能够做到秒级伸缩。HPA 伸缩是分钟级,5 分钟的稳定期,且 prometheus 的扩展业务指标采集本身存在 30s 以上延迟。
2) 银行接口、DCC 接口、Dubbo 服务只能使用 HPA+prometheus 自定义指标方式,而 istio 默认内置了 jaeger+prometheus+grafana 等服务监控与日志追踪的开源组件,并默认进行了 jaeger 埋点、生成了 prometheus 的服务性能及交易量等服务指标,直接可用于 hpa 中,无需应用再做任何埋点和指标采集的适配改造。
3) 定时任务、日月账任务、批量任务适合采用定时伸缩,如下账的任务可以在下账前扩展执行器和批量处理服务数量。
全系统、微服务粒度的灰度发布
基于 Nginx 的灰度发布,局限在接入层进行灰度路由,AB 部署模式浪费资源,灰度粒度大,并且基于内容的灰度发布依赖定制的 lua 插件实现。
常见 web 或者 http 接口的灰度发布实现,主要通过前端 Nginx 反向代理中注入 lua 插件实现灰度路由,不能单独针对后端服务(dubbo 服务、grpc 服务)的灰度发布,因此通过采用 AB 两套部署模式,灰度发布粒度大;另外,由于各类应用接口协议、web 端参差异大,自定义 lua 插件通用性较差。
Dubbo 和 spring cloud 均有各自的灰度发布,应用场景局限在各自的服务框架中,通用性差,各自配置和实现方式差异大。
spring cloud 依赖 zuul 或 cloudgateway 网关实现灰度路由策略,对于 Dubbo 服务通常是在服务消费端实现自定义的灰度路由规则。将 Dubbo 灰度发布、spring cloud 灰度发布以及 Nginx 灰度发布结合起来,可以实现服务粒度的灰度发布。但由于它们各自的实现方式各不相同,往往还需要统一定义一个统一灰度发布规则配置和操作界面来屏蔽配置和操作上差异,降低配置和操作复杂度,增强易用性。
Isio 则通过其动态路由能力实现全系统、服务粒度、统一方式、灵活灰度策略的灰度发布。应用无侵入,无需额外的开发,配置也采用 k8s 的 yaml 文件定义,配套 helm 可实现一键灰度发布,一键滚动更新。
• 营业 WEB:采用 cookie 中的工号作为灰度规则进行路由;
• 集团 OpenAPI:采用 http header 中的渠道 ID 和应用 ID 作为灰度规则进行路由;
• WS 接口:采用流量权重的灰度发布;银行接口和 DCC 接口服务已稳定无需灰度发布;
• Dubbo&Grpc 服务:采用 Grpc Header 或者 Dubbo context 中的工号、账户 ID、测试号码作为灰度规则进行路由;
• 异步实时任务:MQ 消费者进程内部调用 Grpc 或者 Dubbo 服务,也通过 Istio 实现按照工号、账户 ID、测试号码作为灰度规则路由。
零信任网络的服务安全
• 双向 TLS 身份验证:服务之间通过 sidecar 之间双向 TLS 握手,验证服务器证书中提供的服务帐户是否有权运行目标服务,无需更改应用程序代码和基础架构,通过简单配置实现默认的服务安全。
• JWT+HTTPS 的接入身份认证:利用 Istio 基于 JWT 的身份认证机制,在 IngressGateWay 入口网关进行 JWT 有效性的验证。实现外部 CRM 统一门户接入 WEB 的身份认证。
• 通过 CRM 统一门户登录认证服务生成 JWT 签名,在访问账务 web 界面时在 header 中携带 JWT。Authorization: Bearer <jwt token>
• 利用 Istio 基于 JWT 的身份认证机制,在 IngressGateWay 入口网关进行 JWT 有效性的验证,通过验证方可访问账务 web。
• 统一门户与 ingressgateway,ingressgateway 与账务 web 服务之间均采用 tls 协议加密传输,防止 JWT 泄露。
04 结语
云原生的微服务架构 k8s+istio+grpc,凭借其应用无侵入、语言无关、框架无关(兼容 dubbo)、服务治理能力完备、开箱即用、与 k8s 天然融合互补等独特优势,提供了一个普适度广、应用改造成本小、风险最低、服务治理功能完备,并充分利用了 k8s 原生部署和运维能力的解决方案。我们的账务中心微服务化之路最终也通过该解决方案,最终从 dubbo 化改造的泥潭中得以解脱,也让我们成为云原生技术的热衷追随者,顺势而为全面拥抱云原生时代吧
版权声明: 本文为 InfoQ 作者【鲸品堂】的原创文章。
原文链接:【http://xie.infoq.cn/article/121a3a5031152b9f53811b46b】。文章转载请联系作者。
评论