Skip to content

Commit f5544ec

Browse files
committed
feat(tunnel): 添加负载均衡策略支持
- 在模型中添加 lbs 字段用于存储负载均衡策略 - 实现 lbs 参数的解析和配置功能 - 更新 API 接口以支持负载均衡策略的传递 - 在前端创建隧道界面添加负载均衡策略选择组件 - 添加负载均衡策略的国际化语言配置 - 在隧道详情页面展示负载均衡策略信息
1 parent 0d33235 commit f5544ec

File tree

8 files changed

+97
-79
lines changed

8 files changed

+97
-79
lines changed

cmd/dbtool/main.go

Lines changed: 0 additions & 77 deletions
This file was deleted.

internal/api/tunnel.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -848,6 +848,12 @@ func (h *TunnelHandler) HandleGetTunnelDetails(c *gin.Context) {
848848
}
849849
return nil
850850
}(),
851+
"lbs": func() interface{} {
852+
if tunnel.Lbs != nil {
853+
return *tunnel.Lbs
854+
}
855+
return nil
856+
}(),
851857
// endpoint 改为对象形式
852858
"endpoint": map[string]interface{}{
853859
"name": endpointName,
@@ -883,6 +889,7 @@ func (h *TunnelHandler) HandleGetTunnelDetails(c *gin.Context) {
883889
"listenType": parsedConfig.ListenType,
884890
"sni": parsedConfig.Sni,
885891
"block": parsedConfig.Block,
892+
"lbs": parsedConfig.Lbs,
886893
},
887894

888895
// tags - GORM 自动反序列化为 *map[string]string

internal/models/models.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ type Tunnel struct {
102102
Dns *string `json:"dns,omitempty" gorm:"type:text;column:dns"`
103103
Sni *string `json:"sni,omitempty" gorm:"type:text;column:sni"` //SNI服务器名称指示
104104
Block *int `json:"block,omitempty" gorm:"type:int;column:block"` //协议屏蔽:0-禁用, 1-SOCKS, 2-HTTP, 3-TLS
105+
Lbs *int `json:"lbs,omitempty" gorm:"type:int;column:lbs"` //负载均衡策略:0-轮询转移, 1-最优延迟, 2-主备回落
105106

106107
Sorts int64 `json:"sorts" gorm:"type:int;column:sorts;default:0"`
107108

internal/nodepass/parse.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ type TunnelConfig struct {
3636
Dns string // DNS服务器地址
3737
Sni string // SNI服务器名称指示
3838
Block string // 协议屏蔽 (0-禁用, 1-SOCKS, 2-HTTP, 3-TLS)
39+
Lbs string // 负载均衡策略 (0-轮询转移, 1-最优延迟, 2-主备回落)
3940
}
4041

4142
// ParseTunnelURL 解析隧道实例 URL 并返回 Tunnel 模型
@@ -253,6 +254,11 @@ func ParseTunnelURL(rawURL string) *models.Tunnel {
253254
if blockType, err := strconv.Atoi(val); err == nil && blockType >= 0 && blockType <= 3 {
254255
tunnel.Block = &blockType
255256
}
257+
case "lbs":
258+
// 负载均衡策略 (0=轮询转移, 1=最优延迟, 2=主备回落)
259+
if lbsType, err := strconv.Atoi(val); err == nil && lbsType >= 0 && lbsType <= 2 {
260+
tunnel.Lbs = &lbsType
261+
}
256262
}
257263
}
258264
}
@@ -393,6 +399,9 @@ func TunnelToMap(tunnel *models.Tunnel) map[string]interface{} {
393399
if tunnel.Block != nil {
394400
updates["block"] = tunnel.Block
395401
}
402+
if tunnel.Lbs != nil {
403+
updates["lbs"] = tunnel.Lbs
404+
}
396405
return updates
397406
}
398407

@@ -473,6 +482,7 @@ func ParseTunnelConfig(rawURL string) *TunnelConfig {
473482
cfg.Dns = query.Get("dns")
474483
cfg.Sni = query.Get("sni")
475484
cfg.Block = query.Get("block")
485+
cfg.Lbs = query.Get("lbs")
476486

477487
// 根据notcp和noudp参数的组合来设置listenType
478488
if noTCP != "" || noUDP != "" {
@@ -607,6 +617,9 @@ func (c *TunnelConfig) BuildTunnelConfigURL() string {
607617
if c.Block != "" {
608618
queryParams = append(queryParams, fmt.Sprintf("block=%s", c.Block))
609619
}
620+
if c.Lbs != "" {
621+
queryParams = append(queryParams, fmt.Sprintf("lbs=%s", c.Lbs))
622+
}
610623

611624
// 根据listenType生成notcp和noudp参数
612625
if c.ListenType != "" {
@@ -795,6 +808,9 @@ func BuildTunnelURLs(tunnel models.Tunnel) string {
795808
if tunnel.Block != nil {
796809
queryParams = append(queryParams, fmt.Sprintf("block=%d", *tunnel.Block))
797810
}
811+
if tunnel.Lbs != nil {
812+
queryParams = append(queryParams, fmt.Sprintf("lbs=%d", *tunnel.Lbs))
813+
}
798814

799815
if tunnel.ProxyProtocol != nil {
800816
proxyVal := "0"

web/src/components/tunnels/simple-create-tunnel-modal.tsx

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ export default function SimpleCreateTunnelModal({
161161
dns: "",
162162
sni: "", // SNI服务器名称指示
163163
block: "0", // 协议屏蔽:0-禁用, 1-SOCKS, 2-HTTP, 3-TLS (默认禁用)
164+
lbs: "0", // 负载均衡策略:0-轮询转移, 1-最优延迟, 2-主备回落 (默认轮询转移)
164165
});
165166

166167
// 当打开时加载端点,并在 edit 时从API获取隧道详情
@@ -246,6 +247,10 @@ export default function SimpleCreateTunnelModal({
246247
tunnel.block != null
247248
? String(tunnel.block)
248249
: "0",
250+
lbs:
251+
tunnel.lbs != null
252+
? String(tunnel.lbs)
253+
: "0",
249254
}));
250255

251256
// 如果有扩展目标地址,自动展开可选配置
@@ -302,6 +307,7 @@ export default function SimpleCreateTunnelModal({
302307
dns,
303308
sni,
304309
block,
310+
lbs,
305311
} = formData;
306312

307313
// 基本校验
@@ -408,6 +414,7 @@ export default function SimpleCreateTunnelModal({
408414
dns: dns || undefined,
409415
sni: sni || undefined,
410416
block: block !== "" ? parseInt(block) : undefined,
417+
lbs: lbs !== "" ? parseInt(lbs) : undefined,
411418
}),
412419
});
413420
const data = await res.json();
@@ -1027,6 +1034,23 @@ export default function SimpleCreateTunnelModal({
10271034
<SelectItem key="2">{t("simpleCreate.blockTypes.http")}</SelectItem>
10281035
<SelectItem key="3">{t("simpleCreate.blockTypes.tls")}</SelectItem>
10291036
</Select>
1037+
{/* 负载均衡策略 - 只在启用负载均衡时显示 */}
1038+
{isEnableLoadBalancing && (
1039+
<Select
1040+
label={t("simpleCreate.fields.lbs")}
1041+
selectedKeys={
1042+
formData.lbs !== "" ? [formData.lbs] : ["0"]
1043+
}
1044+
onSelectionChange={(keys) => {
1045+
const selectedKey = Array.from(keys)[0] as string;
1046+
handleField("lbs", selectedKey);
1047+
}}
1048+
>
1049+
<SelectItem key="0">{t("simpleCreate.lbsTypes.roundRobin")}</SelectItem>
1050+
<SelectItem key="1">{t("simpleCreate.lbsTypes.leastLatency")}</SelectItem>
1051+
<SelectItem key="2">{t("simpleCreate.lbsTypes.failover")}</SelectItem>
1052+
</Select>
1053+
)}
10301054
<Input
10311055
label={t("simpleCreate.fields.dnsTTL")}
10321056
placeholder={t("simpleCreate.fields.dnsTTLPlaceholder")}

web/src/locales/en-US/tunnels.json

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,10 +351,11 @@
351351
"sni": "SNI",
352352
"sniPlaceholder": "example.com",
353353
"block": "Protocol Block",
354+
"lbs": "Load Balancing Strategy",
354355
"dnsTTL": "DNS TTL",
355356
"dnsTTLPlaceholder": "5m",
356357
"extendedTargets": "Extended Target Addresses",
357-
"extendedTargetsPlaceholder": "192.168.1.1:80&#10;192.168.1.2:80",
358+
"extendedTargetsPlaceholder": "192.168.1.1:80\n192.168.1.2:80",
358359
"extendedTargetsTooltip": "Achieve load balancing by adding target addresses"
359360
},
360361
"modes": {
@@ -381,6 +382,11 @@
381382
"http": "HTTP",
382383
"tls": "TLS"
383384
},
385+
"lbsTypes": {
386+
"roundRobin": "Round Robin",
387+
"leastLatency": "Least Latency",
388+
"failover": "Failover"
389+
},
384390
"tls": {
385391
"inherit": "Inherit",
386392
"inheritWithValue": "Inherit ({{mode}})",
@@ -656,6 +662,13 @@
656662
"tls": "TLS",
657663
"notSet": "Not Set"
658664
},
665+
"lbs": {
666+
"label": "Load Balancing Strategy",
667+
"roundRobin": "Round Robin",
668+
"leastLatency": "Least Latency",
669+
"failover": "Failover",
670+
"notSet": "Not Set"
671+
},
659672
"bindService": {
660673
"label": "Bind Service",
661674
"unknown": "Unknown Service"

web/src/locales/zh-CN/tunnels.json

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,10 +351,11 @@
351351
"sni": "SNI",
352352
"sniPlaceholder": "example.com",
353353
"block": "协议屏蔽",
354+
"lbs": "负载均衡策略",
354355
"dnsTTL": "DNS TTL",
355356
"dnsTTLPlaceholder": "5m",
356357
"extendedTargets": "附加目标地址",
357-
"extendedTargetsPlaceholder": "192.168.1.1:80&#10;192.168.1.2:80",
358+
"extendedTargetsPlaceholder": "192.168.1.1:80\n192.168.1.2:80",
358359
"extendedTargetsTooltip": "通过增加目标地址达到负载均衡的效果"
359360
},
360361
"modes": {
@@ -381,6 +382,11 @@
381382
"http": "HTTP",
382383
"tls": "TLS"
383384
},
385+
"lbsTypes": {
386+
"roundRobin": "轮询转移",
387+
"leastLatency": "最优延迟",
388+
"failover": "主备回落"
389+
},
384390
"tls": {
385391
"inherit": "继承",
386392
"inheritWithValue": "继承 ({{mode}})",
@@ -656,6 +662,13 @@
656662
"tls": "TLS",
657663
"notSet": "未设置"
658664
},
665+
"lbs": {
666+
"label": "负载均衡策略",
667+
"roundRobin": "轮询转移",
668+
"leastLatency": "最优延迟",
669+
"failover": "主备回落",
670+
"notSet": "未设置"
671+
},
659672
"bindService": {
660673
"label": "绑定服务",
661674
"unknown": "未知服务"

web/src/pages/tunnels/details/index.tsx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ interface TunnelInfo {
111111
dns?: string | null;
112112
sni?: string | null;
113113
block?: number | null;
114+
lbs?: number | null;
114115
targetPort: number;
115116
tlsMode: string;
116117
commandLine: string;
@@ -2402,6 +2403,26 @@ export default function TunnelDetailPage() {
24022403
})()
24032404
}
24042405
/>
2406+
<CellValue
2407+
icon={
2408+
<Icon
2409+
className="text-default-600"
2410+
height={18}
2411+
icon="lucide:share-2"
2412+
width={18}
2413+
/>
2414+
}
2415+
label={t("details.instanceInfo.lbs.label")}
2416+
value={
2417+
(() => {
2418+
const lbsType = tunnelInfo?.lbs;
2419+
if (lbsType === 0) return t("details.instanceInfo.lbs.roundRobin");
2420+
if (lbsType === 1) return t("details.instanceInfo.lbs.leastLatency");
2421+
if (lbsType === 2) return t("details.instanceInfo.lbs.failover");
2422+
return t("details.instanceInfo.lbs.notSet");
2423+
})()
2424+
}
2425+
/>
24052426
<CellValue
24062427
icon={
24072428
<Icon

0 commit comments

Comments
 (0)