騰訊雲負載均衡CLB的那些「獨門利器」

歡迎你們前往雲+社區,獲取更多騰訊海量技術實踐乾貨哦~
做者:李想

騰訊人作產品一直是很貼近用戶的需求的,騰訊雲也不例外。負載均衡器做爲公有云上的最基礎的網絡服務,幾乎每家雲廠商都會提供,雖然負載均衡的應用場景和基本功能都大同小異,但在具體的技術實現和特性方面也會有一些差別。今天就聊一聊騰訊雲的負載均衡提供給客戶的那些獨有的特性,你們也能夠了解下騰訊雲負載均衡器的優點所在。git

1.四七層LB自帶客戶端源IP獲取功能

四層負載均衡獲取客戶端源IP幾乎各大雲廠商都支持,對於四層LB來說,網絡包是一個轉發的過程,因此儘管會有隧道封裝基本上這個信息不會丟,技術層面實現不難。github

七層負載均衡通用的作法是作反向代理,相似於Nginx的proxy_pass實現方式,後端服務器收到的網絡包的三層源地址會變成LB的內網地址,而後經過插入X-Forwarded-For HTTP header來傳遞客戶端源IP,微軟Azure包括國內的某些雲廠商都是這種實現方式。算法

騰訊雲的七層負載均衡器不只支持X-Forwarded-For獲取客戶端源IP,同時支持三層直接獲取客戶端源IP,也就是說後端服務器上看到的網絡包的源地址就是客戶的真實訪問地址。後端

下面的截圖顯示的是從後端服務器的抓包,能夠看到X-Forwarded-For記錄的地址是我客戶端的地址180.xxx.219.15,同時數據包的三層源地址也是180.xxx.219.15。跨域

後端服務器抓包

騰訊雲這樣作的好處能夠極大方便客戶來統計客戶端的來源,Nginx或者Apache不用作任何特殊配置,直接經過Access log就能統計出客戶端來源。安全

以Nginx爲例,跑一下"awk '{print $1}' access.log |sort |uniq -c |sort -k1 -nr |head -n10" 就能很容易拿到訪問量前10的IP。下圖中的前兩名的源地址是內部健康檢查用的,因此訪問量較大,能夠忽略。第三名是咱們真實的客戶端訪問,跟上面提到的我這邊測試的客戶端IP一致。bash

訪問量前10的IP

鑑於騰訊雲的實現方式,詳細細節能夠參考社區文章服務器

https://cloud.tencent.com/developer/article/1004723網絡

架構圖以下,簡單說一下,其本質就是L7 Nginx羣集出來的包通過L7.ko內核模塊封裝爲GRE包的時候修改內層源地址仍然爲客戶端的源IP。架構

騰訊雲七層負載均衡實現方式

2.Http/https一鍵強制跳轉

隨着你們對網絡安全的重視,https的網站已經成爲主流,http到https的強制跳轉也成爲許多客戶的基本需求,騰訊雲考慮到這個這個現狀也是提供了一鍵強制轉換的功能。

實現http到https的跳轉自己並不難,最多見的就是利用Nginx的rewrite功能,若是爲了防止LB的HTTPS卸載致使的rewrite循環(後端服務器自己只接受http請求),也能夠配合檢查X-Forwarded-Proto或者X-Client-Proto來判斷源是否爲https來決定是否須要跳轉。

可是這些畢竟仍是須要在後端服務器進行配置,騰訊雲提供了一鍵強制轉換的功能,只需在portal進行簡單配置添加一條自動重定向配置便可,前提是已經配置好了https和http監聽。

一鍵Http/Https跳轉

3.跨地域綁定負載均衡

公網應用型LB支持跨地域綁定雲主機的能力,容許客戶選取後端服務器的地域類型,跨VPC、跨地域綁定後端實例。該功能經過跨域對等鏈接來實現,能夠實現只在一地部署服務器而在不一樣地域部署LB來提高不一樣區域用戶的體驗,實現全球通服的場景。

好比下面的場景,咱們將LB創建在華南,能夠經過修改後端雲主機的的地域爲華東而選擇華東區的服務器。注意該功能目前須要經過工單提早申請才能正常使用。

LB實例詳情

4.支持QUIC協議

QUIC是由Google提出的基於UDP構建的安全多路併發的傳輸層協議,表明了快速UDP Internet鏈接。QUIC經過改進TCP的握手及擁塞算法,重構TLS協議,以及吸取HTTP2的大部分特性可以將弱網絡時的速度提高 20% 以上,很是適合一些遊戲或者流媒體對速度要求比較高的場景。

騰訊雲的解決方案並不須要服務自己支持QUIC協議,CLB會負責處理QUIC協議並轉換成HTTP1.1協議發送給後端應用服務器,服務器對用戶到CLB的QUIC協議並沒有感知。其具體的實現方式以下圖所示:

CLB對QUIC實現方式

附QUIC測試方法:

1. 咱們採用goquic的方案進行測試,因此要提早安裝好GO環境(Centos爲例),這邊再也不贅述,開源項目地址以下

https://github.com/devsisters/goquic

2.獲取項目文件到本地,並安裝GCC,G++

yum -y install gcc
yum -y install gcc-g++
go get -u -d github.com/devsisters/goquic

3.若是沒有配置Ninja,修改build_libs.sh文件

修改前:
cd libquic/$BUILD_DIR
cmake -GNinja $OPT ../..
cd -
ninja -Clibquic/$BUILD_DIR
修改後: 

cd libquic/$BUILD_DIR 
cmake $OPT ../.. 
make -j4

4.編譯靜態庫文件

GOQUIC_BUILD=Release ./build_libs.sh

5.編寫testquic.go文件放入goquic項目目錄下

package main

import (
    "flag"
    "fmt"
    "io/ioutil"
    "net/http"

    "github.com/devsisters/goquic"
    "time"
)

var url string
var logLevel int
var quic bool

func init() {
    flag.StringVar(&url, "url", "http://127.0.0.1:8080/", "host to connect")
    flag.IntVar(&logLevel, "loglevel", -1, "Log level")
    flag.BoolVar(&quic, "QUIC", true, "use QUIC protocol")
}

func main() {
    flag.Parse()
    goquic.SetLogLevel(logLevel)

    client := &http.Client{
        Transport: goquic.NewRoundTripper(false),
    }
    
    var resp *http.Response    
    var err error

    t1 := time.Now()
    if quic == true {
        resp, err = client.Get(url)
    } else {
        resp, err = http.Get(url)
    }
    
    if err != nil {
        panic(err)
    }

    b, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        panic(err)
    }

    fmt.Println("Duration:",time.Now().Sub(t1).Seconds())
    fmt.Println("Body Length:", len(string(b)))
}

6.編譯程序並運行

go build testquic.go
./testquic -url https://www.google.com/ -QUIC=true

相關閱讀


此文已由做者受權雲+社區發佈,轉載請註明原文出處
相關文章
相關標籤/搜索