带春天的标志
最后修改:2021年1月20日
1.概述
在本文中,我们将简要定义特征标志,并提出一种自由的方法来实现在Spring启动应用程序中的方法。然后,我们将挖掘更加复杂的迭代,利用不同的Spring启动功能。
我们将讨论可能需要功能标记并讨论可能的解决方案的各种场景。金宝搏官网188be我们将使用比特币矿区示例应用程序执行此操作。
2.特色标志
特性标志——有时称为特性切换——是一种机制,允许我们启用或禁用我们的应用程序的特定功能,而不必修改代码或重新部署我们的应用程序。
根据给定功能标志所需的动态,我们可能需要全局配置它们,每个应用程序实例或更高的粒度 - 或许每个用户或请求。
与软件工程中的许多情况一样,尝试使用最直接的方法非常重要,以便在手中解决问题而不会增加不必要的复杂性。
功能标志是一个强有力的工具,如果使用得当,可以为我们的系统带来可靠性和稳定性。然而,当它们被误用或维护不足时,它们很快就会成为复杂性和令人头痛的根源。
有很多场景,功能标志可能会派上用场:
基于中继的开发和非动力功能
在基于中继的发展中,特别是当我们想频繁地继续整合时,我们可能会发现自己没有准备好释放某个功能。功能标志可以派上用方便,使我们能够继续发布,而无需进行更改,直到完全就会提供。
特定环境配置
我们可能会发现自己需要某些功能来重置我们的DB以进行E2E测试环境。
或者,我们可能需要为从生产环境中使用的非生产环境使用不同的安全配置。
因此,我们可以利用功能标志来切换正确的环境中的正确设置。
A / B测试
为同一个问题发布多个解决方案并测量其影响是我们可以使用特性标志实现的一种引人注目的技术。
金丝雀释放
部署新功能时,我们可能会决定逐步地进行,从一小组用户开始,并在验证其行为的正确性时扩展其采用。功能标志允许我们实现这一目标。
在下面的部分中,我们将尝试提供一种实用的方法来处理上述场景。
让我们将不同的策略分解为功能标记,以最简单的情况开头然后移动到更精细和更复杂的设置。
3.应用程序级别功能标志
如果我们需要解决前两种用例中的任何一个,应用程序级别标志是一种让事情工作的简单方法。
一个简单的功能标志通常涉及基于该属性的值的属性和某些配置。
3.1。使用春季配置文件的功能标志
在春天我们可以利用配置文件。概要文件使我们能够有选择地配置某些bean,这很方便。通过一些围绕它们的构造,我们可以快速地为应用程序级特性标志创建一个简单而优雅的解决方案。
让我们假装我们建立一个比特币采矿系统。我们的软件已经在生产中,我们的任务是创建实验性改进的采矿算法。
在我们的javaconfig我们可以配置我们的组件:
@Configuration public class ProfiledMiningConfig {@Bean @Profile("!experimental-miner") public BitcoinMiner defaultMiner(){返回新的DefaultBitcoinMiner();} @Bean @Profile(" experimentalMiner ") public BitcoinMiner experimentalMiner(){返回新的ExperimentalBitcoinMiner();}}
然后,使用以前的配置,我们只是需要将我们的个人资料包含要选择新功能。有大量配置我们的应用程序一般来说特别是启用配置文件。同样,有测试实用程序让我们的生活更轻松。
只要我们的系统足够简单,然后,我们可以创建一个基于环境的配置,以确定应用哪些特性标志,忽略哪些特性标志。
让我们想象一下,我们基于卡而不是桌子的新UI以及以前的实验矿工。
我们希望在验收环境中启用两个功能(UAT)。我们可以在我们的文件组中创建以下个人资料组application.yml文件:
春季:档案:组:UAT:实验 - 矿工,UI卡
使用以前的属性到位,我们只需要在UAT环境中启用UAT配置文件以获取所需的一组功能。当然,我们也可以添加一个application-uat.yml.我们项目中的文件包括我们的环境设置的其他属性。
在我们的情况下,我们想要的uat个人资料也包括在内experimental-miner和ui卡。
注意:如果我们在2.4.0之前使用Spring Boot版本,我们将使用spring.profiles.include属性,以配置其他概要文件。相比spring.profiles.active,前者使我们能够以添加方式包括概况。
3.2。使用自定义属性的功能标志
配置文件是一个完成工作的伟大而简单的方法。但是,我们可能需要概要文件以获得其他目的。或许,我们可能希望构建一个更具结构化的功能标志基础架构。
对于这些方案,自定义属性可能是一个理想的选项。
让我们重写我们以前的示例利用@conditionalonproperty.和我们的命名空间:
@configuration公共类custompropsminingconfig {@bean @conditionalonproperty(name =“featurem.miner.experation”,matchifmissing = true)public bitceminer defaultminer(){return new defaultbitcoinminer();@bean @conditionalonproperty(name =“features.miner.experish”)Public BitceInminer Experical Miner(){返回新的实验性BitCoinminer();}}
前面的示例构建在Spring Boot的条件配置之上,并根据属性是否设置为,配置一个组件或另一个组件真正的或错误的(或完全省略)。
结果与3.1中的结果非常相似,但现在我们有我们的命名空间。拥有我们的命名空间允许我们创建有意义的yaml /属性文件:
#[...]某些春天配置功能:矿工:实验:真UI:卡:True#[...]其他功能标志
此外,此新设置允许我们前缀我们的功能标志 - 在我们的情况下,使用特征字首。
这看起来可能是一个小细节,但随着应用程序的增长和复杂性的增加,这个简单的迭代将帮助我们保持对特性标志的控制。
让我们来讨论一下这种方金宝搏官网188be法的其他好处。
3.3。使用 @ConfigurationProperties.
一旦我们获得了前缀的属性,我们就可以创建一个Pojo装饰着@configurationProperties在我们的代码中获取程序化句柄。
在我们正在进行的例子之后:
@component @configurationProperties(prefix =“功能”)公共类ConfigProperties {Private MinerProperties Miner;私人Uiproperties UI;//标准的getters和setters public static class minerproperties {私人布尔实验;//标准getters和setter}公共静态类Uiproperties {私有布尔卡;//标准getters和setter}}
通过将功能标志的状态放入凝聚力单元中,我们开辟了新的可能性,允许我们轻松地将该信息公开到我们的系统的其他部分,例如UI或下游系统。
3.4。揭露功能配置
我们的比特币挖掘系统获得了UI升级,尚未完全准备好了。因此,我们决定将其旗帜旗帜。我们可能有一个单页应用的应用,使用React,Angular或Vue。
无论技术如何,我们需要知道启用了哪些功能,以便相应地呈现页面。
让我们创建一个简单的端点来服务我们的配置,以便我们的UI可以在需要时查询后端:
@RestController公共类功能ConfigController {Private ConfigProperties属性;//构造函数@getmapping(“/ feature-flags”)public configproperties getProperties(){return属性;}}
服务此信息可能有更复杂的方式,例如创建自定义执行器端点。但是为了本指南,控制器端点感觉就像足够好的解决方案。
3.5。保持营地清洁
虽然这听起来很明显,但是一旦我们认真地执行了我们的特性标志,那么当它们不再需要时,我们也需要保持纪律并删除它们。
第一个用例的特性标志——基于主干的开发和非普通特性——通常是短暂的。这意味着我们需要确保我们的configproperties,我们的Java配置和我们的yaml.文件保持干净,最新。
4.更多的粒度特征标志
有时我们发现自己更复杂的情景。对于A / B测试或金丝雀释放,我们以前的方法是不够的。
为了获得更细粒度的特性标志,我们可能需要创建我们的解决方案。这可能涉及定制我们的用户实体,以包含特定于特性的信息,或者可能扩展我们的web框架。
然而,使用功能标志的用户可能不是对每个人的吸引人的想法,还有其他解决方案。
作为替代方案,我们可以利用一些内置工具如togglz.。该工具增加了一些复杂性,但提供了一个很好的开箱解决方案提供与Spring Boot的一流集成。
togglz支持不同激活策略:
- 用户名:与特定用户相关联的标志
- 渐进式推出:为用户基础的百分比启用的标志。这对于Canary发行版很有用,例如,当我们想要验证特性的行为时
- 发布日期:我们可以在某个日期和时间安排要启用的标志。这可能对产品发布,协调释放或优惠和折扣有用
- 客户端IP:基于客户IP的标记功能。当将特定配置应用于特定客户时,这些可能会派上派上派上而分,因为它们具有静态IPS
- 服务器IP:在这种情况下,服务器的IP用于确定是否应启用功能。这对金丝雀释放可能也很有用,这与逐渐不同的方法比逐渐推翻 - 当我们想要评估我们的实例中的性能影响时
- scriptengine:我们可以基于的功能标志启用任意脚本。这可以说是最灵活的选择
- 系统属性:我们可以设置某些系统属性以确定要素标志的状态。这与我们最直接的方法取得的成就非常相似
5.总结
在本文中,我们有机会谈谈功能标志。金宝搏官网188be此外,我们讨论了Spring如何帮助我们在不添加新图书馆的情况下实现一些功能。
我们首先定义这种模式如何帮助我们有一些常见用例。
接下来,我们使用春季和春季启动外开箱工具建立了一些简单的解决方案。通过,我们提出了一个简单而强大的功能标记构造。
下面,我们比较了几种替代方案。从更简单、更不灵活的解决方案过渡到更复杂、但更复杂的模式。
最后,我们简要介绍了一些建立更强大的解决方案的指导方针。当我们需要更高程度的粒度时,这很有用。