你的应用有开关吗?

开发 开发工具
你的应用有开关吗?能不能像灯的开关一样,在需要时打开,在不需要时关闭呢,像USB一样,即插即用呢?

「啪」天色暗下来时,房间里的灯打开了。

「啪」,睡觉时,房间里的灯又关上了。

有个开关可真方便。

[[220644]]

「你的应用有开关吗?为啥不给我加个开关?」,你的应用高叫着,并且在不经意的时候,给你来一个突然袭击。

你的应用有开关吗?能不能像灯的开关一样,在需要时打开,在不需要时关闭呢,像USB一样,即插即用呢?

答案当然是一定的,甚至在一些讲应用开发、设计原则的书籍中,都会将应用是否饮食「回退」功能做为很重要的一项。这里所谓的回退,和我们所说的开关类似,都需要在必要的时候将功能退回到升级前。

假设在周五下班前,你把这一周新开发的功能推到线上,开开心心的合上电脑,去健身了。

健身时脑海里还计划着周末要怎样happy,想着这些,笑意挂上了嘴角。这时,手机响了。挂断几次还坚持打进来。一听,是接到客户反馈,线上应用出了问题,新开发的功能影响了其他东西。这该如何时候,只能收拾东西,加班分析新的代码,找寻修复的方式,再加新代码上线,解决这个问题。

如果有「回退」功能,此时你就可以回退到你上线前,然后仔细检查,不需要急于一时。

如果有开关,你就可以将新的功能「关」掉,然后线上继续跑,不影响其他功能分毫,分分钟解决问题。

怎么关呢?

我们都知道 Java 的 class 在类加载器中加载一次,所以如果在线上出现问题需要处理时,就需要停服更新 class 来升级应用。虽然像我们之前提到的一些方法,也可以实现热加载,但生产环境里较少使用。

除了修改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 的使用类似这样:

  1. if (MyFeatures.HOT_NEW_FEATURE.isActive()) { 
  2.   // 新特性写这里 

你说这不就和我自己写if/else吗? 当然不是啦。这个实现将用户获取,开关状态获取都进行了抽象,可以进行自己的Configuration实现,

  1. public class MyTogglzConfiguration implements TogglzConfig { 
  2.  
  3.     public Class<? extends Feature> getFeatureClass() { 
  4.         return MyFeatures.class; 
  5.     } 
  6.  
  7.     public StateRepository getStateRepository() { 
  8.         return new FileBasedStateRepository(new File("/tmp/features.properties")); 
  9.     } 
  10.  
  11.     public UserProvider getUserProvider() { 
  12.         return new ServletUserProvider(); 
  13.     }} 

然后具体的开关的状态就在stateRepository中进行了定义,可以放在内存中,文件中,数据库中等等。此时可以再搭配上配置中心等,来实现应用功能的动态开关,不影响你周末时光。

【本文为51CTO专栏作者“侯树成”的原创稿件,转载请通过作者微信公众号『Tomcat那些事儿』获取授权】

戳这里,看该作者更多好文

责任编辑:赵宁宁 来源: 51CTO专栏
相关推荐

2012-11-22 11:35:15

打印机

2010-12-21 11:31:09

2023-11-28 08:38:25

API接口开关

2021-09-26 09:22:59

递归代码二叉树

2019-02-21 16:36:16

云服务器云计算服务器

2023-12-08 08:29:53

SpringAOP日志

2019-02-23 15:00:43

2018-07-12 15:01:07

2013-07-19 15:31:20

移动应用僵尸

2011-03-24 09:22:23

Solaris 11兼容性

2024-09-29 09:16:30

2020-12-21 14:42:42

大数据云计算人工智能

2021-03-14 15:05:22

大数据程序员游戏

2021-07-12 07:59:05

对象接口编程

2023-04-26 10:21:04

2018-08-29 18:53:44

2021-03-11 07:26:52

垃圾回收器单线程

2010-04-16 14:51:05

网络流量

2022-01-05 12:03:48

MySQL索引数据

2020-07-14 07:48:19

Java对象JVM
点赞
收藏

51CTO技术栈公众号