Bonding 双活模式：Balance-tlb 与 Balance-alb 技术分析
Bonding 双活模式：Balance-tlb 与 Balance-alb 技术分析一、概述1. 背景在上一篇文章中讨论了 active-backup 模式，能够在一张网卡出现故障时快速切换，配置简单。但这种方式存在明显缺点——虽然有两张网卡，但同一时间只能使用一张，只有当主网卡挂了才会使用备网卡。2. 核心问题在高可用设计中，双活优于主备，主备意味着浪费。用户希望实现两张网卡都在工作，当其中一张网卡挂了时，退回到单网卡模式。3. 解决方案Linux Bonding 驱动提供了两种双活模式：Balance-tlb（Adaptive transmit load balancing，模式 5）：发送负载均衡Balance-alb（Adaptive load balancing，模式 6）：收发双向负载均衡二、Balance-tlb 模式1. 工作原理A. 发送方向假设两张网卡都要发送数据，需要解决 MAC flapping 问题——如果同一个 MAC 地址一会从端口 1 发出，一会从端口 2 发出，交换机通过收到的包学习 MAC 地址会感到困惑。因此，两个 interface 必须使用不同的 MAC 地址。对于发送流量，可以使用两个 interface 来发送，交换机看起来就像是两个不同的主机。B. 接收方向对于接收流量，只能用一个 interface 来接收。实现方式是：在回应 ARP 请求时，总是使用其中一个 interface 的 MAC 地址来回复。graph LR subgraph 服务器 B0[bond0 IP: 192.168.1.10 主MAC: 1a:50:9c:11:58:a3] E0[eth0 MAC: 1a:50:9c:11:58:a3 主接口: 收+发] E1[eth1 MAC: 9e:fa:f1:b5:0c:28 备接口: 仅发] B0 --> E0 B0 --> E1 end C1[客户端1] -->|目标MAC: 1a:50| SW[交换机] C2[客户端2] -->|目标MAC: 1a:50| SW SW --> E0 SW --> E1 E0 -->|源MAC: 1a:50| SW E1 -->|源MAC: 9e:fa| SW SW --> C1 SW --> C22. 流量特征对于发送流量：使用两个 interface 发送数据通过 hash 机制保证同一个 TCP 流总是走同一个 interface，避免 reorder 问题实际上会根据两张卡的负载动态调整使用哪张卡对于接收流量：由于其他客户端只知道 IP 对应一个网卡的 MAC 地址，入流量总是走到其中一个 interface 上从交换机视角看，有一个主机的 MAC 地址只会发出去包，但从来没有其他人发给这个 MAC3. 适用场景虽然只是发送流量可以使用两张卡，但对于面向客户的服务器来说：进入服务器的流量较少（请求一般比较小）从服务器出去的流量较多（响应一般很大）对于短视频服务器、流媒体、HTTP 服务器等，这种方案可以有效解决性能问题。三、Balance-tlb 故障切换流程1. 角色定义主接口：接收流量的 interface备接口：不接受流量、只发送的 interface2. 故障场景A. 备接口故障接收端不受影响发送端切换到只用主接口发送B. 主接口故障发送端切换到只使用备接口发送接收端流量也要切换到备接口3. 快速切换机制接收端流量的切换需要让发送流量的地方来切换。直观思路是切换 ARP，但 ARP 太慢，在 ARP 更新到发送者之前，流量会因发送到挂掉的 MAC 地址而被丢弃。更好的解决办法是让交换机来切换：发送者的流量发送给交换机，交换机再发送给服务器客户端的目标 MAC 地址不能变，但交换机转发的端口改变这与 active-backup 中讨论的 Gratuitous ARP 类似4. MAC 地址交换机制Balance-tlb 模式需要硬件支持改写 MAC 地址。切换过程需要保持主 MAC 地址总是可用，以不影响 ARP 缓存，实现快速切换：sequenceDiagram participant C as 客户端 participant SW as 交换机 participant E0 as eth0 (主: 1a:50) participant E1 as eth1 (备: 9e:fa) Note over C,E1: 正常状态 C->>SW: 发送至 MAC: 1a:50 SW->>E0: 从端口1转发 E0->>SW: 发送 (源MAC: 1a:50) E1->>SW: 发送 (源MAC: 9e:fa) Note over C,E1: 主接口故障 E0--xE0: 故障 E1->>E1: MAC交换 eth1: 1a:50 E1->>SW: GARP (1a:50在端口2) SW->>SW: 更新MAC表 1a:50 → 端口2 Note over C,E1: 切换完成 C->>SW: 发送至 MAC: 1a:50 SW->>E1: 从端口2转发 E1->>SW: 发送 (源MAC: 1a:50)切换步骤：交换主和备的 MAC 地址，主 MAC 地址迁移到备上，继续存活通过备 interface（现在的主）发送一个 GARP，让交换机更新 MAC address table4. 配置示例ip link add bond0 type bond mode balance-tlb ip link set eth0 down ip link set eth1 down ip link set eth0 master bond0 ip link set eth1 master bond0 ip link set bond0 up ip addr add 192.168.1.10/24 dev bond05. 验证配置查看网卡信息，bond0 interface 的 MAC 地址和其中一个 slave eth0 一样：root@ubuntu-5:~$ ip link show 2: bond0: <BROADCAST,MULTICAST,MASTER,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT link/ether 1a:50:9c:11:58:a3 brd ff:ff:ff:ff:ff:ff 35: eth0: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 1500 qdisc fq_codel master bond0 state UNKNOWN link/ether 1a:50:9c:11:58:a3 brd ff:ff:ff:ff:ff:ff 36: eth1: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 1500 qdisc fq_codel master bond0 state UNKNOWN link/ether 9e:fa:f1:b5:0c:28 brd ff:ff:ff:ff:ff:ff其他客户端查询 192.168.1.10 对应的 MAC 地址，获取到的是主 MAC 地址：root@ubuntu-4:~$ arp -a | grep 192.168.1.10 ? (192.168.1.10) at 1a:50:9c:11:58:a3 [ether] on eth06. 故障切换验证在 ping 的同时手动 down 掉 eth0，可以看到 1a:50:9c:11:58:a3 这个地址迁移到了 eth1 上：root@ubuntu-5:~$ ip link set eth0 down root@ubuntu-5:~$ ip link show 35: eth0: <BROADCAST,MULTICAST,SLAVE> mtu 1500 qdisc fq_codel master bond0 state DOWN link/ether 9e:fa:f1:b5:0c:28 brd ff:ff:ff:ff:ff:ff 36: eth1: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 1500 qdisc fq_codel master bond0 state UNKNOWN link/ether 1a:50:9c:11:58:a3 brd ff:ff:ff:ff:ff:ff与此同时，ping 也没有失败。四、Balance-alb 模式1. 工作原理Balance-tlb 只在发送方向使用双卡，能否在接收方向也用上两张卡呢？这涉及到发送者的行为，因为作为流量接收方，有两个 MAC 地址，对于让流量发送到哪一个 interface 来说无能为力。发送者通过 ARP 决定发给哪一个 MAC。解决方案是 ARP negotiation：有两个 interface，分别有两个 MAC 地址希望这两个 interface 各收到 50% 的流量在响应 ARP 时，有时告诉客户端这个 IP 对应 MAC AA，有时说是 MAC BBgraph LR subgraph 服务器 B0[bond0 IP: 192.168.1.10] E0[eth0 MAC: 1a:50:9c:11:58:a3] E1[eth1 MAC: 9e:fa:f1:b5:0c:28] B0 --> E0 B0 --> E1 end C1[客户端1] -->|ARP Query| B0 B0 -->|ARP Reply MAC: 1a:50| C1 C1 -->|Data to 1a:50| SW[交换机] SW --> E0 C2[客户端2] -->|ARP Query| B0 B0 -->|ARP Reply MAC: 9e:fa| C2 C2 -->|Data to 9e:fa| SW SW --> E12. 技术难点A. 客户端一致性对于相同的客户端，要给出相同的 MAC 地址答案。不能让客户端一会发送到 MAC AA，一会又发送到 MAC BB，这样会造成 TCP 乱序影响性能。解决方法：追踪回复给不同客户端的 MAC 地址，后续对于此客户端都回复一样的 MAC 地址。B. ARP 学习问题主机不仅通过发送 ARP 请求获取 IP-MAC 对应关系，还会从收到的 ARP 请求中学习：当主机 Z 收到 ARP 请求时，不管有没有这个地址，都会从请求中学习到 IP 对应的 MAC 地址并缓存在自己的 ARP 缓存中1a:50:9c:11:58:a3 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 58: Request who-has 192.168.1.14 tell 192.168.1.10这样做的目的是减少 ARP 查询，但这对 balance-alb 来说很糟糕：好不容易骗一半客户端认为 MAC 是 AA，一半认为是 BB，一旦发送 ARP 请求，所有人都知道了同一个 MAC 地址。C. ARP 广播问题ARP 请求是发送一个广播包给交换机，交换机帮助广播给所有客户端。对于一个 ARP 请求，发出去的只有一个包，无法对不同客户端区别对待。3. GARP 解决方案ARP 请求刷新所有人缓存无法避免，但可以在刷新之后，重新修正部分客户端的 ARP 缓存：sequenceDiagram participant S as 服务器 participant SW as 交换机 participant C1 as 客户端1 (缓存: 1a:50) participant C2 as 客户端2 (缓存: 9e:fa) Note over S,C2: 正常状态 C1->>S: 发送到 1a:50 C2->>S: 发送到 9e:fa Note over S,C2: 服务器发送ARP请求 S->>SW: ARP Request (源MAC: 1a:50) SW->>C1: 广播ARP SW->>C2: 广播ARP C1->>C1: 学习: 192.168.1.10 = 1a:50 C2->>C2: 学习: 192.168.1.10 = 1a:50 缓存被覆盖! Note over S,C2: 服务器发送GARP修复 S->>C1: GARP (Unicast) 192.168.1.10 = 1a:50 S->>C2: GARP (Unicast) 192.168.1.10 = 9e:fa C2->>C2: 更新缓存: 192.168.1.10 = 9e:fa解决步骤：在发送 ARP 请求收到回复之后，对所有人发送一个 Gratuitous ARP使用不同的 MAC 地址告知这些客户端，重新对客户端分流Gratuitous ARP 不仅可以是问题，也可以是 reply。当其他主机收到这个 ARP reply 时，会更新自己的 ARP 缓存。4. 配置示例配置命令与 balance-tlb 几乎一样，只有 mode 改成 balance-alb：ip link add bond0 type bond mode balance-alb ip link set eth0 down ip link set eth1 down ip link set eth0 master bond0 ip link set eth1 master bond0 ip link set bond0 up ip addr add 192.168.1.10/24 dev bond05. 验证 ARP 分流配置后，在不同的机器上查看 ARP 记录，可以看到相同的 IP 有不同的 MAC 地址：# ubuntu-3 root@ubuntu-3:~$ arp -a ? (192.168.1.10) at 9e:fa:f1:b5:0c:28 [ether] on eth0 # ubuntu-4 root@ubuntu-4:~$ arp -a ? (192.168.1.10) at 1a:50:9c:11:58:a3 [ether] on eth0在服务器上发送 ping 包，并在客户端抓包（只抓 in 方向的包）：# ubuntu-3 抓包结果 09:40:08.639278 ARP, Request who-has 192.168.1.14 tell 192.168.1.10, length 44 09:40:10.746098 ARP, Reply 192.168.1.10 is-at 9e:fa:f1:b5:0c:28, length 28 09:40:10.746125 ARP, Reply 192.168.1.10 is-at 9e:fa:f1:b5:0c:28, length 28 # ubuntu-4 抓包结果 09:40:08.639326 ARP, Request who-has 192.168.1.14 tell 192.168.1.10, length 44 09:40:10.746289 ARP, Reply 192.168.1.10 is-at 1a:50:9c:11:58:a3, length 28 09:40:10.746300 ARP, Reply 192.168.1.10 is-at 1a:50:9c:11:58:a3, length 28所有人都收到了 ARP 广播请求，随后又收到了一个 ARP reply，但 reply 中 IP 对应的 MAC 地址是不同的。6. 故障切换流程Balance-alb 的 failover 过程和 balance-tlb 基本一样，但现在无论哪一个网卡挂了，都必须要更新所有人的 ARP 缓存。Failover 流程：如果挂的是主，交换两张卡的 MAC 地址；如果是备，不需要发送 GARP 给所有人（Unicast），告诉所有人自己的 IP 对应的 MAC（当然是没挂的那一个）将 link set down 并且在其他机器上抓包，会看到有多个 GARP 包发过来：root@ubuntu-4:~$ tcpdump -i eth0 -n arp -Q in 10:04:16.689841 ARP, Reply 192.168.1.10 is-at 1a:50:9c:11:58:a3, length 28 10:04:16.690286 ARP, Reply 192.168.1.10 is-at 1a:50:9c:11:58:a3, length 28 10:04:16.690720 ARP, Reply 192.168.1.10 is-at 1a:50:9c:11:58:a3, length 28五、三种 Bonding 模式对比1. 模式总结模式实现复杂度切换速度网卡利用率硬件要求active-backup简单快速单卡无特殊要求balance-tlb简单快速发送双卡需支持 MAC 地址修改balance-alb简单较慢收发双卡需支持 MAC 地址修改2. 各自特点A. Active-backup（模式 1）实现简单，快速切换只能用单卡，资源浪费B. Balance-tlb（模式 5）实现简单，快速切换发送能用双卡，接收单卡需要硬件支持 MAC 地址修改适合出流量大的场景（如流媒体、HTTP 服务）C. Balance-alb（模式 6）实现简单，切换较慢收发双卡，充分利用带宽涉及 GARP 刷新所有客户端缓存需要硬件支持 MAC 地址修改3. 扩展性这三种方案都是用两张卡讨论的，实际上都可以加更多的卡，工作原理完全一样。4. 局限性这些方案都有缺点，都不是数据中心在用的方案，但离"完美"的方案越来越近了。数据中心的实际方案会在后续文章中讨论。参考资料Kernel Bonding Documentation数据中心网络高可用技术之从服务器到交换机：balance-tlb 和 balance-alb
Frontail Web日志实时流式工具技术分析一、概述1. 简介A. 是什么Frontail 是一个基于 Node.js 开发的日志实时流式传输工具，将传统的 tail -F 命令功能带入了 Web 浏览器。它通过 WebSocket 技术实现日志文件的实时推送，让开发者可以在浏览器界面中实时查看服务器日志，无需通过终端访问。B. 为什么学解决远程日志查看问题，无需 SSH 登录即可监控日志提供友好的 Web UI 界面，支持搜索和高亮显示支持多文件同时监控，适合微服务架构可以集成到现有 Web 基础设施中，与 Nginx 等反向代理配合使用C. 学完能做什么快速搭建日志监控 Web 服务配置基于 Basic Auth 的日志访问控制集成 HTTPS 加密传输自定义日志高亮规则通过 Nginx 反向代理嵌入现有系统2. 前置知识A. 必备技能基本的 Linux 命令行操作了解 tail -F 命令的基本用法Node.js 环境配置B. 推荐知识WebSocket 通信原理Nginx 反向代理配置HTTP 基本认证机制二、环境准备1. 系统要求Node.js 12.x 或更高版本npm 或 yarn 包管理器Linux/Unix/macOS/Windows 操作系统2. 安装步骤全局安装：npm install frontail -g本地安装：npm install frontail --save-dev3. 验证安装frontail --version三、核心概念1. 基本术语WebSocket：全双工通信协议，用于服务器主动推送日志tail -F：持续跟踪文件增长，即使文件被轮转也能继续监控Basic Auth：HTTP 基本认证，用于保护日志访问Daemon：后台进程模式，将 frontail 作为守护进程运行2. 工作原理graph LR A[日志文件] -->|tail -F| B[Frontail 服务] B -->|WebSocket| C[浏览器] C -->|搜索/过滤| B D[配置文件] -->|高亮规则| B E[Nginx] -->|反向代理| B三、核心架构1. 系统组成graph TB subgraph 前端层 A[Web UI] B[WebSocket 客户端] C[搜索过滤] end subgraph 服务层 D[Node.js 服务] E[文件监控模块] F[WebSocket 服务] G[认证模块] end subgraph 数据层 H[日志文件] I[配置文件] end A --> B B --> F F --> E E --> H G --> I四、快速上手1. Hello World 示例# 监控单个日志文件 frontail /var/log/nginx/access.log # 访问 http://localhost:90012. 核心功能演示# 监控多个文件 frontail /var/log/app/*.log # 指定端口和主机 frontail -h 0.0.0.0 -p 8080 /var/log/syslog # 启用高亮 frontail --ui-highlight /var/log/app.log3. 代码讲解Frontail 内部使用 Node.js 的 fs.watch() API 监控文件变化，通过 WebSocket 将新增的日志行实时推送到浏览器。前端使用纯 JavaScript 渲染日志流，支持自动滚动和搜索功能。五、功能详解1. 命令行参数A. 基础参数参数说明默认值-h, --host监听地址0.0.0.0-p, --port监听端口9001-n, --number启动时显示的行数10-l, --lines浏览器中存储的行数2000B. 安全参数参数说明-U, --userBasic Auth 用户名-P, --passwordBasic Auth 密码-k, --keyHTTPS 私钥文件-c, --certificateHTTPS 证书文件C. UI 参数参数说明-t, --theme主题（default、dark）--ui-hide-topbar隐藏顶部栏--ui-no-indent取消缩进--ui-highlight启用高亮--ui-highlight-preset自定义高亮规则文件D. 运行模式参数说明-d, --daemonize后台运行--pid-pathPID 文件路径--log-path日志文件路径--url-pathURL 路径前缀2. 高亮配置默认高亮规则（preset/default.json）：{ "words": { "err": "color: red;", "warn": "color: orange;" }, "lines": { "err": "font-weight: bold;", "exception": "background-color: pink;" } }自定义规则示例：{ "words": { "ERROR": "color: red; font-weight: bold;", "WARN": "color: orange;", "INFO": "color: green;", "DEBUG": "color: gray;" }, "lines": { "Exception": "background-color: #ffcccc;", "Failed": "background-color: #ffebcc;" } }3. Nginx 集成A. 反向代理配置events { worker_connections 1024; } http { server { listen 8080; server_name localhost; location /frontail { proxy_pass http://127.0.0.1:9001/frontail; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } } }B. WebSocket 支持关键配置项：proxy_http_version 1.1：启用 HTTP/1.1Upgrade 头：支持协议升级Connection "upgrade"：允许连接升级六、实战案例1. 场景描述为微服务架构搭建统一的日志监控平台2. 实现步骤A. 启动 Frontail 服务# 后台运行，使用自定义高亮规则 frontail -d \ -p 9001 \ -U admin \ -P secretpassword \ --ui-highlight-preset /etc/frontail/custom.json \ --pid-path /var/run/frontail.pid \ --log-path /var/log/frontail.log \ /var/log/service1/app.log \ /var/log/service2/app.log \ /var/log/service3/app.logB. 配置系统服务（systemd）[Unit] Description=Frontail Log Viewer After=network.target [Service] Type=forking User=logs Group=logs ExecStart=/usr/bin/frontail -d \ -p 9001 \ -U admin \ -P secretpassword \ --ui-highlight-preset /etc/frontail/custom.json \ --pid-path /var/run/frontail.pid \ --log-path /var/log/frontail.log \ /var/log/service/*/app.log Restart=always RestartSec=10 [Install] WantedBy=multi-user.targetC. Nginx HTTPS 配置server { listen 443 ssl http2; server_name logs.example.com; ssl_certificate /etc/letsencrypt/live/logs.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/logs.example.com/privkey.pem; location / { proxy_pass http://127.0.0.1:9001; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } }七、最佳实践1. 安全建议使用 Basic Auth 保护日志访问启用 HTTPS 加密传输限制监听地址为 127.0.0.1，通过 Nginx 代理定期清理历史日志文件2. 性能优化限制浏览器存储行数（--lines 参数）对于大型日志文件，使用 logrotate 进行轮转多文件监控时注意文件描述符限制3. 运维建议使用 systemd 管理服务生命周期配置日志轮转避免磁盘占满监控 Frontail 进程状态设置合理的 PID 和日志路径八、与其他工具对比工具语言特点适用场景FrontailNode.jsWeb UI、轻量级中小规模日志监控Go FrontailGo高性能、单二进制高并发场景LogstashJava功能强大、生态完善大规模日志处理lnavC/C++终端 UI、功能丰富本地日志分析九、常见问题1. 安装问题权限不足# 使用 sudo 安装 sudo npm install frontail -g版本兼容Node.js 版本过低会导致安装失败，建议使用 Node.js 14.x 或更高版本。2. 运行问题端口被占用# 查看端口占用 lsof -i :9001 # 更换端口 frontail -p 9002 /var/log/app.log文件权限# 确保运行用户有读取权限 chmod +r /var/log/app.log3. WebSocket 断连检查 Nginx 配置中的 Upgrade 和 Connection 头设置是否正确，确保 WebSocket 协议升级不被阻止。十、参考资料参考资料Frontail GitHub Repositorycloudash.dev - Log Monitoring Solution
Octopus LLM API 聚合服务技术分析一、新闻概述1. 标题Octopus：为个人打造的 LLM API 聚合与负载均衡服务2. 发布时间2025 年 1 月 16 日3. 来源GitHub 开源项目二、核心内容1. 事件摘要A. 主要内容Octopus 是一个面向个人用户的 LLM API 聚合服务项目，旨在通过统一入口管理多个 LLM 提供商的 API，实现智能负载均衡和成本优化。B. 核心亮点多渠道聚合：统一管理多个 LLM 提供商通道智能负载均衡：支持轮询、随机、故障转移、加权等多种模式协议转换：无缝转换 OpenAI Chat、OpenAI Responses、Anthropic API 格式自动同步：模型列表和价格信息自动更新优雅 UI：简洁美观的 Web 管理面板2. 关键信息A. 技术栈后端：Go 1.24.4前端：Next.js + pnpm数据库：SQLite、MySQL、PostgreSQLB. 部署方式Docker 容器化部署二进制文件直接运行源码编译C. 默认配置服务端口：8080默认账号：admin/admin数据存储：/app/data3. 背景介绍A. 项目起源随着 LLM 服务提供商日益增多，个人用户面临管理多个 API Key、分散调用、成本统计困难等问题。Octopus 应运而生，提供统一的 API 聚合解决方案。B. 相关上下文项目借鉴了 axonhub 的 LLM API 适配模块设计，并整合了 models.dev 的 AI 模型数据库用于价格信息同步。三、详细报道1. 主要内容A. 功能特性渠道管理：支持单通道多 API Key 配置每个通道支持多个端点，智能选择延迟最短的端点自动根据通道类型追加 API 路径分组管理：将多个通道聚合为统一的对外模型名称调用时设置 model 参数为分组名称即可访问所有通道支持多种负载均衡模式负载均衡模式：轮询模式：按顺序依次分配请求到各通道随机模式：随机选择可用通道故障转移：优先使用高优先级通道，失败时切换到低优先级通道加权模式：根据配置的通道权重分配请求B. 技术改进协议转换：OpenAI Chat 格式OpenAI Responses 格式Anthropic Messages 格式Gemini Generate Content 格式自动同步：定期从 models.dev 同步模型定价数据创建通道时自动同步可用模型列表自动创建未知模型的定价信息C. 统计分析综合请求统计Token 消耗统计成本跟踪定期批量写入数据库（性能优化策略）2. 技术细节A. 系统架构graph TB Client[客户端应用] --> Octopus[Octopus API 网关] Octopus --> LoadBalancer[负载均衡器] LoadBalancer --> Channel1[通道 1] LoadBalancer --> Channel2[通道 2] LoadBalancer --> Channel3[通道 3] Channel1 --> Provider1[提供商 1] Channel2 --> Provider2[提供商 2] Channel3 --> Provider3[提供商 3] Octopus --> Database[(数据库)] Octopus --> PriceSync[价格同步] PriceSync --> ModelsDev[models.dev]B. 数据流程sequenceDiagram participant C as 客户端 participant O as Octopus participant LB as 负载均衡 participant P as LLM 提供商 participant D as 数据库 C->>O: API 请求（model=分组名） O->>LB: 负载均衡选择 LB->>O: 返回选定通道 O->>P: 转发请求（协议转换） P-->>O: 返回响应 O-->>C: 返回结果 O->>D: 异步记录统计C. 配置架构graph LR Config[配置文件] --> Server[服务器配置] Config --> Database[数据库配置] Config --> Log[日志配置] Database --> SQLite[SQLite] Database --> MySQL[MySQL] Database --> PostgreSQL[PostgreSQL]3. 数据与事实A. 支持的 LLM 提供商OpenAI（Chat Completions、Responses）Anthropic（Claude）Google（Gemini）其他兼容 OpenAI 格式的提供商B. 数据库支持数据库类型配置示例SQLitedata/data.dbMySQLuser:password@tcp(host:port)/dbnamePostgreSQLpostgresql://user:password@host:port/dbnameC. 性能优化统计数据先存储在内存按配置间隔批量写入数据库减少频繁 I/O 操作对性能的影响四、影响分析1. 行业影响A. 技术趋势LLM 服务聚合成为刚需多模型混合调用成为趋势成本优化工具需求增长B. 竞争格局与其他 API 网关相比，Octopus 更专注于个人用户场景开源免费，降低了个人用户的接入门槛轻量级设计，适合个人部署2. 用户影响A. 现有用户简化了多 API Key 管理统一调用接口，降低集成复杂度实时成本统计，便于预算控制B. 潜在用户个人开发者：快速接入多个 LLM 服务小型团队：共享 API 配额，降低成本研究人员：灵活切换不同模型进行实验C. 迁移成本部署简单，支持 Docker 一键启动兼容 OpenAI SDK，无需修改现有代码配置文件自动生成，开箱即用3. 技术趋势A. 技术方向API 聚合服务标准化智能负载均衡算法优化多协议适配成为标配B. 生态影响促进 LLM 服务的互联互通降低模型切换成本推动价格透明化五、各方反应1. 项目特点开源免费，代码托管在 GitHub活跃的开发维护清晰的文档和使用指南2. 业内评价A. 技术亮点架构简洁，易于理解和扩展前后端分离，便于独立部署多数据库支持，适应不同场景B. 应用场景个人开发环境搭建小型团队 API 管理LLM 应用后端服务3. 用户反馈A. 正面评价部署简单，快速上手UI 界面美观易用功能完整，满足个人需求B. 改进建议增加更多 LLM 提供商支持优化负载均衡算法增强监控告警功能六、相关链接1. 项目地址GitHub 仓库：https://github.com/bestruirui/octopus2. 相关项目axonhub：LLM API 适配模块参考来源models.dev：AI 模型数据库3. 技术文档完整配置说明API 接口文档部署指南参考资料Octopus GitHub Repository
gpt-load 企业级多渠道大模型 API 管理平台技术分析
gpt-load 企业级多渠道大模型 API 管理平台技术分析一、平台概述1. 简介gpt-load 是一款基于 Go 语言开发的企业级多渠道大模型 API 管理平台，专为需要集成多种 AI 服务的企业和开发者设计。它作为透明代理服务，完整保留了各 AI 服务商的原生 API 格式，支持智能密钥管理、负载均衡、故障切换和水平扩展，内置 Web 管理界面，提供高效、稳定的多 AI 服务集成管理方案。2. 核心定位企业级 AI 服务聚合中间件，解决多 AI 服务商接入、密钥管理、负载均衡等痛点问题。3. 设计目标简化 AI 服务集成复杂度，提供统一接入层，降低企业使用多种大模型的技术门槛和运维成本。二、核心功能特性1. 透明代理完全保留 OpenAI、Google Gemini 和 Anthropic Claude 等原生 API 格式，无需修改客户端代码即可无缝迁移。支持官方 OpenAI API、Azure OpenAI 以及其他 OpenAI 兼容服务。支持 Gemini Pro、Gemini Pro Vision 等模型的原生 API。支持 Claude 系列模型，支持高质量的对话和文本生成。2. 智能密钥管理支持密钥分组管理、自动轮换和故障恢复，提升密钥可用性与安全性。提供高性能密钥池，确保在高并发场景下密钥的稳定使用。3. 负载均衡支持多上游端点加权负载均衡，优化请求分发，提高服务整体可用性。自动管理密钥黑名单及恢复机制，减少因密钥失效导致的请求失败。4. 动态配置与热重载系统设置和分组配置支持热重载，修改后无需重启即可生效，提升运维效率。分组配置优先级高于系统设置，满足不同场景下的定制化需求。5. 企业级架构支持分布式主从部署和水平扩展，满足高并发场景下的性能需求。提供全面的监控功能，包括实时统计、健康检查和详细请求日志，便于问题排查与系统优化。6. 现代化管理与安全基于 Vue 3 的 Web 管理界面，直观易用，提升管理效率。管理端与代理端认证分离，支持全局和分组级别代理密钥，强化权限管控。提供优雅关闭、错误恢复和完善的安全机制，确保服务稳定运行。三、系统架构1. 架构设计graph TB subgraph 客户端层 A1[OpenAI 客户端] A2[Gemini 客户端] A3[Claude 客户端] end subgraph gpt-load 代理层 B1[API 网关] B2[认证模块] B3[负载均衡器] B4[密钥管理器] B5[健康检查] B6[配置中心] B7[Web 管理界面] end subgraph 上游服务层 C1[OpenAI API] C2[Azure OpenAI] C3[Gemini API] C4[Claude API] C5[其他兼容服务] end subgraph 数据存储层 D1[(MySQL/PostgreSQL)] D2[(SQLite)] D3[Redis 可选] end A1 --> B1 A2 --> B1 A3 --> B1 B1 --> B2 B2 --> B3 B3 --> B4 B4 --> C1 B4 --> C2 B4 --> C3 B4 --> C4 B4 --> C5 B3 --> B5 B5 --> B4 B7 --> B6 B6 --> B4 B6 --> D1 B6 --> D2 B6 --> D32. 请求处理流程sequenceDiagram participant C as 客户端 participant G as gpt-load 网关 participant A as 认证模块 participant L as 负载均衡器 participant K as 密钥管理器 participant P as 上游 AI 服务 C->>G: 发起 API 请求 G->>A: 验证代理密钥 A-->>G: 认证通过 G->>L: 获取可用端点 L->>K: 请求密钥 K-->>L: 返回健康密钥 L->>P: 转发请求 P-->>L: 返回响应 L-->>G: 转发响应 G-->>C: 返回结果3. 密钥管理机制graph LR subgraph 密钥池 A[密钥组 1] B[密钥组 2] C[密钥组 3] end subgraph 密钥状态 D[活跃密钥] E[冷却密钥] F[黑名单密钥] end subgraph 密钥操作 G[自动轮换] H[故障恢复] I[健康检查] end A --> D B --> D C --> D D --> E E --> D D --> F F --> H H --> D I --> D G --> D四、部署与安装1. 环境准备确保服务器已安装 Docker 和 Docker Compose。准备数据库（MySQL、PostgreSQL 或 SQLite）和 Redis（可选，用于缓存和分布式协调）。2. 下载配置文件mkdir -p gpt-load && cd gpt-load wget https://raw.githubusercontent.com/tbphp/gpt-load/refs/heads/main/docker-compose.yml wget -O .env https://raw.githubusercontent.com/tbphp/gpt-load/refs/heads/main/.env.example3. 修改配置文件编辑 .env 文件，修改 AUTH_KEY 为强密码，确保安全性。根据需要配置数据库连接（DATABASE_DSN）和 Redis 连接（REDIS_DSN）。4. 启动服务docker compose up -d默认使用 SQLite 数据库，适合轻量单机应用。如需使用 MySQL 或 PostgreSQL，请在 docker-compose.yml 文件中取消对应服务的注释，并配置好环境变量。5. 访问管理界面打开浏览器，访问 http://localhost:3001。使用修改后的 AUTH_KEY 登录管理界面。6. 配置 API 代理在管理界面创建服务分组（如 openai、gemini），并添加对应 AI 服务的 API 密钥。客户端通过代理端点调用，替换原生 API 地址为 http://localhost:3001/proxy/{group_name}，使用代理密钥认证。五、技术优势分析1. 透明代理设计完全保留上游 API 格式，客户端无需任何代码修改即可切换到代理层，大幅降低迁移成本。2. 多厂商统一接入同时支持 OpenAI、Azure OpenAI、Google Gemini、Anthropic Claude 等主流 AI 服务，企业可根据成本、性能、合规性等因素灵活选择服务商。3. 智能密钥管理密钥分组、自动轮换、故障恢复等机制，有效应对 API 配额限制、密钥失效等问题，提升服务稳定性。4. 负载均衡与高可用支持加权负载均衡、故障自动切换，配合分布式部署能力，满足企业级高并发场景需求。5. 运维友好热重载配置、Web 管理界面、详细监控日志，降低运维复杂度，提升问题排查效率。6. 安全加固管理端与代理端认证分离、多级代理密钥、优雅关闭机制，全面保障服务安全。六、应用场景1. AI 应用开发商需要集成多种大模型能力，希望统一管理 API 调用、控制成本、保障服务稳定性的场景。2. 企业内部 AI 平台企业内部构建 AI 能力平台，需要统一接入多种 AI 服务，并通过密钥管理、负载均衡等机制保障服务稳定性。3. AI 服务代理商为多个客户提供 AI 服务接入，需要通过密钥分组、负载均衡等机制实现多租户隔离和服务保障。4. 研发团队研发团队在开发过程中需要频繁切换不同 AI 服务进行测试和对比，gpt-load 提供了便捷的统一接入层。七、技术栈1. 后端技术Go 语言：高性能、并发能力强，适合构建代理服务。2. 前端技术Vue 3：现代化 Web 管理界面，提供良好的用户体验。3. 数据存储MySQL/PostgreSQL：生产环境推荐使用的关系型数据库。SQLite：轻量级单机部署场景。Redis：可选，用于缓存和分布式协调。4. 容器化部署Docker、Docker Compose：简化部署流程，支持快速交付。Kubernetes：支持容器编排平台部署，满足大规模集群需求。八、项目资源1. 开源地址GitHub：https://github.com/tbphp/gpt-load用户可以在此获取源代码、参与贡献或报告问题。2. 官网地址官网：https://www.gpt-load.com/基于 Next.js 14 构建，提供项目展示与文档导航。官网为开源项目提供了专业的展示平台，包含项目简介、功能特性、架构图、性能指标等内容。3. 文档地址详细文档可在官网或 GitHub 仓库的 README.md 文件中查看。文档涵盖了平台的功能特性、快速开始指南、配置说明、部署指南等内容，为用户提供全面的使用指导。九、总结gpt-load 作为一款企业级多渠道大模型 API 管理平台，通过透明代理、智能密钥管理、负载均衡等核心特性，为企业集成多种 AI 服务提供了高效、稳定的解决方案。其基于 Go 语言的高性能架构、Vue 3 现代化管理界面、热重载配置等设计，充分体现了企业级产品的设计理念。对于需要统一管理多种 AI 服务的企业和开发者而言，gpt-load 是一个值得考虑的开源选择。参考资料gpt-load 企业级多渠道大模型 API 管理平台gpt-load GitHub 仓库gpt-load 官方网站
Nginx + LVS + Keepalived 百万并发架构实战技术分析一、新闻概述1. 标题百万并发架构实战：Nginx + LVS + Keepalived 架构2. 发布时间2025 年 1 月 15 日（资料整理）3. 来源架构师陈哥（微信公众号）二、核心内容1. 事件摘要A. 主要内容本文详细介绍了 Nginx + LVS + Keepalived 三层负载均衡架构，该架构是支撑百万级并发访问的主流解决方案。B. 核心亮点三层架构设计：LVS（四层）+ Nginx（七层）+ 业务集群高性能：LVS 运行在内核态，可支撑百万级并发连接高可用：Keepalived 提供主备切换和健康检查灵活性：Nginx 提供丰富的七层路由功能2. 关键信息A. 涉及技术LVS（Linux Virtual Server）NginxKeepalivedVRRP 协议DR 模式（Direct Routing）B. 性能指标LVS 可支撑数十万甚至上百万并发连接适用于互联网业务快速发展的场景3. 背景介绍A. 技术需求在互联网业务快速发展的大背景下，支撑百万并发访问成为大型网站和分布式应用设计的关键目标。B. 解决方案Nginx + LVS + Keepalived 架构以其高性能、可扩展性和高可用性，成为常见的解决方案。三、详细报道1. 架构概述A. 整体架构graph TD Client[客户端] -->|请求| LVS[LVS 四层负载均衡] LVS -->|转发| Nginx1[Nginx 七层代理 1] LVS -->|转发| Nginx2[Nginx 七层代理 2] Nginx1 -->|HTTP路由| App1[业务服务器1] Nginx1 -->|HTTP路由| App2[业务服务器2] Nginx2 -->|HTTP路由| App3[业务服务器3] Nginx2 -->|HTTP路由| App4[业务服务器4]B. 架构分层客户端 ↓ LVS（四层负载，抗并发） ↓ Nginx（七层负载，协议处理） ↓ 业务集群2. LVS 负载入口A. 技术特点LVS（Linux Virtual Server）是四层负载均衡解决方案，运行在内核态。核心优势：性能极高：运行在内核态，零拷贝技术抗并发能力强：轻松支撑数十万甚至上百万并发连接只负责转发：不解析 HTTP 协议内容，仅处理 TCP/UDP 数据包B. 工作模式LVS 支持多种工作模式，本文主要介绍 DR 模式（Direct Routing）：DR 模式特点：请求经过 LVS，响应不经过 LVS真实服务器直接响应客户端性能最优，要求 LVS 和服务器在同一物理网络C. LVS Director 架构graph TB subgraph "LVS Director 集群" LVSMaster[LVS Master 主节点] LVSSlave[LVS Slave 备节点] end subgraph "Keepalived 管理" VRRP[VRRP 协议 VIP 管理] Health[健康检查] end subgraph "ipvsadm 规则" Rules[DR 模式 负载均衡规则] end LVSMaster --> VRRP LVSSlave --> VRRP VRRP --> Rules Health --> LVSMaster Health --> LVSSlave3. Keepalived 高可用保障A. 核心功能Keepalived 是 LVS 集群的高可用保障组件。主要功能：VIP（Virtual IP）管理：通过 VRRP 协议实现虚拟 IP 漂移主备切换：当主节点故障时，备节点自动接管 VIP健康检查：自动检测后端节点状态，剔除异常节点B. VRRP 协议VRRP（Virtual Router Redundancy Protocol）是虚拟路由器冗余协议。工作原理：主节点定期发送 VRRP 广播备节点监听广播主节点故障时，备节点根据优先级接管 VIP客户端始终通过 VIP 访问服务C. 故障切换流程sequenceDiagram participant C as 客户端 participant VIP as 虚拟IP (VIP) participant M as LVS Master participant S as LVS Slave C->>VIP: 正常访问 VIP->>M: 转发请求 M->>C: 返回响应 Note over M: 主节点故障 S->>VIP: 检测到主节点故障 S->>VIP: 接管 VIP VIP->>S: VIP 绑定到备节点 C->>VIP: 继续访问 VIP->>S: 转发请求 S->>C: 返回响应4. Nginx 七层反向代理A. 部署位置Nginx 可以部署为两种角色：后端真实服务器的七层代理独立的七层反向代理集群B. 核心职责Nginx 七层负载均衡功能：功能说明HTTP/HTTPS 解析处理 HTTP 协议，SSL 卸载路由与反向代理基于域名、路径、请求头路由限流与熔断保护后端服务，防止雪崩缓存支持静态资源缓存，减轻后端压力灰度发布支持 AB 测试、金丝雀发布健康检查自动检测后端服务状态C. 架构优势Nginx 不直接承受"连接洪峰"，前面有 LVS 做缓冲：LVS 处理大量并发连接Nginx 专注于业务逻辑路由分层设计，职责清晰四、技术细节1. 数据流向分析graph LR C[客户端] -->|DNS解析| VIP[VIP: 1.2.3.4] VIP -->|MAC地址替换| LVS[LVS Master] LVS -->|改写MAC地址| NG[Nginx集群] NG -->|HTTP路由| APP1[应用服务器1] NG -->|HTTP路由| APP2[应用服务器2] APP1 -->|直接响应| C APP2 -->|直接响应| CDR 模式数据包处理流程：客户端请求到达 VIPLVS 接收请求，改写目标 MAC 地址为真实服务器 MAC转发到 Nginx 服务器（不修改 IP 地址）Nginx 处理后转发到业务服务器业务服务器直接响应客户端（不经过 LVS）2. 性能分析A. 各层性能特点组件运行空间主要职责性能特点LVS内核态TCP/UDP 转发极高，百万级并发Nginx用户态HTTP 处理高，万级并发业务服务器用户态业务逻辑取决于应用B. 为什么需要分层问题：为什么不单独使用 Nginx 或 LVS？答案：单独 LVS：无法处理七层逻辑（如基于路径的路由）单独 Nginx：用户态处理，性能不如内核态，连接数受限组合方案：LVS 抗连接洪峰，Nginx 处理业务逻辑，各司其职3. 高可用保障A. 多层高可用graph TB subgraph "第一层：LVS 高可用" LVS_M[LVS Master] LVS_S[LVS Slave] end subgraph "第二层：Nginx 高可用" NG1[Nginx 1] NG2[Nginx 2] NG3[Nginx 3] end subgraph "第三层：应用高可用" APP1[应用集群] APP2[应用集群] end LVS_M -.VRRP.-> LVS_S LVS_M --> NG1 LVS_M --> NG2 LVS_S --> NG2 LVS_S --> NG3 NG1 --> APP1 NG2 --> APP1 NG2 --> APP2 NG3 --> APP2B. 故障场景处理故障点检测机制处理方式LVS Master 宕机VRRP 心跳超时Slave 接管 VIPNginx 宕机Keepalived 健康检查LVS 剔除异常节点应用服务宕机Nginx 被动健康检查Nginx 转发到健康节点五、影响分析1. 行业影响A. 技术趋势三层负载均衡架构已成为互联网行业标准实践开源解决方案（LVS + Nginx + Keepalived）成本优势明显云原生时代，该架构仍在物理机/虚拟机场景广泛应用B. 替代方案对比方案优点缺点适用场景LVS + Nginx + Keepalived成熟稳定、成本低、性能高运维复杂传统IDC、私有云硬件负载均衡（F5等）功能完善、易用昂贵、封闭大型企业云负载均衡（ALB/SLB）托管服务、弹性成本随流量线性增长公有云2. 技术趋势A. 云原生演进Kubernetes Service：基于 iptables/IPVS 的服务发现Ingress Controller：类似 Nginx 的七层路由云厂商托管服务：逐步替代自建负载均衡B. 技术融合LVS 的 IPVS 模块被 Kubernetes 直接采用Nginx 成为 Ingress Controller 主流实现Keepalived 在边缘节点仍广泛使用六、实践建议1. 架构选型适用场景：日活百万级以上的互联网应用需要高并发、高可用的企业级系统自建机房或私有云环境不适用场景：初创期流量较小的应用纯公有云部署（建议使用云厂商托管服务）团队缺乏运维能力2. 运维要点A. 监控告警LVS 连接数、丢包率Nginx QPS、响应时间、错误率Keepalived VIP 状态后端服务健康状态B. 容量规划LVS：根据并发连接数规划（单机可支撑 10 万+ 并发）Nginx：根据 QPS 规划（单机可支撑 1 万+ QPS）业务服务器：根据应用性能规划C. 安全防护限制 SYN flood 攻击配置访问频率限制定期检查漏洞确保 SSL 证书安全3. 最佳实践配置管理：使用配置管理工具（Ansible、SaltStack）灰度发布：利用 Nginx 的灰度能力平滑上线压测验证：上线前进行充分压测文档完善：维护架构文档和应急预案定期演练：定期进行故障切换演练七、总结Nginx + LVS + Keepalived 架构是经典的三层负载均衡解决方案，通过职责分离实现了高性能和高可用性的平衡：LVS：内核态四层负载，抗连接洪峰Nginx：用户态七层代理，灵活路由Keepalived：高可用保障，主备切换该架构经过互联网大厂多年验证，是支撑百万级并发的成熟方案。在云原生时代，虽然出现了更多托管服务，但理解这套架构的底层原理，对于构建高可用系统仍然具有重要意义。参考资料百万并发架构实战：Nginx +LVS+ Keepalived架构！
Patroni + HAProxy + Keepalived + watchdog + ETCD PostgreSQL 高可用集群架构分析
Patroni + HAProxy + Keepalived + watchdog + ETCD PostgreSQL 高可用集群架构分析一、背景与目标1. 项目背景A. 业务场景PostgreSQL 作为主流开源关系型数据库，在企业核心业务系统中扮演着关键角色。传统单节点部署存在单点故障风险，主从复制方案在主节点故障时需要手动切换，影响业务连续性。B. 痛点分析单点故障：主节点宕机导致服务中断手动切换：故障恢复需要人工介入，耗时长脑裂风险：网络分区可能导致多主节点数据一致性问题：主备切换时数据可能丢失2. 设计目标A. 功能目标实现自动故障检测与切换保障数据一致性和完整性提供读写分离能力B. 非功能目标高可用性：99.99% 以上故障切换时间：毫秒级业务无感知：透明切换防止脑裂：分布式共识保障二、总体架构1. 设计原则分层架构：客户端应用层、负载均衡层、数据库集群层、分布式一致性层自动化运维：故障自动检测、自动切换、自动恢复防止脑裂：基于分布式共识的选举机制读写分离：智能路由优化性能2. 系统架构graph TB Client[客户端应用层] --> VIP[虚拟 IP 192.168.231.140] VIP -->|VRRP 协议| Keep1[Keepalived Master] VIP -->|VRRP 协议| Keep2[Keepalived Backup] Keep1 --> HA1[HAProxy 主节点] Keep2 --> HA2[HAProxy 备节点] HA1 -->|读写分离| Patroni1[Patroni Leader] HA1 -->|只读| Patroni2[Patroni Follower] HA1 -->|只读| Patroni3[Patroni Follower] HA2 --> Patroni1 HA2 --> Patroni2 HA2 --> Patroni3 Patroni1 --> PG1[(PostgreSQL 主节点)] Patroni2 --> PG2[(PostgreSQL 备节点)] Patroni3 --> PG3[(PostgreSQL 备节点)] Patroni1 -.分布式共识.-> ETCD1[(ETCD 节点 1)] Patroni2 -.分布式共识.-> ETCD2[(ETCD 节点 2)] Patroni3 -.分布式共识.-> ETCD3[(ETCD 节点 3)] WD1[Watchdog 监控] -.心跳检测.-> Patroni1 WD2[Watchdog 监控] -.心跳检测.-> Patroni2 WD3[Watchdog 监控] -.心跳检测.-> Patroni33. 组件说明客户端应用层：业务系统通过统一 VIP 访问，对底层架构无感知负载均衡层：HAProxy + Keepalived 实现智能路由和负载均衡层高可用数据库集群层：PostgreSQL + Patroni 实现数据高可用和自动故障转移分布式一致性层：ETCD 集群提供强一致性保障，防止脑裂进程监控层：Watchdog 监控 Patroni 进程状态，异常时强制重启三、负载均衡层设计1. HAProxy 组件A. 组件职责HAProxy（High Availability Proxy）是开源高性能代理软件，在架构中负责：接收客户端连接请求根据 PostgreSQL 节点角色进行读写分离路由执行健康检查，自动剔除故障节点实现负载均衡，优化资源利用B. 核心架构graph LR Client[客户端请求] --> Frontend[Frontend 前端处理] Frontend --> LB[Load Balancer 负载均衡] LB --> Backend[Backend 后端管理] Backend --> HC[Health Checker 健康检查] Backend --> CM[Connection Manager 连接管理] Backend --> Server1[(PostgreSQL 主节点)] Backend --> Server2[(PostgreSQL 备节点 1)] Backend --> Server3[(PostgreSQL 备节点 2)] HC -->|健康检查| Server1 HC -->|健康检查| Server2 HC -->|健康检查| Server3 CM --> SE[Statistics Engine 统计引擎]C. 请求处理流程sequenceDiagram participant C as 客户端 participant H as HAProxy participant P as Patroni/PostgreSQL C->>H: 1. 发起连接 H->>H: 2. Accept Connection H->>H: 3. Parse Request H->>H: 4. Route Request H->>H: 5. Select Server（读写分离） H->>P: 6. Connect to Server P-->>H: 7. Connection Established C->>H: 8. Proxy Traffic H->>P: 9. Forward Request P-->>H: 10. Response H-->>C: 11. Process Response H->>C: 12. Close ConnectionD. 健康检查配置default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions inter 3s # 健康检查间隔 3 秒 fall 3 # 连续 3 次失败标记为 down rise 2 # 连续 2 次成功标记为 up option pgsql-check # PostgreSQL 专用健康检查 timeout connect 5s # 连接超时 5 秒 timeout server 30s # 服务器响应超时 30 秒E. 负载均衡算法Round Robin：轮询算法，默认方式Least Connections：最少连接算法Source IP Hashing：源 IP 哈希算法URI Hashing：URI 哈希算法F. 健康检查类型TCP Check：TCP 端口连通性检查HTTP Check：HTTP 请求和响应检查SSL Check：SSL 证书和连接检查PostgreSQL Check：PostgreSQL 数据库检查2. Keepalived 组件A. 组件职责Keepalived 通过 VRRP 协议实现虚拟 IP 高可用，为 HAProxy 主备节点提供心跳检测与故障切换，确保负载均衡层无单点故障。B. 核心架构graph TB VRRP[VRRP 模块] -->|心跳广播| Master[主节点 Priority 100] VRRP -->|心跳广播| Backup[备节点 Priority 90] Master -->|持有 VIP| VIP[虚拟 IP 192.168.231.140] Backup -->|待机| VIP HC[健康检查模块] -->|监控 HAProxy| Master HC -->|监控 HAProxy| Backup HC -->|优先级调整| VRRP SE[脚本执行器] -->|chk_haproxy.sh| HC NS[通知系统] -->|状态变化告警| VRRP IPVS[IPVS 集成] -->|负载均衡| VRRPC. VRRP 状态转换stateDiagram-v2 [*] --> INIT: 系统启动 INIT --> BACKUP: 初始化完成 BACKUP --> MASTER: 收到更高优先级广告 或选举超时 MASTER --> BACKUP: 收到更高优先级广告 MASTER --> FAULT: 健康检查失败 BACKUP --> FAULT: 健康检查失败 FAULT --> BACKUP: 故障恢复D. 配置示例vrrp_instance VI_1 { state MASTER # 主节点 MASTER，备节点 BACKUP interface eth0 # 网络接口 virtual_router_id 51 # 虚拟路由 ID priority 100 # 主节点优先级 100，备节点 90 advert_int 1 # VRRP 心跳广播间隔 1 秒 authentication { auth_type PASS auth_pass 62f7f8e5 } virtual_ipaddress { 192.168.231.140/24 # 虚拟 IP 地址 } } vrrp_script chk_haproxy { script "/check/haproxy.sh" interval 3 # 检查间隔 3 秒 timeout 2 # 超时时间 2 秒 rise 2 # 成功阈值 2 次 fall 3 # 失败阈值 3 次 weight -30 # 优先级调整权重 }E. 故障处理机制主节点故障：自动选举新主节点，VIP 无缝转移健康检查失败：优先级自动调整，触发状态切换服务恢复：自动回到正常状态，重新参与选举四、分布式一致性层设计1. ETCD 组件A. 组件职责ETCD 是基于 Raft 协议的分布式键值存储，为 Patroni 集群提供强一致性的状态存储与共识服务：记录数据库节点角色信息存储 Leader 选举信息维护集群配置数据保障 Leader 选举唯一性，防止脑裂B. 核心架构graph TB Client[Patroni 客户端] --> API[API Server] API --> Raft[Raft 一致性模块] Raft --> Log[日志存储] Raft --> Snapshot[快照存储] Raft --> WAL[WAL 预写日志] Log --> Store[(键值存储)] Snapshot --> Store WAL --> Store Raft -->|心跳广播| Node1[ETCD 节点 1] Raft -->|心跳广播| Node2[ETCD 节点 2] Raft -->|心跳广播| Node3[ETCD 节点 3]C. Raft 选举流程sequenceDiagram participant F1 as Follower 节点 1 participant F2 as Follower 节点 2 participant F3 as Follower 节点 3 participant L as Leader Note over F1,F3: Step 1: Follower State 等待 Leader 心跳 F3->>F3: Election Timeout 超时 Note over F1,F3: Step 2: Election Timeout 触发选举 F3->>F3: 转换为 Candidate State Note over F1,F3: Step 3: Candidate State 增加任期，发起投票 F3->>F1: RequestVote (任期 N) F3->>F2: RequestVote (任期 N) Note over F1,F3: Step 4: Vote Collection 收集投票 F1-->>F3: 投票同意 F2-->>F3: 投票同意 Note over F1,F3: Step 5: Leader Election 获得多数票成为 Leader F3->>F3: 成为 Leader Note over F1,F3: Step 6: Leader State 发送心跳维持权威 F3->>F1: AppendEntries 心跳 F3->>F2: AppendEntries 心跳D. 选举参数配置--heartbeat-interval=100ms # Leader 心跳间隔 --election-timeout=1000ms # 选举超时时间 --min-election-timeout=1000ms # 最小选举超时 --max-election-timeout=2000ms # 最大选举超时 --initial-election-tick-advance=true # 初始选举优化五、进程监控层设计1. Watchdog 组件A. 组件职责Watchdog 通过接收 Patroni 的定时心跳来监控其运行状态：监控 Patroni 进程健康状态检测进程假死或心跳超时触发服务或系统重启防止故障节点导致脑裂B. 核心架构graph TB Patroni[Patroni 进程] -->|每 10 秒心跳| WD[Watchdog 监控器] WD -->|心跳超时 30 秒| Systemd[Systemd 服务管理器] Systemd -->|重启服务| Patroni WD -->|最后手段| Kernel[Linux Kernel Watchdog] Kernel -->|强制重启| SystemC. 配置示例# Watchdog 配置 watchdog: mode: automatic safety_margin: 5 # 安全裕度 5 秒 interval: 10 # 心跳间隔 10 秒 timeout: 30 # 超时时间 30 秒 # Systemd 服务配置 [Service] WatchdogSec=30s # 看门狗超时 30 秒 Restart=on-failure # 失败时重启 RestartSec=1s # 重启间隔 1 秒 StartLimitBurst=3 # 启动限制次数 StartLimitInterval=60s # 启动限制时间窗口D. 故障场景处理脑裂问题：多个主节点同时存在进程假死：Patroni 进程存在但无响应网络分区：节点与 ETCD 集群隔离资源耗尽：CPU、内存或磁盘资源不足E. 恢复处理流程graph TB Start[故障检测] --> Check{心跳超时?} Check -->|是| Alert[告警通知] Check -->|否| Monitor[继续监控] Alert --> Restart[服务重启] Restart --> Success{恢复成功?} Success -->|是| Verify[恢复验证] Success -->|否| SystemReboot[系统重启] SystemReboot --> Verify Verify --> End[恢复完成] Monitor --> StartF. 防止脑裂机制心跳超时检测：30 秒内未收到心跳触发告警自动重启机制：防止故障节点继续写入数据集群状态验证：与 ETCD 集群状态对比数据一致性检查：验证 WAL 日志位置六、数据库集群层设计1. Patroni 组件A. 组件职责Patroni 是 PostgreSQL 高可用架构的核心管家：实现自动化的主备选举执行故障检测与故障转移实时监控数据库状态维护集群配置一致性协调主备节点的流复制同步对接 HAProxy 实现流量智能路由B. 核心架构graph TB EM[Election Manager 选举管理器] -->|状态转换| HM[Health Monitor 健康监控器] HM -->|节点状态检测| PG[PostgreSQL 数据库] EM -->|分布式共识| EC[ETCD Client] EC -->|存储/读取状态| ETCD[(ETCD 集群)] PG -->|角色信息| HM HM -->|健康检查| EM EM -->|REST API| API[REST API 接口] API -->|状态查询| Monitor[监控系统] API -->|手动干预| Admin[管理员]C. 选举状态流程stateDiagram-v2 [*] --> INIT: 系统初始化 INIT --> FOLLOWER: 加入集群 FOLLOWER --> CANDIDATE: Leader 故障检测 CANDIDATE --> LEADER: 获得多数票 CANDIDATE --> FOLLOWER: 未获得多数票 LEADER --> DEMOTED: 主动降级或故障 DEMOTED --> FOLLOWER: 降级完成 LEADER --> FOLLOWER: 重新选举D. 选举流程详解sequenceDiagram participant F1 as Follower 节点 1 participant F2 as Follower 节点 2 participant F3 as Follower 节点 3 participant E as ETCD 集群 participant PG as PostgreSQL Note over F1,F3: 故障检测 F1->>E: 检测 Leader 心跳超时 F2->>E: 检测 Leader 心跳超时 Note over F1,F3: 触发选举 F1->>F1: 转换为 CANDIDATE F1->>E: 请求投票 F2->>E: 投票给 F1 Note over F1,F3: 收集选票 E-->>F1: 获得多数票 F1->>F1: 成为 Leader Note over F1,F3: 提升 PostgreSQL F1->>PG: 提升为主节点 PG-->>F1: 提升成功 Note over F1,F3: 通知集群 F1->>E: 更新集群状态 E-->>F2: 新 Leader 通知 E-->>F3: 新 Leader 通知E. 配置示例dcs: ttl: 30 # Leader 租约超时时间 30 秒 loop_wait: 10 # 心跳发送间隔 10 秒 retry_timeout: 10 # 重试超时时间 10 秒 maximum_lag_on_failover: 1048576 # 最大复制延迟 1MB election: retry_timeout: 10 # 选举重试超时 10 秒 maximum_retry_timeout: 30 # 最大选举重试超时 30 秒 retry_interval: 2 # 选举重试间隔 2 秒 priority: 100 # 节点优先级F. 防止脑裂机制ETCD 共识保障：使用分布式锁和租约机制多数票原则：必须获得集群多数节点的支持自动降级机制：故障节点自动降级避免数据不一致七、技术选型1. 技术栈对比组件层次技术选型替代方案选择理由负载均衡HAProxyNginx、LVS性能优秀、PostgreSQL 专用健康检查VIP 高可用KeepalivedHeartbeat轻量级、配置简单、VRRP 标准分布式共识ETCDConsul、ZooKeeperRaft 协议、强一致性、Go 语言高性能数据库高可用PatroniRePM、PgpoolPython 开发、社区活跃、功能完善进程监控WatchdogMonit系统级保障、硬件级重启能力2. 性能指标故障检测时间：10-30 秒故障切换时间：毫秒级数据零丢失：基于同步复制支持 5 万+ QPS八、高可用机制分析1. 多层级高可用保障graph TB subgraph 第一层 VIP[虚拟 IP] --> Keep[Keepalived 主备] end subgraph 第二层 Keep --> HA[HAProxy 负载均衡] end subgraph 第三层 HA --> Pat[Patroni 集群] end subgraph 第四层 Pat --> PG[PostgreSQL 主备] end subgraph 第五层 Pat --> ETCD[ETCD 共识] WD[Watchdog] -.监控.-> Pat end2. 故障场景处理故障类型检测方式恢复机制恢复时间HAProxy 主节点故障Keepalived 健康检查VIP 切换至备节点3-5 秒PostgreSQL Leader 故障Patroni 健康监控自动选举新 Leader20-30 秒Patroni 进程假死Watchdog 心跳检测强制重启服务/系统30-60 秒ETCD 节点故障Raft 协议自动选举新 ETCD Leader1-2 秒网络分区多数票原则隔离少数派节点选举超时九、监控告警1. 监控指标HAProxy 层：连接数、队列长度、响应时间、后端节点状态Keepalived 层：VIP 状态、VRRP 状态、节点优先级Patroni 层：节点角色、复制延迟、选举状态PostgreSQL 层：连接数、TPS、锁等待、WAL 位置ETCD 层：集群健康、Leader 状态、提案延迟Watchdog 层：心跳状态、重启次数2. 告警规则VIP 切换告警PostgreSQL 主备切换告警复制延迟超阈值告警ETCD 集群成员变更告警Watchdog 触发重启告警十、参考资料Patroni + HAProxy + Keepalived + ETCD 搭建高可用 PostgreSQL 集群
自建CA 手动生成rsa1024的证书并配置nginx实现嵌入式设备ssl加密
一、自建证书+nginx ssl配置使用openssl创建rsa1024根证书，并签发*.example.cn 30年有效期证书要使用 OpenSSL 创建一个 RSA 1024 位的根证书，并签发一个包含通配符的域名证书，可以按照以下步骤进行：（1）创建 RSA 1024 位的根证书（Root CA）：生成根密钥（私钥）：openssl genrsa -out root.key 1024生成自签名的根证书（公钥）：openssl req -x509 -new -nodes -key root.key -days 10950 -out root.crt在证书请求期间，填写相关证书信息。10950 天是根证书的有效期，约合30年。（2）创建通配符域名证书（Wildcard Certificate）：生成域名私钥：openssl genrsa -out domain.key 1024生成域名证书签名请求（CSR）：openssl req -new -key domain.key -out domain.csr在证书请求期间，填写通配符域名 *.example.cn 作为 Common Name (CN)。使用根证书签署域名证书：openssl x509 -req -in domain.csr -CA root.crt -CAkey root.key -CAcreateserial -out domain.crt -days 10950现在，您已经创建了包含通配符域名的证书 domain.crt，其有效期为30年，同时也拥有一个根证书 root.crt 用于签署该域名证书。确保在真实环境中使用更强大的密钥长度和更合适的证书有效期。此外，在生产环境中建议谨慎保管您的私钥和根证书，以防止密钥泄露或篡改。（3）如何调整nginx以允许rsa 1024的证书server { listen 192.168.23.225:3001 ssl; server_name example.cn; access_log /var/log/nginx/example.cn.a.log main; error_log /var/log/nginx/example.e.log; ssl_certificate /etc/nginx/cert.d/test/example.cn.crt; ssl_certificate_key /etc/nginx/cert.d/test/example.cn.key; ssl_session_timeout 5m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:AES128-SHA:!NULL:!aNULL:!MD5:!ADH:!RC4:!DH:!DHE; ssl_prefer_server_ciphers on; location / { proxy_pass http://example; proxy_set_header Host $host; proxy_http_version 1.1; proxy_read_timeout 120s; proxy_set_header X-real-ip $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } 二、TCP后端+Nginx Stream做完上面的配置后，后端是不通的，询问同事后端跑的啥业务，测试不通过，心底没底。后来得知，后端直接是TCP协议，用于接收物联网设备的数据。具体说，这个TCP已经实现了端到端AES对称加密，但是用户还想用SSL来一层非对称加密。而且指明了使用RSA 1024。然后，同事还给了一个方案，通过使用Nginx的Stream模块，加上SSL证书实现安全通信。这个吗，听说过stream作为TCP负载均衡，还真没听说过这个里面还有SSL。不过，经过搜索，还真有，而且在官网也看到了相关资料。走运的是，本来以为还得下载编译nginx模块，没想到直接带了。nginx version: nginx/1.22.0 built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) built with OpenSSL 1.0.2k-fips 26 Jan 2017 TLS SNI support enabled configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie' （1）配置Stream+TCP+SSL# 在nginx.conf配置文件中增加如下配置 stream { log_format stream_log_format '$remote_addr [$time_local] ' '$protocol $status $bytes_sent $bytes_received ' '$session_time "$upstream_addr" ' '"$upstream_bytes_sent" "$upstream_bytes_received" "$upstream_connect_time"'; open_log_file_cache off; include /etc/nginx/stream.d/test/appname/*.conf; } # 在include的文件里面配置 # cat /etc/nginx/stream.d/test/xxx/xxx.conf upstream xxx { server 127.0.0.1:7005 weight=2 max_fails=3 fail_timeout=20s; } server { listen 3000; access_log /var/log/nginx/xxx.a.log stream_log_format; error_log /var/log/nginx/xxx.e.log; proxy_pass bziot-alarmcomet; } server { listen 3001 ssl; access_log /var/log/nginx/xxx.ssl.a.log stream_log_format; error_log /var/log/nginx/xxx.ssl.e.log; ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; ssl_ciphers AES128-SHA:AES256-SHA:RC4-SHA:DES-CBC3-SHA:RC4-MD5; ssl_certificate /etc/nginx/cert.d/test/huarunbaizun.test.stesh.cn.crt; ssl_certificate_key /etc/nginx/cert.d/test/huarunbaizun.test.stesh.cn.key; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; proxy_ssl off; proxy_pass xxx; } （3）测试不挂载CA证书，使用openssl测试挂载CA证书，使用openssl测试
在一些认证网站域名所主的时候，经常会要求在网站根目录下面放置一个特殊的txt文件。但是，有些时候网站是一个反向代理，可以通过如下一个简单的小技巧实现这种验证需求。location /N7dcmP1dsD.txt { return 200 "7eb1d5db3520bd7c8ebbf3a0dc55c06e"; }假设对方让把一个文件名称为N7dcmP1dsD.txt，内容为7eb1d5db3520bd7c8ebbf3a0dc55c06e的文件放在网站根目录下。那么，我们可以在nginx里面的server配置里面，通过增加location的形式增加内容。
一、背景公司接了一个项目，其中一个模块使用websocket连接，但是配置过后还是不行。经过排查，最终实现了websocket的配置和验证。配置中需要注意的是：配置nginx的时候，注意是否配置了证书，以及证书是否正确。使用curl 后端程序+websocket端口+websocket路径是否正确。使用postman或者在线测试是否工作正常。二、拓扑2024-04-16T02:44:41.png（1）nginxupstream ws-xxx { server 127.0.0.1:7003 weight=2 max_fails=3 fail_timeout=20s; } map $http_upgrade $conn_upgrade { default upgrade; '' close; } server { listen 80; server_name xxx; access_log /var/log/nginx/xxx.a.log main; error_log /var/log/nginx/xxx.e.log; location /ngx_status { stub_status on; access_log off; } location / { proxy_passhttp://xxx; proxy_redirect off; proxy_set_headerHost $host; proxy_set_headerX-real-ip $remote_addr; proxy_set_headerX-Forwarded-For $proxy_add_x_forwarded_for; } } server { listen xxx ssl; server_name xxx; access_log /var/log/nginx/xxx main; error_log /var/log/nginx/xxxe.log; ssl_certificate /etc/nginx/cert.d/xxx; ssl_certificate_key /etc/nginx/cert.d/xxx; ssl_session_timeout 5m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4:!DH:!DHE; ssl_prefer_server_ciphers on; location / { proxy_passhttp://xxx; proxy_set_header Host $host; proxy_http_version 1.1; proxy_read_timeout 120s; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_set_header X-real-ip $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; add_header Set-Cookie "Path=/; HttpOnly; Secure"; if ($request_uri ~* "css$|js$|png$|jpg$") { add_header Cache-Control max-age=86400; } } location /ws { proxy_pass http://xxx; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connetion $conn_upgrade; } } （2）后端程序使用curl本地测试后端服务程序正常。[root@xxx-test]# curl 192.168.177.66:2301/ws not a WebSocket handshake request: missing upgrade （3）frpc使用frpc打通内网websocket端口到带有公网ip地址的公网服务器。serverAddr = "xxx" serverPort = 7000 proxies name = "user-comet" type = "tcp" localIP = "192.168.177.66" localPort = 2301 remotePort = 7003 其他在线nginx美化在线websocket测试
server { listen 80 default_server; listen 443 ssl http2 default_server; server_name www.sddts.cn sddts.cn; index index.php index.html index.htm default.php default.htm default.html; root /www/wwwroot/www.sddts.cn; ssl_certificate /www/server/panel/vhost/cert/www.sddts.cn/fullchain.pem; ssl_certificate_key /www/server/panel/vhost/cert/www.sddts.cn/privkey.pem; ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; add_header Strict-Transport-Security "max-age=31536000"; error_page 497 https://$host$request_uri; #清理缓存规则 location ~ /purge(/.*) { proxy_cache_purge cache_one $host$1$is_args$args; #access_log /www/wwwlogs/www.sddts.cn_purge_cache.log; } #PROXY-START/ location ^~ / { proxy_pass http://172.18.19.31; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header REMOTE-HOST $remote_addr; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_http_version 1.1; # proxy_hide_header Upgrade; add_header X-Cache $upstream_cache_status; #Set Nginx Cache set $static_file4w7i7J04 0; if ( $uri ~* "\.(gif|png|jpg|css|js|woff|woff2)$" ) { set $static_file4w7i7J04 1; expires 1m; } if ( $static_file4w7i7J04 = 0 ) { add_header Cache-Control no-cache; } } #禁止访问的文件或目录 location ~ ^/(\.user.ini|\.htaccess|\.git|\.env|\.svn|\.project|LICENSE|README.md) { return 404; } #一键申请SSL证书验证目录相关设置 location ~ \.well-known{ allow all; } access_log /www/wwwlogs/www.sddts.cn.log; error_log /www/wwwlogs/www.sddts.cn.error.log; }