「啪」天黑的时候,房间里的灯亮了。“啪”的一声,正在睡觉的时候,房间里的灯又被关掉了。有一个开关真是太方便了。“你的app有开关吗?要不你给我加个开关吧?”你的应用程序会大喊大叫,当你意想不到的时候,它会让你大吃一惊。您的应用程序有开关吗?能不能像电灯开关一样,需要时打开,不需要时关闭,像USB一样,即插即用?答案当然是肯定的,甚至在一些应用开发中,在设计原则的书籍中,是否使用节食“fallback”功能也被视为非常重要的一项。这里所谓的回滚类似于我们说的switch,必要的时候需要回滚升级前的功能。假设你在周五下班前将本周新开发的功能推送上线,兴高采烈地关上电脑,去健身房锻炼。一边锻炼一边脑子里还盘算着周末要怎么开心。想到这里,我的嘴角挂起一抹笑意。这时,电话响了。我挂了几次,坚持要打电话。一听就收到客户反馈说线上申请有问题,新开发的功能影响了其他东西。这个时候只能收拾东西,加班加点分析新代码,想办法修复,上线添加新代码来解决这个问题。如果有“回滚”功能,此时可以回滚到上线前,再仔细查看,不要急着一会。如果有开关,可以“关闭”新功能,然后继续在线运行,丝毫不影响其他功能,分分钟解决问题。如何关闭它?我们都知道Java类是在类加载器中加载一次的,所以如果线上出现问题需要处理,就需要停止服务更新类来升级应用。虽然像我们之前提到的一些方法也可以实现热加载,但是在生产环境中很少使用。除了修改class文件,我们还可以在代码中写各种If/else来做switch判断。这时如果需要关闭功能,停止更新的不再是类,而是配置信息。对于显示xxx内容的满足一定条件的应用页面,我们大概已经写好了判断。比如JSP、FreeMarker等都是通过一些条件标签来控制页面的渲染。前后端分离,开发API时,如何控制返回结果?这并不容易,if/else是一个穿梭。但有时候,比如需要进行A/BTest,需要根据Alpha和Beta阶段进行用户控制,甚至线上出现问题,需要停止一个新功能……等等对于这一系列的问题,如果Hard-coded到系统中,每次规则改变,都需要修改代码并部署到线上,不够灵活。同时对于A/BTest这种想要快速实验的场景,也不够及时。为了应对类似上述的场景,MatrinFlower提出了一个概念“FeatureToggle”,没错,就是那个提出DI概念的哥们。(不要抱怨为什么老M有那么多概念:))。基本思想是拥有一个配置文件,该文件为您待定的各种功能定义了一堆切换。正在运行的应用程序然后使用这些切换来决定是否显示新功能。这里的Toggle是一个功能开关,决定了什么时候开启哪个功能。Feature方面,除了如上解决临时上网问题时的开关机外,还可以控制访问权限,为特定的用户群体提供一定的功能,也可以用来达到快速A/BTest的目的。验证产品的猜想。关于featuretoggle,各种语言有不同的实现,具体可以参考这里:http://featureflags.io/resources/在Java中,更常用的是Togglz。Togglz的使用方法类似这样:if(MyFeatures.HOT_NEW_FEATURE.isActive()){//在这里写新特性}你不觉得跟我一起写if/else吗?当然不是。这个实现抽象了用户获取和开关状态获取,可以实现自己的Configuration,publicclassMyTogglzConfigurationimplementsTogglzConfig{publicClassgetFeatureClass(){returnMyFeatures.class;}publicStateRepositorygetStateRepository(){returnnewFileBasedStateRepository(newFile("/tmp/features.properties"));}publicUserProvidergetUserProvider(){returnnewServletUserProvider();}}然后具体开关的状态定义在stateRepository中,可以放在内存中,文件中,数据库中等等。这时候可以结合配置中心,实现应用功能的动态切换,不影响你的周末时间。【本文为专栏作家“侯书城”原创稿件,转载请通过作者微信公众号“Tomcat物语”获得授权】点此查看本作者更多好文
