在Kubernetes和HAProxy上部署带有Java后端的单页Web应用

90次阅读
没有评论

问题描述

团队开发单页Web应用,前端使用React,后端使用Spring Boot Java应用。他们使用Kubernetes部署这些应用,但在进行滚动更新时遇到了问题。他们的打包和部署过程如下:
1. CI流水线构建Docker镜像,将Java应用打包为可执行的JAR文件,同时包含React客户端的编译后的JavaScript和CSS资源。
2. 镜像有两个入口点:一个用于启动JAR文件(Java后端),另一个用于启动提供客户端资源(JS/CSS)的Nginx。
3. 使用HAProxy集群根据URL路径将请求路由到Nginx或Java后端。

然而,在滚动更新期间,会有一些带有“旧”Java后端的Pod存在。这导致了这样的情况:使用新部署版本的React客户端的客户端向旧的Java后端发送请求,因为HAProxy只是将API流量路由到任何可用的Java后端。用户想知道如何解决这个问题。

解决方案

请注意以下操作可能涉及版本差异及风险。在操作前请务必做好备份。

采用API版本控制和无缝升级

在这种情况下,实现无缝的部署升级的现代方法不在负载均衡(例如HAProxy)的一侧,而是通过正确的部署规划、向后兼容性和/或特性标志来实现。

在解决这个问题时,负载均衡的调整最终并不能解决问题。原因在于,即使你正确设置了粘性会话,也无法解决这个问题。想象一下,在用户在使用旧版本的React打开应用后,你部署了新的Java后端。如果用户不刷新浏览器,她仍然会使用旧的React应用与新的后端交互(这是因为JavaScript已经加载到浏览器中)。

相反,我们可以采用以下示例中描述的方法,通过API版本控制来实现无缝升级:
1. 假设某个API端点的数据模型将发生变化。
2. 假设旧的API路径是 /v1(甚至没有版本号)。
3. 解决方案如下:
– 创建 /v2 版本的API,并在React应用中注册该版本。
– 最新的Java后端仍然需要同时支持 /v1 和 /v2。
– 首先部署所有支持 /v2 的Java后端(UI仍然使用 /v1,这没问题,因为最新的后端支持它)。
– 一旦所有后端都部署完成,你可以开始部署最新镜像的UI部分(由于所有后端都同时支持 /v1 和 /v2,所以体验是无缝的)。

通过上述方法,避免了版本冲突,用户体验是无缝的。

Docker镜像分割

考虑将Docker镜像拆分成两部分。使用两个入口点的多功能镜像可能需要更好的设计理由。

你可能想要考虑将Docker镜像分成两部分。使用两个入口点的多功能镜像可能需要更好的设计理由。

请注意,这个方案依赖于正确的部署策略和合适的API版本控制,以确保在部署更新时不会影响用户体验。

评论:我同意@toledor的观点。在微服务方案中,通常的做法是尽可能将可部署内容保持最小,并根据需要创建多个实例。这是K8S非常擅长处理的内容。最佳实践是为每个服务创建一个部署,这样你可以更好地控制入口点。

正文完