共计 1578 个字符,预计需要花费 4 分钟才能阅读完成。
背景痛点
Agent 就业系统在高峰期经常面临以下问题:

- 数据库压力大 :简历查询、职位匹配等核心功能导致数据库 QPS 飙升
- 响应延迟高 :用户操作等待时间超过 2 秒,体验急剧下降
- 服务不稳定 :单点故障引发连锁反应,系统可用性低至 99%
- 扩展困难 :单机部署模式无法快速应对流量波动
技术选型
架构对比
- 单体架构
- 优点:开发简单、部署方便
-
缺点:扩展性差、技术栈耦合
-
微服务架构
- 优点:独立扩展、技术异构
- 缺点:运维复杂度高
决策依据
- 业务特点:不同模块负载差异大(如简历处理 CPU 密集,搜索 IO 密集)
- 团队规模:15 人以上研发团队可支撑微服务治理
- 长期规划:需要支持全球化部署
核心实现
服务注册与发现
// Spring Cloud 服务注册示例
@SpringBootApplication
@EnableDiscoveryClient
public class AgentServiceApplication {public static void main(String[] args) {SpringApplication.run(AgentServiceApplication.class, args);
}
}
缓存设计
- 多级缓存策略
- L1:本地缓存(Caffeine)
-
L2:分布式缓存(Redis Cluster)
-
缓存击穿防护
public Resume getResumeWithCache(String resumeId) {
// 布隆过滤器前置校验
if (!bloomFilter.mightContain(resumeId)) {return null;}
// 缓存重建锁
String lockKey = "resume_lock_" + resumeId;
try {if (redisTemplate.opsForValue().setIfAbsent(lockKey, "1", 30, TimeUnit.SECONDS)) {
// 查库并回填缓存
Resume resume = resumeRepository.findById(resumeId);
redisTemplate.opsForValue().set("resume_"+resumeId, resume, 5, TimeUnit.MINUTES);
return resume;
}
// 等待其他线程加载
Thread.sleep(100);
return getResumeWithCache(resumeId);
} finally {redisTemplate.delete(lockKey);
}
}
消息队列应用
- 使用 Kafka 处理简历投递事件
- 分区策略:按职位 ID 哈希分配
// 异步投递处理器
@KafkaListener(topics = "resume_delivery")
public void handleDelivery(ConsumerRecord<String, ResumeDelivery> record) {ResumeDelivery delivery = record.value();
deliveryService.process(delivery);
}
性能优化
压测数据对比
| 指标 | 优化前 | 优化后 |
|---|---|---|
| 最大 QPS | 1200 | 8500 |
| 平均延迟 (ms) | 1500 | 230 |
| 错误率 | 8.7% | 0.3% |
关键优化点
- 连接池调优
- Redis 最大连接数从 200 调整到 800
-
MySQL 连接池添加动态扩容机制
-
索引优化
- 为职位搜索添加组合索引 (city,salary,experience)
避坑指南
缓存一致性
- 采用 Cache Aside Pattern
- 异步刷新热点数据
服务雪崩防护
- 熔断策略
- 错误率超过 50% 时熔断
-
半开状态流量限制
-
降级方案
- 核心服务:返回兜底数据
- 非核心服务:直接熔断
总结与展望
当前系统可支撑万级 QPS,后续可考虑:
- 引入 K8s 实现自动扩缩容
- 试用 Service Mesh 优化服务间通信
- 探索 AI 智能匹配算法
优化永无止境,架构需要持续演进。建议每季度做一次全链路压测,及时发现瓶颈点。
正文完
