LinkAgg - 508364/NetLeaf GitHub Wiki

LinkAgg 模块

概述

⚠️ Beta 版本

LinkAgg(Link Aggregation)模块提供同端口链路聚合功能,支持单端口监听并将请求转发到多个后端服务器。


版本状态

状态 说明
版本 v2.2.1-beta
稳定性 Beta - 功能完整,但可能存在未发现的问题
建议 生产环境使用前请充分测试

功能限制

后端数量限制

限制项 值 说明
最大后端数量 512 索引范围:0-511
后端索引 0 ~ 511 从 0 开始,依次递增
// 后端数量限制为 512 个
// 索引范围: 0 到 511
nl_linkagg_add_http_backend(la, "127.0.0.1", 8081, 1);  // 后端 0
nl_linkagg_add_http_backend(la, "127.0.0.1", 8082, 1);  // 后端 1
// ... 最多添加 512 个后端

// 超过 512 个后,返回错误
int result = nl_linkagg_add_http_backend(la, "127.0.0.1", 8083, 1);
// result = -8 (超过最大后端数量)

同端口 ID 命名

LinkAgg 支持通过 ID 标识不同的服务端口。

命名格式

ID 必须符合 xxx.xxx 格式(点分隔字符串):

格式 示例 说明
xxx.xxx api.users、web.backend、db.primary 必须包含一个点号
// 正确的 ID 格式
nl_linkagg_set_port_id(la, "api.users");    // ✅
nl_linkagg_set_port_id(la, "web.backend");   // ✅
nl_linkagg_set_port_id(la, "db.primary");    // ✅

// 错误的 ID 格式(编译/运行时错误)
nl_linkagg_set_port_id(la, "apiusers");      // ❌ 缺少点号
nl_linkagg_set_port_id(la, "api..users");   // ❌ 点号位置错误
nl_linkagg_set_port_id(la, ".api.users");    // ❌ 不能以点号开头
nl_linkagg_set_port_id(la, "api.users.");    // ❌ 不能以点号结尾

ID 冲突检测

同一进程内,同一端口的 ID 必须唯一

nl_linkagg_t* la = nl_linkagg_create(8080);

// 设置第一个端口的 ID
nl_linkagg_set_port_id(la, "api.users");  // ✅ 成功

// 设置第二个端口的 ID
// 如果使用相同 ID,会被拒绝:
int result = nl_linkagg_set_port_id(la, "api.users");
// result = -9 (不接入,ID被占用)

限制错误码

错误码 含义
-8 超过最大后端数量(512个)
-9 不接入,ID被占用
-10 ID 格式错误(不符合 xxx.xxx 格式)

平台支持

平台 状态 说明
Windows ✅ 完全支持 需要 IPC 模块支持
Linux ✅ 完全支持 需要 IPC 模块支持
macOS ❌ 不支持 依赖的 IPC 模块不支持 macOS

模块依赖

LinkAgg 模块强依赖以下模块:

模块 依赖类型 说明
netleaf 必需 主库,提供基础网络功能
netleaf_ipc 必需 IPC通讯模块,用于IPC后端支持

依赖关系说明

  1. netleaf (主库)

    • 提供 HTTP 服务器和 TCP socket 功能
    • LinkAgg 的基础网络层依赖
  2. netleaf_ipc (IPC模块)

    • 必需依赖,即使不使用 IPC 后端
    • 提供进程间通讯能力
    • 由于 IPC 模块不支持 macOS,LinkAgg 也不支持 macOS

依赖检查

#include "netleaf_linkagg.h"

int main() {
    // 检查 LinkAgg 是否可用
    if (!nl_linkagg_is_available()) {
        printf("LinkAgg is not available on this platform\n");
        printf("Reasons: IPC module not available (macOS not supported)\n");
        return 1;
    }
    
    // 检查 IPC 模块状态
    if (!nl_ipc_is_available()) {
        printf("IPC module is not available - LinkAgg requires IPC\n");
        return 1;
    }
    
    // 继续使用 LinkAgg...
    return 0;
}

负载均衡策略

策略 描述 适用场景
Round Robin 轮询,依次分配请求 后端性能相近时
Random 随机选择后端 简单场景
Least Connections 选择连接数最少的后端 后端负载差异较大时
Weighted Round Robin 加权轮询,根据权重分配 需要按性能分配时

API 参考

平台检测

// 检查LinkAgg模块是否可用
int nl_linkagg_is_available(void);

// 初始化LinkAgg模块(会自动初始化依赖模块)
int nl_linkagg_init(void);

// 关闭LinkAgg模块
void nl_linkagg_shutdown(void);

创建和配置

// 创建链路聚合实例
// port: 监听端口
nl_linkagg_t* nl_linkagg_create(int port);

// 设置负载均衡策略
void nl_linkagg_set_strategy(nl_linkagg_t* la, nl_linkagg_strategy_t strategy);

// 添加HTTP后端
// host: 后端主机地址
// port: 后端端口
// weight: 权重(用于Weighted Round Robin策略)
int nl_linkagg_add_http_backend(nl_linkagg_t* la, const char* host, int port, int weight);

// 添加IPC后端
// path: IPC路径(Windows: \\.\pipe\<name>, Linux: /path/to/socket)
// weight: 权重
int nl_linkagg_add_ipc_backend(nl_linkagg_t* la, const char* path, int weight);

// 启动链路聚合服务
int nl_linkagg_start(nl_linkagg_t* la);

// 停止链路聚合服务
void nl_linkagg_stop(nl_linkagg_t* la);

// 销毁链路聚合实例
void nl_linkagg_destroy(nl_linkagg_t* la);

状态查询

// 获取后端数量
int nl_linkagg_get_backend_count(nl_linkagg_t* la);

// 获取当前策略
nl_linkagg_strategy_t nl_linkagg_get_strategy(nl_linkagg_t* la);

// 获取后端状态
// index: 后端索引(从0开始)
// 返回值: 0=正常, -1=不可用
int nl_linkagg_get_backend_status(nl_linkagg_t* la, int index);

// 获取当前连接数
int nl_linkagg_get_connection_count(nl_linkagg_t* la);

统计信息

// 获取总请求数
uint64_t nl_linkagg_get_total_requests(nl_linkagg_t* la);

// 获取各后端请求数
int nl_linkagg_get_backend_requests(nl_linkagg_t* la, int index, uint64_t* count);

使用示例

示例 1:基本用法(HTTP后端)

#include "netleaf_linkagg.h"
#include <stdio.h>

int main() {
    // === 平台检测 ===
    if (!nl_linkagg_is_available()) {
        printf("LinkAgg is not available (requires IPC module)\n");
        return 1;
    }
    
    // === 初始化模块 ===
    if (nl_linkagg_init() != 0) {
        printf("Failed to initialize LinkAgg\n");
        return 1;
    }
    
    // === 创建链路聚合实例 ===
    nl_linkagg_t* la = nl_linkagg_create(8080);
    if (!la) {
        printf("Failed to create LinkAgg instance\n");
        nl_linkagg_shutdown();
        return 1;
    }
    
    // === 配置负载均衡策略 ===
    nl_linkagg_set_strategy(la, NL_LINKAGG_STRATEGY_ROUND_ROBIN);
    
    // === 添加HTTP后端 ===
    nl_linkagg_add_http_backend(la, "127.0.0.1", 8081, 1);  // 权重1
    nl_linkagg_add_http_backend(la, "127.0.0.1", 8082, 2);  // 权重2
    nl_linkagg_add_http_backend(la, "127.0.0.1", 8083, 1);  // 权重1
    
    // === 启动服务 ===
    if (nl_linkagg_start(la) != 0) {
        printf("Failed to start LinkAgg\n");
        nl_linkagg_destroy(la);
        nl_linkagg_shutdown();
        return 1;
    }
    
    printf("LinkAgg service started on port 8080\n");
    printf("Backends: 3 HTTP servers\n");
    
    // === 保持运行 ===
    while (1) {
#ifdef _WIN32
        Sleep(1000);
#else
        sleep(1);
#endif
    }
    
    // === 清理 ===
    nl_linkagg_stop(la);
    nl_linkagg_destroy(la);
    nl_linkagg_shutdown();
    
    return 0;
}

示例 2:混合后端(HTTP + IPC)

#include "netleaf_linkagg.h"
#include <stdio.h>

int main() {
    // 初始化
    if (!nl_linkagg_is_available()) {
        printf("LinkAgg not available\n");
        return 1;
    }
    
    nl_linkagg_init();
    
    // 创建实例
    nl_linkagg_t* la = nl_linkagg_create(8080);
    
    // 设置策略
    nl_linkagg_set_strategy(la, NL_LINKAGG_STRATEGY_LEAST_CONNECTIONS);
    
    // 添加HTTP后端
    nl_linkagg_add_http_backend(la, "127.0.0.1", 8081, 1);
    nl_linkagg_add_http_backend(la, "127.0.0.1", 8082, 1);
    
    // 添加IPC后端
#ifdef _WIN32
    nl_linkagg_add_ipc_backend(la, "\\\\.\\pipe\\backend_service", 1);
#else
    nl_linkagg_add_ipc_backend(la, "/tmp/backend_service", 1);
#endif
    
    // 启动
    nl_linkagg_start(la);
    
    printf("LinkAgg started with 2 HTTP + 1 IPC backends\n");
    
    while (1) {
#ifdef _WIN32
        Sleep(1000);
#else
        sleep(1);
#endif
    }
    
    // 清理
    nl_linkagg_stop(la);
    nl_linkagg_destroy(la);
    nl_linkagg_shutdown();
    
    return 0;
}

示例 3:选择不同的负载均衡策略

// 轮询(默认)
nl_linkagg_set_strategy(la, NL_LINKAGG_STRATEGY_ROUND_ROBIN);

// 随机
nl_linkagg_set_strategy(la, NL_LINKAGG_STRATEGY_RANDOM);

// 最小连接数
nl_linkagg_set_strategy(la, NL_LINKAGG_STRATEGY_LEAST_CONNECTIONS);

// 加权轮询
nl_linkagg_set_strategy(la, NL_LINKAGG_STRATEGY_WEIGHTED_ROUND_ROBIN);

功能特性

特性 说明 状态
单端口监听 所有请求通过一个端口进入 ✅
多后端支持 支持HTTP和IPC两种后端类型 ✅
负载均衡 四种负载均衡策略可选 ✅
加权分配 支持后端权重配置 ✅
健康检查 自动检测后端健康状态 ⚠️ Beta
故障转移 自动跳过不可用的后端 ⚠️ Beta
统计信息 请求计数和分发统计 ✅

架构说明

flowchart TD
    C["客户端请求"] --> L["LinkAgg 监听端口 (8080)"]
    L --> LB["负载均衡器<br/>(Round Robin / Random / LeastConn / Weighted)"]
    LB --> B1["HTTP 后端 :8081"]
    LB --> B2["HTTP 后端 :8082"]
    LB --> B3["IPC 后端 /tmp/..."]
Loading

线程安全

LinkAgg模块采用线程安全设计:

特性 说明
互斥锁保护 内部使用互斥锁保护共享资源
并发请求 支持高并发请求处理
线程安全API 所有公开API均可从多个线程调用

错误码

错误码 含义
0 成功
-1 通用错误
-2 平台不支持(依赖IPC不可用)
-3 内存分配失败
-4 无效参数
-5 端口绑定失败
-6 后端添加失败
-7 服务未启动
-8 超过最大后端数量(512个)
-9 不接入,ID被占用
-10 ID 格式错误(不符合 xxx.xxx 格式)

模块信息

NL_MODULE_INFO_BEGIN(linkagg, NL_MODULE_TYPE_LINKAGG)
    NL_MODULE_NAME("LinkAgg")
    NL_MODULE_VERSION("2.2.1-beta")
    NL_MODULE_DESCRIPTION("Same-port link aggregation and load balancing (Beta)")
    NL_MODULE_AUTHOR("508364")
    NL_MODULE_PLATFORM(WINDOWS, LINUX)
    NL_MODULE_DEPENDENCY(netleaf)
    NL_MODULE_DEPENDENCY(netleaf_ipc)
NL_MODULE_INFO_END()

最佳实践

1. 始终检查可用性

if (!nl_linkagg_is_available()) {
    // LinkAgg不可用,提供替代方案
    printf("LinkAgg requires IPC module, falling back to direct HTTP\n");
}

2. 合理配置后端权重

// 根据后端性能设置权重
nl_linkagg_add_http_backend(la, "127.0.0.1", 8081, 2);  // 高性能服务器
nl_linkagg_add_http_backend(la, "127.0.0.1", 8082, 1);  // 普通服务器

3. 监控后端状态

// 定期检查后端状态
for (int i = 0; i < nl_linkagg_get_backend_count(la); i++) {
    int status = nl_linkagg_get_backend_status(la, i);
    if (status != 0) {
        printf("Backend %d is unavailable\n", i);
    }
}

4. 使用前启动依赖服务

// 如果使用IPC后端,确保IPC服务已启动
// 否则请求会失败或超时

常见问题

Q: LinkAgg 为什么不支持 macOS?

A: LinkAgg 强依赖 IPC 模块,而 IPC 模块不支持 macOS。如需跨平台解决方案,建议使用纯 HTTP 后端。

Q: 可以只使用 HTTP 后端而不使用 IPC 吗?

A: 可以,但 IPC 模块仍然会被加载(作为必需依赖)。如果只是需要 HTTP 负载均衡,也可以考虑其他方案。

Q: 后端健康检查是如何工作的?

A: 当前版本(Beta)会在请求失败时标记后端为不可用,并在一段时间后重试。完整的健康检查机制正在开发中。

Q: 支持多少个后端?

A: 理论上没有限制,但建议根据实际场景合理配置(通常 3-10 个后端较为合适)。

⚠️ **GitHub.com Fallback** ⚠️