如何在应用程序加载时加载@FeignClient
How to load @FeignClient on application load time
我正在尝试在我的多租户应用程序中实施假客户端概念。我有两个微服务。在其中一个微服务中,我编写了 API 来从数据库中获取数据。我需要在我的其他微服务中使用这些数据。为此,我使用了假装客户的概念。我在第二个微服务加载期间需要数据。但这并没有发生。我收到以下错误
2018-12-14 13:03:10.555 WARN 11268 --- [ restartedMain] c.n.c.sources.URLConfigurationSource : No URLs will be polled as dynamic configuration sources.
2018-12-14 13:03:20.468 WARN 11268 --- [ restartedMain] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'multiTenancyJpaConfiguration': Unsatisfied dependency expressed through field 'multiTenantConnectionProvider'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSourceBasedMultiTenantConnectionProviderImpl': Invocation of init method failed; nested exception is com.netflix.hystrix.exception.HystrixRuntimeException: MultiTenancyFeignClient#getDatabase(String) timed-out and no fallback available.
2018-12-14 13:03:21.233 DEBUG 11268 --- [ restartedMain] c.e.c.E.q.c.t.d.Project.projectRoles : Close successful.
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'multiTenancyJpaConfiguration': Unsatisfied dependency expressed through field 'multiTenantConnectionProvider'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSourceBasedMultiTenantConnectionProviderImpl': Invocation of init method failed; nested exception is com.netflix.hystrix.exception.HystrixRuntimeException: MultiTenancyFeignClient#getDatabase(String) timed-out and no fallback available.
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:372)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1173)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1067)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1081)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:856)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:737)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:370)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:314)
at com.testautomation.TestAutomationApp.main(TestAutomationApp.java:84)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSourceBasedMultiTenantConnectionProviderImpl': Invocation of init method failed; nested exception is com.netflix.hystrix.exception.HystrixRuntimeException: MultiTenancyFeignClient#getDatabase(String) timed-out and no fallback available.
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:137)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:409)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1620)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
... 31 common frames omitted
Caused by: com.netflix.hystrix.exception.HystrixRuntimeException: MultiTenancyFeignClient#getDatabase(String) timed-out and no fallback available.
at com.netflix.hystrix.AbstractCommand.call(AbstractCommand.java:805)
at com.netflix.hystrix.AbstractCommand.call(AbstractCommand.java:790)
at rx.internal.operators.OperatorOnErrorResumeNextViaFunction.onError(OperatorOnErrorResumeNextViaFunction.java:140)
at rx.internal.operators.OnSubscribeDoOnEach$DoOnEachSubscriber.onError(OnSubscribeDoOnEach.java:87)
at rx.internal.operators.OnSubscribeDoOnEach$DoOnEachSubscriber.onError(OnSubscribeDoOnEach.java:87)
at com.netflix.hystrix.AbstractCommand$DeprecatedOnFallbackHookApplication.onError(AbstractCommand.java:1451)
at com.netflix.hystrix.AbstractCommand$FallbackHookApplication.onError(AbstractCommand.java:1376)
at rx.internal.operators.OnSubscribeDoOnEach$DoOnEachSubscriber.onError(OnSubscribeDoOnEach.java:87)
at rx.observers.Subscribers.onError(Subscribers.java:230)
at rx.internal.operators.OnSubscribeThrow.call(OnSubscribeThrow.java:44)
at rx.internal.operators.OnSubscribeThrow.call(OnSubscribeThrow.java:28)
at rx.Observable.unsafeSubscribe(Observable.java:10211)
at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:51)
at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:35)
at rx.Observable.unsafeSubscribe(Observable.java:10211)
at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:41)
at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:30)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
at rx.Observable.unsafeSubscribe(Observable.java:10211)
at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:41)
at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:30)
at rx.Observable.unsafeSubscribe(Observable.java:10211)
at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:41)
at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:30)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
at rx.Observable.unsafeSubscribe(Observable.java:10211)
at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:41)
at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:30)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
at rx.Observable.unsafeSubscribe(Observable.java:10211)
at rx.internal.operators.OperatorOnErrorResumeNextViaFunction.onError(OperatorOnErrorResumeNextViaFunction.java:142)
at rx.internal.operators.OnSubscribeDoOnEach$DoOnEachSubscriber.onError(OnSubscribeDoOnEach.java:87)
at rx.internal.operators.OnSubscribeDoOnEach$DoOnEachSubscriber.onError(OnSubscribeDoOnEach.java:87)
at com.netflix.hystrix.AbstractCommand$HystrixObservableTimeoutOperator.run(AbstractCommand.java:1121)
at com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable.call(HystrixContextRunnable.java:41)
at com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable.call(HystrixContextRunnable.java:37)
at com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable.run(HystrixContextRunnable.java:57)
at com.netflix.hystrix.AbstractCommand$HystrixObservableTimeoutOperator.tick(AbstractCommand.java:1138)
at com.netflix.hystrix.util.HystrixTimer.run(HystrixTimer.java:99)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask.runAndReset(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access1(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.util.concurrent.TimeoutException: null
at com.netflix.hystrix.AbstractCommand.handleTimeoutViaFallback(AbstractCommand.java:980)
at com.netflix.hystrix.AbstractCommand.access0(AbstractCommand.java:59)
at com.netflix.hystrix.AbstractCommand.call(AbstractCommand.java:595)
at com.netflix.hystrix.AbstractCommand.call(AbstractCommand.java:587)
at rx.internal.operators.OperatorOnErrorResumeNextViaFunction.onError(OperatorOnErrorResumeNextViaFunction.java:140)
... 15 common frames omitted
这是我的DataSourceBasedMultiTenantConnectionProviderImpl.class,我在其中编写了假客户端逻辑
package com.testautomation.util;
import org.hibernate.engine.jdbc.connections.spi.AbstractDataSourceBasedMultiTenantConnectionProviderImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.stereotype.Component;
import com.testautomation.domain.MasterDatabase;
import com.testautomation.service.MultiTenancyFeignClient;
import com.testautomation.service.impl.ProjectServiceImpl;
import javax.annotation.PostConstruct;
import javax.sql.DataSource;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
@Component
public class DataSourceBasedMultiTenantConnectionProviderImpl extends AbstractDataSourceBasedMultiTenantConnectionProviderImpl {
private static final long serialVersionUID = 8168907057647334460L;
private static final String DEFAULT_TENANT_ID = "tenant_1";
private MultiTenancyFeignClient masterTenanacyFeign;
private final Logger log = LoggerFactory.getLogger(ProjectServiceImpl.class);
public DataSourceBasedMultiTenantConnectionProviderImpl( MultiTenancyFeignClient masterTenanacyFeign) {
this.masterTenanacyFeign = masterTenanacyFeign;
}
private Map<String, DataSource> map;
@PostConstruct
public void load() throws Exception {
//feign client logic
System.out.println("Feign client logic");
String name = "testautomation" ;
List<MasterDatabase> result = masterTenanacyFeign.getDatabase(name);
System.out.println("datafromUAA" +result);
//feign client logic ends
File[] files = Paths.get("tenants").toFile().listFiles();
Map<String, DataSource> datasources = new HashMap<>();
for(File propertyFile : files) {
Properties tenantProperties = new Properties();
DataSourceBuilder dataSourceBuilder = new DataSourceBuilder(this.getClass().getClassLoader());
try {
tenantProperties.load(new FileInputStream(propertyFile));
String tenantId = tenantProperties.getProperty("name");
dataSourceBuilder.driverClassName("com.mysql.jdbc.Driver")
.url(tenantProperties.getProperty("spring.datasource.url"))
.username(tenantProperties.getProperty("spring.datasource.username"))
.password(tenantProperties.getProperty("spring.datasource.password"));
datasources.put(tenantId, dataSourceBuilder.build());
} catch (IOException e) {
e.printStackTrace();
}
}
map = new HashMap<>();
map.put("tenat3",datasources.get("tenant3"));
map.put("tenant_1",datasources.get("tenant_1"));
map.put("tenant_2",datasources.get("tenant_2"));
}
@Override
protected DataSource selectAnyDataSource() {
return map.get(DEFAULT_TENANT_ID);
}
@Override
protected DataSource selectDataSource(String tenantIdentifier) {
return map.get(tenantIdentifier);
}
}
这是 MultiTenancyFeignClient.class 我要将第二个微服务连接到第一个
package com.testautomation.service;
import java.util.List;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.testautomation.domain.MasterDatabase;
import com.testautomation.util.DataSourceBasedMultiTenantConnectionProviderImpl;
@FeignClient(name="uaa" )
public interface MultiTenancyFeignClient {
@RequestMapping(method = RequestMethod.GET, value = "/api-public/database/{name}")
List<MasterDatabase> getDatabase(@PathVariable ("name") String name);
}
这里有趣的事实是,如果我在应用程序启动后在 API 调用中调用我的假客户端逻辑,那么它工作正常。但是在应用程序加载期间,这不会发生。
在 yml 页面中设置以下属性确实有效。
feign:
hystrix:
enabled: flase
我正在尝试在我的多租户应用程序中实施假客户端概念。我有两个微服务。在其中一个微服务中,我编写了 API 来从数据库中获取数据。我需要在我的其他微服务中使用这些数据。为此,我使用了假装客户的概念。我在第二个微服务加载期间需要数据。但这并没有发生。我收到以下错误
2018-12-14 13:03:10.555 WARN 11268 --- [ restartedMain] c.n.c.sources.URLConfigurationSource : No URLs will be polled as dynamic configuration sources.
2018-12-14 13:03:20.468 WARN 11268 --- [ restartedMain] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'multiTenancyJpaConfiguration': Unsatisfied dependency expressed through field 'multiTenantConnectionProvider'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSourceBasedMultiTenantConnectionProviderImpl': Invocation of init method failed; nested exception is com.netflix.hystrix.exception.HystrixRuntimeException: MultiTenancyFeignClient#getDatabase(String) timed-out and no fallback available.
2018-12-14 13:03:21.233 DEBUG 11268 --- [ restartedMain] c.e.c.E.q.c.t.d.Project.projectRoles : Close successful.
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'multiTenancyJpaConfiguration': Unsatisfied dependency expressed through field 'multiTenantConnectionProvider'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSourceBasedMultiTenantConnectionProviderImpl': Invocation of init method failed; nested exception is com.netflix.hystrix.exception.HystrixRuntimeException: MultiTenancyFeignClient#getDatabase(String) timed-out and no fallback available.
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:372)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1173)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1067)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1081)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:856)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:737)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:370)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:314)
at com.testautomation.TestAutomationApp.main(TestAutomationApp.java:84)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSourceBasedMultiTenantConnectionProviderImpl': Invocation of init method failed; nested exception is com.netflix.hystrix.exception.HystrixRuntimeException: MultiTenancyFeignClient#getDatabase(String) timed-out and no fallback available.
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:137)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:409)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1620)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
... 31 common frames omitted
Caused by: com.netflix.hystrix.exception.HystrixRuntimeException: MultiTenancyFeignClient#getDatabase(String) timed-out and no fallback available.
at com.netflix.hystrix.AbstractCommand.call(AbstractCommand.java:805)
at com.netflix.hystrix.AbstractCommand.call(AbstractCommand.java:790)
at rx.internal.operators.OperatorOnErrorResumeNextViaFunction.onError(OperatorOnErrorResumeNextViaFunction.java:140)
at rx.internal.operators.OnSubscribeDoOnEach$DoOnEachSubscriber.onError(OnSubscribeDoOnEach.java:87)
at rx.internal.operators.OnSubscribeDoOnEach$DoOnEachSubscriber.onError(OnSubscribeDoOnEach.java:87)
at com.netflix.hystrix.AbstractCommand$DeprecatedOnFallbackHookApplication.onError(AbstractCommand.java:1451)
at com.netflix.hystrix.AbstractCommand$FallbackHookApplication.onError(AbstractCommand.java:1376)
at rx.internal.operators.OnSubscribeDoOnEach$DoOnEachSubscriber.onError(OnSubscribeDoOnEach.java:87)
at rx.observers.Subscribers.onError(Subscribers.java:230)
at rx.internal.operators.OnSubscribeThrow.call(OnSubscribeThrow.java:44)
at rx.internal.operators.OnSubscribeThrow.call(OnSubscribeThrow.java:28)
at rx.Observable.unsafeSubscribe(Observable.java:10211)
at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:51)
at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:35)
at rx.Observable.unsafeSubscribe(Observable.java:10211)
at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:41)
at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:30)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
at rx.Observable.unsafeSubscribe(Observable.java:10211)
at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:41)
at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:30)
at rx.Observable.unsafeSubscribe(Observable.java:10211)
at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:41)
at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:30)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
at rx.Observable.unsafeSubscribe(Observable.java:10211)
at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:41)
at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:30)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
at rx.Observable.unsafeSubscribe(Observable.java:10211)
at rx.internal.operators.OperatorOnErrorResumeNextViaFunction.onError(OperatorOnErrorResumeNextViaFunction.java:142)
at rx.internal.operators.OnSubscribeDoOnEach$DoOnEachSubscriber.onError(OnSubscribeDoOnEach.java:87)
at rx.internal.operators.OnSubscribeDoOnEach$DoOnEachSubscriber.onError(OnSubscribeDoOnEach.java:87)
at com.netflix.hystrix.AbstractCommand$HystrixObservableTimeoutOperator.run(AbstractCommand.java:1121)
at com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable.call(HystrixContextRunnable.java:41)
at com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable.call(HystrixContextRunnable.java:37)
at com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable.run(HystrixContextRunnable.java:57)
at com.netflix.hystrix.AbstractCommand$HystrixObservableTimeoutOperator.tick(AbstractCommand.java:1138)
at com.netflix.hystrix.util.HystrixTimer.run(HystrixTimer.java:99)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask.runAndReset(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access1(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.util.concurrent.TimeoutException: null
at com.netflix.hystrix.AbstractCommand.handleTimeoutViaFallback(AbstractCommand.java:980)
at com.netflix.hystrix.AbstractCommand.access0(AbstractCommand.java:59)
at com.netflix.hystrix.AbstractCommand.call(AbstractCommand.java:595)
at com.netflix.hystrix.AbstractCommand.call(AbstractCommand.java:587)
at rx.internal.operators.OperatorOnErrorResumeNextViaFunction.onError(OperatorOnErrorResumeNextViaFunction.java:140)
... 15 common frames omitted
这是我的DataSourceBasedMultiTenantConnectionProviderImpl.class,我在其中编写了假客户端逻辑
package com.testautomation.util;
import org.hibernate.engine.jdbc.connections.spi.AbstractDataSourceBasedMultiTenantConnectionProviderImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.stereotype.Component;
import com.testautomation.domain.MasterDatabase;
import com.testautomation.service.MultiTenancyFeignClient;
import com.testautomation.service.impl.ProjectServiceImpl;
import javax.annotation.PostConstruct;
import javax.sql.DataSource;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
@Component
public class DataSourceBasedMultiTenantConnectionProviderImpl extends AbstractDataSourceBasedMultiTenantConnectionProviderImpl {
private static final long serialVersionUID = 8168907057647334460L;
private static final String DEFAULT_TENANT_ID = "tenant_1";
private MultiTenancyFeignClient masterTenanacyFeign;
private final Logger log = LoggerFactory.getLogger(ProjectServiceImpl.class);
public DataSourceBasedMultiTenantConnectionProviderImpl( MultiTenancyFeignClient masterTenanacyFeign) {
this.masterTenanacyFeign = masterTenanacyFeign;
}
private Map<String, DataSource> map;
@PostConstruct
public void load() throws Exception {
//feign client logic
System.out.println("Feign client logic");
String name = "testautomation" ;
List<MasterDatabase> result = masterTenanacyFeign.getDatabase(name);
System.out.println("datafromUAA" +result);
//feign client logic ends
File[] files = Paths.get("tenants").toFile().listFiles();
Map<String, DataSource> datasources = new HashMap<>();
for(File propertyFile : files) {
Properties tenantProperties = new Properties();
DataSourceBuilder dataSourceBuilder = new DataSourceBuilder(this.getClass().getClassLoader());
try {
tenantProperties.load(new FileInputStream(propertyFile));
String tenantId = tenantProperties.getProperty("name");
dataSourceBuilder.driverClassName("com.mysql.jdbc.Driver")
.url(tenantProperties.getProperty("spring.datasource.url"))
.username(tenantProperties.getProperty("spring.datasource.username"))
.password(tenantProperties.getProperty("spring.datasource.password"));
datasources.put(tenantId, dataSourceBuilder.build());
} catch (IOException e) {
e.printStackTrace();
}
}
map = new HashMap<>();
map.put("tenat3",datasources.get("tenant3"));
map.put("tenant_1",datasources.get("tenant_1"));
map.put("tenant_2",datasources.get("tenant_2"));
}
@Override
protected DataSource selectAnyDataSource() {
return map.get(DEFAULT_TENANT_ID);
}
@Override
protected DataSource selectDataSource(String tenantIdentifier) {
return map.get(tenantIdentifier);
}
}
这是 MultiTenancyFeignClient.class 我要将第二个微服务连接到第一个
package com.testautomation.service;
import java.util.List;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.testautomation.domain.MasterDatabase;
import com.testautomation.util.DataSourceBasedMultiTenantConnectionProviderImpl;
@FeignClient(name="uaa" )
public interface MultiTenancyFeignClient {
@RequestMapping(method = RequestMethod.GET, value = "/api-public/database/{name}")
List<MasterDatabase> getDatabase(@PathVariable ("name") String name);
}
这里有趣的事实是,如果我在应用程序启动后在 API 调用中调用我的假客户端逻辑,那么它工作正常。但是在应用程序加载期间,这不会发生。
在 yml 页面中设置以下属性确实有效。
feign:
hystrix:
enabled: flase