微服务架构实战:Spring Boot + Spring Cloud 从入门到精通

微服务架构实战:Spring Boot + Spring Cloud 从入门到精通

📖 前言

在当今互联网高速发展的时代,传统的单体架构已经难以满足业务快速迭代和高并发的需求。微服务架构作为一种现代化的软件架构风格,已经成为构建大型分布式系统的主流方案。

本文将从实际项目经验出发,深入讲解微服务架构的核心概念、技术选型,并通过 Spring Boot + Spring Cloud 的实战示例,带你从单体架构演进到分布式微服务架构。

适合人群:

  • 有Java/Spring Boot基础的后端开发工程师
  • 想了解微服务架构的技术爱好者
  • 正在考虑从单体架构迁移的团队

🎯 一、什么是微服务架构?

1.1 微服务的定义

微服务架构(Microservices Architecture)是一种将单一应用程序开发为一组小型服务的方法,每个服务运行在自己的进程中,服务之间通过轻量级的通信机制(通常是HTTP/REST API)进行交互。

"Microservices are small, autonomous services that work together." --- Sam Newman, Building Microservices

1.2 核心特征

| 特征 | 说明 | |------|------| | 服务组件化 | 以服务为单位进行组件化,而非库 | | 围绕业务能力组织 | 每个服务对应一个业务能力 | | 产品而非项目 | 团队负责整个产品的生命周期 | | 去中心化治理 | 每个服务可以选择最适合的技术栈 | | 去中心化数据管理 | 每个服务管理自己的数据库 | | 基础设施自动化 | CI/CD、自动化测试、容器化部署 | | 容错设计 | 服务失败不应影响整个系统 | | 演进式设计 | 系统可以逐步演进和优化 |


🔄 二、单体架构 vs 微服务架构

2.1 单体架构

复制代码
┌─────────────────────────────────────────┐
│              单体应用                    │
│  ┌─────────┐ ┌─────────┐ ┌─────────┐   │
│  │ 用户模块 │ │ 订单模块 │ │ 支付模块 │   │
│  └────┬────┘ └────┬────┘ └────┬────┘   │
│       │          │          │          │
│  ┌────┴──────────┴──────────┴────┐    │
│  │         共享数据库            │    │
│  └───────────────────────────────┘    │
└─────────────────────────────────────────┘

单体架构的问题:

  • 代码耦合度高,牵一发而动全身
  • 部署周期长,一个小改动需要重新部署整个应用
  • 技术栈受限,整个应用必须使用同一套技术
  • 扩展困难,无法针对热点模块单独扩展
  • 故障传播,一个模块的问题可能导致整个系统崩溃

2.2 微服务架构

复制代码
┌──────────┐    ┌──────────┐    ┌──────────┐
│ 用户服务  │    │ 订单服务  │    │ 支付服务  │
│ (User)   │    │ (Order)  │    │ (Payment)│
└────┬─────┘    └────┬─────┘    └────┬─────┘
     │              │              │
     └──────────────┼──────────────┘
                    │
              ┌─────┴─────┐
              │  API 网关  │
              └───────────┘
                    │
     ┌──────────────┼──────────────┐
     │              │              │
┌────┴─────┐  ┌────┴─────┐  ┌────┴─────┐
│  MySQL   │  │  MongoDB │  │  Redis   │
└──────────┘  └──────────┘  └──────────┘

微服务架构的优势:

  • 服务独立部署,快速迭代
  • 技术栈灵活,不同服务可以选择不同技术
  • 按需扩展,针对热点服务单独扩容
  • 故障隔离,一个服务故障不影响其他服务
  • 团队自治,小团队独立开发和维护

🛠️ 三、Spring Cloud 核心组件

Spring Cloud 提供了一整套微服务解决方案,以下是核心组件:

| 组件 | 功能 | 常用实现 | |------|------|----------| | 服务注册与发现 | 服务自动注册和发现 | Eureka、Nacos、Consul | | 配置中心 | 统一管理配置 | Spring Cloud Config、Nacos | | API 网关 | 统一入口、路由、鉴权 | Spring Cloud Gateway | | 负载均衡 | 请求分发 | Spring Cloud LoadBalancer | | 熔断器 | 服务降级、故障隔离 | Resilience4j | | 链路追踪 | 分布式调用链追踪 | Micrometer Tracing + Zipkin | | 消息总线 | 配置刷新、事件广播 | Spring Cloud Bus |


💻 四、实战:搭建微服务系统

4.1 项目结构

复制代码
microservice-demo/
├── eureka-server/          # 服务注册中心
├── config-server/          # 配置中心
├── gateway-service/        # API网关
├── user-service/           # 用户服务(提供者)
├── order-service/          # 订单服务(消费者)
└── pom.xml                 # 父POM

4.2 父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-demo</artifactId>
    <version>1.0.0</version>
    <packaging>pom</packaging>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.0</version>
    </parent>
    
    <properties>
        <java.version>17</java.version>
        <spring-cloud.version>2023.0.0</spring-cloud.version>
    </properties>
    
    <modules>
        <module>eureka-server</module>
        <module>config-server</module>
        <module>gateway-service</module>
        <module>user-service</module>
        <module>order-service</module>
    </modules>
    
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

4.3 Eureka 服务注册中心

1. 添加依赖

xml 复制代码
<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>
</dependencies>

2. 启动类

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  // 开启Eureka服务端
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}

3. 配置文件 application.yml

yaml 复制代码
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: 5000

4.4 用户服务(服务提供者)

1. 添加依赖

xml 复制代码
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>runtime</scope>
    </dependency>
</dependencies>

2. 实体类 User.java

java 复制代码
package com.example.user.entity;

import jakarta.persistence.*;
import lombok.Data;

@Data
@Entity
@Table(name = "users")
public class User {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(nullable = false, unique = true)
    private String username;
    
    @Column(nullable = false)
    private String email;
    
    @Column(nullable = false)
    private String phone;
    
    @Column(name = "created_at")
    private LocalDateTime createdAt;
    
    @PrePersist
    protected void onCreate() {
        createdAt = LocalDateTime.now();
    }
}

3. Repository 接口

java 复制代码
package com.example.user.repository;

import com.example.user.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.Optional;

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    
    Optional<User> findByUsername(String username);
    
    Optional<User> findByEmail(String email);
    
    boolean existsByUsername(String username);
}

4. Service 层

java 复制代码
package com.example.user.service;

import com.example.user.entity.User;
import com.example.user.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;

@Service
@RequiredArgsConstructor
public class UserService {
    
    private final UserRepository userRepository;
    
    /**
     * 创建用户
     */
    @Transactional
    public User createUser(User user) {
        if (userRepository.existsByUsername(user.getUsername())) {
            throw new RuntimeException("用户名已存在: " + user.getUsername());
        }
        return userRepository.save(user);
    }
    
    /**
     * 根据ID查询用户
     */
    public Optional<User> getUserById(Long id) {
        return userRepository.findById(id);
    }
    
    /**
     * 根据用户名查询用户
     */
    public Optional<User> getUserByUsername(String username) {
        return userRepository.findByUsername(username);
    }
    
    /**
     * 获取所有用户
     */
    public List<User> getAllUsers() {
        return userRepository.findAll();
    }
    
    /**
     * 更新用户
     */
    @Transactional
    public User updateUser(Long id, User userDetails) {
        User user = userRepository.findById(id)
            .orElseThrow(() -> new RuntimeException("用户不存在: " + id));
        
        user.setEmail(userDetails.getEmail());
        user.setPhone(userDetails.getPhone());
        
        return userRepository.save(user);
    }
    
    /**
     * 删除用户
     */
    @Transactional
    public void deleteUser(Long id) {
        userRepository.deleteById(id);
    }
}

5. Controller 层

java 复制代码
package com.example.user.controller;

import com.example.user.entity.User;
import com.example.user.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api/users")
@RequiredArgsConstructor
public class UserController {
    
    private final UserService userService;
    
    /**
     * 创建用户
     * POST /api/users
     */
    @PostMapping
    public ResponseEntity<User> createUser(@RequestBody User user) {
        User createdUser = userService.createUser(user);
        return ResponseEntity.status(HttpStatus.CREATED).body(createdUser);
    }
    
    /**
     * 获取用户详情
     * GET /api/users/{id}
     */
    @GetMapping("/{id}")
    public ResponseEntity<User> getUserById(@PathVariable Long id) {
        return userService.getUserById(id)
            .map(ResponseEntity::ok)
            .orElse(ResponseEntity.notFound().build());
    }
    
    /**
     * 获取所有用户
     * GET /api/users
     */
    @GetMapping
    public ResponseEntity<List<User>> getAllUsers() {
        return ResponseEntity.ok(userService.getAllUsers());
    }
    
    /**
     * 更新用户
     * PUT /api/users/{id}
     */
    @PutMapping("/{id}")
    public ResponseEntity<User> updateUser(
            @PathVariable Long id, 
            @RequestBody User user) {
        return ResponseEntity.ok(userService.updateUser(id, user));
    }
    
    /**
     * 删除用户
     * DELETE /api/users/{id}
     */
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
        userService.deleteUser(id);
        return ResponseEntity.noContent().build();
    }
}

6. 配置文件 application.yml

yaml 复制代码
server:
  port: 8081

spring:
  application:
    name: user-service
  datasource:
    url: jdbc:h2:mem:userdb
    driver-class-name: org.h2.Driver
  jpa:
    hibernate:
      ddl-auto: create-drop
    show-sql: true

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  instance:
    # 使用IP地址注册
    prefer-ip-address: true
    # 实例ID
    instance-id: ${spring.application.name}:${server.port}

4.5 订单服务(服务消费者)

1. 添加依赖

xml 复制代码
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <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-openfeign</artifactId>
    </dependency>
    <dependency>
        <groupId>io.github.openfeign</groupId>
        <artifactId>feign-okhttp</artifactId>
    </dependency>
</dependencies>

2. 启动类开启Feign

java 复制代码
package com.example.order;

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  // 开启Feign
public class OrderServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderServiceApplication.class, args);
    }
}

3. Feign 客户端接口

java 复制代码
package com.example.order.feign;

import com.example.order.dto.UserDTO;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

/**
 * Feign客户端 - 调用用户服务
 * name: 服务名称(对应eureka中的服务名)
 * fallback: 降级处理类
 */
@FeignClient(name = "user-service", fallbackFactory = UserFeignFallbackFactory.class)
public interface UserFeignClient {
    
    @GetMapping("/api/users/{id}")
    UserDTO getUserById(@PathVariable("id") Long id);
}

4. Feign 降级工厂

java 复制代码
package com.example.order.feign.fallback;

import com.example.order.dto.UserDTO;
import com.example.order.feign.UserFeignClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class UserFeignFallbackFactory implements FallbackFactory<UserFeignClient> {
    
    @Override
    public UserFeignClient create(Throwable cause) {
        log.error("用户服务调用失败", cause);
        
        return new UserFeignClient() {
            @Override
            public UserDTO getUserById(Long id) {
                // 返回降级数据
                UserDTO fallbackUser = new UserDTO();
                fallbackUser.setId(id);
                fallbackUser.setUsername("未知用户");
                fallbackUser.setEmail("N/A");
                fallbackUser.setPhone("N/A");
                return fallbackUser;
            }
        };
    }
}

5. 订单服务调用用户服务

java 复制代码
package com.example.order.controller;

import com.example.order.dto.OrderDTO;
import com.example.order.dto.UserDTO;
import com.example.order.feign.UserFeignClient;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@RestController
@RequestMapping("/api/orders")
@RequiredArgsConstructor
public class OrderController {
    
    private final UserFeignClient userFeignClient;
    
    // 模拟订单数据
    private final List<OrderDTO> orders = new ArrayList<>();
    
    /**
     * 创建订单
     * POST /api/orders?userId=1&product=iPhone&amount=9999
     */
    @PostMapping
    public OrderDTO createOrder(
            @RequestParam Long userId,
            @RequestParam String product,
            @RequestParam Double amount) {
        
        // 1. 调用用户服务获取用户信息
        UserDTO user = userFeignClient.getUserById(userId);
        
        // 2. 创建订单
        OrderDTO order = new OrderDTO();
        order.setOrderId(UUID.randomUUID().toString());
        order.setUserId(userId);
        order.setUsername(user.getUsername());
        order.setProduct(product);
        order.setAmount(amount);
        order.setStatus("CREATED");
        
        orders.add(order);
        return order;
    }
    
    /**
     * 获取订单详情(包含用户信息)
     * GET /api/orders/{orderId}
     */
    @GetMapping("/{orderId}")
    public OrderDTO getOrder(@PathVariable String orderId) {
        return orders.stream()
            .filter(o -> o.getOrderId().equals(orderId))
            .findFirst()
            .orElseThrow(() -> new RuntimeException("订单不存在"));
    }
    
    /**
     * 获取用户的所有订单
     * GET /api/orders/user/{userId}
     */
    @GetMapping("/user/{userId}")
    public List<OrderDTO> getUserOrders(@PathVariable Long userId) {
        return orders.stream()
            .filter(o -> o.getUserId().equals(userId))
            .toList();
    }
}

4.6 API 网关

1. 添加依赖

xml 复制代码
<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
</dependencies>

2. 网关配置 application.yml

yaml 复制代码
server:
  port: 8080

spring:
  application:
    name: gateway-service
  cloud:
    gateway:
      # 路由配置
      routes:
        # 用户服务路由
        - id: user-service
          uri: lb://user-service  # lb:// 表示使用负载均衡
          predicates:
            - Path=/api/users/**
          filters:
            - StripPrefix=0
        
        # 订单服务路由
        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/api/orders/**
          filters:
            - StripPrefix=0
      
      # 全局跨域配置
      globalcors:
        cors-configurations:
          '[/**]':
            allowedOriginPatterns: "*"
            allowedMethods: "*"
            allowedHeaders: "*"
            allowCredentials: true

# Eureka配置
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

🔒 五、微服务设计原则

5.1 单一职责原则

每个服务只负责一个业务能力:

复制代码
✅ 正确:用户服务只处理用户相关的业务
❌ 错误:用户服务同时处理用户、订单、支付

5.2 服务自治原则

复制代码
✅ 每个服务独立开发、测试、部署、扩展
❌ 服务之间强依赖,必须同时部署

5.3 接口契约原则

java 复制代码
// 使用OpenAPI/Swagger定义接口契约
@Operation(summary = "获取用户详情")
@ApiResponse(responseCode = "200", description = "成功")
@ApiResponse(responseCode = "404", description = "用户不存在")
@GetMapping("/{id}")
public ResponseEntity<User> getUserById(
    @Parameter(description = "用户ID") @PathVariable Long id) {
    // ...
}

5.4 数据库独立原则

复制代码
✅ 每个服务拥有自己的数据库
❌ 多个服务共享同一个数据库

5.5 容错设计原则

java 复制代码
// 使用Resilience4j实现熔断
@CircuitBreaker(name = "userService", fallbackMethod = "getUserFallback")
@RateLimiter(name = "userService")
@Retry(name = "userService")
public UserDTO getUser(Long id) {
    return userFeignClient.getUserById(id);
}

// 降级方法
public UserDTO getUserFallback(Long id, Exception e) {
    log.warn("用户服务调用失败,执行降级", e);
    return UserDTO.builder()
        .id(id)
        .username("未知用户")
        .build();
}

⚠️ 六、微服务常见问题与解决方案

6.1 分布式事务问题

问题: 跨服务的数据一致性难以保证

解决方案:

java 复制代码
// 使用Seata实现分布式事务
@Service
public class OrderService {
    
    @GlobalTransactional  // Seata全局事务注解
    public void createOrder(OrderDTO order) {
        // 1. 扣减库存(库存服务)
        inventoryFeignClient.deduct(order.getProductId(), order.getQuantity());
        
        // 2. 扣减余额(账户服务)
        accountFeignClient.deduct(order.getUserId(), order.getAmount());
        
        // 3. 创建订单(本地事务)
        orderRepository.save(order);
        
        // 如果任何一步失败,所有操作都会回滚
    }
}

6.2 服务间通信问题

问题: 同步调用可能导致雪崩

解决方案: 使用消息队列实现异步通信

java 复制代码
// 生产者:订单服务
@Service
@RequiredArgsConstructor
public class OrderEventPublisher {
    
    private final RabbitTemplate rabbitTemplate;
    
    public void publishOrderCreated(OrderDTO order) {
        rabbitTemplate.convertAndSend(
            "order.exchange",
            "order.created",
            order
        );
    }
}

// 消费者:库存服务
@Component
@RequiredArgsConstructor
public class InventoryEventListener {
    
    private final InventoryService inventoryService;
    
    @RabbitListener(queues = "inventory.queue")
    public void handleOrderCreated(OrderDTO order) {
        inventoryService.deduct(order.getProductId(), order.getQuantity());
    }
}

6.3 配置管理问题

问题: 多个服务的配置分散,难以统一管理

解决方案: 使用Nacos作为配置中心

java 复制代码
// 使用Nacos动态配置
@RestController
@RefreshScope  // 支持动态刷新
public class ConfigController {
    
    @Value("${custom.config.value}")
    private String configValue;
    
    @GetMapping("/config")
    public String getConfig() {
        return configValue;
    }
}

6.4 链路追踪问题

问题: 请求经过多个服务,难以追踪完整链路

解决方案: 使用Micrometer + Zipkin

java 复制代码
// 自动集成,无需额外代码
// 1. 添加依赖
// spring-cloud-starter-sleuth
// spring-cloud-sleuth-zipkin

// 2. 配置
// spring.zipkin.base-url=http://localhost:9411
// spring.sleuth.sampler.probability=1.0

// 访问Zipkin UI: http://localhost:9411

📊 七、微服务监控与运维

7.1 Actuator 健康检查

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
yaml 复制代码
management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,prometheus
  endpoint:
    health:
      show-details: always

7.2 Prometheus + Grafana 监控

yaml 复制代码
# Prometheus配置
scrape_configs:
  - job_name: 'spring-boot'
    metrics_path: '/actuator/prometheus'
    static_configs:
      - targets: 
          - 'user-service:8081'
          - 'order-service:8082'
          - 'gateway-service:8080'

🎯 八、总结

8.1 微服务架构适用场景

| 场景 | 是否适合微服务 | |------|---------------| | 大型复杂系统 | ✅ 非常适合 | | 需要快速迭代 | ✅ 非常适合 | | 高并发场景 | ✅ 非常适合 | | 小型简单项目 | ❌ 没必要 | | 团队人数少(<10人) | ⚠️ 需要权衡 |

8.2 技术选型建议

| 组件 | 推荐方案 | 备选方案 | |------|----------|----------| | 服务注册 | Nacos | Eureka、Consul | | 配置中心 | Nacos | Apollo、Config | | API网关 | Spring Cloud Gateway | Kong、Zuul | | 服务调用 | OpenFeign | RestTemplate、WebClient | | 熔断器 | Resilience4j | Sentinel | | 分布式事务 | Seata | 本地消息表 | | 链路追踪 | Micrometer + Zipkin | SkyWalking |

8.3 下一步学习

  1. 深入学习Spring Cloud Alibaba:Nacos、Sentinel、Seata
  2. 容器化部署:Docker + Kubernetes
  3. 服务网格:Istio、Linkerd
  4. Serverless:AWS Lambda、阿里云函数计算

📚 参考资料


作者简介:张伟,杭州Java后端开发工程师,2-5年开发经验,专注于Spring Boot、微服务架构、分布式系统。正在探索Python和FastAPI,持续学习中。

如果这篇文章对你有帮助,欢迎点赞、收藏、关注!有问题欢迎在评论区交流讨论。💬

相关推荐
bang冰冰1 小时前
Trae工具安装和使用教程(新手零基础入门,全程无坑)
java·人工智能·python
阿丰资源1 小时前
基于Spring Boot的网上摄影工作室系统(源码一键运行)
java·spring boot·后端
阿维的博客日记1 小时前
容器是怎么管理 Bean 的?
java·bean
AI人工智能+电脑小能手2 小时前
【大白话说Java面试题】【Java基础篇】第40题:Java中的深拷贝和浅拷贝有什么区别
java·开发语言·后端·面试
@小匠2 小时前
云之家表单数据解析 skills (yzj-form-parser)
java
云烟成雨TD2 小时前
Spring AI Alibaba 1.x 系列【48】状态图编译配置类:CompileConfig 源码解析
java·人工智能·spring
计算机学姐2 小时前
基于微信小程序的图书馆座位预约系统【uniapp+springboot+vue】
vue.js·spring boot·微信小程序·小程序·java-ee·uni-app·intellij-idea
贫民窟的勇敢爷们3 小时前
Java 与 Python 如何选型与融合
java·开发语言·python
小宇的天下3 小时前
Calibre DESIGNrev 单元(Cell)操作核心指南
java·前端·javascript