`

[转] Ribbon问题

 
阅读更多

转自:https://segmentfault.com/a/1190000010486459

 

不知道从哪个版本起(目测跟版本无关,应该是ribbon.eureka.enabled=true的情况下),给ribbon配置物理的server list起,单纯配置xxx.ribbon.listOfServers不起效果了,于是就开启了埋坑之旅。

目前使用的是Camden.SR6版本

异常

java.lang.IllegalStateException: No instances available for xxx
    at org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient.execute(RibbonLoadBalancerClient.java:75)
    at org.springframework.cloud.client.loadbalancer.LoadBalancerInterceptor.intercept(LoadBalancerInterceptor.java:53)
    at org.springframework.http.client.InterceptingClientHttpRequest$InterceptingRequestExecution.execute(InterceptingClientHttpRequest.java:86)
    at org.springframework.cloud.netflix.metrics.MetricsClientHttpRequestInterceptor.intercept(MetricsClientHttpRequestInterceptor.java:68)
    at org.springframework.http.client.InterceptingClientHttpRequest$InterceptingRequestExecution.execute(InterceptingClientHttpRequest.java:86)
    at org.springframework.http.client.InterceptingClientHttpRequest.executeInternal(InterceptingClientHttpRequest.java:70)
    at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
    at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:652)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:613)
    at org.springframework.web.client.RestTemplate.postForEntity(RestTemplate.java:407)
    at org.springframework.web.client.RestTemplate$$FastClassBySpringCGLIB$$aa4e9ed0.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:721)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:85)
    at org.springframework.cloud.netflix.metrics.RestTemplateUrlTemplateCapturingAspect.captureUrlTemplate(RestTemplateUrlTemplateCapturingAspect.java:33)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:629)
    at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:618)
    at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:656)
    at org.springframework.web.client.RestTemplate$$EnhancerBySpringCGLIB$$ec1f757d.postForEntity(<generated>)

复现条件

  • 采用了RibbonClient来指定server list
  • 没有使用@RibbonClients指定,把标注RibbonClient配置类放在了@ComponentScan扫描包下
  • 有多个服务这样指定
  • 而且其中还有一个服务使用load balanced restTemplate的时候,url中的服务名写错了,写成了一个不存在的服务名(当时是把外部的服务名改了导致的)

导致使用到了错误的server list。

问题配置

@RibbonClient(name = "xxx",configuration = XxxRibbonConfig.class)
public class XxxRibbonConfig {

    String listOfServers = "http://192.168.99.100:8080,http://192.168.99.101:8080";

    @Bean
    public ServerList<Server> ribbonServerList() {
        List<Server> list = Lists.newArrayList();
        if (!Strings.isNullOrEmpty(listOfServers)) {
            for (String s: listOfServers.split(",")) {
                list.add(new Server(s.trim()));
            }
        }
        return new StaticServerList<Server>(list);
    }
}

这个的问题是把这个配置放到了@ComponentScan扫描的包下面

查看/beans

{
"bean": "ribbonServerList",
"aliases": [],
"scope": "singleton",
"type": "org.springframework.cloud.netflix.ribbon.StaticServerList",
"resource": "class path resource [com/xxx/XxxRibbonConfig.class]",
"dependencies": []
}

会发现多个ribbonClient的话,其中一个的ribbonServerList注册为全局的了。(为什么会注册为全局的?)而spring-cloud-netflix-core-1.2.6.RELEASE-sources.jar!/org/springframework/cloud/netflix/ribbon/RibbonClientConfiguration.java

    @Bean
    @ConditionalOnMissingBean
    @SuppressWarnings("unchecked")
    public ServerList<Server> ribbonServerList(IClientConfig config) {
        if (this.propertiesFactory.isSet(ServerList.class, name)) {
            return this.propertiesFactory.get(ServerList.class, config, name);
        }
        ConfigurationBasedServerList serverList = new ConfigurationBasedServerList();
        serverList.initWithNiwsConfig(config);
        return serverList;
    }

这里发现已经有了ribbonServerList,而且没有找到指定的服务名的server list配置,于是就采用了全局的。

解决方案

解决方案很简单,就是修改为正确的服务名就可以了。另外一个方案就是不使用RibbonClient配置,最简单的就是配置文件添加NIWSServerListClassName属性:

xxx:
  ribbon:
    ReadTimeout: 60000
    ConnectTimeout: 60000
      NIWSServerListClassName: com.netflix.loadbalancer.ConfigurationBasedServerList
      listOfServers: http://192.168.99.100:8080,http://192.168.99.101:8080

规避全局ribbonServerList的方案

在不使用NIWSServerListClassName属性配置,使用RibbonClient配置的前提下,如何规避全局ribbonServerList呢?

方案1:使用@RibbonClients配置

@SpringCloudApplication
@RibbonClients(value = {
        @RibbonClient(name = "xxx",configuration = XxxRibbonConfig.class),
        @RibbonClient(name = "demo",configuration = DemoRibbonConfig.class)
})
public class DemoServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoServiceApplication.class, args);
    }
}

然后XxxRibbonConfig以及DemoRibbonConfig类上没有任何注解,比如

public class XxxRibbonConfig {

    String listOfServers = "http://192.168.99.100:8080,http://192.168.99.101:8080";

    @Bean
    public ServerList<Server> ribbonServerList() {
        List<Server> list = Lists.newArrayList();
        if (!Strings.isNullOrEmpty(listOfServers)) {
            for (String s: listOfServers.split(",")) {
                list.add(new Server(s.trim()));
            }
        }
        return new StaticServerList<Server>(list);
    }
}

由于类上没有注解,因而这个时候就跟他们类路径是否在@ComponentScan扫描的包下面没有关系了。

方案2

把标注@RibbonClient的XxxRibbonConfig以及DemoRibbonConfig放到@ComponentScan扫描的包外面即可。

分享到:
评论

相关推荐

    漂亮的自绘Ribbon工具栏

    "漂亮的自绘Ribbon工具栏"是一个项目,它展示了如何在Visual Studio 2003环境下使用GDI+技术创建自定义的Ribbon界面。Ribbon界面是Microsoft Office 2007开始引入的一种全新界面设计,以清晰、直观的方式组织功能,...

    WPF ribbon office2010风格

    RIBBON OFFICE2010 风格 我研究RIBBON风格很久了,最开始VS2010用MFC RIBBON ,感觉的确很漂亮,后来转到.NET 上用WPF ribbon 感觉W微软提供的ribbon很有问题,比如你如果是XP系统,就会显示最老土的WIN32标题栏 我...

    ribbon.zip

    因为微服务间的调用,API网关的请求转发等内容,实际上都是通过Ribbon来实现的,包括后续我们将要介绍的Feign,它也是基于Ribbon实现的工具。所以,对Spring Cloud Ribbon的理解和使用,对于我们使用Spring Cloud来...

    Finn之 SpringCloud2.0教程全集(三)- 服务消费者(rest + ribbon)

    Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,它基于Netflix Ribbon...因为微服务间的调用,API网关的请求转发等内容,实际上都是通过Ribbon来实现的,包括后续我们将要介绍的Feign,它也是基于Ribbon实现的工具。

    Ribbon的最佳实践(CB)

    在开发Windows应用时,采用Ribbon界面风格可以提供与Microsoft Office等软件类似的用户交互体验。本文将探讨在C++ Builder中使用Ribbon的最佳实践,帮助开发者创建高效且易用的Ribbon界面。 首先,要注重命令组织。...

    Android 导航菜单 RibbonMenu

    在自定义控件的过程中,需要考虑复用性、性能优化以及兼容性问题,确保在不同版本的Android系统上都能正常运行。 在实际项目中,为了提高代码的可维护性和可扩展性,通常会采用模块化设计。将`RibbonMenu`作为一个...

    spring cloud eureka zuul ribbon hystrix feign config 示例

    在给定的标题和描述中,我们看到了几个关键组件:Eureka、Zuul、Ribbon、Hystrix 和 Feign,这些都是Spring Cloud生态中的重要组成部分。下面将详细阐述这些组件及其在实际应用中的作用。 1. **Eureka**:它是...

    Ribbon_Opencv

    【Ribbon_Opencv】项目是一个基于Visual Studio 2012开发的,结合Ribbon界面设计和OpenCV算法的应用程序。Ribbon界面是微软在Windows 7之后引入的一种用户界面设计风格,常用于提高软件的用户体验和交互性。在这个...

    3.Ribbon服务消费者

    【Ribbon服务消费者】 在Spring Cloud的生态系统中,Ribbon是作为Netflix的子项目出现,主要功能在于提供客户端的负载均衡器。它被设计用于在微服务架构中,当一个服务需要调用其他服务时,确保请求能均匀分布到...

    从Eureka到Ribbon、RestTemplate、Hystrix、Feign、zuul一个小例子

    当服务出现故障或响应时间过长时,Hystrix会打开断路器,避免请求涌向故障服务,转而执行备用逻辑,如降级操作。 5. Feign:Feign是一个声明式的Web服务客户端,使得构建HTTP客户端变得更加简单。它允许开发者通过...

    VS08下Ribbon界面实现的MD5计算工具

    在本文中,我们将深入探讨如何在Visual Studio 2008(简称VS08)环境下,结合Ribbon界面和MD5计算,构建一个实用的工具。首先,让我们了解这两个核心概念:Ribbon界面和MD5算法。 **Ribbon界面**: Ribbon界面是一...

    73-Spring Cloud客户端负载均衡Ribbon笔记1

    Spring Cloud中的Ribbon是实现客户端负载均衡的关键组件。在传统的服务端负载均衡中,像Nginx这样的代理服务器会接收请求并根据预设的算法(如轮询、权重轮询、随机等)转发到后端服务。而在客户端负载均衡模式下,...

    02Spring Cloud Ribbon:负载均衡的服务调用1

    在Spring Cloud生态系统中,Spring Cloud Ribbon是一个至关重要的组件,它主要负责实现客户端的负载均衡,以确保服务间的调用能够均匀地分散到各个实例上,从而提高系统的整体可用性和性能。Ribbon是Netflix开发的一...

    Customizing the 2007 Office Fluent Ribbon for Developers

    这一全新的用户界面取代了传统的多层菜单、工具栏和任务窗格,转而采用了一个更简单且经过优化的设计方案,旨在提高效率和易用性。Fluent UI具有改进的上下文菜单、增强的屏幕提示、迷你工具栏以及键盘快捷键等特性...

    Rocky 2022 R1_Workshop 18 – Ribbon Blender.rar

    在本工作坊中,我们聚焦于"Rocky 2022 R1"的一个关键特性——Ribbon Blender,这是一个用于模拟混合过程的强大工具。Ribbon Blender通常在化工、制药和食品行业中用来混合不同成分,确保均匀性。让我们深入探讨这个...

    System.Windows.Forms.Ribbon:.NET WinForm的功能区控件(http的fork

    在实际开发中,开发者还需要关注性能优化、布局管理、响应式设计等问题,确保功能区在不同分辨率和屏幕尺寸下的良好表现。通过熟练掌握这些知识点,你将能够利用System.Windows.Forms.Ribbon控件创建出专业且用户...

    ribbon,feign,dubbo,sentinel等等的源码分析

    以下是对标题和描述中提到的几个关键组件——Ribbon、Feign、Dubbo、Sentinel的源码分析,以及与它们相关的Spring Boot启动过程、配置文件加载流程、Nacos源码分析、Web MVC配置、DataBinder和Servlet与Filter的加载...

    ribbon-subgraph:Ribbon Finance的子图

    在IT行业中,Ribbon Finance是一个专注于提供金融策略和资产管理服务的去中心化平台。它利用以太坊等区块链网络的智能合约技术,为用户提供高效、透明且安全的金融服务。"Ribbon-subgraph"则可以理解为Ribbon ...

    《深入理解Spring Cloud与微服务构建》学习笔记(十三)~在RestTemplat和Ribbon上使用熔断器

    当服务调用出现异常或超时时,HystrixCommand会触发熔断机制,转而执行回退逻辑,防止故障扩散。 ```java @Service public class HystrixWrappedRestService { @Autowired private RestTemplate restTemplate; ...

    MFC Ribbon类与BCG 类的对应关系

    ### MFC Ribbon类与BCG 类的对应关系 在探讨MFC Ribbon类与BCG类之间的对应关系之前,我们先来了解一下MFC (Microsoft Foundation Classes) 和 BCGSoft(Business Components for Visual C++)的基本概念。 #### ...

Global site tag (gtag.js) - Google Analytics