
三年时间从一个Tomcat走天下到如今几十个微服务各司其职。第一年入职时公司的后端架构就是一台服务器上部署了一个Spring Boot单体应用连Redis都没用session全存在内存里。每次发布要在深夜因为重启期间服务完全不可用。数据库连接池经常爆满一查是有人忘记关闭ResultSet——那会儿的稳定性全靠祈祷。三年过去了我深度参与了技术栈从零到一的搭建过程。回头看每一步选择都对应着一次线上事故或一次性能瓶颈。这份清单不是最优解但每一个组件都是被生产环境验证过的。一、开发框架Spring Boot打底Spring Cloud上车单体应用撑到用户量起来后第一个瓶颈就是部署互相影响——订单模块的OOM能把整个用户服务拖垮。我们决定拆微服务选型时在Dubbo和Spring Cloud之间犹豫过。最终选了Spring Cloud Alibaba。理由很简单Spring Boot的生态太成熟了团队上手零成本。Nacos做注册中心和配置中心OpenFeign做服务间调用Sentinel做限流降级。这套组合至今没出过大问题唯一的忠告是版本一定要对齐Spring Cloud的版本依赖比你想的脆弱得多。二、数据存储MySQL分库分表要趁早MySQL是起步标配但分库分表这件事千万不能等到慢查询报警了再做。我们的订单表在数据量突破五百万后所有查询都开始变慢。加索引已经救不了了因为索引本身也大得放不进内存。当时用ShardingSphere-JDBC做了分库分表按订单ID取模分了16张表。改造过程很痛苦——所有涉及订单的查询都要带上分片键不然就是全表扫描。血的教训预估数据量增速在百万级就做好分表方案哪怕先分两张表也比后面拆分容易十倍。缓存方面Redis是标配。需要警惕的是缓存穿透和雪崩——空值缓存、布隆过滤器、随机过期时间这三个方案最好一开始就写进代码模板里。三、中间件选型消息队列救过我们三次第一次用消息队列是为了解耦。订单创建后要发短信、更新统计、同步到搜索——这些操作堆在同步链路里订单接口响应时间直接飙到两秒。引入RocketMQ后订单只发一条消息下游各自消费接口响应时间从2秒降到200毫秒。后面两次救命一次是流量削峰——大促时把非核心操作全部异步化核心链路扛住了十倍的峰值流量。另一次是最终一致性——分布式事务用本地消息表RocketMQ事务消息实现再也不用担心跨服务的数据不一致。选RocketMQ而非Kafka是因为业务场景是可靠传输而非大数据吞吐。RocketMQ的事务消息和定时消息对业务开发太友好了。四、日志与监控没有可观测性就是盲人摸象这是搭建技术栈时最容易被低估的部分。前半年我们没有统一日志排查问题全靠登录服务器grep效率极低。后来上了ELK日志从业务系统通过Logstash汇聚到ElasticsearchKibana做可视化查询。一次生产事故的排查时间从小时级降到了分钟级。监控方面选择了Prometheus Grafana的组合。每个服务暴露/metrics端点采集JVM内存、GC频率、接口RT、错误率等核心指标。再配上AlertManager的告警规则——从此不用等用户投诉才知道服务挂了。链路追踪用的是SkyWalking虽然有一定性能开销但在微服务架构下是必需品。一次请求跨五六个服务没有链路追踪根本没法定位超时到底发生在哪一环。五、容器化与CI/CD从手工发布到一键部署最后的拼图是容器化和自动化部署。Docker打包应用Kubernetes编排容器GitLab CI实现提交即构建。发布从以前的手工scp jar包重启变成了合并代码自动触发流水线、滚动更新、自动回滚。这一步带来的不只是效率提升——开发环境和生产环境完全一致再也不会出现本地跑得好好的上线就报错的尴尬。清单之外的感悟这三年搭建技术栈的过程其实是在不断回答三个问题第一这个组件解决什么问题不要因为大家都在用就引入每个组件都有运维成本和学习成本。第二团队能不能驾驭再先进的技术如果团队没人会排查问题就是给自己埋雷。第三有没有兜底方案缓存挂了怎么办MQ挂了怎么办注册中心挂了怎么办没有降级方案的组件不如不引入。技术栈不是越庞大越好而是在满足业务需求的前提下尽可能精简。三年时间我从一个只会写CRUD的初级开发成长为能独立设计技术架构的人。而所有的成长都写进了这份被生产环境检验过的清单里。