Java学习第14天 - 微服务架构与Spring Cloud

学习时间: 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. 下一步学习方向

  • 服务网关配置
  • 分布式事务管理
  • 服务监控与追踪
  • 容器化部署
  • 微服务测试策略

学习建议

  1. 架构设计:理解微服务拆分原则和边界设计
  2. 配置管理:学会使用配置中心管理不同环境配置
  3. 服务通信:掌握同步和异步服务间通信方式
  4. 容错处理:理解熔断器、降级等容错机制
  5. 监控运维:学会使用Actuator监控服务状态
相关推荐
whitepure3 分钟前
我如何理解与追求整洁代码
java·后端·代码规范
用户83562907805114 分钟前
Java高效读取Excel表格数据教程
java·后端
yinke小琪17 分钟前
今天解析一下从代码到架构:Java后端开发的"破局"与"新生"
java·后端·架构
渣哥37 分钟前
为什么越来越多公司选择 JAVA?一个老程序员的观察笔记
java
码出极致1 小时前
电商支付场景下基于 Redis 的 Seata 分布式事务生产实践方案
java·后端
chen_note1 小时前
Redis数据持久化——RDB快照和Aof日志追加
java·数据库·mybatis·持久化·aof·rdb
superlls1 小时前
(Redis)缓存三大问题及布隆过滤器详解
java·后端·spring
阿里嘎多哈基米2 小时前
二、JVM 入门——(三)栈
java·开发语言·jvm·线程·
lovebugs2 小时前
🚀 Kubernetes核心命令详解:Java开发者必备指南
java·后端·kubernetes
快乐肚皮2 小时前
IntelliJ IDEA Debug 模式功能指南
java·ide·intellij-idea·debug