[享学Netflix] 六十、Ribbon具有负载均衡能力的客户端:AbstractLoadBalancerAwareClient

当你想在你的代码中找到一个错误时,这很难;当你认为你的代码是不会有错误时,这就更难了。

–> 返回专栏总目录 <–
代码下载地址:https://github.com/f641385712/netflix-learning

前言

Ribbon不仅仅是负载均衡,负载均衡只是它的一个最核心、最出名的模块而已。在聊ribbon-core的时候我们知道它有个核心API是IClient,它表示发送一个请求得到一个响应,不规定发送方式、协议等。

因为Ribbon最核心的功能就是负载均衡,因此本文我们将了解到它这个具有负载均衡能力的客户端:AbstractLoadBalancerAwareClient,它所在的jar是:ribbon-loadbalancer


正文

AbstractLoadBalancerAwareClient

因为我们不太可能把Ribbon当其它用,而只用作负载均衡,因此你可以简单粗暴理解为:AbstractLoadBalancerAwareClient是所有的客户端实现的顶级父类,而实际上也确实如此。

需要注意的是,该抽象类不仅实现了接口IClient,并且还继承自LoadBalancerContext,所以它自己不仅仅是个Client,还拥有着负载均衡上下文。

该抽象类无任何成员属性,提供了一些方法:


初始化方法

它提供两个构造器用于初始化。

public abstract class AbstractLoadBalancerAwareClient<S extends ClientRequest, T extends IResponse> extends LoadBalancerContext implements IClient<S, T>, IClientConfigAware {

    public AbstractLoadBalancerAwareClient(ILoadBalancer lb) {
        super(lb);
    }
    public AbstractLoadBalancerAwareClient(ILoadBalancer lb, IClientConfig clientConfig) {
        super(lb, clientConfig);        
    }

}

作为一个和负载均衡相关的Client,负载均衡器ILoadBalancer是必不可少的喽。


buildLoadBalancerCommand() 构建负载均衡命令

Ribbon执行所有的请求都是基于命令模式去执行的,因此均需要包装成一个LoadBalancerCommand命令:

AbstractLoadBalancerAwareClient:

	// 抽象方法:提供一个RequestSpecificRetryHandler重试处理器
	// 因为重试方案父类定不了:有些是超时重试,有些是异常重试,因此交给子类去决定为好
	// 但请保证是RequestSpecificRetryHandler的子类:因为它已经帮你实现了写基本逻辑
	// 一般使用包装器模式,给RequestSpecificRetryHandler.fallback赋值了就好
	public abstract RequestSpecificRetryHandler getRequestSpecificRetryHandler(S request, IClientConfig requestConfig);
	// 毕竟LoadBalancerCommand的属性众多,默认只给其设置必要的属性,其它的交给调用者去个性化吧
	// 比如常用的:增加监听器来监听必要的执行过程
	protected void customizeLoadBalancerCommandBuilder(S request, IClientConfig config, LoadBalancerCommand.Builder<T> builder) {
		// 空实现,交给子类去定制
	}

	// request请求对象,提供URI(注意不是URL,因为不一定是网络请求)
    protected LoadBalancerCommand<T> buildLoadBalancerCommand(S request, IClientConfig config) {
    	// 得到重试处理器:因为重试处理器对LoadBalancerCommand的行为特别重要
		RequestSpecificRetryHandler handler = getRequestSpecificRetryHandler(request, config);
		LoadBalancerCommand.Builder<T> builder = LoadBalancerCommand.<T>builder()
				.withLoadBalancerContext(this)
				.withRetryHandler(handler)
				.withLoadBalancerURI(request.getUri());
		customizeLoadBalancerCommandBuilder(request, config, builder);
		return builder.build();
	}

它留下一个抽象方法和一个钩子方法给AbstractLoadBalancerAwareClient去完成定制化~


executeWithLoadBalancer() 带有负载均衡能力的执行

它不是接口方法:因为接口方法不具备负载均衡的能力。但是它是更为重要的方法:包装了execute()接口方法,放在LoadBalancerCommand里执行从而就具有负载均衡的能力了。

AbstractLoadBalancerAwareClient:

	// 注意:接口方法只有execute,这是在外层套了一个负载均衡器,均由负载均衡的能力
    public T executeWithLoadBalancer(S request) throws ClientException {
        return executeWithLoadBalancer(request, null);
    }

    public T executeWithLoadBalancer(final S request, final IClientConfig requestConfig) throws ClientException {
    	// 构建一个执行命令:command
    	LoadBalancerCommand<T> command = buildLoadBalancerCommand(request, requestConfig);


		// 提交目标操作/目标请求  -> 执行目标方法
    	return command.submit(server -> {
    		// 根据LB选中的Server,构建出一个最终的URI
    		// 因为你的URI可能没有host、port等是不完整的
    		URI finalUri = reconstructURIWithServer(server, request.getUri());
    		// 给request重新制定一个新的URI
    		S requestForServer = (S) request.replaceUri(finalUri);
    		
    		// execute执行目标方法:一般是发送http请求,当然这不是一定的~
    		return Observable.just(AbstractLoadBalancerAwareClient.this.execute(requestForServer, requestConfig));
    	})
    	// 阻塞的,顺序执行 使用RxJava是为了编程方便、优美
		.toBlocking()
		.single();
    }
}

说明:为了代码结构清晰,内嵌的很多try…catch均省略了

该方法的核心要义是:使用LoadBalancerCommand包装execute目标方法,从而使得其具有了负载均衡的能力。因此在实际应用中:请勿直接调用execute方法,而是使用更加上层、功能更强的executeWithLoadBalancer()方法。


如果仅是在ribbon-loadbalancer这个jar内,IClient体系有且仅有这一个子类AbstractLoadBalancerAwareClient,并且它还是抽象类。由于负载均衡器它并不限定具体协议,比如http、tcp、udp等都是可以做负载均衡的,所以在此jar内并无任何具体的Client实现类

但是在Spring Cloud环境下,一片繁荣:

在这里插入图片描述
在这里插入图片描述
本文并不会介绍Spring Cloud里对它的实现,而是把它放在和Spring Cloud整合的相关章节中。


ClientFactory

既然Client如此重要,为了快速、方便的得到一个Client实例,Ribbon提供了ClientFactory这个工厂类。该类用于快速创建IClient客户端、ILoadBalancerIClientConfig等的工厂。并且它内部还维护了全局的Map,缓存来提高获取效率。

public class ClientFactory {

	// key是ClientName  value是Client实例
	private static Map<String, IClient<?,?>> simpleClientMap = new ConcurrentHashMap<>();
	// key是Lb的名称  value是LB实例
	private static Map<String, ILoadBalancer> namedLBMap = new ConcurrentHashMap<>();
	// key是ClientName  value是该client对应的配置(含默认配置)
	private static ConcurrentHashMap<String, IClientConfig> namedConfig = new ConcurrentHashMap<>();

	// ==========工具方法们=========
	
	// 反射创建一个实例,并且调用其initWithNiwsConfig()方法把config传递给它
	public static Object instantiateInstanceWithClientConfig(String className, IClientConfig clientConfig) {
		...
		IClientConfigAware obj = (IClientConfigAware) clazz.newInstance();
		obj.initWithNiwsConfig(clientConfig);
		return obj;
	}

	// 反射创建一个clientConfigClass类型的配置。IClientConfig接口的自带实现仅有DefaultClientConfigImpl
	// 注意config.loadProperties(name)方法会被调用哦(配置会被加载进来)
	// 最后放进缓存(缓存里就返回缓存里的)
	public static IClientConfig getNamedConfig(String name, Class<? extends IClientConfig> clientConfigClass) {
        IClientConfig config = namedConfig.get(name);
        if (config != null) {
            return config;
        } 
        config = (IClientConfig) clientConfigClass.newInstance();
        config.loadProperties(name);
        ...
        return config;
	}
    public static IClientConfig getNamedConfig(String name) {
        return 	getNamedConfig(name, DefaultClientConfigImpl.class);
    }

	... // 创建`ILoadBalancer`实例的方法几乎一模一样,略

	// 提供名称和客户端配置的实用程序方法来创建客户端和负载均衡器(如果在客户端配置中启用)
	// InitializeNFLoadBalancer默认配置值是true,开启负载均衡器的
	public static synchronized IClient<?, ?> registerClientFromProperties(String restClientName, IClientConfig clientConfig) throws ClientException {
    	IClient<?, ?> client = null;
    	ILoadBalancer loadBalancer = null;
    	// 如果同名的Client已经创建过了,在调用此方法就抛错,而并非把缓存里的返回给你
    	if (simpleClientMap.get(restClientName) != null) {
    		throw new ClientException(ClientException.ErrorType.GENERAL, "A Rest Client with this name is already registered. Please use a different name");
    	}
    	... // 反射创建Client、LB的实例
		simpleClientMap.put(restClientName, client);
		return client;
	}

	// 它木有传入配置:所以全部使用外部化配置
    public static synchronized IClient getNamedClient(String name) {
        return getNamedClient(name, DefaultClientConfigImpl.class);
    }
    public static synchronized IClient getNamedClient(String name, Class<? extends IClientConfig> configClass) {
    	if (simpleClientMap.get(name) != null) {
    	    return simpleClientMap.get(name);
    	}
    	return createNamedClient(name, configClass);
    }
}

其中ClientFactory.instantiateInstanceWithClientConfig()方法是最为通用的:它可以实例化帮你实例化任何实例,包括五大核心组件等。它的优点是初始化完成后自动帮你调用initWithNiwsConfig()方法完成属性赋值~


总结

关于Ribbon具有负载均衡能力的客户端:AbstractLoadBalancerAwareClient就先介绍到这,虽然本文木有提及具体实现类和给出代码示例,但是只要理解了它(其实核心是LoadBalancerCommand)你会觉得其它都是小儿科,这在后面讲解整合时将会继续说明。

至此,关于Ribbon最最最核心部分(包含core和loadbalancer)就全部介绍完了,虽然此项目目前已经停更,但停更不停用,目前仍然是主流的(甚至是唯一的)客户端负载均衡器。学习了它不仅可以用在Spring Cloud体系下运用自如,对于理解dubbo等框架负载均衡机制都易如反掌,另外据我了解深入了解Ribbon,以及有能力使用它来实现多区域部署的人并不多,因此若你掌握了这不就是你升职加薪的砝码了麽~

当然,这不是Ribbon系列的全部,后面还要讲整合、在Spring Cloud下的实战。有了强大的理论做支撑,实战讲解将非常的快。
分隔线

声明

原创不易,码字不易,多谢你的点赞、收藏、关注。把本文分享到你的朋友圈是被允许的,但拒绝抄袭。你也可【左边扫码/或加wx:fsx641385712】邀请你加入我的 Java高工、架构师 系列群大家庭学习和交流。
往期精选

发布了377 篇原创文章 · 获赞 572 · 访问量 51万+
App 阅读领勋章
微信扫码 下载APP
阅读全文

Spring clouud eureka feign调用问题

11-03

最近在学习使用spring cloud 的时候遇到这样一个问题,项目划分了3个模块 注册中心、服务提供方、服务消费方. 分别启动3个项目后 在注册中心的web管理页面 能看到服务提供方和服务消费方都已经注册上来了。但是 当服务消费方调用方法时,通过日志看到是以服务提供方的别名为IP地址发起调用的 一调用就报错 请各位大神们帮忙看看 最好能给我讲讲为什么会出现这个问题 注册中心启动类 ```/** * 注册中心启动类 * */ @EnableEurekaServer @SpringBootApplication public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } } ``` 注册中心配置 ``` server.port=8001 #自我注册 eureka.client.register-with-eureka=false eureka.client.fetch-registry=false # eureka.server.enable-self-preservation=true eureka.server.eviction-interval-timer-in-ms=60000 #关闭自我保护 eureka.server.enableSelfPreservation=false eureka.client.serviceUrl.defaultZone=http://localhost:${server.port}/eureka/ ``` 服务提供方启动类 ``` @EnableDiscoveryClient @SpringBootApplication public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } } ``` 服务提供方Rest接口 ```@RestController @RequestMapping("menu") public class BMenuController { @Autowired private IBMenuService menuService; private static final Logger logger = LoggerFactory.getLogger(BMenuController.class); @RequestMapping("/selectById/{id}") public BMenu selectById(@PathVariable("id") Integer id) { logger.info("数据访问层 菜单通过ID获取 调用 id:[{}]", id); return menuService.selectById(id); } ``` 服务提供方配置: ```#设置应用的名称 spring.application.name=ic-generic #服务注册的Eureka Server地址 #eureka.client.serviceUrl.defaultZone=http://hlwic:hlwic@localhost:8001/eureka eureka.client.serviceUrl.defaultZone=http://localhost:8001/eureka server.port=8002 ``` 服务消费方启动类: ```@SpringBootApplication @EnableDiscoveryClient @EnableFeignClients public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } } ``` 服务消费方 feign接口: ``` @FeignClient("ic-generic") public interface IBMenuService { @RequestMapping("/menu/selectById/{id}") public BMenu selectById(@PathVariable("id") Integer id); ``` 服务消费方配置: ``` spring.application.name=ic-app server.port=8005 eureka.client.serviceUrl.defaultZone=http://localhost:8001/eureka/ ``` ![图片说明](https://img-ask.csdn.net/upload/201711/03/1509679661_1124.png) 异常信息: ```2017-11-03 11:25:13.827 INFO 12140 --- [nio-8005-exec-4] com.hlw.ic.app.facade.BMenuController : 控制器接收到app端发起的通过id查询菜单请求 params[{"id":1}] 2017-11-03 11:25:22.483 WARN 12140 --- [nio-8005-exec-4] com.hlw.ic.app.facade.BMenuController : app端发起的通过id查询菜单请求 发生异常 params[{"id":1}] feign.RetryableException: connect timed out executing GET http://ic-generic/menu/selectById/1 at feign.FeignException.errorExecuting(FeignException.java:67) ~[feign-core-9.5.0.jar:na] at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:104) ~[feign-core-9.5.0.jar:na] at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:76) ~[feign-core-9.5.0.jar:na] at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:103) ~[feign-core-9.5.0.jar:na] at com.sun.proxy.$Proxy82.selectById(Unknown Source) ~[na:na] at com.hlw.ic.app.facade.BMenuController.queryById(BMenuController.java:74) ~[classes/:na] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_131] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_131] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_131] at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_131] at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) [spring-web-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133) [spring-web-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97) [spring-webmvc-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) [spring-webmvc-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) [spring-webmvc-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) [spring-webmvc-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967) [spring-webmvc-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901) [spring-webmvc-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) [spring-webmvc-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872) [spring-webmvc-4.3.9.RELEASE.jar:4.3.9.RELEASE] at javax.servlet.http.HttpServlet.service(HttpServlet.java:661) [tomcat-embed-core-8.5.15.jar:8.5.15] at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) [spring-webmvc-4.3.9.RELEASE.jar:4.3.9.RELEASE] at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) [tomcat-embed-core-8.5.15.jar:8.5.15] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) [tomcat-embed-core-8.5.15.jar:8.5.15] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.15.jar:8.5.15] at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) [tomcat-embed-websocket-8.5.15.jar:8.5.15] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.15.jar:8.5.15] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.15.jar:8.5.15] at org.springframework.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:55) [spring-boot-1.5.4.RELEASE.jar:1.5.4.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.15.jar:8.5.15] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.15.jar:8.5.15] at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:110) [spring-boot-actuator-1.5.4.RELEASE.jar:1.5.4.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.15.jar:8.5.15] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.15.jar:8.5.15] at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) [spring-web-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.15.jar:8.5.15] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.15.jar:8.5.15] at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:105) [spring-web-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.15.jar:8.5.15] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.15.jar:8.5.15] at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81) [spring-web-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.15.jar:8.5.15] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.15.jar:8.5.15] at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) [spring-web-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.15.jar:8.5.15] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.15.jar:8.5.15] at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:106) [spring-boot-actuator-1.5.4.RELEASE.jar:1.5.4.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.15.jar:8.5.15] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.15.jar:8.5.15] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) [tomcat-embed-core-8.5.15.jar:8.5.15] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.15.jar:8.5.15] at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478) [tomcat-embed-core-8.5.15.jar:8.5.15] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.15.jar:8.5.15] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80) [tomcat-embed-core-8.5.15.jar:8.5.15] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.15.jar:8.5.15] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [tomcat-embed-core-8.5.15.jar:8.5.15] at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799) [tomcat-embed-core-8.5.15.jar:8.5.15] at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.15.jar:8.5.15] at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861) [tomcat-embed-core-8.5.15.jar:8.5.15] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455) [tomcat-embed-core-8.5.15.jar:8.5.15] at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.15.jar:8.5.15] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_131] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_131] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.15.jar:8.5.15] at java.lang.Thread.run(Thread.java:748) [na:1.8.0_131] Caused by: java.net.SocketTimeoutException: connect timed out at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method) ~[na:1.8.0_131] at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:85) ~[na:1.8.0_131] at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) ~[na:1.8.0_131] at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) ~[na:1.8.0_131] at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) ~[na:1.8.0_131] at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172) ~[na:1.8.0_131] at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) ~[na:1.8.0_131] at java.net.Socket.connect(Socket.java:589) ~[na:1.8.0_131] at sun.net.NetworkClient.doConnect(NetworkClient.java:175) ~[na:1.8.0_131] at sun.net.www.http.HttpClient.openServer(HttpClient.java:463) ~[na:1.8.0_131] at sun.net.www.http.HttpClient.openServer(HttpClient.java:558) ~[na:1.8.0_131] at sun.net.www.http.HttpClient.<init>(HttpClient.java:242) ~[na:1.8.0_131] at sun.net.www.http.HttpClient.New(HttpClient.java:339) ~[na:1.8.0_131] at sun.net.www.http.HttpClient.New(HttpClient.java:357) ~[na:1.8.0_131] at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:1202) ~[na:1.8.0_131] at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1138) ~[na:1.8.0_131] at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1032) ~[na:1.8.0_131] at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:966) ~[na:1.8.0_131] at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1546) ~[na:1.8.0_131] at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1474) ~[na:1.8.0_131] at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480) ~[na:1.8.0_131] at feign.Client$Default.convertResponse(Client.java:152) ~[feign-core-9.5.0.jar:na] at feign.Client$Default.execute(Client.java:74) ~[feign-core-9.5.0.jar:na] at org.springframework.cloud.netflix.feign.ribbon.FeignLoadBalancer.execute(FeignLoadBalancer.java:80) ~[spring-cloud-netflix-core-1.3.1.RELEASE.jar:1.3.1.RELEASE] at org.springframework.cloud.netflix.feign.ribbon.FeignLoadBalancer.execute(FeignLoadBalancer.java:48) ~[spring-cloud-netflix-core-1.3.1.RELEASE.jar:1.3.1.RELEASE] at com.netflix.client.AbstractLoadBalancerAwareClient$1.call(AbstractLoadBalancerAwareClient.java:109) ~[ribbon-loadbalancer-2.2.2.jar:2.2.2] at com.netflix.loadbalancer.reactive.LoadBalancerCommand$3$1.call(LoadBalancerCommand.java:303) ~[ribbon-loadbalancer-2.2.2.jar:2.2.2] at com.netflix.loadbalancer.reactive.LoadBalancerCommand$3$1.call(LoadBalancerCommand.java:287) ~[ribbon-loadbalancer-2.2.2.jar:2.2.2] at rx.internal.util.ScalarSynchronousObservable$3.call(ScalarSynchronousObservable.java:231) ~[rxjava-1.1.10.jar:1.1.10] at rx.internal.util.ScalarSynchronousObservable$3.call(ScalarSynchronousObservable.java:228) ~[rxjava-1.1.10.jar:1.1.10] at rx.Observable.unsafeSubscribe(Observable.java:10211) ~[rxjava-1.1.10.jar:1.1.10] at rx.internal.operators.OnSubscribeConcatMap$ConcatMapSubscriber.drain(OnSubscribeConcatMap.java:286) ~[rxjava-1.1.10.jar:1.1.10] at rx.internal.operators.OnSubscribeConcatMap$ConcatMapSubscriber.onNext(OnSubscribeConcatMap.java:144) ~[rxjava-1.1.10.jar:1.1.10] at com.netflix.loadbalancer.reactive.LoadBalancerCommand$1.call(LoadBalancerCommand.java:185) ~[ribbon-loadbalancer-2.2.2.jar:2.2.2] at com.netflix.loadbalancer.reactive.LoadBalancerCommand$1.call(LoadBalancerCommand.java:180) ~[ribbon-loadbalancer-2.2.2.jar:2.2.2] at rx.Observable.unsafeSubscribe(Observable.java:10211) ~[rxjava-1.1.10.jar:1.1.10] at rx.internal.operators.OnSubscribeConcatMap.call(OnSubscribeConcatMap.java:94) ~[rxjava-1.1.10.jar:1.1.10] at rx.internal.operators.OnSubscribeConcatMap.call(OnSubscribeConcatMap.java:42) ~[rxjava-1.1.10.jar:1.1.10] at rx.Observable.unsafeSubscribe(Observable.java:10211) ~[rxjava-1.1.10.jar:1.1.10] at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber$1.call(OperatorRetryWithPredicate.java:127) ~[rxjava-1.1.10.jar:1.1.10] at rx.internal.schedulers.TrampolineScheduler$InnerCurrentThreadScheduler.enqueue(TrampolineScheduler.java:73) ~[rxjava-1.1.10.jar:1.1.10] at rx.internal.schedulers.TrampolineScheduler$InnerCurrentThreadScheduler.schedule(TrampolineScheduler.java:52) ~[rxjava-1.1.10.jar:1.1.10] at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber.onNext(OperatorRetryWithPredicate.java:79) ~[rxjava-1.1.10.jar:1.1.10] at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber.onNext(OperatorRetryWithPredicate.java:45) ~[rxjava-1.1.10.jar:1.1.10] at rx.internal.util.ScalarSynchronousObservable$WeakSingleProducer.request(ScalarSynchronousObservable.java:276) ~[rxjava-1.1.10.jar:1.1.10] at rx.Subscriber.setProducer(Subscriber.java:209) ~[rxjava-1.1.10.jar:1.1.10] at rx.internal.util.ScalarSynchronousObservable$JustOnSubscribe.call(ScalarSynchronousObservable.java:138) ~[rxjava-1.1.10.jar:1.1.10] at rx.internal.util.ScalarSynchronousObservable$JustOnSubscribe.call(ScalarSynchronousObservable.java:129) ~[rxjava-1.1.10.jar:1.1.10] at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48) ~[rxjava-1.1.10.jar:1.1.10] at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30) ~[rxjava-1.1.10.jar:1.1.10] at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48) ~[rxjava-1.1.10.jar:1.1.10] at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30) ~[rxjava-1.1.10.jar:1.1.10] at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48) ~[rxjava-1.1.10.jar:1.1.10] at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30) ~[rxjava-1.1.10.jar:1.1.10] at rx.Observable.subscribe(Observable.java:10307) ~[rxjava-1.1.10.jar:1.1.10] at rx.Observable.subscribe(Observable.java:10274) ~[rxjava-1.1.10.jar:1.1.10] at rx.observables.BlockingObservable.blockForSingle(BlockingObservable.java:445) ~[rxjava-1.1.10.jar:1.1.10] at rx.observables.BlockingObservable.single(BlockingObservable.java:342) ~[rxjava-1.1.10.jar:1.1.10] at com.netflix.client.AbstractLoadBalancerAwareClient.executeWithLoadBalancer(AbstractLoadBalancerAwareClient.java:117) ~[ribbon-loadbalancer-2.2.2.jar:2.2.2] at org.springframework.cloud.netflix.feign.ribbon.LoadBalancerFeignClient.execute(LoadBalancerFeignClient.java:63) ~[spring-cloud-netflix-core-1.3.1.RELEASE.jar:1.3.1.RELEASE] at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:97) ~[feign-core-9.5.0.jar:na] ... 70 common frames omitted 2017-11-03 11:25:22.724 INFO 12140 --- [nio-8005-exec-4] com.hlw.ic.app.facade.BMenuController : 控制器接收到app端发起的通过id查询菜单请求 处理完成 耗时[8760] params[{"id":1}] 响应信息[{"code":-1,"mess":"异常"}] ``` 问答

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: Age of Ai 设计师: meimeiellie

分享到微信朋友圈

×

扫一扫,手机浏览