日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
解密SpringCloud微服務(wù)調(diào)用:如何輕松獲取請(qǐng)求目標(biāo)方的IP和端口

目的

Spring Cloud 線上微服務(wù)實(shí)例都是2個(gè)起步,如果出問(wèn)題后,在沒(méi)有ELK等日志分析平臺(tái),如何確定調(diào)用到了目標(biāo)服務(wù)的那個(gè)實(shí)例,以此來(lái)排查問(wèn)題

成都創(chuàng)新互聯(lián)公司專業(yè)為企業(yè)提供神池網(wǎng)站建設(shè)、神池做網(wǎng)站、神池網(wǎng)站設(shè)計(jì)、神池網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)與制作、神池企業(yè)網(wǎng)站模板建站服務(wù),十載神池做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。

圖片

效果

可以看到服務(wù)有幾個(gè)實(shí)例是上線,并且最終調(diào)用了那個(gè)實(shí)例

圖片

考慮到Spring Cloud在版本升級(jí)中使用了兩種負(fù)載均衡實(shí)現(xiàn),Robin和LoadBalancer,下面我們提供兩種實(shí)現(xiàn)方案

Robin實(shí)現(xiàn)方案

1. 技術(shù)棧

  • Spring Cloud: Hoxton.SR6
  • Spring Boot: 2.3.1.RELEASE
  • Spring-Cloud-Openfeign: 2.2.3.RELEASE

2. 繼承RoundRobinRule,并重寫(xiě)choose方法

/**
 * 因?yàn)檎{(diào)用目標(biāo)機(jī)器的時(shí)候,如果目標(biāo)機(jī)器本身假死或者調(diào)用目標(biāo)不通無(wú)法數(shù)據(jù)返回,那么feign無(wú)法打印目標(biāo)機(jī)器。這種場(chǎng)景下我們需要在調(diào)用失敗(目標(biāo)機(jī)器沒(méi)有返回)的時(shí)候也能把目標(biāo)機(jī)器的ip打印出來(lái),這種場(chǎng)景需要我們切入feign選擇機(jī)器的邏輯,注入我們自己的調(diào)度策略(默認(rèn)是roundrobin),在里面打印選擇的機(jī)器即可。
*/
@Slf4j
public class FeignRule extends RoundRobinRule {

    @Override
    public Server choose(Object key) {
        Server server = super.choose(key);
        if (Objects.isNull(server)) {
            log.info("server is null");
            return null;
        }
        log.info("feign rule ---> serverName:{}, choose key:{}, final server ip:{}", server.getMetaInfo().getAppName(), key, server.getHostPort());
        return server;
    }

    @Override
    public Server choose(ILoadBalancer lb, Object key) {
        Server chooseServer = super.choose(lb, key);

        List reachableServers = lb.getReachableServers();
        List allServers = lb.getAllServers();
        int upCount = reachableServers.size();
        int serverCount = allServers.size();
        log.info("serverName:{} upCount:{}, serverCount:{}", Objects.nonNull(chooseServer) ? chooseServer.getMetaInfo().getAppName() : "", upCount, serverCount);
        for (Server server : allServers) {
            if (server instanceof DiscoveryEnabledServer) {
                DiscoveryEnabledServer dServer = (DiscoveryEnabledServer) server;
                InstanceInfo instanceInfo = dServer.getInstanceInfo();
                if (instanceInfo != null) {
                    InstanceInfo.InstanceStatus status = instanceInfo.getStatus();
                    if (status != null) {
                        log.info("serverName:{} server:{}, status:{}", server.getMetaInfo().getAppName(), server.getHostPort(), status);
                    }
                }
            }
        }

        return chooseServer;
    }
}

3.修改RibbonClients配置

import org.springframework.cloud.netflix.ribbon.RibbonClients;
import org.springframework.context.annotation.Configuration;
/**
 * @description:feign 配置
 */
@Configuration
@RibbonClients(defaultConfiguration = {FeignRule.class})
public class FeignConfig {
}

LoadBalancer實(shí)現(xiàn)方案

1. 技術(shù)棧

  • Spring Cloud: 2021.0.4
  • Spring Boot: 2.7.17
  • Spring-Cloud-Openfeign: 3.1.4

2. 繼承ReactorServiceInstanceLoadBalancer,并實(shí)現(xiàn)相關(guān)方法

@Slf4j
public class CustomRoundRobinLoadBalancer implements ReactorServiceInstanceLoadBalancer {
    final AtomicInteger position;
    final String serviceId;
    ObjectProvider serviceInstanceListSupplierProvider;

    public CustomRoundRobinLoadBalancer(ObjectProvider serviceInstanceListSupplierProvider, String serviceId) {
        this(serviceInstanceListSupplierProvider, serviceId, (new Random()).nextInt(1000));
    }

    public CustomRoundRobinLoadBalancer(ObjectProvider serviceInstanceListSupplierProvider, String serviceId, int seedPosition) {
        this.serviceId = serviceId;
        this.serviceInstanceListSupplierProvider = serviceInstanceListSupplierProvider;
        this.position = new AtomicInteger(seedPosition);
    }

    public Mono> choose(Request request) {
        ServiceInstanceListSupplier supplier = this.serviceInstanceListSupplierProvider.getIfAvailable(NoopServiceInstanceListSupplier::new);
        return supplier.get(request).next().map((serviceInstances) -> {
            return this.processInstanceResponse(supplier, serviceInstances);
        });
    }

    private Response processInstanceResponse(ServiceInstanceListSupplier supplier, List serviceInstances) {
        Response serviceInstanceResponse = this.getInstanceResponse(serviceInstances);
        if (supplier instanceof SelectedInstanceCallback && serviceInstanceResponse.hasServer()) {
            ((SelectedInstanceCallback)supplier).selectedServiceInstance((ServiceInstance)serviceInstanceResponse.getServer());
        }

        return serviceInstanceResponse;
    }

    private Response getInstanceResponse(List instances) {
        if (instances.isEmpty()) {
            if (log.isWarnEnabled()) {
                log.warn("No servers available for service: " + this.serviceId);
            }

            return new EmptyResponse();
        } else {

            int pos = this.position.incrementAndGet() & Integer.MAX_VALUE;
            ServiceInstance instance = instances.get(pos % instances.size());
            log.info("serverName:{} upCount:{}",instance.getServiceId(),instances.size());
            log.info("feign rule ---> serverName:{}, final server ip:{}:{}", instance.getServiceId(), instance.getHost(),instance.getPort());
            return new DefaultResponse(instance);
        }
    }
}

3.修改LoadBalancerClients配置

@Configuration
@LoadBalancerClients(defaultConfiguration = CustomLoadBalancerConfiguration.class)
public class CustomLoadBalancerConfig {
}

@Configuration
class CustomLoadBalancerConfiguration {
    /**
     * 參考默認(rèn)實(shí)現(xiàn)
     * @see org.springframework.cloud.loadbalancer.annotation.LoadBalancerClientConfiguration#reactorServiceInstanceLoadBalancer
     * @return
     */
    @Bean
    public ReactorLoadBalancer reactorServiceInstanceLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory) {
        String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
        return new CustomRoundRobinLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
    }
}

以上兩部完成大功告成!

源碼下載:https://github.com/dongweizhao/spring-cloud-example/tree/SR6-OpenFeign https://github.com/dongweizhao/spring-cloud-example/tree/EurekaOpenFeign


新聞名稱:解密SpringCloud微服務(wù)調(diào)用:如何輕松獲取請(qǐng)求目標(biāo)方的IP和端口
地址分享:http://www.dlmjj.cn/article/cdjpeee.html