求知若饥,虚心若愚。
很长时间没写博客了,主要原因出在上家的公司,自己承受着三个半月没工资的痛苦。
突然想起普希金的《假如生活欺骗了你》:
1 | 假如生活欺骗了你 |
对于一个横跨2000多公里、漂泊他乡的人来说,在一线城市打拼,没收入意味着什么?
1 | 上海房租让你喘不过气 |
梦想还是要有的,万一见鬼了呢?但残酷的事实是梦想和现实往往不能共存
。
如果共存的话,中国人这么多,怎么没出来第二个马云、第二个马化腾?
话转回来,谈谈技术吧。
实现自动打包发布上线
这个功能?简单理解,减少重复性工作,方便项目管理
。
一个产品或项目的上线要经历开发、测试、部署
三个环节。
一个公司,可能产品或项目就有上百个,那么每个产品或项目都需要重复走这三个环节吗?答案是必须的,但如果能减少里面重复性的工作
岂不是能更好的管理
?
如何高效的进行迭代开发,与同类公司、同类产品作竞争,自动化部署
就显得尤为重要。
上图简要说明了如何实现自动化部署的流程。
先看下实现后的效果:
神奇吧?通过一个立即构建
按钮,就实现了页面内容的更改,将图片和文字都替换了。
那么点击按钮后究竟做了哪些事情呢?
简要概括实现了以下步骤:将gitlab上的代码下载到了本地电脑上,且进行了代码压缩,压缩完成后发布压缩包到自己的阿里服务器上,阿里服务器成功接收到压缩包后,解压放到了服务器指定目录,最后通过nginx反向代理实现了自动化部署。
该章节会讲解的很细,细化到前端工程师从开始编码,到最后运维工程师发布上线的完整流程,每一步做了具体哪些操作,从而实现自动化部署的。
具体步骤如下:
该部分内容属于前端技术范畴,之前讲解过前端构建的文章《前端工程化+webpack》,在这里就不详细说明了。
vue和webpack方面,需要特别注意两个地方:
1.vue history模式
对于vue开发的单页面应用(SPA)时,在切换不同页面的时候,可以发现html永远只有一个,而vue-router默认hash
模式。
vue hash模式:
格式:http://localhost:8081/#/parent/id
说明:利用url的hash来模拟一个完整的url,当url改变时页面不会重新加载。
vue history模式:
格式:http://localhost:8081/parent/id
说明:利用HTML5的history.pushStateAPI来完成url的跳转而不需要重新加载页面。
用hash模式的缺点是#这种形式真的很丑,完全不像正常的url地址。
既然如此,当然选择使用history模式啦。
铺垫了那么久,想使用好history模式,还需要后台配置支持
。
因为我们的应用是个单页面应用,就一个html文件,如果后台没有正确的配置,当用户在浏览器直接访问http://xxx.com/parent/id时就会返回404,找不到这个页面。
想解决这个问题很简单,只需要在后台配置如果url匹配不到任何静态资源,就跳转到默认的index.html。
vue的router代码中设置默认跳转的页面是componentNotFound组件,404页面:
1 | import Vue from 'vue' |
nginx具体配置如下:
1 | location / { |
最终效果:
2.webpack可配置接口代理
开发一个页面的时候,可能会遇到接口是从不同服务器提供的。如果想实现跨域访问,那么必须配置代理。
以vuejs-templates模板为例,Github地址:https://github.com/vuejs-templates/webpack。
本地想配置代理,具体实现如下:
1.找到项目里config的index.js,配置接口域名:
1 | ... |
2.通过axios和qs创建一个http实例,且与代理/api/wechat后缀保持一致
1 | import axios from 'axios' |
3.在需要的页面使用该方法即可
1 |
|
本地代理接口的原理:
将含有localhost:8081/api/wechat/xxx匹配的接口后缀自动代理到http://zm01bs.zmredu.com/api/wechat/xxx。
上面只说到本地的接口代理,真正的项目部署上线也需要配置接口代理,当然又要用到代理神器nginx。
服务器想配置代理,具体实现如下:
1 | location ~ ^/api/wechat { |
想了解更多关于代理的知识,强烈推荐姐妹篇《谁说前端不需要懂 Nginx》 和 《谁说前端需要懂 Nginx》。
这部分没什么特别需要讲的,但是一定要会安装Git,且熟练使用Git命令
。
下面总结了常用的Git命令,仅供参考:
1 | 分支类: |
想系统的了解学习Git相关的更多内容,强烈推荐廖雪峰老师的《Git教程》。
至此,研发阶段所做的工作已经完毕。最后一句话总结这个阶段究竟做了什么事:
根据业务实现页面,通过webpack打包生成dist上线目录和源码通过git命令上传到远程仓库。
附上项目效果图:
本地打包提交上传gitlab:
gitlab远程仓库接收成功:
第一次听到jenkins
这个词是从我媳妇儿那听到的~惊不惊喜、意不意外?哈哈,因为她是个测试工程师,也懂点自动化测试。于是乎jenkins给我第一印象就是它是做自动化测试用的
。
真正接触jenkins后,发现jenkins的强大之处不仅如此,还有更多更强大的功能,值得我去探索。
大致说下通过jenkins做了哪些上线前的准备工作:
jenkins官网是https://jenkins.io/,
1.安装jenkins
最简单的方式是使用war包安装,具体操作可根据官网的指示操作,
安装教程地址:https://jenkins.io/doc/pipeline/tour/getting-started/
安装时需注意一个地方,因为jenkins是基于Java开发的
,所以需要提前安装Java运行环境,且JDK版本不能低于1.8
。
将下载下来的war包放到任意目录,
执行java -jar jenkins.war --httpPort=12000
执行第一次的时候可能会很慢,因为需要安装jenkins。
安装成功后的会在当前用户根目录下生成一个.jenkins目录,如:/Users/username/.jenkins
,里面就是jenkins的运行程序。
Mac电脑可通过Command+Shift+.
实现对隐藏目录的显隐,安装成功后如下:
.jenkins目录下,通过名字能大概清楚其每个目录下的意义:
1 | jobs 放创建的任务的 |
最终运行成功的控制台:
用浏览器打开http://localhost:12000/
运行,提示您输入管理员密码。按提示路径打开密码文件,输入密码即可。
这个就不截图了,一直默认点击下去就行,安装常用插件可能需要些时间,安装成功后,点击继续,进入创建用户页面。输入用户名、密码,点击完成会进入到jenkins的主页。
这里值得注意的地方是一定要有Git plugin
,因为可以通过该插件实现gitlab和jenkins的互通
。
打击右边开始创建一个新任务
,输入一个任务名称,选择构建一个自由风格的软件项目,点击确定。
接着选择系统管理
找到管理插件
,进行插件的安装:
这里介绍jenkins第二大插件神器Publish Over SSH
,因为可以通过该插件实现jenkins和阿里服务器的互通
。
接着选择可选插件
,搜索Publish Over SSH,进行下载安装,最后重启jenkins。安装成功后,可在已安装
插件中找到:
配置任务有两个功能点:
找到新建好的任务名称,点击后面的小三角,选择配置
:
1.gitlab与jenkins的关联,找到源码管理
,选择Git,输入自己gitlab的地址到Repository URL
后面,默认选中的是master分支,点击应用配置成功。
2.执行压缩打包操作,目的是为上线到阿里服务器做准备
。将gitlab仓库下面的dist目录打包压缩成gz包。找到构建
,点击增加构建步骤
,选择执行shell
:
输入tar zcvf dist.tar.gz dist
命令,该命令的意思是将在workspace目录下的当前任务下的dist目录打包,生成dist.tar.gz包
,点击保存配置成功。
至此,gitlab与jenkins构建阶段所做的工作已经完毕,可以试着点击立即构建
按钮,发现在workspace目录下多了从gitlab仓库下载下来的代码,且仓库下面的dist目录,被打包成了dist.tar.gz。
最后一句话总结这个阶段究竟做了什么事:
jenkins关联gitlab仓库,压缩打包仓库下面的dist目录
终于到最关键的一步,jenkins和阿里服务器进行关联。
大致说下做了哪些工作:
jenkins与阿里服务器想实现关联,需执行以下两个命令成功,且不需要输密码:
1 | ssh ww@101.132.111.255 -p 33333 |
先通过cd ~/.ssh
找到.ssh
目录,然后open .
打开该目录,如果你本地拥有公钥和密钥的话,就不需要创建,直接使用即可。
1.如果没有,先执行创建:
1 | ssh-keygen -t rsa -P '' |
2.如果已经存在,则执行:
1 | ssh-copy-id -i id_rsa.pub ww@101.132.111.255 -p 33333 |
ssh实现免密码登录是通过公钥认证
实现的。
公钥认证,是使用一对加密字符串,一个称为公钥(public key), 任何人都可以看到其内容,用于加密;另一个称为密钥(private key),只有拥有者才能看到,用于解密。
在使用jenkins自动构建并远程登录服务器进行发布应用的时候,需要使用ssh公钥认证来解决登录服务器的问题。
上面两个命令完成了哪些事情可自主查询相关文章,再这就不一一说明了,因为一时半会真说不清楚。
3.ssh登录阿里服务器,在.ssh
目录下会发现多了一个authorized_keys
文本,执行一下命令:
1 | sudo chmod 644 authorized_keys //提高该文件权限 |
查看authorized_keys
文本,你会发现里面的内容,和你本地电脑上id_rsa.pub
公钥上的内容完全一致。
至此,你应该可以通过ssh协议实现免密码登录了。
这块内容如果运气好,可能不会遇到,如果能执行sftp -P 33333 ww@101.132.111.255
成功,这节就可以忽略了。
我在配置jenkins的时候,明明能够通过ssh实现免密码登录,但是在配置SSH的时候,一直报以下错:
1 | Failed to connect SFTP channel. Message [java.io.IOException: Pipe closed |
解决方案如下:
1.ssh登录到阿里服务器,执行命令,全局搜索含有sftp-server的文件
,结果如下:
1 | 执行搜索 |
2.执行命令查看sshd_config
文本,结果如下:
1 | 执行查看 |
最后发现全局搜索的结果里面竟然没有任何目录与sshd_config
文本里面的目录相对应,难怪sftp命令执行不了。
3.将sshd_config
文本里面的内容替换:
1 | # Subsystem sftp /usr/libexec/openssh/sftp-server |
4.最后重启ssh,更新ssh配置:
1 | sudo service ssh restart |
至此,你应该可以通过sftp协议实现免密码登录了。
1.配置全局系统设置SSH
打开jenkins控制台,选择系统管理
找到系统设置
,点击进入:
进入后,找到Publish over SSH
模块,配置如下:
这一步是最最关键的,如果你按照我之前的说法能够执行那两个命令的话,相信你在配置SSH这一步时肯定不会出错。
配置内容讲解:
1 | Jenkins SSH Key |
点击右下角的Test Configuration
按钮,如果出来Success
,那么恭喜你,你的jenkins与你的阿里服务器已经成功打通了。
2.SSH与任务关联
打开jenkins控制台,找到之前创建的任务名称,点击后面的小三角,选择配置
。
找到构建后操作
,点击增加构建后操作步骤
,选择Send build artifacts over SSH
。
配置内容讲解:
1 | SSH Server |
重点解释下Remote directory
和Exec command
两个输入框的内容。
'zhangmen/master/'yyyyMMdd_HH
的意义:master
和yyyyMMdd_HH
。/home/ww/zhangmen/master/yyyyMMdd_HH
中高级
,然后勾选上Remote directory is a date format
,表示远程目录是需要格式化时间的。可能有人会问了,为什么配置个远程目录要这么麻烦,还要用到动态获取日期来生成目录,还有就是master有什么好注意的?
我来说说这里面的缘由:
在配置服务器目录的时候,一定要想到扩展性和维护性。
首先公司里面可能会有许多产品和项目,那么肯定需要进行整理和分类。一个任务只能对应一个项目,一个项目可能有正式环境和测试环境两个。
那么服务器下面的目录结构大致应该是这样的:
1 |
|
这样的结构看上去还OK,但是每个项目可能会进行多次迭代,如果有问题,想进行版本回退该怎么办?
于是乎目录结构应该是这样的:
1 |
|
以我的目录结构为例:
1 | 正式环境和测试环境: |
这样做的话,如果正式部署的时候线上出了问题,比如20180706_19发布的包有问题,想回退的话,直接解压之前20180703_16的包,替换dist即可。
先获取当前服务器的年月日时
,找到该目录,才能实现解压。sh /home/ww/crontab/zxvf_git.sh
构建成功后,执行阿里服务器下/home/ww/crontab/zxvf_git.sh里面的程序
。在zxvf_git.sh
文件里面,保存的内容如下:
1 | dateformat="`date +%Y%m%d_%H`" |
zxvf_git.sh里面的程序实现了解压刚刚上传成功的dist.tar.gz包到master目录
这个功能。
至此,jenkins构建内容就全部结束了,试试立即构建
看下效果吧,最后一句话总结这个阶段究竟做了什么事:
jenkins配置全局SSH,通过SSH配置相应的任务,任务命令需与阿里服务器配合
终于到最后一步了,回忆一下上面jenkins的配置过程,确实不容易。构建那么久,必须要看到效果才算完美,因此需要用到nginx来代理显示。nginx是一个高性能的HTTP代理服务器,基本上所有公司都会用到它。nginx主要作用:接口转发、反向代理
。
上面提到过两个重要目录:/home/ww/zhangmen/master/dist
和/home/ww/zhangmen/develop/dist
。
一个是正式环境需要访问的页面目录,另一个是测试环境需要访问的页面目录。
那如何才能实现访问http://xcx.xjshen.cn
和http://test.xjshen.cn
来对应访问这两个目录呢?
准备工作:登录阿里控制台,在域名下的域名解析
中添加xcx
和test
的解析记录:
1.记录添加成功后,登上阿里服务器,找到conf.d
目录:
1 | cd /etc/nginx/conf.d |
2.conf.d
目录下新增两个配置文件:
创建xcx-xjshen-cn-80.conf
文件,添加如下内容:
1 | server { |
创建test-xjshen-cn-80.conf
文件,添加如下内容:
1 | server { |
具体里面配置是啥意思,可自主查询相关文章,再这就不一一说明了。
3.测试下nginx配置是否正确,重启nginx
1 | sudo nginx -t |
如果有遇到nginx 403
这个问题,可参考以下操作:
1.执行命令:ps aux|grep nginx
查看nginx进程的运行状态
2.输出如下:
1 | www-data 17111 0.0 0.0 118184 3124 ? S 23:07 0:00 nginx: worker process |
发现行程拥有者竟然不一致www-data
和ww
。
3.编辑nginx/nginx.conf
配置文件,保存:
1 | sudo vim /etc/nginx/nginx.conf |
4.重启nginx,再次执行ps aux|grep nginx
命令查看:
1 | sudo nginx reload |
全部换成同一个行程拥有者,403问题解决。
至此,nginx配置阶段所做的工作已经完毕。最后一句话总结这个阶段究竟做了什么事:
将正式目录成功绑定到正式域名,将测试目录成功绑定到测试域名
上面详细讲解了配置正式部署任务
的所有流程,可以自行再新建一个测试部署任务
,从gitlab与jenkins那部分内容开始,重新创建任务,配置任务即可…
最后你通过本地jenkins,能成功实现自动打包发布上线啦!一个按钮就搞定所有!