This is an automated email from the ASF dual-hosted git repository.

morningman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris-website.git


The following commit(s) were added to refs/heads/master by this push:
     new 93d1bb1eeb7 [docs] Add NJet FE load balancing guide for dev and 4.x 
(#3112)
93d1bb1eeb7 is described below

commit 93d1bb1eeb73f26c6b6884f215e579d9f265ce5c
Author: yuanyuan8983 <[email protected]>
AuthorDate: Sat Oct 17 05:41:00 2026 +0800

    [docs] Add NJet FE load balancing guide for dev and 4.x (#3112)
    
    ## Summary
    
    Add NJet as a fifth FE load-balancing option for dev and 4.x, with
    English and Chinese counterparts. Keep the existing option heading
    anchors and append the NJet section after ProxySQL.
    
    - Provide complete data-plane and control-plane configurations for the
    pinned official `tmlake/njet:4.0.2.0` image, including Docker
    configuration mounts and publication of port 6030.
    - Correct the helper paths, shared-memory size, missing events block,
    explicit MySQL health-check module, and required data-plane HTTP
    initialization for administration APIs.
    - Cover backend-list queries, dynamic FE addition/removal with returned
    IDs, and active SQL health checks with a dedicated Doris
    account/database and a TLS setting that matches the FE listener.
    - Explain connection-based distribution, source-IP hashing, timeouts,
    and why the MySQL TCP endpoint does not cover Stream Load HTTP
    redirects.
    - Replace the stale installation URLs and incomplete APT/JSON fragments
    with maintained upstream references.
    - Scope this update to dev and 4.x; the original additions to older
    versions are omitted from the final diff.
    
    ## Validation
    
    - Read OpenNJet official source at
    `04c6b39e6e12d9d6d9bb42e47b3e0b423b3923e5`, including stream proxying,
    upstream APIs, and MySQL health-check parsing/registration.
    - Checked Doris MySQL protocol handling and Stream Load redirect
    behavior in the corresponding source branches.
    - Ran the official `tmlake/njet:4.0.2.0` image
    (`sha256:d0f33aa9575decf2613235629dae8ff799e2f039bd1e5e6cdc833c4a946aa313`)
    locally:
      - `njet -t` succeeds for both configuration files.
      - Backend-list GET returns HTTP 200 and all three configured members.
    - Member POST returns HTTP 201 with ID 3; DELETE returns HTTP 200 and
    removes that member.
    - MySQL health-check configuration POST/GET returns HTTP 200 and the
    submitted configuration.
    - The test container was removed after verification. No live Doris
    backend query or successful SQL health probe was exercised in this
    container test.
    - `git diff --check` and Docusaurus Markdown/MDX compilation pass for
    all four pages. Documentation governance checks introduce no errors.
    
    ---------
    
    Co-authored-by: morningman <[email protected]>
---
 .../cluster-management/load-balancing.md           | 189 +++++++++++++++++++-
 .../cluster-management/load-balancing.md           | 191 ++++++++++++++++++++-
 .../cluster-management/load-balancing.md           | 191 ++++++++++++++++++++-
 .../cluster-management/load-balancing.md           | 189 +++++++++++++++++++-
 4 files changed, 750 insertions(+), 10 deletions(-)

diff --git a/docs/admin-manual/cluster-management/load-balancing.md 
b/docs/admin-manual/cluster-management/load-balancing.md
index ee620f8c336..71f35579c44 100644
--- a/docs/admin-manual/cluster-management/load-balancing.md
+++ b/docs/admin-manual/cluster-management/load-balancing.md
@@ -2,7 +2,7 @@
 {
     "title": "FE Load Balancing",
     "language": "en",
-    "description": "Load balancing options for multi-FE Doris deployments: 
JDBC, Nginx, HAProxy, ProxySQL, plus client IP forwarding via Proxy Protocol.",
+    "description": "Load balancing options for multi-FE Doris deployments: 
JDBC, Nginx, HAProxy, ProxySQL, NJet, plus client IP forwarding via Proxy 
Protocol.",
     "keywords": [
         "Doris load balancing",
         "FE high availability",
@@ -11,6 +11,7 @@
         "Nginx TCP reverse proxy",
         "HAProxy",
         "ProxySQL",
+        "NJet",
         "Proxy Protocol",
         "client IP forwarding",
         "query_port 9030",
@@ -25,7 +26,7 @@
 
 Users connect to Doris over the MySQL protocol through the FE query port 
(`query_port`, default `9030`). When multiple FE nodes are deployed, you can 
place a load balancing layer in front of the FEs to provide high availability 
and connection distribution for the Doris query entry point.
 
-This document describes four load balancing options for Doris and explains how 
to forward the real client IP through the proxy layer using Proxy Protocol.
+This document describes five load balancing options for Doris and explains how 
to forward the real client IP through the proxy layer using Proxy Protocol.
 
 ## Applicable Scenarios
 
@@ -35,6 +36,7 @@ This document describes four load balancing options for Doris 
and explains how t
 | Existing Nginx infrastructure, TCP-layer reverse proxy required | Nginx | 
General-purpose TCP reverse proxy, simple configuration |
 | High-performance TCP proxy with health checks required | HAProxy | Dedicated 
TCP/HTTP load balancer with a rich set of health-check strategies |
 | MySQL protocol-aware proxy required (connection management, read/write 
splitting, etc.) | ProxySQL | Database proxy designed for the MySQL protocol |
+| Dynamic FE membership and active SQL health checks required | NJet | TCP 
proxy with optional management APIs |
 | Need to preserve the real client IP behind the load balancer | Proxy 
Protocol | Used together with Nginx or HAProxy |
 
 ## Prerequisites
@@ -602,6 +604,189 @@ ProxySQL > select * from mysql_server_ping_log;
 110 rows in set (0.001 sec)
 ```
 
+### Option 5: NJet
+
+[OpenNJet](https://github.com/OpenNJet/OpenNJet) provides TCP proxying, 
dynamic upstream management, and optional active MySQL health checks. The 
following example uses the same proxy and FE addresses as the preceding 
sections.
+
+The proxy distributes **connections**. An established MySQL session remains on 
one FE; it does not distribute each SQL statement or replay an interrupted 
query. These settings cover the FE MySQL port. Stream Load uses the HTTP 
endpoint and can redirect to a BE; the client must be able to reach the address 
returned by that redirect.
+
+#### Prepare NJet and the Configuration Files
+
+The example uses the official `tmlake/njet:4.0.2.0` image and its 
`/usr/local/njet` installation prefix. This image is Linux/AMD64; use a 
matching image or configure emulation on ARM hosts. For native installation, 
see the [OpenNJet quick start](https://njet.org.cn/docs/quickstart/), and 
adjust module/configuration paths to your installation.
+
+Save the following two files in the same directory. The FE addresses must be 
reachable from the container.
+
+**`njet.conf` (data plane):**
+
+```text
+worker_processes 1;
+cluster_name njet;
+node_name node1;
+
+helper ctrl modules/njt_helper_ctrl_module.so conf/njet_ctrl.conf;
+helper broker modules/njt_helper_broker_module.so;
+load_module modules/njt_http_upstream_member_module.so;
+
+events {
+    worker_connections 1024;
+}
+stream {
+    upstream mysqld {
+        zone mysqld 128k;
+        hash $remote_addr consistent;
+        server 192.168.1.101:9030 weight=1 max_fails=2 fail_timeout=60s;
+        server 192.168.1.102:9030 weight=1 max_fails=2 fail_timeout=60s;
+        server 192.168.1.103:9030 weight=1 max_fails=2 fail_timeout=60s;
+    }
+    server {
+        listen 6030;
+        proxy_connect_timeout 5s;
+        proxy_timeout 300s;
+        proxy_pass mysqld;
+    }
+}
+http {
+    dyn_kv_conf conf/iot-work.conf;
+}
+```
+
+The `http` block initializes the data-plane modules used by the management 
APIs, even though Doris traffic is forwarded by `stream`. The helper uses 
`conf/njet_ctrl.conf`; it does not use a separate `conf/ctrl.conf` or 
`conf/mqtt.conf` in this example.
+
+**`njet_ctrl.conf` (control plane):**
+
+```text
+load_module modules/njt_http_sendmsg_module.so;
+load_module modules/njt_http_upstream_api_module.so;
+load_module modules/njt_helper_health_check_module.so;
+load_module modules/njt_health_check_mysql_module.so;
+
+events {
+    worker_connections 1024;
+}
+http {
+    server {
+        listen 127.0.0.1:8081;
+        location /api {
+            dyn_module_api;
+        }
+    }
+}
+```
+
+The MySQL health-check module must be loaded explicitly. The management API 
listens on loopback inside the container; the examples access it with `docker 
exec`.
+
+#### Start and Verify
+
+Run from the directory containing both configuration files:
+
+```shell
+docker run -d --name doris-njet \
+  --platform linux/amd64 \
+  --cap-add=NET_ADMIN --cap-add=DAC_READ_SEARCH \
+  -p 6030:6030 \
+  -v "$PWD/njet.conf:/usr/local/njet/conf/njet.conf:ro" \
+  -v "$PWD/njet_ctrl.conf:/usr/local/njet/conf/njet_ctrl.conf:ro" \
+  tmlake/njet:4.0.2.0
+```
+
+Validate both files and inspect the backend list:
+
+```shell
+docker exec doris-njet njet -t
+docker exec doris-njet curl --max-time 10 -sS \
+  http://127.0.0.1:8081/api/v1/upstream_api/stream/upstreams/mysqld/servers/
+```
+
+`njet -t` reports successful validation for both configuration files. The API 
returns HTTP 200 and a JSON array containing the three configured FEs. Connect 
through the proxy, replacing `doris_user` with an existing Doris account:
+
+```shell
+mysql -h192.168.1.100 -P6030 -u doris_user -p -e 'SELECT 1 AS connection_test;'
+```
+
+```text
++-----------------+
+| connection_test |
++-----------------+
+|               1 |
++-----------------+
+```
+
+Key settings:
+
+| Setting | Example | Effect |
+| --- | --- | --- |
+| `zone` | `mysqld 128k` | Shared state required for dynamic upstream 
management. |
+| `hash` | `$remote_addr consistent` | Assigns new connections using a 
consistent hash of client IP. Clients sharing one source IP may reach the same 
FE. |
+| `max_fails` / `fail_timeout` | `2` / `60s` | Passive failure detection for 
backend connections. This does not configure active SQL checks. |
+| `listen` | `6030` | Proxy's MySQL-protocol port. Docker publishes it with 
`-p 6030:6030`. |
+| `proxy_connect_timeout` / `proxy_timeout` | `5s` / `300s` | Backend 
connection timeout and proxy inactivity timeout. Adapt these to your 
query/session requirements. |
+
+#### Dynamically Add and Remove an FE
+
+To add an FE, send:
+
+```shell
+docker exec doris-njet curl --max-time 10 -i \
+  -H 'Content-Type: application/json' \
+  -d 
'{"server":"192.168.1.104:9030","weight":2,"max_fails":1,"fail_timeout":"5s"}' \
+  http://127.0.0.1:8081/api/v1/upstream_api/stream/upstreams/mysqld/servers/
+```
+
+The API returns HTTP 201 and the new member, including its assigned `id`. For 
the initial three-member configuration, the first new member has ID 3. Use the 
actual returned ID when deleting it:
+
+```shell
+docker exec doris-njet curl --max-time 10 -i -X DELETE \
+  http://127.0.0.1:8081/api/v1/upstream_api/stream/upstreams/mysqld/servers/3
+```
+
+Deletion returns HTTP 200; a subsequent GET no longer lists that member. Keep 
the configuration files consistent with your intended membership before 
recreating the container.
+
+#### Configure Active MySQL Health Checks
+
+Active SQL checks require an explicit API configuration and a working Doris 
account/database. Run the following as a Doris administrator, replacing the 
password:
+
+```sql
+CREATE DATABASE IF NOT EXISTS health_check_db;
+CREATE USER IF NOT EXISTS 'njet_health'@'%' IDENTIFIED BY 
'<replace-with-password>';
+GRANT SELECT_PRIV ON health_check_db.* TO 'njet_health'@'%';
+```
+
+Use the same password in the request below. `useSsl` is `false` for a non-TLS 
FE listener; set it to `true` only when the FE listener is configured for TLS.
+
+```shell
+docker exec doris-njet curl --max-time 10 -i \
+  -H 'Content-Type: application/json' \
+  -d '{
+    "interval":"5s",
+    "jitter":"1s",
+    "timeout":"5s",
+    "passes":1,
+    "fails":1,
+    "sql":{
+      "select":"select 1",
+      "useSsl":false,
+      "user":"njet_health",
+      "password":"<replace-with-password>",
+      "db":"health_check_db"
+    }
+  }' \
+  http://127.0.0.1:8081/api/v1/hc/smysql/mysqld
+```
+
+A successful configuration returns HTTP 200 with `{"code":0,"msg":"success"}`. 
Subsequent checks authenticate, select the configured database, and execute 
`select 1` against each FE.
+
+| Field | Required / Default | Description |
+| --- | --- | --- |
+| `interval`, `jitter`, `timeout` | Set explicitly in this example | Check 
interval, timer jitter, and timeout, expressed as durations. |
+| `passes`, `fails` | Set explicitly in this example | Consecutive 
successes/failures required to change health state. |
+| `port` | Optional; upstream server port | Override the port used for checks. 
|
+| `sql.select` | Set explicitly | SQL statement used to validate the FE. |
+| `sql.useSsl` | Optional; NJet defaults to `true` | Must match the FE 
listener's TLS setting. |
+| `sql.user`, `sql.password` | Set for the Doris account | Credentials used by 
the health checker. |
+| `sql.db` | Required, nonempty | Existing database selected by the checker. |
+
+If the API times out, verify the helper paths and the data-plane `http` block. 
If a health check fails, verify the database, credentials, network 
reachability, and TLS setting; a successful configuration response alone does 
not prove the FE is healthy. For more details, see the [OpenNJet source and 
documentation](https://github.com/OpenNJet/OpenNJet) and [JSON configuration 
format](https://njet.org.cn/cases/njet_support_json/).
+
 ## Client IP Forwarding (Proxy Protocol)
 
 <!-- Knowledge type: Configuration parameter / Operational procedure -->
diff --git 
a/i18n/zh-CN/docusaurus-plugin-content-docs/current/admin-manual/cluster-management/load-balancing.md
 
b/i18n/zh-CN/docusaurus-plugin-content-docs/current/admin-manual/cluster-management/load-balancing.md
index 740929fbb1b..2c23f478259 100644
--- 
a/i18n/zh-CN/docusaurus-plugin-content-docs/current/admin-manual/cluster-management/load-balancing.md
+++ 
b/i18n/zh-CN/docusaurus-plugin-content-docs/current/admin-manual/cluster-management/load-balancing.md
@@ -2,7 +2,7 @@
 {
     "title": "FE 负载均衡",
     "language": "zh-CN",
-    "description": "介绍 Doris 多 FE 节点的负载均衡方案:JDBC、Nginx、HAProxy、ProxySQL,以及通过 
Proxy Protocol 实现客户端 IP 透传。",
+    "description": "介绍 Doris 多 FE 
节点的负载均衡方案:JDBC、Nginx、HAProxy、ProxySQL、NJet,以及通过 Proxy Protocol 实现客户端 IP 透传。",
     "keywords": [
         "Doris 负载均衡",
         "FE 高可用",
@@ -11,6 +11,7 @@
         "Nginx TCP 反向代理",
         "HAProxy",
         "ProxySQL",
+        "NJet",
         "Proxy Protocol",
         "客户端 IP 透传",
         "query_port 9030",
@@ -25,7 +26,7 @@
 
 用户通过 FE 的查询端口(`query_port`,默认 `9030`)使用 MySQL 协议连接 Doris。当部署多个 FE 节点时,可以在 FE 
之上部署负载均衡层,实现 Doris 查询入口的高可用与连接分发。
 
-本文档介绍四种适用于 Doris 的负载均衡方案,并说明如何通过 Proxy Protocol 在代理层后透传客户端真实 IP。
+本文档介绍五种适用于 Doris 的负载均衡方案,并说明如何通过 Proxy Protocol 在代理层后透传客户端真实 IP。
 
 ## 适用场景
 
@@ -35,6 +36,7 @@
 | 已有 Nginx 基础设施,需要 TCP 层反向代理 | Nginx | 通用 TCP 反向代理,配置简单 |
 | 需要高性能 TCP 代理与健康检查 | HAProxy | 专业 TCP/HTTP 负载均衡,支持丰富的健康检查策略 |
 | 需要 MySQL 协议感知的代理(连接管理、读写分离等) | ProxySQL | 面向 MySQL 协议的数据库代理 |
+| 需要动态管理上游 FE 并进行主动 SQL 健康检查 | NJet | TCP 代理及可选的管理 API |
 | 需要在负载均衡后保留客户端真实 IP | Proxy Protocol | 配合 Nginx 或 HAProxy 使用 |
 
 ## 前置条件
@@ -602,6 +604,189 @@ ProxySQL > select * from mysql_server_ping_log;
 110 rows in set (0.001 sec)
 ```
 
+### 方案五:NJet
+
+[OpenNJet](https://github.com/OpenNJet/OpenNJet) 提供 TCP 代理、动态上游管理以及可选的 MySQL 
主动健康检查。以下示例沿用前文的代理节点和 FE 地址。
+
+代理按**连接**分配流量。已建立的 MySQL 会话会保持在同一个 FE 上,不会逐条 SQL 分配,也不会重放中断的查询。这些配置只覆盖 FE 的 
MySQL 端口。Stream Load 使用 HTTP 端点,可能重定向到 BE;客户端需要能够访问重定向返回的地址。
+
+#### 准备 NJet 和配置文件
+
+示例使用官方 `tmlake/njet:4.0.2.0` 镜像,安装前缀为 `/usr/local/njet`。该镜像为 Linux/AMD64,ARM 
主机需要使用匹配的镜像或配置模拟运行。原生安装参见 [OpenNJet 
快速开始](https://njet.org.cn/docs/quickstart/),并按实际安装位置调整模块和配置路径。
+
+将以下两个文件保存到同一目录,确保容器能够访问 FE 地址。
+
+**`njet.conf`(数据面):**
+
+```text
+worker_processes 1;
+cluster_name njet;
+node_name node1;
+
+helper ctrl modules/njt_helper_ctrl_module.so conf/njet_ctrl.conf;
+helper broker modules/njt_helper_broker_module.so;
+load_module modules/njt_http_upstream_member_module.so;
+
+events {
+    worker_connections 1024;
+}
+stream {
+    upstream mysqld {
+        zone mysqld 128k;
+        hash $remote_addr consistent;
+        server 192.168.1.101:9030 weight=1 max_fails=2 fail_timeout=60s;
+        server 192.168.1.102:9030 weight=1 max_fails=2 fail_timeout=60s;
+        server 192.168.1.103:9030 weight=1 max_fails=2 fail_timeout=60s;
+    }
+    server {
+        listen 6030;
+        proxy_connect_timeout 5s;
+        proxy_timeout 300s;
+        proxy_pass mysqld;
+    }
+}
+http {
+    dyn_kv_conf conf/iot-work.conf;
+}
+```
+
+虽然 Doris 流量由 `stream` 转发,管理 API 仍需要 `http` 块来初始化数据面模块。Helper 使用 
`conf/njet_ctrl.conf`;本例不需要单独的 `conf/ctrl.conf` 或 `conf/mqtt.conf`。
+
+**`njet_ctrl.conf`(控制面):**
+
+```text
+load_module modules/njt_http_sendmsg_module.so;
+load_module modules/njt_http_upstream_api_module.so;
+load_module modules/njt_helper_health_check_module.so;
+load_module modules/njt_health_check_mysql_module.so;
+
+events {
+    worker_connections 1024;
+}
+http {
+    server {
+        listen 127.0.0.1:8081;
+        location /api {
+            dyn_module_api;
+        }
+    }
+}
+```
+
+必须显式加载 MySQL 健康检查模块。管理 API 监听容器内的回环地址,以下通过 `docker exec` 访问。
+
+#### 启动和验证
+
+在包含两个配置文件的目录中执行:
+
+```shell
+docker run -d --name doris-njet \
+  --platform linux/amd64 \
+  --cap-add=NET_ADMIN --cap-add=DAC_READ_SEARCH \
+  -p 6030:6030 \
+  -v "$PWD/njet.conf:/usr/local/njet/conf/njet.conf:ro" \
+  -v "$PWD/njet_ctrl.conf:/usr/local/njet/conf/njet_ctrl.conf:ro" \
+  tmlake/njet:4.0.2.0
+```
+
+检查两个配置文件并查看上游列表:
+
+```shell
+docker exec doris-njet njet -t
+docker exec doris-njet curl --max-time 10 -sS \
+  http://127.0.0.1:8081/api/v1/upstream_api/stream/upstreams/mysqld/servers/
+```
+
+`njet -t` 会报告两个配置文件均验证成功。API 返回 HTTP 200 和包含三个 FE 的 JSON 数组。通过代理连接 Doris,将 
`doris_user` 替换为已有的 Doris 用户:
+
+```shell
+mysql -h192.168.1.100 -P6030 -u doris_user -p -e 'SELECT 1 AS connection_test;'
+```
+
+```text
++-----------------+
+| connection_test |
++-----------------+
+|               1 |
++-----------------+
+```
+
+关键配置:
+
+| 配置 | 示例值 | 作用 |
+| --- | --- | --- |
+| `zone` | `mysqld 128k` | 动态上游管理需要的共享状态空间。 |
+| `hash` | `$remote_addr consistent` | 对客户端 IP 做一致性 Hash 以分配新连接。共享同一源 IP 
的客户端可能访问同一个 FE。 |
+| `max_fails` / `fail_timeout` | `2` / `60s` | 后端连接的被动失败检测,不会配置主动 SQL 检查。 |
+| `listen` | `6030` | 代理的 MySQL 协议端口,通过 Docker 的 `-p 6030:6030` 发布。 |
+| `proxy_connect_timeout` / `proxy_timeout` | `5s` / `300s` | 
后端建连超时及代理空闲超时,应按查询和会话需求调整。 |
+
+#### 动态添加和删除 FE
+
+添加 FE 的请求:
+
+```shell
+docker exec doris-njet curl --max-time 10 -i \
+  -H 'Content-Type: application/json' \
+  -d 
'{"server":"192.168.1.104:9030","weight":2,"max_fails":1,"fail_timeout":"5s"}' \
+  http://127.0.0.1:8081/api/v1/upstream_api/stream/upstreams/mysqld/servers/
+```
+
+API 返回 HTTP 201 和新成员信息,其中包含分配的 `id`。在初始三个成员的配置下,第一个新增成员的 ID 为 3。删除时应使用实际返回的 ID:
+
+```shell
+docker exec doris-njet curl --max-time 10 -i -X DELETE \
+  http://127.0.0.1:8081/api/v1/upstream_api/stream/upstreams/mysqld/servers/3
+```
+
+删除返回 HTTP 200,之后 GET 的列表中不再包含该成员。重新创建容器前,应使配置文件与预期成员列表保持一致。
+
+#### 配置 MySQL 主动健康检查
+
+主动 SQL 检查需要显式调用 API 配置,并准备可用的 Doris 账户和数据库。使用 Doris 管理员执行以下 SQL,并替换密码:
+
+```sql
+CREATE DATABASE IF NOT EXISTS health_check_db;
+CREATE USER IF NOT EXISTS 'njet_health'@'%' IDENTIFIED BY 
'<replace-with-password>';
+GRANT SELECT_PRIV ON health_check_db.* TO 'njet_health'@'%';
+```
+
+在下方请求中使用相同密码。对于未启用 TLS 的 FE 监听端口,`useSsl` 使用 `false`;只有 FE 监听端口已配置 TLS 时才设置为 
`true`。
+
+```shell
+docker exec doris-njet curl --max-time 10 -i \
+  -H 'Content-Type: application/json' \
+  -d '{
+    "interval":"5s",
+    "jitter":"1s",
+    "timeout":"5s",
+    "passes":1,
+    "fails":1,
+    "sql":{
+      "select":"select 1",
+      "useSsl":false,
+      "user":"njet_health",
+      "password":"<replace-with-password>",
+      "db":"health_check_db"
+    }
+  }' \
+  http://127.0.0.1:8081/api/v1/hc/smysql/mysqld
+```
+
+配置成功返回 HTTP 200 和 `{"code":0,"msg":"success"}`。后续健康检查会对每个 FE 完成认证、选择指定数据库并执行 
`select 1`。
+
+| 字段 | 是否必填 / 默认值 | 说明 |
+| --- | --- | --- |
+| `interval`、`jitter`、`timeout` | 本例显式设置 | 检查间隔、定时器抖动和超时,使用时间长度格式。 |
+| `passes`、`fails` | 本例显式设置 | 改变健康状态前,需要连续成功或失败的次数。 |
+| `port` | 可选;默认使用上游端口 | 覆盖检查使用的端口。 |
+| `sql.select` | 本例显式设置 | 用于验证 FE 的 SQL。 |
+| `sql.useSsl` | 可选;NJet 默认 `true` | 必须与 FE 监听端口的 TLS 配置匹配。 |
+| `sql.user`、`sql.password` | 根据 Doris 账户设置 | 健康检查使用的凭据。 |
+| `sql.db` | 必填且非空 | 检查器要选择的已有数据库。 |
+
+API 超时时,请检查 Helper 路径以及数据面的 `http` 块。健康检查失败时,请检查数据库、凭据、网络和 TLS 配置;配置请求成功并不代表 
FE 已健康。更多说明参见 [OpenNJet 源码和文档](https://github.com/OpenNJet/OpenNJet)及 [JSON 
配置格式](https://njet.org.cn/cases/njet_support_json/)。
+
 ## 客户端 IP 透传(Proxy Protocol)
 
 <!-- 知识类型: 配置参数 / 操作步骤 -->
@@ -671,7 +856,7 @@ backend forward-fe
 
 ### 验证 IP 透传是否成功
 
-1. 通过代理连接 Doris:
+1. 通过代理连接 Doris,将 `doris_user` 替换为已有的 Doris 用户:
 
     ```sql
     mysql -uroot -P6030 -h192.168.1.100
diff --git 
a/i18n/zh-CN/docusaurus-plugin-content-docs/version-4.x/admin-manual/cluster-management/load-balancing.md
 
b/i18n/zh-CN/docusaurus-plugin-content-docs/version-4.x/admin-manual/cluster-management/load-balancing.md
index 740929fbb1b..2c23f478259 100644
--- 
a/i18n/zh-CN/docusaurus-plugin-content-docs/version-4.x/admin-manual/cluster-management/load-balancing.md
+++ 
b/i18n/zh-CN/docusaurus-plugin-content-docs/version-4.x/admin-manual/cluster-management/load-balancing.md
@@ -2,7 +2,7 @@
 {
     "title": "FE 负载均衡",
     "language": "zh-CN",
-    "description": "介绍 Doris 多 FE 节点的负载均衡方案:JDBC、Nginx、HAProxy、ProxySQL,以及通过 
Proxy Protocol 实现客户端 IP 透传。",
+    "description": "介绍 Doris 多 FE 
节点的负载均衡方案:JDBC、Nginx、HAProxy、ProxySQL、NJet,以及通过 Proxy Protocol 实现客户端 IP 透传。",
     "keywords": [
         "Doris 负载均衡",
         "FE 高可用",
@@ -11,6 +11,7 @@
         "Nginx TCP 反向代理",
         "HAProxy",
         "ProxySQL",
+        "NJet",
         "Proxy Protocol",
         "客户端 IP 透传",
         "query_port 9030",
@@ -25,7 +26,7 @@
 
 用户通过 FE 的查询端口(`query_port`,默认 `9030`)使用 MySQL 协议连接 Doris。当部署多个 FE 节点时,可以在 FE 
之上部署负载均衡层,实现 Doris 查询入口的高可用与连接分发。
 
-本文档介绍四种适用于 Doris 的负载均衡方案,并说明如何通过 Proxy Protocol 在代理层后透传客户端真实 IP。
+本文档介绍五种适用于 Doris 的负载均衡方案,并说明如何通过 Proxy Protocol 在代理层后透传客户端真实 IP。
 
 ## 适用场景
 
@@ -35,6 +36,7 @@
 | 已有 Nginx 基础设施,需要 TCP 层反向代理 | Nginx | 通用 TCP 反向代理,配置简单 |
 | 需要高性能 TCP 代理与健康检查 | HAProxy | 专业 TCP/HTTP 负载均衡,支持丰富的健康检查策略 |
 | 需要 MySQL 协议感知的代理(连接管理、读写分离等) | ProxySQL | 面向 MySQL 协议的数据库代理 |
+| 需要动态管理上游 FE 并进行主动 SQL 健康检查 | NJet | TCP 代理及可选的管理 API |
 | 需要在负载均衡后保留客户端真实 IP | Proxy Protocol | 配合 Nginx 或 HAProxy 使用 |
 
 ## 前置条件
@@ -602,6 +604,189 @@ ProxySQL > select * from mysql_server_ping_log;
 110 rows in set (0.001 sec)
 ```
 
+### 方案五:NJet
+
+[OpenNJet](https://github.com/OpenNJet/OpenNJet) 提供 TCP 代理、动态上游管理以及可选的 MySQL 
主动健康检查。以下示例沿用前文的代理节点和 FE 地址。
+
+代理按**连接**分配流量。已建立的 MySQL 会话会保持在同一个 FE 上,不会逐条 SQL 分配,也不会重放中断的查询。这些配置只覆盖 FE 的 
MySQL 端口。Stream Load 使用 HTTP 端点,可能重定向到 BE;客户端需要能够访问重定向返回的地址。
+
+#### 准备 NJet 和配置文件
+
+示例使用官方 `tmlake/njet:4.0.2.0` 镜像,安装前缀为 `/usr/local/njet`。该镜像为 Linux/AMD64,ARM 
主机需要使用匹配的镜像或配置模拟运行。原生安装参见 [OpenNJet 
快速开始](https://njet.org.cn/docs/quickstart/),并按实际安装位置调整模块和配置路径。
+
+将以下两个文件保存到同一目录,确保容器能够访问 FE 地址。
+
+**`njet.conf`(数据面):**
+
+```text
+worker_processes 1;
+cluster_name njet;
+node_name node1;
+
+helper ctrl modules/njt_helper_ctrl_module.so conf/njet_ctrl.conf;
+helper broker modules/njt_helper_broker_module.so;
+load_module modules/njt_http_upstream_member_module.so;
+
+events {
+    worker_connections 1024;
+}
+stream {
+    upstream mysqld {
+        zone mysqld 128k;
+        hash $remote_addr consistent;
+        server 192.168.1.101:9030 weight=1 max_fails=2 fail_timeout=60s;
+        server 192.168.1.102:9030 weight=1 max_fails=2 fail_timeout=60s;
+        server 192.168.1.103:9030 weight=1 max_fails=2 fail_timeout=60s;
+    }
+    server {
+        listen 6030;
+        proxy_connect_timeout 5s;
+        proxy_timeout 300s;
+        proxy_pass mysqld;
+    }
+}
+http {
+    dyn_kv_conf conf/iot-work.conf;
+}
+```
+
+虽然 Doris 流量由 `stream` 转发,管理 API 仍需要 `http` 块来初始化数据面模块。Helper 使用 
`conf/njet_ctrl.conf`;本例不需要单独的 `conf/ctrl.conf` 或 `conf/mqtt.conf`。
+
+**`njet_ctrl.conf`(控制面):**
+
+```text
+load_module modules/njt_http_sendmsg_module.so;
+load_module modules/njt_http_upstream_api_module.so;
+load_module modules/njt_helper_health_check_module.so;
+load_module modules/njt_health_check_mysql_module.so;
+
+events {
+    worker_connections 1024;
+}
+http {
+    server {
+        listen 127.0.0.1:8081;
+        location /api {
+            dyn_module_api;
+        }
+    }
+}
+```
+
+必须显式加载 MySQL 健康检查模块。管理 API 监听容器内的回环地址,以下通过 `docker exec` 访问。
+
+#### 启动和验证
+
+在包含两个配置文件的目录中执行:
+
+```shell
+docker run -d --name doris-njet \
+  --platform linux/amd64 \
+  --cap-add=NET_ADMIN --cap-add=DAC_READ_SEARCH \
+  -p 6030:6030 \
+  -v "$PWD/njet.conf:/usr/local/njet/conf/njet.conf:ro" \
+  -v "$PWD/njet_ctrl.conf:/usr/local/njet/conf/njet_ctrl.conf:ro" \
+  tmlake/njet:4.0.2.0
+```
+
+检查两个配置文件并查看上游列表:
+
+```shell
+docker exec doris-njet njet -t
+docker exec doris-njet curl --max-time 10 -sS \
+  http://127.0.0.1:8081/api/v1/upstream_api/stream/upstreams/mysqld/servers/
+```
+
+`njet -t` 会报告两个配置文件均验证成功。API 返回 HTTP 200 和包含三个 FE 的 JSON 数组。通过代理连接 Doris,将 
`doris_user` 替换为已有的 Doris 用户:
+
+```shell
+mysql -h192.168.1.100 -P6030 -u doris_user -p -e 'SELECT 1 AS connection_test;'
+```
+
+```text
++-----------------+
+| connection_test |
++-----------------+
+|               1 |
++-----------------+
+```
+
+关键配置:
+
+| 配置 | 示例值 | 作用 |
+| --- | --- | --- |
+| `zone` | `mysqld 128k` | 动态上游管理需要的共享状态空间。 |
+| `hash` | `$remote_addr consistent` | 对客户端 IP 做一致性 Hash 以分配新连接。共享同一源 IP 
的客户端可能访问同一个 FE。 |
+| `max_fails` / `fail_timeout` | `2` / `60s` | 后端连接的被动失败检测,不会配置主动 SQL 检查。 |
+| `listen` | `6030` | 代理的 MySQL 协议端口,通过 Docker 的 `-p 6030:6030` 发布。 |
+| `proxy_connect_timeout` / `proxy_timeout` | `5s` / `300s` | 
后端建连超时及代理空闲超时,应按查询和会话需求调整。 |
+
+#### 动态添加和删除 FE
+
+添加 FE 的请求:
+
+```shell
+docker exec doris-njet curl --max-time 10 -i \
+  -H 'Content-Type: application/json' \
+  -d 
'{"server":"192.168.1.104:9030","weight":2,"max_fails":1,"fail_timeout":"5s"}' \
+  http://127.0.0.1:8081/api/v1/upstream_api/stream/upstreams/mysqld/servers/
+```
+
+API 返回 HTTP 201 和新成员信息,其中包含分配的 `id`。在初始三个成员的配置下,第一个新增成员的 ID 为 3。删除时应使用实际返回的 ID:
+
+```shell
+docker exec doris-njet curl --max-time 10 -i -X DELETE \
+  http://127.0.0.1:8081/api/v1/upstream_api/stream/upstreams/mysqld/servers/3
+```
+
+删除返回 HTTP 200,之后 GET 的列表中不再包含该成员。重新创建容器前,应使配置文件与预期成员列表保持一致。
+
+#### 配置 MySQL 主动健康检查
+
+主动 SQL 检查需要显式调用 API 配置,并准备可用的 Doris 账户和数据库。使用 Doris 管理员执行以下 SQL,并替换密码:
+
+```sql
+CREATE DATABASE IF NOT EXISTS health_check_db;
+CREATE USER IF NOT EXISTS 'njet_health'@'%' IDENTIFIED BY 
'<replace-with-password>';
+GRANT SELECT_PRIV ON health_check_db.* TO 'njet_health'@'%';
+```
+
+在下方请求中使用相同密码。对于未启用 TLS 的 FE 监听端口,`useSsl` 使用 `false`;只有 FE 监听端口已配置 TLS 时才设置为 
`true`。
+
+```shell
+docker exec doris-njet curl --max-time 10 -i \
+  -H 'Content-Type: application/json' \
+  -d '{
+    "interval":"5s",
+    "jitter":"1s",
+    "timeout":"5s",
+    "passes":1,
+    "fails":1,
+    "sql":{
+      "select":"select 1",
+      "useSsl":false,
+      "user":"njet_health",
+      "password":"<replace-with-password>",
+      "db":"health_check_db"
+    }
+  }' \
+  http://127.0.0.1:8081/api/v1/hc/smysql/mysqld
+```
+
+配置成功返回 HTTP 200 和 `{"code":0,"msg":"success"}`。后续健康检查会对每个 FE 完成认证、选择指定数据库并执行 
`select 1`。
+
+| 字段 | 是否必填 / 默认值 | 说明 |
+| --- | --- | --- |
+| `interval`、`jitter`、`timeout` | 本例显式设置 | 检查间隔、定时器抖动和超时,使用时间长度格式。 |
+| `passes`、`fails` | 本例显式设置 | 改变健康状态前,需要连续成功或失败的次数。 |
+| `port` | 可选;默认使用上游端口 | 覆盖检查使用的端口。 |
+| `sql.select` | 本例显式设置 | 用于验证 FE 的 SQL。 |
+| `sql.useSsl` | 可选;NJet 默认 `true` | 必须与 FE 监听端口的 TLS 配置匹配。 |
+| `sql.user`、`sql.password` | 根据 Doris 账户设置 | 健康检查使用的凭据。 |
+| `sql.db` | 必填且非空 | 检查器要选择的已有数据库。 |
+
+API 超时时,请检查 Helper 路径以及数据面的 `http` 块。健康检查失败时,请检查数据库、凭据、网络和 TLS 配置;配置请求成功并不代表 
FE 已健康。更多说明参见 [OpenNJet 源码和文档](https://github.com/OpenNJet/OpenNJet)及 [JSON 
配置格式](https://njet.org.cn/cases/njet_support_json/)。
+
 ## 客户端 IP 透传(Proxy Protocol)
 
 <!-- 知识类型: 配置参数 / 操作步骤 -->
@@ -671,7 +856,7 @@ backend forward-fe
 
 ### 验证 IP 透传是否成功
 
-1. 通过代理连接 Doris:
+1. 通过代理连接 Doris,将 `doris_user` 替换为已有的 Doris 用户:
 
     ```sql
     mysql -uroot -P6030 -h192.168.1.100
diff --git 
a/versioned_docs/version-4.x/admin-manual/cluster-management/load-balancing.md 
b/versioned_docs/version-4.x/admin-manual/cluster-management/load-balancing.md
index ee620f8c336..71f35579c44 100644
--- 
a/versioned_docs/version-4.x/admin-manual/cluster-management/load-balancing.md
+++ 
b/versioned_docs/version-4.x/admin-manual/cluster-management/load-balancing.md
@@ -2,7 +2,7 @@
 {
     "title": "FE Load Balancing",
     "language": "en",
-    "description": "Load balancing options for multi-FE Doris deployments: 
JDBC, Nginx, HAProxy, ProxySQL, plus client IP forwarding via Proxy Protocol.",
+    "description": "Load balancing options for multi-FE Doris deployments: 
JDBC, Nginx, HAProxy, ProxySQL, NJet, plus client IP forwarding via Proxy 
Protocol.",
     "keywords": [
         "Doris load balancing",
         "FE high availability",
@@ -11,6 +11,7 @@
         "Nginx TCP reverse proxy",
         "HAProxy",
         "ProxySQL",
+        "NJet",
         "Proxy Protocol",
         "client IP forwarding",
         "query_port 9030",
@@ -25,7 +26,7 @@
 
 Users connect to Doris over the MySQL protocol through the FE query port 
(`query_port`, default `9030`). When multiple FE nodes are deployed, you can 
place a load balancing layer in front of the FEs to provide high availability 
and connection distribution for the Doris query entry point.
 
-This document describes four load balancing options for Doris and explains how 
to forward the real client IP through the proxy layer using Proxy Protocol.
+This document describes five load balancing options for Doris and explains how 
to forward the real client IP through the proxy layer using Proxy Protocol.
 
 ## Applicable Scenarios
 
@@ -35,6 +36,7 @@ This document describes four load balancing options for Doris 
and explains how t
 | Existing Nginx infrastructure, TCP-layer reverse proxy required | Nginx | 
General-purpose TCP reverse proxy, simple configuration |
 | High-performance TCP proxy with health checks required | HAProxy | Dedicated 
TCP/HTTP load balancer with a rich set of health-check strategies |
 | MySQL protocol-aware proxy required (connection management, read/write 
splitting, etc.) | ProxySQL | Database proxy designed for the MySQL protocol |
+| Dynamic FE membership and active SQL health checks required | NJet | TCP 
proxy with optional management APIs |
 | Need to preserve the real client IP behind the load balancer | Proxy 
Protocol | Used together with Nginx or HAProxy |
 
 ## Prerequisites
@@ -602,6 +604,189 @@ ProxySQL > select * from mysql_server_ping_log;
 110 rows in set (0.001 sec)
 ```
 
+### Option 5: NJet
+
+[OpenNJet](https://github.com/OpenNJet/OpenNJet) provides TCP proxying, 
dynamic upstream management, and optional active MySQL health checks. The 
following example uses the same proxy and FE addresses as the preceding 
sections.
+
+The proxy distributes **connections**. An established MySQL session remains on 
one FE; it does not distribute each SQL statement or replay an interrupted 
query. These settings cover the FE MySQL port. Stream Load uses the HTTP 
endpoint and can redirect to a BE; the client must be able to reach the address 
returned by that redirect.
+
+#### Prepare NJet and the Configuration Files
+
+The example uses the official `tmlake/njet:4.0.2.0` image and its 
`/usr/local/njet` installation prefix. This image is Linux/AMD64; use a 
matching image or configure emulation on ARM hosts. For native installation, 
see the [OpenNJet quick start](https://njet.org.cn/docs/quickstart/), and 
adjust module/configuration paths to your installation.
+
+Save the following two files in the same directory. The FE addresses must be 
reachable from the container.
+
+**`njet.conf` (data plane):**
+
+```text
+worker_processes 1;
+cluster_name njet;
+node_name node1;
+
+helper ctrl modules/njt_helper_ctrl_module.so conf/njet_ctrl.conf;
+helper broker modules/njt_helper_broker_module.so;
+load_module modules/njt_http_upstream_member_module.so;
+
+events {
+    worker_connections 1024;
+}
+stream {
+    upstream mysqld {
+        zone mysqld 128k;
+        hash $remote_addr consistent;
+        server 192.168.1.101:9030 weight=1 max_fails=2 fail_timeout=60s;
+        server 192.168.1.102:9030 weight=1 max_fails=2 fail_timeout=60s;
+        server 192.168.1.103:9030 weight=1 max_fails=2 fail_timeout=60s;
+    }
+    server {
+        listen 6030;
+        proxy_connect_timeout 5s;
+        proxy_timeout 300s;
+        proxy_pass mysqld;
+    }
+}
+http {
+    dyn_kv_conf conf/iot-work.conf;
+}
+```
+
+The `http` block initializes the data-plane modules used by the management 
APIs, even though Doris traffic is forwarded by `stream`. The helper uses 
`conf/njet_ctrl.conf`; it does not use a separate `conf/ctrl.conf` or 
`conf/mqtt.conf` in this example.
+
+**`njet_ctrl.conf` (control plane):**
+
+```text
+load_module modules/njt_http_sendmsg_module.so;
+load_module modules/njt_http_upstream_api_module.so;
+load_module modules/njt_helper_health_check_module.so;
+load_module modules/njt_health_check_mysql_module.so;
+
+events {
+    worker_connections 1024;
+}
+http {
+    server {
+        listen 127.0.0.1:8081;
+        location /api {
+            dyn_module_api;
+        }
+    }
+}
+```
+
+The MySQL health-check module must be loaded explicitly. The management API 
listens on loopback inside the container; the examples access it with `docker 
exec`.
+
+#### Start and Verify
+
+Run from the directory containing both configuration files:
+
+```shell
+docker run -d --name doris-njet \
+  --platform linux/amd64 \
+  --cap-add=NET_ADMIN --cap-add=DAC_READ_SEARCH \
+  -p 6030:6030 \
+  -v "$PWD/njet.conf:/usr/local/njet/conf/njet.conf:ro" \
+  -v "$PWD/njet_ctrl.conf:/usr/local/njet/conf/njet_ctrl.conf:ro" \
+  tmlake/njet:4.0.2.0
+```
+
+Validate both files and inspect the backend list:
+
+```shell
+docker exec doris-njet njet -t
+docker exec doris-njet curl --max-time 10 -sS \
+  http://127.0.0.1:8081/api/v1/upstream_api/stream/upstreams/mysqld/servers/
+```
+
+`njet -t` reports successful validation for both configuration files. The API 
returns HTTP 200 and a JSON array containing the three configured FEs. Connect 
through the proxy, replacing `doris_user` with an existing Doris account:
+
+```shell
+mysql -h192.168.1.100 -P6030 -u doris_user -p -e 'SELECT 1 AS connection_test;'
+```
+
+```text
++-----------------+
+| connection_test |
++-----------------+
+|               1 |
++-----------------+
+```
+
+Key settings:
+
+| Setting | Example | Effect |
+| --- | --- | --- |
+| `zone` | `mysqld 128k` | Shared state required for dynamic upstream 
management. |
+| `hash` | `$remote_addr consistent` | Assigns new connections using a 
consistent hash of client IP. Clients sharing one source IP may reach the same 
FE. |
+| `max_fails` / `fail_timeout` | `2` / `60s` | Passive failure detection for 
backend connections. This does not configure active SQL checks. |
+| `listen` | `6030` | Proxy's MySQL-protocol port. Docker publishes it with 
`-p 6030:6030`. |
+| `proxy_connect_timeout` / `proxy_timeout` | `5s` / `300s` | Backend 
connection timeout and proxy inactivity timeout. Adapt these to your 
query/session requirements. |
+
+#### Dynamically Add and Remove an FE
+
+To add an FE, send:
+
+```shell
+docker exec doris-njet curl --max-time 10 -i \
+  -H 'Content-Type: application/json' \
+  -d 
'{"server":"192.168.1.104:9030","weight":2,"max_fails":1,"fail_timeout":"5s"}' \
+  http://127.0.0.1:8081/api/v1/upstream_api/stream/upstreams/mysqld/servers/
+```
+
+The API returns HTTP 201 and the new member, including its assigned `id`. For 
the initial three-member configuration, the first new member has ID 3. Use the 
actual returned ID when deleting it:
+
+```shell
+docker exec doris-njet curl --max-time 10 -i -X DELETE \
+  http://127.0.0.1:8081/api/v1/upstream_api/stream/upstreams/mysqld/servers/3
+```
+
+Deletion returns HTTP 200; a subsequent GET no longer lists that member. Keep 
the configuration files consistent with your intended membership before 
recreating the container.
+
+#### Configure Active MySQL Health Checks
+
+Active SQL checks require an explicit API configuration and a working Doris 
account/database. Run the following as a Doris administrator, replacing the 
password:
+
+```sql
+CREATE DATABASE IF NOT EXISTS health_check_db;
+CREATE USER IF NOT EXISTS 'njet_health'@'%' IDENTIFIED BY 
'<replace-with-password>';
+GRANT SELECT_PRIV ON health_check_db.* TO 'njet_health'@'%';
+```
+
+Use the same password in the request below. `useSsl` is `false` for a non-TLS 
FE listener; set it to `true` only when the FE listener is configured for TLS.
+
+```shell
+docker exec doris-njet curl --max-time 10 -i \
+  -H 'Content-Type: application/json' \
+  -d '{
+    "interval":"5s",
+    "jitter":"1s",
+    "timeout":"5s",
+    "passes":1,
+    "fails":1,
+    "sql":{
+      "select":"select 1",
+      "useSsl":false,
+      "user":"njet_health",
+      "password":"<replace-with-password>",
+      "db":"health_check_db"
+    }
+  }' \
+  http://127.0.0.1:8081/api/v1/hc/smysql/mysqld
+```
+
+A successful configuration returns HTTP 200 with `{"code":0,"msg":"success"}`. 
Subsequent checks authenticate, select the configured database, and execute 
`select 1` against each FE.
+
+| Field | Required / Default | Description |
+| --- | --- | --- |
+| `interval`, `jitter`, `timeout` | Set explicitly in this example | Check 
interval, timer jitter, and timeout, expressed as durations. |
+| `passes`, `fails` | Set explicitly in this example | Consecutive 
successes/failures required to change health state. |
+| `port` | Optional; upstream server port | Override the port used for checks. 
|
+| `sql.select` | Set explicitly | SQL statement used to validate the FE. |
+| `sql.useSsl` | Optional; NJet defaults to `true` | Must match the FE 
listener's TLS setting. |
+| `sql.user`, `sql.password` | Set for the Doris account | Credentials used by 
the health checker. |
+| `sql.db` | Required, nonempty | Existing database selected by the checker. |
+
+If the API times out, verify the helper paths and the data-plane `http` block. 
If a health check fails, verify the database, credentials, network 
reachability, and TLS setting; a successful configuration response alone does 
not prove the FE is healthy. For more details, see the [OpenNJet source and 
documentation](https://github.com/OpenNJet/OpenNJet) and [JSON configuration 
format](https://njet.org.cn/cases/njet_support_json/).
+
 ## Client IP Forwarding (Proxy Protocol)
 
 <!-- Knowledge type: Configuration parameter / Operational procedure -->


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to