最小化DevOps自动化流程(Golang)
-
Why?
为什么要做自动化流程?
在开发过程中,我们在本地机器上做开发,完成一次功能迭代之后,如何发布到远程产品服务器一直是个很头疼的问题。最通常的做法就是使用(S)FTP把代码(或者代码压缩包)覆盖到服务器上。这样的做法虽然“直截了当”,但是容易出错,而且全程需要人为干预。(笔者亲历过其他项目部门的负责人过来求助,说发布时拷贝代码到服务器的过程中,服务器突然宕机没有反应。)所以我们需要一种方式帮助我们完成代码发布的整个过程。有非常多的第三方工具帮助我们实现流程自动化的目的。
我们要完成的目标是:1,无人干预;2,缩短发布时间,减少发布时期存在的风险;3,增加项目迭代效率。
-
What?
用什么工具来做自动化流程?
git, github(gitlab)
-
When?
在什么时机下创建自动化流程?
理论上是在第一次发布项目到服务器之前就需要做自动化流程。但是根据迭代开发的思想,我们在创建项目的时候就应该开始着手创建自动化流程。
-
How?
如何创建一个最小化的自动化流程?
我们通过三部实现开发部署流程自动化。
-
创建版本仓库
接着clone 远程仓库到本地开发机器.
如果你还没有创建任何项目代码文件。此时可以使用命令:
git clone git@gitlab.com:EdisonLeung/devops.git cd devops touch README.md git add README.md git commit -m "add README" git push -u origin master
如果您已经开始了本地机器上的编码工作,此时可以在项目目录下使用命令:
git init git remote add origin git@gitlab.com:EdisonLeung/devops.git git add . git commit -m "Initial commit" git push -u origin master
如果您不光在本地开始了编码工作,同时在本地已经创建了git仓库.此时可以在项目目录下使用命令:
git remote rename origin old-origin git remote add origin git@gitlab.com:EdisonLeung/devops.git git push -u origin --all git push -u origin --tags
最后在服务器clone我们的版本仓库(记得添加服务器SSH Key到Gitlab):
cd ~/www git clone git@gitlab.com:EdisonLeung/devops.git
clone完成:
root@aliyun:~/www# git clone git@gitlab.com:EdisonLeung/devops.git Cloning into 'devops'... remote: Enumerating objects: 3, done. remote: Counting objects: 100% (3/3), done. remote: Total 3 (delta 0), reused 0 (delta 0) Receiving objects: 100% (3/3), done.
目前我们从项目开发到项目部署有三个动作要手动做:
a) 本地机器git push到远程仓库
b) 远程服务器git pull拉去远程仓库版本
c) 重启webserver服务
第二步我们就要将这三个动作自动化。
-
创建自动化部署脚本
创建deploy目录,并创建两个文件,main.go和deploy.sh:
deploy.go
package main import ( "io" "log" "net/http" "os/exec" ) func relaunching() { cmd := exec.Command("sh", "./deploy.sh") err := cmd.Start() if err != nil { log.Fatal(err) } err = cmd.Wait() } func restart(w http.ResponseWriter, r *http.Request) { io.WriteString(w, "<h1>deploy server: restarting webserver...</h1>") relaunching() io.WriteString(w, "<h1>deploy server: webserver restarted!</h1>") } func main() { http.HandleFunc("/", restart) http.ListenAndServe(":5000", nil) }
当服务器5000端口被访问时,http.HandleFunc会创建路由调用restart函数relaunching函数,调用过程中在浏览器输出启动过程.
最终relaunching函数调用命令行deploy.sh来重启webserver.
deploy.sh脚本内容如下:
#! /bin/sh kill -9 $(pgrep webserver) cd ~/www/devops git pull git@gitlab.com:EdisonLeung/devops.git ./webserver &
再创建一个main.go来启动一个最小web页面:
代码示例如下:
package main import ( "io" "net/http" ) func index(w http.ResponseWriter, r *http.Request) { io.WriteString(w, "<h1>This is Index Page!</h1>") } func main() { http.HandleFunc("/", index) http.ListenAndServe(":8080", nil) }
注意:这里的http监听端口号要与deploy.go内的端口号区别开,不能是相同端口号,不然会有端口冲突造成服务不能启动!
这时的代码架构就完成了,下面我们来编译发布代码:
因为我们在本地机器环境编译代码,所以对于异构系统来说,go语言为我们提供了相应的参数来针对不同的操作系统和架构进行代码的编译:
因为服务器所采用的是linux amd64的系统,所以编译命令的环境变量如下:
main.go编译生成webserver
env GOOS=linux GOARCH=amd64 go build -o webserver
进入deploy目录编译生成deploy
env GOOS=linux GOARCH=amd64 go build
输出的文件如图:
下面我们提交项目:
进入DevOps根目录
git add . git commit -m "basic automatic publishing feature." git push origin master
提交结果:
Counting objects: 8, done. Delta compression using up to 4 threads. Compressing objects: 100% (8/8), done. Writing objects: 100% (8/8), 5.03 MiB | 1.21 MiB/s, done. Total 8 (delta 1), reused 0 (delta 0) To gitlab.com:EdisonLeung/devops.git 91e5396..c9c087f master -> master
接下来就要进入服务器拉去最新版本代码并发布。
登录远程服务器拉取代码:
root@aliyun:~/www/devops# git pull remote: Enumerating objects: 9, done. remote: Counting objects: 100% (9/9), done. remote: Compressing objects: 100% (8/8), done. remote: Total 8 (delta 0), reused 0 (delta 0) Unpacking objects: 100% (8/8), done. From gitlab.com:EdisonLeung/devops 91e5396..c9c087f master -> origin/master Updating 91e5396..c9c087f Fast-forward deploy/deploy | Bin 0 -> 6594124 bytes deploy/deploy.go | 28 ++++++++++++++++++++++++++++ deploy/deploy.sh | 6 ++++++ main.go | 15 +++++++++++++++ webserver | Bin 0 -> 6498848 bytes 5 files changed, 49 insertions(+) create mode 100755 deploy/deploy create mode 100644 deploy/deploy.go create mode 100644 deploy/deploy.sh create mode 100644 main.go create mode 100755 webserver
将deploy目录拷贝至用户根目录:cp -r ~/www/devops/deploy/* ~/
启动webserver和deploy service:
cd ~ ./www/devops/webserver & ./deploy &
打开浏览器查看结果显示:
两个服务均启动成功了!
注意1.两个服务启动前,先用以下命令查看是否有相同服务正在运行,如果有,先将其kill掉:$ps aux | grep webserver
$kill [pid]
注意2.使用chmod命令给服务程序和脚本提权:chmod a+x webserver
-
自动获取版本推送事件webhook
我们将部署触发的地址添加到远程版本仓库的webhook中,如图:
webhook添加完成:
下面我们验证一下这个简单的自动化流程的效果。
我们把显示的文本改为"This is the Index Page2".
然后编译提交
查看结果:
文章中提到的做法仅仅是抛砖引玉,实现使用Golang是因为语言结构上简短精悍,更容易理解流程,如果您使用其他语言,例如python,php等都可以用相同的方式实现。同时流程上仅关注自动化的过程,开发编译的整个过程都在本地进行,服务端没有提到任何反向代理的服务及运行环境、虚拟环境的配置,因为在虚拟化环境下这些做法会有很多变化,很多情况下完全没有必要做,或者很少去做。更没有必要像目前这样自己去实现自动化流程。如果没有虚拟化实现自动化流程的经验,直接上手虚拟化,还没有很深入理解的情况下,在虚拟化环境下做DevOps及微服务架构,会给自己带来很大的困惑。具体这些将会在后续的文章中提到。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Java入门系列-27-反射
咱们可能都用过 Spring AOP ,底层的实现原理是怎样的呢? 反射常用于编写工具,企业级开发要用到的 Mybatis、Spring 等框架,底层的实现都用到了反射。能用好反射,就能提高我们编码的核心能力。 反射机制 JAVA反射机制是在运行状态中,对于任意一个实体类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性。 作用: 在运行时判断任意一个对象所属的类 在运行时构造任意一个类的对象 在运行时判断任意一个类所具有的成员变量和方法 在运行时调用任意一个对象的成员变量和方法 生成动态代理 常用的类: java.lang.Class:代表一个类 java.lang.reflect.Method:代表类的方法 java.lang.reflect.Field:代表类的成员变量 java.lang.reflect.Constructor:代表类的构造方法 Class 类 Class 类的实例表示正在运行的 Java 应用程序中的类和接口,Class 没有公共构造方法,Class 对象是在加载类时由 Java 虚拟机及通过调用类加载器中的 defineCla...
- 下一篇
C++ 编译器
C++编译器 当我们定义了一个类的时候, C++编译器在默认的情况下会为我们添加默认的构造方法, 拷贝构造方法, 析构函数和=运算符 在第一次创建对象的语句中如: MyString myString = "hello, world!";中, 如果我们定义的构造函数为如下, 则就是隐式调用构造方法, 如果构造方法使用了explicit修饰则会报错, 总之在第一次创建对象的语句中, 就算出现了=, 只能调用构造方法, 而不是=方法, 因为我们是要构造对象, =真正起作用是在这个对象创建完毕之后 MyString(const char *str="") { this->len = strlen(str); this->values = new char[this->len + 1]; strcpy(this->values, str); } C++中的对象在内存中的分布 没有继承的情况下 就是一个结构体的分布 单继承的情况下(方法使用virtual修饰) A为基类, B为派生类, 在创建B的实例的时候, 在内存中B的内存中会有一个虚指针(virt_pa)指向一个虚函数...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- 设置Eclipse缩进为4个空格,增强代码规范
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- SpringBoot2整合Redis,开启缓存,提高访问速度
- CentOS关闭SELinux安全模块
- CentOS8安装Docker,最新的服务器搭配容器使用
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程