1. 什么是 Spring Cloud Alibaba ?答案:Spring Cloud Alibaba 是 Spring 官方认证的 Spring Cloud 实现,致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。依托 Spring Cloud Alibaba,您只需要添加一些注解和少量配置,就可以将 Spring Cloud 应用接入阿里分布式应用解决方案,通过阿里中间件来迅速搭建分布式应用系统。2. Spring Cloud Alibaba 实现了哪些 Spring Cloud 特性,对应的组件分别是什么?答案:3. Spring Cloud Alibaba 提供哪些阿里云商业化组件的支持?答案:Spring Cloud Alibaba 除提供开源组件之外,还支持阿里云商业化组件,以丰富微服务和云计算的 Spring 编程模型:具体请参考 Spring Cloud Alibaba 子工程:https://github.com/alibaba/aliyun-spring-boot/4. 请说明 Spring Cloud Alibaba Nacos Discovery 的核心特性有哪些?答案:Nacos Discovery 核心特性包括:Spring Cloud Commons 服务发现和发现Reactive 服务发现Spring Boot Actuator Endpoint 和 HealthIndicatorNetflix Ribbon(复杂均衡组件)Watch 特性(Spring Cloud 心跳事件)5. 请说明 Spring Cloud Alibaba Nacos Config 的核心特性有哪些?答案:Nacos Config 核心特性包括:Spring Cloud 动态配置源(PropertySourceLocator)Spring Cloud 配置动态更新(@RefreshScope 以及历史追踪)多种配置格式解析(Properties、YAML、XML 和 JSON 等)Nacos 连接诊断分析Spring Boot Actuator Endpoint 和 HealthIndicator6. 同为服务调用组件,请说明 Spring Cloud OpenFeign 与 Dubbo Spring Cloud 的相同点和区别?答案:相同点:编程模型面向 Java 接口编程(动态生成调用代理,屏蔽底层细节)注解驱动外部化配置异步调用REST 支持服务治理:负载均衡服务熔断失败重试服务链路追踪差异点:元信息:Spring Cloud OpenFeign 需要在 Java 接口上预置 Spring MVC 注解以实现 REST 服务路由,而 Dubbo Spring Cloud 仅需要 Java 方法签名即可实现服务路由。同时,后者还能在运行时获取 Dubbo 元信息能力版本支持:Spring Cloud OpenFeign 无法实现单个 Java 接口多版本支持,Dubbo Spring Cloud 可以同时支持多版本泛化调用:Spring Cloud OpenFeign 无法支持服务的泛化调用,而 Dubbo Spring Cloud 内建 GenericService 接口予以支持,类似于 Spring Cloud @LoadBalanced RestTemplate 特性通讯协议:Dubbo Spring Cloud 支持多种通讯协议,比如 dubbo、grpc、thrift 以及 REST, Spring Cloud OpenFeign 仅支持 REST扩展特性:Dubbo Spring Cloud 承继 Apache Dubbo 高扩展特性,包括通讯协议、序列化协议、负载均衡等7. 什么是 Dubbo 服务自省?答案:服务自省是 Dubbo 应用在运行时处理和分析 Dubbo 服务元信息(Metadata)的过程,如当前应用暴露 的Dubbo 服务以及各自的通讯协议等。期间会伴随着事件的广播和处理,如服务暴露事件。Dubbo 服务自省架构是其传统架的一种补充,更是未来 Dubbo 架构,它更适合以下使用场景:超大规模 Dubbo 服务治理场景微服务架构和元原生应用Dubbo 元数据架构的基石
一、简介分布式一致性是分布式系统亟需解决的关键问题之一,根据过去一年的调查问卷,在微服务的实践中分布式事务是用户遇到的最大痛点。目前市面缺少经过洪荒流量验证的分布式事务组件,Seata 在阿里经济体内部经过了漫长的孵化,承载了双 11 洪荒流量,实践证明 Seata 是一款解决分布式数据一致性的的优秀组件。Seata 于 2019 年正式对外开源,开源后就受到了大家的热情追捧,一度蝉联 GitHub 活跃排名榜首。Seata 除了提供了独创的 AT 事务模式外,还扩展了 TCC、Saga 和 XA 事务模式,满足大家对于不同业务场景中的需求。相关详细信息可参考其官网 Seata官网学习目标理解分布式事务在业务中的核心使用场景和常用解决方案理解 Seata AT 事务模式的核心原理掌握 Seata 作为分布式事务组件与 Spring Cloud 的整合如何扩展一个 RPC 框架Seata 实战二、为什么需要分布式事务?分布式事务不是在新架构下产生的新问题,即使在单体应用中同样存在着分布式事务问题,典型的场景是单体应用执行方法中含有多个数据源。X/OPEN 对于这一问题,提出了含有三种角色的 DTP(Distributed Transaction Processing)模型并形成了 XA 规范来解决此问题。各厂商针对 XA 规范做了具体的实现,也就是大家常说的 XA 协议。在 Java 体系中基于 DTP 模型提出了 JTA 规范(参考 JSR 907), 定义了分布式事务中的事务管理器(TM)与资源管理器(RM)、应用程序(AP)等的 Java 接口。在Java EE 时代,应用服务器如 weblogic 充当了 TM 的角色,而传统关系数据库通过实现 XA 协议充当了 RM 的角色。随着互联网的高速发展,庞大的用户群体和快速的需求变化已经成为了传统架构的痛点。在这种情况下,如何从系统架构的角度出发,构建出灵活、易扩展的系统来快速响应需求的变化,同时,随着用户量的增加,如何保证系统的稳定性、高可用性、可伸缩性等等,成为了系统架构面临的挑战。微服务基于此背景应运而生,微服务架构越来越来越成为一种架构趋势,其本质是分布式去中心化。但微服务架构绝不是银弹,它不一定是一种能支撑未来一二十年的架构,引入微服务架构时需要我们根据业务场景,系统复杂性和团队规模有步骤的进行。微服务架构的引入使分布式数据一致性问题更为突出,由原来的单体应用拆分出来几十甚至上百个微服务,如何保证服务间的一致性?当在一条较长的微服务调用链中,位于中间位置的微服务节点出现异常,如何保证整个服务的数据一致性?分布式一致性的引入,一定不可避免带来性能问题,如何更高效的解决分布式一致性问题,一直是我们致力于解决此问题的关键出发点。在“一切都正常”的情况下,我们可以认为我们并不需要分布式事务。但系统很难满足这种理想状态,系统可能因为一个非法的参数校验无法将服务链路继续向下调用下去,系统可能出现令人反感的超时问题,我们不清楚被调用的服务是否真正的执行了,被调用服务可能正在部署,网络抖动亦或者节点宕机导致接口无法继续调用。这些问题普遍存在于我们的系统中,业务的本质体现在数据上,数据不一致的直接后果是可能产生资损,更严重的是如果不一致的数据不能被及时发现,业务再次基于此数据的进行相关逻辑操作,会进一步导致数据错上加错,最终很难溯源。三、常见的分布式事务解决方案从是否满足事务 ACID 特性上,我们可以将事务分为两大类:刚性事务和柔性事务。在常见解决方案中 XA 事务属于刚性事务解决方案,而其他的大多数解决方案如 TCC、Saga、消息最终一致性则属于柔性事务解决方案。以下将对几种常见的事务方案做简要的介绍:消息最终一致性消息最终一致性方案是在 Seata 问世之前,市面上应用最广泛的一种解决方案。它本身具有削峰填谷,可异步化的优点,更多的适应于可异步化的末端链路消息通知场景。但是它本身也存在着一些缺点:需要依赖可靠消息组件,消息的可靠性很重要,大多数的原生消息组件故障时很难降级;实时性比较差,要经过多次网络 IO 开销和持久化,遇到队列积压情形实时性不可控;无法保证隔离性,在已发送消息和消息消费之前,中间数据对外可见,无法满足事务 isolate 特性;只能向前重试不可向后回滚,消息消费无法成功时无法回滚消息生产侧的数据;无法保证多条消息间的数据一致性。XAXA 标准提出后的 20 多年间未能得到持续的演进,在学术界有协议优化和日志协同处理等相关的研究,在工业界使用XA落地方案的相对较少,主要集中在应用服务器的场景。XA方案要求相关的厂商提供其具体协议的实现,目前大部分关系数据库支持了 XA 协议,但是支持程度不尽相同,例如,MySQL 在 5.7 才对 xa_prepare 语义做了完整支持。XA 方案被人诟病的是其性能,其实更为严重的是对于连接资源的占用,导致在高并发未有足够的连接资源来响应请求成为系统的瓶颈。在微服务架构下 XA 事务方案随着微服务链路的扩展成为一种反伸缩模式,进一步加剧了资源的占用。另外 XA 事务方案要求事务链路中的 resource 全部实现 XA 协议方可使用,若其中某一资源不满足,那么就无法保证整个链路的数据一致性。TCCTCC 方案要求用户根据业务场景实现 try,confirm,cancel 三个接口,由框架根据事务所处的事务阶段和决议来自动调用用户实现的三个接口。从概念上 TCC 框架可以认为是一种万能框架,但是其难点是业务对于这三个接口的实现,开发成本相对较高,有较多业务难以做资源预留相关的逻辑处理,以及是否需要在预留资源的同时从业务层面来保证隔离性。因此,这种模式比较适应于金融场景中易于做资源预留的扣减模型。Saga有了 TCC 解决方案为什么还需要 Saga 事务解决方案?上文提到了 TCC 方案中对业务的改造成本较大,对于内部系统可以自上而下大刀阔斧的推进系统的改造,但对于第三方的接口的调用往往很难推动第三方进行 TCC 的改造,让对方为了你这一个用户去改造 TCC 方案而其他用户并不需要,需求上明显也是不合理的。要求第三方业务接口提供正反接口比如扣款和退款,在异常场景下必要的数据冲正是合理的。另外,Saga 方案更加适应于工作流式的长事务方案并且可异步化。上面提到了4种常用的分布式事务解决方案,Seata 集成了TCC、Saga 和 XA 方案。另外,Seata 还提供了独创的 AT 强一致分布式事务解决方案。下文将对 AT 方案进行简要的介绍。三、AT 事务模式一个分布式事务有全局唯一的 xid,由若干个分支事务构成,每个分支事务有全局唯一的 branchId。上图展示了在一个分支事务中 RM 与 TC 的交互过程。其中主要包含的交互动作如下:branchRegister分布式事务一阶段执行,分支事务在 commit 之前与 TC 交互获取 全局锁 和返回 branchId。全局锁为 Seata 应用锁等同于修改数据记录的行锁,若获取锁失败将会进行锁重试,此处提供了两种重试策略是否持有数据库连接重试全局锁,默认为释放数据库连接。若成功,则抢占全局锁并返回 branchId,若重试到最大次数失败,则发起全局事务的回滚,对已完成的分支事务执行回滚。branchReport分布式事务一阶段执行,本地事务 commit 之后与 TC 交互,上报本地事务已完成标识。目前 branchReport 动作已经在 1.0 版本做了相关的优化,本地事务 commit 不上报,本地事务rollback 上报。经过优化分布式事务的整体性能在 globalCommit 场景下最低提升25%,最高提升50%。本地事务 rollback 上报可以帮助 TC 快速决策需要回滚的分支事务。branchCommit分布式事务二阶段执行,在形成 globalCommit 决议后执行。AT 模式中此步骤异步执行来提升其性能,可以认为分布式事务 globalCommit 决议提交到TC 释放完全局锁就已经完成了整个分布式事务的处理。branchCommit 在 AT 模式主要用于删除一阶段的 undo_log,TC 下发到 RM 后并不是立即执行,而是通过定时任务 + SQL 批量合并的方式来提升其处理性能。branchRollback分布式事务二阶段执行,在形成 globalRollback 决议后执行。RM 收到 branchRollback 请求,取 undo_log 表中对应的branchId 记录解析 rollback_info 字段,对现有数据和 undo log 后镜像对比,对比不同则分支事务回滚失败。对比成功则根据前镜像构造 SQL 并执行反向操作和删除 undo log。
五、Seata 与 Spring Cloud 集成如上图,Seata 与 Spring Cloud Alibaba 集成代码结构如上图所示。从代码上可以分为三大部分:rest、feign 和 web。AutoConfiguration 结尾的类是 @Configuration 类被 spring.factories 加载,负责创建 package 中所属的 bean。rest对应 restTemplate 调用,实现 ClientHttpRequestInterceptor 接口,将当前事务上下文包装到 HttpRequest header 中,加入到拦截器列表中。feign对应 openFeign 调用,这部分实现了事务上下文传递,与 Hystrix、Sentinel 、Ribbon 组件集成功能。需要特别注意是 Hystrix 中跨线程的事务上下文传递。这部分代码大量使用了Builder、Wrapper 模式,有兴趣的同学可深入阅读。web对应 Spring Web Servlet 中的处理,实现了 HandlerInterceptor 接口。在 preHandle 预处理中取 httpRequest header 中 Seata 的事务上下文并使用 API 绑定到当前线程的事务处理上下文中,这种后续的数据源操作就自动加入到了分布式事务的链路中;在 afterCompletion 中做了当前线程事务上下文的清除,防止事务上下文在线程中污染。六、如何扩展一个 RPC 框架?在上一节,我们讲到了 Seata 是如何与 Spring Cloud 相集成的。Seata 目前已经集成了 Spring Cloud、Alibaba Dubbo、Apache Dubbo、Motan、gRPC 和 sofa-RPC 等微服务调用。结合上一节与 Spring Cloud 的集成,扩展一个RPC 框架我们需要做哪些工作呢 ?主要可以分为两大部分:事务上下文传递Seata 的事务上下文目前主要包含:xid 和调用服务的分支事务类型。xid 为一个分布式事务的全局唯一标识,类似于 Tracing 中的 traceId,只有将 xid 传递下去才可能加入到分布式事务的链路中。调用服务的分支事务类型主要用于非 AT 模式,例如在一个 TCC 分支事务中不能再嵌套 AT 分支事务。主流的 RPC 框架大多是基于 TCP 协议之上的私有协议封装或者是基于 HTTP 协议。Seata 的事务上下文标识都是简单的字符串,序列化由 RPC 框架直接完成,大多数 RPC 框架实现了 filter 或者 interceptor 接口,通过将 Seata 的事务上下文填充到协议中的 attachment 字段或者 http header 中,就可以简单的完成事务上下文的传递。事务上下文绑定和清除在 RPC 的 provider 端收到 consumer 的请求,将事务上下文取出,通过 API 绑定到当前的执行线程中,这样后续的业务处理都纳入到了 Seata 的分布式事务链路中。执行完业务处理后,需要对绑定到当前线程的事务上下文清除掉,防止产生线程事务上下文污染。具体 API 可参考官网文档:https://seata.io/zh-cn/docs/user/api.html请大家思考一下如何去与 Dubbo 集成的呢?https://github.com/seata/seata/tree/develop/integration/dubbo七、Seata 实战本节将通过一个基于 Spring Cloud 的订单和库存服务进行 Seata 实战。我们在 沙箱环境 里准备好了一套 seata 的实际应用案例,服务调用结构如下所示:如图所示,服务链路中包含三个微服务:business(微服务入口)、order(订单服务)和 storage(库存服务)。业务逻辑通过 url 调用 business 服务,business 服务会通过 openFeign 的方式分别调用 storage 和 order 服务。每个服务调用后会根据正常(ok)或异常(fail)的返回值决定是否抛出异常,若返回结果不为 ok 那么 business 将抛出异常,触发整个事务回滚,预期数据至 business 方法执行前的数据并且库存总量和与初始值一致。当 order 和 storage 两个服务调用正常,用户可以根据 url 中的 mockException=true 或 false 来注入一个 mock 异常,当注入异常后,期望数据回滚至 business 方法执行前的数据并且库存总量和与初始值一致。异常模拟在 bussiness 中请求超过现有库存,通过参数 count 来指定要扣减的库存数量,当超出库存,将抛出异常进行事务回滚。在 bussiness 中请求中加入 mockException=true 参数,触发事务回滚。启动步骤以下请求 url 中的 localhost 请根据实际值进行替换。1.启动 order 和 storage 服务,最后启动 business 服务。服务的注册和发现,Seata 服务注册和发现 在这里使用了 Nacos 启动成功后,可以通过 Nacos 控制台的 sandbox-seata namespace 看到如下服务:2.访问 business 的url :http://localhost:8080/seata/check 来检查初始化数据3.通过访问 business 的url:http://localhost:8080/seata/feign?count=5&mockException=true 来触发业务逻辑:其中 count 代表扣减库存的数量,当库存不足将触发事务回滚;mockException 代表是否触发业务异常,设置为 true 会触发业务异常,并通过分布式事务实现回滚。4.每次操作完 business 请求后,访问 business 的 url :http://localhost:8080/seata/check 来检查操作后数据。5.重复以上 3(根据实际需要请求,不必每次请求相同),4 步骤,最后再次通过访问 business 的 url :http://localhost:8080/seata/check 来检查结果数据:使用总结1.引入依赖。com.alibaba.cloud:spring-cloud-starter-alibaba-seata 中包含了 io.seata:seata-spring-boot-starter 依赖。若于期望依赖 seata 的版本不一致,可手动排除重引入。com.alibaba.cloud 原生 版本说明。parent:<dependencyManagement> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>${alibaba.cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencyManagement> module: <dependencies> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-seata</artifactId> </dependency> </dependencies>2.添加配置文件,具体配置项说明参考 此处。seata: enabled: true application-id: business tx-service-group: my_test_tx_group config: type: nacos nacos: namespace: "sandbox-seata" serverAddr: 139.196.203.133:8848 group: SEATA_GROUP username: xxx password: xxx registry: type: nacos nacos: application: seata-server serverAddr: 139.196.203.133:8848 group: SEATA_GROUP namespace: "sandbox-seata" username: xxx password: xxx3.在所有业务库中创建 undo_log 表,不同的数据库类型脚本参考 此处 ,示例中已自动完成创建。4.在需要纳入分布式事务链路的入口 service 方法(保证可使 Spring 切面生效的位置亦可)上添加 @GlobalTransactional 注解。八、其他Seata 更多 sample 样例 ,请参考 样例Seata 社区联系方式,请参见 联系我们欢迎大家试用阿里云商业化产品 GTS,更高性能,更稳定,全面兼容 Seata。
近些年随着云技术的发展,越来越多的用户选择使用云技术来代替传统的 IT 基础设施。在云技术发展的早期,业界的关注点集中在虚拟化、分布式、存储等 Iaas 方面的技术。但是随着“云原生”概念的提出,大家的注意力开始转移到如何构建更加适合云环境运行的应用上来。“什么样的架构才是适合在云环境中运行”是一个非常大的问题,在此先不展开讨论,而是到 CNCF 对云原生的定义中寻找答案:云原生技术有利于各组织在公有云、私有云和混合云等新型动态环境中,构建和运行可弹性扩展的应用。云原生的代表技术包括容器、服务网格、微服务、不可变基础设施和声明式 API。这些技术能够构建容错性好、易于管理和便于观察的松耦合系统。结合可靠的自动化手段,云原生技术使工程师能够轻松地对系统作出频繁和可预测的重大变更。从上文的定义中可以发现“微服务”在云原生技术中占有这非常重要的位置。在 jakarta.ee 2019 年的调研报告中也印证了这一点,超过40%公司选择采用微服务架构来构建云上系统:我们继续把视角聚焦到 Java 语言下。Pivotal 依托于 Spring 这个 Java 语言下编程模型的事实标准,结合大量业界经验,为广大 Java 开发者带来了 Spring Cloud 框架。该框架是对云环境下微服务开发中需要解决的各种问题的标准化,以帮助开发者快速实现分布式系统中的某些常见模式(例如,配置管理,服务发现,断路器等)。同时,基于 Pivotal 强大的标准制定能力与影响力,Spring Cloud 拥有一个强大的国际化社区,阿里巴巴作为这个社区里重要的成员,也贡献出了 Spring Cloud Alibaba 这套优秀的实现,这也是目前整个 Spring Cloud 体系下最完善并且在持续更新的实现方案。
一、简介事件驱动架构(Event-driven 架构,简称 EDA)是软件设计领域内的一套程序设计模型。这套模型的意义是所有的操作通过事件的发送/接收来完成。举个例子,比如一个订单的创建在传统软件设计中服务端通过接口暴露创建订单的动作,然后客户端访问创建订单。在事件驱动设计里,订单的创建通过接收订单事件来完成,这个过程中有事件发送者和事件接受者这两个模块,事件发送者的作用是发送订单事件,事件接受者的作用的接收订单事件。Spring Cloud Stream 是一套基于消息的事件驱动开发框架,它提供了一套全新的消息编程模型,此模型屏蔽了底层具体消息中间件的使用方式。开发者们使用这套模型可以完成基于消息的事件驱动应用开发。学习目标掌握 Spring 对消息的编程模型封装掌握 RocketMQ 整合 Spring Cloud Stream 完成消息的发送和接收掌握 RocketMQ 整合 Spring Cloud Bus 完成远程事件的发送和接收详细内容概念理解:指导读者理解 Spring 的消息编程模型消息发送/接收:实战 Spring Cloud Steam RocketMQ Binder事件发送/接收: 实战 Spring Cloud Bus RocketMQ二、理解 Spring 消息编程模型首先我们来看这个场景,不同的消息中间件发送消息的代码:每个消息中间件都有自己的消息模型编程,他们的代码编写方式都不一致。同样地,在消息的订阅方面,也是不同的代码。这个时候如果某天想把 Kafka 切换到 RocketMQ,必须得修改大量代码。Spring 生态里有两个消息相关的模块和项目,分别是 spring-messaging 模块和 Spring Integration 项目,它们对消息的编程模型进行了统一,不论是 Apache RocketMQ 的 Message,或者是 Apache Kafka 的 ProducerRecord,都被统一称为 org.springframework.messaging.Message 接口。Message 接口有两个方法,分别是 getPayload 以及 getHeaders 用于获取消息体以及消息头。如图所示,这也意味着一个消息 Message 由 Header 和 Payload 组成:Payload 是一个泛型,意味是消息体可以放任意数据类型。Header 是一个 MessageHeaders 类型的消息头。有了消息之后,这个消息被发送到哪里呢?Spring 提供了消息通道 MessageChannel 的概念。消息可以被发送到消息通道里,然后再通过消息处理器 MessageHandler 去处理消息通道里的消息:消息处理这里又会遇到一个问题。如果消息通道里只有 1 个消息,但是消息处理器有 N 个,这个时候要被哪个消息处理器处理呢?这里又涉及一个消息分发器的问题。UnicastingDispatcher 表示单播的处理方式,消息会通过负载均衡被分发到某一个消息处理器上,BroadcastingDispatcher 表示广播的方式,消息会被所有的消息处理器处理。
一、简介服务注册与发现是微服务架构体系中最关键的组件之一。如果尝试着用手动的方式来给每一个客户端来配置所有服务提供者的服务列表是一件非常困难的事,而且也不利于服务的动态扩缩容。Nacos Discovery 可以帮助您将服务自动注册到 Nacos 服务端并且能够动态感知和刷新某个服务实例的服务列表。除此之外,Nacos Discovery 也将服务实例自身的一些元数据信息 - 例如 host,port,健康检查 URL,主页等内容注册到 Nacos。Nacos 的获取和启动方式可以参考 Nacos 官网。学习目标掌握 Nacos Discovery 实现 Spring Cloud 服务注册和发现掌握 Nacos Discovery 整合 Spring Cloud 负载均衡和服务调用理解 Nacos Discovery 高级特性:命名空间、安全控制、元数据、Nacos Watch 等详细内容快速上手:指导读者从使用 Nacos Discovery 进行服务注册/发现服务调用整合:实战 Nacos Discovery 整合 @LoadBalanced RestTemplate 以及 Open Feign运维特性:演示 Nacos Discovery 高级外部化配置以及 Endpoint 内部细节二、快速上手1.如何引入 Nacos Discovery 进行服务注册/发现Nacos Discovery 引入的方式通常有两种,由易到难分别为:Aliyun Java Initializr 引入和 Maven pom.xml 依赖。官方推荐使用 Aliyun Java Initializr 方式引入 Nacos Discovery,以便简化组件之间的依赖关系。[偷懒] 直接在沙箱里查看应用代码点击 链接,直接访问沙箱环境,这里会有为你准备好的案例代码 ^_^。[简单] 通过 Aliyun Java Initializr 创建工程并引入 Nacos Discovery(推荐)由于 Spring Cloud 组件的版本和依赖较为复杂,推荐读者使用 Aliyun Java Initializr 构建应用工程。下文以 Google Chrome 浏览器为例,当网页加载后,首先,在 “项目基本信息” 部分输入 Group :"com.alibaba.cloud" 以及 Artifact:"nacos-discovery-provider-sample"(见下图绿框部分)然而,“组件依赖” 输入框搜索:"Nacos"(见下图红箭头部分),最后,选择 "Nacos Service Discovery"(见下图红框部分),如下所示:Nacos Service Discovery 组件选择后,展开“示例代码”部分,选择合适的示例代码:由于“服务注册 & 发现”是两个独立的端,所以示例代码也被分为两个部分。通过点击“获取代码”来获得由平台生成的代码:点击 下载 按钮后,平台将生成一个名为 "nacos-discovery-provider-sample.zip" 的压缩文件,将其保存到本地目录,并解压该文件,工程目录将随之生成。打开目录下的 pom.xml 文件,不难发现 Nacos Discovery starter 声明其中(以下 XML 内容均来自于项目根路径中的 pom.xml 文件):XML <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency>不过该 starter 并未指定版本,具体的版本声明在 com.alibaba.cloud:spring-cloud-alibaba-dependencies 部分:XML <dependencyManagement> <dependencies> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>${spring-cloud-alibaba.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>其中,${spring-cloud-alibaba.version} 和 ${spring-boot.version} 分别为 Spring Cloud Alibaba 和 Spring Boot 组件依赖的版本,它们的版本定义在 <properties> 元素中,即 2.2.1.RELEASE 和 2.3.0.RELEASE:XML <properties> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-boot.version>2.3.0.RELEASE</spring-boot.version> <spring-cloud-alibaba.version>2.2.1.RELEASE</spring-cloud-alibaba.version> </properties>如果读者非常熟悉 Maven 依赖管理的配置方式,可以考虑 Maven pom.xml 依赖 Nacos Discovery。[高级] 通过 Maven pom.xml 依赖 Nacos Discovery如果要在您的项目中使用 Nacos 来实现服务注册/发现,使用 group ID 为 com.alibaba.cloud 和 artifact ID 为 spring-cloud-starter-alibaba-nacos-discovery 的 starter。XML<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency>该声明方式同样需要声明 com.alibaba.cloud:spring-cloud-alibaba-dependencies,内容与上小节相同,在此不再赘述。下一节将讨论如何使用 Nacos Discovery 进行服务注册/发现。2.使用 Nacos Discovery 进行服务注册/发现使用 Nacos Discovery 进行服务注册/发现与传统 Spring Cloud 的方式并没有本质区别,仅需添加相关外部化配置即可工作。换言之,Nacos Discovery 不会侵入应用代码,方便应用整合和迁移,这归功于 Spring Cloud 的高度抽象。如果读者熟悉 Spring Cloud 服务注册和发现的话,通常需要将注册中心预先部署,Nacos Discovery 也不例外。启动 Nacos 服务器具体启动方式参考 Nacos 官网。Nacos Server 启动后,进入 http://ip:8848 查看控制台(默认账号名/密码为 nacos/nacos):关于更多的 Nacos Server 版本,可以从 release 页面 下载最新的版本。启动服务提供者(Provider)增加 Maven 依赖回到之前构建的应用 nacos-discovery-provider-sample,在此基础增加 Spring WebMVC 以及 Spring Boot Actuator Starter 依赖:XML <dependencies> <!-- Spring WebMVC Starter --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Spring Boot Actuator Starter --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> ... </dependencies>增加 Nacos Discovery 外部化配置Nacos 基本的配置需要添加到 application.properties(也可以是 application.yaml )文件中。application.proeprties 文件已被 Aliyun Java Initializr 生成,内容如下:spring.application.name=nacos-discovery-provider-sample management.endpoints.jmx.exposure.include=* management.endpoints.web.exposure.include=* management.endpoint.health.show-details=always # spring cloud access&secret config # 可以访问如下地址查看: https://usercenter.console.aliyun.com/#/manage/ak alibaba.cloud.access-key=**** alibaba.cloud.secret-key=**** # 应用服务 WEB 访问端口 server.port=8080 # Actuator Web 访问端口 management.server.port=8081增加 NacosDiscovery 配置,如下所示:spring.application.name=nacos-discovery-provider-sample management.endpoints.jmx.exposure.include=* management.endpoints.web.exposure.include=* management.endpoint.health.show-details=always # spring cloud access&secret config # 可以访问如下地址查看: https://usercenter.console.aliyun.com/#/manage/ak alibaba.cloud.access-key=**** alibaba.cloud.secret-key=**** # 应用服务 WEB 访问端口 server.port=8080 # Actuator Web 访问端口 management.server.port=8081 ## Nacos 注册中心配置地址(无需配置 HTTP 协议部分) spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848 ## Nacos 客户端认证信息(默认用户名和密码均为 nacos) spring.cloud.nacos.discovery.user-name=nacos spring.cloud.nacos.discovery.password=naocs请注意,Nacos 服务器默认关闭认证,建议在生产环境开启,详情请参考此 Blog。激活 Nacos Discovery 服务注册与发现Aliyun Java Initializr 默认不会自动激活 Nacos Discovery 服务注册与发现,需要在引导类(main 方法所在类)标注 Spring Cloud 服务注册与发现标准注解@EnableDiscoveryClient,代码如下所示:Javaimport org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @SpringBootApplication @EnableDiscoveryClient public class NacosDiscoveryProviderSampleApplication { public static void main(String[] args) { SpringApplication.run(NacosDiscoveryProviderSampleApplication.class, args); } }启动引导类启动引导类 NacosDiscoveryProviderSampleApplication,观察控制台输出(隐藏时间部分的内容):[ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' [ main] c.a.c.n.registry.NacosServiceRegistry : nacos registry, DEFAULT_GROUP nacos-discovery-provider-sample 30.225.19.241:8080 register finished [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8081 (http) [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat] [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.35] [ main] o.a.c.c.C.[Tomcat-1].[localhost].[/] : Initializing Spring embedded WebApplicationContext [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 176 ms [ main] o.s.b.a.e.web.EndpointLinksResolver : Exposing 18 endpoint(s) beneath base path '/actuator' [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8081 (http) with context path '' [ main] .NacosDiscoveryProviderSampleApplication : Started NacosDiscoveryProviderSampleApplication in 3.037 seconds (JVM running for 3.615)按照日志的描述,应用使用了 Tomcat 作为 Web 服务器,并且将 8080 和 8081 作为应用服务和 Actuator Web 端口。同时, "c.a.c.n.registry.NacosServiceRegistry : nacos registry, DEFAULT_GROUP nacos-discovery-provider-sample 30.225.19.241:8080 register finished" 表明服务实例注册成功,其 IP 为 30.225.19.241,服务端口为 8080。下一步,观察 Nacos 控制台 注册情况。观察 Nacos 控制台服务注册打开 Nacos 控制台中的“服务列表”,点击“查询”按钮,观察页面的变化:其中应用 nacos-discovery-provider-sample 出现在列表中,说明该应用已成功注册。至此,使用 Nacos Discovery 进行服务注册/发现演示完毕。接下来的示例将变得更为复杂,实现 Spring Cloud 服务调用。如果不想使用 Nacos 作为您的服务注册与发现,可以将 spring.cloud.nacos.discovery 设置为 false。
一、简介Nacos 提供用于存储配置和其他元数据的 key/value 存储,为分布式系统中的外部化配置提供服务器端和客户端支持。使用 Spring Cloud Alibaba Nacos Config,您可以在 Nacos Server 集中管理你 Spring Cloud 应用的外部属性配置。Spring Cloud Alibaba Nacos Config 是 Config Server 和 Client 的替代方案,客户端和服务器上的概念与 Spring Environment 和 PropertySource 有着一致的抽象,在特殊的 bootstrap 阶段,配置被加载到 Spring 环境中。当应用程序通过部署管道从开发到测试再到生产时,您可以管理这些环境之间的配置,并确保应用程序具有迁移时需要运行的所有内容。Nacos 的获取和启动方式可以参考 Nacos 官网。注:如果读者是阿里云商业化组件 ANS 或 ACM 用户,请使用 Nacos Config 代替对应的组件。学习目标使用 Nacos Config 作为 Spring Cloud 分布式配置使用 Nacos Config 实现 Bean 动态刷新了解 Nacos Config 高级配置详细内容快速上手:使用 Nacos Config 作为外部化配置源多文件扩展名支持:以 YAML 文件扩展名为例,讨论 Nacos Config 多文件扩展名支持动态配置更新:演示 @RefreshScope 特性,实现 Bean 动态刷新自定义扩展:自定义 namespace、Group 以及 Data Id 的配置扩展运维特性:演示 Nacos Config 高级外部化配置以及 Endpoint 内部细节二、快速上手下面会介绍如何使用 Nacos Config 支持和实现分布式配置。如何引入 Nacos Config 支持分布式配置Nacos Config 引入的方式同样也有两种,即 Aliyun Java Initializr 引入和 Maven pom.xml 依赖。官方推荐使用 Aliyun Java Initializr 方式引入 Nacos Discovery,以便简化组件之间的依赖关系。[偷懒] 直接在沙箱里查看应用代码点击 链接,直接访问沙箱环境,这里会有为你准备好的案例代码^_^。[简单] 通过 Aliyun Java Initializr 创建工程并引入 Nacos Config(推荐)由于 Spring Cloud 组件的版本和依赖较为复杂,推荐读者使用 Aliyun Java Initializr 构建应用工程。读者选择偏好的 Web 浏览器访问 Aliyun Java Initializr,其资源网址为:https://start.aliyun.com/bootstrap.html下文以 Google Chrome 浏览器为例,当网页加载后,首先,在 "项目基本信息" 部分输入 Group :“com.alibaba.cloud” 以及 Artifact:“nacos-config-sample”。然后,“组件依赖” 输入框搜索:“Nacos Config”,选择 "Nacos Configuration",如下所示:同上组件操作,增加 “Spring Web” 和 “Spring Boot Actuator” 组件:组件选择后,点击 “生成” 高亮按钮。随后,平台将生成一个名为 “nacos-config-sample.zip” 的压缩文件,将其保存到本地目录,并解压该文件,工程目录将随之生成。打开目录下的 pom.xml 文件,不难发现 Nacos starter 声明其中(以下 XML 内容均来自于项目根路径中的 pom.xml 文件):XML <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency>不过该 starter 并未指定版本,具体的版本声明在 com.alibaba.cloud:spring-cloud-alibaba-dependencies 部分:XML <dependencyManagement> <dependencies> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>${spring-cloud-alibaba.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>其中,${spring-cloud-alibaba.version} 和 ${spring-boot.version} 分别为 Spring Cloud Alibaba 和 Spring Boot 组件依赖的版本,它们的版本定义在 <properties>元素中,即 2.2.1.RELEASE 和 2.3.0.RELEASE:XML <properties> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-boot.version>2.3.0.RELEASE</spring-boot.version> <spring-cloud-alibaba.version>2.2.1.RELEASE</spring-cloud-alibaba.version> </properties>如果读者非常熟悉 Maven 依赖管理的配置方式,可以考虑 Maven pom.xml 依赖 Nacos Config。[高级] 通过 Maven pom.xml 依赖 Nacos Config如果要在您的项目中使用 Nacos 来实现服务注册/发现,使用 group ID 为 com.alibaba.cloud和 artifact ID 为 spring-cloud-starter-alibaba-nacos-config的 starter。XML<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency>该声明方式同样需要声明 com.alibaba.cloud:spring-cloud-alibaba-dependencies,内容与上小节相同,在此不再赘述。下一节将讨论如何使用 Nacos Config 支持分布式配置。使用 Nacos Config 实现分布式配置使用 Nacos Config 实现分布式配置与 Spring Cloud Consul 和 Spring Cloud Zookeeper 的方式非常类似,仅需添加相关外部化配置即可工作。换言之,Nacos Config 同样不会侵入应用代码,方便应用整合和迁移,如果读者熟悉 Spring Cloud Consul 或 Spring Cloud Zookeeper 使用方式 的话,通常需要将 Consul 或 Zookeeper 服务进程预先部署,Nacos Config 也如此。启动 Nacos 服务器我们为开发者提供了一套免费的 Nacos Server :进入 http://139.196.203.133:8848/nacos/ 查看控制台(账号名/密码为 nacos-configuration/nacos-configuration),选择 "配置管理/配置列表":由于服务是公共免费的,为了做好隔离,所以分布式配置的功能,请选择在 sandbox-configuration 的命名空间下操作。具体启动方式参考 Nacos 官网。关于更多的 Nacos Server 版本,可以从 release 页面 下载最新的版本。添加 Nacos 配置点击“配置列表”页面右侧的 "+" 号(红色箭头所指):)浏览器跳转新页面,并填充内容如下:其中,Data ID 由应用名(nacos-config-sample)+ 文件后缀名(.properties) 组成,点击“发布”按钮(红色箭头所指),配置内容为user.name=nacos-config-sample user.age=90发布成功后,控制台会出现提示弹出框。特别提醒图片中的 Data ID 中的应用名,使用的是 nacos-config-sample 。如果使用我们提供的 Nacos Server ,由于多个用户同时使用,可能存在应用名冲突的问题。建议修改为跟别人都不重复的应用名:spring.application.name=xxxxxx替换上面的 xxxxx 部分配置应用 Nacos Config Server 地址回到应用 nacos-config-sample 工程,在 resources 目录下新建名为 “bootstrap.properties" 文件,并配置以下内容:spring.cloud.nacos.config.server-addr=139.196.203.133:8848 spring.cloud.nacos.config.username=nacos-configuration spring.cloud.nacos.config.password=nacos-configuration spring.cloud.nacos.config.namespace=sandbox-configuration注意,Nacos Server 地址必须配置在 bootstrap.properties 文件。注意当你使用域名的方式来访问 Nacos 时, spring.cloud.nacos.config.server-addr 配置的方式为域名:port。 例如 Nacos 的域名为abc.com.nacos,监听的端口为 80,则 spring.cloud.nacos.config.server-addr=abc.com.nacos:80。 注意 80 端口不能省略。添加读取 Nacos Config 实现修改 nacos-config-sample 引导类,如下所示:Java@SpringBootApplication public class NacosConfigSampleApplication { @Value("${user.name}") private String userName; @Value("${user.age}") private int userAge; @PostConstruct public void init() { System.out.printf("[init] user name : %s , age : %d%n", userName, userAge); } public static void main(String[] args) { SpringApplication.run(NacosConfigSampleApplication.class, args); } }启动 Nacos Config 应用运行 nacos-config-sample 引导类 NacosConfigSampleApplication,观察控制台结果(截取关键日志信息):Bash[init] user name : nacos-config-sample , age : 90如果在沙箱内启动应用,由于暂时还无法看到运行时的日志,可以通过WEB 控制器的方式查看参数,具体操作见 5.1 节。1.如何引入 Nacos Config 支持分布式配置Nacos Config 引入的方式同样也有两种,即 Aliyun Java Initializr 引入和 Maven pom.xml 依赖。官方推荐使用 Aliyun Java Initializr 方式引入 Nacos Discovery,以便简化组件之间的依赖关系。2.使用 Nacos Config 实现分布式配置使用 Nacos Config 实现分布式配置与 Spring Cloud Consul 和 Spring Cloud Zookeeper 的方式非常类似,仅需添加相关外部化配置即可工作。换言之,Nacos Config 同样不会侵入应用代码,方便应用整合和迁移,如果读者熟悉 Spring Cloud Consul 或 Spring Cloud Zookeeper 使用方式 的话,通常需要将 Consul 或 Zookeeper 服务进程预先部署,Nacos Config 也如此。
Nacos Config 内部提供了一个 Endpoint, 对应的 Endpoint ID 为 nacos-config,其 Actuator Web Endpoint URI 为 /actuator/nacos-config注:使用 Nacos Config Spring Cloud 1.x 版本的话,其 URI 地址则为 /nacos-config其中,Endpoint 暴露的 Json 中包含了三种属性:NacosConfigProperties: 当前应用 Nacos 的基础配置信息RefreshHistory: 配置刷新的历史记录Sources: 当前应用配置的数据信息由于 Aliyun Java Initializr 所生成的应用工程默认激活 Spring Boot Actuator Endpoints(JMX 和 Web),具体配置存放在 application.properties 文件中,同时,Actuator Web 端口设置为 8081,内容如下:management.endpoints.jmx.exposure.include=* management.endpoints.web.exposure.include=* management.endpoint.health.show-details=always # Actuator Web 访问端口 management.server.port=8081因此,应用 nacos-config-sample 无需调整,直接访问:http://127.0.0.1:8081/actuator/nacos-config,服务响应的内容如下:Json{ "NacosConfigProperties": { "serverAddr": "127.0.0.1:8848", "username": "", "password": "", "encode": null, "group": "DEFAULT_GROUP", "prefix": null, "fileExtension": "properties", "timeout": 3000, "maxRetry": null, "configLongPollTimeout": null, "configRetryTime": null, "enableRemoteSyncConfig": false, "endpoint": null, "namespace": null, "accessKey": null, "secretKey": null, "contextPath": null, "clusterName": null, "name": null, "sharedConfigs": null, "extensionConfigs": null, "refreshEnabled": true, "sharedDataids": null, "refreshableDataids": null, "extConfig": null, "configServiceProperties": { "secretKey": "", "namespace": "", "username": "",
一、Spring Cloud Stream 是一套基于消息的事件驱动开发框架。Spring Cloud Stream 在 Spring Integration 项目的基础上再进行了一些封装,提出一些新的概念,让开发者能够更简单地使用这套消息编程模型。如图所示,这是三者之间的关系:如下图所示,这是 Spring Cloud Stream 的编程模型。通过 RabbitMQ Binder 构建 input Binding 用于读取 RabbitMQ 上的消息,将 payload 内容转成大写再通过 Kafka Binder 构建的 output Binding 写入到 Kafka 中。图上中间的 4 行非常简单的代码就可以完成从 RabbitMQ 读取消息再写入到 Kafka 的动作。以下代码是使用 Spring Cloud Stream 以最简单的方式完成消息的发送和接收:@SpringBootApplication@EnableBinding({Source.class, Sink.class}) // ① public class SCSApplication { public static void main(String[] args) { new SpringApplicationBuilder().sources(SCSApplication.class) .web(WebApplicationType.NONE).run(args); } @Autowired Source source; // ② @Bean public CommandLineRunner runner() { return (args) -> { source.output().send(MessageBuilder.withPayload("custom payload").setHeader("k1", "v1").build()); // ③ }; } @StreamListener(Sink.INPUT) // ④ @SendTo(Source.OUTPUT) // ⑤ public String receive(String msg) { return msg.toUpperCase(); } }使用 @EnableBinding 注解,注解里面有两个参数 Source 和 Sink,它们都是接口。Source 接口内部有个 MessageChannel 类型返回值的 output 方法,被 @Output 注解修饰表示这是一个 Output Binding;Sink 接口内部有个 SubscribableChannel 类型返回值的 intput 方法,被 @Input 注解修饰表示这是一个 Input Binding。@EnableBinding 注解会针对这两个接口生成动态代理。注入 @EnableBinding 注解对于 Source 接口生成的动态代理。使用 @EnableBinding 注解对于 Source 接口生成的动态代理内部的 MessageChannel 发送一条消息。最终消息会被发送到消息中间件对应的 topic 里。@StreamListener 注解订阅 @EnableBinding 注解对于 Sink 接口生成的动态代理内部的 SubscribableChannel 中的消息,这里会订阅到消息中间件对应的 topic 和 group。消息处理结果发送到 @EnableBinding 注解对于 Source 接口生成的动态代理内部的 MessageChannel。最终消息会被发送到消息中间件对应的topic 里。上述代码需要配置信息:spring.cloud.stream.bindings.input.destination=test-input spring.cloud.stream.bindings.input.group=test-input-binder spring.cloud.stream.bindings.input.binder=kafka spring.cloud.stream.bindings.output.destination=test-output spring.cloud.stream.bindings.output.binder=rocketmq这里的 Input Binding 对应的 topic 是 test-input,group 是 test-input-binder,对应的 MQ 是 Kafka,Output Binding 对应的 topic 是 test-output,对应的 MQ 是 RocketMQ。所以这段代码的意思是 以 test-input-binder 这个 group 去 Kafka 上读取 test-input 这个 topic 下的消息,把消息的内容转换成大写再发送给 RocketMQ 的 test-output topic 上。当然,你也可以直接通过 沙箱环境 直接查看案例
从 Spring 到 Spring CloudSpring熟悉 java 语言的同学,对 Spring 框架应该都不陌生。从 2004 年 1.0 版本发布开始,便由于其灵活易用的特性受到了整个 Java 行业的广泛关注。经过十多年的发展,Spring 框架早已经成为 Java 语言下编程模型的事实标准。其所倡导的 IOC/AOP 概念也早已深入人心。在 Spring 框架的早期,大家都喜欢称其为“轻量化”框架(现在好像早就没人提这个词了^_^),“轻量”是相对于 EJB 等企业级开发框架而言的。其“轻”的特性体现在:框架本身的大小很小,早期版本的jar包不超过1MB;同时不依赖于运行容器,也是说任何容器里都可以运行Spring框架;更加重要的是 Spring 是非侵入的,使用Spring开发的应用可以不完全依赖Spring的类;Spring Boot但是事情总会发生变化,随着 Spring 的不断发展,越来越多的组件被集成到了框架中。Spring 框架也从一个小巧精简的 IOC 容器框架变成了一套大而全的框架集合。开发者为了实现组件的整合工作,往往需要在大量的 xml 文件、java 注解 中完成各种 bean 的配置。曾经屠龙的少年,如今也变成了恶龙。那个时候,很多比 Spring 更加简单小巧的 IOC 容器如雨后春笋般的出现。业界开始出现一种声音:Spring 是不是已经不行了,或者是在走下坡路了。就在这个时候 Pivotal 推出了 Spring Boot 来彻底的解决这些问题。使用 Spring Boot 可以大大简化 Spring 应用的开发工作。在 Spring Boot 中无论是官方组件还是第三方框架都会提供各种“starter”来方便开发者进行依赖和集成。由于采用了“约定大于配置”的思想,开发者在引入“stater”以后只需要做少量的配置工作就可以完成框架集成工作。往往开发者只需要很少量的代码就可以实现以前大量配置文件才能做到的功能。同时 Spring Boot 还是一套面向生产环境设计的框架。配置外化、运行情况检查功能,可以很方便的在系统外部实现对系统的管理。同时 Spring Boot 还是一个运行时容器。通过内嵌 Tomcat 、Jetty 等使得程序的运行不在依赖传统的应用服务器。这一点在云原生时代意义尤其重大。Spring 官方对 Spring Boot 特色定义如下:创建独立的Spring应用程序直接嵌入Tomcat,Jetty或Undertow(无需部署WAR文件)提供自以为是的“starter”依赖项,以简化构建配置尽可能自动配置Spring和三方类库提供可用于生产的功能,例如指标,运行状况检查和外部化配置完全没有代码生成,也不需要XML配置Spring CloudSpring Cloud 是什么,没有比官方的定义更能说明问题了:Spring Cloud provides tools for developers to quickly build some of the common patterns in distributed systems (e.g. configuration management, service discovery, circuit breakers, intelligent routing, micro-proxy, control bus, one-time tokens, global locks, leadership election, distributed sessions, cluster state). Coordination of distributed systems leads to boiler plate patterns, and using Spring Cloud developers can quickly stand up services and applications that implement those patterns. They will work well in any distributed environment, including the developer’s own laptop, bare metal data centres, and managed platforms such as Cloud Foundry.这里面提到几个关键词:分布式系统中的常见模式任何分布式环境“分布式系统中的常见模式”给了 Spring Cloud 一个清晰的定位,即“模式”。也就是说 Spring Cloud 是针对分布式系统开发所做的通用抽象,是标准模式的实现。这个定义非常抽象,看完之后并不能知道 Spring Cloud 具体包含什么功能。再来看一下 Spring 官方给出的一个 High Light 的架构图,就可以对这套模式有更清晰的认识:可以看到这个图中间就是各个Microservice,也就是我们的这个微服务的实现,周边周围的话就是去围绕这个微服务来去做各种辅助的信息事情。例如分布式追踪、服务注册、配置服务等,都绕微服务运行时所依赖的必不可少的的支持性功能。我们可以得出这样一个结论:Spring Cloud 是以微服务为核心的分布式系统的一个构建标准。Spring Cloud Alibaba既然说 Spring Cloud 是标准,那么自然少不了针对标准的实现。参与这个标准实现的公司有很多,例如:Google 的 Spring Cloud GCP,Netflix 的 Spring Cloud Netflix,Microsoft 的 Spring Cloud Azure 等等。当然还有我们阿里巴巴的 Spring Cloud Alibaba。Spring Cloud Alibaba 从 19 年初开始提交代码就获得了业界的广泛关注,从下面这张图中可以看到,在很短的时间之内,Spring Cloud Alibaba 就成为了 Spring Cloud 家族中最受关注的框架:下面这张图很好的说明了 Spring Cloud Alibaba 的组成以及与 Spring Cloud 的关系:图中深色的部分,其实它就是 Spring Cloud 标准,一共有 3 层。中间颜色最深的部分是微服务的核心组件,包括了“ RPC 调用”以及“服务注册与发现”。第二层,也就是围绕着核心的这一圈,是一些辅助微服务更好的工作功能,包括了负载均衡、路由、网关、断路器,还有分布式追踪等等这些内容。再外层的话,主要是些分布式云环境里通用能力。最外面这一圈,是 Spring Cloud Alibaba 对 Spring Cloud 的实现。右上部分是对于 Spring Cloud 标准的实现。例如,我们通过 Dubbo 实现了 RPC 调用功能,通过 Nacos 实现了“服务注册与发现”、“分布式配置”,通过 Sentinel 实现了断路器等等,这里就不一一列举了。左下部分是我们 Spring Cloud Alibaba 对阿里云各种服务的集成。可能很多同学会有这样的一个问题:为什么要加上这一部分呢?此时回头审视一下 Spring Cloud ,它仅仅是一个微服务的一个框架。但是在实际生产过程中,单独使用微服务框架其实并不足以支撑我们去构建一个完整的系统。所以这部分是用阿里帮助开发者完成微服务以外的云产品集成的功能。为什么要分成两个部分呢,这也是为了打消大家对于使用了 Spring Cloud Alibaba 以后就会被平台绑定的担忧。虽然在品牌商都叫做SpringCloudAlibaba,但是在代码上,我们采用了两个独立的项目维护。分别是 Spring Cloud Alibaba 和 Aliyun Spring Boot目前,Spring Cloud Alibaba 包含如下组件:开源部分Sentinel:把流量作为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。Nacos:一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。RocketMQ:一款开源的分布式消息系统,基于高可用分布式集群技术,提供低延时的、高可靠的消息发布与订阅服务。Dubbo:Apache Dubbo 是一款高性能 Java RPC 框架。Seata:阿里巴巴开源产品,一个易于使用的高性能微服务分布式事务解决方案。平台服务部分Alibaba Cloud OSS: 阿里云对象存储服务(Object Storage Service,简称 OSS),是阿里云提供的海量、安全、低成本、高可靠的云存储服务。您可以在任何应用、任何时间、任何地点存储和访问任意类型的数据。Alibaba Cloud SchedulerX: 阿里中间件团队开发的一款分布式任务调度产品,提供秒级、精准、高可靠、高可用的定时(基于 Cron 表达式)任务调度服务。Alibaba Cloud SMS: 覆盖全球的短信服务,友好、高效、智能的互联化通讯能力,帮助企业迅速搭建客户触达通道。