学习时间: 4-5小时
学习目标: 掌握微服务架构设计原则,学会使用Spring Cloud构建分布式系统
详细学习清单
✅ 第一部分:微服务架构基础(60分钟)
1. 微服务架构概念
微服务特点
diff
- 单一职责:每个服务只负责一个业务功能
- 独立部署:服务可以独立开发、测试、部署
- 技术多样性:不同服务可以使用不同的技术栈
- 数据隔离:每个服务拥有自己的数据库
- 分布式管理:服务间通过网络通信
微服务架构图
java
// MicroserviceArchitecture.java
package com.example.demo.architecture;
public class MicroserviceArchitecture {
public static void main(String[] args) {
System.out.println("=== 微服务架构组件 ===");
System.out.println("1. 服务注册与发现 (Eureka/Consul)");
System.out.println("2. 配置中心 (Config Server)");
System.out.println("3. 网关服务 (Gateway)");
System.out.println("4. 负载均衡 (Ribbon)");
System.out.println("5. 熔断器 (Hystrix)");
System.out.println("6. 分布式追踪 (Sleuth)");
System.out.println("7. 监控中心 (Actuator)");
}
}
2. 微服务设计原则
服务拆分原则
java
// ServiceDesignPrinciples.java
package com.example.demo.architecture;
import java.util.List;
import java.util.ArrayList;
public class ServiceDesignPrinciples {
public static class ServiceBoundary {
private String serviceName;
private String domain;
private List<String> responsibilities;
private List<String> dependencies;
public ServiceBoundary(String serviceName, String domain) {
this.serviceName = serviceName;
this.domain = domain;
this.responsibilities = new ArrayList<>();
this.dependencies = new ArrayList<>();
}
public void addResponsibility(String responsibility) {
this.responsibilities.add(responsibility);
}
public void addDependency(String dependency) {
this.dependencies.add(dependency);
}
// Getter方法
public String getServiceName() { return serviceName; }
public String getDomain() { return domain; }
public List<String> getResponsibilities() { return responsibilities; }
public List<String> getDependencies() { return dependencies; }
}
public static void main(String[] args) {
// 用户服务边界
ServiceBoundary userService = new ServiceBoundary("user-service", "用户管理");
userService.addResponsibility("用户注册");
userService.addResponsibility("用户认证");
userService.addResponsibility("用户信息管理");
userService.addDependency("数据库");
userService.addDependency("Redis缓存");
// 订单服务边界
ServiceBoundary orderService = new ServiceBoundary("order-service", "订单管理");
orderService.addResponsibility("订单创建");
orderService.addResponsibility("订单查询");
orderService.addResponsibility("订单状态管理");
orderService.addDependency("用户服务");
orderService.addDependency("商品服务");
orderService.addDependency("支付服务");
// 商品服务边界
ServiceBoundary productService = new ServiceBoundary("product-service", "商品管理");
productService.addResponsibility("商品信息管理");
productService.addResponsibility("库存管理");
productService.addResponsibility("商品分类管理");
productService.addDependency("数据库");
productService.addDependency("文件存储服务");
System.out.println("=== 微服务边界设计 ===");
printServiceBoundary(userService);
printServiceBoundary(orderService);
printServiceBoundary(productService);
}
private static void printServiceBoundary(ServiceBoundary service) {
System.out.println("\n服务名称: " + service.getServiceName());
System.out.println("业务领域: " + service.getDomain());
System.out.println("职责范围:");
for (String responsibility : service.getResponsibilities()) {
System.out.println(" - " + responsibility);
}
System.out.println("依赖服务:");
for (String dependency : service.getDependencies()) {
System.out.println(" - " + dependency);
}
}
}
✅ 第二部分:Spring Cloud基础配置(90分钟)
1. 父项目配置
父项目pom.xml
xml
<!-- 父项目 pom.xml -->
<?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.example</groupId>
<artifactId>microservice-parent</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<spring-boot.version>2.7.14</spring-boot.version>
<spring-cloud.version>2021.0.8</spring-cloud.version>
<spring-cloud-alibaba.version>2021.0.5.0</spring-cloud-alibaba.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- Spring Boot BOM -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Spring Cloud BOM -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Spring Cloud Alibaba BOM -->
<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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
</plugin>
</plugins>
</build>
</project>
2. 服务注册中心
Eureka Server配置
xml
<!-- eureka-server/pom.xml -->
<?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>
<parent>
<groupId>com.example</groupId>
<artifactId>microservice-parent</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>eureka-server</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
Eureka Server主类
java
// EurekaServerApplication.java
package com.example.eureka;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
Eureka Server配置
yaml
# eureka-server/src/main/resources/application.yml
server:
port: 8761
spring:
application:
name: eureka-server
eureka:
instance:
hostname: localhost
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
server:
enable-self-preservation: false
eviction-interval-timer-in-ms: 1000
3. 配置中心
Config Server配置
xml
<!-- config-server/pom.xml -->
<?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>
<parent>
<groupId>com.example</groupId>
<artifactId>microservice-parent</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>config-server</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
Config Server主类
java
// ConfigServerApplication.java
package com.example.config;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
Config Server配置
yaml
# config-server/src/main/resources/application.yml
server:
port: 8888
spring:
application:
name: config-server
cloud:
config:
server:
git:
uri: https://github.com/your-username/config-repo
default-label: main
search-paths: config
username: your-username
password: your-token
native:
search-locations: classpath:/config
✅ 第三部分:微服务实现(90分钟)
1. 用户服务
用户服务pom.xml
xml
<!-- user-service/pom.xml -->
<?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>
<parent>
<groupId>com.example</groupId>
<artifactId>microservice-parent</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>user-service</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
</project>
用户服务主类
java
// UserServiceApplication.java
package com.example.userservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}
用户服务配置
yaml
# user-service/src/main/resources/bootstrap.yml
spring:
application:
name: user-service
cloud:
config:
uri: http://localhost:8888
fail-fast: true
profiles:
active: dev
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
prefer-ip-address: true
instance-id: ${spring.application.name}:${server.port}
management:
endpoints:
web:
exposure:
include: health,info,metrics
endpoint:
health:
show-details: always
用户实体类
java
// User.java
package com.example.userservice.model;
import javax.persistence.*;
import java.time.LocalDateTime;
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(unique = true, nullable = false)
private String username;
@Column(unique = true, nullable = false)
private String email;
@Column(nullable = false)
private String password;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@Column(name = "phone")
private String phone;
@Column(name = "enabled")
private Boolean enabled = true;
@Column(name = "created_at")
private LocalDateTime createdAt;
@Column(name = "updated_at")
private LocalDateTime updatedAt;
@PrePersist
protected void onCreate() {
createdAt = LocalDateTime.now();
updatedAt = LocalDateTime.now();
}
@PreUpdate
protected void onUpdate() {
updatedAt = LocalDateTime.now();
}
// Getter和Setter方法
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
public String getFirstName() { return firstName; }
public void setFirstName(String firstName) { this.firstName = firstName; }
public String getLastName() { return lastName; }
public void setLastName(String lastName) { this.lastName = lastName; }
public String getPhone() { return phone; }
public void setPhone(String phone) { this.phone = phone; }
public Boolean getEnabled() { return enabled; }
public void setEnabled(Boolean enabled) { this.enabled = enabled; }
public LocalDateTime getCreatedAt() { return createdAt; }
public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; }
public LocalDateTime getUpdatedAt() { return updatedAt; }
public void setUpdatedAt(LocalDateTime updatedAt) { this.updatedAt = updatedAt; }
}
用户Repository
java
// UserRepository.java
package com.example.userservice.repository;
import com.example.userservice.model.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByUsername(String username);
Optional<User> findByEmail(String email);
List<User> findByEnabled(Boolean enabled);
@Query("SELECT u FROM User u WHERE u.firstName LIKE %:keyword% OR u.lastName LIKE %:keyword%")
List<User> findByKeyword(@Param("keyword") String keyword);
@Query("SELECT COUNT(u) FROM User u WHERE u.enabled = true")
long countActiveUsers();
boolean existsByUsername(String username);
boolean existsByEmail(String email);
}
用户Service
java
// UserService.java
package com.example.userservice.service;
import com.example.userservice.model.User;
import com.example.userservice.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Optional;
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
@Autowired
private PasswordEncoder passwordEncoder;
@Transactional
public User createUser(User user) {
// 验证用户信息
validateUser(user);
// 检查用户名和邮箱是否已存在
if (userRepository.existsByUsername(user.getUsername())) {
throw new RuntimeException("用户名已存在: " + user.getUsername());
}
if (userRepository.existsByEmail(user.getEmail())) {
throw new RuntimeException("邮箱已被注册: " + user.getEmail());
}
// 加密密码
user.setPassword(passwordEncoder.encode(user.getPassword()));
user.setEnabled(true);
return userRepository.save(user);
}
@Transactional(readOnly = true)
public Optional<User> getUserById(Long id) {
return userRepository.findById(id);
}
@Transactional(readOnly = true)
public Optional<User> getUserByUsername(String username) {
return userRepository.findByUsername(username);
}
@Transactional(readOnly = true)
public Optional<User> getUserByEmail(String email) {
return userRepository.findByEmail(email);
}
@Transactional(readOnly = true)
public List<User> getAllUsers() {
return userRepository.findAll();
}
@Transactional(readOnly = true)
public List<User> getActiveUsers() {
return userRepository.findByEnabled(true);
}
@Transactional(readOnly = true)
public List<User> searchUsersByKeyword(String keyword) {
return userRepository.findByKeyword(keyword);
}
@Transactional
public User updateUser(Long id, User updateUser) {
User existingUser = userRepository.findById(id)
.orElseThrow(() -> new RuntimeException("用户不存在, ID: " + id));
// 更新允许修改的字段
if (updateUser.getFirstName() != null) {
existingUser.setFirstName(updateUser.getFirstName());
}
if (updateUser.getLastName() != null) {
existingUser.setLastName(updateUser.getLastName());
}
if (updateUser.getPhone() != null) {
existingUser.setPhone(updateUser.getPhone());
}
return userRepository.save(existingUser);
}
@Transactional
public void deleteUser(Long id) {
User user = userRepository.findById(id)
.orElseThrow(() -> new RuntimeException("用户不存在, ID: " + id));
userRepository.delete(user);
}
@Transactional
public void updateUserStatus(Long id, boolean enabled) {
User user = userRepository.findById(id)
.orElseThrow(() -> new RuntimeException("用户不存在, ID: " + id));
user.setEnabled(enabled);
userRepository.save(user);
}
public long getActiveUserCount() {
return userRepository.countActiveUsers();
}
private void validateUser(User user) {
if (user.getUsername() == null || user.getUsername().trim().isEmpty()) {
throw new RuntimeException("用户名不能为空");
}
if (user.getEmail() == null || user.getEmail().trim().isEmpty()) {
throw new RuntimeException("邮箱不能为空");
}
if (user.getPassword() == null || user.getPassword().trim().isEmpty()) {
throw new RuntimeException("密码不能为空");
}
if (user.getUsername().length() < 3 || user.getUsername().length() > 20) {
throw new RuntimeException("用户名长度必须在3-20个字符之间");
}
if (user.getPassword().length() < 6) {
throw new RuntimeException("密码长度不能少于6个字符");
}
}
}
用户Controller
java
// UserController.java
package com.example.userservice.controller;
import com.example.userservice.model.User;
import com.example.userservice.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Optional;
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserService userService;
@PostMapping
public ResponseEntity<User> createUser(@RequestBody User user) {
User createdUser = userService.createUser(user);
return ResponseEntity.ok(createdUser);
}
@GetMapping("/{id}")
public ResponseEntity<User> getUserById(@PathVariable Long id) {
Optional<User> user = userService.getUserById(id);
return user.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
@GetMapping("/username/{username}")
public ResponseEntity<User> getUserByUsername(@PathVariable String username) {
Optional<User> user = userService.getUserByUsername(username);
return user.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
@GetMapping("/email/{email}")
public ResponseEntity<User> getUserByEmail(@PathVariable String email) {
Optional<User> user = userService.getUserByEmail(email);
return user.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
@GetMapping
public ResponseEntity<List<User>> getAllUsers() {
List<User> users = userService.getAllUsers();
return ResponseEntity.ok(users);
}
@GetMapping("/active")
public ResponseEntity<List<User>> getActiveUsers() {
List<User> users = userService.getActiveUsers();
return ResponseEntity.ok(users);
}
@GetMapping("/search")
public ResponseEntity<List<User>> searchUsers(@RequestParam String keyword) {
List<User> users = userService.searchUsersByKeyword(keyword);
return ResponseEntity.ok(users);
}
@PutMapping("/{id}")
public ResponseEntity<User> updateUser(@PathVariable Long id, @RequestBody User user) {
User updatedUser = userService.updateUser(id, user);
return ResponseEntity.ok(updatedUser);
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
userService.deleteUser(id);
return ResponseEntity.ok().build();
}
@PatchMapping("/{id}/status")
public ResponseEntity<Void> updateUserStatus(@PathVariable Long id, @RequestParam boolean enabled) {
userService.updateUserStatus(id, enabled);
return ResponseEntity.ok().build();
}
@GetMapping("/stats/active-count")
public ResponseEntity<Long> getActiveUserCount() {
long count = userService.getActiveUserCount();
return ResponseEntity.ok(count);
}
}
✅ 第四部分:服务间通信与熔断器(60分钟)
1. Feign客户端
Feign客户端配置
java
// OrderServiceClient.java
package com.example.userservice.client;
import com.example.userservice.dto.OrderDTO;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
@FeignClient(name = "order-service", fallback = OrderServiceFallback.class)
public interface OrderServiceClient {
@GetMapping("/api/orders/user/{userId}")
List<OrderDTO> getUserOrders(@PathVariable("userId") Long userId);
@GetMapping("/api/orders/user/{userId}/recent")
List<OrderDTO> getUserRecentOrders(@PathVariable("userId") Long userId,
@RequestParam("limit") int limit);
@GetMapping("/api/orders/user/{userId}/stats")
OrderStatsDTO getUserOrderStats(@PathVariable("userId") Long userId);
}
Feign降级处理
java
// OrderServiceFallback.java
package com.example.userservice.client;
import com.example.userservice.dto.OrderDTO;
import com.example.userservice.dto.OrderStatsDTO;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
@Component
public class OrderServiceFallback implements OrderServiceClient {
@Override
public List<OrderDTO> getUserOrders(Long userId) {
// 返回空列表作为降级策略
return new ArrayList<>();
}
@Override
public List<OrderDTO> getUserRecentOrders(Long userId, int limit) {
// 返回空列表作为降级策略
return new ArrayList<>();
}
@Override
public OrderStatsDTO getUserOrderStats(Long userId) {
// 返回默认统计信息作为降级策略
OrderStatsDTO stats = new OrderStatsDTO();
stats.setTotalOrders(0);
stats.setTotalAmount(0.0);
stats.setAverageAmount(0.0);
return stats;
}
}
2. 熔断器配置
Hystrix配置
yaml
# user-service/src/main/resources/application.yml
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 5000
timeout:
enabled: true
circuitBreaker:
requestVolumeThreshold: 20
errorThresholdPercentage: 50
sleepWindowInMilliseconds: 5000
fallback:
enabled: true
threadpool:
default:
coreSize: 10
maxQueueSize: 100
queueSizeRejectionThreshold: 100
熔断器监控
java
// HystrixMetricsController.java
package com.example.userservice.controller;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/hystrix")
public class HystrixMetricsController {
@HystrixCommand(fallbackMethod = "getHystrixMetricsFallback")
@GetMapping("/metrics")
public String getHystrixMetrics() {
// 模拟获取Hystrix指标
return "Hystrix metrics data";
}
public String getHystrixMetricsFallback() {
return "Hystrix metrics unavailable";
}
}
🎯 今日学习总结
1. 掌握的核心技能
- ✅ 微服务架构设计原则
- ✅ Spring Cloud基础组件配置
- ✅ 服务注册与发现机制
- ✅ 配置中心的使用
- ✅ 微服务间通信
2. 微服务架构特点
- 服务拆分:按业务领域划分服务边界
- 独立部署:每个服务可以独立开发部署
- 技术多样性:不同服务可以使用不同技术栈
- 数据隔离:每个服务拥有独立数据库
- 分布式管理:通过服务注册发现实现
3. Spring Cloud组件
- Eureka:服务注册与发现
- Config Server:配置中心
- Feign:声明式HTTP客户端
- Hystrix:熔断器
- Ribbon:负载均衡
4. 下一步学习方向
- 服务网关配置
- 分布式事务管理
- 服务监控与追踪
- 容器化部署
- 微服务测试策略
学习建议
- 架构设计:理解微服务拆分原则和边界设计
- 配置管理:学会使用配置中心管理不同环境配置
- 服务通信:掌握同步和异步服务间通信方式
- 容错处理:理解熔断器、降级等容错机制
- 监控运维:学会使用Actuator监控服务状态