在前面的文章中,我们已经发现了开关的踪影,例如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);
}
}
} }