# 四、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服务只要可以高效读取请求即可,后端写数据库的实时性能要求不高。
架构图如下:
![](https://img.kancloud.cn/a6/1b/a61b823c490255dc61c5d290fa8cd39f_982x661.png)
## 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)
原创书籍: [https://www.kancloud.cn/@aceld](https://www.kancloud.cn/@aceld)
![](https://img.kancloud.cn/b0/d1/b0d11a21ba62e96aef1c11d5bfff2cf8_227x227.jpg)
>**原创声明:未经作者允许请勿转载, 如果转载请注明出处**
- 一、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启动工具脚本