<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ## 5) 負載均衡模塊基礎設計 ### 5.1 基礎 ? 每個模塊`modid/cmdid`下有若干節點,節點的集合稱為此模塊的路由; 對于每個節點,有兩種狀態: - `idle`:此節點可用,可作為API**(相當于Agent的客戶端)**請求的節點使用; - `overload`:此節點過載,暫時不可作為API請求的節點使用 ? 在請求節點時,有幾個關鍵屬性: - 虛擬成功次數`vsucc`,API匯報節點調用結果是成功時,該值+1 - 虛擬失敗次數`verr`,API匯報節點調用結果是失敗時,該值+1 - 連續成功次數`contin_succ`,連續請求成功的次數 - 連續失敗次數`contin_err`,連續請求失敗的次數 這4個字段,在節點狀態改變時(idle<—>overload),會被重置。 ### 5.2 調度方式 - 圖1 ![](https://img.kancloud.cn/54/84/54840375c2d793a337b4a1530f685a08_1172x571.png) - 圖2 ![](https://img.kancloud.cn/2c/01/2c0136c133e4a007562920411a11f21e_1006x579.png) 如圖所示,整體的調度節點的方式大致如下。這里每個節點就是一個Host主機信息,也就是我們需要被管理的主機信息,一個主機信息應該包括基本的ip和port還有一些其他屬性。 如圖1,API相當于我們的Agent模塊的客戶端,也是業務端調用的請求主機接口。 API發送GetHost請求,發送給Agent的server端,傳遞信息包括modID/cmdID. AgentServer 使用UDPserver處理的API網絡請求,并且交給了某個"負載均衡算法". 如圖2,一個負載均衡算法,我們稱之為是一個"load balance", 一個"load balance"對應針對一組modID/cmdID下掛在的全部host信息進行負載。每個"load balance"都會有兩個節點隊列。一個隊列是"idle_list",存放目前可用的Host主機信息(ip+port), 一個隊列是"overload_list",存放目前已經過載的Host主機信息(ip+port). 當API對某模塊發起節點獲取時: - Load Balance從空閑隊列拿出隊列頭部節點,作為選取的節點返回,同時將此節點重追到隊列尾部; - **probe機制** :如果此模塊過載隊列非空,則每經過`probe_num`次節點獲取后(默認=10),給過載隊列中的節點一個機會,從過載隊列拿出隊列頭部節點,作為選取的節點返回,讓API試探性的用一下,同時將此節點重追到隊列尾部; - 如果空閑隊列為空,說明整個模塊過載了,返回過載錯誤;且也會經過`probe_num`次節點獲取后(默認=10),給過載隊列中的節點一個機會,從過載隊列拿出隊列頭部節點,作為選取的節點返回,讓API試探性的用一下,同時將此節點重追到隊列尾部; > 調度就是:從空閑隊列輪流選擇節點;同時利用probe機制,給過載隊列中節點一些被選擇的機會 ### 5.2 API層與Agent Load Balance的通信協議 > /Lars/base/proto/lars.proto ```protobuf syntax = "proto3"; package lars; /* Lars系統的消息ID */ enum MessageId { ID_UNKNOW = 0; //proto3 enum第一個屬性必須是0,用來占位 ID_GetRouteRequest = 1; //向DNS請求Route對應的關系的消息ID ID_GetRouteResponse = 2; //DNS回復的Route信息的消息ID ID_ReportStatusRequest = 3; //上報host調用狀態信息請求消息ID ID_GetHostRequest = 4; //API 發送請求host信息給 Lb Agent模塊 消息ID ID_GetHostResponse = 5; //agent 回執給 API host信息的 消息ID } enum LarsRetCode { RET_SUCC = 0; RET_OVERLOAD = 1; //超載 RET_SYSTEM_ERROR = 2; //系統錯誤 RET_NOEXIST = 3; //資源不存在 } //... //... // API 請求agent 獲取host信息 (UDP) message GetHostRequest { uint32 seq = 1; int32 modid = 2; int32 cmdid = 3; } // Agent回執API的 host信息 (UDP) message GetHostResponse { uint32 seq = 1; int32 modid = 2; int32 cmdid = 3; int32 retcode = 4; HostInfo host = 5; } ``` 這里主要增加兩個ID:`ID_GetHostRequest`和`ID_GetHostResponse`,即,API的getHost請求的發送ID和回收ID。其中兩個ID對應的message包為`GetHostRequest`和`GetHostResponse`。 ### 5.3 host_info與Load Balance初始化 我們首先應該定義幾個數據結構,分別是 `host_info`:表示一個host主機的信息 `load_balance`:針對一組`modid/cmdid`的負載均衡模塊 `route_lb`:一共3個,和agent的udp server(提供api服務)的數量一致,一個server對應一個route_lb,每個route_lb負責管理多個`load_balance` ![](https://img.kancloud.cn/07/9d/079d375ee3226460c44aa5df3d373fa7_1024x768.png) #### **host_info** > lars_loadbalance_agent/include/host_info.h ```c #pragma once /* * 被代理的主機基本信息 * * */ struct host_info { host_info(uint32_t ip, int port, uint32_t init_vsucc): ip(ip), port(port), vsucc(init_vsucc), verr(0), rsucc(0), rerr(0), contin_succ(0), contin_err(0), overload(false) { //host_info初始化構造函數 } uint32_t ip; //host被代理主機IP int port; //host被代理主機端口 uint32_t vsucc; //虛擬成功次數(API反饋),用于過載(overload),空閑(idle)判定 uint32_t verr; //虛擬失敗個數(API反饋),用于過載(overload),空閑(idle)判定 uint32_t rsucc; //真實成功個數, 給Reporter上報用戶觀察 uint32_t rerr; //真實失敗個數,給Reporter上報用戶觀察 uint32_t contin_succ; //連續成功次數 uint32_t contin_err; //連續失敗次數 bool overload; //是否過載 }; ``` `host_info`包含,最關鍵的主機信息ip+port.除了這個還有一些用戶負載均衡算法判斷的屬性。 #### **load_balance** > lars_loadbalance_agent/include/load_balance.h ```c #pragma once #include <ext/hash_map> #include <list> #include "host_info.h" #include "lars.pb.h" //ip + port為主鍵的 host信息集合 typedef __gnu_cxx::hash_map<uint64_t, host_info*> host_map; // key:uint64(ip+port), value:host_info typedef __gnu_cxx::hash_map<uint64_t, host_info*>::iterator host_map_it; //host_info list集合 typedef std::list<host_info*> host_list; typedef std::list<host_info*>::iterator host_list_it; /* * 負載均衡算法核心模塊 * 針對一組(modid/cmdid)下的全部host節點的負載規則 */ class load_balance { public: load_balance(int modid, int cmdid): _modid(modid), _cmdid(cmdid) { //load_balance 初始化構造 } //判斷是否已經沒有host在當前LB節點中 bool empty() const; //從當前的雙隊列中獲取host信息 int choice_one_host(lars::GetHostResponse &rsp); //如果list中沒有host信息,需要從遠程的DNS Service發送GetRouteHost請求申請 int pull(); //根據dns service遠程返回的結果,更新_host_map void update(lars::GetRouteResponse &rsp); //當前load_balance模塊的狀態 enum STATUS { PULLING, //正在從遠程dns service通過網絡拉取 NEW //正在創建新的load_balance模塊 }; STATUS status; //當前的狀態 private: int _modid; int _cmdid; int _access_cnt; //請求次數,每次請求+1,判斷是否超過probe_num閾值 host_map _host_map; //當前load_balance模塊所管理的全部ip + port為主鍵的 host信息集合 host_list _idle_list; //空閑隊列 host_list _overload_list; //過載隊列 }; ``` 一個`load_balance`擁有兩個host鏈表集合,還有一個以ip/port為主鍵的`_host_map`集合。 **屬性**: `_idle_list`:全部的空閑節點Host集合列表。 `_overload_list`:全部的過載節點Host集合列表。 `_host_map`:當前`load_balance`中全部所管理的ip+port是host總量,是一個`hash_map<uint64_t, host_info*>`類型。 `_modid,_cmdid`:當前`load_balance`所綁定的`modid/cmdid`。 `_access_cnt`:記錄當前`load_balance`被api的請求次數,主要是用戶判斷是否觸發probe機制(從overload_list中嘗試取節點) `status`: 當前`load_balance`所處的狀態。包括`PULLING`,`NEW`. 是當`load_balance`在向遠程`dns service`請求host 的時候,如果正在下載中,則為`PULLING`狀態,如果是增加被創建則為`NEW`狀態。 **方法** `choice_one_host()`:根據負載均衡算法從兩個list中取得一個可用的host信息放在`GetRouteResponse &rsp`中 `pull()`:如果list中沒有host信息,需要從遠程的DNS Service發送GetRouteHost請求申請。 `update()`:根據dns service遠程返回的結果,更新`_host_map` 以上方法我們暫時先聲明,暫不實現,接下來,我們來定義`route_lb`數據結構 #### **route_lb** > /lars_loadbalance_agent/include/route_lb.h ```c #pragma once #include "load_balance.h" //key: modid+cmdid value: load_balance typedef __gnu_cxx::hash_map<uint64_t, load_balance*> route_map; typedef __gnu_cxx::hash_map<uint64_t, load_balance*>::iterator route_map_it; /* * 針對多組modid/cmdid ,route_lb是管理多個load_balanace模塊的 * 目前設計有3個,和udp-server的數量一致,每個route_lb分別根據 * modid/cmdid的值做hash,分管不同的modid/cmdid * * */ class route_lb { public: //構造初始化 route_lb(int id); //agent獲取一個host主機,將返回的主機結果存放在rsp中 int get_host(int modid, int cmdid, lars::GetHostResponse &rsp); //根據Dns Service返回的結果更新自己的route_lb_map int update_host(int modid, int cmdid, lars::GetRouteResponse &rsp); private: route_map _route_lb_map; //當前route_lb下的管理的loadbalance pthread_mutex_t _mutex; int _id; //當前route_lb的ID編號 }; ``` **屬性** `_route_lb_map`: 當前route_lb下的所管理的全部`load_balance`(一個load_balance負責一組modid/cmdid的集群負載)。其中key是modid/cmdid,value則是load_balance對象. `_mutex`:保護`_route_lb_map`的鎖。 `_id`:當前route_lb的id編號,編號從1-3,與udpserver的數量是一致的。一個agent udp server對應一個id。 **方法** `get_host()`:直接處理API業務層發送過來的`ID_GetHostRequest`請求。agent獲取一個host主機,將返回的主機結果存放在rsp中. `update_host()`:這個是`load_balance`觸發`pull()`操作,遠程Dns Service會返回結果,`route_lb`根據Dns Service返回的結果更新自己的`_route_lb_map`. --- ### 關于作者: 作者:`Aceld(劉丹冰)` mail: [danbing.at@gmail.com](mailto:danbing.at@gmail.com) github: [https://github.com/aceld](https://github.com/aceld) 原創書籍: [http://www.hmoore.net/@aceld](http://www.hmoore.net/@aceld) ![](https://img.kancloud.cn/b0/d1/b0d11a21ba62e96aef1c11d5bfff2cf8_227x227.jpg) >**原創聲明:未經作者允許請勿轉載, 如果轉載請注明出處**
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看