mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-10-19 12:25:00 +03:00
feat(balancer): add balancer-to-balancer fallback support
Xray does not natively support using a balancer as fallbackTag for
another balancer. This feature automates the loopback workaround:
when a user selects a balancer as fallback, the panel generates a
loopback outbound + routing rule in the template.
How it works:
- User picks fallback balancer from dropdown
- Panel creates loopback outbound _bl_{target} + routing rule
- Balancer fallbackTag set to _bl_{target}
- Traffic: Balancer A → loopback _bl_B → routing rule → Balancer B
Key features:
- Dedup: multiple balancers sharing same fallback reuse one loopback
- DFS cycle detection at edit time and on save
- Self-reference guard (cannot select own balancer)
- Delete protection (blocks if used as fallback by others)
- Cleans up routing rules referencing deleted balancers
- Override resolves balancer tags through loopback mechanism
- All live status tags resolved for display
- Internal _bl_ objects filtered from Outbounds/Routing UI
- Backward-compatible with old _bl_ naming format
- Translations for all 13 locales
This commit is contained in:
@@ -906,11 +906,23 @@ func (s *XrayService) GetBalancersStatus(tags []string) ([]BalancerStatus, error
|
||||
}
|
||||
|
||||
// OverrideBalancer forces a balancer in the running core to use the given
|
||||
// outbound tag; an empty target clears the override.
|
||||
// outbound tag; an empty target clears the override. When target names
|
||||
// another balancer, the override resolves to the loopback outbound that
|
||||
// routes traffic through the target balancer via the routing rules.
|
||||
func (s *XrayService) OverrideBalancer(tag, target string) error {
|
||||
if !s.IsXrayRunning() {
|
||||
return errors.New("xray is not running")
|
||||
}
|
||||
if target != "" {
|
||||
resolved, err := s.resolveOverrideTarget(target)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if resolved == "" {
|
||||
return errors.New("balancer fallback target not found in routing rules")
|
||||
}
|
||||
target = resolved
|
||||
}
|
||||
if err := s.xrayAPI.Init(p.GetAPIPort()); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -918,6 +930,42 @@ func (s *XrayService) OverrideBalancer(tag, target string) error {
|
||||
return s.xrayAPI.SetBalancerTarget(tag, target)
|
||||
}
|
||||
|
||||
// resolveOverrideTarget checks if target names a balancer and, if so,
|
||||
// returns the loopback outbound tag that routes to it through the
|
||||
// routing rules. Returns empty if target is already a concrete outbound.
|
||||
func (s *XrayService) resolveOverrideTarget(target string) (string, error) {
|
||||
template, err := s.settingService.GetXrayConfigTemplate()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
var cfg map[string]any
|
||||
if err := json.Unmarshal([]byte(template), &cfg); err != nil {
|
||||
return "", err
|
||||
}
|
||||
routing, _ := cfg["routing"].(map[string]any)
|
||||
if routing == nil {
|
||||
return "", nil
|
||||
}
|
||||
rules, _ := routing["rules"].([]any)
|
||||
for _, r := range rules {
|
||||
rule, ok := r.(map[string]any)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if rule["balancerTag"] != target {
|
||||
continue
|
||||
}
|
||||
inboundTags, ok := rule["inboundTag"].([]any)
|
||||
if !ok || len(inboundTags) == 0 {
|
||||
continue
|
||||
}
|
||||
if lbTag, ok := inboundTags[0].(string); ok && strings.HasPrefix(lbTag, "_bl_") {
|
||||
return lbTag, nil
|
||||
}
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// TestRoute asks the running core which outbound its router picks for the
|
||||
// described connection.
|
||||
func (s *XrayService) TestRoute(req xray.RouteTestRequest) (*xray.RouteTestResult, error) {
|
||||
|
||||
@@ -1706,13 +1706,18 @@
|
||||
"tagPlaceholder": "وسم موازن فريد",
|
||||
"selector": "المحدد",
|
||||
"fallback": "Fallback",
|
||||
"fallbackBalancerHint": "اختر موزان أحمال آخر كبديل",
|
||||
"balancerFallbackInfo": "سيتم توجيه حركة المرور عبر: الموزان → Loopback → الخادم → الموزان المستهدف → الاتصال الخارجي. سيؤدي هذا إلى إضافة قفزة إضافية عبر الخادم، مما قد يسبب تأخيرات طفيفة.",
|
||||
"balancerFallbackCycle": "لا يمكن تعيين هذا الموزان كبديل — سيؤدي ذلك إلى إنشاء تبعية دائرية.",
|
||||
"balancerDeleteInUse": "لا يمكن حذف هذا الموزان — يتم استخدامه كبديل لـ: {names}",
|
||||
"expected": "المتوقع",
|
||||
"expectedPlaceholder": "العدد الأمثل للعقد",
|
||||
"maxRtt": "أقصى RTT",
|
||||
"tolerance": "التحمل",
|
||||
"baselines": "Baselines",
|
||||
"costs": "Costs",
|
||||
"balancerDesc": "ماينفعش تستخدم balancerTag و outboundTag مع بعض. لو اتستخدموا مع بعض، outboundTag هو اللي هيشتغل."
|
||||
"balancerDesc": "ماينفعش تستخدم balancerTag و outboundTag مع بعض. لو اتستخدموا مع بعض، outboundTag هو اللي هيشتغل.",
|
||||
"cycleTooltip": "حلقة: {path} → (العودة إلى {start})"
|
||||
},
|
||||
"wireguard": {
|
||||
"secretKey": "المفتاح السري",
|
||||
@@ -2152,4 +2157,4 @@
|
||||
"statusDown": "غير متصل",
|
||||
"statusUp": "متصل"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1825,6 +1825,12 @@
|
||||
"tagPlaceholder": "unique balancer tag",
|
||||
"selector": "Selector",
|
||||
"fallback": "Fallback",
|
||||
"fallbackBalancerHint": "Select another balancer as fallback",
|
||||
"balancerFallbackInfo": "Traffic will be routed through: Balancer → Loopback → Server → Target Balancer → Outbound. This adds an extra hop through the server, which may introduce slight delays.",
|
||||
"balancerFallbackCycle": "Cannot set this balancer as fallback — it would create a circular dependency.",
|
||||
"balancerDeleteInUse": "Cannot delete this balancer — it is used as fallback by: {names}",
|
||||
"reservedPrefix": "_bl_ prefix is reserved for internal balancer loopback objects",
|
||||
"cycleTooltip": "Cycle: {path} → (back to {start})",
|
||||
"expected": "Expected",
|
||||
"expectedPlaceholder": "optimal node count",
|
||||
"maxRtt": "Max RTT",
|
||||
@@ -2155,4 +2161,4 @@
|
||||
"statusDown": "DOWN",
|
||||
"statusUp": "UP"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1706,13 +1706,18 @@
|
||||
"tagPlaceholder": "etiqueta única de balanceador",
|
||||
"selector": "Selector",
|
||||
"fallback": "Fallback",
|
||||
"fallbackBalancerHint": "Seleccione otro balanceador como respaldo",
|
||||
"balancerFallbackInfo": "El tráfico se enrutará a través de: Balanceador → Loopback → Servidor → Balanceador destino → Conexión saliente. Esto agrega un salto adicional a través del servidor, lo que puede introducir ligeros retrasos.",
|
||||
"balancerFallbackCycle": "No se puede establecer este balanceador como respaldo — crearía una dependencia circular.",
|
||||
"balancerDeleteInUse": "No se puede eliminar este balanceador — se usa como respaldo para: {names}",
|
||||
"expected": "Esperado",
|
||||
"expectedPlaceholder": "número óptimo de nodos",
|
||||
"maxRtt": "Máx. RTT",
|
||||
"tolerance": "Tolerancia",
|
||||
"baselines": "Baselines",
|
||||
"costs": "Costs",
|
||||
"balancerDesc": "No es posible utilizar balancerTag y outboundTag al mismo tiempo. Si se utilizan al mismo tiempo, sólo funcionará outboundTag."
|
||||
"balancerDesc": "No es posible utilizar balancerTag y outboundTag al mismo tiempo. Si se utilizan al mismo tiempo, sólo funcionará outboundTag.",
|
||||
"cycleTooltip": "Ciclo: {path} → (volver a {start})"
|
||||
},
|
||||
"wireguard": {
|
||||
"secretKey": "Llave secreta",
|
||||
@@ -2152,4 +2157,4 @@
|
||||
"statusDown": "CAÍDO",
|
||||
"statusUp": "ACTIVO"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1706,13 +1706,18 @@
|
||||
"tagPlaceholder": "تگ منحصربهفرد بالانسر",
|
||||
"selector": "انتخابگر",
|
||||
"fallback": "Fallback",
|
||||
"fallbackBalancerHint": "یک بالانسر دیگر به عنوان پشتیبان انتخاب کنید",
|
||||
"balancerFallbackInfo": "ترافیک از مسیر زیر مسیریابی میشود: بالانسر → Loopback → سرور → بالانسر مقصد → اتصال خروجی. این یک پرش اضافی از طریق سرور اضافه میکند که ممکن است تأخیرهای جزئی ایجاد کند.",
|
||||
"balancerFallbackCycle": "امکان تنظیم این بالانسر به عنوان پشتیبان وجود ندارد — وابستگی دایرهای ایجاد میکند.",
|
||||
"balancerDeleteInUse": "امکان حذف این بالانسر وجود ندارد — به عنوان پشتیبان برای موارد زیر استفاده میشود: {names}",
|
||||
"expected": "مورد انتظار",
|
||||
"expectedPlaceholder": "تعداد نود بهینه",
|
||||
"maxRtt": "حداکثر RTT",
|
||||
"tolerance": "تحمل",
|
||||
"baselines": "خطوط پایه",
|
||||
"costs": "هزینهها",
|
||||
"balancerDesc": "امکان استفاده همزمان balancerTag و outboundTag باهم وجود ندارد. درصورت استفاده همزمان فقط outboundTag عمل خواهد کرد."
|
||||
"balancerDesc": "امکان استفاده همزمان balancerTag و outboundTag باهم وجود ندارد. درصورت استفاده همزمان فقط outboundTag عمل خواهد کرد.",
|
||||
"cycleTooltip": "حلقه: {path} → (بازگشت به {start})"
|
||||
},
|
||||
"wireguard": {
|
||||
"secretKey": "کلید شخصی",
|
||||
@@ -2152,4 +2157,4 @@
|
||||
"statusDown": "قطع",
|
||||
"statusUp": "وصل"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1706,13 +1706,18 @@
|
||||
"tagPlaceholder": "tag balancer unik",
|
||||
"selector": "Selector",
|
||||
"fallback": "Fallback",
|
||||
"fallbackBalancerHint": "Pilih load balancer lain sebagai fallback",
|
||||
"balancerFallbackInfo": "Lalu lintas akan di-routing melalui: Load Balancer → Loopback → Server → Load Balancer tujuan → Koneksi keluar. Ini menambahkan hop tambahan melalui server, yang dapat menyebabkan sedikit penundaan.",
|
||||
"balancerFallbackCycle": "Tidak dapat mengatur load balancer ini sebagai fallback — akan menciptakan dependensi siklik.",
|
||||
"balancerDeleteInUse": "Tidak dapat menghapus load balancer ini — digunakan sebagai fallback untuk: {names}",
|
||||
"expected": "Diharapkan",
|
||||
"expectedPlaceholder": "jumlah node optimal",
|
||||
"maxRtt": "Maks. RTT",
|
||||
"tolerance": "Toleransi",
|
||||
"baselines": "Baselines",
|
||||
"costs": "Costs",
|
||||
"balancerDesc": "BalancerTag dan outboundTag tidak dapat digunakan secara bersamaan. Jika digunakan secara bersamaan, hanya outboundTag yang akan berfungsi."
|
||||
"balancerDesc": "BalancerTag dan outboundTag tidak dapat digunakan secara bersamaan. Jika digunakan secara bersamaan, hanya outboundTag yang akan berfungsi.",
|
||||
"cycleTooltip": "Siklus: {path} → (kembali ke {start})"
|
||||
},
|
||||
"wireguard": {
|
||||
"secretKey": "Kunci Rahasia",
|
||||
@@ -2152,4 +2157,4 @@
|
||||
"statusDown": "MATI",
|
||||
"statusUp": "AKTIF"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1706,13 +1706,18 @@
|
||||
"tagPlaceholder": "一意のバランサータグ",
|
||||
"selector": "セレクター",
|
||||
"fallback": "Fallback",
|
||||
"fallbackBalancerHint": "フォールバックとして別のバランサーを選択してください",
|
||||
"balancerFallbackInfo": "トラフィックは以下のルートで転送されます:バランサー → Loopback → サーバー → ターゲットバランサー → アウトバウンド。これによりサーバーを経由する追加ホップが発生し、多少の遅延が生じる場合があります。",
|
||||
"balancerFallbackCycle": "このバランサーをフォールバックに設定できません — 循環依存が発生します。",
|
||||
"balancerDeleteInUse": "このバランサーを削除できません — 以下のバランサーのフォールバックとして使用されています:{names}",
|
||||
"expected": "期待値",
|
||||
"expectedPlaceholder": "最適ノード数",
|
||||
"maxRtt": "最大 RTT",
|
||||
"tolerance": "許容範囲",
|
||||
"baselines": "Baselines",
|
||||
"costs": "Costs",
|
||||
"balancerDesc": "balancerTagとoutboundTagは同時に使用できません。同時に使用された場合、outboundTagのみが有効になります。"
|
||||
"balancerDesc": "balancerTagとoutboundTagは同時に使用できません。同時に使用された場合、outboundTagのみが有効になります。",
|
||||
"cycleTooltip": "循環: {path} → ({start} に戻る)"
|
||||
},
|
||||
"wireguard": {
|
||||
"secretKey": "シークレットキー",
|
||||
@@ -2152,4 +2157,4 @@
|
||||
"statusDown": "ダウン",
|
||||
"statusUp": "アップ"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1706,13 +1706,18 @@
|
||||
"tagPlaceholder": "tag única do balanceador",
|
||||
"selector": "Seletor",
|
||||
"fallback": "Fallback",
|
||||
"fallbackBalancerHint": "Selecione outro balanceador como fallback",
|
||||
"balancerFallbackInfo": "O tráfego será roteado através de: Balanceador → Loopback → Servidor → Balanceador de destino → Conexão de saída. Isso adiciona um salto extra pelo servidor, o que pode introduzir pequenos atrasos.",
|
||||
"balancerFallbackCycle": "Não é possível definir este balanceador como fallback — isso criaria uma dependência circular.",
|
||||
"balancerDeleteInUse": "Não é possível excluir este balanceador — ele é usado como fallback para: {names}",
|
||||
"expected": "Esperado",
|
||||
"expectedPlaceholder": "número ótimo de nós",
|
||||
"maxRtt": "Máx. RTT",
|
||||
"tolerance": "Tolerância",
|
||||
"baselines": "Baselines",
|
||||
"costs": "Costs",
|
||||
"balancerDesc": "Não é possível usar balancerTag e outboundTag ao mesmo tempo. Se usados simultaneamente, apenas outboundTag funcionará."
|
||||
"balancerDesc": "Não é possível usar balancerTag e outboundTag ao mesmo tempo. Se usados simultaneamente, apenas outboundTag funcionará.",
|
||||
"cycleTooltip": "Ciclo: {path} → (voltar para {start})"
|
||||
},
|
||||
"wireguard": {
|
||||
"secretKey": "Chave Secreta",
|
||||
@@ -2152,4 +2157,4 @@
|
||||
"statusDown": "INATIVO",
|
||||
"statusUp": "ATIVO"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1706,13 +1706,18 @@
|
||||
"tagPlaceholder": "уникальный тег балансировщика",
|
||||
"selector": "Селектор",
|
||||
"fallback": "Fallback",
|
||||
"fallbackBalancerHint": "Выберите другой балансировщик в качестве запасного",
|
||||
"balancerFallbackInfo": "Трафик будет маршрутизирован через: Балансировщик → Loopback → Сервер → Целевой балансировщик → Исходящее соединение. Это добавляет дополнительный хоп через сервер, что может вызвать небольшие задержки.",
|
||||
"balancerFallbackCycle": "Невозможно назначить этот балансировщик запасным — это создаст циклическую зависимость.",
|
||||
"balancerDeleteInUse": "Невозможно удалить этот балансировщик — он используется как запасной для: {names}",
|
||||
"expected": "Ожидаемое",
|
||||
"expectedPlaceholder": "оптимальное число узлов",
|
||||
"maxRtt": "Макс. RTT",
|
||||
"tolerance": "Допуск",
|
||||
"baselines": "Baselines",
|
||||
"costs": "Costs",
|
||||
"balancerDesc": "Невозможно одновременно использовать balancerTag и outboundTag. При одновременном использовании будет работать только outboundTag."
|
||||
"balancerDesc": "Невозможно одновременно использовать balancerTag и outboundTag. При одновременном использовании будет работать только outboundTag.",
|
||||
"cycleTooltip": "Цикл: {path} → (обратно к {start})"
|
||||
},
|
||||
"wireguard": {
|
||||
"secretKey": "Секретный ключ",
|
||||
@@ -2152,4 +2157,4 @@
|
||||
"statusDown": "НЕДОСТУПЕН",
|
||||
"statusUp": "РАБОТАЕТ"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1706,13 +1706,18 @@
|
||||
"tagPlaceholder": "benzersiz dengeleyici etiketi",
|
||||
"selector": "Seçici",
|
||||
"fallback": "Fallback",
|
||||
"fallbackBalancerHint": "Yedek olarak başka bir dengeleyici seçin",
|
||||
"balancerFallbackInfo": "Trafik şu yoldan yönlendirilecektir: Dengeleyici → Loopback → Sunucu → Hedef dengeleyici → Bağlantı çıkışı. Bu, sunucu üzerinden ek bir atlama ekler ve hafif gecikmelere neden olabilir.",
|
||||
"balancerFallbackCycle": "Bu dengeleyiciyi yedek olarak ayarlayamazsınız — döngüsel bağımlılık oluşturur.",
|
||||
"balancerDeleteInUse": "Bu dengeleyici silinemez — şu dengeleyicilerin yedeği olarak kullanılmaktadır: {names}",
|
||||
"expected": "Beklenen",
|
||||
"expectedPlaceholder": "optimal düğüm sayısı",
|
||||
"maxRtt": "Maks. RTT",
|
||||
"tolerance": "Tolerans",
|
||||
"baselines": "Baselines",
|
||||
"costs": "Costs",
|
||||
"balancerDesc": "Dengeleyici Etiketi (balancerTag) ve Giden Bağlantı Etiketi (outboundTag) aynı anda kullanılamaz. Aynı anda kullanıldığında yalnızca giden bağlantı etiketi geçerli olur."
|
||||
"balancerDesc": "Dengeleyici Etiketi (balancerTag) ve Giden Bağlantı Etiketi (outboundTag) aynı anda kullanılamaz. Aynı anda kullanıldığında yalnızca giden bağlantı etiketi geçerli olur.",
|
||||
"cycleTooltip": "Döngü: {path} → ({start} adresine geri dön)"
|
||||
},
|
||||
"wireguard": {
|
||||
"secretKey": "Gizli Anahtar",
|
||||
@@ -2152,4 +2157,4 @@
|
||||
"statusDown": "ÇEVRİMDIŞI",
|
||||
"statusUp": "ÇEVRİMİÇİ"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1706,13 +1706,18 @@
|
||||
"tagPlaceholder": "унікальний тег балансувальника",
|
||||
"selector": "Селектор",
|
||||
"fallback": "Fallback",
|
||||
"fallbackBalancerHint": "Оберіть інший балансувач як резервний",
|
||||
"balancerFallbackInfo": "Трафік буде маршрутизовано через: Балансувач → Loopback → Сервер → Цільовий балансувач → Вихідне зʼєднання. Це додає додатковий хоп через сервер, що може спричинити невеликі затримки.",
|
||||
"balancerFallbackCycle": "Неможливо призначити цей балансувач резервним — це створить циклічну залежність.",
|
||||
"balancerDeleteInUse": "Неможливо видалити цей балансувач — він використовується як резервний для: {names}",
|
||||
"expected": "Очікуване",
|
||||
"expectedPlaceholder": "оптимальна кількість вузлів",
|
||||
"maxRtt": "Макс. RTT",
|
||||
"tolerance": "Допуск",
|
||||
"baselines": "Baselines",
|
||||
"costs": "Costs",
|
||||
"balancerDesc": "Неможливо використовувати balancerTag і outboundTag одночасно. Якщо використовувати одночасно, працюватиме лише outboundTag."
|
||||
"balancerDesc": "Неможливо використовувати balancerTag і outboundTag одночасно. Якщо використовувати одночасно, працюватиме лише outboundTag.",
|
||||
"cycleTooltip": "Цикл: {path} → (назад до {start})"
|
||||
},
|
||||
"wireguard": {
|
||||
"secretKey": "Приватний ключ",
|
||||
@@ -2152,4 +2157,4 @@
|
||||
"statusDown": "НЕДОСТУПНО",
|
||||
"statusUp": "ДОСТУПНО"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1706,13 +1706,18 @@
|
||||
"tagPlaceholder": "tag balancer duy nhất",
|
||||
"selector": "Selector",
|
||||
"fallback": "Fallback",
|
||||
"fallbackBalancerHint": "Chọn một load balancer khác làm dự phòng",
|
||||
"balancerFallbackInfo": "Lưu lượng sẽ được định tuyến qua: Load Balancer → Loopback → Máy chủ → Load Balancer mục tiêu → kết nối ra ngoài. Điều này thêm một hop bổ sung qua máy chủ, có thể gây ra độ trễ nhẹ.",
|
||||
"balancerFallbackCycle": "Không thể đặt load balancer này làm dự phòng — sẽ tạo ra phụ thuộc vòng.",
|
||||
"balancerDeleteInUse": "Không thể xóa load balancer này — nó được sử dụng làm dự phòng cho: {names}",
|
||||
"expected": "Kỳ vọng",
|
||||
"expectedPlaceholder": "số node tối ưu",
|
||||
"maxRtt": "RTT tối đa",
|
||||
"tolerance": "Dung sai",
|
||||
"baselines": "Baselines",
|
||||
"costs": "Costs",
|
||||
"balancerDesc": "Không thể sử dụng balancerTag và outboundTag cùng một lúc. Nếu sử dụng cùng lúc thì chỉ outboundTag mới hoạt động."
|
||||
"balancerDesc": "Không thể sử dụng balancerTag và outboundTag cùng một lúc. Nếu sử dụng cùng lúc thì chỉ outboundTag mới hoạt động.",
|
||||
"cycleTooltip": "Vòng lặp: {path} → (quay lại {start})"
|
||||
},
|
||||
"wireguard": {
|
||||
"secretKey": "Khoá bí mật",
|
||||
@@ -2152,4 +2157,4 @@
|
||||
"statusDown": "NGỪNG HOẠT ĐỘNG",
|
||||
"statusUp": "HOẠT ĐỘNG"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1706,13 +1706,18 @@
|
||||
"tagPlaceholder": "唯一均衡器标签",
|
||||
"selector": "选择器",
|
||||
"fallback": "Fallback",
|
||||
"fallbackBalancerHint": "选择另一个负载均衡器作为备用",
|
||||
"balancerFallbackInfo": "流量将通过以下路径路由:负载均衡器 → Loopback → 服务器 → 目标负载均衡器 → 出站连接。这会增加一个经过服务器的额外跳转,可能会引入轻微延迟。",
|
||||
"balancerFallbackCycle": "无法将此负载均衡器设置为备用 — 这会创建循环依赖。",
|
||||
"balancerDeleteInUse": "无法删除此负载均衡器 — 它被用作以下负载均衡器的备用:{names}",
|
||||
"expected": "期望",
|
||||
"expectedPlaceholder": "最佳节点数",
|
||||
"maxRtt": "最大 RTT",
|
||||
"tolerance": "容差",
|
||||
"baselines": "Baselines",
|
||||
"costs": "Costs",
|
||||
"balancerDesc": "无法同时使用 balancerTag 和 outboundTag。如果同时使用,则只有 outboundTag 会生效。"
|
||||
"balancerDesc": "无法同时使用 balancerTag 和 outboundTag。如果同时使用,则只有 outboundTag 会生效。",
|
||||
"cycleTooltip": "循环: {path} → (回到 {start})"
|
||||
},
|
||||
"wireguard": {
|
||||
"secretKey": "密钥",
|
||||
@@ -2152,4 +2157,4 @@
|
||||
"statusDown": "断开",
|
||||
"statusUp": "恢复"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1706,13 +1706,18 @@
|
||||
"tagPlaceholder": "唯一均衡器標籤",
|
||||
"selector": "選擇器",
|
||||
"fallback": "Fallback",
|
||||
"fallbackBalancerHint": "選擇另一個負載平衡器作為備用",
|
||||
"balancerFallbackInfo": "流量將透過以下路徑路由:負載平衡器 → Loopback → 伺服器 → 目標負載平衡器 → 出站連線。這會增加一個經過伺服器的額外跳轉,可能會引入輕微延遲。",
|
||||
"balancerFallbackCycle": "無法將此負載平衡器設定為備用 — 這會建立循環依賴。",
|
||||
"balancerDeleteInUse": "無法刪除此負載平衡器 — 它被用作以下負載平衡器的備用:{names}",
|
||||
"expected": "期望",
|
||||
"expectedPlaceholder": "最佳節點數",
|
||||
"maxRtt": "最大 RTT",
|
||||
"tolerance": "容差",
|
||||
"baselines": "Baselines",
|
||||
"costs": "Costs",
|
||||
"balancerDesc": "無法同時使用 balancerTag 和 outboundTag。如果同時使用,則只有 outboundTag 會生效。"
|
||||
"balancerDesc": "無法同時使用 balancerTag 和 outboundTag。如果同時使用,則只有 outboundTag 會生效。",
|
||||
"cycleTooltip": "循環: {path} → (回到 {start})"
|
||||
},
|
||||
"wireguard": {
|
||||
"secretKey": "金鑰",
|
||||
@@ -2152,4 +2157,4 @@
|
||||
"statusDown": "中斷",
|
||||
"statusUp": "恢復"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user