mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2026-01-16 12:04:10 +08:00
feat: Create load balancer with health check. (#10419)
Refs https://github.com/1Panel-dev/1Panel/issues/10412
This commit is contained in:
parent
7ed81996b8
commit
da75f050e2
13 changed files with 74 additions and 15 deletions
|
|
@ -3074,6 +3074,10 @@ func (w WebsiteService) UpdateLoadBalance(req request.WebsiteLBUpdate) error {
|
|||
if !fileOp.Stat(filePath) {
|
||||
return nil
|
||||
}
|
||||
oldContent, err := fileOp.GetContent(filePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
parser, err := parser.NewParser(filePath)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -3125,10 +3129,7 @@ func (w WebsiteService) UpdateLoadBalance(req request.WebsiteLBUpdate) error {
|
|||
if err = nginx.WriteConfig(config, nginx.IndentedStyle); err != nil {
|
||||
return buserr.WithErr("ErrUpdateBuWebsite", err)
|
||||
}
|
||||
if err = opNginx(nginxInstall.ContainerName, constant.NginxReload); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return nginxCheckAndReload(string(oldContent), filePath, nginxInstall.ContainerName)
|
||||
}
|
||||
|
||||
func (w WebsiteService) DeleteLoadBalance(req request.WebsiteLBDelete) error {
|
||||
|
|
|
|||
|
|
@ -2531,6 +2531,8 @@ const message = {
|
|||
strategy: 'Strategy',
|
||||
strategyDown: 'Down',
|
||||
strategyBackup: 'Backup',
|
||||
ipHashBackupErr: 'IP hash does not support backup nodes',
|
||||
|
||||
staticChangePHPHelper: 'Currently a static website, you can switch to a PHP website',
|
||||
proxyCache: 'Reverse Proxy Cache',
|
||||
cacheLimit: 'Cache Space Limit',
|
||||
|
|
|
|||
|
|
@ -2507,6 +2507,8 @@ const message = {
|
|||
strategy: 'Estrategia',
|
||||
strategyDown: 'Baja',
|
||||
strategyBackup: 'Backup',
|
||||
ipHashBackupErr: 'IP hash does not support backup nodes',
|
||||
|
||||
staticChangePHPHelper: 'Actualmente es un sitio estático, puedes cambiarlo a PHP',
|
||||
proxyCache: 'Caché de proxy inverso',
|
||||
cacheLimit: 'Límite de espacio de caché',
|
||||
|
|
|
|||
|
|
@ -2447,6 +2447,8 @@ const message = {
|
|||
strategy: '戦略',
|
||||
strategyDown: '無効',
|
||||
strategyBackup: 'バックアップ',
|
||||
ipHashBackupErr: 'IPハッシュはバックアップノードをサポートしていません',
|
||||
|
||||
staticChangePHPHelper: '現在は静的ウェブサイトですが、PHPウェブサイトに切り替えることができます。',
|
||||
proxyCache: 'リバースプロキシキャッシュ',
|
||||
cacheLimit: 'キャッシュスペース制限',
|
||||
|
|
|
|||
|
|
@ -2405,6 +2405,8 @@ const message = {
|
|||
strategy: '전략',
|
||||
strategyDown: '비활성화',
|
||||
strategyBackup: '백업',
|
||||
ipHashBackupErr: 'IP 해시는 백업 노드를 지원하지 않습니다',
|
||||
|
||||
staticChangePHPHelper: '현재 정적 웹사이트이며 PHP 웹사이트로 전환할 수 있습니다.',
|
||||
proxyCache: '리버스 프록시 캐시',
|
||||
cacheLimit: '캐시 공간 제한',
|
||||
|
|
|
|||
|
|
@ -2502,6 +2502,8 @@ const message = {
|
|||
strategy: 'Strategi',
|
||||
strategyDown: 'Lumpuh',
|
||||
strategyBackup: 'Sandaran',
|
||||
ipHashBackupErr: 'Hash IP tidak menyokong nod sandaran',
|
||||
|
||||
staticChangePHPHelper: 'Kini laman web statik, boleh ditukar ke laman web PHP.',
|
||||
proxyCache: 'Cache Proksi Terbalik',
|
||||
cacheLimit: 'Had Ruang Cache',
|
||||
|
|
|
|||
|
|
@ -2503,6 +2503,8 @@ const message = {
|
|||
strategy: 'Estratégia',
|
||||
strategyDown: 'Desativar',
|
||||
strategyBackup: 'Backup',
|
||||
ipHashBackupErr: 'Hash IP não suporta nós de backup',
|
||||
|
||||
staticChangePHPHelper: 'Atualmente um site estático, pode ser alterado para um site PHP.',
|
||||
proxyCache: 'Cache de Proxy Reverso',
|
||||
cacheLimit: 'Limite de Espaço de Cache',
|
||||
|
|
|
|||
|
|
@ -2500,6 +2500,8 @@ const message = {
|
|||
strategy: 'Стратегия',
|
||||
strategyDown: 'Отключить',
|
||||
strategyBackup: 'Резервный',
|
||||
ipHashBackupErr: 'IP хэш не поддерживает резервные узлы',
|
||||
|
||||
staticChangePHPHelper: 'В настоящее время статический сайт, можно переключить на PHP сайт.',
|
||||
proxyCache: 'Кэш Обратного Прокси',
|
||||
cacheLimit: 'Ограничение Пространства Кэша',
|
||||
|
|
|
|||
|
|
@ -2559,6 +2559,8 @@ const message = {
|
|||
strategy: 'Strateji',
|
||||
strategyDown: 'Kapalı',
|
||||
strategyBackup: 'Yedek',
|
||||
ipHashBackupErr: 'IP 哈希不支持备用节点',
|
||||
|
||||
staticChangePHPHelper: 'Şu anda statik bir web sitesi, PHP web sitesine geçiş yapabilirsiniz',
|
||||
proxyCache: 'Ters Vekil Önbelleği',
|
||||
cacheLimit: 'Önbellek Alanı Sınırı',
|
||||
|
|
|
|||
|
|
@ -2358,6 +2358,8 @@ const message = {
|
|||
strategy: '策略',
|
||||
strategyDown: '停用',
|
||||
strategyBackup: '備用',
|
||||
ipHashBackupErr: 'IP 哈希不支援備用節點',
|
||||
|
||||
staticChangePHPHelper: '目前為靜態網站,可切換為 PHP 網站',
|
||||
proxyCache: '反向代理快取',
|
||||
cacheLimit: '快取空間限制',
|
||||
|
|
|
|||
|
|
@ -2350,6 +2350,8 @@ const message = {
|
|||
strategy: '策略',
|
||||
strategyDown: '停用',
|
||||
strategyBackup: '备用',
|
||||
ipHashBackupErr: 'IP 哈希不支持备用节点',
|
||||
|
||||
staticChangePHPHelper: '当前为静态网站,可以切换为 PHP 网站',
|
||||
proxyCache: '反代缓存',
|
||||
cacheLimit: '缓存空间限制',
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
</el-button>
|
||||
<el-alert :closable="false" class="!mt-2">
|
||||
<template #default>
|
||||
<span style="white-space: pre-line">{{ $t('website.loadBalanceHelper') }}</span>
|
||||
<span class="whitespace-pre-line">{{ $t('website.loadBalanceHelper') }}</span>
|
||||
</template>
|
||||
</el-alert>
|
||||
</template>
|
||||
|
|
@ -39,7 +39,15 @@
|
|||
<el-tag>{{ $t('website.maxConns') }}: {{ item.maxConns }}</el-tag>
|
||||
</td>
|
||||
<td v-if="item.flag != ''">
|
||||
<el-tag type="info">{{ $t('website.strategy') }}: {{ item.flag }}</el-tag>
|
||||
<el-tag type="info">
|
||||
{{ $t('website.strategy') }}:
|
||||
<span v-if="item.flag === 'backup'">
|
||||
{{ $t('website.strategyBackup') }}
|
||||
</span>
|
||||
<span v-if="item.flag === 'down'">
|
||||
{{ $t('website.strategyDown') }}
|
||||
</span>
|
||||
</el-tag>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ import { createLoadBalance, updateLoadBalance } from '@/api/modules/website';
|
|||
import i18n from '@/lang';
|
||||
import { FormInstance } from 'element-plus';
|
||||
import { ref } from 'vue';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import { MsgError, MsgSuccess } from '@/utils/message';
|
||||
import { Rules, checkNumberRange } from '@/global/form-rules';
|
||||
import { getAlgorithms, getStatusStrategy } from '@/global/mimetype';
|
||||
import { Website } from '@/api/interface/website';
|
||||
|
|
@ -204,23 +204,51 @@ const acceptParams = async (req: LoadBalanceOperate) => {
|
|||
open.value = true;
|
||||
};
|
||||
|
||||
const handleServers = () => {
|
||||
for (const server of item.value.servers) {
|
||||
if (!server.weight || server.weight == '') {
|
||||
server.weight = 0;
|
||||
}
|
||||
if (!server.maxFails || server.maxFails == '') {
|
||||
server.maxFails = 0;
|
||||
}
|
||||
if (!server.maxConns || server.maxConns == '') {
|
||||
server.maxConns = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const rollBackServers = () => {
|
||||
for (const server of item.value.servers) {
|
||||
if (server.weight == 0) {
|
||||
server.weight = undefined;
|
||||
}
|
||||
if (server.maxFails == 0) {
|
||||
server.maxFails = undefined;
|
||||
}
|
||||
if (server.maxConns == 0) {
|
||||
server.maxConns = undefined;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const submit = async (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return;
|
||||
await formEl.validate(async (valid) => {
|
||||
if (!valid) {
|
||||
return;
|
||||
}
|
||||
let checkBackup = false;
|
||||
if (item.value.algorithm == 'ip_hash') {
|
||||
checkBackup = true;
|
||||
}
|
||||
for (const server of item.value.servers) {
|
||||
if (!server.weight || server.weight == '') {
|
||||
server.weight = 0;
|
||||
}
|
||||
if (!server.maxFails || server.maxFails == '') {
|
||||
server.maxFails = 0;
|
||||
}
|
||||
if (!server.maxConns || server.maxConns == '') {
|
||||
server.maxConns = 0;
|
||||
if (checkBackup && server.flag == 'backup') {
|
||||
MsgError(i18n.global.t('website.ipHashBackupErr'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
handleServers();
|
||||
loading.value = true;
|
||||
try {
|
||||
if (item.value.operate === 'edit') {
|
||||
|
|
@ -231,6 +259,8 @@ const submit = async (formEl: FormInstance | undefined) => {
|
|||
MsgSuccess(i18n.global.t('commons.msg.createSuccess'));
|
||||
}
|
||||
handleClose();
|
||||
} catch {
|
||||
rollBackServers();
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue