要了解配置管理通常有多么困难,我们只需要查看最简单的配置:一个标志,告诉我们的 Web 服务器是否正在维护。如果是这样,我们不应该对数据库发出请求,而应该向访问者返回一条简单的“抱歉,我们正在维护;请稍后重试”消息。如果网站未在维护中,则应发生所有正常的 Web 服务行为。
在典型情况下,更新单个标志会迫使我们将更新的配置文件推送到所有 Web 服务器,并且可能会迫使我们在所有服务器上重新加载配置,如果不是迫使我们重新启动应用程序服务器本身的话。
与其随着服务数量的增长而尝试编写和维护配置文件,不如将配置写入 Redis。通过将配置放入 Redis,并通过编写应用程序以从 Redis 获取配置信息,我们不再需要编写工具来推送配置信息并导致我们的服务器和服务重新加载该配置。
为了实现这个简单的行为,我们假设我们已经构建了一个中间件层或插件,就像我们在第 2 章中用于缓存的中间件层或插件一样,如果一个简单的 is_under_maintenance() 函数返回 True,它将返回我们的维护页面,否则,如果它返回 False,它将像往常一样处理请求。我们的实际函数将检查一个名为 is-under-maintenance 的键。如果该键有任何值存储在那里,我们将返回 True;否则,我们将返回 False。为了帮助最大限度地减少在高 Web 服务器负载下对 Redis 的负载(因为人们喜欢在获得维护页面时点击刷新),我们将每秒只更新一次信息。我们的函数可以在此列表中看到。
LAST_CHECKED = None IS_UNDER_MAINTENANCE = False def is_under_maintenance(conn):
global LAST_CHECKED, IS_UNDER_MAINTENANCE
将这两个变量设置为全局变量,以便我们稍后可以写入它们。
if LAST_CHECKED < time.time() - 1:
检查自上次检查以来是否至少经过了 1 秒。
LAST_CHECKED = time.time()
更新上次检查时间。
IS_UNDER_MAINTENANCE = bool(
conn.get('is-under-maintenance'))
找出系统是否正在维护中。
return IS_UNDER_MAINTENANCE
返回系统是否正在维护中。
通过将该函数插入到应用程序中的正确位置,我们可以在 1 秒内影响数千台 Web 服务器的行为。我们选择 1 秒是为了帮助减少对流量非常大的网站的 Redis 的负载,但是如果我们的需求需要更快的更新,我们可以减少或删除该函数的一部分。这似乎是一个玩具示例,但它演示了将配置信息保存在公共可访问位置的强大功能。但是,更复杂的配置选项呢?