作者:李想
腾讯人做产品一直是很贴近用户的需求的,腾讯云也不例外。负载均衡器作为公有云上的最基础的网络服务,几乎每家云厂商都会提供,虽然负载均衡的应用场景和基本功能都大同小异,但在具体的技术实现和特性方面也会有一些差异。今天就聊一聊腾讯云的负载均衡提供给客户的那些独有的特性,大家也可以了解下腾讯云负载均衡器的优势所在。
1.四七层LB自带客户端源IP获取功能
四层负载均衡获取客户端源IP几乎各大云厂商都支持,对于四层LB来讲,网络包是一个转发的过程,所以尽管会有隧道封装基本上这个信息不会丢,技术层面实现不难。
七层负载均衡通用的做法是做反向代理,类似于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一致。
鉴于腾讯云的实现方式,详细细节可以参考社区文章
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监听。
3.跨地域绑定负载均衡
公网应用型LB支持跨地域绑定云主机的能力,允许客户选取后端服务器的地域类型,跨VPC、跨地域绑定后端实例。该功能通过跨域对等连接来实现,可以实现只在一地部署服务器而在不同地域部署LB来提升不同区域用户的体验,实现全球通服的场景。
比如下面的场景,我们将LB建立在华南,可以通过修改后端云主机的的地域为华东而选择华东区的服务器。注意该功能目前需要通过工单提前申请才能正常使用。
4.支持QUIC协议
QUIC是由Google提出的基于UDP构建的安全多路并发的传输层协议,代表了快速UDP Internet连接。QUIC通过改进TCP的握手及拥塞算法,重构TLS协议,以及吸收HTTP2的大部分特性能够将弱网络时的速度提升 20% 以上,非常适合一些游戏或者流媒体对速度要求比较高的场景。
腾讯云的解决方案并不需要服务本身支持QUIC协议,CLB会负责处理QUIC协议并转换成HTTP1.1协议发送给后端应用服务器,服务器对用户到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