上一篇说到,代码上线到仅开放了ftp权限的虚拟主机,是如何的痛苦。

经过一段时间的忍耐之后,我忍无可忍,觉得应该靠技术手段来解决这个痛点。

然而思考得确实不太周到,用了一种现在看来很是“丑陋”的方案来解决。


然而不管怎么样,这也是我在尝试进行虚拟主机上线代码的第一个尝试,也反映了我针对这个问题的思考过程,所以不管怎么样,还是拿出来说说看。


思路


我的代码,都是通过SVN进行管理的(新浪sae,多个svn又不要钱喽)。而这些代码部署到虚拟主机上也很简单,因为一般不需要修改数据,只要原封不动地,把修改的文件都通过ftp上传到虚拟主机不就行了?

然而有一点,ftp如果是上传压缩包的话,就得到虚拟主机的web管理界面,找到对应路径才能解压,这个很麻烦,所以为了不麻烦,我还是单个文件来上传吧,直接远程覆盖掉。

可是又有一点,ftp上传的时候,如果是上传若干个小文件,速度会非常慢。


因此我确定下来的思路就是:


  1. 上传到svn的代码,通过某种方式再上传到ftp
  2. 直接上传文件,覆盖远程文件
  3. 上传的文件,尽可能地少

更具体一点


  1. 假设当前ftp上部署的代码,在SVN里面对应的版本是A,如果ftp上面没有部署过,那么A=0
  2. 我在线下修改了一些文件,当然也可能是新增或是删除,然后commit到了SVN服务器,现在的版本即为B。当然,我们上线的B版本,也可以并非是SVN中最新的版本。
  3. 在一个临时目录,checkout SVN,切换至版本B
  4. 通过svn -r A:B --summarize命令,获得A与B版本之间的代码差异
  5. 关注标记为A和M的文件,即新增和修改的
  6. 通过ftp-php这个库连接至ftp,进行修改
  7. 将所有A和M的文件夹,进行创建;将所有A和M的文件,进行上传
  8. 在本地(或者ftp上),创建一个文件,标记当前ftp上的部署版本号
  9. 如果不确定线上的版本号究竟是否正确也没关系,把A的值随便调小一点,影响就是可能会多上线一些和线上完全相同的文件罢了。

如果出问题了,要回滚,也是类似的,只不过,传进来的A和B参数就反过来,即比较的时候去看B:A,diff的情况。


这个方案看起来复杂了一些,但是确实比人肉要方便多了,我只需要在我的本地电脑上,运行一个命令,就能够快速地发布新代码到虚拟主机上。在一段时间内(可能有2、3个月左右吧),我一直是用这种方案来执行部署的。


但是这个方案什么缺点呢?


  1. 在上线的过程中,会有一段时间的不稳定态,因为有的文件变成新的了,有的还没有,这个不稳定态基本取决于网速和我修改的文件的数量。
  2. 记录ftp上代码版本的方案不太智能,虽然记录了,但是我还是习惯通过命令行参数来指定初始版本号
  3. 废文件我没有主动删除,一些文件在SVN上被标记为D,即A版本的时候还存在,B版本的时候就删除了,这个我没有删掉

当然,这其中最致命的问题就是1,不稳定态的存在,可能会导致一些问题。但是在这种思路设计下,这个问题基本上是无解的。

所以在之后,我很快地就淘汰了这个方案,更换成了一种更好的整体打包上线的实现。