? 小马哥 & Josh Long ?
喜欢写一首诗一般的代码,更喜欢和你共同 code review,英雄的相惜,犹如时间沉淀下来的对话,历久方弥新。
相见如故,@杭州。
4 月 18 日,Josh Long 来到了阿里巴巴西溪园区,我们向其演示了 Spring Cloud Alibaba 各个组件的功能和实现方式,Josh Long 看完意犹未尽,表示会在新的 Spring Tips 视频再次介绍 Spring Cloud Alibaba 中的其他组件。(点击文末阅读原文,访问上一期spring-tips-bootiful-alibaba)
画外音:首次遇见,@北京:我和 Josh Long 的一天
一天后, Spring Cloud Alibaba 发布了首个 GA 版本,此次开发历时 267 天,汇集 26 位 contributor 的努力,覆盖 Spring Cloud Edgware、Spring Cloud Finchley 和 Spring Cloud Greenwich 3 个版本。Spring Cloud 联合创始人 Spencer Gibb 在 Spring 官网的博客页面宣布该发板消息。随后,Spring Cloud 官方 Twitter 也发布了此消息
Spring 贺电史:
Spring Cloud Alibaba发布第二个版本,Spring 发来贺电
增加了 4 个新的模块:spring-cloud-alibaba-dubbo、spring-cloud-alibaba-seata、spring-cloud-alibaba-sentinel-zuul 以及 spring-cloud-alicloud-sms。
spring-cloud-alibaba-nacos 和 spring-cloud-alibaba-sentinel 对应的组件客户端进行了升级,新增了一些 feature,并且优化了一些功能。
spring-cloud-stream-binder-rocketmq 进行了比较大的重构,并且集成了 RocketMQ Spring 项目。同时 spring-cloud-starter-bus-rocketmq 也进行了一些优化。
修复了之前版本的一些 bug。
新版本的版本号对应关系如下表:
由于 Spring Cloud Alibaba 还在 Spring Cloud 孵化器内,所以版本号不能高于 1。
发布三个版本意味着维护三个分支,这个过程需要付出很多精力来做修改,遇到的难点有以下这些:
F 和 G 版对应的 JDK 版本是 Java 8 及以上,而 E 版还是 Java 7,这意味着 lambda 表达式或其它 Java 8 包含的类或方法等这些 Java8 才有的特性,在 Java 7 的分支下需要重新写一遍。
Spring Cloud 官方提供的组件在不同版本的处理逻辑并不一致,需要逐一进行适配。比如 Sentinel 整合 Feign 的时候,Feign 中的 RequestTemplate#url
方法在 G 版进行了修改。
不同版本的 Spring Cloud 规范并不一样,实现方式也变了。比如 Spring Cloud Strean Binder 在 G 版本的接口声明跟 E 、F 版本不一致。
SpringBoot 的兼容性问题,比如 Endpoint 的 id 策略,Actuator 的自动化配置生效写法,SpringApplicationEvent 事件在不同版本的执行顺序、策略变化等等。
测试、回归流程变长等等。
另外一个新增的组件是 Seata (原 Fescar,即分布式事务解决方案)。
Seata 是 阿里巴巴 开源的分布式事务中间件,以高效并且对业务 0 侵入的方式,解决微服务场景下面临的分布式事务问题。
随着业务需求和架构的变化,单体应用被拆分为微服务,原有的单库数据源已经改成了分别使用独立的数据源。业务过程将由多个个服务的调用来完成。此时,每一个服务内部的数据一致性仍可以通过本地事务来保证,但整个业务层面的全局数据一致性的保障改如何保障呢?这就是 Seata 所解决的微服务架构下典型的分布式事务需求。
Seata 提供了 AT(Automatic Transaction)和 TCC (Try-Confirm-Cancel) 两种工作模式。AT 模式是对业务完全无侵入,支持目前绝大多数 支持 ACID 事务的 关系型数据库。
当事务的参与者只有 支持 ACID 事务的关系型数据库时,Seata 可以在完全不侵入 业务的情况下完成分布式事务方案。
当事务的参与者中包含其他场景时,Seata 提供了与 AT 相应的另外一种工作模式称为 TCC 模式 ,来解决这些场景下的分布式事务问题。TCC 模式下,分支事务需要应用自己来定义业务本身及提交和回滚的逻辑。
Seata 事务的传播是依赖于在微服务调用链中传递 Seata 事务 上下文来完成的。如何在 Spring Cloud 框架中传播 Seata 事务上下文,并使得 Spring Cloud 用户更方便使用 Seata,就是 Spring Cloud Alibaba Seata 解决的问题。
在 Spring Cloud 这一层面,我们通过在微服务中传递事务上下文的方式完成了 Seata 在 Spring Cloud 层面的接入:
Spring MVC 环境下支持自动还原 Seata 事务上下文;
支持服务调用者通过 RestTemplate 或 FeignClient 调用时,自动传递 Seata 事务上下文;
支持 FeignClient 和 Hystrix、Sentinel 同时使用的场景;
在之前的 RocketMQ Binder 实现中,Binder 内部使用原生的 RocketMQ Producer 和 Consumer 进行消息的处理。
新版本对 RocketMQ Binder 进行了重构,集成了 RocketMQ Spring,其中 RocketMQ Spring 提供了这些功能:
统一使用 RocketMQTemplate
用于消息的发送。
提供 @RocketMQListener
注解用于消息的消费。
提供 @RocketMQLocalTransactionListener 接口配合 @RocketMQTransactionListener 注解进行事务消息的处理。
提供 RocketMQProperties
外部化配置配合 RocketMQAutoConfiguration
自动化配置类完成一些实例的自动化注册。
提供 RocketMQListenerContainer
容器规范了消息监听器对消息的处理。
RocketMQ Binder 集成 RocketMQ Spring 之后,会将 RocketMQ Binder 内部原先使用原生的 RocketMQ Producer 和 Consumer 替换成 RocketMQ Spring 内部提供的类或接口。
同时项目引入了 Binder 也可以使用 RocketMQ Spring 的特性:
消息发送方面,可以使用 Binder 自身提供的 MessageChannel
发送,也可以使用 RocketMQ Spring 提供了 RocketMQTemplate
进行发送。
消息消费方面,可以使用 Binder 自身提供的 @StreamListener
或 @ServiceActivator
进行消费,也可以使用 @RocketMQListener
进行消费。
Spring Cloud 体系消息总线的新选择 - 基于 RocketMQ 的消息总线组件,可以用于构建自身的微服务消息体系,底座基于 Spring Cloud Stream RocketMQ Binder 实现。
新版本中所有的消费者默认会使用 广播 和 rocketmq-bus-group
消费组进行消息的订阅。
Nacos Client 依赖使用了最新的 1.0.0 版本。Nacos 1.0.0 GA 版本,可大规模投入到生产环境,我们建议升级到 1.0.0 版本。
在配置这一块,上一个版本发布以后已经覆盖了绝大多数的场景,如果涉及到没有覆盖的场景,欢迎大家来创建 Issue 进行讨论或直接创建 Pull Request 来完善。
我们再重温一下目前 Nacos Config 提供的功能:
支持 Spring Cloud 官方的配置加载机制,通过内部相关规则(应用名、应用名 + Profile)自动生成相关的 Data Id 配置。目前支持 properties 和 yaml(yml) 格式的数据。
支持从多个 dataid 和 groupid 中获取和监听配置,并支持优先级指定。
支持多个应用之间的共享配置。
在注册这一块,我们支持了 HeartbeatEvent
事件,该事件会在 Spring Cloud 体系中的网关所使用。支持了 HeartbeatEvent
事件也就意味着 Nacos Discovery 目前也兼容了 Zuul 和 Spring Cloud Gateway。
同时还有一些其它额外的改进:
可以选择使用 @DiscoveryClient
注解,引入 starter 之后不使用该注解也会自动进行服务的注册。
支持 namespace 隔离注册数据(Nacos Client 0.8.0 或以上版本即可支持)。
上个版本发布之后,Sentinel 组件就已经对 Spring 体系中的客户端组件提供了比较好的支持了。
RestTemplate:构造的时候加上 @SentinelRestTemplate
会额外获取 Sentinel 的保护。
Feign:引入 openfeign 依赖后,打开 feign.sentinel.enabled=true
开关再配合 Sentinel 的资源即可使用。
新版本 Sentinel 组件对 Zuul 1.x 网关进行了集成,使用方式也非常地简单,只需要针对 url 进行资源的设置即可:比如使用 Zuul 后访问 /provider1/hello
服务,那么对应的资源名是 /provider1/hello
。同时也提供 RequestOriginParser
进行 origin 的设置, UrlCleaner
进行资源的 clean、 ZuulBlockFallbackProvider
对 BlockException
的处理逻辑这些 "配套" 的方式来让我们更加方便地使用 Sentinel 对 Zuul 进行限流降级处理。
关于 Spring Cloud Gateway 网关的支持,会在 Sentinel 1.6 版本支持。
优化了 RestTemplate 的降级处理,这是因为其内部提供了 ResponseErrorHandler
用于解析 Response 信息,并判断是否是一个错误请求。Sentinel 对 RestTemplate 的降级处理跟该策略进行了融合。
SentinelEndpoint
内部展示的信息更加完善,包括了应用名,日志所在目录,日志名策略,dashboard地址,metrics 文件大小,客户端ip,数据源客户端心跳时间等等信息。
外部化配置更加完善,详情可以参考 Wiki (地址:https://github.com/spring-cloud-incubator/spring-cloud-alibaba/wiki/Sentinel#more)。
@SentinelRestTemplate
在某些场景下不生效。
支持 Spring Cloud 官方提供的 @EnableCircuitBreaker
注解。
解决动态数据源在首次加载情况下规则数据不存在的话推送失败的问题(数据源外部化配置添加了 rule-type
字段)。
Dubbo 作为成熟的 RPC 框架,其易用性、扩展性和健壮性已得到业界的认可。Dubbo 与 Spring Cloud 并非竞争关系,Dubbo Spring Cloud 的出现使得 Dubbo 生态体系发生了巨大变化,它作为 Spring Cloud Alibaba 的最核心组件,完全地拥抱 Spring Cloud 技术栈,不仅保持 Spring Cloud 原生特性,而且提供更为完善的 Dubbo 服务治理能力。简言之,Dubbo Spring Cloud 对 Spring Cloud 技术栈所带来的革命性变化。
通过以下表格,简要地对比 Spring Cloud 与 Dubbo Spring Cloud 的功能特性:
更多的特性细节,请参考下文的“功能特性” 部分。
版本支持
由于 Spring 官方宣布 Spring Cloud Edgware(下文简称为 “E” 版) 将在 2019 年 8 月 1 号后停止维护,因此,目前 Dubbo Spring Cloud 发布版本并未对 “E” 版提供支持,仅为 Finchley 与 Greenwich (下文分别简称为 “F” 版 和 “G” 版) 开发,同时也建议和鼓励 Spring Cloud 用户更新至 “F” 版 或 “G” 版。
同时,Dubbo Spring Cloud 基于 Apache Dubbo Spring Boot 2.7.1 开发(最低 Java 版本为 1.8),提供完整的 Dubbo 注解驱动、外部化配置以及 Production-Ready 的特性。(详情请参考:https://github.com/apache/incubator-dubbo-spring-boot-project)
以下表格将说明 Dubbo Spring Cloud 版本关系映射关系:
Dubbo Spring Cloud 基于 Spring Cloud Commons 抽象实现 Dubbo 服务注册与发现,应用只需增添外部化配置属性 “dubbo.registry.address = spring-cloud://localhost
”,就能轻松地桥接到所有原生 Spring Cloud 注册中心,包括:
Nacos
Eureka
Zookeeper
Consul
Dubbo Spring Cloud 将在下个版本支持 Spring Cloud 注册中心与 Dubbo 注册中心并存,提供双注册机制,实现无缝迁移。
默认情况,Spring Cloud Open Feign 以及 @LoadBalanced
RestTemplate
作为 Spring Cloud 的两种服务调用方式。Dubbo Spring Cloud 为其提供了第三种选择,即 Dubbo 服务将作为 Spring Cloud 服务调用的同等公民出现,应用可通过 Apache Dubbo 注解 @Service
和 @Reference
暴露和引用 Dubbo 服务,实现服务间多种协议的通讯。同时,也可以利用 Dubbo 泛化接口轻松实现服务网关。
Dubbo Spring Cloud 引入了全新的服务治理特性 - 服务自省(Service Introspection),其设计目的在于最大化减轻注册中心负载,去 Dubbo 注册元信息中心化。假设一个 Spring Cloud 应用引入 Dubbo Spring Boot Starter,并暴露 N 个 Dubbo 服务,以 Dubbo Nacos 注册中心为例,当前应用将注册 N+1 个 Nacos 应用,除 Spring Cloud 应用本身之前,其余 N 个应用均来自于 Dubbo 服务,当 N 越大时,注册中心负载越重。因此,Dubbo Spring Cloud 应用对注册中心的负载相当于传统 Dubbo 的 N 分之一,在不增加基础设施投入的前提下,理论上,使其集群规模扩大 N 倍。当然,未来的 Dubbo 也将提供服务自省的能力。
尽管 Dubbo Spring Cloud 完全地保留了原生 Spring Cloud 服务调用特性,不过 Dubbo 服务治理的能力是 Spring Cloud Open Feign 所不及的,如高性能、高可用以及负载均衡稳定性等方面。因此,建议开发人员将 Spring Cloud Open Feign 或者 @LoadBalanced
RestTemplate
迁移为 Dubbo 服务。考虑到迁移过程并非一蹴而就,因此,Dubbo Spring Cloud 提供了方案,即 @DubboTransported
注解。该注解能够帮助服务消费端的 Spring Cloud Open Feign 接口以及 @LoadBalanced
RestTemplate
Bean 底层走 Dubbo 调用(可切换 Dubbo 支持的协议),而服务提供方则只需在原有 @RestController
类上追加 Dubbo @Servce
注解(需要抽取接口)即可,换言之,在不调整 Feign 接口以及 RestTemplate
URL 的前提下,实现无缝迁移。如果迁移时间充分的话,建议使用 Dubbo 服务重构系统中的原生 Spring Cloud 服务的定义。
了解更多 Dubbo Spring Cloud 的特性以及设计细节,可访问:
Spring Cloud Alibaba wiki:
https://github.com/spring-cloud-incubator/spring-cloud-alibaba/wiki
Dubbo 的博客:
http://dubbo.apache.org/zh-cn/blog/index.html
如果您需要进一步了解 Dubbo Spring Cloud 使用细节,可参考:
官方 Samples:
https://github.com/spring-cloud-incubator/spring-cloud-alibaba/tree/master/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples
其子模块说明如下:
spring-cloud-dubbo-sample-api:API 模块,存放 Dubbo 服务接口和模型定义
spring-cloud-dubbo-provider-web-sample:Dubbo Spring Cloud 服务提供方示例(Web 应用)
spring-cloud-dubbo-provider-sample:Dubbo Spring Cloud 服务提供方示例(非 Web 应用)
spring-cloud-dubbo-consumer-sample:Dubbo Spring Cloud 服务消费方示例
spring-cloud-dubbo-servlet-gateway-sample:Dubbo Spring Cloud Servlet 网关简易实现示例
如果您在使用的过程中遇到任何问题,请内容反馈至
https://github.com/spring-cloud-incubator/spring-cloud-alibaba/issues
短信服务(Short Message Service)是阿里云为用户提供的一种通信服务的能力。
我们规范了短信服务对应的一些方法在 ISmsService
接口中,提供了鉴权、短信单次/批量发送、查询、短信上行/下行监听器注册等功能。
可以在配置文件中配置对应的 ak、sk、上行,下行队列名。程序对应的类中就可以注入 ISmsService
,然后即可进行短信的相关操作。
Sentinel 目前已经支持 reactive,并且会在 Sentinel 发布 1.6 版本支持 Spring Cloud Gateway 之后,进行 WebFlux 和 Spring Cloud Gateway 的适配。同时 RocketMQ Binder 将会适配 MessageSource 进行消息的拉取。
Spring Cloud Alibaba 从开源到发布第一个正式版本,受到了很多社区同学的关注。社区的每一个 Issue ,每一个 PR,都是对整个项目的帮助,都在为建设更好用的 Spring Cloud 添砖加瓦。我们希望有更多社区的同学加入进来,一起把项目做好。
我们真心地感谢为这个项目提出过 Issue 和 PR 的同学,以及这些 contributor:
@HaojunRen, @xiejiashuai, @mengxiangrui007, @yunzheng1228, @tigerMoon, @slievrly, @mostcool, @pig4cloud, @carlWangTao, @yanglbme, @codewaltz1994, @caojiele, @JakeConnors376W, @Harris2012, @justlive1, @毛建伟(wb-maojianwei) , @bluesword12350
最后还要特别感谢 Spring Cloud Alibaba 生态中的其他开源项目:
Dubbo
https://github.com/apache/incubator-dubbo
Seata
https://github.com/seata/seata
Sentinel
https://github.com/alibaba/sentinel
Nacos
https://github.com/alibaba/nacos
RocketMQ
https://github.com/apache/rocketmq
本文作者:
方剑(花名:洛夜)
GitHub ID @fangjian0423,开源爱好者,阿里巴巴高级开发工程师,阿里云产品 EDAS 开发,Spring Cloud Alibaba 开源项目负责人之一。
小马哥(mercyblitz)
GitHub ID @mercyblitz,Java 劝退师,Apache Dubbo PMC, Spring Cloud Alibaba 项目架构师。目前主要负责阿里巴巴中间件开源项目、微服务技术实施、架构衍进和基础设施构建等工作。
/ Spring Cloud Bus 消息总栈介绍 /
Photo by Adi Goldstein on Unsplash
©每周一推
第一时间获得下期分享
☟☟☟
Tips:
# 点下“在看”❤️
# 然后,公众号对话框内发送“浴巾“,试试手气??
# 本期奖品是来自淘宝心选的绵柔浴巾。