首先讲一下开关的由来,例如东京在6月18日做店庆促销活动,在交易下单环节,可能需要调用A、B、C三个接口来完成,但是其实A和B是必须的,C只是附加的功能(例如在下单的时候做一下推荐),可有可无,在平时系统没有压力,容量充足的情况下,调用下没问题,但是在类似店庆之类的大促环节,系统已经满负荷了,这时候其实完全可以不去调用C接口,怎么实现这个呢?改代码?no,no,no,这样太不敏捷,此时开关诞生了,开发人员只要简单执行一下命令或者点一下页面,就可以关掉对于C接口的调用,在大促过去之后,再把开关恢复回去即可。

    ​    ​问题一:在单个java系统中如何实现开关功能?

​    ​其实对于开关来说,对应Java中的类型,很好映射,就是一个boolean值,在需要做开关操作的地方,调用这个属性,判断状态,然后走相应的逻辑即可。这个类是一个单例,保证全局唯一(代码就不写了,单例模式一般是学习设计模式中最开始接触的呵呵)。

    ​    ​问题二:单个java系统中,如何实现开关值变更的操作呢?

​    ​在单机系统中,改变开关的状态很简单(留一个口子,外部可以改变属性的值,例如改为true或者false),这时候,可以是页面来维护开关,通过页面的点击类改变这个全局唯一的属性,从而实现开关动作的触发。

    ​    ​问题三:多个同构java系统,如何实现开关状态的同步呢?

​    ​通过一和二的介绍,在单机情况下,开关的变更可以了,但是在多个同构(这里的同构,值得是部署的同一套代码,逻辑完全相同,类似Master和Slaver的模式)系统中,如何保持一致呢?单例模式,开关属性是被加载到本地缓存,就是说java一直持有的对象,在FullGC的时候回收不走的那种。这个时候,如果要保持各个系统中开关属性状态的一致,就需要从第三方外部系统中加载这个数据。

​    ​什么系统能充当第三方外部系统呢?可以是一个数据库访问系统,我们暂且称之为MetaServer,开关的属性防止在DB中,然后MetaServer提供页面来修改数据,同时提供接口读取开关的数据,在应用启动的时候,通过MetaServer来读取数据,加载到本地缓存中。这时候就有个问题,就是我通过MetaServer的页面改变了值,各个应用如何知道我改变了属性呢?这个时候就需要通过一些办法(办法很多,可以是消息系统,可以是zookeeper,可以是页面触发)来清理一下开关属性的缓存,让缓存重新加载一下,从而实现最新的状态获取。

​    ​总体思路就是:metaServer维护开关数据--应用读取DB中的数据到本地缓存--DB中数据变更--触发开关属性缓存重新加载。

​    ​这个是不是有点复杂,有没有更加简单的办法?当然有了,之前淘宝开源了一个系统diamond(持久化配置管理系统),其实可以理解为“配置信息的伪推送服务”,例如我变更了一个开关的属性,不再需要做清理缓存的事情,diamond帮你做掉了(原理很简单,例如系统A订阅了在diamond中的开关信息,这时候A会启动一个线程,每隔一段时间来轮循diamond的服务端,看看开关属性的数据有没有变更,如果有变更,在diamond服务端来加载最新的数据)。

​    ​总体思路是:在diamond中维护配置信息--系统订阅开关属性--系统轮循配置是否有变更,有变更直接就变掉了。

    ​    ​问题四:开关设计的几个坑

​    ​有时候,我们为了方便,没有借助问题三种的MetaServer或者diamond的方式,就是留了一个HTTP的接口来触发修改开关(多台机器的话,可以写批量脚本),这时候其实需要我们在apache或者nginx中,把这个URL的访问禁止掉,防止恶意用户在外部拼凑链接来进行开关的变动,这时候只能在服务器上通过linux的curl来触发操作了。

​    ​还有一个,就是如果通过HTTP的形式来修改开关的属性,有个是需要注意的,就是开关的执行要幂等操作,这样方便操作,避免出现集群中数据不一致的状态(就是执行开,开关就是开,不能第一次执行是开,第二次执行是关)。

    ​    ​问题五:开关组合情况下怎么搞?

​    ​上面的几种情况,仅仅是执行单个开关,应该比较简单。但是我同时又A、B、C三个开关,在不同的业务场景下,可能需要关闭A和B开关,在另外一个场景下,可能需要关闭A和C开关,这时候认为操作有可能会有遗漏或者疏忽,怎么搞呢?在单独属性开关的基础上做封装,例如A和B上面增加一层属性,暂且叫“AB”,修改AB的值,对应的系统修改A和B的值,这样就避免人肉记住一些组合。

    ​    ​问题六:如何实现自动升降级?

​    ​上面的情况,都是在提起可以预知的情况下,我们做一些人为的操作,这个能不能自动化?当然可以,就是这一小节讨论的自动升降级。

​    ​举例子,现在东京和作的外部物流公司有多家,会调用它们的系统或者物流节点的状态,这个时候,物流公司系统是不稳定的,如果挂了或者响应时间慢了,对于自身的系统会影响比较大,比较理想的办法是,在物流公司系统出现问题的时候,这块逻辑自动降级处理,然后等物流公司系统好了之后,再把这部分逻辑自动升级,整个过程没有人为参与,自动保持系统稳定性。这里说一下总体思路:

​    ​第一步:搞一个计数器,记录接口,暂定A的调用成功次数、失败次数以及响应时间;

​    ​第二步:将这些信息放入队列中,同时设置阀值(例如RT超过5秒就降级,1秒就升级)以及阀值触发改动的开关;

​    ​第三部:异步启动一个线程,扫描队列,达到我们的条件,就触发做变更(有个问题,就是加入业务降级了,这时候就没有调用量,也就没有了自动升级的条件了,怎么搞呢?这时候业务降级,并不是完全100%的停掉,可以预留一部分流量继续调用A,把A调用的信息放入队列中,根据这些信息,就能实现升级了);

    ​    ​总结:

​    ​上面这些是在陆续的系统维护中尝试或者看到的处理办法,通过开关的方式,实现系统的升降级,从而更好的保护系统。

关于java分布式系统开关功能设计(服务升降级)的更多相关文章

  1. java分布式系统开关功能设计(服务升降级)

     ​问题一:在单个java系统中如何实现开关功能? ​    ​其实对于开关来说,对应Java中的类型,很好映射,就是一个boolean值,在需要做开关操作的地方,调用这个属性,判断状态,然后走相应的 ...

  2. 170227、java分布式系统开关功能设计(服务升降级)

    首先讲一下开关的由来,例如东京在6月18日做店庆促销活动,在交易下单环节,可能需要调用A.B.C三个接口来完成,但是其实A和B是必须的,C只是附加的功能(例如在下单的时候做一下推荐),可有可无,在平时 ...

  3. 树莓派上Java程序作为linux服务并开机自动启动

    http://www.iigrowing.cn/shu_mei_pai_shang_java_cheng_xu_zuo_wei_linux_fu_wu_bing_kai_ji_zi_dong_qi_d ...

  4. 基于JAVA WEB技术旅游服务网站系统设计与实现网上程序代写

    基于JAVA WEB技术旅游服务网站系统设计与实现网上程序代写 专业程序代写服务(QQ:928900200) 随着社会的进步.服务行业的服务水平不断发展与提高,宾馆.酒店.旅游等服务行业的信息量和工作 ...

  5. 多模块分布式系统的简单服务访问 - OSGI原形(.NET)

    多模块分布式系统的简单服务访问 - OSGI原形(.NET) 先描述一下本篇描述的适用场景(3台server, 各个模块分布在各个Server上,分布式模块互相依赖.交互的场景): 多个OSIG引擎交 ...

  6. 分布式系统的消息&服务模式简单总结

    分布式系统的消息&服务模式简单总结 在一个分布式系统中,有各种消息的处理,有各种服务模式,有同步异步,有高并发问题甚至应对高并发问题的Actor编程模型,本文尝试对这些问题做一个简单思考和总结 ...

  7. java开源即时通讯软件服务端openfire源码构建

    java开源即时通讯软件服务端openfire源码构建 本文使用最新的openfire主干代码为例,讲解了如何搭建一个openfire开源开发环境,正在实现自己写java聊天软件: 编译环境搭建 调试 ...

  8. java http post/get 服务端和客户端实现json传输

    注:本文来源于<java http post/get 服务端和客户端实现json传输> 最近需要写http post接口所以学习下. 总的还是不难直接上源码! PostHttpClient ...

  9. flagr a/b 测试特性开关&&微服务动态配置工具

    flagr a/b 测试特性开关&&微服务动态配置工具 简单运行 docker docker run -it -p 18000:18000 checkr/flagr 运行界面 说明 参 ...

随机推荐

  1. HPU组队赛J:Ball King(线段树)

    时间限制 1 Second  内存限制 512 Mb 题目描述 HPU601球王争霸赛即将举行,ACMER纷纷参加. 现在有n个人报名参赛,每个人都有一个实力值 ai,实力值较大者获胜. 为保证比赛公 ...

  2. 一个简易的drf的项目例子

    luffy_city 1.项目介绍 今日内容:(路飞项目) contentType组件: 路飞学成项目,有课程,学位课(不同的课程字段不一样),价格策略 问题, 如何设计表结构,来表示这种规则 为专题 ...

  3. jdk1.8新特性----接口可以有方法体,子类可以不用重写接口中已实现的方法

    是的这就是jdk1.8新特性之一,刚刚看到. 注意:编译环境是1.8. public interface Tree { public static String name="树名" ...

  4. 新一代构建工具gradle学习

    简介:Gradle的出现,是技术发展的必然,站在了Ant.maven等构建工具的肩膀上,使用了一种强大且具有表达性的基于Groovy的领域特定语言(DSL),使其拥有易用且灵活的方式去实现定制逻辑.方 ...

  5. day 06Hadoop

    更换虚拟机以后操作的步奏1.到每一台机器上修改ip地址 ,然后修改hosts1.5 给每台机器配置免密码登录 2.修改hadoop 的配置文件,发送到每台机器上3.启动dfs start-dfs.sh ...

  6. itcast-spring-三大框架整合

    三大框架架构(整合原理) struts整合到spring   hibernate整合到spring 导包 eclipse需要导入   myeclipse不用 单独配置spring容器 单独配置stru ...

  7. 如何将centos7作为DNS服务器

    简单来说,dns服务器是起到缓存的作用.比如说我们第一次dig www.baidu.com的时候,dns服务器因为没有解析过百度地址,所以它需要向上一级dns服务器进行查询,然后查询结果会缓存在这台d ...

  8. Pushpin How it works

    转自:https://pushpin.org/docs/about/#how-it-works Introduction Pushpin is a reverse proxy server that ...

  9. madlib centos yum 包安装

    使用centos 测试安装madlib sql 机器学习类库 安装步骤 添加pg 10 repo yum install https://download.postgresql.org/pub/rep ...

  10. 初等数论及其应用 (第6版) (Kenneth H.Rosen 著)

    第1章 整数 1.1 数和序列 1.2 和与积 1.3 数学归纳法 1.4 斐波那契数 1.5 整除性 第2章 整数的表示法和运算 2.1 整数的表示法 2.2 整数的计算机运算 2.3 整数运算的复 ...