#为什么要做SpringCloudTencent
SpringBoot+SpringCloud仍是Java生态最主流的框架
年4月SpringBoot发布1.0版本,经过8年时间的发展,SpringBoot已然成为Java开发框架的事实标准。在分布式微服务领域,年1月SpringCloud发布Angel.SR5版本。
SpringCloud延承了SpringBoot最核心的组件化、低配置快速集成的核心思想,同时定义了一套标准的微服务SPI。基于这套SPI出现了SpringCloudNetfix等优秀的微服务解决方案实现套件。
在远程服务调用框架方面,Feign和RestTemplate基于普适的HTTP协议,在易用性、可观测性、跨语言等方面具备天然的优势。所以SpringCloud自年发布第一个版本之后蓬勃发展。
从行业情况看,SpringBoot+SpringCloud是目前Java使用最广泛的开发框架之一。
年开始以Istio为代表的ServiceMesh开始在社区中孵化,到年已经有非常多的ServiceMesh产品。ServiceMesh核心思想是下沉服务调用相关的基础能力到独立的Sidecar进程,通过流量代理的方式治理流量。任何一种方案都不是万能药,Sidecar模式也存在一些问题。
例如:高度依赖底层Paas能力治理Sidecar(注入、版本管理、升级等)、Sidecar需要额外占用一定的资源、增加一定的网络延迟、增加排障难度等。所以国内真正能够落地ServiceMesh的企业并不多。
综上所述,我们认为在未来很长一段时间内SpringBoot+SpringCloud仍是Java主流的微服务解决方案,虽然它看上去没有像Istio、Dapr那样的先进。在满足企业业务发展诉求的前提下,低成本、高效、稳定的架构方案才是最好的方案。
腾讯年开源的北极星(PolarisMesh)提供了一站式微服务解决方案
北极星是一款集注册中心、配置中心、服务治理中心为一体的一站式微服务解决方案,在腾讯内部已覆盖90%的业务,注册的实例节点数更是达到了万的规模。在21年开源之后,在社区内也有外部公司生产落地。
公司内部的架构师经常会做一些技术选型,比如注册中心用Zookeeper、Consul、Nacos等,配置中心用Apollo、Nacos,限流熔断用Sentinel。多组件也意味着需要维护多套服务,占用更多的资源,用户体验上也难以做到一致性。
所以一站式微服务解决方案能够大大简化技术选型、运维、资源成本。当然也可以把北极星当做方案里的一部分,例如只用北极星的服务注册发现,配置中心仍然选型Apollo。毕竟还是那个道理,没有万能的方案,适合企业业务自身诉求的方案才是最好的方案。
另外北极星在某些能力横向对比上也有一定的优势。例如完全无状态的注册中心更加便于运维,强大的服务路由能力支持复杂的业务场景等。具体的产品功能在第二部分会更加详细的介绍。
小结
基于以上两点核心原因,把北极星作为SpringCloud一个开箱即用的实现套件就顺理成章了。既能满足SpringCloud的用户,又能满足北极星Java的用户。当然SpringCloudTencent目前只对接了北极星的能力,后续会支持更多腾讯开源的优秀产品。
#SpringCloudTencent模块详细介绍
目前SpringCloudTencent主要提供了微服务领域常见的服务注册与发现、配置中心、服务路由、限流熔断以及元数据链路透传能力。接下去会详细介绍每一部分的能力。
图:SpringCloudTencent能力大图
2.1服务注册与发现(SpringCloudTencentPolarisDiscovery)
服务注册与发现是SpringCloudTencent最为核心的功能之一,通过实现SpringCloud的服务注册与发现的标准接口,提供微服务应用快速接入北极星服务注册中心的能力。开发者通过简单的引入SpringCloudTencent服务注册与发现的依赖,即可使用北极星的服务注册与发现功能。
接入服务注册与发现之后,还能按需使用北极星提供的强大服务治理能力,例如场景化的服务路由能力、服务熔断能力等。方便开发者针对微服务的实际生产场景作出个性化的服务治理配置。
北极星的服务模型包括命名空间、服务和服务实例。
命名空间
命名空间提供了一种在同一个注册中心下资源的逻辑隔离的机制,同一命名空间下的服务命名必须唯一,但是跨命名空间允许存在同名的服务。命名空间常用于区分不同的环境或者多个业务之间的服务隔离。
服务
服务也是逻辑的概念,提供一个特定业务领域的服务能力。例如订单服务,用户服务,转账服务等。
服务实例
服务实例是服务下的一个具体的物理节点。
(图:服务实例详情)
SpringCloudTencent在基础的服务注册发现上,提供了一些拓展能力。首先,SpringCloudTencent集成了北极星的一些路由插件,通过在北极星控制台页面更改服务实例的隔离状态或者权重值,都可以实现服务实例的动态上下线的特性,如上图所示。
SpringCloudTencent还提供了多服务注册与发现的进阶功能。举个例子,公司内部多个部门或组织使用了不同的服务注册中心,当决策技术栈统一或是迁移到北极星注册中心时,需要使用平滑的方式进行业务改造,而非直接替换原有的SDK接入北极星注册中心。此时可以使用SpringCloudTencent的多服务注册与发现的能力,帮助开发者的微服务应用过渡技术栈转换的尴尬期。
SpringCloudTencent提供的这样一系列针对服务注册与发现的周边功能,完善了微服务架构的治理与管控能力。
2.2配置中心(SpringCloudTencentPolarisConfig)
今年上半年北极星开始支持配置中心的能力。北极星配置中心核心配置三元组模型为:
Namespace
用于逻辑隔离集群的能力,例如常用于隔离环境。
FileGroup
配置文件组,一组配置文件的集合。在SpringCloudTencent里,我们推荐的最佳实践是一个应用为一个FileGroup。对于框架类的配置,以框架名作为一个FileGroup,例如dubbo。
File
配置文件,例如properties、yml格式的配置文件。配置文件为最小管理单元,而不是配置文件里的配置项。
[Namespace,FileGroup,File]唯一定位一份配置文件。我们在设计模型的时候,参考了业界主流的配置中心产品,我们认为配置文件、配置文件组的概念,是开发者广泛认知且理解成本最低的配置领域模型,例如本地磁盘的文件夹和文件的概念。
配置中心核心能力是配置管理能力以及动态实时推送能力。在配置管理方面,一个应用往往具有非常多的配置文件,如何清晰的管理配置文件是一个非常重要的能力。我们在管控台设计UI时,开创性的把文件名以/作为分隔符树状形式展示。如下图所示,可以按应用模块划分目录,通过目录方式能够清晰管理一个应用下杂乱的配置文件。
(图:配置文件管理页面)
另外在SpringCloud集成方面,众所周知SpringBoot会自动加载应用resources目录下的application.yml、application.properties以及优先级更高的application-${activeProfile}.yml文件。在SpringCloudTencentPolarisConfig集成时,我们完全沿用了这套原生的配置加载机制。
也就是SpringCloudTencentPolarisConfig在启动时,会自动加载应用文件组下的application.yml和application-${activeProfile}.yml文件到Spring容器里。用户在做迁移时,只需把resources目录下所有的配置文件原封不动的上传到北极星即可。
2.3服务路由(SpringCloudTencentPolarisRouter)
在微服务领域,由于服务做了细粒度的拆分部署服务变的非常的轻量灵活。在结合k8s云原生极速弹性能力之后变的更加的强大。但是底层的Paas能力只是提供了基础弹性能力,真正发挥能力需要依赖上层的流量调配的能力。
放眼SpringCloud生态,能够深度整合SpringCloud提供场景化服务路由能力的组件套件并不多。这里解释一下场景化,服务调用框架根据一定的规则实现服务路由的能力我们称之为底层原子能力。
原子能力是非常通用的能力,但是很多时候并不能直接用于具体的业务场景。例如常见的测试环境分组,就近路由,蓝绿发布等称之为场景。服务路由只有做了场景化之后,才能真正做到开箱即用服务于业务。
SpringCloudTencentPolarisRouter目前实现了两种场景化的路由能力以及一种非常灵活的规则路由的能力。
元数据路由
服务实例都会附属一组元数据,例如环境信息,机房信息等等。元数据路由简单的讲就是以元数据信息作为路由的依据进来路由。这样讲还是有些抽象,我们以一个测试环境例子来解释一下。
(图:开发环境示意图)
上图是非常经典的用于解决测试环境冲突的方案。一次迭代中SvcA需要和SvcD联调,当团队人数少的时候,可以直接把stable环境部署成开发分支代码然后进行联调。但是当多个开发任务并行的情况下就会出现环境争抢的情况。
一种解决方式是每个开发任务独立部署一套全链路的环境,这种方式耗时耗力效果还很差。业界最主流的做法就是上图所示,每个开发任务子环境只需要部署联调的应用即可,链路上不在子环境里的服务都路由回stable稳定环境。
使用SpringCloudTencent为了达到以上的目的,只需要每个服务部署的时候,增加以下两个环境变量即可实现。
SCT_METADATA_CONTENT_ENV=dev1
SCT_METADATA_CONTENT_TRANSITIVE=ENV
SpringCloudTencentPolarisRouter组件会自动读取以上环境变量,并在每次服务调用时优先调用到跟当前实例ENV值一样的目标实例。
元数据路由使用的场景非常广泛,更多的细节请查阅GithubWiki。
规则路由
元数据路由本质上是基于服务实例的元数据进行筛选,是为了支持具体特定的场景而内置的服务路由能力。无需下发任何路由规则,使用起来非常简单。
而实际业务场景非常复杂,例如以下几种典型的业务场景:
内部员工路由到一套生产灰度环境,外部普通用户则路由到生产正式环境
VIP客户路由到一套高保环境,普通客户路由到普通环境
以上两种业务场景,则无法通过元数据路由实现。因为涉及到业务请求参数,而不是系统维度的环境变量。规则路由就是用于满足复杂业务场景而实现的一套基于规则的服务路由实现。
一个典型的规则如下图所示:
(图:路由规则配置页面)
上图表达的含义是:HTTPQueryParam的uid参数值为时,调用到ENV=gray的实例分组。通过路由规则能够描述出绝大多数复杂的业务场景。
为了便于使用,SpringCloudTencent内置了一套表达式标签规则,自动从HTTP请求中解析标签值。目前支持的表达式规则有:
${