四月初去曼谷看了一场Coldplay的演唱会《A Head Full Of Dreams》,于是,我的人生清单上,终于又完成了一项有生之年的任务:
有生之年去听一场Coldplay现场演唱会
喜欢上Coldplay有比较长一段时间了,总是喜欢在写代码的时候听他们的歌。去年底得知Coldplay的2017亚洲巡回演唱会开始出票,有台湾,日本,新加坡,菲律宾,韩国,曼谷等几处演出地点,随即在网上抢到了2017年曼谷场4.7号的票,再经过几个月的苦苦等待,终于达成了今年四月初的曼谷之行。
君看一叶舟,出没风波里
四月初去曼谷看了一场Coldplay的演唱会《A Head Full Of Dreams》,于是,我的人生清单上,终于又完成了一项有生之年的任务:
有生之年去听一场Coldplay现场演唱会
喜欢上Coldplay有比较长一段时间了,总是喜欢在写代码的时候听他们的歌。去年底得知Coldplay的2017亚洲巡回演唱会开始出票,有台湾,日本,新加坡,菲律宾,韩国,曼谷等几处演出地点,随即在网上抢到了2017年曼谷场4.7号的票,再经过几个月的苦苦等待,终于达成了今年四月初的曼谷之行。
回想起之前写过的《环保低功耗PT下载机打造攻略》和《环保低功耗PT下载机打造攻略–续篇》,这日子,一晃就快五年了,真是时光如梭啊……
在这近五年的时间里面,这台7*24小时开机的下载机,平时几乎就不用关机(除了小区偶尔的断电),伴随我混各大PT站,看了N部高清电影,追了N部美剧。但是,不幸的是,也就是在最近,这台下载机突然歇菜了,无法开机启动,究其原因,应该是主板寿终正寝了。好吧,用了这么多年,再细想一下当时组装花的成本,700来块,也算值了。
某日搜索文章,误入了别人家的blog,发现有个动态特效还挺不错,网页中会动态随机生成许多的点和线条,鼠标停留的地方会自动吸附这些线条,构成动态的几何图形。这么酷炫的效果怎能错过呢,打算“借鉴”到我的blog来。不过,翻遍了那位仁兄的blog,也没有看到相关的介绍,无奈只有分析一下他家的blog代码,原来是在网页中创建了一个巨大的canvas,设置透明度为50%,并且设置z-index为-1,让它位置在blog正文的下方。最后,通过一个叫mouse.js来实现动态的几何图形绘制和移动等效果。
于是乎,开始动手,三下五除二的把这个酷炫特技“移植”了过来……
自从上次《为你的Blog快速开启https支持》过后,blog试运行了一段时间,感觉还不错。随着国内SSL证书免费的推广,将来HTTPS必然是趋势。于是,打算把blog全面开启支持HTTPS。
迁移的步骤大致分为两部:
在Docker大行其道的今天,我们能够非常方便的使用容器打包我们的应用程序,并且将它在我们的服务器上部署并运行起来。但是,谈论到如何停掉运行中的docker容器并正确的终止其中的程序,这就成为一个非常值得讨论的话题了。
我的Blog是基于hexo生成的纯静态页面,host在nginx server上。其实通过普通的http访问方式已经足够了,开启https纯属折腾,请叫我不折腾不舒服斯基。
提到https,不得不提到免费的StarSSL证书,之前也申请了用过一段时间,感觉申请和续期证书的步骤都比较繁琐。后来随着证书过期,遂放弃之……
最近,在网上火透半边天的,非 Let’s Encrypt 的免费SSL证书莫属了。Let’s Encrypt 是一个将于2015年末推出的数字证书认证机构,将通过旨在消除当前手动创建和安装证书的复杂过程的自动化流程,为安全网站提供免费的SSL/TLS证书,同时,它还是免费、自动化、开放的证书签发服务。Let’s Encrypt的证书申请和续期都非常方便,默认的证书有效期是90天,通过cron的定时任务可以实现自动化的续期,所以,能通过自动的方式解决的问题都不是问题,这也是这次折腾起https支持的原因。此篇blog主要记录一下申请证书,配置证书到nginx,以及自动续期的实现步骤,供有兴趣的同学参考。
在发布和部署程序时,我们往往会有这样的需求:把版本号内置在程序里面,运行和部署程序的时候,可以用来知晓当前发布和部署的程序是什么版本。在一个编译好的可执行程序中,我们通常可以用类似: ./app_name -version 的方式,来获取当前程序的版本号。有了程序的版本号,更便于生产环境中,当程序出现问题时,工程师可以方便的根据版本号查找对应代码的改动,从而更容易定位到问题的所在。
这里主要介绍一下如何用Makefile以及Go本身所支持的编译特性,实现编译时自动生成版本号的功能。
持续集成(Continuous integration,简称CI)是一种软件开发实践,即团队开发成员经常集成他们的工作,在每一天的时间中,可能会发生一次或者多次集成。而每一次的集成都是通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早的在持续集成的阶段发现软件中的错误。 持续集成给团队所带来的好处,不言而喻:
- 减少并降低软件开发中的风险:在每天一次或者多次的集成中,通过相应的测试,能尽早的发现软件中的缺陷,尽量把软件中的错误暴露在开发阶段。最常见的场景,就是在多人的团队中,别人改动相关代码影响了你的代码逻辑,但他们不知道你写过这些单元测试或者没有跑单元测试的习惯,而持续集成能帮助解决这样的问题。
- 减少重复而又枯燥的单元测试过程:代码的改动不能避免的就是需要重复并且不断回归的运行之前写好的单元测试,而这一过程往往让工程师头疼,因为编译代码,准备测试数据,运行测试并查看结果,完全是重复的体力劳动。通过自动化的持续集成,不需要人工干预,完全可以把工程师从痛苦的循环中拯救出来,降低心智负担,让工程师能够把精力放在具有更高价值的事情上。
- 随时生成可运行和部署的软件:利用持续集成的特性,我们随时可以得到可以运行和部署的软件,对于客户来说,可以部署的软件产品是最实际的资产。而对于团队成员来说,也能让他们更有信心,因为他们清楚的知道每一次构建的结果,他们知道他们对软件的改动造成了哪些影响,结果怎么样。
上面提到了持续集成的各种好处,其实,持续集成的好处还不止如此。在GitLab中,不仅仅提供了代码托管的功能,而内置的持续集成功能,也是它功能上的一大亮点。从GitLab 8.0以上的版本,就提供了GitLab CI的功能。从官网的介绍可以了解到,GitLab CI拥有许多不错的特性,其中比较惹眼的几点,包括:
- 多平台支持:很巧的是,GitLab CI的Runner是由Go所开发的,这意味着在众多支持Go的平台上,都可以运行构建,甚至是树莓派上哦!
- 多语言支持:编译脚本是基于命令行驱动的,支持Java, PHP, Ruby, C及其他语言。
- 并行构建支持:GitLab CI会把多个同时出发的构建分派到不同机器上,以实现更快的并行执行。
- 自动伸缩:在保证最小化成本的基础上,自动启动与关闭虚拟机来进行构建。
关于GitLab CI的特性还有很多,可以查看官方文档了解更多特性。
GitLab CI的大致架构,如下图:
主要分为GitLab CI和GitLab Runner两个部分。GitLab CI部分,实际上已经集成到GitLab的Web中,主要负责提供友好的界面,供用户管理项目与构建。而GitLab Runner,主要负责生成构建与运行单元测试以及完成其他后续的持续集成任务。GitLab Runner主要通过API与Web端的GitLab CI进行交互。为了实现持续集成,我们可以选用的最小化配置是一个GitLab CI实例与一个GitLab Runner。当然,如果要提高构建的效率,我们可以在条件允许的情况下,部署任意多个GitLab Runner。
使用GitLab CI的功能,首先需要安装GitLab Runner。官方不推荐在同一台服务器上既运行GitLab,又跑GitLab Runner,因此,建议搭建单独的服务器用以运行GitLab Runner。这次实验中,用到了另外一台在Azure印尼机房的Linux服务器来安装GitLab Runner。在Linux的服务器上安装GitLab Runner,过程是比较简单的:
首先,需要添加GitLab的官方源到apt或者yum中:
1 | # For Debian/Ubuntu |
完成过后,就可以直接用apt或者yum来安装了:
1 | # For Debian/Ubuntu |
安装过后,就是注册的过程。注册的过程,实际上就是把某台服务器上的GitLab Runner跟GitLab的Web关联起来。在GitLab中,runner分为两种类型:Shared Runner(共享型)和Specific Runner(指定型)
- Shared Runner: 这类Runner是全局的,意思是为整个GitLab系统范围内的project提供构建服务,只有系统管理员能创建这类Runner。
- Specific Runner: 这类Runner是被指定为某个project提供构建服务的,这意味着系统中的任何用户,都可以建立自己的Runner,并把它指派给自己的某一个project。
在注册Runner的时候,需要填入Token,GitLab根据不同的Token确定这个Runner是被设置为Shared Runner还是Specific Runner。
在这里,我们注册一个共享类型的Runner。首先,需要在GitLab的管理后台,拿到Runner的Token,然后开始注册。注册过程如下:
1 | sudo gitlab-ci-multi-runner register |
在这里,为了自动化构建Go相关的项目,我们采用docker作为Runner运行的方式,并选择golang:1.6.2的docker镜像。注册成功之后,会提示可以启动Runner了。另外,顺便提一下更新Runner的方法:
1 | # For Debian/Ubuntu |
注册成功之后,我们便能在GitLab的管理后台中看到这个Shared Runner:
接下来的过程,就是在项目中创建.gitlab-ci.yml
配置文件,这个文件的意义在于告诉CI在构建的过程中应该做哪些事情,比如如何初始化环境,如何运行我们的test case。这个文件需要签入到我们工程的源代码中,并随项目的源文件一同提交。更加详细的配置项目,可以参考这里。
最后一步,就是给我们的Go工程编写test case并commit,之后push给GitLab,在检测到push的改动之后,会主动触发Shared Runner的运行和构建的动作。成功运行之后,我们能在Runner的运行情况中查看到结果:
对于成功编译和构建的项目,我们还可以为这个项目打上徽标。徽标能让团队的其他成员更加直观的了解最近的一次自动构建的结果。徽标的访问URL大致如下,根据自己域名和项目名称的不同,稍有变化: http://example.gitlab.com/namespace/project/badges/branch/build.svg
通过设置,我们已经开启了GitLab CI的自动构建之旅,并配置了一个简单的Shared Runner,一切看来都非常简单。在实际的需求中,我们甚至可以根据团队的需求,配置多个Shared Runner,并为特殊的project设置指定的Runner。这样能大大节省构建的时间,提升GitLab CI的效率。
GitLab是一个贴心的开发者伙伴,内置集成的GitLab CI提供更为贴心的持续集成功能,Runner中搭配Docker更有锦上添花的感觉,最关键的是我们能以正确的姿势去使用它们,从而为团队带来最大化的收益,提升软件质量和开发效率。
最近闲下心来,重新折腾了一下GitLab,相比起一两年前折腾起GitLab的痛苦经历,各种Ruby环境配置以及依赖包的问题,搞得人一心想放弃。如今,GitLab的安装包安装起来真是方便多了,使用官方提供的Omnibus package,可以在两三分钟的时间搭好GitLab,可以看到GitLab作为一个开源产品,是一直在不断进步的。