feat: Add concurrency configuration for PHP performance optimization (#9877)

This commit is contained in:
CityFun 2025-08-07 21:39:33 +08:00 committed by GitHub
parent 9fed5f4bb8
commit e76836f394
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 104 additions and 12 deletions

View file

@ -873,9 +873,9 @@ func downloadApp(app model.App, appDetail model.AppDetail, appInstall *model.App
_ = fileOp.CreateDir(appVersionDir, constant.DirPerm)
}
if logger == nil {
global.LOG.Infof("download app[%s] from %s", app.Name, appDetail.DownloadUrl)
global.LOG.Infof("download app [%s] from %s", app.Name, appDetail.DownloadUrl)
} else {
logger.Printf("download app[%s] from %s", app.Name, appDetail.DownloadUrl)
logger.Printf("download app [%s] from %s", app.Name, appDetail.DownloadUrl)
}
filePath := path.Join(appVersionDir, app.Key+"-"+appDetail.Version+".tar.gz")
@ -891,9 +891,9 @@ func downloadApp(app model.App, appDetail model.AppDetail, appInstall *model.App
if err = files.DownloadFileWithProxy(appDetail.DownloadUrl, filePath); err != nil {
if logger == nil {
global.LOG.Errorf("download app[%s] error %v", app.Name, err)
global.LOG.Errorf("download app [%s] error %v", app.Name, err)
} else {
logger.Printf("download app[%s] error %v", app.Name, err)
logger.Printf("download app [%s] error %v", app.Name, err)
}
return
}

View file

@ -2795,6 +2795,7 @@ const message = {
'Provide a full startup command. For example, "pip install -r requirements.txt && python manage.py runserver 0.0.0.0:5000".',
dotnetHelper: 'Provide a full startup command. For example, "dotnet MyWebApp.dll".',
dirHelper: 'Note: Please fill in the directory path inside the container',
concurrency: 'Concurrency Scheme',
},
process: {
pid: 'Process ID',

View file

@ -2685,8 +2685,9 @@ const message = {
goDirHelper: 'ディレクトリまたはサブディレクトリにはgoファイルまたはバイナリファイルを含める必要があります',
pythonHelper:
'完全な起動コマンドを提供しますたとえばPIP Install -R Repormations.txt && python manage.py runserver 0.0.0.0:5000',
donetHelper: '完全な起動コマンドを入力してください例えばdotnet MyWebApp.dll',
dotnetHelper: '完全な起動コマンドを入力してください例えばdotnet MyWebApp.dll',
dirHelper: 'ノート: コンテナ内のディレクトリパスを入力してください',
concurrency: '並行処理スキーム',
},
process: {
pid: 'プロセスID',

View file

@ -2637,8 +2637,9 @@ const message = {
goDirHelper: '디렉터리 또는 하위 디렉터리는 Go 또는 바이너리 파일을 포함해야 합니다.',
pythonHelper:
'전체 시작 명령을 제공하세요. : "pip install -r requirements.txt && python manage.py runserver 0.0.0.0:5000".',
donetHelper: '완전한 시작 명령을 입력하세요. : dotnet MyWebApp.dll',
dotnetHelper: '완전한 시작 명령을 입력하세요. : dotnet MyWebApp.dll',
dirHelper: '주의: 컨테이너 내의 디렉토리 경로를 입력하세요',
concurrency: '동시성 체계',
},
process: {
pid: '프로세스 ID',

View file

@ -2746,8 +2746,9 @@ const message = {
goDirHelper: 'Direktori atau subdirektori mesti mengandungi fail Go atau binari.',
pythonHelper:
'Sediakan arahan permulaan penuh. Contohnya, "pip install -r requirements.txt && python manage.py runserver 0.0.0.0:5000".',
donetHelper: 'Sila isi arahan pelancaran lengkap, contohnya dotnet MyWebApp.dll',
dotnetHelper: 'Sila isi arahan pelancaran lengkap, contohnya dotnet MyWebApp.dll',
dirHelper: 'Nota: Sila isi laluan direktori di dalam bekas',
concurrency: 'Skim Serentak',
},
process: {
pid: 'Process ID',

View file

@ -2750,8 +2750,9 @@ const message = {
goDirHelper: 'O diretório ou subdiretório deve conter arquivos Go ou binários.',
pythonHelper:
'Forneça um comando completo de inicialização. Por exemplo, "pip install -r requirements.txt && python manage.py runserver 0.0.0.0:5000".',
donetHelper: 'Por favor, preencha o comando completo de inicialização, por exemplo, dotnet MyWebApp.dll',
dotnetHelper: 'Por favor, preencha o comando completo de inicialização, por exemplo, dotnet MyWebApp.dll',
dirHelper: 'Nota: Preencha o caminho do diretório dentro do contêiner',
concurrency: 'Esquema de Concorrência',
},
process: {
pid: 'ID do Processo',

View file

@ -2742,8 +2742,9 @@ const message = {
goDirHelper: 'Директория или поддиректория должна содержать файлы Go или бинарные файлы.',
pythonHelper:
'Укажите полную команду запуска. Например, "pip install -r requirements.txt && python manage.py runserver 0.0.0.0:5000".',
donetHelper: 'Пожалуйста, укажите полную команду запуска, например, dotnet MyWebApp.dll',
dotnetHelper: 'Пожалуйста, укажите полную команду запуска, например, dotnet MyWebApp.dll',
dirHelper: 'Примечание: Укажите путь к каталогу внутри контейнера',
concurrency: 'Схема параллелизма',
},
process: {
pid: 'ID процесса',

View file

@ -2832,6 +2832,7 @@ const message = {
'Tam bir başlatma komutu sağlayın. Örneğin, "pip install -r requirements.txt && python manage.py runserver 0.0.0.0:5000".',
dotnetHelper: 'Tam bir başlatma komutu sağlayın. Örneğin, "dotnet MyWebApp.dll".',
dirHelper: 'Not: Lütfen kapsayıcı içindeki dizin yolunu doldurun',
concurrency: 'Eşzamanlılık Şeması',
},
process: {
pid: 'İşlem Kimliği',

View file

@ -2603,8 +2603,9 @@ const message = {
environment: '環境變數',
pythonHelper:
'請填寫完整啟動指令例如pip install -r requirements.txt && python manage.py runserver 0.0.0.0:5000',
donetHelper: '請填寫完整的啟動命令例如 dotnet MyWebApp.dll',
dotnetHelper: '請填寫完整的啟動命令例如 dotnet MyWebApp.dll',
dirHelper: '說明請填寫容器內的目錄路徑',
concurrency: '並發方案',
},
process: {
pid: '進程ID',

View file

@ -2593,8 +2593,9 @@ const message = {
environment: '环境变量',
pythonHelper:
'请填写完整启动命令例如pip install -r requirements.txt && python manage.py runserver 0.0.0.0:5000',
donetHelper: '请填写完整启动命令例如 dotnet MyWebApp.dll',
dotnetHelper: '请填写完整启动命令例如 dotnet MyWebApp.dll',
dirHelper: '说明请填写容器内的目录路径',
concurrency: '并发方案',
},
process: {
pid: '进程ID',

View file

@ -19,7 +19,7 @@
<el-input :disabled="mode === 'edit'" v-model="runtime.name"></el-input>
</el-form-item>
<AppConfig v-model="runtime" :mode="mode" appKey="dotnet" />
<DirConfig v-model="runtime" :mode="mode" :scriptHelper="$t('runtime.donetHelper')" />
<DirConfig v-model="runtime" :mode="mode" :scriptHelper="$t('runtime.dotnetHelper')" />
<el-form-item :label="$t('app.containerName')" prop="params.CONTAINER_NAME">
<el-input v-model.trim="runtime.params['CONTAINER_NAME']"></el-input>
</el-form-item>

View file

@ -2,6 +2,16 @@
<el-form :model="params" :rules="variablesRules" ref="phpFormRef" label-position="top" v-loading="loading">
<el-row v-loading="loading">
<el-col :span="22" :offset="1">
<el-form-item :label="$t('runtime.concurrency')">
<el-select v-model="concurrency" @change="changeConcurrency">
<el-option
v-for="item in concurrencyOptions"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item :label="$t('runtime.operateMode')" prop="pm">
<el-select v-model="params.pm">
<el-option :label="$t('runtime.dynamic')" :value="'dynamic'"></el-option>
@ -85,6 +95,79 @@ const variablesRules = reactive({
'pm.min_spare_servers': [checkNumberRange(0, 99999)],
'pm.max_spare_servers': [checkNumberRange(0, 99999)],
});
const concurrency = ref('');
const concurrencyOptions = ref([
{ label: '4 GB', value: '4' },
{ label: '8 GB', value: '8' },
{ label: '16 GB', value: '16' },
{ label: '32 GB', value: '32' },
{ label: '48 GB', value: '48' },
{ label: '64 GB', value: '64' },
{ label: '96 GB', value: '96' },
{ label: '128 GB', value: '128' },
]);
const fpmConfigMap = {
'4': {
max_children: 80,
start_servers: 10,
min_spare_servers: 10,
max_spare_servers: 30,
},
'8': {
max_children: 120,
start_servers: 10,
min_spare_servers: 10,
max_spare_servers: 30,
},
'16': {
max_children: 200,
start_servers: 15,
min_spare_servers: 15,
max_spare_servers: 50,
},
'32': {
max_children: 300,
start_servers: 20,
min_spare_servers: 20,
max_spare_servers: 50,
},
'48': {
max_children: 400,
start_servers: 20,
min_spare_servers: 20,
max_spare_servers: 50,
},
'64': {
max_children: 500,
start_servers: 30,
min_spare_servers: 30,
max_spare_servers: 60,
},
'96': {
max_children: 700,
start_servers: 40,
min_spare_servers: 40,
max_spare_servers: 70,
},
'128': {
max_children: 1000,
start_servers: 50,
min_spare_servers: 50,
max_spare_servers: 100,
},
};
const changeConcurrency = () => {
const config = fpmConfigMap[concurrency.value];
if (config) {
params['pm.max_children'] = config.max_children;
params['pm.start_servers'] = config.start_servers;
params['pm.min_spare_servers'] = config.min_spare_servers;
params['pm.max_spare_servers'] = config.max_spare_servers;
}
};
const get = () => {
loading.value = true;