Spring Boot 整合 Spring Cloud Alibaba各个微服务组件
1、spring boot、spring cloud以及spring cloud alibaba版本控制对照
①spring boot版本
官网推荐必须用2.x以后的版本,目前GitHub上面的版本截至目前2023/03/04是v3.0.4 版本查看地址,当然最新的并非最稳定的,接下来我们还需要看springcloud的对应版本来选择springboot版本。
②spring cloud版本及spring cloud Alibaba版本选择
我们去官网查看Spring Cloud,可以看到最新稳定版本是2022.0.1 CURRENT GA
SpringCloud的版本关系 Spring Cloud 采用了英国伦敦地铁站的名称来命名,并由地铁站名称字母A-Z依次类推的形式来发布迭代版本SpringCloud是一个由许多子项目组成的综合项目,各子项目有不同的发布节奏。为了管理SpringCloud与各子项目的版本依赖关系,发布了一个清单,其中包括了某个SpringCloud版本对应的子项目版本。为了避免SpringCloud版本号与子项目版本号混淆,SpringCloud版本采用了名称而非版本号的命名,这些版本的名字采用了伦敦地铁站的名字,根据字母表的顺序来对应版本时间顺序。例如Angel是第一个版本, Brixton是第二个版本。当SpringCloud的发布内容积累到临界点或者一个重大BUG被解决后,会发布一个"service releases"版本,简称SRX版本,比如Greenwich.SR2就是SpringCloud发布的Greenwich版本的第2个SRX版本。
但是目前看来springcloud从H版后又改成了日期为准的版本
通过官网我们可以看到springcloud和springboot之间的版本对应关系,当然了spirng官网也给我们了官方接口,直接返回版本对照结果:https://start.spring.io/actuator/info。
这里Alibaba GitHub地址出具了一份spring boot、spring cloud以及spring cloud alibaba版本依赖关系,十分通俗,易看懂,版本说明 ,目前企业级客户老项目相关 Spring Boot 版本仍停留在 Spring Boot 2.4 以下,spring cloud使用的的是Hoxton版本。
如我们上边所说,springcloud从H版本后就更改了版本命名方式,所以spirngcloudAlibab也跟着更改了方式,可以说是非常的贴心。
这里还需注意spring cloud Alibaba版本对应的子组件版本,否则就会出现不兼容的问题。
综上所述,我们选择市面上应用最广泛的Hoxton版本的spring cloud。
Spring Cloud Alibaba Version | Spring Cloud Version | Spring Boot Version |
---|---|---|
2.2.9.RELEASE | Spring Cloud Hoxton.SR12 | 2.3.12.RELEASE |
Spring Cloud Alibaba Version对应的子组件版本:
Spring Cloud Alibaba Version | Sentinel Version | Nacos Version | RocketMQ Version | Dubbo Version | Seata Version |
---|---|---|---|---|---|
2.2.9.RELEASE | 1.8.5 | 2.1.0 | 4.9.4 | ~ | 1.5.2 |
2、创建父工程
父工程的主要作用是用来管理和控制依赖版本。
创建一个空的maven项目,只用留下pom.xml文件即可,我们通过dependencyManagement标签来管理依赖版本,并设置打包方式为pom,pom内容如下
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.drizzle</groupId>
<artifactId>springCloudDemo</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>order</module>
<module>discount</module>
<module>gateway</module>
<module>order-api</module>
</modules>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<spring.boot.version>2.3.12.RELEASE</spring.boot.version>
<spring.cloud.version>Hoxton.SR12</spring.cloud.version>
<spring.cloud.alibaba.version>2.2.9.RELEASE</spring.cloud.alibaba.version>
<lombok.version>1.18.26</lombok.version>
<mybatis.version>3.5.1</mybatis.version>
<mysql.version>8.0.17</mysql.version>
<druid.version>1.2.4</druid.version>
<jackson.version>2.14.1</jackson.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<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-alibaba-dependencies</artifactId>
<version>${spring.cloud.alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
接下来就可以创建子模块,来实现服务注册、配置发现、服务调用、熔断、限流、网关等功能。
3、搭建Nacos注册中心
我这里为了方便直接在我的服务器上面用docker容器化技术搭建了nacos。
注意:当nacos客户端升级为2.x版本后,新增了gRPC的通信方式,新增了两个端口。这两个端口在nacos原先的端口上(默认8848),进行一定偏移量自动生成,所以带上8848一共要开放3个端口。
端口 | 与主端口的偏移量 | 描述 |
---|---|---|
9848 | 1000 | 客户端gRPC请求服务端端口,用于客户端向服务端发起连接和请求 |
9849 | 1001 | 服务端gRPC请求服务端端口,用于服务间同步等 |
启动命令如下:
docker run \
--name my_nacos -d \
-p 8848:8848 \
-p 9848:9848 \
-p 9849:9849 \
--privileged=true \
--restart=always \
-e JVM_XMS=32m \
-e JVM_XMX=512m \
-e JVM_XMN=128m \
-e MODE=standalone \
-e PREFER_HOST_MODE=hostname \
-e SPRING_DATASOURCE_PLATFORM=mysql \
-e MYSQL_SERVICE_HOST=150.158.84.19 \
-e MYSQL_SERVICE_PORT=3306 \
-e MYSQL_SERVICE_DB_NAME=nacos_config \
-e MYSQL_SERVICE_USER=root \
-e MYSQL_SERVICE_PASSWORD=admin@210513 \
-v /u96e8/nacos/logs:/home/nacos/logs \
-v /u96e8/nacos/data:/home/nacos/data \
nacos/nacos-server
-Xms 堆内存的初始大小,默认为物理内存的1/64
-Xmx 堆内存的最大大小,默认为物理内存的1/4
-Xmn 堆内新生代的大小。通过这个值也可以得到老生代的大小:-Xmx减去-Xmn xmx的1/4。
4、创建子工程,集成Nacos
子模块pom.xml如下,以order为例:
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>springCloudDemo</artifactId>
<groupId>com.drizzle</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>order</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 服务注册中心 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- 服务配置中心 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
</dependencies>
</project>
新建bootstrap.yml配置文件,配置nacos地址:
spring:
cloud:
nacos:
# nacos服务地址
server-addr: --
username: --
password: --
config:
# 配置文件后缀
file-extension: yaml
# 配置文件所在空间id
namespace: eb295bff-85c4-4e20-bc18-1463fd599157
profiles:
active: dev
# 配置文件名
application:
name: spring-order-dev
在nacos注册中心创建一个dev的命名空间,创建对应服务的配置文件
在启动类上直接使用 @SpringCloudApplication 注解,此注解包含了开启nacos服务的注解。
配置工作做完后,启动,即可在nacos中发现已经注册的服务列表。
5、集成Openfeign和hystrix
引入相关的依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
这里我创建了两个工程,order工程放主要的业务逻辑,order-api将openfeign接口、实体、常量、枚举解耦出来,这样其他的模块在调用order服务是只需要引入order-api即可,减少不必要的引入,减少jar包体积。
在order-api中创建feign接口:
@Component
@FeignClient(value = "spring-order-dev", fallback = OrderServiceFallback.class)
public interface IOrderClient {
String orderPath = "/get/orderById";
@GetMapping(orderPath)
OrderEntity getOrderById(@RequestParam("id") Long id);
}
OrderServiceFallback为业务熔断处理类,当接口发生异常时,可以给用户一些友好的提示,当然这里我没有创建公用的返回标准,只是举例说明,代码如下:
@Component
@Slf4j
public class OrderServiceFallback implements IOrderClient {
@Override
public OrderEntity getOrderById(Long id) {
log.error("服务调用失败!");
return null;
}
}
注意需要开启断路器功能,默认是关闭的:
feign:
hystrix:
enabled: true
随后在启动类上面加上@EnableFeignClients(扫描feign接口)@EnableCircuitBreaker(开启熔断断路器功能)。
其他业务模块调用时,首先需要引入order模块的api,比如优惠(discount)模块pom如下:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 服务注册中心 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- 服务配置中心 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>com.drizzle</groupId>
<artifactId>order-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
然后添加nacos、feign、断路器的配置,启动,然后尝试调用order的feign接口,我这里为了测试直接在控制层调用了feign:
@RestController
@RequestMapping("discount")
public class DiscountController {
// 注入feign clien
@Resource
private IOrderClient iOrderClient;
@GetMapping("get/order")
public OrderEntity getOrder(Long id) {
return iOrderClient.getOrderById(id);
}
}
6、集成sentinel
引入pom:
<!-- 流控 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
添加配置:
spring:
cloud:
sentinel:
transport:
dashboard: ip:8858
heartbeat-interval-ms: 500
# 配置 sentinel.eager=true 时,取消Sentinel控制台懒加载功能
eager: true
# 如果有多套网络,又无法正确获取本机IP,则需要使用下面的参数设置当前机器可被外部访问的IP地址,供admin控制台使用
# spring.cloud.sentinel.transport.client-ip=# sentinel 配置
7、配置网关
gateway项目pom文件:
<dependencies>
<!-- 服务注册中心 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- 服务配置中心 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- 流控 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
</dependencies>
配置一些简单的过滤规则:
spring:
cloud:
gateway:
enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
discovery:
locator:
enabled: true #使用服务发现路由
routes:
- id: spring-order # 路由的id,没有规定规则但要求唯一,建议配合服务名
#匹配后提供服务的路由地址
uri: lb://spring-order-dev:7020
predicates:
- Path=/order/** # 断言,路径相匹配的进行路由(注意**为通配符)
- id: spring-discount
uri: lb://spring-discount-dev:8020
predicates:
- Path=/discount/** #断言,路径相匹配的进行路由
sentinel:
transport:
dashboard: ip:8858
heartbeat-interval-ms: 500
# 配置 sentinel.eager=true 时,取消Sentinel控制台懒加载功能
eager: true
ribbon:
eager-load:
enabled: true # 开启Ribbon的饥饿加载模式,启动时创建 RibbonClient