motan笔记-服务治理和高可用
Cluster
Cluster is a service broker,Cluster 是服务的经纪人,motan的服务治理和高可用都是通过它来实现的。
@Spi(scope = Scope.PROTOTYPE)
public interface Cluster<T> extends Caller<T> {
@Override
void init();
void setUrl(URL url);
void setLoadBalance(LoadBalance<T> loadBalance);
void setHaStrategy(HaStrategy<T> haStrategy);
void onRefresh(List<Referer<T>> referers);
List<Referer<T>> getReferers();
LoadBalance<T> getLoadBalance();
}
负载均衡策略
通过负载均衡策略,来选择服务的引用实例。
@Spi(scope = Scope.PROTOTYPE)
public interface LoadBalance<T> {
void onRefresh(List<Referer<T>> referers);
Referer<T> select(Request request);
void selectToHolder(Request request, List<Referer<T>> refersHolder);
void setWeightString(String weightString);
}
支持多种负载均衡策略:
- ActiveWeight , 低并发优化 负载均衡器
- Random, 随机负载均衡器
- ConfigurableWeight ,权重可配置的负载均衡器
- ConsistentHash ,一致性哈希负载均衡器
- LocalFirst ,本地服务优先
- RoundRobin ,轮询
高可用策略
支持两种容错策略:Failfast(快速失败) 和 Failover(故障转移,故障切换),实现故障节点自动摘除,自动探测恢复,有效进行服务故障隔离,远离服务卡死及雪崩。
···
@Spi(scope = Scope.PROTOTYPE)
public interface HaStrategy
void setUrl(URL url);
Response call(Request request, LoadBalance<T> loadBalance);
}
···
Failfast
@SpiMeta(name = "failfast")
public class FailfastHaStrategy<T> extends AbstractHaStrategy<T> {
@Override
public Response call(Request request, LoadBalance<T> loadBalance) {
Referer<T> refer = loadBalance.select(request);
return refer.call(request);
}
}
Failover
@SpiMeta(name = "failover")
public class FailoverHaStrategy<T> extends AbstractHaStrategy<T> {
protected ThreadLocal<List<Referer<T>>> referersHolder = new ThreadLocal<List<Referer<T>>>() {
@Override
protected java.util.List<com.weibo.api.motan.rpc.Referer<T>> initialValue() {
return new ArrayList<Referer<T>>();
}
};
@Override
public Response call(Request request, LoadBalance<T> loadBalance) {
List<Referer<T>> referers = selectReferers(request, loadBalance);
if (referers.isEmpty()) {
throw new MotanServiceException(String.format("FailoverHaStrategy No referers for request:%s, loadbalance:%s", request,
loadBalance));
}
URL refUrl = referers.get(0).getUrl();
// 先使用method的配置
int tryCount =
refUrl.getMethodParameter(request.getMethodName(), request.getParamtersDesc(), URLParamType.retries.getName(),
URLParamType.retries.getIntValue());
// 如果有问题,则设置为不重试
if (tryCount < 0) {
tryCount = 0;
}
for (int i = 0; i <= tryCount; i++) {
Referer<T> refer = referers.get(i % referers.size());
try {
request.setRetries(i);
return refer.call(request);
} catch (RuntimeException e) {
// 对于业务异常,直接抛出
if (ExceptionUtil.isBizException(e)) {
throw e;
} else if (i >= tryCount) {
throw e;
}
LoggerUtil.warn(String.format("FailoverHaStrategy Call false for request:%s error=%s", request, e.getMessage()));
}
}
throw new MotanFrameworkException("FailoverHaStrategy.call should not come here!");
}
protected List<Referer<T>> selectReferers(Request request, LoadBalance<T> loadBalance) {
List<Referer<T>> referers = referersHolder.get();
referers.clear();
loadBalance.selectToHolder(request, referers);
return referers;
}
}

浙公网安备 33010602011771号