介绍
我希望能够有两个不同的弹簧配置文件,并根据配置文件更改为我们的假装构建者的硬编码地址。
目前有以下内容:
return builder.target(cls, "http://" + serviceName);
但我实际上想执行以下操作并覆盖地址:
return builder.target(cls, "http://our-server:8009/" + serviceName);
为什么
有时我们不想在我们的开发环境中运行所有的服务。此外,某些服务有时只能通过 zuul 网关获得。
所以我们在不同的情况和条件下运行相同的代码。
技术细节
我们有以下代码用于构建我们的 Feign 客户端。
我们过去一直在使用@FeignClient注解,但最近我们决定开始手动构建我们的 feignClients。
下面的例子:
@FeignClient(name = "ab-document-store", configuration = MultiPartSupportConfiguration.class, fallback = DocumentStoreFallback.class)
我们使用以下命令调用 feignRegistrar 类:
return registerFeignClient(DocumentStoreClient.class, true);
@RequiredArgsConstructor
//@Component
@Slf4j
public class FeignRegistrar {
@Autowired
private Decoder decoder;
@Autowired
private Encoder encoder;
@Autowired
private Client client;
@Autowired
private Contract feignContract;
@Autowired
private ObjectFactory<HttpMessageConverters> messageConverters;
@Autowired
private List<RequestInterceptor> interceptors;
public <T> T register(Class<T> cls, String serviceName, boolean isDocumentStore) {
if(isDocumentStore){
encoder = new MultipartFormEncoder(new SpringEncoder(messageConverters));
}
//Client trustSSLSockets = new Client.Default(getSSLSocketFactory(), new NoopHostnameVerifier());
Feign.Builder builder = Feign.builder()
.client(client)
.encoder(encoder)
.decoder(decoder)
.contract(feignContract)
.logger(new Slf4Logger())
.logLevel(Logger.Level.HEADERS);
builder.requestInterceptor(new RequestInterceptor() {
@Override
public void apply(RequestTemplate template) {
template.header("X-Service-Name", serviceName);
}
});
for(RequestInterceptor interceptor : interceptors) {
builder.requestInterceptor(interceptor);
}
log.debug("Registering {} - as feign proxy ", serviceName);
return builder.target(cls, "http://" + serviceName);
}
public static class Slf4Logger extends Logger {
@Override
protected void log(String configKey, String format, Object... args) {
log.info("{} - {}", configKey, args);
}
}
}
Spring Cloud 属性覆盖
我们也一直在使用属性文件,例如application-ENV.property带有以下条目的条目:
ab-document-store.ribbon.NIWSServerListClassName:com.netflix.loadbalancer.ConfigurationBasedServerList
ab-document-store.ribbon.listOfServers: localhost:8025
不幸的是,listOfServers这对我们来说还不够。我们也希望能够分配目录/路径。就像是:
ab-document-store.ribbon.listOfServers: localhost:8025/ab-document-store
其他解决方法
我曾考虑在所有请求中潜入标头,例如X-SERVICE-NAME使用假装拦截器。然后我们可以将所有服务指向一个地址(例如 localhost:9001),并将这些请求转发/代理到 localhost:9001/X-SERVICE-NAME。
但是,我更喜欢更简单的解决方案,例如:
ab-document-store.ribbon.listOfServers: localhost:8025/ab-document-store
但这不起作用:(