Spring Cloud微服务框架,实战企业级优惠券系统---xingkeit.top/7727/
微服务架构是 Java 后端进阶的必经之路,但初学者往往被复杂的组件配置(Eureka、Gateway、Feign、Config)劝退。其实,学习微服务的最佳方式不是死记硬背,而是通过一个具体的业务场景去串联各个组件。
本文将以一个 “高并发优惠券系统” 为例,带你从 0 到 1 搭建一套标准的 Spring Cloud Alibaba 微服务架构。我们将覆盖服务注册、负载均衡、远程调用、网关路由等核心知识点,并提供核心实战代码。
一、 项目架构与模块划分
在实际企业开发中,微服务的划分遵循“高内聚、低耦合”原则。对于优惠券系统,我们将其拆分为三个核心服务:
- coupon-service(优惠券服务) :负责优惠券的增删改查、库存扣减。
- user-service(用户服务) :负责用户信息管理、领取资格校验。
- gateway-service(网关服务) :系统的统一入口,负责路由转发、鉴权。
技术选型:Spring Boot 3.x + Spring Cloud Alibaba 2022.x + Nacos + OpenFeign + LoadBalancer。
二、 基础设施:服务注册与发现
微服务之间要相互调用,首先得“找到对方”。Nacos 是目前最主流的注册中心与配置中心。
1. 父工程与公共模块依赖
2. 优惠券服务启动类
java
复制
package com.itcast.coupon;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient // 开启服务注册与发现
public class CouponApplication {
public static void main(String[] args) {
SpringApplication.run(CouponApplication.class, args);
}
}
3. 配置文件
yaml
复制
# application.yml
server:
port: 8081
spring:
application:
name: coupon-service # 服务名称,非常重要
cloud:
nacos:
server-addr: 127.0.0.1:8848 # Nacos 地址
discovery:
namespace: public
三、 核心业务:OpenFeign 声明式远程调用
假设用户领取优惠券时,用户服务需要调用优惠券服务来扣减库存。在微服务中,我们不写原生的 HttpClient,而是使用 OpenFeign,它像调用本地方法一样调用远程服务。
1. 在优惠券服务中提供接口
java
复制
@RestController
@RequestMapping("/coupon")
public class CouponController {
@Autowired
private CouponService couponService;
@PostMapping("/deduct")
public String deduct(@RequestParam("couponId") Long couponId, @RequestParam("userId") Long userId) {
boolean success = couponService.deductStock(couponId, userId);
return success ? "领取成功" : "领取失败(库存不足或已领取)";
}
}
2. 在用户服务中定义 Feign 客户端
首先引入依赖
定义接口:
java
复制
package com.itcast.user.feign;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
// value = "coupon-service" 对应被调用服务的 spring.application.name
@FeignClient(value = "coupon-service")
public interface CouponFeignClient {
// 定义方法签名,要完全对齐目标 Controller 的接口定义
@PostMapping("/coupon/deduct")
String deductStock(@RequestParam("couponId") Long couponId, @RequestParam("userId") Long userId);
}
3. 在用户服务中调用
java
复制
@Service
public class UserOrderService {
@Autowired
private CouponFeignClient couponFeignClient;
public void placeOrderWithCoupon(Long userId, Long couponId) {
// ... 订单逻辑 ...
// 远程调用优惠券服务扣减库存
// 这里实现了服务间的解耦,User 服务不需要知道 Coupon 服务的具体 IP,只需知道名字
String result = couponFeignClient.deductStock(couponId, userId);
System.out.println("远程调用结果:" + result);
}
}
四、 统一入口:Gateway 网关路由
前端(App、Web)不能直接访问后端的微服务(8081、8082端口),这样不安全且难以管理。我们需要一个网关作为“前台接待”。
1. Gateway 服务依赖
2. 路由配置实战
yaml
复制
server:
port: 9000 # 网关端口
spring:
application:
name: gateway-service
cloud:
nacos:
server-addr: 127.0.0.1:8848
gateway:
routes:
# 路由到用户服务
- id: user-route
# lb:// 代表 LoadBalance,从 Nacos 拉取服务列表并负载均衡
uri: lb://user-service
predicates:
# 前端请求 http://gateway:9000/api/user/** 会转发到这里
- Path=/api/user/**
filters:
# 去掉路径前缀,例如 /api/user/1 -> user/1
- StripPrefix=1
# 路由到优惠券服务
- id: coupon-route
uri: lb://coupon-service
predicates:
- Path=/api/coupon/**
filters:
- StripPrefix=1
效果:前端只需请求 http://localhost:9000/api/coupon/deduct,网关会自动将其转发给 coupon-service 的 /coupon/deduct 接口。
五、 总结:微服务开发的“全景图”
通过这个优惠券系统的实战,我们串起了微服务开发的核心流程:
- 服务拆分:根据业务领域拆分 User、Coupon 服务。
- 服务治理:利用 Nacos 实现服务的自动注册与发现。
- 服务通信:利用 OpenFeign 实现服务间优雅、负载均衡的调用。
- 统一入口:利用 Gateway 实现路由转发与请求过滤。
掌握了这套组合拳,你就已经具备了搭建企业级微服务架构的入场券。接下来可以继续探索 Sentinel(熔断限流) 、Seata(分布式事务) 等更高级的组件,让你的架构在“高并发”场景下稳如泰山。