From ad3670c9ad63c1b17787c125608b16810d9bb0a2 Mon Sep 17 00:00:00 2001 From: zhengkunwang <31820853+zhengkunwang223@users.noreply.github.com> Date: Mon, 9 Sep 2024 17:08:04 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20PHP=20=E5=A2=9E=E5=8A=A0=E6=80=A7?= =?UTF-8?q?=E8=83=BD=E8=B0=83=E6=95=B4=E9=85=8D=E7=BD=AE=20(#6420)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- agent/app/api/v2/runtime.go | 50 ++++++- agent/app/dto/request/runtime.go | 5 + agent/app/model/runtime.go | 8 + agent/app/service/runtime.go | 65 +++++++- agent/router/ro_runtime.go | 5 +- frontend/src/api/interface/runtime.ts | 5 + frontend/src/api/modules/runtime.ts | 8 + frontend/src/lang/modules/en.ts | 14 ++ frontend/src/lang/modules/tw.ts | 11 ++ frontend/src/lang/modules/zh.ts | 11 ++ .../runtime/php/config/config/index.vue | 1 - .../website/runtime/php/config/index.vue | 12 +- .../runtime/php/config/performance/index.vue | 140 ++++++++++++++++++ 13 files changed, 326 insertions(+), 9 deletions(-) create mode 100644 frontend/src/views/website/runtime/php/config/performance/index.vue diff --git a/agent/app/api/v2/runtime.go b/agent/app/api/v2/runtime.go index 378d169ef..2da89cb37 100644 --- a/agent/app/api/v2/runtime.go +++ b/agent/app/api/v2/runtime.go @@ -76,6 +76,13 @@ func (b *BaseApi) DeleteRuntime(c *gin.Context) { helper.SuccessWithOutData(c) } +// @Tags Website +// @Summary Delete runtime +// @Description 删除运行环境校验 +// @Accept json +// @Success 200 +// @Security ApiKeyAuth +// @Router /installed/delete/check/:id [get] func (b *BaseApi) DeleteRuntimeCheck(c *gin.Context) { runTimeId, err := helper.GetIntParamByKey(c, "runTimeId") if err != nil { @@ -362,7 +369,6 @@ func (b *BaseApi) UpdatePHPFile(c *gin.Context) { helper.SuccessWithData(c, nil) } -// 写一个调用 GetPHPConfigFile 的方法 // @Tags Runtime // @Summary Get php conf file // @Description 获取 php 配置文件 @@ -383,3 +389,45 @@ func (b *BaseApi) GetPHPConfigFile(c *gin.Context) { } helper.SuccessWithData(c, data) } + +// @Tags Runtime +// @Summary Update fpm config +// @Description 更新 fpm 配置 +// @Accept json +// @Param request body request.FPMConfig true "request" +// @Success 200 +// @Security ApiKeyAuth +// @Router /runtimes/php/fpm/config [post] +func (b *BaseApi) UpdateFPMConfig(c *gin.Context) { + var req request.FPMConfig + if err := helper.CheckBindAndValidate(&req, c); err != nil { + return + } + if err := runtimeService.UpdateFPMConfig(req); err != nil { + helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) + return + } + helper.SuccessWithOutData(c) +} + +// @Tags Runtime +// @Summary Get fpm config +// @Description 获取 fpm 配置 +// @Accept json +// @Param id path integer true "request" +// @Success 200 {object} response.FPMConfig +// @Security ApiKeyAuth +// @Router /runtimes/php/fpm/config/:id [get] +func (b *BaseApi) GetFPMConfig(c *gin.Context) { + id, err := helper.GetParamID(c) + if err != nil { + helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInternalServer, nil) + return + } + data, err := runtimeService.GetFPMConfig(id) + if err != nil { + helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) + return + } + helper.SuccessWithData(c, data) +} diff --git a/agent/app/dto/request/runtime.go b/agent/app/dto/request/runtime.go index 23c288648..9243321df 100644 --- a/agent/app/dto/request/runtime.go +++ b/agent/app/dto/request/runtime.go @@ -95,3 +95,8 @@ type PHPFileReq struct { ID uint `json:"id" validate:"required"` Type string `json:"type" validate:"required"` } + +type FPMConfig struct { + ID uint `json:"id" validate:"required"` + Params map[string]interface{} `json:"params" validate:"required"` +} diff --git a/agent/app/model/runtime.go b/agent/app/model/runtime.go index 69e67fa7d..aeec498e9 100644 --- a/agent/app/model/runtime.go +++ b/agent/app/model/runtime.go @@ -37,6 +37,14 @@ func (r *Runtime) GetPath() string { return path.Join(constant.RuntimeDir, r.Type, r.Name) } +func (r *Runtime) GetFPMPath() string { + return path.Join(constant.RuntimeDir, r.Type, r.Name, "conf", "php-fpm.conf") +} + +func (r *Runtime) GetPHPPath() string { + return path.Join(constant.RuntimeDir, r.Type, r.Name, "conf", "php.ini") +} + func (r *Runtime) GetLogPath() string { return path.Join(r.GetPath(), "build.log") } diff --git a/agent/app/service/runtime.go b/agent/app/service/runtime.go index fc603afb6..aacfd8306 100644 --- a/agent/app/service/runtime.go +++ b/agent/app/service/runtime.go @@ -58,6 +58,8 @@ type IRuntimeService interface { UpdatePHPConfig(req request.PHPConfigUpdate) (err error) UpdatePHPConfigFile(req request.PHPFileUpdate) error GetPHPConfigFile(req request.PHPFileReq) (*response.FileInfo, error) + UpdateFPMConfig(req request.FPMConfig) error + GetFPMConfig(id uint) (*request.FPMConfig, error) } func NewRuntimeService() IRuntimeService { @@ -833,7 +835,7 @@ func (r *RuntimeService) UpdatePHPConfig(req request.PHPConfigUpdate) (err error phpConfigPath := path.Join(runtime.GetPath(), "conf", "php.ini") fileOp := files.NewFileOp() if !fileOp.Stat(phpConfigPath) { - return buserr.WithMap("ErrFileNotFound", map[string]interface{}{"name": "php.ini"}, nil) + return buserr.WithName("ErrFileNotFound", "php.ini") } configFile, err := fileOp.OpenFile(phpConfigPath) if err != nil { @@ -931,3 +933,64 @@ func (r *RuntimeService) UpdatePHPConfigFile(req request.PHPFileUpdate) error { } return nil } + +func (r *RuntimeService) UpdateFPMConfig(req request.FPMConfig) error { + runtime, err := runtimeRepo.GetFirst(commonRepo.WithByID(req.ID)) + if err != nil { + return err + } + cfg, err := ini.Load(runtime.GetFPMPath()) + if err != nil { + return err + } + for k, v := range req.Params { + var valueStr string + switch v := v.(type) { + case string: + valueStr = v + case int: + valueStr = fmt.Sprintf("%d", v) + case float64: + valueStr = fmt.Sprintf("%.f", v) + default: + continue + } + cfg.Section("www").Key(k).SetValue(valueStr) + } + if err := cfg.SaveTo(runtime.GetFPMPath()); err != nil { + return err + } + return nil +} + +var PmKeys = map[string]struct { +}{ + "pm": {}, + "pm.max_children": {}, + "pm.start_servers": {}, + "pm.min_spare_servers": {}, + "pm.max_spare_servers": {}, +} + +func (r *RuntimeService) GetFPMConfig(id uint) (*request.FPMConfig, error) { + runtime, err := runtimeRepo.GetFirst(commonRepo.WithByID(id)) + if err != nil { + return nil, err + } + fileOp := files.NewFileOp() + if !fileOp.Stat(runtime.GetFPMPath()) { + return nil, buserr.WithName("ErrFileNotFound", "php-fpm.conf") + } + params := make(map[string]interface{}) + cfg, err := ini.Load(runtime.GetFPMPath()) + if err != nil { + return nil, err + } + for _, key := range cfg.Section("www").Keys() { + if _, ok := PmKeys[key.Name()]; ok { + params[key.Name()] = key.Value() + } + } + res := &request.FPMConfig{Params: params} + return res, nil +} diff --git a/agent/router/ro_runtime.go b/agent/router/ro_runtime.go index 6bf4e668e..1131039b9 100644 --- a/agent/router/ro_runtime.go +++ b/agent/router/ro_runtime.go @@ -13,7 +13,7 @@ func (r *RuntimeRouter) InitRouter(Router *gin.RouterGroup) { baseApi := v2.ApiGroupApp.BaseApi { - groupRouter.GET("/installed/delete/check/:runTimeId", baseApi.DeleteRuntimeCheck) + groupRouter.GET("/installed/delete/check/:id", baseApi.DeleteRuntimeCheck) groupRouter.POST("/search", baseApi.SearchRuntimes) groupRouter.POST("", baseApi.CreateRuntime) groupRouter.POST("/del", baseApi.DeleteRuntime) @@ -39,6 +39,7 @@ func (r *RuntimeRouter) InitRouter(Router *gin.RouterGroup) { groupRouter.POST("/php/config", baseApi.UpdatePHPConfig) groupRouter.POST("/php/update", baseApi.UpdatePHPFile) groupRouter.POST("/php/file", baseApi.GetPHPConfigFile) + groupRouter.POST("/php/fpm/config", baseApi.UpdateFPMConfig) + groupRouter.GET("/php/fpm/config/:id", baseApi.GetFPMConfig) } - } diff --git a/frontend/src/api/interface/runtime.ts b/frontend/src/api/interface/runtime.ts index 643a29c76..39f52c608 100644 --- a/frontend/src/api/interface/runtime.ts +++ b/frontend/src/api/interface/runtime.ts @@ -166,4 +166,9 @@ export namespace Runtime { id: number; type: string; } + + export interface FPMConfig { + id: number; + params: any; + } } diff --git a/frontend/src/api/modules/runtime.ts b/frontend/src/api/modules/runtime.ts index dcf904052..a3da6dac7 100644 --- a/frontend/src/api/modules/runtime.ts +++ b/frontend/src/api/modules/runtime.ts @@ -96,3 +96,11 @@ export const UpdatePHPFile = (req: Runtime.PHPUpdate) => { export const GetPHPConfigFile = (req: Runtime.PHPFileReq) => { return http.post(`/runtimes/php/file`, req); }; + +export const UpdateFPMConfig = (req: Runtime.FPMConfig) => { + return http.post(`/runtimes/php/fpm/config`, req); +}; + +export const GetFPMConfig = (id: number) => { + return http.get(`/runtimes/php/fpm/config/${id}`); +}; diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts index 33120ac13..8466a32ae 100644 --- a/frontend/src/lang/modules/en.ts +++ b/frontend/src/lang/modules/en.ts @@ -2443,6 +2443,20 @@ const message = { uninstallExtension: 'Are you sure you want to uninstall the extension {0}', phpConfigHelper: 'Modifying the configuration requires restarting the operating environment, do you want to continue', + operateMode: 'operation mode', + dynamic: 'dynamic', + static: 'static', + ondemand: 'on-demand', + dynamicHelper: + 'dynamically adjust the number of processes, high flexibility, suitable for websites with large traffic fluctuations or low memory', + staticHelper: + 'fixed number of processes, suitable for websites with high concurrency and stable traffic, high resource consumption', + ondemandHelper: + 'processes are started and destroyed on demand, resource utilization is optimal, but the initial response may be slow', + max_children: 'maximum number of processes allowed to be created', + start_servers: 'number of processes created at startup', + min_spare_servers: 'minimum number of idle processes', + max_spare_servers: 'maximum number of idle processes', }, process: { pid: 'Process ID', diff --git a/frontend/src/lang/modules/tw.ts b/frontend/src/lang/modules/tw.ts index cd1a12640..c28ed2c1a 100644 --- a/frontend/src/lang/modules/tw.ts +++ b/frontend/src/lang/modules/tw.ts @@ -2266,6 +2266,17 @@ const message = { popularExtension: '常用擴充', uninstallExtension: '是否確認卸載擴充功能 {0}', phpConfigHelper: '修改配置需要重新啟動運行環境,是否繼續', + operateMode: '運行模式', + dynamic: '動態', + static: '靜態', + ondemand: '按需', + dynamicHelper: '動態調整進程數,彈性高,適合流量波動較大或低記憶體的網站', + staticHelper: '固定進程數,適合高併發穩定流量的網站,資源消耗較高', + ondemandHelper: '進程按需啟動和銷毀,資源利用最優,但初始回應可能較慢', + max_children: '允許創建的最大進程數', + start_servers: '啟動時所建立的進程數', + min_spare_servers: '最小空閒行程數', + max_spare_servers: '最大空閒行程數', }, process: { pid: '進程ID', diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index ccc4b2972..c393a3aa9 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -2268,6 +2268,17 @@ const message = { popularExtension: '常用扩展', uninstallExtension: '是否确认卸载扩展 {0}', phpConfigHelper: '修改配置需要重启运行环境,是否继续', + operateMode: '运行模式', + dynamic: '动态', + static: '静态', + ondemand: '按需', + dynamicHelper: '动态调整进程数,灵活性高,适合流量波动较大或者低内存的网站', + staticHelper: '固定进程数,适合高并发和稳定流量的网站,资源消耗较高', + ondemandHelper: '进程按需启动和销毁,资源利用最优,但初始响应可能较慢', + max_children: '允许创建的最大进程数', + start_servers: '启动时创建的进程数', + min_spare_servers: '最小空闲进程数', + max_spare_servers: '最大空闲进程数', }, process: { pid: '进程ID', diff --git a/frontend/src/views/website/runtime/php/config/config/index.vue b/frontend/src/views/website/runtime/php/config/config/index.vue index 76ae9ae1b..a16c35962 100644 --- a/frontend/src/views/website/runtime/php/config/config/index.vue +++ b/frontend/src/views/website/runtime/php/config/config/index.vue @@ -16,7 +16,6 @@ {{ $t('php.max_execution_time') }} - diff --git a/frontend/src/views/website/runtime/php/config/index.vue b/frontend/src/views/website/runtime/php/config/index.vue index a35067bed..ee992d0f2 100644 --- a/frontend/src/views/website/runtime/php/config/index.vue +++ b/frontend/src/views/website/runtime/php/config/index.vue @@ -11,12 +11,15 @@ - - + + - + + + + @@ -24,11 +27,12 @@