Spring Cloud Ribbon 自定义服务发现

Spring Cloud Ribbon支持自定义的服务发现。服务发现时,可以实现自己的服务发现逻辑,可以配置一个或者多个服务的发现等等。

继承com.netflix.loadbalancer.AbstractServerList实现自定义的服务发现获取方式,可以参考ribbon默认的实现com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList

以一个需求为例,阐述如何实现和配置自定义的服务发现。

需求: 服务发现某个微服务,如果微服务不存在时,服务发现另一个微服务,伪装成未发现的微服务实例

简单理解就是:服务发现微服务A,如果找不到微服务A的实例,服务发现微服务B,把微服务B发现的结果作为微服务A的实例地址。

一个简单的实现方式: 复制com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList代码并重命名。

...
public class ZeusDiscoveryEnabledNIWSServerList extends AbstractServerList<DiscoveryEnabledServer> {
		...
    private List<DiscoveryEnabledServer> obtainServersViaDiscovery() {
        ...
        if (vipAddresses != null) {
            ...
        }
        // 实现自定义的服务发现逻辑
        if (!serverList.isEmpty()) {
            return serverList;
        }
        logger.warn("can not found service '{}' instance; Discover zeus instance as proxy service", vipAddresses);
        // 服务发现自定义的微服务,假装为当前的微服务实例
        client.getInstancesByVipAddress('custom-service-name', isSecure);
                .stream()
                .filter(i -> i.getStatus().equals(InstanceStatus.UP))
                .map(i -> createServer(i, isSecure, shouldUseIpAddr))
                .forEach(serverList::add);
        if (!serverList.isEmpty()) {
            logger.info("discover zeus instance count: {}", serverList.size());
        }
        return serverList;
    }
		...
}

增加配置类

...
import com.netflix.client.config.IClientConfig;
import com.netflix.discovery.EurekaClient;
import com.netflix.loadbalancer.ServerList;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.netflix.ribbon.RibbonClientName;
import org.springframework.cloud.netflix.ribbon.eureka.DomainExtractingServerList;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.inject.Provider;

/**
 * @author luobo.hwz on 2021/05/18 10:26 PM
 */
@Configuration
public class ZeusRibbonConfiguration {

  	//不需要修改
    @Value("${ribbon.eureka.approximateZoneFromHostname:false}")
    private boolean approximateZoneFromHostname = false;
		// 不需要修改
    @RibbonClientName
    private String serviceId = "client";

    // 创建上面自定义服务发现类的 Bean
    @Bean
    public ServerList<?> ribbonServerList(IClientConfig config, Provider<EurekaClient> eurekaClientProvider, ZeusDiscovery zeusDiscovery) {
        ZeusDiscoveryEnabledNIWSServerList discoveryServerList = new ZeusDiscoveryEnabledNIWSServerList(config,
                eurekaClientProvider, zeusDiscovery);
        return new DomainExtractingServerList(discoveryServerList, config, this.approximateZoneFromHostname);
    }
}

通过上述2步,自定义的服务发现就实现了。上面的配置类是关键,SpringCloud Ribbon会针对每个不同的微服务名,生成一个spring context,每个context都会生成上面配置类中的bean,通过这种方式,将自定义的服务发现规则,配置到了ribbon内。

ribbon会定时调用该方法,从注册中心获取微服务地址。


上述代码实现的功能

微服务A正常时的服务发现逻辑。

在这里插入图片描述

微服务A找不到时,服务发现微服务B,把结果作为微服务A的实例地址。

在这里插入图片描述

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值