跳到主要内容Spring Cloud 微服务核心组件实战指南 | 极客日志Javajava
Spring Cloud 微服务核心组件实战指南
Spring Cloud 微服务架构涵盖注册中心、配置中心、网关及分布式事务等关键组件。本文详解 Nacos 服务注册与配置管理,OpenFeign 声明式调用,Sentinel 流控降级,Gateway 路由过滤以及 Seata 分布式事务解决方案。通过实际代码示例,展示如何搭建高可用微服务架构,解决远程调用、负载均衡及数据一致性等问题。
女王0 浏览 Spring Cloud 微服务架构实战
Spring Cloud 简介
Spring Cloud 是分布式系统的一站式解决方案。理解分布式架构前,先明确它与单体、集群的区别:
| 架构演进 | 单体架构 | 集群架构 | 分布式架构 |
|---|
| 定义 | 所有功能模块都在一个项目里 | 单体的多服务器版本 | 大型应用拆分成小应用分布部署 |
| 优点 | 开发部署简单 | 解决大并发 | 解决单体 + 集群问题,模块自治 |
| 缺点 | 无法应对高并发 | 模块升级麻烦,多语言交互难 | 需处理远程调用、数据一致性等 |
在分布式架构中,通常通过网关(Gateway)分发请求,微服务独立部署并注册到注册中心(Nacos)。若模块跨服务器调用,需借助 Nacos 进行服务发现与配置管理。当服务调用失败可能引发雪崩时,需引入熔断机制(Sentinel)。涉及多个数据库操作时,则需分布式事务方案(Seata)。
前期准备
搭建项目骨架
快速搭建框架结构,创建父工程 spring-cloud-demo。
导依赖
在父模块的 pom.xml 中管理版本,注意 Spring Boot、Spring Cloud 及 Spring Cloud Alibaba 的版本兼容性。
<?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>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
3.3.4
4.0.0
com.atguigu
spring-cloud-demo
1.0-SNAPSHOT
pom
17
17
UTF-8
2023.0.3
2023.0.3.2
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
com.alibaba.cloud
spring-cloud-alibaba-dependencies
${spring-cloud-alibaba.version}
pom
import
<version>
</version>
<relativePath/>
</parent>
<modelVersion>
</modelVersion>
<groupId>
</groupId>
<artifactId>
</artifactId>
<version>
</version>
<packaging>
</packaging>
<properties>
<maven.compiler.source>
</maven.compiler.source>
<maven.compiler.target>
</maven.compiler.target>
<project.build.sourceEncoding>
</project.build.sourceEncoding>
<spring-cloud.version>
</spring-cloud.version>
<spring-cloud-alibaba.version>
</spring-cloud-alibaba.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>
</groupId>
<artifactId>
</artifactId>
<version>
</version>
<type>
</type>
<scope>
</scope>
</dependency>
<dependency>
<groupId>
</groupId>
<artifactId>
</artifactId>
<version>
</version>
<type>
</type>
<scope>
</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
创建模块
- services 模块:作为所有
service-xxx 模块的父模块。
- service-order / service-product 模块:具体的业务服务模块。
- model 模块:统一管理实体类。
Nacos - 注册/配置中心
基础入门
下载 Nacos Server,启动命令为 startup.cmd -m standalone。默认账号密码均为 nacos。
注册中心
服务注册
将微服务注册到 Nacos 进行管理。在 service-order 和 service-product 中添加依赖并配置。
<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>
</dependencies>
配置文件 (application.properties):
server.port=8000
spring.application.name=service-order
spring.cloud.nacos.server-addr=127.0.0.1:8848
启动后访问 http://localhost:8848/nacos 即可看到服务列表。
服务发现
服务发现允许服务间通过 Nacos 自动发现对方地址。启动类添加 @EnableDiscoveryClient 注解。
@EnableDiscoveryClient
@SpringBootApplication
public class ProductMainApplication {
public static void main(String[] args) {
SpringApplication.run(ProductMainApplication.class, args);
}
}
测试类中可使用 DiscoveryClient 获取服务实例信息。
远程调用
初始阶段使用 RestTemplate 配合 DiscoveryClient 手动构建 URL 进行调用。
@Service
@Slf4j
public class OrderServiceImpl implements OrderService {
@Autowired DiscoveryClient discoveryClient;
@Autowired RestTemplate restTemplate;
@Override
public Order createOrder(Long userId, Long productId) {
List<ServiceInstance> instances = discoveryClient.getInstances("service-product");
ServiceInstance instance = instances.get(0);
String url = "http://" + instance.getHost() + ":" + instance.getPort() + "/productId/" + productId;
log.info("远程请求:{}", url);
return restTemplate.getForObject(url, Product.class);
}
}
负载均衡
1. 使用 LoadBalancerClient
@Autowired LoadBalancerClient loadBalancerClient;
ServiceInstance choose = loadBalancerClient.choose("service-product");
2. 使用 @LoadBalanced 注解
更推荐的方式,在配置类中将 RestTemplate 注册为 Bean 并添加 @LoadBalanced。
@Configuration
public class OrderConfig {
@LoadBalanced
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
此时调用 URL 可直接写服务名:http://service-product/productId/{id}。
思考:注册中心宕机后远程调用还能成功吗?
第一次调用需要查询 Nacos,若 Nacos 宕机则无法获取地址。但后续调用会读取缓存中的地址列表,因此只要服务本身存活,即使 Nacos 暂时不可用,基于缓存的负载均衡依然有效。
配置中心
整合配置
导入 spring-cloud-starter-alibaba-nacos-config 依赖,并在配置文件中指定导入路径。
spring.config.import=nacos:service-order.properties
# 关闭配置检查,避免未配置时报错
spring.cloud.nacos.config.import-check.enabled=false
在 Nacos 控制台编写配置文件,代码中使用 @Value 或 @ConfigurationProperties 获取。
自动刷新
- @RefreshScope:在包含
@Value 的类上添加此注解,修改配置后无需重启即可生效。
- @ConfigurationProperties:批量绑定配置,天然支持自动刷新,无需额外注解。
- NacosConfigManager:监听配置变化事件,适合复杂场景。
数据隔离
利用 Namespace 区分环境(dev/test/prod),Group 区分不同服务,具体配置文件区分不同配置项。
spring:
profiles:
active: prod
cloud:
nacos:
config:
import-check:
enabled: false
namespace: ${spring.profiles.active:public}
OpenFeign
OpenFeign 是声明式远程调用客户端,相比编程式的 RestTemplate 更简洁。
基础使用
- 添加
spring-cloud-starter-openfeign 依赖。
- 启动类添加
@EnableFeignClients。
- 编写 Feign Client 接口。
@FeignClient(value = "service-product")
public interface ProductFeignClient {
@GetMapping(value = "/productId/{id}")
public Product getProductById(@PathVariable("id") Long productId);
}
进阶配置
开启日志
在 application.yml 中设置日志级别,或在配置类中定义 Logger.Level.FULL。
logging:
level:
com.atguigu.order.feign: debug
超时控制
spring:
cloud:
openfeign:
client:
config:
default:
connect-timeout: 1000
read-timeout: 2000
重试机制
配置 Retryer Bean,默认重试 5 次。
@Bean
Retryer retryer() {
return new Retryer.Default();
}
Fallback 兜底返回
结合 Sentinel 实现降级。当远程调用失败时,执行 fallback 类中的方法返回默认值。
@FeignClient(value = "service-product", fallback = ProductFeignClientFallback.class)
public interface ProductFeignClient { ... }
Sentinel
环境搭建
下载并启动 Sentinel Dashboard,配置服务连接地址。
spring.cloud.sentinel.transport.dashboard=localhost:8080
spring.cloud.sentinel.eager=true
异常处理
- Web 接口异常:实现
BlockExceptionHandler 接口自定义返回结果。
- @SentinelResource 异常:在方法上添加注解,指定
blockHandler 或 fallback 方法。
- OpenFeign 异常:走 Feign 自身的 fallback 机制。
规则配置
- 流控模式:直接、关联、链路策略。
- 流控效果:快速失败、Warm Up(预热)、排队等待。
- 熔断降级:慢调用比例、异常比例、异常数。
- 热点参数:针对特定参数值进行限流。
Gateway
Gateway 是微服务网关,负责路由转发、过滤等。
环境配置
创建 gateway 模块,添加 spring-cloud-starter-gateway 依赖。
路由配置 (Predicates & Filters)
在 application.yml 中配置路由规则。
spring:
cloud:
gateway:
routes:
- id: order-route
uri: lb://service-order
predicates:
- Path=/api/order/**
filters:
- RewritePath=/api/order/?(?<segment>.*), /${segment}
- Predicates:断言,决定请求是否匹配该路由(如路径、Header、Query 参数等)。
- Filters:过滤器,对请求或响应进行预处理(如添加 Header、重写路径)。
全局过滤器 (GlobalFilter)
实现 GlobalFilter 接口可拦截所有请求,常用于统一鉴权、日志记录等。
@Component
public class RTGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
long startTime = System.currentTimeMillis();
return chain.filter(exchange).doFinally(r -> {
long endTime = System.currentTimeMillis();
log.info("耗时:{}ms", endTime - startTime);
});
}
@Override
public int getOrder() { return 0; }
}
Seata
核心概念
- TC (Transaction Coordinator):事务协调者,服务端。
- TM (Transaction Manager):事务管理器,发起全局事务。
- RM (Resource Manager):资源管理器,操作分支事务。
使用步骤
- 启动 Seata Server。
- 各微服务添加
spring-cloud-starter-alibaba-seata 依赖。
- 配置
file.conf 连接 TC。
- 全局事务入口方法添加
@GlobalTransactional,分支事务方法添加 @Transactional。
@GlobalTransactional
public void createOrder(...) {
accountService.deduct(...);
storageService.reduce(...);
}
事务模式
- AT 模式:默认模式,无侵入,基于二阶段提交协议。
- XA 模式:强一致性,性能较差。
- TCC 模式:高性能,需手写 Try/Confirm/Cancel 逻辑。
- Saga 模式:长事务,基于补偿机制。
小结
Seata 的核心在于保证跨库操作的数据一致性。引入依赖后,只需在关键方法上加注解即可启用分布式事务管控。
相关免费在线工具
- Keycode 信息
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
- Escape 与 Native 编解码
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
- JavaScript / HTML 格式化
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
- JavaScript 压缩与混淆
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online