连续交付–第6部分–向后和向前兼容性
上一章节: 启动–自检
向后兼容性是开发人员必须采用和实践的一个非常重要的思维定势。
大多数生产系统不只包含一台服务器,而是包含一组服务器。 部署新代码段时,您不会立即将其部署到所有服务器上,因为持续部署策略的一部分是在部署过程中停机时间为零。 如果您一次部署到所有服务器,并且部署需要重新启动服务器,则所有服务器将同时重新启动,从而导致停机。
现在考虑以下情形。 您编写了一个新的代码,该代码需要DTO中的一个新字段并将其写入数据库。 现在,如果逐步部署服务器,则将有一段时间,有些服务器将具有使用新字段的新代码,而有些则不会。 具有新代码的服务器将在DTO中发送新字段,而尚未部署的服务器将没有新字段并且无法识别它。
一个更重要的概念是避免部署依赖性,在这种情况下,必须在部署另一组服务之前先部署一组服务。 如果我们使用前面的示例,这甚至会使情况变得更糟。 假设您使用SOA架构,现在有发送新字段的客户端和没有发送新字段的客户端。 或者,您部署现在发送新字段的客户端,但尚未部署可以读取它们并可能损坏的服务器。 您可能会说,好吧,我不会这样做,我将首先部署可以读取新字段的服务器,然后再部署发送它的客户端。 但是,在连续部署中,您可以像部署新代码一样容易,也可以回滚代码。 因此,即使先部署服务器再部署客户端,现在也可以回滚服务器而无需回滚客户端,从而再次造成客户端将未知字段发送到服务器的情况。
因此,这是下一个非常重要的实践。 所有代码必须向后和向前兼容 。 那是什么意思呢? 在我们之前的示例中,这非常简单。 旧服务器必须忽略未知的字段和参数(这是前向兼容性),您的服务器可以抵抗API扩展。 现在,知道如何处理新字段的新服务器也必须处理不发送此新字段的旧客户端。 在我们的示例中,如果客户端尚未部署并且不发送新字段,它们可以简单地使用默认值(这是向后兼容)。
在大多数情况下,向后兼容更容易,因为它是需要处理旧客户端的新代码。 但是,向前兼容性有时会很棘手,因为您正在运行旧代码,现在需要处理一个新的用例,而该用例最初并不是在编写时就设计的。 如果您知道旧代码无法处理新数据,则解决此问题的一种简单方法是发布一个中间版本,该版本首先“教授”旧代码以优雅地处理以前不知道的新数据; 在确信它可以正常工作之后,您可以部署实际使用新数据的新代码。 现在,如果您需要回滚新代码,则您的中间版本可以处理由回滚代码编写的数据,并在不中断的情况下优雅地忽略它。
在Wix,我们遇到了一个极端情况,因为配置错误,我们将整个生产系统回滚了整整一个月。 修复它之后,我们意识到,即使我们的系统回退了整整一个月,由于一切都向后和向前兼容,并且服务器处理了由较新代码编写的新数据,因此一切都保持零停机。 您可以在此处阅读有关我们不断回滚的更多信息 。
翻译自: https://www.javacodegeeks.com/2013/05/continuous-delivery-part-6-backward-forward-compatibility.html