说起前端微服务化,最容易落地的是应用级微服务。我们团队去年把用户中心、订单流程、商品管理这三个模块拆成了独立应用。具体怎么做的?给每个子应用创建独立的代码仓库,用Webpack的Module Federation实现运行时模块联邦。当时在配置remotes字段时踩了个坑:主应用加载子应用时如果网络波动会导致白屏,后来通过配置fallback和retry机制才解决。
路由分配这块要特别注意。我们采用了基于业务域名的路由方案:主应用部署在,用户中心放在。在Nginx里配置反向代理时,记得设置CORS头部,特别是遇到IE11这种老古董时要加P3P策略。有个血泪教训是缓存配置,某次发布后用户反馈页面显示的是上周的版本,最后发现是CDN缓存了index.html,现在我们都用内容哈希做文件指纹。
状态管理是另一个难点。刚开始尝试过让子应用直接读写Vuex store,结果某个子应用的bug导致整个store被清空。后来改用事件总线+约定规范:跨应用数据交互必须通过主应用的事件中心,数据格式要符合预设的schema。比如订单模块需要用户信息时,不能直接调用用户模块的接口,而是通过发布USER_INFO_REQUEST事件来获取。
说到部署,我们搭建了独立的Docker镜像仓库。每个子应用都有自己的Dockerfile,通过CI/CD流水线自动构建镜像。Kubernetes的配置里特别要注意资源限制,曾经有个子应用内存泄漏导致整个节点崩溃。现在每个pod都设置了resources.requests和resources.limits,并且配置了健康检查接口。
监控方案我们折腾了很久。最初直接用Sentry收集错误日志,但无法区分错误来源。后来自己搭建了日志收集系统:每个子应用在前端埋点中注入应用标识,错误日志通过统一的API上报,在Grafana里按应用名称分类展示。还加了性能监控,当首屏加载时间超过3秒就触发告警。
最近在试验组件级微服务,把数据可视化图表封装成Web Components。这样React和Vue项目都能直接调用,不过Shadow DOM的样式隔离确实让人头疼。团队内部正在推行API契约优先开发:前后端先约定接口规范,再并行开发,接口文档用Swagger生成,再用Apollo做GraphQL端点管理。
这种架构也不是银弹。我们统计过,微服务化后首屏加载时间平均增加了200ms,需要靠骨架屏和智能预加载来弥补。另外团队协作成本明显上升,现在每周都要开接口联调会。但长远看,当团队规模扩大到20人以上,这种架构确实提升了开发效率------至少不用每次发布都担心把整个系统搞崩。
微服务不是赶时髦,关键是找到适合团队现状的拆分粒度。我们现在正尝试把构建流水线优化成增量部署,只有变更过的子应用才触发完整构建。下一步打算探索Serverless架构,把部分轻量级服务迁移到函数计算,毕竟能省点服务器成本总是好的。