自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

原來一個 Map 就能搞定注冊表了

開發(fā) 前端
本篇從源碼角度帶你學(xué)習(xí) Eureka 服務(wù)端接收注冊的流程。另外我從源碼中也發(fā)現(xiàn)了一些值得我們學(xué)習(xí)的地方,如 Eureka 存儲注冊表的數(shù)據(jù)結(jié)構(gòu)、利用讀寫鎖來控制更細(xì)粒度的并發(fā)性,提高程序的運行效率。

[[429868]]

本篇從源碼角度帶你學(xué)習(xí) Eureka 服務(wù)端接收注冊的流程。另外我從源碼中也發(fā)現(xiàn)了一些值得我們學(xué)習(xí)的地方,如 Eureka 存儲注冊表的數(shù)據(jù)結(jié)構(gòu)、利用讀寫鎖來控制更細(xì)粒度的并發(fā)性,提高程序的運行效率。

接下來,會從以下幾個方面講解:

客戶端發(fā)送注冊請求。

Eureka 注冊中心接收注冊請求。

服務(wù)端將客戶端注冊信息保存到一個 Map 里面。

關(guān)于源碼的獲取直接到官網(wǎng)下載就好了。https://github.com/Netflix/eureka

本文已收錄到我的 github:https://github.com/Jackson0714/PassJava-Learning

一、注冊入口

上一講我們知道了 Eureka Client 是通過發(fā)送 http 請求來注冊的,那么肯定是有一個地方來接收這個 http 請求的,也就是注冊入口。這是怎么玩的呢?

其實是用到了 jersey 框架,這個框架不用深究,我們只需要知道這個框架在哪引用以及做什么事情的就可以了。

可以把 jersey 類比 mvc 框架,jersey 有 servlet 專門處理 http 請求。引用 jersey 框架的地方:

  1. \eureka\eureka-server\src\main\webapp\WEB-INF\web.xml 

然后處理 HTTP 請求的 controller 在哪呢?

其實是在 eureka-core 項目的 resources 目錄下,里面定義了很多的 Resource 結(jié)尾的類,它們就是用來處理 HTTP 請求的。

  1. \eureka\eureka-core\src\main\java\com\netflix\eureka\resources 

通過XxResource 類的英文注釋我們也可以知道,這個 jersey resource 類是用來處理 HTTP 請求的。

  1. A jersey resource that handles request 

ApplicationsResource

最后找到了 ApplicationResource 類的 addInstance 方法就是我們要找的處理注冊請求的方法。

二、接收注冊請求

整體流程如下:

2.1 接收注冊請求的方法

addInstance 方法里面的核心代碼就是

  1. registry.register(info, true); 

registry 就是 PeerAwareInstanceRegistryImpl 的實例對象。它實現(xiàn)了 PeerAwareInstanceRegistry 接口。

調(diào)用它的 register() 方法后會調(diào)用抽象類 AbstractInstanceRegistry 的 register() 方法,核心代碼就是在這個抽象類的 register() 方法。另外要說下的就是上面的抽象類和接口分別實現(xiàn)和繼承了接口 InstanceRegistry。

接口和類的關(guān)系圖如下:

那么注冊信息會放到哪個里面呢?

三、存放注冊信息的地方

我們看到源碼里面定義了一個 gNewMap,是 ConcurrentHashMap,然后賦值給了 gMap 變量

  1. ConcurrentHashMap<String, Lease<InstanceInfo>> gNewMap  

所以其實是用 gMap 變量來存注冊信息的。我們來分析 gMap 的結(jié)構(gòu)。

首先 gMap 是 ConcurrentHashMap 結(jié)構(gòu),所以就是 key-value 這種鍵值對的。

  • key 就是一個 唯一 id,String 類型。值類似這種:i-00000004
  • value 里面存的是 Lease。
  • Lease是一個類,里面持有一個 instanceInfo 的 holder。這個 instanceInfo 就是注冊過來的服務(wù)實例信息,包含 ip 地址,端口號等。

把服務(wù)實例信息放到 gMap 中也很簡單,調(diào)用 put 方法就可以了。

  1. gMap.put(registrant.getId(), lease); 

下面是我注冊了兩個服務(wù)實例的狀態(tài):

四、值得學(xué)習(xí)的地方

4.1 ConcurrentHashMap?

上面講到 ConcurrentHashMap,為什么不是用 hashmap ?

  1. ConcurrentHashMap<String, Lease<InstanceInfo>>() 

原因:

在并發(fā)編程中使用 HashMap 可能造成死循環(huán) ( JDK 1.7 和 1.8 可能會造成數(shù)據(jù)丟失)

HashTable 效率非常較低。

簡單說下 ConcurrentHashMap 的底層原理是怎么樣的?

ConcurrentHashMap 內(nèi)部細(xì)分了若干個小的 HashMap,稱之為段(Segment)。默認(rèn)情況下一個 ConcurrentHashMap 被進一步細(xì)分為 16 個段,既就是鎖的并發(fā)度。如果需要在 ConcurrentHashMap 中添加一個新的表項,并不是將整個 HashMap 加鎖,而是首先根據(jù) hashcode 得到該表項應(yīng)該存放在哪個段中,然后對該段加鎖,并完成 put 操作。在多線程環(huán)境中,如果多個線程同時進行put操作,只要被加入的表項不存放在同一個段中,則線程間可以做到真正的并行。

4.2 readWriteLock?

我們看到源碼中有用到讀鎖 ReentrantReadWriteLock,如下所示

  1. readWriteLock = new ReentrantReadWriteLock(); 
  2. Lock read = readWriteLock.readLock(); 
  3. read.lock(); 
  4. ... 
  5. read.unlock(); 

4.2.1 為什么分為讀鎖和寫鎖?

原因:

在沒有讀寫鎖之前,假設(shè)使用普通的 ReentrantLock,那么雖然保證了線程安全,但是也浪費了一定的資源,因為如果多個讀操作同時進行,其實并沒有線程安全問題,可以允許讓多個讀操作并行,以便提高程序效率。

但是寫操作不是線程安全的,如果多個線程同時寫,或者在寫的同時進行讀操作,便會造成線程安全問題。

讀寫鎖就解決了這樣的問題,它設(shè)定了一套規(guī)則,既可以保證多個線程同時讀的效率,同時又可以保證有寫入操作時的線程安全。

讀鎖: 允許多個線程獲取讀鎖,同時訪問同一個資源。

讀鎖

寫鎖: 只允許一個線程獲取寫鎖,不允許同時訪問同一個資源。

寫鎖

整體思路:

是它有兩把鎖,第 1 把鎖是寫鎖,獲得寫鎖之后,既可以讀數(shù)據(jù)又可以修改數(shù)據(jù),而第 2 把鎖是讀鎖,獲得讀鎖之后,只能查看數(shù)據(jù),不能修改數(shù)據(jù)。讀鎖可以被多個線程同時持有,所以多個線程可以同時查看數(shù)據(jù)。

在讀的地方合理使用讀鎖,在寫的地方合理使用寫鎖,靈活控制,可以提高程序的執(zhí)行效率。

4.2.2 讀寫鎖的獲取規(guī)則

在使用讀寫鎖時遵守下面的獲取規(guī)則:

  • 如果有一個線程已經(jīng)占用了讀鎖,則此時其他線程如果要申請讀鎖,可以申請成功。
  • 如果有一個線程已經(jīng)占用了讀鎖,則此時其他線程如果要申請寫鎖,則申請寫鎖的線程會一直等待釋放讀鎖,因為讀寫不能同時操作。
  • 如果有一個線程已經(jīng)占用了寫鎖,則此時其他線程如果申請寫鎖或者讀鎖,都必須等待之前的線程釋放寫鎖,同樣也因為讀寫不能同時,并且兩個線程不應(yīng)該同時寫。

讀寫鎖互斥總結(jié):

  • 讀讀共享。
  • 寫寫互斥、讀寫互斥、寫讀互斥。

五、總結(jié)

本篇從源碼的角度,分析了 Eureka 服務(wù)端接收注冊信息的流程,核心邏輯就是將服務(wù)實例的注冊信息放到 ConcurrentHashMap 里面,同時利用讀鎖來控制細(xì)粒度的并發(fā)注冊。另外介紹了下我們不太熟悉的 Jersey 框架,它是用來處理 HTTP 請求的,比如用來處理客戶端注冊的 HTTP 請求。

從源碼分析中,我學(xué)到了 Eureka 存儲注冊表用到的數(shù)據(jù)結(jié)構(gòu) ConcurrentHashMap

本文轉(zhuǎn)載自微信公眾號「悟空聊架構(gòu)」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系悟空聊架構(gòu)公眾號。

 

責(zé)任編輯:武曉燕 來源: 悟空聊架構(gòu)
相關(guān)推薦

2011-08-04 16:37:09

注冊表編輯器注冊表

2025-04-08 01:00:00

Spring開發(fā)系統(tǒng)

2021-11-23 23:01:40

Windows微軟系統(tǒng)

2024-02-19 00:21:45

開源圖片

2009-08-21 09:43:49

C#編輯注冊表

2021-07-02 10:18:51

Windows 11操作系統(tǒng)微軟

2025-03-03 00:00:55

Spring文件下載開發(fā)

2011-04-21 09:10:16

2011-03-17 11:24:15

2011-08-04 16:04:09

注冊表

2022-02-17 08:00:00

容器注冊表云計算開發(fā)

2021-10-11 09:34:55

微軟Windows 11注冊表

2017-08-09 16:24:46

2009-07-03 13:12:59

Windows CE

2011-08-04 16:49:33

注冊表注冊表編輯器

2011-08-04 16:26:20

注冊表編輯器

2011-08-04 09:37:11

注冊表

2011-08-04 15:20:19

注冊表注冊表編輯器

2011-08-05 15:02:17

注冊表Registry To

2010-09-09 17:13:06

點贊
收藏

51CTO技術(shù)棧公眾號