使用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);
}
重启项目,测试代码,大功告成,打完收工!
评论区