Client Server baize 是百度系统部物理网络黑盒监控团队开发的配置驱动网络质量持续监控工具。与 bitflip 的命令行参数模式不同,baize 使用 JSON 配置文件,支持在同一进程中同时运行 Client 和 Server,适合大规模部署和长期运行场景。
百度物理网络内部使用的 baize 工具既支持配置文件,也支持定时拉取数据库节点的配置数据,开源版做了简化,只支持配置文件。同时内部版还会将数据推送到 Kafka 中供聚合程序处理,开源版默认输出到日志中,但已提供了接口可以各种实现。
核心特性:
baize 在百度大规模物理网络中广泛应用于以下场景:
baize 和 bitflip 底层使用相同的 sonar 探测引擎,但面向不同的使用场景:
| 特性 | bitflip | baize |
|---|---|---|
| 配置方式 | 命令行参数 | JSON 配置文件 |
| 进程角色 | 单一角色(client 或 server) | 支持单进程同时运行 client + server |
| 适用场景 | 临时探测、快速排查 | 长期部署、持续监控 |
| 日志管理 | 标准输出 | 按天轮转文件 + 自动清理 |
| pprof | 不支持 | 内置 pprof HTTP 服务 |
| 探测能力 | 丢包 + bitflip 检测 | 相同(共享 sonar 引擎) |
| 退出限制 | 到达 count/duration 自动退出 | ExitOnReachLimit=false,持续运行 |
# 克隆仓库
git clone https://github.com/baidu/nettools.git
cd nettools
# 编译全部工具
make compile
# 或单独编译 baize
go build -o baize ./cmd/baize/
# 本地测试构建 (snapshot)
make snapshot
# 正式发布 (需要 git tag + GITHUB_TOKEN)
git tag v1.0.0
make deploy
dist/ 目录。
| 操作系统 | 架构 | 支持 |
|---|---|---|
| Linux | AMD64 | ✓ |
| Linux | ARM64 | ✓ |
| macOS | AMD64 | ✓ |
| macOS | ARM64 | ✓ |
# 使用示例配置作为起点
cp baize.example.json baize.json
# 编辑配置,填入实际 IP 地址
vim baize.json
# 使用默认配置文件 baize.json
sudo ./baize
# 指定配置文件路径
sudo ./baize -c /etc/baize/baize.json
sudo 权限来设置 IP TOS/DSCP 值。如果仅运行 Server 角色,可能不需要 root 权限。
仅启动 Client:
{
"client": {
"client_addr": "10.0.0.1",
"server_addrs": "10.0.0.2"
}
}
仅启动 Server:
{
"server": {
"server_addr": "10.0.0.2",
"client_addrs": "10.0.0.1"
}
}
同时启动 Client 和 Server(互探模式):
{
"pprof_addr": ":6060",
"log_dir": "/var/log/baize",
"log_max_age_days": 7,
"client": {
"client_addr": "10.0.0.1",
"server_addrs": "10.0.0.2"
},
"server": {
"server_addr": "10.0.0.1",
"client_addrs": "10.0.0.2"
}
}
baize 使用 JSON 格式的配置文件,默认路径为 baize.json,可通过 -c 参数指定。
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
pprof_addr | string | "" | pprof HTTP 服务监听地址(如 :6060),为空则不启动 |
log_dir | string | "" | 日志文件目录,为空则输出到 stderr |
log_max_age_days | int | 7 | 日志文件保留天数(≤0 时默认 7 天) |
client | object | null | Client 角色配置,为 null 则不启动 Client |
server | object | null | Server 角色配置,为 null 则不启动 Server |
client 和 server 至少需要配置一个,否则程序启动后会立即退出。
{
"pprof_addr": ":6060",
"log_dir": "/var/log/baize",
"log_max_age_days": 7,
"client": {
"client_addr": "10.0.0.1",
"server_addrs": "10.0.0.2",
"tos": 64,
"client_port_range": "43500,43599",
"server_port_range": "43600,43609",
"rate_in_span": 5000,
"span": "1s",
"delay": "3s",
"msg_len": 1024,
"count": 0,
"send_duration": "0s",
"verbose": false
},
"server": {
"server_addr": "10.0.0.2",
"client_addrs": "10.0.0.1",
"tos": 64,
"client_port_range": "43500,43599",
"server_port_range": "43600,43609",
"rate_in_span": 5000,
"span": "1s",
"delay": "3s",
"msg_len": 1024,
"verbose": false
}
}
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
client_addr | string | "" | 客户端 IP 地址(本机) |
server_addrs | string | "" | 服务端 IP 地址,多个用逗号分隔 |
tos | int | 0 | IP TOS/DSCP 值 |
client_port_range | string | "" | 客户端源端口范围,格式 min,max |
server_port_range | string | "" | 服务端目的端口范围,格式 min,max |
rate_in_span | int64 | 0 | 每个 span 内的发包速率(pps) |
span | string | "0s" | 统计时间窗口,Go duration 格式(如 1s、5s) |
delay | string | "0s" | 统计处理延迟,等待在途报文(如 3s) |
msg_len | int | 0 | 消息体大小(不含 32 字节头部) |
count | int | 0 | 最大发包数(0 = 不限制) |
send_duration | string | "0s" | 最大发送时长(0 = 不限制) |
verbose | bool | false | 丢包时打印详细端口信息 |
ExitOnReachLimit=false,即使配置了 count 或 send_duration
server_addrs 支持逗号分隔的多个地址,Client 会同时向所有 Server 发送探测报文:
{
"client": {
"client_addr": "10.0.0.1",
"server_addrs": "10.0.0.2,10.0.0.3,10.0.0.4"
}
}
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
server_addr | string | "" | 服务端监听 IP 地址(本机) |
client_addrs | string | "" | 允许的客户端 IP 地址,多个用逗号分隔 |
tos | int | 0 | IP TOS/DSCP 值 |
client_port_range | string | "" | 客户端源端口范围,格式 min,max |
server_port_range | string | "" | 服务端监听端口范围,格式 min,max |
rate_in_span | int64 | 0 | 每个 span 内的发包速率 |
span | string | "0s" | 统计时间窗口 |
delay | string | "0s" | 统计处理延迟 |
msg_len | int | 0 | 消息体大小 |
verbose | bool | false | 丢包时打印详细端口信息 |
client_addrs 用于过滤和识别合法的 Client 报文。多个地址用逗号分隔。
{
"log_dir": "/var/log/baize",
"client": {
"client_addr": "10.0.0.1",
"server_addrs": "10.0.0.2",
"rate_in_span": 5000,
"span": "1s",
"delay": "3s"
}
}
{
"log_dir": "/var/log/baize",
"server": {
"server_addr": "10.0.0.2",
"client_addrs": "10.0.0.1",
"rate_in_span": 5000,
"span": "1s",
"delay": "3s"
}
}
两台机器各自运行 baize,互为 Client 和 Server,实现双向网络质量监控:
# 机器 A (10.0.0.1) 的配置
{
"pprof_addr": ":6060",
"log_dir": "/var/log/baize",
"log_max_age_days": 7,
"client": {
"client_addr": "10.0.0.1",
"server_addrs": "10.0.0.2",
"rate_in_span": 5000,
"span": "1s",
"delay": "3s",
"msg_len": 1024,
"tos": 64
},
"server": {
"server_addr": "10.0.0.1",
"client_addrs": "10.0.0.2",
"rate_in_span": 5000,
"span": "1s",
"delay": "3s",
"msg_len": 1024,
"tos": 64
}
}
{
"client": {
"client_addr": "10.0.0.1",
"server_addrs": "10.0.0.2",
"client_port_range": "43500,43599",
"server_port_range": "43600,43609",
"rate_in_span": 10000,
"span": "1s",
"delay": "3s",
"msg_len": 1024,
"tos": 128
}
}
{
"client": {
"client_addr": "10.0.0.1",
"server_addrs": "10.0.0.2,10.0.0.3,10.0.0.4",
"rate_in_span": 5000,
"span": "1s",
"delay": "3s"
}
}
{
"pprof_addr": ":6060",
"log_dir": "/var/log/baize",
"client": {
"client_addr": "10.0.0.1",
"server_addrs": "10.0.0.2",
"rate_in_span": 5000,
"span": "1s",
"delay": "3s",
"verbose": true
}
}
启动后可通过 pprof 分析运行时状态:
# 查看 goroutine 状态
go tool pprof http://localhost:6060/debug/pprof/goroutine
# 查看 CPU profile
go tool pprof http://localhost:6060/debug/pprof/profile?seconds=30
# 查看内存分配
go tool pprof http://localhost:6060/debug/pprof/heap
当配置了 log_dir 时,baize 会将日志写入文件并自动管理轮转和清理:
/var/log/baize/
├── baize.log # symlink → 指向当天日志
├── baize.log.20260601 # 6月1日日志
├── baize.log.20260602 # 6月2日日志
├── baize.log.20260603 # 6月3日日志
└── baize.log.20260604 # 6月4日日志(当天)
baize.log 始终指向当天日志文件,方便实时查看(tail -f baize.log)。log_max_age_days 的日志文件在轮转时自动删除。{
"log_dir": "/var/log/baize",
"log_max_age_days": 7
}
log_dir 为空,日志输出到 stderr,适合容器化部署中由日志收集器统一采集。
log_max_age_days 设为 0 或负数时,默认保留 7 天。清理仅在日志轮转时触发,不会在运行中频繁检查。
临时探测用 bitflip(命令行参数,开箱即用);长期持续监控用 baize(配置文件驱动,内置日志轮转和 pprof)。
可以。baize 支持在配置文件中同时配置 client 和 server,它们会在同一进程中以独立 goroutine 运行。注意端口范围不能冲突。
是的,baize 不支持热加载配置。修改配置文件后需要重启进程。推荐使用 systemd 等进程管理工具:
sudo systemctl restart baize
发送 SIGINT (Ctrl+C) 或 SIGTERM 信号。程序会取消所有 goroutine 并等待 1 秒让在途报文回来后退出。如果使用 systemd,systemctl stop baize 会发送 SIGTERM。
Client 需要设置 socket 的 IP_TOS 选项来标记 DSCP 值,某些系统需要特权才能设置非默认 TOS。
配置 pprof_addr 后,可通过 Go pprof 工具分析 goroutine、CPU、内存等性能数据。详见"使用示例 - 调试模式"章节。
支持,用逗号分隔。例如 "server_addrs": "10.0.0.2,10.0.0.3"。Client 会向所有列出的 Server 发送探测。
使用 Go 的 time.ParseDuration 格式,如 "1s"、"5s"、"1m"、"1h"。无效格式会被忽略并打印警告日志。
不会。日志按天轮转,超过 log_max_age_days(默认 7 天)的日志会在轮转时自动删除。