老梁聊全栈系列:(阶段一)从单体到云原生的演进脉络

发布于:2025-09-11 ⋅ 阅读:(23) ⋅ 点赞:(0)

大家好,我是技术老梁,这是系列文章的第二篇。欢迎大家讨论,分享经验。如果知识对你有用,关注我,多多支持老梁,鼓励我分享更高质量的内容。

接上篇《全栈经验之谈系列:(阶段一)架构思维与全局观

技术演进如同一条奔腾不息的河流,开发生涯中,我见证了Java后端从笨重的单体架构蜕变为优雅的云原生体系,前端从简单的jQuery脚本进化为现代化的Vue/React框架。本文将回顾这一演进历程,分享关键转折点与技术选型思考,为开发者提供一份避坑指南和架构演进参考。

一、宏观时间轴(Java × 前端)

时期 业务特征 Java 后端主流栈 前端主流栈 痛点关键词 关键技术决策
2008-2011(Web1.5) 企业内网、OA、ERP Struts1/2 + Spring2 + Hibernate3 JSP + jQuery1 并发低、交付慢、耦合重 页面标签+DAO 复用
2012-2014(Web2.0) 社交/电商雏形 Spring3 + MyBatis + Tomcat7 jQuery + Backbone 半前后端分离、SEO 难 REST 化、接口统一
2015-2017(移动互联网) 高并发、秒杀 Spring4 + SpringMVC + Dubbo Vue1/React15 + Axios 雪崩、重复代码、跨域 微服务+网关+CDN
2018-2020(中台 & 多云) 业务中台、数据共享 SpringBoot2 + SpringCloud Netflix Vue2/React16 + Webpack4 链路追踪、配置漂移 注册中心+配置中心+链路追踪
2021-今(云原生) Serverless、FinOps SpringBoot3 + SpringCloud2023 + GraalVM Vue3/React18 + Vite 冷启动、镜像大、成本 K8s+ServiceMesh+可观测

二、五个阶段详解

1. 单体厚重期(2008-2011)

  • Java:一个 war 包含 200+ 张表、3000+ 类;Struts-XML 地狱。

  • 前端:JSP 里嵌 jQuery,刷新整页;IE6 兼容占 30% 人力。

  • 典型故障:HotDeploy 内存泄漏,Tomcat 每晚上重启一次。

    // 典型的早期Spring MVC控制器
    @Controller
    @RequestMapping("/user")
    public class UserController {
        
        @Autowired
        private UserService userService;
        
        @RequestMapping(value = "/list", method = RequestMethod.GET)
        public String listUsers(Model model) {
            List<User> users = userService.getAllUsers();
            model.addAttribute("users", users);
            return "user/list"; // 返回JSP视图路径
        }
    }

    经验:

    • 先拆"业务包",再拆"技术包";包内高内聚,包间低耦合。

    • 前端引入 Tiles 模板,第一次抽象公共头部底部。

2. 前后端分离兴起(2012-2014)

  • Java:Spring3 全注解、MyBatis 干掉 Hibernate;RestController 出现。

  • 前端:Backbone 双向绑定 → 减轻 DOM;grunt 做合并压缩。

实践:

  • REST 统一返回格式:{code,msg,data},前端错误拦截统一化。

  • 跨域 JSONP → CORS,后端加 @CrossOrigin

解决的问题

  1. 前后端团队可以并行开发,提高效率

  2. 前端获得更大技术自主权,用户体验大幅提升

  3. 后端API可被多种客户端复用(Web、移动端等)

  4. 部署独立性增强,前端静态资源可部署至CDN

3. 微服务爆炸期(2015-2017)

  • Java:Dubbo + ZooKeeper;SpringBoot1.2 简化嵌入式容器。

  • 前端:AngularJS/Vue/React开始崛起,构建独立工程,双向绑定+组件化

  • ​java
    // Spring Boot RESTful 控制器
    @RestController
    @RequestMapping("/api/users")
    public class UserApiController {
        
        @Autowired
        private UserService userService;
        
        @GetMapping
        public ResponseEntity<List<UserDTO>> getUsers(
            @RequestParam(defaultValue = "0") Integer page,
            @RequestParam(defaultValue = "20") Integer size) {
            
            Page<User> users = userService.getUsers(PageRequest.of(page, size));
            return ResponseEntity.ok(UserMapper.INSTANCE.toDtoList(users.getContent()));
        }
    }
    
    javascript
    
    // Vue 2.x 前端调用示例
    export default {
      data() {
        return {
          users: [],
          loading: false
        }
      },
      methods: {
        async fetchUsers() {
          this.loading = true
          try {
            const response = await axios.get('/api/users', {
              params: { page: 0, size: 20 }
            })
            this.users = response.data
          } catch (error) {
            console.error('获取用户列表失败:', error)
          } finally {
            this.loading = false
          }
        }
      },
      mounted() {
        this.fetchUsers()
      }
    }​

    技术治理

    • 网关:Zuul1 统一限流、鉴权。

    • 配置中心:自研 cfg-center,推拉结合。

    • 前端动态路由:Vue-Router + Webpack 代码分割,首屏从 800KB → 280KB。

  • 组织:康威定律显灵——拆服务前先拆团队,2 Pizza 团队(7±2 人)。

        核心价值

  1. 服务解耦:系统拆分为小型、专注的微服务

  2. 独立部署:每个服务可独立开发、部署和扩展

  3. 技术多样性:不同服务可采用最适合的技术栈

  4. 容错能力:熔断、降级等机制提升系统韧性

4. 中台&多云期(2018-2020)

  • Java:SpringCloud Netflix → Alibaba;Sentinel 流控、Nacos 注册+配置。

  • 前端:Vue2 生态成熟,Element-UI 开箱即用;React16 Hooks 颠覆 Class。

  • 挑战

    • 链路黑盒:排查 5 分钟订单失败需 2 小时。

    • 公共业务重复:会员、积分、营销各自写一套。

  • 解法

    • 观测三件套:ELK + Prometheus + Jaeger;日志索引字段统一 60+。

    • 业务中台:用户/商品/订单 3 个中心,DDD+防腐层,Java 包结构:

      user-center
      ├─ application
      ├─ domain
      ├─ infrastructure
      └─ client
    • 前端搭建 Low-Code 平台:Vue2 + JSON-Schema,营销页 0 代码,周上线 200+ 活动页。

5. 云原生期(2021-至今)

  • Java

    • SpringBoot3 → JakartaEE9、原生编译 GraalVM,启动 0.15s。

    • Spring6 AOT 与 RuntimeHints,告别反射配置。

    • 服务网格:Istio1.16 接管 mTLS、灰度、熔断,业务代码 0 侵入。

  • 前端

    • Vue3 + Vite 秒级热更新;React18 并发渲染+Server Component。

    • Edge Rendering:Vercel/Cloudflare Functions,API 与页面同边缘节点,FP 减少 35%。

  • 成本治理

    • FinOps 实践:命名空间级资源池,业务单元成本可视化;HPA 基于 QPS+CPU 混合指标,每月节省 40% 云账单。

  • 新痛点

    • 镜像体积大 → 采用 distroless + 多阶段构建,从 218MB 降到 38MB。

    • Native-Image 调试难 → 保留传统 JVM 镜像作为 debug 模式,通过 Helm 一键切换。


三、演进背后的 4 条底层逻辑

  1. 业务驱动 > 技术自嗨
    每轮重构都因"量""质""钱"三指标触顶:订单量翻倍、缺陷率 >5%、云费用占毛利 >8%。

  2. 先治理,再拆分
    观测、配置、安全、成本 4 条基线没准备好,就别急着上 Service Mesh。

  3. 数据一致性与交付速度不可兼得,必须取舍
    强一致场景用 TCC + 补偿;最终一致场景用 Saga + 消息表,前端友好提示"处理中"。

  4. 团队认知是架构天花板
    2016 年我们写"分布式事务"PPT 给运维讲,被问"事务是什么?"——从此明白:技术升级必须伴随培训、OKR、激励同步走。


四、可复制的"演进 Checklist"

阶段 后端检查项 前端检查项 交付 & 治理
单体→模块化 ① 包结构按 domain 划分 ① 公共组件抽成 JSP tag Jenkins+Ant 自动打包
模块化→服务化 ① Dubbo 接口 T 级测试 ① 跨域白名单 每日接口契约 review
服务化→中台 ① 领域层无 MySQL 驱动 ① 统一 DesignToken 链路追踪采样率 10%
中台→云原生 ① GraalVM 原生编译 ① Vite 预构建 GitOps + HPA + FinOps

五、演进中的经验与教训

成功经验

  1. 渐进式演进:避免重写式改造,采用绞杀者模式逐步替换

  2. API先行:前后端基于API契约并行开发,提高效率

  3. 基础设施即代码:使用Terraform/Ansible管理基础设施

  4. 监控先行:在新服务上线前建立完善的监控体系

踩坑教训

  1. 微服务过度拆分:导致分布式事务复杂性和网络开销大增

  2. 技术选型盲目追新:稳定性应优先于技术新颖性

  3. 忽视团队技能储备:新技术需要相应的团队能力支撑

  4. 低估运维复杂度:微服务带来了部署和监控的复杂性

六、小结 & 下集预告

十五年的技术浪潮,从 SSH 到云原生,变的是工具,不变的是"让系统可演进"的核心目标。下一篇《现代全栈的"角色边界"与"能力雷达图"》,我会把上面这张 Checklist 量化成雷达模板,并给出 Java & Vue/React 双栈的 0-1 成长路线图。敬请期待!


网站公告

今日签到

点亮在社区的每一天
去签到