TCP是有狀態的連接,客戶端與服務端進行的是長連接,一旦建立連接,一個客戶端發起的請求,必須落在同一臺tcp的server上,如何做負載均衡呢?


缺點: 會存在dns劫持
通過搭建tcp-server集群來保證高可用,客戶端來實現負載均衡:
client內配置有tcp1/tcp2/tcp3.daojia.com三個tcp-server的外網IP,客戶端通過“隨機”的方式選擇tcp-server,假設選擇到的是tcp1.daojia.com,通過DNS解析tcp1.daojia.com,通過外網IP連接真實的tcp-server
如何保證高可用呢?
如果client發現某個tcp-server連接不上,則選擇另一個。
潛在的缺點?
* 每次連接前,需要多實施一次DNS訪問
* 難以預防DNS劫持
* 多一次DNS訪問意味著更長的連接時間,這個不足在手機端更為明顯
如何解決DNS的問題?
直接將IP配置在客戶端,可以解決上述兩個問題,很多公司也就是這么做的(俗稱“IP直通車”)。
“IP直通車”有什么新問題?
* 將IP寫死在客戶端,在客戶端實施負載均衡,擴展性很差:
* 如果原有IP發生變化,客戶端得不到實時通知
* 如果新增IP,即tcp-sever擴容,客戶端也得不到實時通知
如果負載均衡策略變化,需要升級客戶端
只有將復雜的策略下沉到服務端,才能根本上解決擴展性的問題。
增加一個http接口,將客戶端的“IP配置”與“均衡策略”放到服務端是一個不錯的方案:
client每次訪問tcp-server前,先調用一個新增的get-tcp-ip接口,對于client而言,這個http接口只返回一個tcp-server的IP
這個http接口,實現的是原client的IP均衡策略,拿到tcp-server的IP后,和原來一樣向tcp-server發起TCP長連接
,這樣的話,擴展性問題就解決了:
如果原有IP發生變化,只需要修改get-tcp-ip接口的配置
如果新增IP,也是修改get-tcp-ip接口的配置,如果負載均衡策略變化,需要升級客戶端
然而,新的問題又產生了,如果所有IP放在客戶端,當有一個IP掛掉的時候,client可以再換一個IP連接,保證可用性,而get-tcp-ip接口只是維護靜態的tcp-server集群IP,對于這些IP對應的tcp-server是否可用,是完全不知情的,怎么辦呢?

