最后的结尾,留给 Jenkins 吧。

最后的结尾,留给 Jenkins 吧。

编程那点事 随便写写 PHP 3874 字 / 8 分钟

相信不少人都听说过国内著名的安全问题反馈网站——乌云网。这个网站定位是“自由平等的”的漏洞报告平台。平台会员中有不少大佬白帽子。他们挖掘计算机、网站上的漏洞,然后在乌云网上提交反馈。而乌云网则会第一时间通知厂商进行修复。乌云网同时也会根据漏洞的危险程度给予白帽子奖励。

但厂商若接到通知后迟迟不给予回应,乌云便会将漏洞逐渐披露,先是给核心的会员,若厂商始终不回应,最后漏洞将会向公众开放。乌云的这一做法确实在一定程度上起到了促进互联网安全的作用。但是,由于它的过于“强大”,到后来先后连续披露京东商城、支付宝、网易等国内著名互联网企业在用户信息安全防护中存在的高危漏洞;国内知名技术社区 CSDN 的 600 余万用户资料。此后又陆续有消息称,包括多玩 800 万用户信息、7K7K 小游戏的 2000 万用户、网站的 1000 万用户资料,以及人人网、U9网、百合网、开心网、天涯、世纪佳缘等网站数据库也通过乌云网漏洞发布平台遭遇不同程度的外泄。

好的,这下事情就闹大了。最后迫于舆论压力,2016 年 7 月 20 日 乌云官方网站关闭。网站首页显示通知 “乌云及相关服务升级公告。”

(真正的原因大家都懂,因为触犯到了一些公司的利益。)

但是,虽然乌云网倒下了,但是网站上还有类似“乌云知识库”的网站,上面保存了原来乌云网的一些公开的漏洞,其中有一些还真的是高危级别的。你可以在这个网站看到:http://www.anquan.us/

说真的,看乌云网上发布的漏洞,真的有种看黑客大片的满足感,虽然明知道这些漏洞肯定已经被修复了,但是还是觉得超厉害,超满足。

进入 bilibili 内网,8000+ QQ 用户密码,控制游戏全服玩家,强制和马化腾聊天,扫描腾讯内网...... 真的是想都不敢想啊!向大佬们低头。

但是,今天其实并不是聊网络安全的。以上只是一个引子。点开上面第一个登入 bilibili 内网的漏洞的文章,你可以从作者的截图中对 b 站内部的技术栈有个大概的了解。

b 站这种由 bishi 最初一人建立起来,后面拉了些人一起干的小团队项目,其中所用到的技术才是最接地气的。相比起来,我认为阿里,腾讯那些大厂所用的技术其实对于个人而言并没有太多的参考价值了。

那么 bilibili 这小破站内部到底用了哪些技术呢?先报一个猛料:他们的后台审核视频的系统,其实是 dedecms 改的!!对,你没有听错,不是他们自己写的,是拿 dede 的后台改的!真的是接地气。

什么?要实锤是吧?给你!

(随便点开一个视频,打开控制台看 cookies!)

        怎么说呢,没想到 b 站居然会这么 low ,要知道 dedecms 可是被一堆服务商当做毒瘤的,老薛主机装这个是要被封号的!

除此之外呢,我们从那篇文章中还得知了 b 站内网,域名为:bilibili.co,需要 OpenVPN 连上内部 VPN 网络进入。了解到了 b 站是使用自己服务器搭建的 GitLab 进行代码版本管理的。我还以为是花钱开的 GitHub 私有 repo。

同时,他们还有内网的百科:

(看这个内容和排版,嗯,WordPress 的味道)

        还有这个:

第一次看到这个我是懵逼的,Jenkins......是什么鬼咯?原来看到有不少项目都在用,觉得是那种很牛逼的东西,一般的小团队用不到的。但是......看到破站也在用,才意识到这可能是团队开发中必不可少的东西。

上网查了一波,完全看不懂介绍啊!什么叫持续集成啊?什么叫监控重复的工作?单元测试用的?不像啊。真的是一脸懵逼。

直到陆陆续续写了好几个 PHP 的项目后,我才发现了一个十分繁琐的事情——我每次写好的代码,我需要用 ftp 把它们传到服务器上,就算是用了版本控制放到 GitHub,部署到服务器上也是手动去 clone。久而久之就感觉烦了,有什么东西可以代替我做这些事吗?

上网一搜,发现都在说这个 Jenkins。原来如此,Jenkins 其实是检测到你向的 Git 仓库里提交了新的版本后,会自动执行一系列事情,比如帮你自动部署到服务器上,给你发个邮件之类的......

嗯,是个好东西。那么我也尝试着装一个吧。

在往 VPS 上装 Jenkins 前,我吸取了上次搭建树莓派内网穿透的教训,提前备份了服务器快照,以备不测时可以一键还原。(果然刚开始确实是玩脱了的,然后回滚了快照。)

Jenkins 是需要 Java 环境才能运行的,官方推荐是安装 Java 8。嗯,那么连上服务器,开始吧!

这个时候,Mac 用户的优越感就体现出来了。当 Windows 系统还要安装第三方比如 Xshell 等软件时,我们直接就可以打开系统自带的终端,然后 ssh 连接,十分便捷快速。(我吹爆苹果!)

(就是这个,超级好用!)

        简简单单就好啦~ 值得注意的是,端口号不能以在服务器 IP 后加冒号的形式填写,需要加上 -p 这个参数。并且貌似如果不在 IP 前填写用户名的话,会默认以 Mac 上的用户名登录,并不会向你询问。

(黑底绿字,可以这很 Geek)

        我们全程使用 yum 来安装 Java 以及 Jenkins,首先可以先查看一下 yum 库中的 Java 版本:

[shell]# yum -y list java*[/shell]

        我们需要安装 Java 8 的所有 jdk:

[shell]#yum -y install java-1.8.0-openjdk*[/shell]

        安装完成后可以键入 java 来确认是否安装成功。之后我们就开始安装 Jenkins 啦!安装方法遵循 Jenkins 官方的文档。

[shell]# sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat/jenkins.repo # sudo rpm --import https://pkg.jenkins.io/redhat/jenkins.io.key[/shell]

        我猜想这两段命令的意思是将 Jenkins 的库添加到 yum 里面。之后就可以直接使用 yum 命令安装最新的 Jenkins 了。

[shell]# yum install jenkins[/shell]

        安装完成后,Jenkins 默认是使用 8080 端口,如果与之前的端口有冲突,可以进入 /etc/sysconfig/jenkins 进行修改。安装了宝塔面板的,请不要忘记在“安全”选项中开放相应的端口。

        一切准备就绪后,就可以启动啦!

[shell]# service jenkins start[/shell]

        速度飞快,之后就可以在浏览器中打开 Jenkins 了。最初 Jenkins 为了确认你管理员的身份,会需要你复制它根目录下的一个文件中的密码进行解锁。这些都很好操作:

因为是一个全新的玩意儿,作为第一次接触的萌新,我直接选择了新手入门,接着 Jenkins 就会帮我们安装常用的插件,比如 Git 之类的。

        等等,我好像看到了什么奇怪的东西!这个插件的名字怎么这么独特!

SSH Slaves!SSH 奴隶!我知道这是个帮你自动处理项目部署工作的东西,但是你起这个名字羞辱一个插件真的好吗?

        值得一提的是,插件貌似是 Jenkins 中十分重要的东西,昨晚看了开源中国发来的邮件,说是他们自家的“码云”已经支持 Jenkins,而使用的方法,就是需要安装他们提供的插件。

        首先,我先新建一个测试项目体验一下吧,选择“构建一个自由风格的软件项目”:

因为是测试,不太想在 GitHub 上创建测试的 repo,怕会玷污了我的贡献记录,所以我使用了开源中国的“码云”(阿里巴巴律师函警告!)

(一个十分简单的 PHP 文件,就 echo 了两句话)

        在 Jenkins 里填写好项目的 Git 仓库,我要的功能其实只是将代码复制到服务器目录上,只需要 clone 就行了,除非是私有项目,否则不加 SSH Key 也可以的。

其中下方的构建触发器就是我们常用的 Webhook 了,不过这个 Webhook 十分简单,只需要 GET 请求一个 URL 即可,连 POST 都免了,自己用手机都可以远程构建。

(没打码,TOKEN 暴露了)

        之后便可以开心的先来一次构建啦~

这里只是将我们的项目从远程 Git 仓库 clone 到了本地,之后就没有别的操作了。在上面的项目设置中,我们可以设置构建时需要做的事。但是......我并不是很知道正式的应该怎么部署 PHP 代码到服务器,网上也没有搜到。便异想天开地选择执行一段 shell 命令,直接将 Jenkins clone 下来的 Git 仓库中的文件复制到网站根目录下就行了:

这样做虽然确实是能达到效果,但是复制过来的文件,会包含版本控制的信息;README.md ,开源协议等 Markdown 文件也在,看着就很难受。(再加个 rm 命令删掉不就好了?)对了,这里执行 Linux 下的 cp 复制命令时,我遇到了有三个小坑

1.并没有足够的权限将文件复制到的 /www/wwwroot/ 目录下,这时就算在命令前加上 sudo 也不行,毕竟 Jenkins 又没有 root 权限。正确方法是将目标文件夹的权限设置成 777 就好了(默认是 755,没有写入的权限)。这在宝塔面板里很容易设置。

2.复制过去的不是文件,而是整个文件夹。这时在前面加上 -r 参数,源目录后面加上 . 就可以递归复制目录下的文件了。

3.遇到重名文件,需要用户手动输入 yes 才能替换。怎样实现强制替换呢?这里需要指出的是 Linux 中的 cp 命令,虽然你输入的是 cp,但 Linux 系统为了安全起见,会自动转换成 cp -i 执行,使得遇到重名文件时会向用户确认。这就 Linux 当中的别名 alias。(涨知识了)去掉别名的方法很简单,在命令开头加上反斜杠 \ 就行啦,有点编程语言中的转义符号的意味。

之后就可以开始再执行一次构建了:

(左边那几次构建失败的,就是我在摸索怎么解决上面那三个坑的过程)

        至此,我们的 Jenkins 自动部署 PHP 就算是搭建好了,之后可以在服务器设置个定时任务什么的,每天定时部署项目。

最后再来聊点题外话吧~ 我觉得 Jenkins 里面用天气图标来表示当前项目的构建情况挺有创意的——成功就是太阳,有几次失败就是乌云,失败了很多次就是雷阵雨。

并且在对于 bilibili 的技术栈有过了解后,我心里大概有了如果自己成了 CTO 后的想法:(开始瞎想了)全部人!只能用 Slack 办公聊天(对,我就是喜欢用 Slack),代码 push 到内网 GitLab,还可以给别人做 code review,不同项目的人有兴趣还可以 pull request。内网维基,内网论坛什么的都搞起来,管你用什么 discuz,有就行。代码跑单元测试,最后 Jenkins 定时部署上线。禁止像知乎一样直接在线上环境改代码,新功能灰度测试放在晚上8点后。服务器分布在全中国搞容灾备份,每一小时存一遍快照。(理想很棒,但没钱是硬伤)

对了,说实话, 第一次看到 Jenkins 的 Logo:

我脑海里第一想到的就是 PHP 中 composer 的那个 Logo:

这不就是 PowerPoint 2003 中剪贴画的画风吗?都是一样的丑,你们两个的 Logo 都可以当情头了。

美中不足的是,我发现我 VPS 上的 Jenkins 过了一会儿总是会莫名其妙地崩掉,然后又需要我手动重启:

[shell]# /etc/init.d/jenkins start[/shell]

可能是与某些软件有冲突吧?话说是不是用那个 Docker 虚拟化一下就好了?话说 Docker 又是什么鬼玩意?之前在 Twitter 上看到有人招 PHP 程序员说要会这个。有时间去了解下好了,我觉得他们的那个鲸鱼的 Logo 就很可爱啊。

(一群翻白眼的鲸鱼)