零停机升级服务

在项目迭代的过程中,我们经常会进行更新线上代码的操作,而更新的操作我们会希望影响的用户越少越好,最好是能做到零停机更新。 在目前云原生的大背景下,K8s 的滚动更新策略会更为人知一些,但是一些中小型项目的部署建立一套 K8s 服务从成本和收益的角度来看是有些得不偿失的。 本文介绍用 Docker 和 Traefik 如何实现零停机升级服务。关于 Traefik 在 更靠近云原生的反向代理神器-Traefik 一文中有更详细的介绍。 整个服务部署流程如下 本方案通过 gitlab CI/CD 来进行部署,开发人员仅需在对应的分支提交代码,服务器会自动完成 构建 -> 部署 -> 通知 等操作。 在 部署 阶段通过蓝绿发布的方式来进行零停机升级的。 蓝绿发布是通 shell 脚本进行操作的,由于 Traefik 的 docker provider 不支持动态的增删服务,本方案采取了 file provider,shell 会启动新服务的时候修改Traefik 的 file provider 来把新服务加入到负载均衡的集群,并在新服务启动完成后,把老服务从负载均衡迁出并停用老服务。 得益于 Traefik 对动态配置的支持,所有对配置文件的修改是无需重启 Traefik,它会自动发现配置文件的变动,把最新的配置加载到程序内部。 整个 部署 流程中始终都会有容器在线提供服务,我们也就实现了零停机升级系统的目标。 本文最后会附上一份完整的 demo 链接,感兴趣的可以下载之后运行一下了解整个操作机制。 本方案还存在一些局限,如蓝绿发布其实是 blue 和 green 交替提供服务,如果你本身是一个服务集群,这个方案并不能很好的适应。 如果你面临上述问题可以考虑 docker swarm 来解决问题,或者部署 K8s,其间的选择主要是看你服务的规模。 本文到此基本结束,如果你更好的想法,欢迎留言讨论。 示例代码:https://github.com/yunxi177/zero-downtime References zero-downtime deploys with Docker Compose and Traefik:https://github....

September 18, 2024 · 1 min · 云溪

Go CI/CD 实践

最近用 Go 开发项目,本地发开和调试起来都非常方便,当到了接口对接阶段就出现了问题。 CI/CD 中文为持续集成/持续部署是敏捷开发的重要一环,有了 CI/CD 你可以快速的构建出 Feature/Fix 环境,加快版本的上线节奏。 本次的设计目标是:让开发者只需要提交代码即可,由 Gitlab 去执行代码构建和代码部署的能力,此外我还需要在部署阶段保证服务的正常可用。 我将 Gitlab 流水线 (Pipelines) 设置了两个阶段: 构建:编译出 Go 的可执行文件 部署:完成线上的部署工作 在部署阶段, Runner 会保证原有接口的正常的情况下: 用最新的可执行文件启动一个临时服务,并修改 nignix 反向代理,将所有的新请求代理到临时服务 停掉并升级老服务 把 Nginx 反向代理代理到新的正是服务,关闭掉临时服务。 具体 .gitlab-ci.yml 内容如下: stages: - build - deploy variables: GOMODCACHE: /project-path/mod build: image: golang:1.21 stage: build cache: # 缓存 paths: - mod script: - touch ./config/config.yml # 编译你的 Go 程序 - export GO111MODULE=on - export GOPROXY=https://goproxy.cn - go mod download - go build -ldflags "-linkmode external -extldflags -static -s -w" -o main ....

February 1, 2024 · 1 min · 云溪

jenkins pipeline 环境变量详解

关于 Jenkins 的环境变量,可以分为系统内置环境变量和自定义环境变量。系统内置环境变量是 Jenkins 内部定义的环境变量。自定义环境变量是用户自己定义的环境变量 系统环境变量 jenkins 的内置环境变量的查看方式有两种,一种是通过 web url 地址查看,另一种是通过 shell 命令 printenv 查看 方式一:通过地址访问 直接在浏览器中访问 ${YOUR_JENKINS_HOST}/env-vars.html 页面就可以,比如 http://localhost:8080/env-vars.html ,每个变量的用途写的都很清楚 方式二:printenv 通过 shell 命令printenv 获取 pipeline { agent any stages { stage("Env Variables") { steps { sh "printenv" } } } } 通过执行上述 pipeline 的构建,就可以打印出系统内置的环境变量 自定义环境变量 在内置环境变量的基础上,有事我们也需要定义我们自己的的环境变量来方便开发和部署,自定义环境变量的设置分为三种,分别是:声明式,脚本式,内置函数式,接下来分别讲解一下三种方式各是如何设置的。 声明式 声明式定义结构如下: environment { key = value } 声明式可以在 pipeline 的任意阶段声明,看如下示例 pipeline { agent { label any } environment { //全局环境变量 NAME = "zhangsan" } stages { stage('Build') { environment { // 仅在 Build 阶段下有效的环境变量 NAME = "Andy" } steps { sh 'printenv' } } } } 脚本式 脚本式基本结构如下:...

June 7, 2021 · 2 min · 云溪

前端CI/CD落地实践

随着 nodejs 的兴起,前端开发也进入了 新的时代,webpack 的诞生,更是让其如虎添翼,构建出欣欣向荣的前端生态. 然而事物的发展总是在:发现问题->解决问题->引入新问题中往复。 webpack 给前端带来了一个新的高频操作就是打包,高频的打包会带来如下问题: 阻塞前端工作:前端必须等到打包完成,才能 进入后续工作,如果打包时间过长,这中间就会阻塞就会更加明显。 影响团队协作:当功能点开发完成后,未避免频繁打包,会将多个功能点合并在 一起打包,这样就会导致测试没有办法提前介入测试,如果测试出问题的功能点是在几天前开发的,对于代码已经有所遗忘,还需要阅读代码帮助找回记忆gg。 打断专注时间:如果前端正在专注的解决一个复杂问题,此时出现紧急问题需要打包,使得前端不得不从当前工作中抽身出来进行打包,打包完成后将需要一段时间的预热才可以像之前一样 专注的处理未完成的问题。 对于上述 问题完全可以通过工具构建出一套 CI/CD 方案交由计算机来解决,让前端工程师从打包解放出来。 工具 jenkens: 是一款由 JAVA 编写的开源的持续集成工具. gogs: 轻量级代码仓库 jenkins 与 gogs 的通讯是通过 Gogs plugin 通过 webhook 来通讯的。 方案 方案设计大致如下: 方案执行步骤: 前端工程师往代码仓库 push 代码 gogs 会调用 jenkins 的 webhook 地址触发 jenkins 工作流 jenkins 会将前端代码从代码仓库中拉取最新的代码,并执行构建流程 将构建好的代码上传到 dist 仓库(如果存在 CDN 则清除 CDN 缓存) push dist 仓库到 gogs 远程仓库 gogs 触发 dist 仓库的 webhook,将服务器代码更新到最新的打包文件 完成部署 测试人员执行测试用例(如果由缺陷,将缺陷反馈给前端开发人员) 好处 完成上述方案,前端工程师只需要将前端代码 push 到远程仓库,服务器会自动构建响应的包,并部署到测试服务器上供测试测试,前端可以缩小提交粒度并更快的将功能交付测试,也可以将问题尽早暴露尽早解决。...

March 29, 2021 · 1 min · 云溪