Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用微服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。 依托 Spring Cloud Alibaba,只需要添加一些注解和少量配置,就可以将 Spring Cloud 应用接入阿里微服务解决方案,通过阿里中间件来迅速搭建分布式应用系统。
SpringCloud Alibaba 主要功能
服务限流降级 :默认支持 WebServlet、WebFlux, OpenFeign、RestTemplate、Spring Cloud Gateway, Zuul, Dubbo 和 RocketMQ 限流降级功能的接入,可以在运行时通过控制台实时修改限流降级规则,还支持查看限流降级 Metrics 监控。
服务注册与发现 :适配 Spring Cloud 服务注册与发现标准,默认集成了 Ribbon 的支持。
分布式配置管理 :支持分布式系统中的外部化配置,配置更改时自动刷新。
消息驱动能力 :基于 Spring Cloud Stream 为微服务应用构建消息驱动能力。
分布式事务 :使用 @GlobalTransactional 注解, 高效并且对业务零侵入地解决分布式事务问题。
阿里云对象存储 :阿里云提供的海量、安全、低成本、高可靠的云存储服务。支持在任何应用、任何时间、任何地点存储和访问任意类型的数据。
分布式任务调度 :提供秒级、精准、高可靠、高可用的定时(基于 Cron 表达式)任务调度服务。同时提供分布式的任务执行模型,如网格任务。网格任务支持海量子任务均匀分配到所有 Worker(schedulerx-client)上执行。
阿里云短信服务 :覆盖全球的短信服务,友好、高效、智能的互联化通讯能力,帮助企业迅速搭建客户触达通道。
组件 **Sentinel **:把流量作为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
**Nacos **:一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。
**RocketMQ **:一款开源的分布式消息系统,基于高可用分布式集群技术,提供低延时的、高可靠的消息发布与订阅服务。
**Dubbo **:Apache Dubbo™ 是一款高性能 Java RPC 框架。
**Seata **:阿里巴巴开源产品,一个易于使用的高性能微服务分布式事务解决方案。
Alibaba Cloud OSS : 阿里云对象存储服务(Object Storage Service,简称 OSS),是阿里云提供的海量、安全、低成本、高可靠的云存储服务。您可以在任何应用、任何时间、任何地点存储和访问任意类型的数据。
Alibaba Cloud SchedulerX : 阿里中间件团队开发的一款分布式任务调度产品,提供秒级、精准、高可靠、高可用的定时(基于 Cron 表达式)任务调度服务。
Alibaba Cloud SMS : 覆盖全球的短信服务,友好、高效、智能的互联化通讯能力,帮助企业迅速搭建客户触达通道。
如何使用 引入依赖 在electricity-common
模块引入依赖。
<dependencyManagement > <dependencies > <dependency > <groupId > com.alibaba.cloud</groupId > <artifactId > spring-cloud-alibaba-dependencies</artifactId > <version > 2021.1</version > <type > pom</type > <scope > import</scope > </dependency > </dependencies > </dependencyManagement >
版本管理规范 项目的版本号格式为 x.x.x 的形式,其中 x 的数值类型为数字,从 0 开始取值,且不限于 0~9 这个范围。项目处于孵化器阶段时,第一位版本号固定使用 0,即版本号为 0.x.x 的格式。
由于 Spring Boot 1 和 Spring Boot 2 在 Actuator 模块的接口和注解有很大的变更,且 spring-cloud-commons 从 1.x.x 版本升级到 2.0.0 版本也有较大的变更,因此springcloud alibaba
采取跟SpringBoot
版本号一致的版本:
1.5.x 版本适用于 Spring Boot 1.5.x
2.0.x 版本适用于 Spring Boot 2.0.x
2.1.x 版本适用于 Spring Boot 2.1.x
2.2.x 版本适用于 Spring Boot 2.2.x
2021.x 版本适用于 Spring Boot 2.4.x
Nacos Discovery 接入 Nacos Discovery
在electricity-common
模块的 pom.xml 文件中引入Nacos Discovery Starter
。
<dependency > <groupId > com.alibaba.cloud</groupId > <artifactId > spring-cloud-starter-alibaba-nacos-discovery</artifactId > </dependency >
在electricity-coupon
模块的application.yml
文件中添加 nacos 的服务地址和应用名称
spring: cloud: nacos: discovery: server-addr: 127.0 .0 .1 :8848 application: name: electricity-coupon
在启动类上加入@EnableDiscoveryClient
注解开启服务注册与发现功能
@SpringBootApplication @EnableDiscoveryClient public class ElectricityCouponApplication { public static void main (String[] args) { SpringApplication.run(ElectricityCouponApplication.class, args); } }
启动 Nacos Server
在 github 上下载 Nacos Server 。
将下载好的压缩包解压出来,修改 bin 目录下的start.cmd
文件。nacos server 配置的默认是集群启动,本机电脑上我们以单机的方式启动,所以要修改为单机模式。
# 将 cluster修改为 standalone set MODE ="standalone"
双击start.cmd
文件,启动 nacos server。
linux/mac 等类 unix 系统,启动start.sh
文件。
sh startup.sh -m standalone
启动刚才配置 nacos 的electricity-coupon
模块。
验证 在浏览器输入http://127.0.0.1:8848/nacos
,输入用户名和密码(都是nacos)进入控制台,可以看到已经注册的服务。
Feign Feign 是一个声明式的 HTTP 客户端,他的目的就是让远程调用更加简单。给远程服务发的是 HTTP 请求。
这里测试会员服务远程调用优惠券服务。
引入 maven 依赖 openfeign 的依赖在创建项目时已经导入,如果没有引入,在各个微服务模块中都需要导入。
<dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-openfeign</artifactId > </dependency >
生成优惠券 在electricity-coupon
模块模拟优惠券,供会员模块调用。
@RestController @RequestMapping("coupon/coupon") public class CouponController { @Autowired private CouponService couponService; @RequestMapping("/member/list") public R memberCoupon () { CouponEntity coupon = new CouponEntity (); coupon.setCouponName("满199减100" ); return R.ok().put("coupons" , Arrays.asList(coupon)); } }
创建远程调用客户端接口 远程调用客户端告诉 springCloud 将要调用 coupon 服务的各种模块。
@FeignClient("electricity-coupon") public interface CouponFeignService { @RequestMapping("/coupon/coupon/member/list") public R memberCoupon () ; }
开启远程调用服务 在会员服务启动类上卡其远程调用服务。
@SpringBootApplication @EnableDiscoveryClient @EnableFeignClients(basePackages = "com.laughing.electricity.member.feign") public class ElectricityMemberApplication { public static void main (String[] args) { SpringApplication.run(ElectricityMemberApplication.class, args); } }
测试远程调用 @RestController @RequestMapping("member/member") public class MemberController { @Autowired CouponFeignService couponFeignService; @RequestMapping("/coupons") public R test () { MemberEntity memberEntity = new MemberEntity (); memberEntity.setNickname("杰哥不要啊" ); R memberCoupon = couponFeignService.memberCoupon(); return R.ok().put("member" , memberEntity).put("coupons" , memberCoupon.get("coupons" )); } }
如果你配置的 springboot 和 springcloud 版本比较高,启动项目时会报下面的错误。 No Feign Client for loadBalancing defined. Did you forget to include spring-cloud-starter-loadbalancer?
解决方案:将electricity-common
模块中的 springcloud 依赖修改一下。
<dependency > <groupId > com.alibaba.cloud</groupId > <artifactId > spring-cloud-starter-alibaba-nacos-discovery</artifactId > <exclusions > <exclusion > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-netflix-ribbon</artifactId > </exclusion > </exclusions > </dependency > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-loadbalancer</artifactId > <version > 3.0.2</version > </dependency >
Nacos Config 引入 maven 依赖 在electricity-common
模块的 pom.xml 文件中引入Nacos Config Starter
。
<dependency > <groupId > com.alibaba.cloud</groupId > <artifactId > spring-cloud-starter-alibaba-nacos-config</artifactId > </dependency >
配置 Nacos Config 元数据 在微服务模块中新建bootstrap.properties
配置文件配置原数据,bootstrap.properties
配置文件会优先于application.properties
文件加载。
spring.application.name =electricity-coupon spring.cloud.nacos.config.server-addr =127.0.0.1:8848
获取配置 完成上述两步后,应用会从 Nacos Config 中获取相应的配置,并添加在 Spring Environment 的 PropertySources 中。这里我们使用 @Value 注解来将对应的配置注入到 CouponController 的 userName 和 age 字段,并添加@RefreshScope
打开动态刷新功能。
@RefreshScope @RestController @RequestMapping("coupon/coupon") public class CouponController { @Value("${coupon.user.name}") private String name; @Value("${coupon.user.age}") private int age; @RequestMapping("/test") public R test () { return R.ok().put("name" , name).put("age" , age); } }
启动应用 先启动 nacos server 程序,然后启动微服务项目,在浏览器输入项目地址获取信息。
localhost:7000/coupon/coupon/test
配置 Nacos DataID 数据 在 nacos 服务前端页面配置管理的配置列表中添加 DataID,DataID 为应用名.properties
,选择配置格式,然后添加配置内容。
配置完成后,只需要修改这里的配置数据就可以自动获取新的数据,不需要再重新启动项目。
如果配置完成后,一切都正常,但是获取不到 nacos 配置的数据,应该是 springcloud 版本问题。
解决方案:在electricity-common
模块添加依赖。
<dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-bootstrap</artifactId > <version > 3.0.2</version > </dependency >
命名空间和分组 nacos 中可以划分不同的命名空间和分组,默认的命名空间是 public,默认分组为 DEFAULT_GROUP。当配置文件较多时,我们可以配置不同的命名空间和分组对配置进行管理。
在 nacos 配置中心页面配置好命名空间和分组,然后在bootstrap.properties
文件中添加配置。
spring.cloud.nacos.config.namespace =dev spring.cloud.nacos.config.group =coupon
加载多配置集 当配置信息比较多时,所有配置都放在一个文件里不好维护,我们可以把配置信息分离出来配置多个数据文件。
可以按照项目中配置的不同模块,将application.yml
中的数据配置分离。例如按照数据源,mybatis,springcloud等划分成多个文件。然后按照之前的方式,新建配置文件,放在相应的命名空间和分组下。
在bootstrap.properties
文件中添加配置。
spring.cloud.nacos.config.ext-config[0].data-id =datasource.yml spring.cloud.nacos.config.ext-config[0].group =dev spring.cloud.nacos.config.ext-config[0].refresh =true spring.cloud.nacos.config.ext-config[1].data-id =mybatis.yml spring.cloud.nacos.config.ext-config[1].group =dev spring.cloud.nacos.config.ext-config[1].refresh =true spring.cloud.nacos.config.ext-config[2].data-id =other.yml spring.cloud.nacos.config.ext-config[2].group =dev spring.cloud.nacos.config.ext-config[2].refresh =true
Gateway 新建模块 新建 springboot 模块,勾选 gateway 依赖。
<?xml version="1.0" encoding="UTF-8" ?> <project xmlns ="http://maven.apache.org/POM/4.0.0" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation ="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" > <modelVersion > 4.0.0</modelVersion > <parent > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-parent</artifactId > <version > 2.5.1</version > <relativePath /> </parent > <groupId > com.laughing.electricity</groupId > <artifactId > electricity-gateway</artifactId > <version > 0.0.1-SNAPSHOT</version > <name > electricity-gateway</name > <description > API网关</description > <properties > <java.version > 1.8</java.version > <spring-cloud.version > 2020.0.3</spring-cloud.version > </properties > <dependencies > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-gateway</artifactId > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-test</artifactId > <scope > test</scope > </dependency > </dependencies > <dependencyManagement > <dependencies > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-dependencies</artifactId > <version > ${spring-cloud.version}</version > <type > pom</type > <scope > import</scope > </dependency > <dependency > <groupId > com.alibaba.cloud</groupId > <artifactId > spring-cloud-starter-alibaba-nacos-config</artifactId > </dependency > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-bootstrap</artifactId > <version > 3.0.2</version > </dependency > <dependency > <groupId > com.alibaba.cloud</groupId > <artifactId > spring-cloud-starter-alibaba-nacos-discovery</artifactId > <exclusions > <exclusion > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-starter-netflix-ribbon</artifactId > </exclusion > </exclusions > </dependency > <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-loadbalancer</artifactId > <version > 3.0.2</version > </dependency > </dependencies > </dependencyManagement > <build > <plugins > <plugin > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-maven-plugin</artifactId > </plugin > </plugins > </build > </project >
配置 nacos
spring.cloud.nacos.discovery.server-addr =127.0.0.1:8848 spring.application.name =electricity-gateway server.port =8888
新建 bootstrap.properites 配置文件
spring.application.name =electricity-gateway spring.cloud.nacos.discovery.server-addr =127.0.0.1:8848 spring.cloud.nacos.config.namespace =dev
spring: cloud: gateway: routes: - id: zhibo8 uri: https://www.zhibo8.cc predicates: - Query=url,zhibo8 - id: bing uri: https://bing.com predicates: - Query=url,bing
访问 localhost:8888/?bing
可以直接跳转到 https://www.bing.com