侧边栏壁纸
  • 累计撰写 18 篇文章
  • 累计创建 13 个标签
  • 累计收到 4 条评论

目 录CONTENT

文章目录

[java]强迫症,日志出现的No servers available for service问题

骑摩托的程序员
2025-02-25 / 0 评论 / 1 点赞 / 255 阅读 / 569 字

使用feigncleint调用第三方,因为第三方需要header中携带token等其他信息,所以自定义了配置RequestInterceptor,配置到@FeignClient的configuration中
第三方api的feign接口,HellomotorApiService 代码如下


import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;


@FeignClient(value = "hellomotorApiService", configuration = HellomotorApiFeignUrlInterceptor.class)
public interface HellomotorApiService {

    /**
     * 保存业务
     *
     * @param hellomotorDTO
     * @return
     */
    @PostMapping("/hellomotor/save")
    ResultVO save(@RequestBody HellomotorDTO hellomotorDTO);
}

自定义RequestInterceptor



import com.alibaba.fastjson.JSON;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import javax.annotation.Resource;
import java.util.Map;
import java.util.Random;


@Slf4j
public class HellomotorApiFeignUrlInterceptor implements RequestInterceptor {

    @Value("${thirdApi.hellomotor.apiServer}")
    private String url;
    
    @Value("${thirdApi.hellomotor.token}")
    private String token;


    @SneakyThrows
    @Override
    public void apply(RequestTemplate template) {
        template.target(url);
        template.header(CommonConstants.AUTHORIZATION,token);
    }
}

日志出现,但是实际业务不受影响,强迫症,日志中容不得杂物,接下来就开动,消灭它!

[2025/02/25/ 16:31:14.684]2025-02-25 16:31:14.684 [TID: N/A] [pool-273] WARN  o.s.c.l.c.RoundRobinLoadBalancer - [getInstanceResponse,98] -  No servers available for service: api.hellomotor.cn

找到报错类的代码

package org.springframework.cloud.loadbalancer.core;


public class RoundRobinLoadBalancer implements ReactorServiceInstanceLoadBalancer {
    // 略

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

            return new EmptyResponse();
        } else if (instances.size() == 1) {
            return new DefaultResponse((ServiceInstance)instances.get(0));
        } else {
            int pos = this.position.incrementAndGet() & Integer.MAX_VALUE;
            ServiceInstance instance = (ServiceInstance)instances.get(pos % instances.size());
            return new DefaultResponse(instance);
        }
    }
}

其实从源码可以看到大概是在ribbo使用了负载均衡,跟踪源码也没有找到有配置可以关闭,但是既然修改代码,就来个一刀切,想办法让上面的HellomotorApiService不走ribbo,接下来有思路了。再自定义一个配置类让ribbon失效。


import feign.Client;
import org.springframework.context.annotation.Bean;

import java.util.List;

/**
 * 禁用 openfeign的负载均衡,避免RoundRobinLoadBalancer warn日志 No servers available for service
 * @see org.springframework.cloud.loadbalancer.core.RoundRobinLoadBalancer#getInstanceResponse(List)
 */
public class DisableLoadBalanceConfiguration {
    @Bean
    public Client feignClient() {
        return new Client.Default(null, null);
    }
}

接下来修改feignclient,使用咱们的新配置


import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;


@FeignClient(value = "hellomotorApiService", configuration = {HellomotorApiFeignUrlInterceptor.class, DisableLoadBalanceConfiguration.class})
public interface HellomotorApiService {

    /**
     * 保存业务
     *
     * @param hellomotorDTO
     * @return
     */
    @PostMapping("/hellomotor/save")
    ResultVO save(@RequestBody HellomotorDTO hellomotorDTO);
}

重启项目,测试代码,大功告成,打完收工!

1

评论区