安全的代码部署

安全的代码部署

安全的代码部署

安全,优雅的线上代码部署。

非常非常重要却又极其容易被忽视的问题:原子发布


如果不能完全避免错误,那就努力把出错的概率降到最低。

`switch` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT '应用开关:1-开,0-关。应用升级、安装、维护时需要暂时关闭,使其不能访问,否则会出现意外(即使这样也还是不能完全避免极端时候的并发问题,不过还是将故障降到最低概率了)',来自家校 s_app表

安全的实现服务部署的思考

上面这个问题可引申到怎么实现安全,平滑的代码部署的问题上去了。

要想实现安全的代码迁移、热替换、部署,光从应用层,用文件锁,做开关的形式去做还是不行的,必须从内核的角度去做。

比如实现php服务的线上运行环境的代码部署,如果直接替换文件可能会出现不可预料的问题,以及错误,所以做一个开关,暂停网站,但是已有的代码还在内存中跑怎么办,那就做一个程序生命检测的机制,只要程序有活着的,那就锁文件,知道文件没锁了就说明整个系统停了,但是这样还不够,很难保证所有程序都遵循这个约定,活着时都去摸一摸这个问题。

那么就要使出最后的绝招了,从内核去控制程序的生命,首先使用传统的方式暂停所有程序,关闭队列服务,关闭常驻程序,关闭访问开关,此时也还不能够确定是不是都停止了,那我们就等(正常的服务正在运行的可能此时还在内存中运行着呢),只要常驻和队列服务关闭了,那么内核一会也会停止的,只要从php内核那里检测到彻底没有生命活动了,就表示当前没有任何活动程序了,那么此时就说明绝对安全了,此时就可以放心的开始部署工作了。

对于线上的服务部署,针对不同的平台。业界肯定早已经有成熟的技术方案了,以后有时间在研究。

如果直接采用替换文件的方式,那么是很危险的,可能会出现难以预料的错误,这在生产环境中是致命的,因为文件的替换可能不是原子性的同时都能够替换(这是由PHP的运行机制决定的),这样的话,如果旧文件引入新文件的,那么逻辑可能就会出现难以预料的问题。所以安全的替换必须是原子性的,即要么同时都替换,要么都不替换,不能出现交叉的情况。

这种部署方式需要停服,对于一个线上的使用量很大的生产系统来说,停服代价太大了。

应该使用平稳的部署方案,比如A服务是旧服务,最新的提交时B服务,那么开启一个B服务,让新的请求全部使用B服务,这样就平滑过渡过来了,对原有的A服务完全没有影响,两者可以同时运行。等A服务逐渐没有人访问时,再停止就可以。


热迁移

热迁移,可以想象的例子,蜂巢迁移,想把A蜂巢的蜜蜂迁移到B蜂巢,但是当前A蜂巢已经在使用中了,要使得迁移过程中不影响采蜜的蜜蜂只能这样,做个和A一样性质的蜂巢B,将B放在A旁边,关闭A的入口,只保留出口,这样蜜蜂会慢慢到B蜂巢中去,而此时A蜂巢中还有工作的蜜蜂,所以不能直接关闭,但是我们关闭入口只保留出口,这样A里面的蜜蜂会逐渐减少,一段时间后完全没有蜜蜂了,此时我们已经完成了热迁移了,蜜蜂都转移到B中了,现在可以放心的停用A了。

php + Laravel 实现部署自动化

Facebook 如何实现大规模快速发布?

Facebook 是如何做大规模代码部署的?

容器技术演化史

少年,是时候换种更优雅的方式部署你的php代码了 - 码王信息 - 博客园

一般如何将开发测试服务器上的代码部署到生产环境? - 知乎

利用WebHook实现PHP自动部署Git代码-萧晔离

git pull 能实现原子性替换吗?

Deployer 中文网 — PHP 代码部署工具

在 2016 年做 PHP 开发是一种什么样的体验?(一) - SegmentFault 思否

简单轻松部署你的项目 - Deployer - PHP 那些事 - SegmentFault 思否

使用php部署工具deployer实现自动部署 - 二次元の技术宅

如何正确发布PHP代码 - CSDN博客

一个正确实现的发布系统至少应该支持原子发布。如果说每一个版本都表示一个独立的状态的话,那么在发布期间,任何一次请求只能在单一状态下被执行。如此称之为支持原子发布;反之如果在发布期间,一次请求跨越不同的状态,那么就不能称之为原子发布。我们不妨举个例子来说明一下:假设一次请求需要 include 两个 PHP 文件,分别是 a.php 和 b.php,当 include a.php 完成后,发布代码,接着 include b.php,如果处理不当的话,那么就可能会导致旧版本的 a.php 和新版本的 b.php 同时存在于同一个请求之中,换句话说就是没有实现原子发布。(重要:非常非常重要却又极其容易被忽视的问题)

PHP执行系统外部命令函数:exec()、passthru()、system()、shell_exec() - gaohj - 博客园


从nginx看 线上环境的热部署和热更新替换

【开源组件】深入浅出Nginx

思考1:Nginx如何做到热部署?所谓热部署,就是配置文件nginx.conf修改后,不需要stop Nginx,不需要中断请求,就能让配置文件生效!(nginx -s reload 重新加载/nginx -t检查配置/nginx -s stop)通过上文我们已经知道worker进程负责处理具体的请求,那么如果想达到热部署的效果,可以想象:方案一:修改配置文件nginx.conf后,主进程master负责推送给worker进程更新配置信息,worker进程收到信息后,更新进程内部的线程信息。方案二:修改配置文件nginx.conf后,重新生成新的worker进程,当然会以新的配置进行处理,而且新的请求都必须交给新的worker进程,至于老worker进程,等把那些以前的请求处理完毕,kill掉即可。Nginx采用的就是方案二来达到热部署的!

代码部署规范 - 个人文章 - SegmentFault 思否


无服务器环境的安全部署

没有服务器的网站怎么安全部署呢(只能FTP上传文件的那种虚拟主机),网站需要增加一个站点开关,能够关闭入口(用户访问时就显示网站关闭升级中,多多返利程序升级时就是这样的,需要在后台关闭站点),并保证没有后台程序在运行时(开关关闭后等一会,检查没有队列等后台任务),再上传新文件覆盖就可以,等新文件上传完毕后在打开站点开关,这样才能确保安全。否则直接上传文件覆盖就不满足原子发布。


分享到:


相關文章: