可配置

让我们写的 Web 应用可配置是一项很有挑战性,也很实用的技能。

起先,我们在本地开发的时候为本地创建了一套环境,也创建了本地的配置。接着我们需要将我们的包部署到测试环境,也生成了测试环境的相应配置。这其中如果有其他的环境,我们也需要创建相应的环境。最后,我们还需要为产品环境创建全新的配置。

下图是 Druapl 框架的部署流:

Drupal Deployment Flow

在不同的环境下,他们使用不同的 Content。这些 Content 的内容不仅仅可以是一些系统相当的配置,也可以是一些不同环境下的 UI 等等。而在这其中也会涉及到一些比较复杂的知识,下面只是做一些简单的介绍。

环境配置

最常见的例子就是我们需要在不同的环境有不同的配置。大原则就是我们不能直接使用产品的环境测试,因此我们就需要为不同的环境配置不同的数据库:

  • 开发环境。即开发者用于开发的环境,大部分的数据都是由我们自己注入的,在开发的过程中我们也会添加一些数据。
  • 集成测试环境/测试环境。和开发环境一样,这些数据也是由我们注入的,而这些数据主要用于测试目的。当应用出现Bug时,我们可能就需要添加新的测试及其测试数据。
  • 模拟环境(Staging)。在软件最终发布前,开发或者设计人员对软件进行调整后可以及时预览改变的测试环境,这个环境更接近于产品最终发布后的运行环境。因此,这个环境的数据一般来说就是产品环境的一些旧数据——可能是几个月前,几年前的数据。
  • 产品环境。即线上环境,都是真实的用户数据。

因此从理论上来说,我们就需要4~5个不同的数据库配置。而这些不同的数据库配置并不代表着他们使用的是相同的数据库。我们可以在本地环境使用 SQLite,而在我们的产品环境使用 MySQL。不过,最好的情况是我们应该使用同一个配置。这样当出现问题的时候,我们也很容易排查、

而除了数据库配置之外,我们还有一些其他配置。因此针对于不同的环境的配置最好独立地写在不同的文件里。并且这些配置最好可以以文件名来区分,如针对于开发环境,就是 dev.config.js,针对于测试环境就是 test.config.js

因此,为了实现不同的环境使用不同的配置,我们就需要有一个变更控制。如果我们只有相应的配置,而没有对应的运行机制那就有问题了。

运行机制

当我们的应用程序在服务器上运行得好好的时候,我们可能就不想因为修改配置而去重启机器,这时候我们就需要配置热加载。即我们修改配置后,不需要重启服务即可以使用新的配置。对应的还有一种,便是我们需要重启机器才能实现配置。

无论是哪种方式都需要修改配置来实现。而在我们使用的过程中热加载可能需要消耗一些系统资源,因为我们的系统需要不断地读取配置的状态并对其进行判断。并且如果我们的应用运行在多个机器上的时候,我们可能需要一个个的上支个性。而如果是冷启动的话,就可以考虑使用自动部署的方式来完成。

对应的,我们也需要在我们的代码中实现判断这些配置的逻辑。

功能开关

当我们上线了新功能之后,这时候如果有个 Bug,那么我们是下线么?要知道这个版本里面包含了很多的 Bug 修复。如果在设计这个新功能的时候,有一个可配置的 Toogle,那么我们就不需要下线了。只需要切换这个toggle,就可以解决问题了。

对于有多套环境的开发来说,如果我们针对不同的环境都有不同的配置,那么这个灵活的开发会帮助我们更好的开发。

Feature Toggle

它是一种允许控制线上功能开启或者关闭的方式,通常会采取配置文件的方式来控制。其过程如下图所示:

Feature Toggle

当我们需要 A 功能的时候,我们就只需要把 A 功能的开关打开。当我们需要 B 功能,而不需要 A 功能的时候,我们就可以把相应的功能关掉。像在 Java 里的 Spring 框架,就可以用 PropertyPlaceHolder 来做相似的事。使用 bean 文件创建一个 properties

  1. <util:properties id="myProps" location="WEB-INF/config/prop.properties"/>

然后注入这个值:

  1. @Value("#{myProps['message']}")

我们可以直接判断这个值是否是真,从而显示这个内容。

  1. <spring:eval expression="@myProps.message" var="messageToggle"/>
  2. <c:if test="${messageToggle eq true}">
  3. message
  4. </c:if>

这是一种很实用,而且很有趣的技术。

参考书籍:《配置管理最佳实践》