腾讯IEG游戏后台开发面试实战:从SQL优化到分布式任务调度的技术复盘
1. SQL优化实战从慢查询到索引覆盖面试官一上来就盯着我的SQL优化经验问这确实是游戏后台开发的高频考点。记得当时我提到一个用户表联查部门表的案例部门表数据量小用户表数据量大这时候如果把部门表放在LEFT JOIN的左侧性能能提升30%以上。这个优化原理其实很简单——小表驱动大表就像你搬仓库时先把小件物品清空再处理大件会更高效。Explain命令是我的诊断利器。有次线上接口超时用Explain一看发现全表扫描了200万条记录原来where条件里的字段没建索引。加上联合索引后查询时间从2秒降到50毫秒。这里有个细节要注意联合索引的顺序必须遵循最左前缀原则。比如索引是(a,b,c)但查询只用到b和c字段这个索引就白建了。覆盖索引的坑我踩过不少。有次自以为聪明地建了(a,b)联合索引结果select里还包含了c字段导致大量回表操作。后来改成(a,b,c)三列索引查询速度直接起飞。这里有个口诀索引要覆盖select和where缺一不可。实际项目中还会遇到分页查询性能问题我的经验是不要用limit 10000,10这种写法而是记录上一页最后一条记录的ID用where id last_id limit 10来优化。2. 分布式定时任务的设计哲学从单体定时任务升级到分布式架构我选型时重点对比了XXL-JOB和Elastic-Job。最终选择XXL-JOB是因为它的管理界面太香了像游戏后台这种需要频繁调整定时策略的场景特别合适。部署时我搞了个三节点集群用Nginx做负载均衡数据库用的MySQL主从复制确保调度中心高可用。任务阻塞问题是个经典坑。有次线上有个视频转码任务跑了2小时导致后续任务全部堆积。后来我们配置了快慢线程池超过1分钟的任务自动转到慢池并设置任务超时中断机制。更复杂的场景下我们还用到了分片广播策略比如要处理100万条用户数据10个执行器各自处理10万条通过sharding参数动态分配任务。任务监控方面除了系统自带的邮件报警我还接入了公司内部的IM机器人。有次凌晨3点收到报警发现是Redis连接池耗尽导致任务失败紧急扩容后避免了早高峰的服务崩溃。这里分享个技巧在XXL-JOB中实现IJobHandler的log方法可以把关键日志实时推送监控系统。3. 消息队列选型的实战思考消息队列选型时我带着团队做了三轮压测。对比Kafka、RabbitMQ和RocketMQ的TPS表现Kafka单机能达到10万/s但消息延迟波动大RabbitMQ稳定在2万/sRocketMQ约5万/s且延迟稳定。考虑到游戏后台需要兼顾峰值流量和消息可靠性最终选择了RocketMQ。有个值得分享的细节我们消息体用了Protocol Buffers序列化比JSON体积小40%。消费端做了分级消费策略重要消息立即处理次要消息延迟处理。遇到消费堆积时通过动态扩容Consumer实例来解决配合RocketMQ的tag过滤功能可以精准控制不同业务的消息流速。死信队列的设计也很有讲究。我们设置了三重保障首次失败重试3次仍然失败则进入延迟队列第三次尝试还失败就转人工处理。所有异常消息都会带上完整的上下文信息方便问题追踪。这套机制在处理支付订单时特别管用避免了因为网络抖动导致订单丢失。4. Redis在游戏场景的妙用游戏后台的排行榜功能我们用Redis的zset实现只用了50行代码。关键点在于score的设计把战斗力数值乘以10000再加上(1-最后更新时间戳/MAX_TIMESTAMP)这样既能按战力排序又能在战力相同时优先显示最新数据。每天凌晨用Lua脚本批量清理30天前的数据内存占用始终控制在2GB以内。热点数据缓存有个经典问题——缓存击穿。我们的解决方案是1使用双重检查锁2设置逻辑过期时间3缓存预热时采用渐进式加载。比如玩家信息缓存不是全量加载而是按最近活跃度分批次加载。监控到某明星战队比赛时会提前把相关数据加载到缓存。Redis集群的运维也有门道。我们遇到过slot迁移导致连接闪断的问题后来在客户端做了自动重试机制并调整了cluster-node-timeout参数。大key扫描用的是自研工具定期分析内存碎片率发现超过1.5就主动执行memory purge。这些经验在面试时聊出来能明显感觉到面试官眼睛一亮。5. 高并发场景下的架构设计秒杀系统是我们做过的最刺激的项目。第一版用Redis扣减库存结果超卖了3%。后来改成Lua脚本原子操作配合Redis集群的分片特性把库存数据分散到多个slot。前端做了三级限流Nginx层限制IP频次网关层验证令牌服务层用分布式锁控制并发写。最终在1万QPS下实现了零超卖。服务熔断策略也值得一说。我们基于Sentinel实现了动态熔断当接口错误率超过50%且持续5秒自动降级返回缓存数据。熔断后每隔10秒放一个请求探活恢复后逐步放开流量。这套机制在游戏新版本上线时特别有用能把服务器雪崩风险降到最低。数据库分库分表我们采用玩家ID哈希取模但遇到联表查询就头疼。后来引入ShardingSphere的绑定表功能把关联表的分片规则配置一致查询性能提升8倍。热数据迁移时用了影子表方案先双写两周数据校验无误后再切读流量整个过程玩家完全无感知。