微信号:tomcat0000

介绍:由从事应用服务器核心研发的工程师维护.文章深入Tomcat源码,分析应用服务器的实现细节,工作原理.以及与之相关的技术,使用技巧,工作实战等.起于Tomcat,但不止于此.同时会分享JVM、并发等,内容多为原创...

你的应用有开关吗?

2018-02-24 07:28 侯树成


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

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


有个开关可真方便。


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


你的应用有开关吗?能不能像灯的开关一样,在需要时打开,在不需要时关闭呢,像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实现,


public class MyTogglzConfiguration implements TogglzConfig {

    public Class<? extends Feature> getFeatureClass() {
        return MyFeatures.class;
    }

    public StateRepository getStateRepository() {
        return new FileBasedStateRepository(new File("/tmp/features.properties"));
    }

    public UserProvider getUserProvider() {
        return new ServletUserProvider();
    }}


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


号外:最近新开了「知识星球」,在这里会分享一些平时工作生活中看到、想到和用到的内容,同时也和「小集体」的小伙伴们一起互相影响,不断的学习、输入,同时输出,共同进步。可以看前一篇内容了解:2018,厉兵秣马


相关阅读:

谁动了我的 class?

学习Java虚拟机也许这是最好的方法

Java七武器系列长生剑 -- Java虚拟机的显微镜 Serviceability Agent

类加载器与类的热替换(Hotswap)






☆★☆更多精彩内容☆★☆


一台机器上安装多个Tomcat 的原理(回复001)

监控Tomcat中的各种数据 (回复002)

启动Tomcat的安全机制(回复003)

乱码问题的原理及解决方式(回复007)

Tomcat 日志工作原理及配置(回复011)

web.xml 解析实现(回复 012)

线程池的原理( 回复 014)

Tomcat 的集群搭建原理与实现 (回复 015)

类加载器的原理 (回复 016)

类找不到等问题 (回复 017)

代码的热替换实现(回复 018)

Tomcat 进程自动退出问题 (回复 019)

为什么总是返回404? (回复 020)

...


PS: 对于一些 Tomcat常见问题,在公众号的【常见问题】菜单中,有需要的朋友欢迎关注查看。

觉得本文对你有帮助?请分享给更多人支持一下吧,谢谢

关注『 Tomcat那些事儿  』 ,发现更多精彩文章!了解各种常见问题背后的原理与答案。深入源码,分析细节,内容原创,欢迎关注。


 
Tomcat那些事儿 更多文章 2018,厉兵秣马 谁动了我的 class? 学习Java虚拟机也许这是最好的方法 没想到你是这样的 JDBC 如何检测 Tomcat 的状态是 UP 还是 DOWN ?
猜您喜欢 学员分享 | "最大的收获还是在于思维上的转变……" 参加 HKOSC 2016 见闻 别开发 app 了 达内送福利 | 与“粽”不同,这个端午应该这样过! PMI 2017在沪举行 阿里风林火山项目和PMO团队双双获奖