【Pigeon源码阅读】客户端集群访问策略实现原理(九)

策略介绍和配置示例

在pigeon开源版本中,目前实现了4种集群策略:

  1. failfast:调用服务的一个节点失败后抛出异常返回,可以同时配置重试timeoutRetry和retries属性
  2. failover:调用服务的一个节点失败后会尝试调用另外的一个节点,可以同时配置重试timeoutRetry和retries属性
  3. failsafe:调用服务的一个节点失败后不会抛出异常,返回null,后续版本会考虑按配置默认值返回
  4. forking:同时调用服务的所有可用节点,返回调用最快的节点结果数据

在failfast和failover中,重试只限于超时异常,即RequestTimeoutException,其他异常在调用失败后仍会直接抛出。

配置示例如下:

<bean id="echoService" class="com.dianping.pigeon.remoting.invoker.config.spring.ReferenceBean" init-method="init">
	<property name="url" value="http://service.dianping.com/com.dianping.pigeon.demo.EchoService" />
	<property name="interfaceName" value="com.dianping.pigeon.demo.EchoService" />
	<property name="callType" value="sync" />
	<property name="timeout" value="1000" />
	<!-- 失败策略,快速失败failfast/失败转移failover/失败忽略failsafe/并发取最快返回forking,默认failfast -->
	<property name="cluster" value="failfast" />
	<!-- 是否超时重试,默认false -->
	<property name="timeoutRetry" value="false" />
	<!-- 重试次数,默认1 -->
	<property name="retries" value="1" />
</bean>

集群策略初始化和调用流程

集群策略的扩展定义在ClusterInvokeFilter中。在触发RPC请求前,先调用ClusterInvokeFilter来选择响应的集群策略完成RPC请求:

public class ClusterInvokeFilter extends InvocationInvokeFilter {
   

    public InvocationResponse invoke(ServiceInvocationHandler handler, InvokerContext invocationContext)
            throws Throwable {
   
        InvokerConfig<?> invokerConfig = invocationContext.getInvokerConfig();
        // 获取配置指定的集群模式
        Cluster cluster = ClusterFactory.selectCluster(invokerConfig.getCluster());
        if (cluster == null) {
   
            throw new IllegalArgumentException("Unsupported cluster type:" + cluster);
        }
        // 使用指定集群策略
        return cluster.invoke(handler, invocationContext);
    }

}

上面提到的4中集群策略的初始化和获取逻辑在ClusterFactory中完成:

public class ClusterFactory {
   

    private final static ConcurrentHashMap<String, Cluster> clusters = new ConcurrentHashMap<String, Cluster>();

    static {
   
        init();
    }

    // 初始化4种集群策略
    public static void init() {
   
        clusters.put(Constants.CLUSTER_FAILFAST, new FailfastCluster());
        clusters.put(Constants.CLUSTER_FAILOVER, new FailoverCluster());
        clusters.put(Constants.CLUSTER_FAILSAFE, new FailsafeCluster());
        clusters.put(Constants.CLUSTER_FORKING, new ForkingCluster());
    }

    // 用于注册自定义的集群策略
    public static void registerCluster(String clusterType, Cluster cluster) {
   
        clusters.put(clusterType, cluster);
    }

    // 根据集群策略类型字符串获取相应的集群策略实例
    public static Cluster selectCluster(String clusterType) {
   
        Cluster cluster = clusters.get(clusterType);
        if (cluster == null) {
   
            return clusters.get(Constants.CLUSTER_FAILFAST);
        }
        return cluster;
    }
}

每个集群策略的逻辑起点是invoke方法,内部的大致实现逻辑是先初始化一个远程请求供远程传输,而后根据负载均衡策略选取合适的连接,如果在选取可用连接时抛出ServiceUnavailableException会直接失败,否则再应用特定的集群策略来完成调用。
下面开始对各种策略的实现原理进行分析:

failfast 快速失败策略

如果使用failfase策略,会在调用失败后抛出异常,如果配置了timeoutRetry=true,会在因为捕获到RequestTimeoutException异常失败后,重试调用最多retries次,具体实现逻辑如下:

public class FailfastCluster implements Cluster {
   

    private ClientManager clientManager = ClientManager.getInstance();

    private static final Logger logger = LoggerLoader.getLogger(FailfastCluster.class);

    @Override
    public InvocationResponse invoke(ServiceInvocationHandler handler, InvokerContext invocationContext)
            throws Throwable {
   
        InvokerConfig<?> invokerConfig = invocationContext
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值