java 程序报错回滚_Nginx

回滚是一种运维操作。通常发生在部署过程中发现问题,需要将目标环境恢复到部署前的状态。

在我看来,回滚有两种模式。其中一种是一步步执行反向操作,我称之为反向操作模式

基于反向操作的回滚模式

可能是由于过去手工运维的思维方式的惯性,我发现不少人只知道这一种模式。

比如使用手工部署Nginx的配置的操作如下:

  1. 1. SSH登录到目标服务器
  2. 2. 进入到存放Nginx的/etc/nginx/sites-enabled/目录
  3. 3. 编辑目标配置文件vim example.443.conf
  4. 4. 增加一个location配置
  5. 5. reload nginx使配置生效

在反向操作模式的回滚方案中,我们应该该如何回滚呢?回滚步骤1,2,3,5步骤与部署时一致。第4步,需要操作人员找到该配置,并删除。

这时,操作人员在操作时就可能会出错,而且出错了,你可能很难觉察到。因为他是手工操作的。

那么,有人就想,以上步骤能自动回滚就好了。

可是,该如何自动回滚呢?我们需要在部署时就设计好相应的自动化回滚脚本。当需要时,就触发其自动回滚。

然而这个回滚方案的方案是无法通用的,而且增加了运维成本。因为普通的运维人员对于一个Nginx的配置的变更,是非常不愿意写回滚的脚本的,而且,他本人也不一定能写出正确的、可靠的自动化回滚脚本。

那么,有人就会想了,我能否实现自动生成回滚代码的平台?

答案是可以的。你必须预先定义每一个步骤动作,比如在平台上将Nginx配置的修改作为一个动作定义。然后再定义它的反操作。

如果你是实现过类似平台项目,你会知道,这工作量是无穷无尽的。因为运维的操作是无穷无尽的。

你可以说平台可以提供自定义步骤动作的能力,那么你同样会遇到“他本人也不一定能写出正确的、可靠的自动化回滚脚本”的问题。而且,既然是平台了,定义操作的责任就应该是平台的责任。

所以,这是一个业界的难题。

在面试过程中,面试官通常假设我也会遇到同样的难题。然而,我根本不会遇到这个问题。

基于版本的回滚模式

我在解释这个模式时,很多人无法理解。

还是以部署Nginx配置为案例。但是通过Ansible来实现自动化部署。假设已经存在以下部署脚本:

- hosts: prod-nginx
  gather_facts: yes
  become: true
  vars_files: 
        # Nginx的配置
    - common_vars/nginx.yaml
  roles:
     # Nginx的部署逻辑,是声明式的、幂等的。
    - ansible-role-nginx

以上代码含义大概是:部署Nginx到prod-nginx主机列表上,并使用common_vars/nginx.yaml文件中的配置。

nginx.yaml的配置如下:

nginx_vhosts:
- listen: "80"
  server_name: "*.example.com"
  return: "301 https://{{example_domain}}$request_uri"
  filename: "example.80.conf"

我们对以上代码版本化(提前到Git中,并通过自动化构建),得到版本号:v1.0.1。

现在我们需要像“反向操作的回滚模式”中的案例那样修改线上的配置时,我们的做法是在nginx.yaml配置增加相应的配置,最终效果如下:

nginx_vhosts:
- listen: "80"
  server_name: "*.example.com"
  return: "301 https://{{example_domain}}$request_uri"
  filename: "example.80.conf"
- listen: "80"
  server_name: "*.abc.com"
  return: "301 https://{{example_domain}}$request_uri"
  filename: "abc.80.conf"

然后将代码push到代码库中,经过构建,我们得到版本号:v1.1.0。

部署时,使用v1.1.0的代码部署即可。

基于版本的回滚模式,回滚就很简单了。就是再执行一次v1.0.1版本(v1.1.0的上一个版本)的代码就可以了。

基于这种模式实现平台化,也非常简单。平台不需要关心具体运行的内容,就要选择上一个正确的版本的代码执行,就完成了回滚。不会遇到“基于反向操作的回滚模式”的实现过程遇到的各种问题。

也因为这种简单化,平台实现部署的标准化,也非常简单。

但是,基于版本的回滚模式是有前提的,你的部署代码的执行必须是幂等的、声明式的。幂等的,指的是同一份代码,运行多次,得到的结果是一样的。

小结

基于版本的回滚模式准确来说,也是部署。也就是它使用老版本部署代替传统的“回滚”。