欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Go語言實戰(zhàn)之實現(xiàn)均衡器功能

 更新時間:2023年04月12日 11:14:36   作者:小雄Ya  
這篇文章主要為大家詳細介紹了如何利用Golang?實現(xiàn)一個簡單的流浪均衡器,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

前言

當(dāng)我們需要處理成千上萬的的用戶請求時,當(dāng)一臺服務(wù)器可能無法滿足這千萬級別的請求時就可能需要擴容,增加服務(wù)器的數(shù)量來維持響應(yīng)請求。服務(wù)器數(shù)量增多了,那流量如何均衡分配也是一個問題。這時就需要一個負載均衡,進行協(xié)調(diào)可用服務(wù)器之間的流量。

本文主要講述使用 Golang 實現(xiàn)一個簡單的流浪均衡器。

負載均衡

負載均衡器就是一個能夠?qū)φ埱罅髁客ㄟ^算法將請求轉(zhuǎn)發(fā)到相應(yīng)的后端服務(wù)。其基本是在所有后端服務(wù)前置。一個用戶請求過來先經(jīng)過負載均衡器,然后由負載均衡器轉(zhuǎn)發(fā)請求到具體的后端服務(wù)上。所以其功能相對來說其實很簡單:轉(zhuǎn)發(fā)請求。其核心就是,均衡算法然后實現(xiàn)均衡轉(zhuǎn)發(fā)請求。常用的算法有以下幾種:

輪詢算法

輪詢法就是通過順序輪流轉(zhuǎn)發(fā)到后端服務(wù)器上。這種方式是最簡單的,只需要按照順序進行分配,不關(guān)心各服務(wù)負載情況,只需關(guān)心服務(wù)是否可用。如果檢查服務(wù)存活可用則直接轉(zhuǎn)發(fā)到當(dāng)前服務(wù)。

所以這種方法比較適合用在多個服務(wù)器間硬件能力和處理能力都差不多的情況,然后對請求進行拆分均衡的轉(zhuǎn)發(fā)到各服務(wù)上。

簡單實現(xiàn)輪詢例子:

type roundRobin struct {
    targets []*url.URL
    index   int
}

func (rr *roundRobin) nextTarget() *url.URL {
    target := rr.targets[rr.index]
    rr.index = (rr.index + 1) % len(rr.targets)
    return target
}

func (rr *roundRobin) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    target := rr.nextTarget()
    proxy := httputil.NewSingleHostReverseProxy(target)
    proxy.ServeHTTP(w, r)
}

定義了一個名為 roundRobin 的結(jié)構(gòu)體,并實現(xiàn)了一個名為 nextTarget 的方法,該方法返回下一個目標(biāo)服務(wù)器的 URL。在 ServeHTTP 方法中,我們使用 nextTarget 方法獲取下一個目標(biāo)服務(wù)器的 URL,并創(chuàng)建一個反向代理對象來將請求轉(zhuǎn)發(fā)到選定的服務(wù)器。

加權(quán)輪詢算法

加圈輪詢算法是基于輪詢算法的。當(dāng)后端服務(wù)處理能力有差別的時候,比如可能A服務(wù)處理能力強于B服務(wù)2倍,那可以通過加權(quán)方式控制A服務(wù)處理請求多于B服務(wù)。

type serverWeight int

const (
	ServerA serverWeight = 6
	ServerB serverWeight = 3
	ServerC serverWeight = 1
)

比如以上配置表示,每有10個請求就會有6個會轉(zhuǎn)發(fā)到A服務(wù)器,3個轉(zhuǎn)發(fā)到B服務(wù)器,1個轉(zhuǎn)發(fā)到C服務(wù)器。

最少連接數(shù)算法

最小連接數(shù)是轉(zhuǎn)發(fā)依據(jù)始終是按照服務(wù)器當(dāng)前連接數(shù)最小的那個進行轉(zhuǎn)發(fā)。這種方式可以更加有效的利用后端服務(wù),合理的分流到各服務(wù)器。該算法不僅要檢查各服務(wù)是否有效,還需要記錄各服務(wù)已存在的連接數(shù)量。有點像連接池管理。

當(dāng)然最少連接數(shù)算法,也可以對它們增加權(quán)重,即在比較連接數(shù)時同時考慮各服務(wù)的權(quán)重,被選中的服務(wù)器其連接數(shù)與權(quán)重的比要最小才能被選中。

詳細實現(xiàn)

定義結(jié)構(gòu)體

其他的算法,這里就不一一展開說明,想了解可以自己搜索。本文主要實踐使用最少連接算法的負責(zé)均衡器。所以一個均衡器的工作是查找連接數(shù)最少的服務(wù),然后根據(jù)服務(wù)地址轉(zhuǎn)發(fā)出去。當(dāng)然還需要知道當(dāng)前可用服務(wù)是否存活。所以可以先定義一個記錄這些信息的結(jié)構(gòu)體,如服務(wù)請求地址,存活狀態(tài)、連接數(shù)等相關(guān)信息。

type Backend interface {
    GetURL() string
    GetConnections() int
}

type leastConn struct {
    targets []Backend
    mutex   sync.Mutex
}

func (lc *leastConn) leastTarget() Backend {
    var target Backend
    minConns := math.MaxInt32

    for _, t := range lc.targets {
        lc.mutex.Lock()
        conns := t.GetConnections()
        lc.mutex.Unlock()

        if conns < minConns {
            minConns = conns
            target = t
        }
    }
    return target
}

func (lc *leastConn) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    target := lc.leastTarget()
    targetURL := target.GetURL()

    proxy := httputil.NewSingleHostReverseProxy(targetURL)
    proxy.ServeHTTP(w, r)
}

為了避免出現(xiàn)競爭情況,通過增加鎖來控制。RWMutex 適合用于讀多寫少的場景。支持多個 goroutie 可以同時獲取讀鎖,但是寫時僅支持一個 goroutine 占有。reverseProxy 官網(wǎng)的解釋:是一種 Http Handler ,接收請求并發(fā)送到另一臺服務(wù)器中,把響應(yīng)代理回客戶端。所以 ReverseProxy 的作用就是轉(zhuǎn)發(fā)原始的請求。

在上面的代碼中國,我們定義了一個名為 Backend 的接口,并實現(xiàn)了一個名為 leastConn 的結(jié)構(gòu)體。在 leastConn 結(jié)構(gòu)體中,我們使用 Backend 接口代替直接使用 URL 來表示服務(wù)器,這樣我們可以將任何實現(xiàn)了 Backend 接口的服務(wù)器添加到負載均衡器中。

leastTarget 方法中,我們使用 Backend 接口的方法來獲取每個服務(wù)器的當(dāng)前連接數(shù),并選擇連接數(shù)最少的服務(wù)器來處理該請求。

以上就是Go語言實戰(zhàn)之實現(xiàn)均衡器功能的詳細內(nèi)容,更多關(guān)于Go均衡器的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 深入理解go slice結(jié)構(gòu)

    深入理解go slice結(jié)構(gòu)

    這篇文章主要介紹了go slice結(jié)構(gòu),本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2021-09-09
  • Go使用Weighted實現(xiàn)資源管理

    Go使用Weighted實現(xiàn)資源管理

    這篇文章主要介紹了Go?語言中的?Weighted?并發(fā)原語,包括?Weighted?的基本使用方法、實現(xiàn)原理、使用注意事項等內(nèi)容,感興趣的小伙伴可以了解一下
    2023-06-06
  • go語言實現(xiàn)字符串base64編碼的方法

    go語言實現(xiàn)字符串base64編碼的方法

    這篇文章主要介紹了go語言實現(xiàn)字符串base64編碼的方法,實例分析了Go語言操作字符串的技巧及base64編碼的使用技巧,需要的朋友可以參考下
    2015-03-03
  • Golang中Append()使用實例詳解

    Golang中Append()使用實例詳解

    今天在刷leetcode的時候,第113題讓我遇到了一個Go語言中append函數(shù)的一個坑,所以復(fù)習(xí)下,這篇文章主要給大家介紹了關(guān)于Golang中Append()使用的相關(guān)資料,需要的朋友可以參考下
    2023-01-01
  • golang json數(shù)組拼接的實例

    golang json數(shù)組拼接的實例

    這篇文章主要介紹了golang json數(shù)組拼接的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • Go語言小白入門刷題打印輸出沙漏

    Go語言小白入門刷題打印輸出沙漏

    這篇文章主要介紹了Go語言刷題打印輸出沙漏的示例過程詳解,非常適合剛?cè)腴TGo語言的小白學(xué)習(xí),有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2021-11-11
  • Go語言中使用 buffered channel 實現(xiàn)線程安全的 pool

    Go語言中使用 buffered channel 實現(xiàn)線程安全的 pool

    這篇文章主要介紹了Go語言中使用 buffered channel 實現(xiàn)線程安全的 pool,因為Go語言自帶的sync.Pool并不是很好用,所以自己實現(xiàn)了一線程安全的 pool,需要的朋友可以參考下
    2014-10-10
  • 淺談goland導(dǎo)入自定義包時出錯(一招解決問題)

    淺談goland導(dǎo)入自定義包時出錯(一招解決問題)

    這篇文章主要介紹了淺談goland導(dǎo)入自定義包時出錯(一招解決問題),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • 詳解Golang開啟http服務(wù)的三種方式

    詳解Golang開啟http服務(wù)的三種方式

    這篇文章主要介紹了詳解Golang開啟http服務(wù)的三種方式,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • Go語言入門之基礎(chǔ)語法和常用特性解析

    Go語言入門之基礎(chǔ)語法和常用特性解析

    這篇文章主要給大家講解了Go語言的基礎(chǔ)語法和常用特性解析,比較適合入門小白,文中通過代碼示例介紹的非常詳細,對我們學(xué)習(xí)Go語言有一定的幫助,需要的朋友可以參考下
    2023-07-07

最新評論