motan源码分析九:开关
在前面的文章中,我们已经发现了开关的踪影,例如cluster,motan支持多个cluster,当前的cluster因为开关关闭的情况下,就会使用下一个cluster。
1.开关相关的类和接口主要都在包com.weibo.api.motan.switcher下,类Switcher是具体的开关:
public class Switcher {
private boolean on = true;
private String name; // 开关名 public Switcher(String name, boolean on) {//创建开关
this.name = name;
this.on = on;
} public String getName() {//开关名称
return name;
} /**
* isOn: true,服务可用; isOn: false, 服务不可用
*
* @return
*/
public boolean isOn() {
return on;
} /**
* turn on switcher
*/
public void onSwitcher() {//操作开关为开的状态
this.on = true;
} /**
* turn off switcher
*/
public void offSwitcher() {
this.on = false;
}
}
2.开关的服务接口SwitcherService
public interface SwitcherService {
/**
* 获取接口降级开关
*
* @param name
* @return
*/
Switcher getSwitcher(String name); /**
* 获取所有接口降级开关
*
* @return
*/
List<Switcher> getAllSwitchers(); /**
* 初始化开关。
*
* @param switcherName
* @param initialValue
*/
void initSwitcher(String switcherName, boolean initialValue); /**
* 检查开关是否开启。
*
* @param switcherName
* @return true :设置来开关,并且开关值为true false:未设置开关或开关为false
*/
boolean isOpen(String switcherName); /**
* 检查开关是否开启,如果开关不存在则将开关置默认值,并返回。
*
* @param switcherName
* @param defaultValue
* @return 开关存在时返回开关值,开关不存在时设置开关为默认值,并返回默认值。
*/
boolean isOpen(String switcherName, boolean defaultValue); /**
* 设置开关状态。
*
* @param switcherName
* @param value
*/
void setValue(String switcherName, boolean value); /**
* register a listener for switcher value change, register a listener twice will only fire once
*
* @param switcherName
* @param listener
*/
void registerListener(String switcherName, SwitcherListener listener);
3.监听开关变化的接口SwitcherListener,主要是监听开关值的变化,由相关的监听者自行实现
4.SwitcherService的实现类LocalSwitcherService
public class LocalSwitcherService implements SwitcherService { private static ConcurrentMap<String, Switcher> switchers = new ConcurrentHashMap<String, Switcher>();//开关集合map private Map<String, List<SwitcherListener>> listenerMap = new ConcurrentHashMap();//监听器map @Override
public Switcher getSwitcher(String name) {
return switchers.get(name);
} @Override
public List<Switcher> getAllSwitchers() {
return new ArrayList<Switcher>(switchers.values());//获取当前开关服务下的所有开关
} private void putSwitcher(Switcher switcher) {
if (switcher == null) {
throw new MotanFrameworkException("LocalSwitcherService addSwitcher Error: switcher is null");
} switchers.put(switcher.getName(), switcher);
} @Override
public void initSwitcher(String switcherName, boolean initialValue) {
setValue(switcherName, initialValue);
} @Override
public boolean isOpen(String switcherName) {
Switcher switcher = switchers.get(switcherName);
return switcher != null && switcher.isOn();
} @Override
public boolean isOpen(String switcherName, boolean defaultValue) {
Switcher switcher = switchers.get(switcherName);
if (switcher == null) {
switchers.putIfAbsent(switcherName, new Switcher(switcherName, defaultValue));
switcher = switchers.get(switcherName);
}
return switcher.isOn();
} @Override
public void setValue(String switcherName, boolean value) {
putSwitcher(new Switcher(switcherName, value)); List<SwitcherListener> listeners = listenerMap.get(switcherName);
if(listeners != null) {
for (SwitcherListener listener : listeners) {
listener.onValueChanged(switcherName, value);
}
}
} @Override
public void registerListener(String switcherName, SwitcherListener listener) {//为某个开关添加监听器
synchronized (listenerMap) {
if (listenerMap.get(switcherName) == null) {
List listeners = Collections.synchronizedList(new ArrayList());
listenerMap.put(switcherName, listeners);
listeners.add(listener);
} else {
List listeners = listenerMap.get(switcherName);
if (!listeners.contains(listener)) {
listeners.add(listener);
}
}
}
} @Override
public void unRegisterListener(String switcherName, SwitcherListener listener) {//为某个开关移出监听器
synchronized (listenerMap) {
if (listener == null) {
listenerMap.remove(switcherName);
} else {
List<SwitcherListener> listeners = listenerMap.get(switcherName);
listeners.remove(listener);
}
}
} }
motan源码分析九:开关的更多相关文章
- motan源码分析六:客户端与服务器的通信层分析
本章将分析motan的序列化和底层通信相关部分的代码. 1.在上一章中,有一个getrefers的操作,来获取所有服务器的引用,每个服务器的引用都是由DefaultRpcReferer来创建的 pub ...
- ABP源码分析九:后台工作任务
文主要说明ABP中后台工作者模块(BackgroundWorker)的实现方式,和后台工作模块(BackgroundJob).ABP通过BackgroundWorkerManager来管理Backgr ...
- Heritrix源码分析(九) Heritrix的二次抓取以及如何让Heritrix抓取你不想抓取的URL
本博客属原创文章,欢迎转载!转载请务必注明出处:http://guoyunsky.iteye.com/blog/644396 本博客已迁移到本人独立博客: http://www.yun5u ...
- MyBatis框架的使用及源码分析(九) Executor
从<MyBatis框架的使用及源码分析(八) MapperMethod>文中我们知道执行Mapper的每一个接口方法,最后调用的是MapperMethod.execute方法.而当执行Ma ...
- jQuery源码分析(九) 异步队列模块 Deferred 详解
deferred对象就是jQuery的回调函数解决方案,它解决了如何处理耗时操作的问题,比如一些Ajax操作,动画操作等.(P.s:紧跟上一节:https://www.cnblogs.com/grea ...
- Vue.js 源码分析(九) 基础篇 生命周期详解
先来看看官网的介绍: 主要有八个生命周期,分别是: beforeCreate.created.beforeMount.mounted.beforeupdate.updated .beforeDes ...
- motan源码分析十:流量切换
motan提供了流量切换的功能,可以实现把一个group的流量切换到另一个group(一个或多个服务都可以).大家可以使用tomcat部署motan的管理工具,并设置几个组,例如可以参考demo代码: ...
- motan源码分析十一:部分特性
本章将描述motan部分的特性并对源码进行分析. 1.requestid的维护,使用了当前时间左移20位,再和一个自增变量组合 public class RequestIdGenerator { ); ...
- motan源码分析八:涉及到底层的客户端调用
之前我们分析了客户端调用服务端的源码,但是没有涉及到通讯层和序列化层,本文将之前讲过的内容做一次串联. 1.上层通过动态代理调用refer的call,每个refer又对应一个nettyclient,下 ...
随机推荐
- SGU 186.The Chain
看懂题就是水题... code #include <iostream> #include <algorithm> using namespace std; int a[110] ...
- Fedora 18 安装前指南
Secure Boot 与 Win 8 随着 Win8 的发布,先前关于 Secure Boot 和 UEFI 的诸多猜测也得到了证实,Fedora 18 也将如同当初计划的那样使用 shim + ...
- meta标签常用属性整理
在segmentfault看到这篇文章,觉得整理的很详细,所以转载过来和大家分享一下. 原文地址:http://segmentfault.com/blog/ciaocc/119000000240791 ...
- YII 验证邮箱和QQ号码
//验证邮箱非空,和邮箱格式 //验证邮箱非空,和邮箱格式 array("email","e ...
- Unable to find the ncurses libraries or the required header files解决
问题: 解决方法: sudo apt-get install ncurses-dev 参考:Unable to find the ncurses libraries or the required h ...
- 基于 Webpack & Vue & Vue-Router 的 SPA 初体验
基于 Webpack & Vue & Vue-Router 的 SPA 初体验 本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com ...
- 使用 Scut 搭建通服架构
整体通服的架构图如下: 整体思路: 尽量将公共的业务逻辑分拆到单个业务服务器: 公共业务RDB读写分离,提高IO并发量: 角色简要信息.角色战斗信息修改后将ID压入修改队列,简要信息每3分钟通知同步一 ...
- Android 5.0 技术新趋势
由于 Android 的版本分裂比较严重,整个新系统升级可能需要一两年甚至更长时间.所以目前使用 Android 5.0 的大部分是喜欢尝鲜的用户,同时现在市场上能够很好支持 Android 5.0 ...
- Maximum Submatrix 2
Codeforces Round #221 (Div. 1) B:http://codeforces.com/problemset/problem/375/B 题意:给你一个n*m的0,1矩阵,你可以 ...
- android 读取SD卡文件
SD卡作为手机的扩展存储设备,在手机中充当硬盘角色,可以让我们手机存放更多的数据以及多媒体等大体积文件.因此查看SD卡的内存就跟我们查看硬盘的剩余空间一样,是我们经常操作的一件事,那么在Android ...