「啪」天色暗下来时,房间里的灯打开了。
「啪」,睡觉时,房间里的灯又关上了。
有个开关可真方便。
「你的应用有开关吗?为啥不给我加个开关?」,你的应用高叫着,并且在不经意的时候,给你来一个突然袭击。
你的应用有开关吗?能不能像灯的开关一样,在需要时打开,在不需要时关闭呢,像USB一样,即插即用呢?
答案当然是一定的,甚至在一些讲应用开发、设计原则的书籍中,都会将应用是否饮食「回退」功能做为很重要的一项。这里所谓的回退,和我们所说的开关类似,都需要在必要的时候将功能退回到升级前。
假设在周五下班前,你把这一周新开发的功能推到线上,开开心心的合上电脑,去健身了。
健身时脑海里还计划着周末要怎样happy,想着这些,笑意挂上了嘴角。这时,手机响了。挂断几次还坚持打进来。一听,是接到客户反馈,线上应用出了问题,新开发的功能影响了其他东西。这该如何时候,只能收拾东西,加班分析新的代码,找寻修复的方式,再加新代码上线,解决这个问题。
如果有「回退」功能,此时你就可以回退到你上线前,然后仔细检查,不需要急于一时。
如果有开关,你就可以将新的功能「关」掉,然后线上继续跑,不影响其他功能分毫,分分钟解决问题。
怎么关呢?
我们都知道 Java 的 class 在类加载器中加载一次,所以如果在线上出现问题需要处理时,就需要停服更新 class 来升级应用。虽然像我们之前提到的一些方法,也可以实现热加载(类加载器与类的热替换(Hotswap)),但生产环境里较少使用。
除了修改class文件外,我们还可以在代码里编写各种 If/else来进行开关判断,这个时候如果需要关闭功能是,停服更新的不再是class,而是配置信息。
我们在应用的页面里大概都写过类似符合某种条件展示xxx内容之类的判断,例如JSP、FreeMarker 之类的在通过一些条件标签来进行页面的渲染进行控制。
在前后端分离,API开发的时候,如何进行这些返回结果的控制呢? 这不简单嘛, if / else 一把梭。
但有些时候,比如需要进行A/B Test, 需要根据Alpha、Beta 阶段进行用户控制,甚至是线上产生了问题,需要把新上的一个feature停掉... 等等这一系列
问题,如果硬编码到系统里,每次规则发生变更时,都需要修改代码,部署上线,不够灵活。
同时,对于A/B Test 这种想要快速实验的场景,也不够及时。
为了就对类似上述的场景, Matrin Flower 提出了一个 「Feature Toggle」的概念,对,就是那个提出DI 概念的哥们。(不要吐槽老M 的概念为啥这么多:))。
The basic idea is to have a configuration file that defines a bunch of toggles for various features you have pending. The running application then uses these toggles in order to decide whether or not to show the new feature.
这里的Toggle就是个开关,针对feature 的开关,决定在什么时候开启什么feature。
针对 feature,除了可以像上面解决线上临时问题时进行开关外,也可以进行访问权限控制,对于特定群组的用户提供某些功能,同时也可以用于实现快速的 A/B Test 的目的,来验证产品的猜想。
关于 feature toggle,各种语言有不同的实现,具体请参见这里:
http://featureflags.io/resources/
在Java中,较常用的是 Togglz。
Togglz 的使用类似这样:
if(MyFeatures.HOT_NEW_FEATURE.isActive()){// 新特性写这里
}
你说这不就和我自己写if/else吗? 当然不是啦。这个实现将用户获取,开关状态获取都进行了抽象,可以进行自己的Configuration实现,
publicclassMyTogglzConfigurationimplementsTogglzConfig{publicClass
然后具体的开关的状态就在stateRepository中进行了定义,可以放在内存中,文件中,数据库中等等。此时可以再搭配上配置中心等,来实现应用功能的动态开关,不影响你周末时光。:)
领取专属 10元无门槛券
私享最新 技术干货