技术分享
🎤 技术分享记录
这里记录我的技术分享和演讲经历。
2024年
微服务架构实践
- 时间:2024年10月
- 主题:从单体到微服务的演进之路
- 内容要点:
- 微服务的优缺点
- 服务拆分原则
- 分布式事务处理
- 服务治理方案
Redis性能优化
- 时间:2024年8月
- 主题:Redis在高并发场景下的优化实践
- 内容要点:
- 缓存设计模式
- 持久化策略选择
- 主从复制与哨兵
- 集群方案对比
💻 技术实践案例
案例1:高并发秒杀系统设计
背景: 电商平台秒杀活动,预计QPS达到10万+
技术方案:
- 前端限流:按钮置灰、验证码
- 接入层:Nginx限流、IP黑名单
- 应用层:Redis预减库存、消息队列削峰
- 数据层:主从分离、读写分离
java
// 秒杀接口示例
@PostMapping("/seckill/{productId}")
public Result seckill(@PathVariable Long productId, @RequestParam String token) {
// 1. 验证token
if (!tokenService.verify(token)) {
return Result.fail("请先获取秒杀资格");
}
// 2. Redis预减库存
Long stock = redisTemplate.opsForValue().decrement("stock:" + productId);
if (stock < 0) {
return Result.fail("库存不足");
}
// 3. 发送消息到MQ,异步创建订单
SeckillMessage msg = new SeckillMessage(productId, userId);
mqService.send("seckill_queue", msg);
return Result.success("排队中...");
}效果:
- QPS从1万提升到10万
- 响应时间从500ms降到50ms
- 系统稳定性显著提升
案例2:MySQL慢查询优化
问题: 某查询耗时3秒,严重影响用户体验
原因分析:
sql
-- 问题SQL
SELECT * FROM orders
WHERE user_id = 123
AND status = 1
AND create_time > '2024-01-01'
ORDER BY create_time DESC
LIMIT 20;
-- EXPLAIN分析
type: ALL -- 全表扫描
rows: 500万
Extra: Using where; Using filesort优化方案:
- 创建复合索引
sql
CREATE INDEX idx_user_status_time
ON orders(user_id, status, create_time);- 覆盖索引优化
sql
-- 只查询需要的字段
SELECT id, order_no, amount, create_time
FROM orders
WHERE user_id = 123
AND status = 1
AND create_time > '2024-01-01'
ORDER BY create_time DESC
LIMIT 20;效果:
- 查询时间从3秒降到10ms
- type从ALL变成ref
- rows从500万降到20
案例3:接口响应时间优化
背景: 用户详情接口响应慢,平均500ms
性能瓶颈:
- 数据库查询:200ms(7次查询)
- 外部API调用:250ms
- 数据处理:50ms
优化方案:
- 减少数据库查询
java
// 优化前:N+1查询
User user = userDao.getById(userId);
List<Order> orders = orderDao.getByUserId(userId); // 查询1次
for (Order order : orders) {
order.setItems(itemDao.getByOrderId(order.getId())); // 查询N次
}
// 优化后:批量查询
User user = userDao.getById(userId);
List<Order> orders = orderDao.getByUserId(userId);
List<Long> orderIds = orders.stream().map(Order::getId).collect(Collectors.toList());
List<OrderItem> items = itemDao.getByOrderIds(orderIds); // 1次查询
Map<Long, List<OrderItem>> itemMap = items.stream()
.collect(Collectors.groupingBy(OrderItem::getOrderId));
orders.forEach(order -> order.setItems(itemMap.get(order.getId())));- 异步调用外部API
java
// 使用CompletableFuture并行调用
CompletableFuture<UserInfo> userInfoFuture =
CompletableFuture.supplyAsync(() -> apiService.getUserInfo(userId));
CompletableFuture<UserScore> userScoreFuture =
CompletableFuture.supplyAsync(() -> apiService.getUserScore(userId));
// 等待所有结果
CompletableFuture.allOf(userInfoFuture, userScoreFuture).join();
UserInfo userInfo = userInfoFuture.get();
UserScore userScore = userScoreFuture.get();- 添加缓存
java
@Cacheable(value = "user", key = "#userId", expire = 300)
public UserDetailVO getUserDetail(Long userId) {
// 业务逻辑
}效果:
- 响应时间从500ms降到50ms
- 数据库查询从7次降到2次
- 用户体验显著提升
🛠️ 踩坑记录
坑1:缓存穿透导致数据库崩溃
现象: 大量请求不存在的数据,缓存未命中,直接打到数据库
解决方案:
- 布隆过滤器预判
- 缓存空值(设置短过期时间)
- 接口限流
坑2:Redis内存溢出
现象: Redis内存占用持续增长,最终OOM
原因:
- 没有设置过期时间
- 大key占用内存
- 内存淘汰策略不合理
解决方案:
- 设置合理的过期时间
- 拆分大key
- 配置maxmemory和淘汰策略
- 定期清理无用数据
坑3:线程池参数配置不当
现象: 高并发时,请求大量超时
原因: 核心线程数设置过小,任务大量堆积在队列中
解决方案:
java
// 根据实际情况配置
ThreadPoolExecutor executor = new ThreadPoolExecutor(
20, // 核心线程数
50, // 最大线程数
60L, TimeUnit.SECONDS, // 空闲线程存活时间
new LinkedBlockingQueue<>(100), // 有界队列
new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略
);📖 技术文章推荐
后端开发
- 深入理解JVM垃圾回收(待补充)
- MySQL索引优化实战(待补充)
- 分布式事务解决方案(待补充)
系统设计
- 高并发系统设计(待补充)
- 缓存设计模式(待补充)
- 微服务架构实践(待补充)
性能优化
- 接口性能优化指南(待补充)
- 数据库性能调优(待补充)
- 前端性能优化(待补充)
💬 技术问答
Q: 如何提高系统的并发能力?
A: 可以从以下几个方面优化:
- 应用层:异步处理、线程池优化、连接池优化
- 缓存层:Redis缓存热点数据
- 数据库层:读写分离、分库分表、索引优化
- 架构层:负载均衡、CDN、消息队列削峰
Q: 如何设计一个高可用系统?
A: 高可用系统设计要点:
- 消除单点故障:多机房部署、主从备份
- 快速故障恢复:健康检查、自动切换
- 限流降级:保护核心功能
- 监控告警:及时发现问题
- 容灾演练:定期测试恢复流程
Q: 分布式系统如何保证数据一致性?
A: 常用方案:
- 强一致性:两阶段提交(2PC)、三阶段提交(3PC)
- 最终一致性:消息队列、定时任务对账
- BASE理论:基本可用、软状态、最终一致性
- 分布式事务框架:Seata、TCC
💡 提示
这是一个demo文档,欢迎补充更多技术分享内容。