1. Eureka源码探索(一)-客户端服务端的启动和负载均衡

1.1. 服务端

1.1.1. 找起始点

  1. 目前唯一知道的,就是启动Eureka服务需要添加注解@EnableEurekaServer,但是暂时找不到它被使用的地方
  2. 看日志,明显有打印discovery client,服务端同时也用作客户端,因为它可以相互注册,以下是自动配置类

  3. 知道了客户端有自动配置类,可以想象服务端也应该有,找到相应的包,发现果然有

1.1.2. 服务初始化

  1. 启动初始化

  2. 接下来是个发布订阅方法,发布对象继承了Spring的ApplicationEvent,可以看出肯定会有订阅者接收该配置,配置内容就是我们application.properties里配置的属性,不配则是默认属性

1.1.3. @EnableEurekaServer起作用的原理

  1. 进入该注解,可以看到注解中还有个注解@Import它的作用就是将之后的类对象所对应的实例,实例化并加入spring容器管理
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(EurekaServerMarkerConfiguration.class)
public @interface EnableEurekaServer { }
  1. 进入EurekaServerMarkerConfiguration类,可以看到如下,该类的作用仅仅用来标记下,为启动类判断是否需要启动EurekaServer
@Configuration
public class EurekaServerMarkerConfiguration { @Bean
public Marker eurekaServerMarkerBean() {
return new Marker();
} class Marker { } }
  1. 它具体被使用的地方如下,用一个@ConditionalOnBean表示,若存在该类Bean,则启动配置生效

1.2. 客户端

1.2.1. 调用解析过程

  1. restTemplate调用
restTemplate.getForEntity("http://eureka-server", String.class);
  1. 在不断深入后,最终处理的是一个拦截器

  2. 拦截器进的实际处理类是LoadBalancerInterceptor

  3. 但里面实际的负载均衡调用loadBalancer又是RibbonLoadBalancerClient

  4. 这就真真的进了Ribbon的负载均衡调用了,至于这个RibbonLoadBalancerClient怎么注入进来的,这也简单,这里有两层关系,该LoadBalancerInterceptor如何实例化的,和RibbonLoadBalancerClient如何实例化并注入的,可以看如下图





  5. 好了,不扯开去了,继续解析服务名,实际上,接下来就是RibbonLoadBalancerClient的实现了

  6. 继续深入

  7. 轮询核心算法

1.3. 模拟负载均衡调用

1.3.1. 代码直接上

@SpringBootApplication
@EnableDiscoveryClient
@RestController
@Slf4j
public class EurekaClientApplication { public static void main(String[] args) {
SpringApplication.run(EurekaClientApplication.class, args);
}
@Autowired
private RestTemplate restTemplate; @Autowired
private DiscoveryClient discoveryClient; /**
* 使用Ribbon的负载均衡
* @return
*/
@GetMapping("/")
public ResponseEntity<String> getTime(){
return restTemplate.getForEntity("http://eureka-server", String.class);
} /**
* 模拟轮询负载的调用
* @return
*/
@GetMapping("/discovery")
public ResponseEntity<String> discovery(){
List<ServiceInstance> instances = discoveryClient.getInstances("eureka-server");
int i = incrementAndGetModule(instances.size());
return restTemplate.getForEntity(((EurekaDiscoveryClient.EurekaServiceInstance) instances.get(i)).getInstanceInfo().getHomePageUrl(), String.class);
} private AtomicInteger nextIndex = new AtomicInteger();
private int incrementAndGetModule(int module) {
for (; ; ) {
int current = nextIndex.get();
int next = (current + 1) % module;
if (nextIndex.compareAndSet(current,next) && current < module) {
return current;
}
}
} /**
* 加上@LoadBalanced该注解使用的Ribbon的负载均衡算法
*/
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
  1. 这里用了Ribbon的负载均衡轮询算法和直接调用discoveryClient实现最简单的模拟轮询算法
  2. 注意,测试discovery的时候可以需要把@LoadBalanced注掉

Eureka源码探索(一)-客户端服务端的启动和负载均衡的更多相关文章

  1. Spring Cloud系列(三):Eureka源码解析之服务端

    一.自动装配 1.根据自动装配原理(详见:Spring Boot系列(二):Spring Boot自动装配原理解析),找到spring-cloud-starter-netflix-eureka-ser ...

  2. Ribbon源码分析(一)-- RestTemplate 以及自定义负载均衡算法

    如果只是想看ribbon的自定义负载均衡配置,请查看: https://www.cnblogs.com/yangxiaohui227/p/13186004.html 注意: 1.RestTemplat ...

  3. sofa-bolt源码阅读(1)-服务端的启动

    Bolt服务器的核心类是RpcServer,启动的时候调用父类AbstractRemotingServer的startup方法. com.alipay.remoting.AbstractRemotin ...

  4. Spring Cloud系列(四):Eureka源码解析之客户端

    一.自动装配 1.根据自动装配原理(详见:Spring Boot系列(二):Spring Boot自动装配原理解析),找到spring-cloud-netflix-eureka-client.jar的 ...

  5. Golang源码探索(二) 协程的实现原理(转)

    Golang最大的特色可以说是协程(goroutine)了, 协程让本来很复杂的异步编程变得简单, 让程序员不再需要面对回调地狱,虽然现在引入了协程的语言越来越多, 但go中的协程仍然是实现的是最彻底 ...

  6. 微服务之SpringCloud实战(四):SpringCloud Eureka源码分析

    Eureka源码解析: 搭建Eureka服务的时候,我们会再SpringBoot启动类加上@EnableEurekaServer的注解,这个注解做了一些什么,我们一起来看. 点进@EnableEure ...

  7. 4. 源码分析---SOFARPC服务端暴露

    服务端的示例 我们首先贴上我们的服务端的示例: public static void main(String[] args) { ServerConfig serverConfig = new Ser ...

  8. 【一起学源码-微服务】Nexflix Eureka 源码十:服务下线及实例摘除,一个client下线到底多久才会被其他实例感知?

    前言 前情回顾 上一讲我们讲了 client端向server端发送心跳检查,也是默认每30钟发送一次,server端接收后会更新注册表的一个时间戳属性,然后一次心跳(续约)也就完成了. 本讲目录 这一 ...

  9. 【一起学源码-微服务】Nexflix Eureka 源码十二:EurekaServer集群模式源码分析

    前言 前情回顾 上一讲看了Eureka 注册中心的自我保护机制,以及里面提到的bug问题. 哈哈 转眼间都2020年了,这个系列的文章从12.17 一直写到现在,也是不容易哈,每天持续不断学习,输出博 ...

随机推荐

  1. CMD命令锦集

    虽然随着计算机产业的发展,Windows 操作系统的应用越来越广泛,DOS 面临着被淘汰的命运,但是因为它运行安全.稳定,有的用户还在使用,所以一般Windows 的各种版本都与其兼容,用户可以在Wi ...

  2. C#中DataGridView 对XML文档的使用

    窗体就只用添加一个DataGridView控件就可以了.详细解释请参照上一篇中的借鉴曲终人散博客园的文档. XML文档代码如下:test.xml <?xml version="1.0& ...

  3. 关于新建Eclipse新建一个WEB项目后创建一个jsp文件头部报错问题?

    点击项目右键→Build Path→Libraries→AddLibrary→Server Runtime→Apache Tomcat v7.0→Finsh  操作步骤如上! http://jingy ...

  4. 浅谈前端中的mvvm与mvc

    用了vue这么久,却没有认真的关注mvvm与mvc,着实汗颜.趁着周末刚好看了一下网上的文章还有书籍,简单的谈一下我的理解. -以下图片均摘自网络. 一.MVC 特点:单项通讯 视图(View):用户 ...

  5. jQuery学习之旅 Item3 属性操作与样式操作

    本节将Dom元素的操作:属性操作.样式操作.设置和获取HTML,文本和值.Css-Dom操作. 1.属性操作 <input type="text" name="us ...

  6. MongoDB中级---->关联多表查询

    http://www.linuxidc.com/Linux/2011-08/41043.htm DBRef is a more formal specification for creating re ...

  7. Android 框架练成 教你打造高效的图片加载框架

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/41874561,本文出自:[张鸿洋的博客] 1.概述 优秀的图片加载框架不要太多, ...

  8. 借助HTML中的特殊符号在markdown中打印出来

    转自:https://blog.csdn.net/html5_/article/details/21639475 HTML中的特殊符号 原创 2014年03月20日 18:35:23 标签: HTML ...

  9. 用Excel导入Oracle数据库plsql

    打开plsql之后,在工具栏点击[tools]--[ODBC Imoprter] 选择导入文件的类型,这里是excel文件,所以选择Excel Files 输入连接数据库的用户名和密码 点击Conne ...

  10. 【bzoj 3233】[Ahoi2013]找硬币 ——搜索

    Description 小蛇是金融部部长.最近她决定制造一系列新的货币.假设她要制造的货币的面值为x1,x2,x3… 那么x1必须为1,xb必须为xa的正整数倍(b>a).例如 1,5,125, ...