Netflix Ribbon的阅读理解

最近用到Ribbon,总是觉得Ribbon既强大但是又不好用,其实根源还是对其内部的工作原理不够了解,导致对一些现象不能给出合理的解释,也影响了功能扩展。希望通过本次梳理,能够对Ribbon有一个较为清晰的理解!最近记性也不好了,还是要写下来才有印象。。。-_-

Ribbon + Spring Cloud

Ribbon是Netflix开源的一款用于客户端软负载均衡的工具软件。
Spring Cloud对Ribbon进行了一些封装以更好的使用Spring Boot的自动化配置理念。

先建个环境跑起来

  • 搭建一个基本的Spring Boot项目
  • 引入Spring Cloud Zuul依赖(Zuul直接包含了Ribbon的依赖,省点事。。。)
<dependency>    
   <groupId>org.springframework.cloud</groupId>  
   <artifactId>spring-cloud-starter-zuul</artifactId>   
   <version>1.2.3.RELEASE</version>
</dependency>
  • 启用Zuul
@SpringBootApplication
@EnableZuulProxy
public class ZuulApplication {
    public static void main(String[] args) {    
        SpringApplication.run(ZuulApplication.class, args);
    }
}
  • 配置路由
server:  
    port: 7777
zuul:  
    routes:   
       node:
           path: /api/**
           serviceId: node
ribbon: 
   eureka:
      enabled: false
node: 
    ribbon:
      listOfServers: http://localhost:9600,http://localhost:9500

OK,访问http://localhost:7777/api/hello,就可以看到请求在9500和9600间不停切换了。

我在9500,9600启动了两个node express server, 只接受'/hello'请求,返回'Hello,world! {port}'

看看源码

如上,Ribbon发挥了负载均衡的作用,从结果来看,目前ribbon是使用轮询的方式进行负载均衡。为了更好的理解,还是看看代码,他到底怎么工作的?

入口

查看spring-cloud-netflix-core-1.2.3.RELEASE.jar/META-INF/spring.fatories文件:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration,
...
org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration,\

很明显,RibbonAutoConfiguration就是Spring Boot启动Rabbion的入口配置类。

RibbonAutoConfiguration

public class RibbonAutoConfiguration {
...
 @Bean
 public SpringClientFactory springClientFactory() {   
     SpringClientFactory   factory = new SpringClientFactory();  
     factory.setConfigurations(this.configurations);   return factory;}
...
}

很明显,最重要的bean就是SpringClientFactory, 为啥?因为其他bean都需要他去初始化。。。

SpringClientFactory

方法列表如图:


SpringClientFactory.png

查看方法列表,此类提供了获取指定serviceId的IClient, ILoadBalance, ILoadBalanceContext等对象的重要方法。

  • IClient 是发起请求并执行的接口,先不管;
  • ILoadBalanceContext 封装了一些负载均衡额外的方法,比如noteOpenConnection(), noteError(), noteResponse()等等,先不管。
  • ILoadBalance就是我想知道的负载均衡啦。

仔细查看获取LB(LoadBalance)实例的方法,发现LB实例最终从父类NamedContextFactory获取Bean。
Bean来源AnnotationConfigApplicationContext context ,

public <T> Map<String, T> getInstances(String name, Class<T> type) {
   AnnotationConfigApplicationContext context = getContext(name);   
    if (BeanFactoryUtils.beanNamesForTypeIncludingAncestors(context, type).length > 0) {    
      return BeanFactoryUtils.beansOfTypeIncludingAncestors(context, type);   
    }   
    return null;
}

这个Context从那里获取我想要的bean实例呢?还是截图吧,这个鬼排版傻死了。

createContext

看看context的创建过程,上面的红圈处,它会尝试为每个serviceId使用属于自己的配置类(当然前提是你有对应的配置),并注册;
下面的红圈说明,它会注册一个默认的配置类this.defaultConfigType,

this.defaultConfigType = RibbonClientConfiguration.class;
context.register(PropertyPlaceholderAutoConfiguration.class, this.defaultConfigType);

至此,一个关键的配置类被发现了:RibbonClientConfiguration, 不容易-_-!

RibbonClientConfiguration

方法列表:


Paste_Image.png

基本上看着方法名就知道各种Bean是干什么的吧(IRule,IPing,ServerList,ILoadBalancer,ServerListFilter,RibbonLoadBalancerContext,RetryHandler,ServerIntrospector)。
更重要的是:我们可以大胆的为每个serviceId指定自己的配置类了,如下,为"node"指定IPing的特殊的实现类:

@RibbonClient(name = "node", configuration = NodeServiceConfig.class)
public class ZuulApplication {
...
}
public class NodeServiceConfig {  
  private String name = "node";   
  @Autowired    
  private IClientConfig iClientConfig;   
  @Bean    
  public IPing ribbonPing(IClientConfig iClientConfig) {    
      if (this.propertiesFactory.isSet(IPing.class, name)) {            
          return this.propertiesFactory.get(IPing.class, iClientConfig, name);       
       }        
      return new NoOpPing();   
   }
}

未完待续...

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,026评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,655评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,726评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,204评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,558评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,731评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,944评论 2 314
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,698评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,438评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,633评论 2 247
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,125评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,444评论 3 255
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,137评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,103评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,888评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,772评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,669评论 2 271

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,103评论 18 139
  • zuul 上传文件 在user-service中定义一个上传接口: 配置文件配置如下: 在user-service...
    二月_春风阅读 10,186评论 2 8
  • Zuul 代码地址:https://github.com/jedyang/springCloud 先来看一个简单的...
    运维开发笔记阅读 620评论 0 2
  • 如今做Java尤其是web几乎是避免不了和Spring打交道了,但是Spring是这样的大而全,新鲜名词不断产生,...
    MageekChiu阅读 1,596评论 0 26
  • 看着朋友圈的一条的祝福端午节,也许真的只有陪伴着你他才能感受到这份看不见,摸不着的气氛了吧,夏日炎炎,六月份到...
    mini迷你阅读 156评论 0 0