在《黑马商城》这种典型的微服务架构中,随着业务增长和用户访问量的增加,系统面临的风险也随之而来。例如,恶意请求、突发流量高峰等都可能导致服务雪崩,进而影响整个系统的可用性。因此,对微服务进行保护显得尤为重要。本文将深入探讨《黑马商城》微服务保护的核心技术,包括限流、熔断和降级,并提供简单易懂的注释版代码示例,帮助大家更好地理解和应用。
问题场景重现:高并发下的服务雪崩
想象一下《黑马商城》正在进行促销活动,大量的用户涌入抢购商品。如果没有进行适当的保护,订单服务可能会因为处理大量的请求而过载,导致响应时间变长甚至崩溃。由于服务之间的依赖关系,订单服务的崩溃可能会蔓延到商品服务、支付服务等,最终导致整个系统瘫痪,这就是典型的服务雪崩。
底层原理深度剖析:限流、熔断、降级
为了避免服务雪崩,我们需要引入限流、熔断和降级这三种保护机制:
- 限流 (Rate Limiting): 控制服务接收请求的速率,防止过多的请求压垮服务。常见的限流算法有令牌桶算法、漏桶算法等。例如,我们可以限制每个用户每分钟只能创建 10 个订单,超出限制的请求直接拒绝或排队等待。
- 熔断 (Circuit Breaker): 当某个服务出现故障(例如响应时间过长、错误率过高)时,熔断器会立即切断对该服务的调用,防止故障扩散。一段时间后,熔断器会尝试恢复对该服务的调用,如果服务恢复正常,则关闭熔断器。
- 降级 (Fallback): 当服务出现故障或被熔断时,降级机制会提供一个备用方案,保证用户体验。例如,当
商品服务无法正常访问时,可以返回一个预先准备好的静态商品列表。
这三者之间的关系是互补的:限流用于预防,熔断用于止损,降级用于善后。
具体的代码/配置解决方案
这里以 Spring Cloud Gateway + Sentinel 为例,演示如何在《黑马商城》中实现微服务保护。
1. 引入 Sentinel 依赖
在 pom.xml 文件中添加 Sentinel 的依赖:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
2. 配置 Sentinel
在 application.yml 中配置 Sentinel:
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8080 # Sentinel 控制台地址
port: 8719 # Sentinel 客户端端口
# 关闭自动数据源配置,使用自定义数据源
datasource:
flow:
nacos:
server-addr: localhost:8848 # Nacos 地址
data-id: sentinel-flow-rules # Nacos 中存储流控规则的 Data ID
group-id: DEFAULT_GROUP
rule-type: flow # 规则类型
degrade:
nacos:
server-addr: localhost:8848
data-id: sentinel-degrade-rules # Nacos 中存储降级规则的 Data ID
group-id: DEFAULT_GROUP
rule-type: degrade # 规则类型
authority:
nacos:
server-addr: localhost:8848
data-id: sentinel-authority-rules # Nacos 中存储授权规则的 Data ID
group-id: DEFAULT_GROUP
rule-type: authority # 规则类型
system:
nacos:
server-addr: localhost:8848
data-id: sentinel-system-rules # Nacos 中存储系统规则的 Data ID
group-id: DEFAULT_GROUP
rule-type: system # 规则类型
3. 定义流控规则
在 Sentinel 控制台中定义流控规则,或者通过 Nacos 配置。例如,限制 订单服务 的 QPS 为 100:
[
{
"resource": "/order/create", // 需要保护的资源
"limitApp": "default",
"grade": 1, // QPS 限流
"count": 100, // QPS 阈值
"strategy": 0, // 直接拒绝
"controlBehavior": 0, // 快速失败
"clusterMode": false
}
]
4. 代码中使用 Sentinel API
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class OrderController {
@GetMapping("/order/create")
@SentinelResource(value = "/order/create", fallback = "createOrderFallback") // 定义资源,并指定 fallback 方法
public String createOrder() {
// 创建订单的业务逻辑
return "Order created successfully";
}
public String createOrderFallback() {
// 降级逻辑,例如返回提示信息
return "Order creation is busy, please try again later.";
}
}
5. 熔断降级配置 (示例)
通过 Sentinel 控制台或 Nacos 配置熔断降级规则。例如,当 订单服务 的平均响应时间超过 500ms 时,进行熔断:
[
{
"resource": "/order/create", // 对应的资源
"grade": 0, // 熔断降级策略 (0: 平均响应时间, 1: 异常比例, 2: 异常数)
"count": 500, // 阈值 (单位毫秒,针对 RT 策略)
"timeWindow": 10, // 熔断时长 (单位秒)
"statIntervalMs": 1000, // 统计时间窗口 (单位毫秒)
"minRequestAmount": 5, // 最小请求数量
"slowRatioThreshold": 0.5, // 慢调用比例 (RT 策略下有效)
"avgRtThreshold": 500 // 平均响应时间 (RT 策略下有效)
}
]
6. Nginx 反向代理与负载均衡的配合
在实际部署中,通常会使用 Nginx 作为反向代理服务器,对多个 订单服务 实例进行负载均衡。配合 Sentinel 的流控,可以更好地保护后端服务。
upstream order_service {
server order-service-instance1:8080;
server order-service-instance2:8080;
# ... 其他实例
}
server {
listen 80;
server_name example.com;
location /order/ {
proxy_pass http://order_service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Nginx 可以配置 upstream 来实现负载均衡,将请求分发到不同的后端服务实例。通过监控 Nginx 的并发连接数,可以及时发现并处理潜在的性能瓶颈。同时也可以使用宝塔面板等工具进行可视化管理和配置。
实战避坑经验总结
- 不要过度限流: 过度限流可能会影响正常用户的访问,需要在保证系统稳定性的前提下,尽量减少对用户体验的影响。
- 合理配置熔断策略: 熔断策略的配置需要根据实际情况进行调整,避免误判导致服务无法正常访问。
- 做好监控和告警: 监控服务的各项指标(例如响应时间、错误率),并设置合理的告警阈值,及时发现和处理问题。
- 考虑异地多活架构: 为了提高系统的可用性,可以考虑部署异地多活架构,即使某个地区的服务出现故障,也可以切换到其他地区的服务。
- 灰度发布: 升级服务时,采用灰度发布的方式,逐步将流量导向新版本,减少风险。
通过以上措施,可以有效地保护《黑马商城》的微服务架构,提高系统的稳定性和可用性。
冠军资讯
代码一只喵