# 四、Lars-Reporter Service開發
## 1) 簡介
負責接收各agent對某modid、cmdid下節點的調用狀態的上報。
> 目前`agent`我們還沒有實現,就可以把agent當成一個普通客戶端就可以。
agent會把代理的host節點的狀態上報給Reporter,Reporter負責存儲在Mysql數據庫中。
**業務**:
Reporter服務模型采用了single thread TCP服務器 + 線程池處理請求
* 主線程Reporter負責接收agent請求,并根據請求中攜帶的`modid`和`cmdid`,拼接后進行`murmurHash`(一致性hash),分配到某個線程的MQ上
* Thread 1~N們負責處理請求:把MQ上的請求中的數據同步更新到MySQL數據表
由于agent上報給Reporter的信息是攜帶時間的,且僅作為前臺展示方便查看服務的過載情況,故通信僅有請求沒有響應
于是Reporter服務只要可以高效讀取請求即可,后端寫數據庫的實時性能要求不高。
架構圖如下:

## 2) 數據庫創建
- 表`ServerCallStatus`:
| 字段 | 數據類型 | 是否可以為空 | 主鍵 | 默認 | 附加 | 說明 |
| -------- | ---------- | ------------ | ---- | ---- | ---- | ------------ |
| modid | int(11) | No | 是 | NULL | | 模塊ID |
| modid | int(11) | No | 是 | NULL | | 指令ID |
| ip | int(11) | No | 是 | NULL | | 服務器IP地址 |
| port | int(11) | No | 是 | NULL | | 服務器端口 |
| caller | int(11) | No | 是 | NULL | | 調用者 |
| succ_cnt | int(11) | No | | NULL | | 成功次數 |
| err_cnt | int(11) | No | | NULL | | 失敗次數 |
| ts | bigint(20) | No | | NULL | | 記錄時間 |
| overload | char(1) | No | | NULL | | 是否過載 |
> Lars/base/sql/lars_dns.sql
```sql
DROP TABLE IF EXISTS `ServerCallStatus`;
CREATE TABLE `ServerCallStatus` (
`modid` int(11) NOT NULL,
`cmdid` int(11) NOT NULL,
`ip` int(11) NOT NULL,
`port` int(11) NOT NULL,
`caller` int(11) NOT NULL,
`succ_cnt` int(11) NOT NULL,
`err_cnt` int(11) NOT NULL,
`ts` bigint(20) NOT NULL,
`overload` char(1) NOT NULL,
PRIMARY KEY (`modid`,`cmdid`,`ip`,`port`,`caller`),
KEY `mlb_index` (`modid`,`cmdid`,`ip`,`port`,`caller`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
```
## 3) Proto協議定義
> 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
}
//一個管理的主機的信息
message HostInfo {
int32 ip = 1;
int32 port = 2;
}
//請求lars-dns route信息的消息內容
message GetRouteRequest {
int32 modid = 1;
int32 cmdid = 2;
}
//lars-dns 回復的route信息消息內容
message GetRouteResponse {
int32 modid = 1;
int32 cmdid = 2;
repeated HostInfo host = 3;
}
message HostCallResult {
int32 ip = 1; //主機ip
int32 port = 2; //主機端口
uint32 succ = 3; //調度成功
uint32 err = 4; //調度失敗
bool overload = 5; //是否過載
}
//上報 負載均衡 調度數據 給 lars_reporter 的消息內容
message ReportStatusReq {
int32 modid = 1;
int32 cmdid = 2;
int32 caller = 3;
repeated HostCallResult results = 4;
uint32 ts = 5;
}
```
---
### 關于作者:
作者:`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)

>**原創聲明:未經作者允許請勿轉載, 如果轉載請注明出處**
- 一、Lars系統概述
- 第1章-概述
- 第2章-項目目錄構建
- 二、Reactor模型服務器框架
- 第1章-項目結構與V0.1雛形
- 第2章-內存管理與Buffer封裝
- 第3章-事件觸發EventLoop
- 第4章-鏈接與消息封裝
- 第5章-Client客戶端模型
- 第6章-連接管理及限制
- 第7章-消息業務路由分發機制
- 第8章-鏈接創建/銷毀Hook機制
- 第9章-消息任務隊列與線程池
- 第10章-配置文件讀寫功能
- 第11章-udp服務與客戶端
- 第12章-數據傳輸協議protocol buffer
- 第13章-QPS性能測試
- 第14章-異步消息任務機制
- 第15章-鏈接屬性設置功能
- 三、Lars系統之DNSService
- 第1章-Lars-dns簡介
- 第2章-數據庫創建
- 第3章-項目目錄結構及環境構建
- 第4章-Route結構的定義
- 第5章-獲取Route信息
- 第6章-Route訂閱模式
- 第7章-Backend Thread實時監控
- 四、Lars系統之Report Service
- 第1章-項目概述-數據表及proto3協議定義
- 第2章-獲取report上報數據
- 第3章-存儲線程池及消息隊列
- 五、Lars系統之LoadBalance Agent
- 第1章-項目概述及構建
- 第2章-主模塊業務結構搭建
- 第3章-Report與Dns Client設計與實現
- 第4章-負載均衡模塊基礎設計
- 第5章-負載均衡獲取Host主機信息API
- 第6章-負載均衡上報Host主機信息API
- 第7章-過期窗口清理與過載超時(V0.5)
- 第8章-定期拉取最新路由信息(V0.6)
- 第9章-負載均衡獲取Route信息API(0.7)
- 第10章-API初始化接口(V0.8)
- 第11章-Lars Agent性能測試工具
- 第12章- Lars啟動工具腳本