一、架构设计
微服务架构是一种将大型单体应用拆分为一系列小型、自治服务的策略,每个服务运行在其独立的进程中,并通过轻量级通信协议(如RESTful API)相互通信。此架构促进了开发团队的敏捷性、服务的独立部署和扩展,以及技术栈的多样性。
本设计将采用Java作为编程语言,Spring Boot作为开发框架,以及Spring Cloud Alibaba进行服务治理。基于Spring Cloud Alibaba提供了一系列微服务解决方案,包括服务注册与发现、配置管理、服务调用、熔断降级、服务网关等。
二、技术选型
- 编程语言:Java
- 框架:Spring Boot
- 服务治理:Spring Cloud Alibaba
三、微服务设计
服务划分
根据业务需求,我们将设计一个电商系统的微服务架构。为了简化设计,我们将重点实现用户服务(UserService)和订单服务(OrderService)两个微服务。
API设计
每个微服务将提供RESTful API接口,用于与其他微服务进行通信。我们将使用Swagger或Springfox生成API文档,以确保API的易用性和可维护性。
技术逻辑与实现过程
服务注册与发现
使用Nacos作为服务注册中心。每个微服务在启动时都会向Nacos注册自己的信息(如服务名、IP地址、端口等),以便其他微服务可以通过Nacos来查找和调用。
实现步骤:
-
部署并启动Nacos服务注册中心:
- 下载并安装Nacos。
- 启动Nacos服务。
-
在用户服务和订单服务的Spring Boot项目中引入Spring Cloud Alibaba Nacos依赖:
- 创建一个父POM文件来管理所有子模块的公共依赖和版本。
<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.example</groupId> <artifactId>microservice-parent</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>pom</packaging> <properties> <java.version>1.8</java.version> <spring-boot.version>2.7.5</spring-boot.version> <spring-cloud-alibaba.version>2021.1.0.0</spring-cloud-alibaba.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>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>${spring-cloud-alibaba.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <modules> <module>user-service</module> <module>order-service</module> <module>gateway</module> </modules> </project>- 每个子模块(如用户服务、订单服务、网关)的
pom.xml应该继承自父POM,并添加特定于该模块的依赖。
<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>com.example</groupId> <artifactId>microservice-parent</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>user-service</artifactId> <dependencies> <!-- Spring Boot Starter Web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Spring Cloud Alibaba Nacos Discovery --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!-- Spring Cloud OpenFeign --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <!-- Spring Cloud Alibaba Sentinel --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency> </dependencies> </project> -
配置Nacos客户端:
- 在
application.yml中配置Nacos客户端,包括服务名、Nacos服务器地址等。
server: port: 8081 # 服务端口 spring: application: name: user-service # 服务名称 cloud: nacos: discovery: server-addr: 127.0.0.1:8848 # Nacos服务地址 feign: client: config: default: connectTimeout: 5000 # 连接超时时间 readTimeout: 5000 # 读取超时时间 sentinel: transport: dashboard: localhost:8080 # Sentinel 控制台地址 - 在
-
启动微服务:
- 启动微服务,它们将自动向Nacos注册中心注册。
服务调用
使用OpenFeign进行服务之间的调用。OpenFeign是一个声明式的Web服务客户端,它使得写HTTP客户端变得更简单。
实现步骤:
-
在用户服务和订单服务的Spring Boot项目中引入Spring Cloud OpenFeign依赖:
- 已在上述
pom.xml中添加。
- 已在上述
-
配置OpenFeign:
- 在
application.yml中配置OpenFeign,包括服务名、超时时间等。
- 在
-
创建一个Feign客户端接口,用于调用其他微服务提供的API。
package com.example.orderservice.feign; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @FeignClient("user-service") public interface UserServiceClient { @GetMapping("/users/{userId}") String getUserInfo(@PathVariable("userId") String userId); } -
在需要使用服务调用的地方注入Feign客户端接口,并调用其方法。
package com.example.orderservice.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/orders") public class OrderController { @Autowired private UserServiceClient userServiceClient; @GetMapping("/{orderId}") public String getOrderInfo(@PathVariable("orderId") String orderId) { String userInfo = userServiceClient.getUserInfo("123"); return "Order Info for Order ID: " + orderId + ", User Info: " + userInfo; } }
服务熔断与降级
使用Sentinel进行服务的熔断与降级。Sentinel是面向分布式服务架构的高可用防护组件,主要用于流量控制、熔断降级、系统负载保护等。
实现步骤:
-
在用户服务和订单服务的Spring Boot项目中引入Spring Cloud Alibaba Sentinel依赖:
- 已在上述
pom.xml中添加。
- 已在上述
-
配置Sentinel:
- 在
application.yml中配置Sentinel,包括熔断规则、降级策略等。
- 熔断规则配置
circuitbreaker: sentinel: enabled: true rules: - resource: getUserInfo # 资源名称,对应API方法 count: 5 # 触发熔断的异常数 timeWindow: 10 # 熔断持续时间(秒) minRequestAmount: 10 # 最小请求数 statIntervalMs: 1000 # 统计时间窗口(毫秒) slowRequestRatioThreshold: 0.5 # 慢请求比例阈值- 降级策略配置
degrade: sentinel: rules: - resource: getUserInfo # 资源名称,对应API方法 count: 5 # 降级阈值 timeWindow: 10 # 降级持续时间(秒) grade: 1 # 降级策略类型(0: 异常比例, 1: 异常数) minRequestAmount: 10 # 最小请求数 statIntervalMs: 1000 # 统计时间窗口(毫秒) - 在
-
在需要熔断与降级的Feign客户端接口方法上添加@SentinelResource注解,并指定熔断后的回退方法。
package com.example.orderservice.feign; import com.alibaba.csp.sentinel.annotation.SentinelResource; import com.alibaba.csp.sentinel.slots.block.BlockException; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @FeignClient("user-service") public interface UserServiceClient { @SentinelResource(value = "getUserInfo", blockHandler = "handleBlock", fallback = "handleFallback") @GetMapping("/users/{userId}") public String getUserInfo(@PathVariable("userId") String userId) { return "User Info for User ID: " + userId; } public String handleBlock(@PathVariable("userId") String userId, BlockException ex) { return "Blocked by Sentinel: " + ex.getMessage(); } public String handleFallback(@PathVariable("userId") String userId) { return "Fallback: User Info for User ID: " + userId; } }解释
@SentinelResource:标记需要Sentinel保护的方法。value:资源名称,对应API方法。blockHandler:当请求被限流或熔断时调用的处理方法。fallback:当请求失败时调用的回退方法。
handleBlock:处理限流或熔断的回调方法。handleFallback:处理请求失败的回退方法。
服务网关
使用Gateway作为服务网关,用于路由转发、过滤、鉴权等功能。
实现步骤:
-
部署并启动Gateway服务网关:
- 创建一个新的Spring Boot项目作为网关服务。
-
在Gateway项目的Spring Boot中引入Spring Cloud Gateway依赖:
- 在
pom.xml中添加依赖。
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> - 在
-
配置Gateway的路由规则,将不同的请求路径映射到对应的服务上。
server: port: 8000 # 网关服务端口 spring: application: name: gateway-service # 服务名称 cloud: gateway: routes: - id: user-service uri: lb://user-service predicates: - Path=/users/** - id: order-service uri: lb://order-service predicates: - Path=/orders/** -
(可选)配置过滤器、鉴权等功能。
四、测试与验证
- 单元测试:使用JUnit等工具对服务进行单元测试,确保服务的功能正确。
- 集成测试:通过模拟调用和响应,验证服务之间的调用关系和熔断降级机制是否正常工作。
- 性能测试:使用JMeter等工具对服务进行性能测试,确保服务在高并发下能够正常运行。
五、总结
本设计通过Java、Spring Boot和Spring Cloud Alibaba实现了一个微服务架构,包括用户服务和订单服务两个微服务。通过Nacos实现服务注册与发现,通过OpenFeign实现服务调用,通过Sentinel实现服务熔断与降级,通过Gateway实现服务网关。该设计提高了系统的灵活性、可扩展性和可维护性,满足了快速变化的业务需求。