Koupleless 助力「人力家」实现分布式研发集中式部署,又快又省!

原创 赵云兴、葛志刚

文|赵云兴,葛志刚

仁励家网络科技(杭州)有限公司架构师

专注 to B 领域架构

本文 2111字 阅读5分钟

背景

人力家由阿里钉钉与人力窝共同孵化,致力于为企业提供以薪酬为核心的一体化 HR SaaS 解决方案,加速对中国人力资源服务行业数字化赋能。

人力资源软件通常由多模块组成,如人力资源规划、招聘、培训、绩效管理、薪酬福利、劳动关系,以及员工和组织管理等。随着业务发展,部分模块进入稳定期,仅需少量维护投入。例如,一个早期有 20 人研发的项目,现在拆分为 5 个应用。尽管产品成熟,但由于客户需求随竞争、业务和政策变化,仍需每年投入部分精力进行迭代。

长时间以来,我们一直面临着以下问题,而苦于没有解决方案:

  • 系统资源浪费:5 个应用支撑的业务,我们在生产环境为每个应用部署了 3 台 2C4G 的 Pod,一共是 15 个 Pod 的资源。

  • 迭代运维成本高:因为业务的复杂性,经常需要多个应用同时改动,部署等待周期长,单应用部署时间在 6 分钟左右。

在过去,我们已经探索过以下方案:

  • 压缩工程:通过排除冗余的 jar 依赖,降低镜像大小。但空间有限,整个应用 jar 包只能从 100+M 减少到 80+M,整个镜像依然有 500M,能节省的部署等待时间有限。

  • 单 ECS 上部署多应用:我们需要为这个应用做特别的定制,譬如监听端口要支持多个;部署脚本也要特别定制,要支持滚动发布,健康检测不同的端口,一段时间以后运维容易搞不清整个部署方案,容易出现运维事故。

初见成效

直到在某个月不黑风不高的夜晚,我们在最大的程序员交友网站上遇到了 Koupleless 团队。看完框架的介绍,我们立刻明白,Koupleless 就是我们要寻找的解决方案。

经过近两个月的敲敲打打,模块成功瘦身了,其中最大的模块的 jar 也只有不到 4M应用部署的体积从 500M 一下子降到了 5M 以下,具体可见下图~

点击查看图片

但高兴不过一天,我们在「如何把 Koupleless 部署到生产环境」上遇到了难题。因为我们没有专门的运维团队,部署都是开发人员通过阿里云的云效流水线,直接把镜像推送到 K8s 的 Pod。但这样改了以后,我们迎来了一连串待解决的问题......

  • 模块要不要流量,还是直接通过基座处理流量?

  • 如何在单独部署模块的时候先把基座的流量摘掉?

  • 发布成功以后如何做健康检查?

  • 如何重新开放基座流量?

Koupleless 的生产环境部署

在这里要特别感谢 Koupleless 团队的伙伴,给了我们很多专业的建议和方案。最终,我们选择了以下部署方案:

点击查看图片

整体方案是,在基座上增加监听 oss 文件变化自动更新部署模块,卸载老版本模块安装新版模块,所有流量由 nginx 进入,转发到进程 tomcat (基座和多个模块复用同个 tomcat host),并在基座上控制健康检查和流量的开关,主要工作是在基座上扩充一些能力:

1、基座支持配置自身运行的必要条件,譬如需要模块 A、B、C 都安装成功才能放流量进来;

2、检查 oss 目录,自动安装最新的模块版本,并做健康检查;

3、实现 K8s 的 liveness:用来在基座部署的时候判断基座是否成功启动。只要基座启动成功,即返回成功,这样基座可以走后续的安装模块逻辑;

4、实现 K8s 的 readiness:主要控制外部流量是否可以进来。因此这里需要判断所有必须安装的模块是否健康,并且对应的流量文件 A_status 等是否存在 (该文件是一个空文件,在滚动发布的时候开关流量的时候用)

小 Tips 目前 Koupleless 优化了静态部署和健康检查能力,能够直接满足我们的需求:

  • 静态部署:在基座启动成功后,允许用户通过自定义的方式安装模块;
  • 健康检查:在基座启动成功且用户自定义安装的模块启动后,Koupleless 框架将原生 SpringBoot 的 readiness 配置为 'ACCEPTING_TRAFFIC',用户可以通过探测 readiness 决定是否让流量进入。

以下是 K8s 上的配置图:

  • 就绪检查和启动探测:

点击查看图片

* 在 Pod 上增加云存储的挂载:

点击查看图片

模块动态部署时需要考虑两个问题:怎么感知新的模块并部署?在模块部署的前后怎么通过健康检查,控制基座流量?

我们的方案大概如下:

1、模块通过流水线,直接 jar 上传到一个 oss 目录;

2、基座上增加配置,配置基座承接流量的必须安装的模块,以及对应模块的健康检查地址;

3、基座监听 oss 文件夹的变化,来决定是否重新部署模块 (譬如有更晚的/更大的版本的模块上传到了 oss)

4、基座部署模块前,先摘流量 (可以通过删除一个空文件来实现,结合上一步 K8s 的 readiness 逻辑,空文件删除以后,readiness 检测不通过,流量就不会进来。但模块是存活的,防止有耗时的线程还在运行)

5、安装好模块以后,把删除的文件写上,就可以开流量了;

6、集群下,基座通过 redis 来控制 Pod 不会出现并行安装,保证流量不会断;

7、基座提供就绪检查:就绪检查只需要判断基座起来了就可以。

存活检查是比较关键的一步:

a.判断第 4 步的空文件是否存在;

b.需要判断所有必须安装的模块都可以访问。

小 Tips

目前 Koupleless 优化了健康检查能力,能够在模块动态安装/卸载之前关闭流量,将 readiness 配置为 REFUSING_TRAFFIC,并允许用户配置模块卸载前的静默时长,让流量在静默时期处于关闭状态。在卸载的静默时长结束、旧模块卸载完成、全部模块安装成功后,readiness 才会配置为ACCEPTING_TRAFFIC 状态。

总结

在以前,单个模块升级发布一次要 6 分多钟。

点击查看图片

而改造后,升级单个模块只需要把编译后的 jar 上传到 oss 即可。

点击查看图片

最终的效果,通过一组简单的数字对比就可以看出差异:

  • 在服务器资源上,以前需要 15X2C4G,现在只需要 3X4c8G,节省了 18C36G 的服务器资源

  • 在单个模块的发布时间上,我们从之前的 6分钟降低到了3 分钟

  • 在单个模块的部署资源上,我们从 500M **降低到了 5M **。

再次感谢 Koupleless 团队伙伴的专业支持,特别是有济、立蓬。当我们在改造过程中遇到一些个性场景的兼容性问题,他们都能快速响应,让我们整个升级改造时间大大缩短。

通过升级 Koupleless 架构,人力家实现了多应用的合并部署、并行研发、轻量集中部署,大大降低了运维成本。

天下架构,分久必合,合久必分。而 Koupleless,让架构演进(分合)更丝滑🥰

相关推荐
间彧2 分钟前
Nginx + Keepalived 实现高可用集群(Linux下)
后端
间彧3 分钟前
在Kubernetes中如何部署高可用的Nginx Ingress Controller?
后端
间彧6 分钟前
Ribbon负载均衡器和Nginx负载均衡器有什么区别
后端
间彧14 分钟前
Nacos详解与项目实战
后端
间彧15 分钟前
nginx、网关Gateway、Nacos、多个服务实例之间的数据链路详解
后端
间彧17 分钟前
Nacos与Eureka在性能上有哪些具体差异?
后端
间彧18 分钟前
详解Nacos健康状态监测机制
后端
间彧20 分钟前
如何利用Nacos实现配置的灰度发布?
后端
毕业设计制作和分享32 分钟前
springboot159基于springboot框架开发的景区民宿预约系统的设计与实现
java·spring boot·后端
计算机学长felix2 小时前
基于SpringBoot的“中学信息技术课程教学网站”的设计与实现(源码+数据库+文档+PPT)_2025-10-17
数据库·spring boot·后端