最近有位球友问了我一个问题:如何提高系统稳定性,减少线上事故?确实系统稳定性非常重要。今天这篇文章跟大家一起聊聊这个话题,希望对你会有所帮助。
前言
最近有位球友问了我一个问题:如何提高系统稳定性,减少线上事故?
确实系统稳定性非常重要。
今天这篇文章跟大家一起聊聊这个话题,希望对你会有所帮助。
一、建立完善的可观测体系
可观测性是系统稳定性的基石。
有些小伙伴在工作中可能遇到过这样的情况:系统突然变慢,但查看CPU、内存都正常,就是找不到问题根源。
1. 多维度监控体系
// 使用Spring Boot Actuator实现健康检查
@Configuration
publicclass HealthConfig {
@Component
publicclass CustomHealthIndicator implements HealthIndicator {
@Autowired
private DataSource dataSource;
@Autowired
private RedisTemplate redisTemplate;
@Override
public Health health() {
// 检查数据库连接
if (!checkDatabase()) {
return Health.down()
.withDetail("database", "连接失败")
.build();
}
// 检查Redis连接
if (!checkRedis()) {
return Health.down()
.withDetail("redis", "连接异常")
.build();
}
// 检查磁盘空间
if (!checkDiskSpace()) {
return Health.down()
.withDetail("disk", "空间不足")
.build();
}
return Health.up().build();
}
private boolean checkDatabase() {
try {
return dataSource.getConnection().isValid(5);
} catch (Exception e) {
returnfalse;
}
}
private boolean checkRedis() {
try {
redisTemplate.opsForValue().get("health_check");
returntrue;
} catch (Exception e) {
returnfalse;
}
}
private boolean checkDiskSpace() {
File file = new File(".");
return file.getFreeSpace() > 1024 * 1024 * 1024; // 剩余1GB以上
}
}
}
代码逻辑解析:
- 通过实现HealthIndicator接口,我们可以自定义健康检查逻辑
- 检查数据库连接是否正常
- 检查Redis等中间件连接状态
- 检查系统资源如磁盘空间
- 当任何组件异常时,立即返回down状态,便于监控系统及时告警
2. 分布式链路追踪
// 使用Spring Cloud Sleuth实现链路追踪
@RestController
publicclass OrderController {
privatefinal Tracer tracer;
public OrderController(Tracer tracer) {
this.tracer = tracer;
}
@PostMapping("/orders")
public ResponseEntity<Order> createOrder(@RequestBody OrderRequest request) {
// 开始新的Span
Span span = tracer.nextSpan().name("createOrder").start();
try (Tracer.SpanInScope ws = tracer.withSpanInScope(span)) {
// 记录业务操作
span.tag("user.id", request.getUserId());
span.tag("order.amount", String.valueOf(request.getAmount()));
// 执行订单创建逻辑
Order order = orderService.createOrder(request);
// 记录成功结果
span.event("order.created");
return ResponseEntity.ok(order);
} catch (Exception e) {
// 记录错误信息
span.error(e);
throw e;
} finally {
span.finish();
}
}
}
链路追踪的价值:
- 快速定位性能瓶颈
- 可视化服务调用关系
- 分析跨服务异常
二、构建弹性架构:限流、降级、熔断
有些小伙伴在工作中可能遇到过这样的场景:大促期间流量激增,系统被瞬间打垮。
这时候就需要弹性架构来保护系统。
1. 智能限流策略
// 使用Resilience4j实现限流
@Configuration
publicclass RateLimitConfig {
@Bean
public RateLimiterRegistry rateLimiterRegistry() {
return RateLimiterRegistry.of(
RateLimiterConfig.custom()
.limitForPeriod(100) // 每秒100个请求
.limitRefreshPeriod(Duration.ofSeconds(1))
.timeoutDuration(Duration.ofMillis(100))
.build()
);
}
@Service
publicclass OrderService {
privatefinal RateLimiter rateLimiter;
public OrderService(RateLimiterRegistry registry) {
this.rateLimiter = registry.rateLimiter("orderService");
}
@RateLimiter(name = "orderService", fallbackMethod = "createOrderFallback")
public Order createOrder(OrderRequest request) {
// 正常的订单创建逻辑
return processOrderCreation(request);
}
// 降级方法
public Order createOrderFallback(OrderRequest request, Exception e) {
// 记录降级日志
log.warn("订单服务触发限流降级, userId: {}", request.getUserId());
// 返回兜底数据或抛出业务异常
thrownew BusinessException("系统繁忙,请稍后重试");
}
}
}
限流策略详解:
- 固定窗口:简单但存在临界问题
- 滑动窗口:更精确但实现复杂
- 令牌桶:允许突发流量
- 漏桶:平滑流量,保持稳定速率
2. 服务熔断机制
// 熔断器配置
@Configuration
publicclass CircuitBreakerConfig {
@Bean
public CircuitBreakerRegistry circuitBreakerRegistry() {
return CircuitBreakerRegistry.of(
CircuitBreakerConfig.custom()
.failureRateThreshold(50) // 失败率阈值50%
.slowCallRateThreshold(50) // 慢调用阈值50%
.slowCallDurationThreshold(Duration.ofSeconds(2)) // 2秒以上算慢调用
.waitDurationInOpenState(Duration.ofSeconds(60)) // 打开状态等待60秒
.permittedNumberOfCallsInHalfOpenState(10) // 半开状态允许10个调用
.minimumNumberOfCalls(10) // 最小调用数
.slidingWindowType(SlidingWindowType.COUNT_BASED)
.slidingWindowSize(10) // 滑动窗口大小
.build()
);
}
@Service
publicclass PaymentService {
privatefinal CircuitBreaker circuitBreaker;
public PaymentService(CircuitBreakerRegistry registry) {
this.circuitBreaker = registry.circuitBreaker("paymentService");
}
public PaymentResult processPayment(PaymentRequest request) {
return circuitBreaker.executeSupplier(() -> {
// 调用支付服务
return paymentClient.pay(request);
});
}
}
}
熔断器状态机:
- CLOSED:正常状态,请求正常通过
- OPEN:打开状态,所有请求被拒绝
- HALF_OPEN:半开状态,允许部分请求试探
三、高可用部署策略
有些小伙伴在工作中可能忽略了部署环节的重要性,实际上很多线上事故都发生在发布过程中。
1. 蓝绿部署
# Kubernetes蓝绿部署配置
apiVersion:apps/v1
kind:Deployment
metadata:
name:order-service-v2
spec:
replicas:3
selector:
matchLabels:
app:order-service
version:v2
template:
metadata:
labels:
app:order-service
version:v2
spec:
containers:
-name:order-service
image:order-service:v2.0.0
readinessProbe:
httpGet:
path:/actuator/health
port:8080
initialDelaySeconds:30
periodSeconds:10
livenessProbe:
httpGet:
path:/actuator/health
port:8080
initialDelaySeconds:60
periodSeconds:20
---
apiVersion:v1
kind:Service
metadata:
name:order-service
spec:
selector:
app:order-service
version:v2# 切换流量到新版本
ports:
-port:80
targetPort:8080
蓝绿部署优势:
- 快速回滚:只需修改Service的selector
- 零停机发布
- 避免版本兼容问题
2. 灰度发布
// 基于流量权重的灰度发布
@Component
publicclass GrayReleaseRouter {
@Value("${gray.release.ratio:0.1}")
privatedouble grayRatio;
@Autowired
private HttpServletRequest request;
public boolean shouldRouteToNewVersion() {
String userId = getUserIdFromRequest();
// 基于用户ID的哈希进行分流
int hash = Math.abs(userId.hashCode());
double ratio = (hash % 100) / 100.0;
return ratio < grayRatio;
}
public Object routeRequest(Object request) {
if (shouldRouteToNewVersion()) {
// 转发到新版本服务
return callNewVersion(request);
} else {
// 使用老版本服务
return callOldVersion(request);
}
}
private String getUserIdFromRequest() {
// 从请求中提取用户ID
return request.getHeader("X-User-Id");
}
}
灰度发布策略:
- 按用户ID分流
- 按流量比例分流
- 按业务参数分流(如特定城市、用户等级)
四、数据一致性与事务管理
数据不一致是很多线上事故的根源。
有些小伙伴在工作中可能遇到过:订单扣款成功但库存未减少,或者消息重复消费导致数据重复。
1. 分布式事务解决方案
// 使用Seata实现分布式事务
@Service
publicclass OrderServiceImpl implements OrderService {
@GlobalTransactional
@Override
public Order createOrder(OrderRequest request) {
// 1. 创建订单(本地事务)
Order order = orderMapper.insert(request);
// 2. 扣减库存(远程服务)
inventoryFeignClient.deduct(request.getProductId(), request.getQuantity());
// 3. 创建积分记录(远程服务)
pointsFeignClient.addPoints(request.getUserId(), request.getAmount());
return order;
}
}
// 库存服务
@Service
publicclass InventoryServiceImpl implements InventoryService {
@Transactional
@Override
public void deduct(String productId, Integer quantity) {
// 检查库存
Inventory inventory = inventoryMapper.selectByProductId(productId);
if (inventory.getStock() < quantity) {
thrownew BusinessException("库存不足");
}
// 扣减库存
inventoryMapper.deductStock(productId, quantity);
// 记录库存变更日志
inventoryLogMapper.insert(new InventoryLog(productId, quantity));
}
}
分布式事务模式:
- 2PC:强一致,但性能较差
- TCC:高性能,但实现复杂
- SAGA:长事务场景,最终一致
- 本地消息表:简单可靠,应用广泛
2. 消息队列的可靠投递
// 本地消息表实现最终一致性
@Service
@Transactional
publicclass OrderServiceWithLocalMessage {
@Autowired
private OrderMapper orderMapper;
@Autowired
private MessageLogMapper messageLogMapper;
@Autowired
private RabbitTemplate rabbitTemplate;
public void createOrder(OrderRequest request) {
// 1. 创建订单
Order order = orderMapper.insert(request);
// 2. 记录本地消息
MessageLog messageLog = new MessageLog();
messageLog.setMessageId(UUID.randomUUID().toString());
messageLog.setContent(buildMessageContent(order));
messageLog.setStatus(MessageStatus.PENDING);
messageLogMapper.insert(messageLog);
// 3. 发送消息到MQ
try {
rabbitTemplate.convertAndSend("order.exchange",
"order.created", messageLog.getContent());
// 4. 更新消息状态为已发送
messageLogMapper.updateStatus(messageLog.getMessageId(),
MessageStatus.SENT);
} catch (Exception e) {
// 发送失败,消息状态保持PENDING,由定时任务重试
log.error("消息发送失败", e);
}
}
// 消息重试定时任务
@Scheduled(fixedDelay = 60000) // 每分钟执行一次
public void retryFailedMessages() {
List<MessageLog> failedMessages = messageLogMapper
.selectByStatus(MessageStatus.PENDING);
for (MessageLog message : failedMessages) {
try {
rabbitTemplate.convertAndSend("order.exchange",
"order.created", message.getContent());
messageLogMapper.updateStatus(message.getMessageId(),
MessageStatus.SENT);
} catch (Exception e) {
log.error("重试消息发送失败: {}", message.getMessageId(), e);
}
}
}
}
可靠消息要点:
- 先持久化消息,再发送MQ
- 使用定时任务补偿未发送的消息
- 消费者实现幂等性
五、容量规划与性能优化
有些小伙伴在工作中可能等到系统出现性能问题才开始优化,实际上容量规划应该前置。
1. 压力测试与容量评估
// 使用JMH进行基准测试
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
@State(Scope.Thread)
publicclass OrderServiceBenchmark {
private OrderService orderService;
private OrderRequest request;
@Setup
public void setup() {
orderService = new OrderService();
request = new OrderRequest("user123", "product456", 2, 100.0);
}
@Benchmark
public void createOrderBenchmark() {
orderService.createOrder(request);
}
public static void main(String[] args) throws RunnerException {
Options options = new OptionsBuilder()
.include(OrderServiceBenchmark.class.getSimpleName())
.forks(1)
.warmupIterations(2)
.measurementIterations(3)
.build();
new Runner(options).run();
}
}
容量规划步骤:
- 基准测试:获取单机性能指标
- 压力测试:找到系统瓶颈点
- 容量计算:根据业务目标计算所需资源
- 预留buffer:通常预留30%-50%的冗余
2. 数据库性能优化
-- 慢查询分析
EXPLAINANALYZE
SELECT o.*, u.username, p.product_name
FROM orders o
LEFTJOINusers u ON o.user_id = u.user_id
LEFTJOIN products p ON o.product_id = p.product_id
WHERE o.create_time BETWEEN'2023-01-01'AND'2023-12-31'
AND o.status = 'COMPLETED'
AND u.city = '北京'
ORDERBY o.amount DESC
LIMIT100;
-- 索引优化建议
-- 1. 复合索引覆盖常用查询条件
CREATEINDEX idx_orders_user_time ON orders(user_id, create_time);
-- 2. 覆盖索引避免回表
CREATEINDEX idx_orders_covering ON orders(status, create_time, amount)
INCLUDE (user_id, product_id);
-- 3. 函数索引优化复杂条件
CREATEINDEX idx_orders_month ON orders(EXTRACT(MONTHFROM create_time));
数据库优化策略:
- 读写分离:主库写,从库读
- 分库分表:水平拆分大表
- 索引优化:避免全表扫描
- 查询优化:减少JOIN,避免SELECT *
六、应急预案与故障处理
即使做了万全准备,故障仍然可能发生。有些小伙伴在工作中可能因为没有预案而手忙脚乱。
1. 故障预案库
// 自动化故障切换
@Component
publicclass AutoFailoverHandler {
@Autowired
private CircuitBreakerRegistry circuitBreakerRegistry;
@Autowired
private RedisTemplate redisTemplate;
@EventListener
public void handleDatabaseFailure(DatabaseDownEvent event) {
log.warn("数据库故障,启用降级策略");
// 1. 打开熔断器,防止请求堆积
CircuitBreaker circuitBreaker = circuitBreakerRegistry
.circuitBreaker("databaseService");
circuitBreaker.transitionToOpenState();
// 2. 启用本地缓存模式
redisTemplate.opsForValue().set("degradation.mode", "true");
// 3. 发送告警通知
alertService.sendCriticalAlert("数据库故障,已启用降级模式");
}
// 定时检查数据库恢复
@Scheduled(fixedRate = 30000)
public void checkDatabaseRecovery() {
if (isDatabaseRecovered()) {
log.info("数据库已恢复,关闭降级模式");
redisTemplate.delete("degradation.mode");
CircuitBreaker circuitBreaker = circuitBreakerRegistry
.circuitBreaker("databaseService");
circuitBreaker.transitionToClosedState();
}
}
}
2. 故障演练
// 混沌工程故障注入
@RestController
publicclass ChaosController {
@PostMapping("/chaos/inject")
public String injectChaos(@RequestBody ChaosConfig config) {
switch (config.getFaultType()) {
case"latency":
// 注入延迟
injectLatency(config.getDuration(), config.getLatencyMs());
break;
case"exception":
// 注入异常
injectException(config.getDuration(), config.getExceptionRate());
break;
case"memory":
// 消耗内存
consumeMemory(config.getMemoryMb());
break;
default:
thrownew IllegalArgumentException("不支持的故障类型");
}
return"故障注入成功";
}
private void injectLatency(Duration duration, long latencyMs) {
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
AtomicBoolean enabled = new AtomicBoolean(true);
// 设置延迟
ThreadLocalRandom random = ThreadLocalRandom.current();
AspectJProxyFactory factory = new AspectJProxyFactory(new Object());
factory.addAspect(new LatencyAspect(enabled, latencyMs, random));
// 定时关闭
executor.schedule(() -> enabled.set(false),
duration.toMillis(), TimeUnit.MILLISECONDS);
}
}
总结
接下来,给大家总结一下提高系统稳定性的几个核心要点:
1. 预防为主
- 完善监控:建立多层次监控体系
- 容量规划:提前评估系统容量
- 代码质量:严格的代码审查和测试
2. 快速发现
- 智能告警:基于机器学习的异常检测
- 链路追踪:快速定位问题根因
- 日志分析:集中式日志管理
3. 快速恢复
- 弹性架构:限流、降级、熔断
- 自动化运维:一键回滚、自动扩容
- 应急预案:完善的故障处理流程
4. 持续改进
- 故障复盘:每次事故都要深度分析
- 混沌工程:主动发现系统弱点
- 技术债管理:定期偿还技术债务
记住,系统稳定性是一个持续改进的过程,没有终点。
每个团队都应该根据自身情况,选择最适合的稳定性建设路径。
AI大模型学习福利
作为一名热心肠的互联网老兵,我决定把宝贵的AI知识分享给大家。 至于能学习到多少就看你的学习毅力和能力了 。我已将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。
一、全套AGI大模型学习路线
AI大模型时代的学习之旅:从基础到前沿,掌握人工智能的核心技能!

因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获取
二、640套AI大模型报告合集
这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。

因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获
三、AI大模型经典PDF籍
随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。

因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获
四、AI大模型商业化落地方案

因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获
作为普通人,入局大模型时代需要持续学习和实践,不断提高自己的技能和认知水平,同时也需要有责任感和伦理意识,为人工智能的健康发展贡献力量

被折叠的 条评论
为什么被折叠?



