欧美在线观看视频网站,亚洲熟妇色自偷自拍另类,啪啪伊人网,中文字幕第13亚洲另类,中文成人久久久久影院免费观看 ,精品人妻人人做人人爽,亚洲a视频

一種基于負載均衡器的鏈路復用方法及系統(tǒng)與流程

文檔序號:11959882閱讀:211來源:國知局
一種基于負載均衡器的鏈路復用方法及系統(tǒng)與流程

本發(fā)明涉及網(wǎng)絡領(lǐng)域,尤其涉及一種基于負載均衡器的鏈路復用方法及系統(tǒng)。



背景技術(shù):

負載均衡器可以提供廉價有效透明的方法擴展網(wǎng)絡設(shè)備和服務器的帶寬、增加吞吐量、加強網(wǎng)絡數(shù)據(jù)處理能力、提高網(wǎng)絡的靈活性和可用性。負載均衡器的作用是將數(shù)據(jù)處理分攤到多個操作單元上進行執(zhí)行,如圖1所示,客戶端1~4對服務器的訪問請求先發(fā)給負載均衡器,負載均衡器根據(jù)預定的負載均衡算法將所述訪問請求發(fā)送給相應的服務器(服務器1或服務器2);負載均衡器為每個客戶端建立一條和服務器之間的鏈路,其中,負載均衡器和客戶端之間的前端鏈路,與負載均衡器和后端服務器之間的后端鏈路是一一對應的關(guān)系。

比如Nginx(發(fā)音同engine x)是一款輕量級的Web服務器/反向代理服務器及電子郵件(IMAP/POP3)代理服務器,常被作為負載均衡器使用,并在一個BSD-like協(xié)議下發(fā)行。由俄羅斯的程序設(shè)計師Igor Sysoev所開發(fā),供俄國大型的入口網(wǎng)站及搜索引擎Rambler(俄文:Рамблер)使用。

傳統(tǒng)的負載均衡器和后端服務器之間的鏈路并發(fā)隨著前客戶端數(shù)量的增加而增大,但是普通的服務器不支持高并發(fā)鏈路,存在客戶端數(shù)量達到一定閾值后系統(tǒng)崩潰的風險。



技術(shù)實現(xiàn)要素:

本發(fā)明提供一種基于負載均衡器的鏈路復用方案,能將負載均衡器和后端服務器之間的并發(fā)數(shù)量固定,徹底解決服務器不能支持高并發(fā)的問題。

為了解決上述問題,采用以下技術(shù)方案:

一種基于負載均衡器的鏈路復用方法,包括:

通過前端鏈路接收客戶端發(fā)送的數(shù)據(jù),根據(jù)所述客戶端發(fā)送的數(shù)據(jù)中攜帶的客戶端的標識信息選擇服務器,并在為所選擇的服務器預先配置的N條后端鏈路中,根據(jù)所述客戶端的標識信息選擇一條后端鏈路;N為正整數(shù);所述前端鏈路是所述負載均衡器與客戶端之間的鏈路,所述后端鏈路是所述負載均衡器與服務器之間的鏈路;

將所述客戶端發(fā)送的數(shù)據(jù)通過所選擇的后端鏈路發(fā)送給所選擇的服務器。

可選地,所述客戶端的標識信息包括:所述客戶端的IP地址和所述客戶端的端口;

所述根據(jù)客戶端的標識信息選擇服務器包括:

對所述客戶端的IP地址進行哈希運算,根據(jù)運算結(jié)果選擇服務器;

所述根據(jù)標識信息在為所選擇的服務器預先配置的N條后端鏈路中選擇一條后端鏈路包括:

對所述客戶端的端口進行哈希運算,根據(jù)運算結(jié)果在所選擇的服務器的N條后端鏈路中選擇一條后端鏈路。

可選地,將所述客戶端發(fā)送的數(shù)據(jù)通過所選擇的后端鏈路發(fā)送給所選擇的服務器包括:

將所述客戶端發(fā)送的數(shù)據(jù)加上包頭后得到封裝數(shù)據(jù);所述包頭至少包括所述客戶端的標識信息;將所述封裝數(shù)據(jù)通過所選擇的后端鏈路發(fā)送給所選擇的服務器;

所述方法還包括:

通過后端鏈路接收服務器針對所述封裝數(shù)據(jù)的響應數(shù)據(jù),所述響應數(shù)據(jù)中攜帶所述封裝數(shù)據(jù)的包頭;

將所述響應數(shù)據(jù)去除所述包頭;

根據(jù)所述包頭中的客戶端的標識信息確定所述響應數(shù)據(jù)的目的客戶端, 通過與所述目的客戶端之間的前端鏈路將去除包頭后的響應數(shù)據(jù)發(fā)送給所述目的客戶端。

可選地,接收針對所述封裝數(shù)據(jù)的響應數(shù)據(jù)的后端鏈路,和發(fā)送所述封裝數(shù)據(jù)的后端鏈路為同一條后端鏈路。

可選地,所述的方法還包括:

當和所述目的客戶端之間的前端鏈路忙時,將要發(fā)送給所述目的客戶端的待發(fā)送數(shù)據(jù)先放入該前端鏈路對應的前端應用層緩沖區(qū)中,待所述前端鏈路空閑后讀取所述待發(fā)送數(shù)據(jù),并將所述待發(fā)送數(shù)據(jù)發(fā)送到與所述前端鏈路對應的前端傳輸層緩沖區(qū)中。

可選地,將所述客戶端發(fā)送的數(shù)據(jù)加上包頭后得到封裝數(shù)據(jù)前還包括:

當所述客戶端發(fā)送的數(shù)據(jù)通過前端鏈路到達所述前端鏈路對應的前端傳輸層緩沖區(qū)時,判斷根據(jù)所述客戶端的標識信息選擇的后端鏈路對應的后端應用層緩沖區(qū)是否有剩余空間;當有剩余空間時,比較所述后端應用層緩沖區(qū)的剩余空間和所述前端鏈路對應的前端應用層緩沖區(qū)的剩余空間的大小,取最小值,然后按照所述最小值從所述前端鏈路對應的前端傳輸層緩沖區(qū)中將客戶端發(fā)送的數(shù)據(jù)提取到所述前端鏈路對應的前端應用層緩沖區(qū),再發(fā)送到根據(jù)所述客戶端的標識信息選擇的后端鏈路對應的后端應用層緩沖區(qū)。

一種基于負載均衡器的鏈路復用系統(tǒng),設(shè)置于負載均衡器中,包括:

前端鏈路管理模塊,用于通過前端鏈路接收客戶端發(fā)送的數(shù)據(jù),根據(jù)所述客戶端發(fā)送的數(shù)據(jù)中攜帶的客戶端的標識信息選擇服務器,并在為所選擇的服務器預先配置的N條后端鏈路中,根據(jù)所述客戶端的標識信息選擇一條后端鏈路;N為正整數(shù);所述前端鏈路是所述負載均衡器與客戶端之間的鏈路,所述后端鏈路是所述負載均衡器與服務器之間的鏈路;

后端鏈路管理模塊,用于將所述客戶端發(fā)送的數(shù)據(jù)通過所選擇的后端鏈路發(fā)送給所選擇的服務器。

可選地,所述客戶端的標識信息包括:所述客戶端的IP地址和所述客戶端的端口;

所述前端鏈路管理模塊根據(jù)客戶端的標識信息選擇服務器包括:

所述前端鏈路管理模塊對所述客戶端的IP地址進行哈希運算,根據(jù)運算結(jié)果選擇服務器;

所述前端鏈路管理模塊根據(jù)標識信息在為所選擇的服務器預先配置的N條后端鏈路中選擇一條后端鏈路包括:

所述前端鏈路管理模塊對所述客戶端的端口進行哈希運算,根據(jù)運算結(jié)果在所選擇的服務器的N條后端鏈路中選擇一條后端鏈路。

可選地,所述的系統(tǒng)還包括:

數(shù)據(jù)轉(zhuǎn)換模塊,用于將所述客戶端發(fā)送的數(shù)據(jù)加上包頭后得到封裝數(shù)據(jù);所述包頭至少包括所述客戶端的標識信息;

所述后端鏈路管理模塊將所述客戶端發(fā)送的數(shù)據(jù)通過所選擇的后端鏈路發(fā)送給所選擇的服務器是指:

所述后端鏈路管理模塊將所述數(shù)據(jù)轉(zhuǎn)換模塊得到的封裝數(shù)據(jù)通過所選擇的后端鏈路發(fā)送給所選擇的服務器;

所述后端鏈路管理模塊還用于通過后端鏈路接收服務器針對所述封裝數(shù)據(jù)的響應數(shù)據(jù),所述響應數(shù)據(jù)中攜帶所述封裝數(shù)據(jù)的包頭;

所述數(shù)據(jù)轉(zhuǎn)換模塊還用于將所述響應數(shù)據(jù)去除所述包頭;

所述前端鏈路管理模塊還用于根據(jù)所述包頭中的客戶端的標識信息確定所述響應數(shù)據(jù)的目的客戶端,通過與所述目的客戶端之間的鏈路將去除包頭后的響應數(shù)據(jù)發(fā)送給所述目的客戶端。

可選地,接收針對所述封裝數(shù)據(jù)的響應數(shù)據(jù)的后端鏈路,和發(fā)送所述封裝數(shù)據(jù)的后端鏈路為同一條后端鏈路。

可選地,所述的系統(tǒng)還包括:

數(shù)據(jù)存儲模塊,包括分別對應于每條前端鏈路的前端應用層緩沖區(qū)和前端傳輸層緩沖區(qū);

所述前端鏈路管理模塊還用于當和所述目的客戶端之間的前端鏈路忙時,將要發(fā)送給所述目的客戶端的待發(fā)送數(shù)據(jù)先放入該前端鏈路對應的前端應用層緩沖區(qū)中,待所述前端鏈路空閑后讀取所述待發(fā)送數(shù)據(jù),并將所述待發(fā)送數(shù)據(jù)發(fā)送到與所述前端鏈路對應的前端傳輸層緩沖區(qū)中。

可選地,所述數(shù)據(jù)存儲模塊還包括分別對應于每條后端鏈路的后端應用層緩沖區(qū)和后端傳輸層緩沖區(qū);

所述前端鏈路管理模塊還用于當所述客戶端發(fā)送的數(shù)據(jù)通過前端鏈路到達所述前端鏈路對應的前端傳輸層緩沖區(qū)時,判斷根據(jù)所述客戶端的標識信息選擇的后端鏈路對應的后端應用層緩沖區(qū)是否有剩余空間;當有剩余空間時,比較所述后端應用層緩沖區(qū)的剩余空間和所述前端鏈路對應的前端應用層緩沖區(qū)的剩余空間的大小,取最小值,然后按照所述最小值從所述前端鏈路對應的前端傳輸層緩沖區(qū)中將客戶端發(fā)送的數(shù)據(jù)提取到所述前端鏈路對應的前端應用層緩沖區(qū),再發(fā)送到根據(jù)所述客戶端的標識信息選擇的后端鏈路對應的后端應用層緩沖區(qū);

所述數(shù)據(jù)轉(zhuǎn)換模塊在所述后端應用層緩沖區(qū)中進行所述將客戶端發(fā)送的數(shù)據(jù)加上包頭后得到封裝數(shù)據(jù)的操作。

本發(fā)明通過鏈路復用使后端服務器和負載均衡器之間保持固定的并發(fā)數(shù)量,不會受前端客戶端數(shù)量的增長而線性增長,從而在客戶端高并發(fā)下保證系統(tǒng)的穩(wěn)定性。采用本發(fā)明的方案后,負載均衡器和后端服務器之間的鏈路數(shù)目在上電時已經(jīng)固定,當客戶端和負載均衡器之間鏈接數(shù)目增多時,負載均衡器和后端每個服務器之間的鏈接數(shù)目固定不變。這樣既能控制后端服務器的數(shù)量,又不會讓服務器的接入連接數(shù)隨著前端客戶端鏈接數(shù)目的增多而線性增長。本發(fā)明的方案可以基于nginx實現(xiàn),但不局限于nginx,負載均衡設(shè)備均適用本發(fā)明。

本發(fā)明的其它特征和優(yōu)點將在隨后的說明書中闡述,并且,部分地從說明書中變得顯而易見,或者通過實施本發(fā)明而了解。本發(fā)明的目的和其他優(yōu)點可通過在說明書、權(quán)利要求書以及附圖中所特別指出的結(jié)構(gòu)來實現(xiàn)和獲得。

附圖說明

附圖用來提供對本發(fā)明技術(shù)方案的進一步理解,并且構(gòu)成說明書的一部分,與本申請的實施例一起用于解釋本發(fā)明的技術(shù)方案,并不構(gòu)成對本發(fā)明技術(shù)方案的限制。

圖1為現(xiàn)有技術(shù)中負載均衡器的工作示意圖;

圖2為本發(fā)明實施例一的鏈路復用方法的流程示意圖;

圖3為本發(fā)明實施例一的例子里的工作示意圖;

圖4為本發(fā)明實施例二的鏈路復用系統(tǒng)的示意圖;

圖5為本發(fā)明實施例二的例子的結(jié)構(gòu)示意圖;

圖6為本發(fā)明實施方式一的后端鏈路建立示意圖;

圖7為本發(fā)明實施方式二的流程示意圖;

圖8為本發(fā)明實施方式三的流程示意圖;

圖9為本發(fā)明實施方式四的流程示意圖;

圖10為本發(fā)明實施方式五的數(shù)據(jù)流向示意圖;

圖11為本發(fā)明實施方式六的數(shù)據(jù)流向示意圖;

圖12為本發(fā)明實施方式七的流程示意圖。

具體實施方式

下面將結(jié)合附圖及實施例對本發(fā)明的技術(shù)方案進行更詳細的說明。

需要說明的是,如果不沖突,本發(fā)明實施例以及實施例中的各個特征可以相互結(jié)合,均在本發(fā)明的保護范圍之內(nèi)。另外,雖然在流程圖中示出了邏輯順序,但是在某些情況下,可以以不同于此處的順序執(zhí)行所示出或描述的步驟。

實施例一、一種基于負載均衡器的鏈路復用方法,如圖2所示,包括:

S10、通過前端鏈路接收客戶端發(fā)送的數(shù)據(jù),根據(jù)所述客戶端發(fā)送的數(shù) 據(jù)中攜帶的客戶端的標識信息選擇服務器,并在為所選擇的服務器預先配置的N條后端鏈路中,根據(jù)所述客戶端的標識信息選擇一條后端鏈路;N為正整數(shù);所述前端鏈路是所述負載均衡器與客戶端之間的鏈路,所述后端鏈路是所述負載均衡器與服務器之間的鏈路;

S20、將所述客戶端發(fā)送的數(shù)據(jù)通過所選擇的后端鏈路發(fā)送給所選擇的服務器。

本實施例中,后端鏈路的數(shù)目固定為N,無論負載均衡器所連接的客戶端如何增加,并不會增加負載均衡器和服務器之間的鏈路數(shù)量;每條后端鏈路將用于傳輸一個或多個客戶端的數(shù)據(jù);具體哪條后端鏈路傳輸哪個客戶端的數(shù)據(jù),則可以根據(jù)客戶端的標識信息確定。這樣可以避免客戶端增多時服務器存在高并發(fā)鏈路的問題。

可選地,所述客戶端的標識信息包括:所述客戶端的IP地址和所述客戶端的端口;

所述根據(jù)客戶端的標識信息選擇服務器包括:

對所述客戶端的IP地址進行哈希運算,根據(jù)運算結(jié)果選擇服務器;

所述根據(jù)標識信息在為所選擇的服務器預先配置的N條后端鏈路中選擇一條后端鏈路包括:

對所述客戶端的PORT(端口)進行哈希運算,根據(jù)運算結(jié)果在所選擇的服務器的N條后端鏈路中選擇一條后端鏈路。

通過哈希運算可以根據(jù)客戶端的標識信息唯一確定一個服務器和一條后端鏈路。還可以保存客戶端的標識信息和所選擇的服務器/后端鏈路,這樣在之后收到具有相同標識信息的客戶端發(fā)送的數(shù)據(jù)后,可以不用再次進行哈希運算,而直接通過客戶端的標識信息確定所選擇的服務器/后端鏈路。

在其它可選方案中,也可以預先設(shè)置客戶端的標識信息和服務器/后端鏈路的對應關(guān)系,根據(jù)對應關(guān)系選擇服務器/后端鏈路,比如不同的IP地址范圍對應不同的服務器,不同的IP地址和端口的組合對應不同的后端鏈路。還可以自行設(shè)置通過客戶端的標識信息選擇服務器/后端鏈路的規(guī)則。

可選地,將所述客戶端發(fā)送的數(shù)據(jù)通過所選擇的后端鏈路發(fā)送給所選擇的服務器包括:

將所述客戶端發(fā)送的數(shù)據(jù)加上包頭得到封裝數(shù)據(jù);所述包頭至少包括所述客戶端的標識信息;將所述封裝數(shù)據(jù)通過所選擇的后端鏈路發(fā)送給所選擇的服務器;

所述方法還包括:

通過后端鏈路接收服務器針對所述封裝數(shù)據(jù)的響應數(shù)據(jù),所述響應數(shù)據(jù)中攜帶所述封裝數(shù)據(jù)的包頭;

將所述響應數(shù)據(jù)去除所述包頭;

根據(jù)所述包頭中的客戶端的標識信息確定所述響應數(shù)據(jù)的目的客戶端,通過與所述目的客戶端之間的前端鏈路將去除包頭后的響應數(shù)據(jù)發(fā)送給所述目的客戶端。

可選地,接收針對所述封裝數(shù)據(jù)的響應數(shù)據(jù)的后端鏈路,和發(fā)送所述封裝數(shù)據(jù)的后端鏈路為同一條后端鏈路。

服務器可以在接收到負載均衡器轉(zhuǎn)發(fā)來的、客戶端發(fā)送的數(shù)據(jù)時,將所用的后端鏈路的標識以及所述客戶端的標識信息保存為一條信息;當需要反饋響應消息時,根據(jù)目的客戶端的標識信息找到對應的后端鏈路;這樣就能保證收發(fā)采用的后端鏈路一致。

可選地,所述方法還包括:

當和所述目的客戶端之間的前端鏈路忙時,將要發(fā)送給所述目的客戶端的待發(fā)送數(shù)據(jù)先放入該前端鏈路對應的前端應用層緩沖區(qū)中,待所述前端鏈路空閑后讀取所述待發(fā)送數(shù)據(jù),并將所述待發(fā)送數(shù)據(jù)發(fā)送到與所述前端鏈路對應的前端傳輸層緩沖區(qū)中。

這樣可以保證當一條前端鏈路中傳輸?shù)臄?shù)據(jù)有積壓時,可以先緩沖發(fā)送給客戶端的數(shù)據(jù),而不至于對前端鏈路造成沖擊。

可選地,將所述客戶端發(fā)送的數(shù)據(jù)加上包頭得到封裝數(shù)據(jù)前還包括:

當所述客戶端發(fā)送的數(shù)據(jù)通過前端鏈路到達所述前端鏈路對應的前端 傳輸層緩沖區(qū)時,判斷根據(jù)所述客戶端的標識信息選擇的后端鏈路對應的后端應用層緩沖區(qū)是否有剩余空間;當有剩余空間時,比較所述后端應用層緩沖區(qū)的剩余空間和所述前端鏈路對應的前端應用層緩沖區(qū)的剩余空間的大小,取最小值,然后按照所述最小值從所述前端鏈路對應的前端傳輸層緩沖區(qū)中將客戶端發(fā)送的數(shù)據(jù)提取到所述前端鏈路對應的前端應用層緩沖區(qū),再發(fā)送到根據(jù)所述客戶端的標識信息選擇的后端鏈路對應的后端應用層緩沖區(qū)。

這樣可以保證當一條后端鏈路上的客戶端發(fā)送的數(shù)據(jù)較集中時,可以先緩沖客戶端發(fā)送的數(shù)據(jù),而不至于對后端鏈路造成沖擊。

可選地,所述方法還包括:

當根據(jù)客戶端的標識信息選擇后端鏈路后,將所述客戶端的標識信息及所述后端鏈路的狀態(tài)作為一條信息保存到數(shù)據(jù)庫中;

當與服務器之間的后端鏈路斷開時,在所述數(shù)據(jù)庫中查找與斷開的后端鏈路相關(guān)的信息;所述相關(guān)的信息是指:該信息中的后端鏈路為所述斷開的后端鏈路,將該信息中后端鏈路的狀態(tài)修改為斷開。

下面用一個與linux操作系統(tǒng)結(jié)合的具體例子詳細介紹負載均衡器采用本實施例后的數(shù)據(jù)處理流程。

步驟201,負載均衡器在上電階段,讀取配置信息,確定后端的服務器數(shù)量,以及本負載均衡器啟動多少進程,以及每個進程向后端每個服務器建立的鏈接數(shù)目。

一種可供參考的配置信息如下所示:

worker_processes配置本負載均衡器啟動多少進程;

tcp_limit_conn配置本負載均衡器每個進程在上電階段與后端服務器建立多少鏈接;

limit_proxy_buffer配置每條前端鏈路的前端應用層緩沖區(qū)大小,用于存放前端鏈路收發(fā)的臨時數(shù)據(jù)。

limit_upstream_buffer配置每條后端鏈路的后端應用層緩沖區(qū)大??;

upstream xxxx配置后端服務器組名,大括號內(nèi)的服務器為該服務器組包含哪些后端服務器的信息,這些信息包括后端服務器的IP和PORT;

server段內(nèi)配置了負載均衡器啟動的端口已經(jīng)向后端跳轉(zhuǎn)至哪個服務器組,與upstream組相對應。

步驟202,負載均衡器根據(jù)配置信息向后端服務器建立連接。

步驟203,負載均衡器將與后端服務器建立的socket鏈接的讀寫事件放入linux操作系統(tǒng)的epoll隊列,linux操作系統(tǒng)對該隊列循環(huán)掃描,一旦掃描到有數(shù)據(jù)到達或者數(shù)據(jù)鏈路空閑,即發(fā)信號通知。

步驟204,有客戶端向負載均衡器建鏈,負載均衡器從socket鏈接讀取客戶端的標識信息,并將客戶端的標識信息存放入內(nèi)存數(shù)據(jù)庫,并將客戶端與負載均衡器之間的鏈接事件放入linux的epoll隊列,linux操作系統(tǒng)開始循 環(huán)掃描,一旦掃描到有數(shù)據(jù)到達或者數(shù)據(jù)鏈路空閑,即發(fā)信號通知。

步驟205,客戶端_1向負載均衡器發(fā)送數(shù)據(jù)data_1,客戶端_2和客戶端_3以及客戶端_4向負載均衡器發(fā)送數(shù)據(jù)data_2、data_3和data_4,4個數(shù)據(jù)包假設(shè)按順序到達負載均衡器。

步驟206,負載均衡器將data_1、data_2、data_3、data_4封裝,封裝格式為:鏈路狀態(tài)(2字節(jié))+客戶端的IP地址(4字節(jié))+客戶端的端口(4字節(jié))+會話號(4字節(jié))+數(shù)據(jù)長度(4字節(jié))+data_x(x為1~4),假設(shè)封裝后的數(shù)據(jù)除data_x外的包頭數(shù)據(jù)稱為c_x(x為1~4);其中鏈路狀態(tài)是指負載均衡器與服務器之間的后端鏈路的狀態(tài)。

步驟207,如圖3所示,負載均衡器將c_1+data_1根據(jù)客戶端的IP和PORT進行哈希算法,選擇后端的server_1及一條與server_1之間的后端鏈路,將c_1+data_1發(fā)出,然后按順序?qū)_2+data_2通過一條與server_2之間的后端鏈路發(fā)給后端的server_2,c_3+data_3通過一條與server_1之間的后端鏈路(圖3中和發(fā)c_1+data_1的后端鏈路是同一條,也可以不同)發(fā)給server_1,c_4+data_4通過一條與server_2之間的后端鏈路(圖3中和發(fā)c_2+data_2的后端鏈路是同一條,也可以不同)發(fā)給server_2。算法不局限于哈希算法,要求同一客戶端同一條前端鏈路到達負載均衡器的數(shù)據(jù),能夠固定通過同一條后端鏈路分發(fā)給同一個服務器即可。

步驟208,負載均衡器和后端服務器的socket讀事件被觸發(fā),負載均衡器收到后端server_1發(fā)過來的響應數(shù)據(jù)c_1+response_1。

步驟209,負載均衡器將數(shù)據(jù)去掉包頭,解析出response_1,將response_1發(fā)給客戶端_1。

步驟210,假設(shè)負載均衡器收到后端server_1的響應數(shù)據(jù)為c_1+response_1和c_3+response_3,負載均衡器將response_1發(fā)給客戶端_1,將response_3發(fā)給客戶端_3。

步驟211,假設(shè)負載均衡器收到后端server_1的響應數(shù)據(jù)為c_1+response_1和c_3+response_3,并且客戶端_1和負載均衡器之間的前端鏈路正繁忙,則負載均衡器將c_1+response_1存放入相應前端鏈路的前端應 用層緩沖區(qū),等客戶端_1和負載均衡器之間的前端鏈路空閑時,將c_1+response_1取出,發(fā)給客戶端_1。

實施例二、一種基于負載均衡器的鏈路復用系統(tǒng)(后文簡稱為本系統(tǒng)),如圖4所示,包括:

前端鏈路管理模塊21,用于通過前端鏈路接收客戶端發(fā)送的數(shù)據(jù),根據(jù)所述客戶端發(fā)送的數(shù)據(jù)中攜帶的客戶端的標識信息選擇服務器,并在為所選擇的服務器預先配置的N條后端鏈路中,根據(jù)所述客戶端的標識信息選擇一條后端鏈路;N為正整數(shù);所述前端鏈路是所述負載均衡器與客戶端之間的鏈路,所述后端鏈路是所述負載均衡器與服務器之間的鏈路;

后端鏈路管理模塊22,用于將所述客戶端發(fā)送的數(shù)據(jù)通過所選擇的后端鏈路發(fā)送給所選擇的服務器。

可選地,所述客戶端的標識信息包括:所述客戶端的IP地址和所述客戶端的端口;

所述前端鏈路管理模塊根據(jù)客戶端的標識信息選擇服務器包括:

所述前端鏈路管理模塊對所述客戶端的IP地址進行哈希運算,根據(jù)運算結(jié)果選擇服務器;

所述前端鏈路管理模塊根據(jù)標識信息在為所選擇的服務器預先配置的N條后端鏈路中選擇一條后端鏈路包括:

所述前端鏈路管理模塊對所述客戶端的端口進行哈希運算,根據(jù)運算結(jié)果在所選擇的服務器的N條后端鏈路中選擇一條后端鏈路。

可選地,所述系統(tǒng)還包括:

數(shù)據(jù)轉(zhuǎn)換模塊,用于將所述客戶端發(fā)送的數(shù)據(jù)加上包頭后得到封裝數(shù)據(jù);所述包頭至少包括所述客戶端的標識信息;

所述后端鏈路管理模塊將所述客戶端發(fā)送的數(shù)據(jù)通過所選擇的后端鏈路發(fā)送給所選擇的服務器是指:

所述后端鏈路管理模塊將所述數(shù)據(jù)轉(zhuǎn)換模塊得到的封裝數(shù)據(jù)通過所選 擇的后端鏈路發(fā)送給所選擇的服務器;

所述后端鏈路管理模塊還用于通過后端鏈路接收服務器針對所述封裝數(shù)據(jù)的響應數(shù)據(jù),所述響應數(shù)據(jù)中攜帶所述封裝數(shù)據(jù)的包頭;

所述數(shù)據(jù)轉(zhuǎn)換模塊還用于將所述響應數(shù)據(jù)去除所述包頭;

所述前端鏈路管理模塊還用于根據(jù)所述包頭中的客戶端的標識信息確定所述響應數(shù)據(jù)的目的客戶端,通過與所述目的客戶端之間的鏈路將去除包頭后的響應數(shù)據(jù)發(fā)送給所述目的客戶端。

可選地,所述后端鏈路管理模塊接收針對所述封裝數(shù)據(jù)的響應數(shù)據(jù)的后端鏈路,和發(fā)送所述封裝數(shù)據(jù)的后端鏈路為同一條后端鏈路。

可選地,所述系統(tǒng)還包括:

數(shù)據(jù)存儲模塊,包括分別對應于每條前端鏈路的前端應用層緩沖區(qū)和前端傳輸層緩沖區(qū);

所述前端鏈路管理模塊還用于當和所述目的客戶端之間的前端鏈路忙時,將要發(fā)送給所述目的客戶端的待發(fā)送數(shù)據(jù)先放入該前端鏈路對應的前端應用層緩沖區(qū)中,待所述前端鏈路空閑后讀取所述待發(fā)送數(shù)據(jù),并將所述待發(fā)送數(shù)據(jù)發(fā)送到與所述前端鏈路對應的前端傳輸層緩沖區(qū)中。

可選地,所述數(shù)據(jù)存儲模塊還包括分別對應于每條后端鏈路的后端應用層緩沖區(qū)和后端傳輸層緩沖區(qū);

所述前端鏈路管理模塊還用于當所述客戶端發(fā)送的數(shù)據(jù)通過前端鏈路到達所述前端鏈路對應的前端傳輸層緩沖區(qū)時,判斷根據(jù)所述客戶端的標識信息選擇的后端鏈路對應的后端應用層緩沖區(qū)是否有剩余空間;當有剩余空間時,比較所述后端應用層緩沖區(qū)的剩余空間和所述前端鏈路對應的前端應用層緩沖區(qū)的剩余空間的大小,取最小值,然后按照所述最小值從所述前端鏈路對應的前端傳輸層緩沖區(qū)中將客戶端發(fā)送的數(shù)據(jù)提取到所述前端鏈路對應的前端應用層緩沖區(qū),再發(fā)送到根據(jù)所述客戶端的標識信息選擇的后端鏈路對應的后端應用層緩沖區(qū);

所述數(shù)據(jù)轉(zhuǎn)換模塊在所述后端應用層緩沖區(qū)中進行所述將客戶端發(fā)送 的數(shù)據(jù)加上包頭后得到封裝數(shù)據(jù)的操作。

可選地,所述前端鏈路管理模塊還用于當根據(jù)客戶端的標識信息選擇后端鏈路后,將所述客戶端的標識信息及所述后端鏈路的狀態(tài)作為一條信息保存到數(shù)據(jù)庫中;當與服務器之間的后端鏈路斷開時,在所述數(shù)據(jù)庫中查找與斷開的后端鏈路相關(guān)的信息;所述相關(guān)的信息是指:該信息中的后端鏈路為所述斷開的后端鏈路,將該信息中后端鏈路的狀態(tài)修改為斷開。

一個具體例子如圖5所示,包括5個模塊:配置模塊、前端鏈路管理模塊、數(shù)據(jù)轉(zhuǎn)換模塊、后端鏈路管理模塊和數(shù)據(jù)存儲模塊。

配置模塊負責在上電初始化的時候,將配置信息讀入內(nèi)存,參考步驟201;

前端鏈路管理模塊功能有五個:

負責將新接入的前端鏈路的客戶端的標識信息讀入內(nèi)存數(shù)據(jù)庫(本方案采用的內(nèi)存數(shù)據(jù)庫為紅黑樹),并且向后端的服務器發(fā)送建鏈通知,即發(fā)送一個16字節(jié)的包頭,參考步驟206,第一個鏈路狀態(tài)設(shè)置為約定的0x01,此時data_len字段填0。

負責將收到的客戶端發(fā)送的數(shù)據(jù)傳入數(shù)據(jù)轉(zhuǎn)換模塊處理,如果數(shù)據(jù)轉(zhuǎn)換模塊處理有積壓(即:前端鏈路對應的前端傳輸層緩沖區(qū)已滿),則等待數(shù)據(jù)轉(zhuǎn)換模塊,暫停接收客戶端發(fā)送的數(shù)據(jù)。

客戶端和本系統(tǒng)之間斷開前端鏈路時,負責發(fā)送前端鏈路斷開通知給后端服務器,前端鏈路狀態(tài)對應的狀態(tài)碼為0x03,前端鏈路斷開通知也是16字節(jié)。

客戶端和本系統(tǒng)之間長時間沒有數(shù)據(jù)收發(fā)動作,則發(fā)送前端鏈路狀態(tài)通知給后端服務器,前端鏈路狀態(tài)對應的狀態(tài)碼為0x03,同時斷開此客戶端和本系統(tǒng)之間的前端鏈路。

收到數(shù)據(jù)轉(zhuǎn)換模塊轉(zhuǎn)發(fā)的后端服務器的響應數(shù)據(jù)時,將該響應數(shù)據(jù)發(fā)送給相應的客戶端。

數(shù)據(jù)轉(zhuǎn)換模塊功能主要是負責將前端鏈路管理模塊傳入的數(shù)據(jù)封裝成 c_x+data_x的格式,c_x的內(nèi)容參考步驟206,封裝完畢,則將封裝后的數(shù)據(jù)傳入后端鏈路管理模塊。還負責去除響應數(shù)據(jù)中的包頭c_x后發(fā)送給前端鏈路管理模塊。

后端鏈路管理模塊的功能有四個:

負責將數(shù)據(jù)轉(zhuǎn)換模塊傳入的封裝數(shù)據(jù)向后端的服務器發(fā)送,并負責從后端的服務器接收返回的響應數(shù)據(jù),轉(zhuǎn)發(fā)給數(shù)據(jù)轉(zhuǎn)換模塊。

當后端的服務器和本系統(tǒng)之間的后端鏈路斷開并且重連失敗時要通知前端鏈路管理模塊,由前端鏈路管理模塊將內(nèi)存數(shù)據(jù)庫中的選擇此后端鏈路的客戶端的標識信息都刪除;當原本選擇該后端鏈路的客戶端再發(fā)送數(shù)據(jù)時,前端鏈路管理模塊根據(jù)客戶端的標識信息重新選擇一條后端鏈路。

對后端的服務器的狀態(tài)進行定時監(jiān)控,當后端的服務器和本系統(tǒng)之間的后端鏈路斷開時負責重連,保持后端鏈路的數(shù)目和配置信息一致。

后端的服務器的響應數(shù)據(jù)接收過快,前端鏈路管理模塊處理不及時(即:前端傳輸層緩沖區(qū)已滿)時,負責將數(shù)據(jù)存入數(shù)據(jù)存儲模塊。

數(shù)據(jù)存儲模塊主要負責存儲前端發(fā)送不及時的積壓數(shù)據(jù),數(shù)據(jù)存放入環(huán)形鏈表,當前端鏈路空閑時從鏈表頭按順序發(fā)送。

實施方式一,主要是上電初始化階段以及和服務器建立鏈路階段的實施方式。具體包括如下步驟:

步驟401,本系統(tǒng)上電初始化階段,配置為:

worker_processes 2;

tcp_limit_conn 2;

本系統(tǒng)開啟兩個進程:工作進程1和工作進程2。

步驟402,工作進程1向服務器_1建立兩條鏈路,每條鏈路的信息存入內(nèi)存,并將于后端服務器的鏈路事件加入epoll隊列監(jiān)控。

步驟403,工作進程1向服務器_2建立兩條鏈路,每條鏈路的信息存入內(nèi)存,并將于后端服務器的鏈路事件加入epoll隊列監(jiān)控。

步驟404,工作進程2向服務器_1建立兩條鏈路,每條鏈路的信息存入內(nèi)存,并將于后端服務器的鏈路事件加入epoll隊列監(jiān)控。

步驟405,工作進程2向服務器_2建立兩條鏈路,每條鏈路的信息存入內(nèi)存,并將于后端服務器的鏈路事件加入epoll隊列監(jiān)控。

執(zhí)行完上述步驟后,負載均衡器和服務器_1以及服務器_2之間建立的后端鏈路如圖6所示,工作進程1和服務器_1以及服務器_2之間各有兩條后端鏈路,工作進程2和服務器_1以及服務器_2之間也各有兩條后端鏈路。

步驟402~405不分先后且可以并行;其中,工作進程1和2都采用實施例一的方法進行工作,可采用一個或多個工作進程來執(zhí)行實施例一的方法;可以將每個工作進程看成一個實施例二中的鏈路復用系統(tǒng),一個負載均衡器中可以包括一個或多個實施例二所述的鏈路復用系統(tǒng)。

圖7為本發(fā)明實施方式二,主要是數(shù)據(jù)上行的流程。具體包括如下步驟501~509:

配置如上述步驟201。

步驟501,本系統(tǒng)偵聽端口8034,并采用epoll監(jiān)控該偵聽端口。

步驟502,客戶端向本系統(tǒng)偵聽的8034端口三次握手建立TCP鏈接,本系統(tǒng)將新建鏈接事件進入前端鏈路管理模塊開始處理。

步驟503,前端鏈路管理模塊從socket鏈路信息中獲取客戶端的標識信息,根據(jù)客戶端的標識信息中的IP和PORT進行哈希,哈希算法如下:

根據(jù)IP哈希到服務器,根據(jù)PORT哈希到此服務器的具體后端鏈路。根據(jù)哈希的結(jié)果選擇要發(fā)送的目的服務器和此服務器的某一條后端鏈路。本發(fā)明不限于采用哈希算法來選擇服務器和后端鏈路。

步驟504,前端鏈路管理模塊將該客戶端的信息存入內(nèi)存數(shù)據(jù)庫(可以但不限于采用紅黑樹數(shù)據(jù)庫),存入的信息包括:客戶端鏈路會話標識、客戶端IP地址、客戶端端口等。

步驟505,前端鏈路管理模塊發(fā)送建鏈通知給相應的后端服務器,建鏈 通知格式參考步驟206。

步驟506,前端鏈路管理模塊將客戶端和本系統(tǒng)新建立的鏈接的socket讀事件用epoll開始監(jiān)控。

步驟507,客戶端向本系統(tǒng)發(fā)送數(shù)據(jù)data_1,前端鏈路管理模塊接收數(shù)據(jù)。

步驟508,前端鏈路管理模塊將數(shù)據(jù)data_1送入數(shù)據(jù)轉(zhuǎn)換模塊處理。數(shù)據(jù)轉(zhuǎn)換模塊給data_1封裝一個包頭,包頭的格式參考步驟206。

步驟509,數(shù)據(jù)轉(zhuǎn)換模塊將封裝后的數(shù)據(jù)包送入后端鏈路管理模塊處理。后端鏈路管理模塊將數(shù)據(jù)轉(zhuǎn)換模塊傳入的數(shù)據(jù)包通過步驟503中哈希到的相應后端鏈路發(fā)給相應的后端服務器。

圖8為實施方式三,主要是數(shù)據(jù)下行并且與客戶端之間的前端鏈路不繁忙的流程。具體包括如下步驟601~605:

步驟601,后端鏈路管理模塊收到后端服務器的響應數(shù)據(jù)。

步驟602,后端鏈路管理模塊判斷是否為完整的響應數(shù)據(jù)。判斷是否為完整的響應數(shù)據(jù)的方法為查看數(shù)據(jù)包頭中的“數(shù)據(jù)長度字段”后面的數(shù)據(jù)長度是否達到“數(shù)據(jù)長度字段”。如果響應數(shù)據(jù)完整,則轉(zhuǎn)交給數(shù)據(jù)轉(zhuǎn)換模塊開始解析,去掉包頭;如果響應數(shù)據(jù)不完整,則等待后續(xù)剩余數(shù)據(jù)。

步驟603,數(shù)據(jù)轉(zhuǎn)換模塊將解析后的響應數(shù)據(jù)傳入前端鏈路管理模塊,前端鏈路管理模塊從內(nèi)存數(shù)據(jù)庫中讀出響應數(shù)據(jù)的目的客戶端的標識信息。

步驟604,本系統(tǒng)執(zhí)行發(fā)送數(shù)據(jù)操作,將應用層的數(shù)據(jù)復制到傳輸層。

步驟605,前端鏈路管理模塊將傳輸層的數(shù)據(jù)發(fā)送至目的客戶端。

圖9為實施方式三,主要是數(shù)據(jù)下行并且客戶端鏈路繁忙的流程。具體包括如下步驟701~706:

步驟701,后端鏈路管理模塊收到后端服務器的響應數(shù)據(jù)。

步驟702,后端鏈路管理模塊判斷是否為完整的響應數(shù)據(jù)。判斷是否為完整的響應數(shù)據(jù)的方法為查看數(shù)據(jù)包頭中的“數(shù)據(jù)長度單字段”后面的數(shù)據(jù)長度是否達到“數(shù)據(jù)長度字段”。如果響應數(shù)據(jù)完整,則轉(zhuǎn)交給數(shù)據(jù)轉(zhuǎn)換模塊開始解析,去掉包頭;如果響應數(shù)據(jù)不完整,則等待后續(xù)剩余數(shù)據(jù)。

步驟703,數(shù)據(jù)轉(zhuǎn)換模塊將解析后的響應數(shù)據(jù)傳入前端鏈路管理模塊,前端鏈路管理模塊從內(nèi)存數(shù)據(jù)庫中讀出響應數(shù)據(jù)的目的客戶端的標識信息。

步驟704,前端鏈路管理模塊執(zhí)行發(fā)送數(shù)據(jù)操作,一但本系統(tǒng)和客戶端之間的前端鏈路出現(xiàn)擁塞繁忙導致發(fā)送失敗,則將待發(fā)送的數(shù)據(jù)保存到數(shù)據(jù)存儲模塊,并等待。

步驟705,當本系統(tǒng)和客戶端之間的前端鏈路由擁塞變?yōu)榭臻e,則linux操作系統(tǒng)發(fā)信號通知本系統(tǒng),前端鏈路管理模塊從數(shù)據(jù)存儲模塊取出所述待發(fā)送的數(shù)據(jù)執(zhí)行發(fā)送操作。

步驟706,前端鏈路管理模塊發(fā)送所述待發(fā)送的數(shù)據(jù)至客戶端。

實施方式五主要是數(shù)據(jù)上行流程中鏈路的數(shù)據(jù)管理方式。具體包括如下步驟:

步驟801,客戶端的數(shù)據(jù)到達本系統(tǒng)所在機器的前端傳輸層緩沖區(qū),先檢測下本系統(tǒng)與后端服務器之間相應后端鏈路的后端應用層緩沖區(qū)中有多少剩余空間,如果沒有剩余空間,加入定時器,下次再次檢測;同時客戶端的數(shù)據(jù)再次到達本系統(tǒng),會再次檢測本系統(tǒng)與后端服務器之間相應后端鏈路的后端應用層緩沖區(qū)中有多少剩余空間。

步驟802,如果本系統(tǒng)與后端服務器之間相應后端鏈路的后端應用層緩沖區(qū)中有剩余空間,比較剩余空間和本系統(tǒng)與前端客戶端之間前端鏈路的前端應用層緩沖區(qū)剩余空間的大小,取最小值,然后從前端傳輸層緩沖區(qū)中將客戶端發(fā)送的數(shù)據(jù)提取到本系統(tǒng)與前端客戶端之間前端鏈路的前端應用層緩沖區(qū)。

步驟803,將前端客戶端與本系統(tǒng)之間前端鏈路的前端應用層緩沖區(qū)中的數(shù)據(jù)推送到本系統(tǒng)與后端服務器之間的后端鏈路的后端應用層緩沖區(qū)。

步驟804,在本系統(tǒng)與后端服務器之間的后端鏈路的后端應用層緩沖區(qū)中完成16字節(jié)頭的添加。

步驟805,將本系統(tǒng)與后端服務器之間的后端鏈路的后端應用層緩沖區(qū)中的數(shù)據(jù)推送到本系統(tǒng)和后端服務器之間后端鏈路的后端傳輸層緩沖區(qū)。完成上行流程的鏈路的數(shù)據(jù)管理。

各緩沖區(qū)之間的數(shù)據(jù)流向如圖10所示。

實施方式六主要是數(shù)據(jù)下行流程中鏈路的數(shù)據(jù)管理方式。具體包括如下步驟:

步驟901,后端服務器的數(shù)據(jù)到達本系統(tǒng)所在機器的后端傳輸層數(shù)據(jù)流緩沖區(qū)。

步驟902,將本系統(tǒng)與后端服務器之間后端鏈路的后端傳輸層緩沖區(qū)中的數(shù)據(jù)提取到本系統(tǒng)與后端服務器之間后端鏈路的后端應用層緩沖區(qū)。

步驟903,假設(shè)某個客戶端和本系統(tǒng)之間出現(xiàn)前端鏈路忙會導致數(shù)據(jù)阻塞,為了解決這個問題,為每個客戶端都設(shè)置一個數(shù)據(jù)存儲鏈(保存在數(shù)據(jù)存儲模塊中),將本系統(tǒng)與后端的服務器之間后端鏈路對應的后端應用層層緩沖區(qū)中的響應數(shù)據(jù)按客戶端分段解析,解析出的數(shù)據(jù)放在所述響應數(shù)據(jù)的目的客戶端的存儲鏈上,為了保證時序,將解析出的數(shù)據(jù)存放在數(shù)據(jù)存儲鏈的鏈尾;所述數(shù)據(jù)存儲鏈位于本系統(tǒng)的前端應用層緩沖區(qū)中。

步驟904,每解析一次發(fā)送某個客戶端的響應數(shù)據(jù),都遍歷一下該客戶端的數(shù)據(jù)存儲鏈,從鏈表的頭開始取數(shù)據(jù),然后在鏈路空閑時(即傳輸層緩沖區(qū)未滿的情況下)發(fā)送到本系統(tǒng)和該客戶端之間的前端鏈路對應的前端傳輸層緩沖區(qū)。完成數(shù)據(jù)下行的鏈路的數(shù)據(jù)管理。

各緩沖區(qū)之間的數(shù)據(jù)流向如圖11所示。

圖12為實施方式七,以具體的一個業(yè)務場景來描述本發(fā)明。此業(yè)務場景是手機用戶需要備份和下載短信聊天記錄,數(shù)據(jù)以IMAP協(xié)議傳輸,由于 手機用戶群龐大,一般的IMAP協(xié)議服務器滿足不了高并發(fā)的需求,則需要用到本專利提出的解決方案。具體包括如下步驟1001~1012:

步驟1001,手機用戶在手機上執(zhí)行短信聊天記錄的備份操作。

步驟1002,短信聊天記錄備份后以IMAP協(xié)議格式發(fā)送至本系統(tǒng)。

步驟1003,本系統(tǒng)將IMAP協(xié)議格式封裝一個16字節(jié)的header。

步驟1004,本系統(tǒng)根據(jù)上述鏈路復用方法選擇一條后端鏈路。

步驟1005,本系統(tǒng)將封裝后的數(shù)據(jù)發(fā)送至后端server的代理適配器。

步驟1006,后端服務器的代理適配器將數(shù)據(jù)解析,解析出純IMAP協(xié)議數(shù)據(jù)。

步驟1007,后端服務器的代理適配器將純的IMAP協(xié)議數(shù)據(jù)交由IMAP協(xié)議服務器處理。

步驟1008,IMAP協(xié)議服務器返回一個響應給后端服務器代理適配器,告知此次操作的結(jié)果。

步驟1009,后端服務器的代理適配器將操作結(jié)果封裝一個16字節(jié)的header并原鏈路返回給本系統(tǒng)。

步驟1010,本系統(tǒng)解析出純的IMAP協(xié)議響應。

步驟1011,本系統(tǒng)將純的IMAP協(xié)議響應發(fā)送至手機客戶端。

步驟1012,手機客戶端上顯示此次備份聊天記錄的操作結(jié)果。

手機客戶端下載聊天記錄的流程和備份聊天記錄的流程相似,不同的是前者是從后端IMAP協(xié)議服務器下載數(shù)據(jù),后者是向IMAP協(xié)議服務器上傳數(shù)據(jù)。

實施方式七是以IMAP協(xié)議舉例說明應用場景,本發(fā)明不局限于IMAP協(xié)議,所有的TCP協(xié)議均適用本發(fā)明,包括但不限于POP、SIP、MGCP、HTTP等協(xié)議。

本領(lǐng)域普通技術(shù)人員可以理解上述方法中的全部或部分步驟可通過程 序來指令相關(guān)硬件完成,所述程序可以存儲于計算機可讀存儲介質(zhì)中,如只讀存儲器、磁盤或光盤等??蛇x地,上述實施例的全部或部分步驟也可以使用一個或多個集成電路來實現(xiàn)。相應地,上述實施例中的各模塊/單元可以采用硬件的形式實現(xiàn),也可以采用軟件功能模塊的形式實現(xiàn)。本發(fā)明不限制于任何特定形式的硬件和軟件的結(jié)合。

雖然本發(fā)明所揭露的實施方式如上,但所述的內(nèi)容僅為便于理解本發(fā)明而采用的實施方式,并非用以限定本發(fā)明。任何本發(fā)明所屬領(lǐng)域內(nèi)的技術(shù)人員,在不脫離本發(fā)明所揭露的精神和范圍的前提下,可以在實施的形式及細節(jié)上進行任何的修改與變化,但本發(fā)明的專利保護范圍,仍須以所附的權(quán)利要求書所界定的范圍為準。

當前第1頁1 2 3 
網(wǎng)友詢問留言 已有0條留言
  • 還沒有人留言評論。精彩留言會獲得點贊!
1
广西| 达孜县| 明溪县| 桑日县| 卢氏县| 建昌县| 鹤庆县| 芦溪县| 普定县| 博客| 会宁县| 峨眉山市| 阳城县| 丰宁| 城固县| 利川市| 华坪县| 缙云县| 霍林郭勒市| 潍坊市| 南宫市| 台前县| 松桃| 北安市| 宜昌市| 石家庄市| 开远市| 布拖县| 康定县| 平昌县| 西安市| 孝义市| 兴和县| 平乡县| 兴业县| 牙克石市| 五指山市| 中阳县| 通榆县| 安陆市| 安陆市|