| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 大数据 -> 一个 Map 干掉 Eureka 注册表 -> 正文阅读 |
|
[大数据]一个 Map 干掉 Eureka 注册表 |
前言本篇从源码角度带你学习 Eureka 服务端接收注册的流程。另外我从源码中也发现了一些值得我们学习的地方,如 Eureka 存储注册表的数据结构、利用读写锁来控制更细粒度的并发性,提高程序的运行效率。 接下来,会从以下几个方面讲解:
一、注册入口上一讲我们知道了 Eureka Client 是通过发送 http 请求来注册的,那么肯定是有一个地方来接收这个 http 请求的,也就是注册入口。这是怎么玩的呢? 其实是用到了 jersey 框架,这个框架不用深究,我们只需要知道这个框架在哪引用以及做什么事情的就可以了。 可以把 jersey 类比 mvc 框架,jersey 有 servlet 专门处理 http 请求。引用 jersey 框架的地方:
然后处理 HTTP 请求的 controller 在哪呢? 其实是在 eureka-core 项目的 resources 目录下,里面定义了很多的 Resource 结尾的类,它们就是用来处理 HTTP 请求的。
通过XxResource 类的英文注释我们也可以知道,这个 jersey resource 类是用来处理 HTTP 请求的。
最后找到了 ApplicationResource 类的 addInstance 方法就是我们要找的处理注册请求的方法。 二、接收注册请求整体流程如下: 2.1 接收注册请求的方法addInstance 方法里面的核心代码就是
调用它的 register() 方法后会调用抽象类 AbstractInstanceRegistry 的 register() 方法,核心代码就是在这个抽象类的?register() 方法。另外要说下的就是上面的抽象类和接口分别实现和继承了接口 InstanceRegistry。 接口和类的关系图如下: 那么注册信息会放到哪个里面呢? 三、存放注册信息的地方我们看到源码里面定义了一个 gNewMap,是 ConcurrentHashMap,然后赋值给了 gMap 变量
所以其实是用 gMap 变量来存注册信息的。我们来分析 gMap 的结构。 首先 gMap 是 ConcurrentHashMap 结构,所以就是 key-value 这种键值对的。
把服务实例信息放到 gMap 中也很简单,调用 put 方法就可以了。
下面是我注册了两个服务实例的状态: 四、值得学习的地方4.1 ConcurrentHashMap?上面讲到 ConcurrentHashMap,为什么不是用 hashmap ?
原因:
简单说下 ConcurrentHashMap 的底层原理是怎么样的? ConcurrentHashMap 内部细分了若干个小的 HashMap,称之为段(Segment)。 默认情况下一个 ConcurrentHashMap 被进一步细分为 16 个段,既就是锁的并发度。如果需要在 ConcurrentHashMap 中添加一个新的表项,并不是将整个 HashMap 加锁,而是首先根据 hashcode 得到该表项应该存放在哪个段中,然后对该段加锁,并完成 put 操作。在多线程环境中,如果多个线程同时进行put操作,只要被加入的表项不存放在同一个段中,则线程间可以做到真正的并行。 4.2 readWriteLock?我们看到源码中有用到读锁?
4.2.1 为什么分为读锁和写锁? 原因: 在没有读写锁之前,假设使用普通的 ReentrantLock,那么虽然保证了线程安全,但是也浪费了一定的资源,因为如果多个读操作同时进行,其实并没有线程安全问题,可以允许让多个读操作并行,以便提高程序效率。 但是写操作不是线程安全的,如果多个线程同时写,或者在写的同时进行读操作,便会造成线程安全问题。 读写锁就解决了这样的问题,它设定了一套规则,既可以保证多个线程同时读的效率,同时又可以保证有写入操作时的线程安全。 读锁:?允许多个线程获取读锁,同时访问同一个资源。 写锁:?只允许一个线程获取写锁,不允许同时访问同一个资源。 整体思路: 是它有两把锁,第 1 把锁是写锁,获得写锁之后,既可以读数据又可以修改数据,而第 2 把锁是读锁,获得读锁之后,只能查看数据,不能修改数据。读锁可以被多个线程同时持有,所以多个线程可以同时查看数据。 在读的地方合理使用读锁,在写的地方合理使用写锁,灵活控制,可以提高程序的执行效率。 4.2.2 读写锁的获取规则 在使用读写锁时遵守下面的获取规则:
读写锁互斥总结:
五、总结本篇从源码的角度,分析了 Eureka 服务端接收注册信息的流程,核心逻辑就是将服务实例的注册信息放到? 从源码分析中,我学到了 Eureka 存储注册表用到的数据结构 ConcurrentHashMap<String, Lease<InstanceInfo>>(),大家可以借鉴下用到项目中。然后又复习了一遍 ConcurrentHashMap原理、可重入读写锁的原理,学习就是不断记忆,不断遗忘的过程,学习源码正好可以复习一波~ |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 8:32:58- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |