mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-19 00:09:16 +08:00
feat: 增加nginx性能调整页面
This commit is contained in:
parent
c111290609
commit
ddf6555250
@ -20,7 +20,21 @@ http {
|
||||
|
||||
access_log /var/log/nginx/access.log main;
|
||||
sendfile on;
|
||||
keepalive_timeout 65;
|
||||
|
||||
server_names_hash_bucket_size 512;
|
||||
client_header_buffer_size 32k;
|
||||
client_max_body_size 50m;
|
||||
keepalive_timeout 60;
|
||||
|
||||
gzip on;
|
||||
gzip_min_length 1k;
|
||||
gzip_buffers 4 16k;
|
||||
gzip_http_version 1.1;
|
||||
gzip_comp_level 2;
|
||||
gzip_types text/plain application/javascript application/x-javascript text/javascript text/css application/xml;
|
||||
gzip_vary on;
|
||||
gzip_proxied expired no-cache no-store private auth;
|
||||
gzip_disable "MSIE [1-6]\.";
|
||||
|
||||
include /etc/nginx/conf.d/*.conf;
|
||||
}
|
@ -2,6 +2,7 @@ package v1
|
||||
|
||||
import (
|
||||
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
@ -15,3 +16,34 @@ func (b *BaseApi) GetNginx(c *gin.Context) {
|
||||
}
|
||||
helper.SuccessWithData(c, fileInfo)
|
||||
}
|
||||
|
||||
func (b *BaseApi) GetNginxConfigByScope(c *gin.Context) {
|
||||
|
||||
var req dto.NginxScopeReq
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
|
||||
params, err := nginxService.GetConfigByScope(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, params)
|
||||
}
|
||||
|
||||
func (b *BaseApi) UpdateNginxConfigBy(c *gin.Context) {
|
||||
|
||||
var req dto.NginxConfigReq
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := nginxService.UpdateConfigByScope(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
@ -10,18 +10,23 @@ type NginxConfig struct {
|
||||
}
|
||||
|
||||
type NginxConfigReq struct {
|
||||
Scope NginxScope `json:"scope"`
|
||||
Scope NginxKey `json:"scope"`
|
||||
Operate NginxOp `json:"operate"`
|
||||
WebSiteID uint `json:"webSiteId" validate:"required"`
|
||||
WebSiteID uint `json:"webSiteId"`
|
||||
Params interface{} `json:"params"`
|
||||
}
|
||||
|
||||
type NginxScope string
|
||||
type NginxScopeReq struct {
|
||||
Scope NginxKey `json:"scope"`
|
||||
}
|
||||
|
||||
type NginxKey string
|
||||
|
||||
const (
|
||||
Index NginxScope = "index"
|
||||
LimitConn NginxScope = "limit-conn"
|
||||
SSL NginxScope = "ssl"
|
||||
Index NginxKey = "index"
|
||||
LimitConn NginxKey = "limit-conn"
|
||||
SSL NginxKey = "ssl"
|
||||
HttpPer NginxKey = "http-per"
|
||||
)
|
||||
|
||||
type NginxOp string
|
||||
@ -32,12 +37,21 @@ const (
|
||||
ConfigDel NginxOp = "delete"
|
||||
)
|
||||
|
||||
var ScopeKeyMap = map[NginxScope][]string{
|
||||
var ScopeKeyMap = map[NginxKey][]string{
|
||||
Index: {"index"},
|
||||
LimitConn: {"limit_conn", "limit_rate", "limit_conn_zone"},
|
||||
SSL: {"ssl_certificate", "ssl_certificate_key"},
|
||||
HttpPer: {"server_names_hash_bucket_size", "client_header_buffer_size", "client_max_body_size", "keepalive_timeout", "gzip", "gzip_min_length", "gzip_comp_level"},
|
||||
}
|
||||
|
||||
type NginxScope string
|
||||
|
||||
const (
|
||||
NginxHttp NginxScope = "http"
|
||||
NginxServer NginxScope = "server"
|
||||
NginxEvents NginxScope = "events"
|
||||
)
|
||||
|
||||
var RepeatKeys = map[string]struct {
|
||||
}{
|
||||
"limit_conn": {},
|
||||
@ -45,8 +59,7 @@ var RepeatKeys = map[string]struct {
|
||||
}
|
||||
|
||||
type NginxParam struct {
|
||||
Name string `json:"name"`
|
||||
SecondKey string `json:"secondKey"`
|
||||
IsRepeatKey bool `json:"isRepeatKey"`
|
||||
Params []string `json:"params"`
|
||||
Name string `json:"name"`
|
||||
SecondKey string `json:"secondKey"`
|
||||
Params []string `json:"params"`
|
||||
}
|
||||
|
@ -211,18 +211,10 @@ func updateInstall(installId uint, detailId uint) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//oldDetail, err := appDetailRepo.GetFirst(commonRepo.WithByID(install.AppDetailId))
|
||||
//if err != nil {
|
||||
// return err
|
||||
//}
|
||||
|
||||
detail, err := appDetailRepo.GetFirst(commonRepo.WithByID(detailId))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//if oldDetail.LastVersion == detail.Version {
|
||||
// install.CanUpdate = false
|
||||
//}
|
||||
if install.Version == detail.Version {
|
||||
return errors.New("two version is same")
|
||||
}
|
||||
@ -592,3 +584,15 @@ func handleInstalled(installed []model.AppInstall) ([]dto.AppInstalled, error) {
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func getAppInstallByKey(key string) (model.AppInstall, error) {
|
||||
app, err := appRepo.GetFirst(appRepo.WithKey(key))
|
||||
if err != nil {
|
||||
return model.AppInstall{}, err
|
||||
}
|
||||
appInstall, err := appInstallRepo.GetFirst(appInstallRepo.WithAppId(app.ID))
|
||||
if err != nil {
|
||||
return model.AppInstall{}, err
|
||||
}
|
||||
return appInstall, nil
|
||||
}
|
||||
|
@ -10,12 +10,9 @@ import (
|
||||
type NginxService struct {
|
||||
}
|
||||
|
||||
func (w NginxService) GetNginxConfig() (dto.FileInfo, error) {
|
||||
nginxApp, err := appRepo.GetFirst(appRepo.WithKey("nginx"))
|
||||
if err != nil {
|
||||
return dto.FileInfo{}, err
|
||||
}
|
||||
nginxInstall, err := appInstallRepo.GetFirst(appInstallRepo.WithAppId(nginxApp.ID))
|
||||
func (n NginxService) GetNginxConfig() (dto.FileInfo, error) {
|
||||
|
||||
nginxInstall, err := getAppInstallByKey("nginx")
|
||||
if err != nil {
|
||||
return dto.FileInfo{}, err
|
||||
}
|
||||
@ -31,3 +28,21 @@ func (w NginxService) GetNginxConfig() (dto.FileInfo, error) {
|
||||
}
|
||||
return dto.FileInfo{FileInfo: *info}, nil
|
||||
}
|
||||
|
||||
func (n NginxService) GetConfigByScope(req dto.NginxScopeReq) ([]dto.NginxParam, error) {
|
||||
|
||||
keys, ok := dto.ScopeKeyMap[req.Scope]
|
||||
if !ok || len(keys) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return getHttpConfigByKeys(keys)
|
||||
}
|
||||
|
||||
func (n NginxService) UpdateConfigByScope(req dto.NginxConfigReq) error {
|
||||
keys, ok := dto.ScopeKeyMap[req.Scope]
|
||||
if !ok || len(keys) == 0 {
|
||||
return nil
|
||||
}
|
||||
return updateHttpNginxConfig(getNginxParams(req.Params, keys))
|
||||
}
|
||||
|
90
backend/app/service/nginx_utils.go
Normal file
90
backend/app/service/nginx_utils.go
Normal file
@ -0,0 +1,90 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/nginx"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/nginx/components"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/nginx/parser"
|
||||
"os"
|
||||
"path"
|
||||
)
|
||||
|
||||
func getDefaultNginxConfig() (dto.NginxConfig, error) {
|
||||
var nginxConfig dto.NginxConfig
|
||||
|
||||
nginxInstall, err := getAppInstallByKey("nginx")
|
||||
if err != nil {
|
||||
return nginxConfig, err
|
||||
}
|
||||
|
||||
configPath := path.Join(constant.AppInstallDir, "nginx", nginxInstall.Name, "conf", "nginx.conf")
|
||||
content, err := os.ReadFile(configPath)
|
||||
if err != nil {
|
||||
return nginxConfig, err
|
||||
}
|
||||
config := parser.NewStringParser(string(content)).Parse()
|
||||
config.FilePath = configPath
|
||||
nginxConfig.Config = config
|
||||
nginxConfig.OldContent = string(content)
|
||||
nginxConfig.ContainerName = nginxInstall.ContainerName
|
||||
nginxConfig.FilePath = configPath
|
||||
|
||||
return nginxConfig, nil
|
||||
}
|
||||
|
||||
func getHttpConfigByKeys(keys []string) ([]dto.NginxParam, error) {
|
||||
nginxConfig, err := getDefaultNginxConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config := nginxConfig.Config
|
||||
http := config.FindHttp()
|
||||
|
||||
var res []dto.NginxParam
|
||||
for _, key := range keys {
|
||||
dirs := http.FindDirectives(key)
|
||||
for _, dir := range dirs {
|
||||
nginxParam := dto.NginxParam{
|
||||
Name: dir.GetName(),
|
||||
Params: dir.GetParameters(),
|
||||
}
|
||||
if isRepeatKey(key) {
|
||||
nginxParam.SecondKey = dir.GetParameters()[0]
|
||||
}
|
||||
res = append(res, nginxParam)
|
||||
}
|
||||
if len(dirs) == 0 {
|
||||
nginxParam := dto.NginxParam{
|
||||
Name: key,
|
||||
Params: []string{},
|
||||
}
|
||||
res = append(res, nginxParam)
|
||||
}
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func updateHttpNginxConfig(params []dto.NginxParam) error {
|
||||
nginxConfig, err := getDefaultNginxConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
config := nginxConfig.Config
|
||||
http := config.FindHttp()
|
||||
for _, p := range params {
|
||||
newDir := components.Directive{
|
||||
Name: p.Name,
|
||||
Parameters: p.Params,
|
||||
}
|
||||
if isRepeatKey(p.Name) {
|
||||
http.UpdateDirectiveBySecondKey(p.Name, p.SecondKey, newDir)
|
||||
} else {
|
||||
http.UpdateDirectives(p.Name, newDir)
|
||||
}
|
||||
}
|
||||
if err := nginx.WriteConfig(config, nginx.IndentedStyle); err != nil {
|
||||
return err
|
||||
}
|
||||
return nginxCheckAndReload(nginxConfig.OldContent, nginxConfig.FilePath, nginxConfig.ContainerName)
|
||||
}
|
@ -175,11 +175,8 @@ func nginxCheckAndReload(oldContent string, filePath string, containerName strin
|
||||
|
||||
func getNginxConfig(alias string) (dto.NginxConfig, error) {
|
||||
var nginxConfig dto.NginxConfig
|
||||
nginxApp, err := appRepo.GetFirst(appRepo.WithKey("nginx"))
|
||||
if err != nil {
|
||||
return nginxConfig, err
|
||||
}
|
||||
nginxInstall, err := appInstallRepo.GetFirst(appInstallRepo.WithAppId(nginxApp.ID))
|
||||
|
||||
nginxInstall, err := getAppInstallByKey("nginx")
|
||||
if err != nil {
|
||||
return nginxConfig, err
|
||||
}
|
||||
@ -257,7 +254,6 @@ func getNginxConfigByKeys(website model.WebSite, keys []string) ([]dto.NginxPara
|
||||
Params: dir.GetParameters(),
|
||||
}
|
||||
if isRepeatKey(key) {
|
||||
nginxParam.IsRepeatKey = true
|
||||
nginxParam.SecondKey = dir.GetParameters()[0]
|
||||
}
|
||||
res = append(res, nginxParam)
|
||||
@ -266,7 +262,7 @@ func getNginxConfigByKeys(website model.WebSite, keys []string) ([]dto.NginxPara
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func updateNginxConfig(website model.WebSite, params []dto.NginxParam, scope dto.NginxScope) error {
|
||||
func updateNginxConfig(website model.WebSite, params []dto.NginxParam, scope dto.NginxKey) error {
|
||||
nginxConfig, err := getNginxConfig(website.Alias)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -279,7 +275,7 @@ func updateNginxConfig(website model.WebSite, params []dto.NginxParam, scope dto
|
||||
Name: p.Name,
|
||||
Parameters: p.Params,
|
||||
}
|
||||
if p.IsRepeatKey {
|
||||
if isRepeatKey(p.Name) {
|
||||
server.UpdateDirectiveBySecondKey(p.Name, p.SecondKey, newDir)
|
||||
} else {
|
||||
server.UpdateDirectives(p.Name, newDir)
|
||||
@ -291,7 +287,7 @@ func updateNginxConfig(website model.WebSite, params []dto.NginxParam, scope dto
|
||||
return nginxCheckAndReload(nginxConfig.OldContent, nginxConfig.FilePath, nginxConfig.ContainerName)
|
||||
}
|
||||
|
||||
func updateConfig(config *components.Config, scope dto.NginxScope) {
|
||||
func updateConfig(config *components.Config, scope dto.NginxKey) {
|
||||
newConfig := &components.Config{}
|
||||
switch scope {
|
||||
case dto.LimitConn:
|
||||
@ -306,11 +302,15 @@ func updateConfig(config *components.Config, scope dto.NginxScope) {
|
||||
Name: dir.GetName(),
|
||||
Parameters: dir.GetParameters(),
|
||||
}
|
||||
config.UpdateDirectiveBySecondKey(dir.GetName(), dir.GetParameters()[0], newDir)
|
||||
if isRepeatKey(dir.GetName()) {
|
||||
config.UpdateDirectiveBySecondKey(dir.GetName(), dir.GetParameters()[0], newDir)
|
||||
} else {
|
||||
config.UpdateDirectives(dir.GetName(), newDir)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getNginxParamsFromStaticFile(scope dto.NginxScope) []dto.NginxParam {
|
||||
func getNginxParamsFromStaticFile(scope dto.NginxKey) []dto.NginxParam {
|
||||
var nginxParams []dto.NginxParam
|
||||
newConfig := &components.Config{}
|
||||
switch scope {
|
||||
@ -429,7 +429,6 @@ func handleParamMap(paramMap map[string]string, keys []string) []dto.NginxParam
|
||||
Params: getParamArray(k, v),
|
||||
}
|
||||
if isRepeatKey(k) {
|
||||
param.IsRepeatKey = true
|
||||
param.SecondKey = param.Params[0]
|
||||
}
|
||||
nginxParams = append(nginxParams, param)
|
||||
|
@ -16,5 +16,7 @@ func (a *NginxRouter) InitNginxRouter(Router *gin.RouterGroup) {
|
||||
baseApi := v1.ApiGroupApp.BaseApi
|
||||
{
|
||||
groupRouter.GET("", baseApi.GetNginx)
|
||||
groupRouter.POST("/scope", baseApi.GetNginxConfigByScope)
|
||||
groupRouter.POST("/update", baseApi.UpdateNginxConfigBy)
|
||||
}
|
||||
}
|
||||
|
@ -26,3 +26,13 @@ func (c *Config) FindServers() []*Server {
|
||||
}
|
||||
return servers
|
||||
}
|
||||
|
||||
func (c *Config) FindHttp() *Http {
|
||||
var http *Http
|
||||
directives := c.Block.FindDirectives("http")
|
||||
if len(directives) > 0 {
|
||||
http = directives[0].(*Http)
|
||||
}
|
||||
|
||||
return http
|
||||
}
|
||||
|
@ -67,9 +67,9 @@ func (h *Http) FindDirectives(directiveName string) []IDirective {
|
||||
}
|
||||
|
||||
func (h *Http) UpdateDirectives(directiveName string, directive Directive) {
|
||||
directives := make([]IDirective, len(h.GetDirectives()))
|
||||
directives := h.Directives
|
||||
index := -1
|
||||
for i, dir := range h.GetDirectives() {
|
||||
for i, dir := range directives {
|
||||
if dir.GetName() == directiveName {
|
||||
index = i
|
||||
break
|
||||
@ -107,3 +107,20 @@ func (h *Http) RemoveDirectives(names []string) {
|
||||
func (h *Http) GetBlock() IBlock {
|
||||
return h
|
||||
}
|
||||
|
||||
func (h *Http) UpdateDirectiveBySecondKey(name string, key string, directive Directive) {
|
||||
directives := h.Directives
|
||||
index := -1
|
||||
for i, dir := range directives {
|
||||
if dir.GetName() == name && dir.GetParameters()[0] == key {
|
||||
index = i
|
||||
break
|
||||
}
|
||||
}
|
||||
if index > -1 {
|
||||
directives[index] = &directive
|
||||
} else {
|
||||
directives = append(directives, &directive)
|
||||
}
|
||||
h.Directives = directives
|
||||
}
|
||||
|
14
cmd/server/nginx_conf/http_per.conf
Normal file
14
cmd/server/nginx_conf/http_per.conf
Normal file
@ -0,0 +1,14 @@
|
||||
server_names_hash_bucket_size 512;
|
||||
client_header_buffer_size 32k;
|
||||
client_max_body_size 50m;
|
||||
keepalive_timeout 60;
|
||||
|
||||
gzip on;
|
||||
gzip_min_length 1k;
|
||||
gzip_buffers 4 16k;
|
||||
gzip_http_version 1.1;
|
||||
gzip_comp_level 2;
|
||||
gzip_types text/plain application/javascript application/x-javascript text/javascript text/css application/xml;
|
||||
gzip_vary on;
|
||||
gzip_proxied expired no-cache no-store private auth;
|
||||
gzip_disable "MSIE [1-6]\.";
|
@ -18,3 +18,6 @@ var Limit []byte
|
||||
|
||||
//go:embed index.html
|
||||
var Index []byte
|
||||
|
||||
//go:embed http_per.conf
|
||||
var HttpPer []byte
|
||||
|
@ -1 +1,17 @@
|
||||
export namespace Nginx {}
|
||||
export namespace Nginx {
|
||||
export interface NginxScopeReq {
|
||||
scope: string;
|
||||
}
|
||||
export interface NginxParam {
|
||||
name: string;
|
||||
secondKey: string;
|
||||
params: string[];
|
||||
}
|
||||
|
||||
export interface NginxConfigReq {
|
||||
operate: string;
|
||||
websiteId?: number;
|
||||
scope: string;
|
||||
params?: any;
|
||||
}
|
||||
}
|
||||
|
@ -94,7 +94,6 @@ export namespace WebSite {
|
||||
export interface NginxParam {
|
||||
name: string;
|
||||
secondKey: string;
|
||||
isRepeatKey: string;
|
||||
params: string[];
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,15 @@
|
||||
import http from '@/api';
|
||||
import { File } from '../interface/file';
|
||||
import { Nginx } from '../interface/nginx';
|
||||
|
||||
export const GetNginx = () => {
|
||||
return http.get<File.File>(`/nginx`);
|
||||
};
|
||||
|
||||
export const GetNginxConfigByScope = (req: Nginx.NginxScopeReq) => {
|
||||
return http.post<Nginx.NginxParam[]>(`/nginx/scope`, req);
|
||||
};
|
||||
|
||||
export const UpdateNginxConfigByScope = (req: Nginx.NginxConfigReq) => {
|
||||
return http.post<any>(`/nginx/update`, req);
|
||||
};
|
||||
|
@ -29,6 +29,7 @@
|
||||
</el-col>
|
||||
<el-col :xs="8" :sm="6" :md="4" :lg="3" :xl="6">
|
||||
<el-button type="primary" link @click="onOperate('restart')">{{ $t('app.restart') }}</el-button>
|
||||
<el-divider direction="vertical" />
|
||||
<el-button type="primary" link @click="setting">{{ $t('commons.button.set') }}</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
@ -759,5 +759,15 @@ export default {
|
||||
security: '安全',
|
||||
backup: '备份',
|
||||
log: '日志',
|
||||
nginxPer: '性能调整',
|
||||
},
|
||||
nginx: {
|
||||
serverNamesHashBucketSizeHelper: '服务器名字的hash表大小',
|
||||
clientHeaderBufferSizeHelper: '客户端请求的头buffer大小',
|
||||
clientMaxBodySizeHelper: '最大上传文件',
|
||||
keepaliveTimeoutHelper: '连接超时时间',
|
||||
gzipMinLengthHelper: '最小压缩文件',
|
||||
gzipCompLevelHelper: '压缩率',
|
||||
gzipHelper: '是否开启压缩传输',
|
||||
},
|
||||
};
|
||||
|
@ -76,7 +76,6 @@ const search = (req: WebSite.NginxConfigReq) => {
|
||||
}
|
||||
}
|
||||
if (param.name === 'limit_rate') {
|
||||
console.log(param.params[0].match(/\d+/g)?.join(''));
|
||||
form.rate = Number(param.params[0].match(/\d+/g));
|
||||
}
|
||||
}
|
||||
|
@ -1,45 +1,52 @@
|
||||
<template>
|
||||
<AppStatus :app-key="'nginx'" @setting="setting" @is-exist="checkExist"></AppStatus>
|
||||
<LayoutContent v-if="nginxIsExist">
|
||||
<br />
|
||||
<el-card v-if="!openNginxConfig">
|
||||
<LayoutContent :header="$t('website.website')">
|
||||
<ComplexTable :pagination-config="paginationConfig" :data="data" @search="search()">
|
||||
<template #toolbar>
|
||||
<el-button type="primary" plain @click="openCreate">
|
||||
{{ $t('commons.button.create') }}
|
||||
</el-button>
|
||||
<el-button type="primary" plain @click="openGroup">{{ $t('website.group') }}</el-button>
|
||||
<!-- <el-button type="primary" plain>{{ '修改默认页' }}</el-button>
|
||||
<div>
|
||||
<AppStatus :app-key="'nginx'" @setting="setting" @is-exist="checkExist"></AppStatus>
|
||||
<LayoutContent v-if="nginxIsExist">
|
||||
<br />
|
||||
<el-card v-if="!openNginxConfig">
|
||||
<LayoutContent :header="$t('website.website')">
|
||||
<ComplexTable :pagination-config="paginationConfig" :data="data" @search="search()">
|
||||
<template #toolbar>
|
||||
<el-button type="primary" plain @click="openCreate">
|
||||
{{ $t('commons.button.create') }}
|
||||
</el-button>
|
||||
<el-button type="primary" plain @click="openGroup">{{ $t('website.group') }}</el-button>
|
||||
<!-- <el-button type="primary" plain>{{ '修改默认页' }}</el-button>
|
||||
<el-button type="primary" plain>{{ '默认站点' }}</el-button> -->
|
||||
</template>
|
||||
<el-table-column :label="$t('commons.table.name')" fix show-overflow-tooltip prop="primaryDomain">
|
||||
<template #default="{ row }">
|
||||
<el-link @click="openConfig(row.id)">{{ row.primaryDomain }}</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('commons.table.status')" prop="status"></el-table-column>
|
||||
<!-- <el-table-column :label="'备份'" prop="backup"></el-table-column> -->
|
||||
<el-table-column :label="'备注'" prop="remark"></el-table-column>
|
||||
<!-- <el-table-column :label="'SSL证书'" prop="ssl"></el-table-column> -->
|
||||
<fu-table-operations
|
||||
:ellipsis="1"
|
||||
:buttons="buttons"
|
||||
:label="$t('commons.table.operate')"
|
||||
fixed="right"
|
||||
fix
|
||||
/>
|
||||
</ComplexTable>
|
||||
</LayoutContent>
|
||||
</el-card>
|
||||
<el-card v-if="openNginxConfig">
|
||||
<NginxConfig :containerName="containerName"></NginxConfig>
|
||||
</el-card>
|
||||
<el-table-column
|
||||
:label="$t('commons.table.name')"
|
||||
fix
|
||||
show-overflow-tooltip
|
||||
prop="primaryDomain"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<el-link @click="openConfig(row.id)">{{ row.primaryDomain }}</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('commons.table.status')" prop="status"></el-table-column>
|
||||
<!-- <el-table-column :label="'备份'" prop="backup"></el-table-column> -->
|
||||
<el-table-column :label="'备注'" prop="remark"></el-table-column>
|
||||
<!-- <el-table-column :label="'SSL证书'" prop="ssl"></el-table-column> -->
|
||||
<fu-table-operations
|
||||
:ellipsis="1"
|
||||
:buttons="buttons"
|
||||
:label="$t('commons.table.operate')"
|
||||
fixed="right"
|
||||
fix
|
||||
/>
|
||||
</ComplexTable>
|
||||
</LayoutContent>
|
||||
</el-card>
|
||||
<el-card v-if="openNginxConfig">
|
||||
<NginxConfig :containerName="containerName"></NginxConfig>
|
||||
</el-card>
|
||||
|
||||
<CreateWebSite ref="createRef" @close="search"></CreateWebSite>
|
||||
<DeleteWebsite ref="deleteRef" @close="search"></DeleteWebsite>
|
||||
<WebSiteGroup ref="groupRef"></WebSiteGroup>
|
||||
</LayoutContent>
|
||||
<CreateWebSite ref="createRef" @close="search"></CreateWebSite>
|
||||
<DeleteWebsite ref="deleteRef" @close="search"></DeleteWebsite>
|
||||
<WebSiteGroup ref="groupRef"></WebSiteGroup>
|
||||
</LayoutContent>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@ -7,6 +7,9 @@
|
||||
<el-collapse-item :title="$t('website.log')" name="2">
|
||||
<ContainerLog ref="dialogContainerLogRef" />
|
||||
</el-collapse-item>
|
||||
<el-collapse-item :title="$t('website.nginxPer')" name="3">
|
||||
<NginxPer />
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
</LayoutContent>
|
||||
</template>
|
||||
@ -16,6 +19,7 @@ import LayoutContent from '@/layout/layout-content.vue';
|
||||
import Source from './source/index.vue';
|
||||
import { ref, watch } from 'vue';
|
||||
import ContainerLog from '@/components/container-log/index.vue';
|
||||
import NginxPer from './performance/index.vue';
|
||||
|
||||
let activeName = ref('1');
|
||||
let dialogContainerLogRef = ref();
|
||||
|
142
frontend/src/views/website/website/nginx/performance/index.vue
Normal file
142
frontend/src/views/website/website/nginx/performance/index.vue
Normal file
@ -0,0 +1,142 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-card>
|
||||
<el-form :model="form" :rules="variablesRules" ref="nginxFormRef" label-width="160px">
|
||||
<el-row>
|
||||
<el-col :span="1"><br /></el-col>
|
||||
<el-col :span="9">
|
||||
<el-form-item label="server_names_hash_bucket_size" prop="server_names_hash_bucket_size">
|
||||
<el-input clearable v-model.number="form.server_names_hash_bucket_size"></el-input>
|
||||
<span class="input-help">{{ $t('nginx.serverNamesHashBucketSizeHelper') }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="client_header_buffer_size" prop="client_header_buffer_size">
|
||||
<el-input clearable v-model.number="form.client_header_buffer_size">
|
||||
<template #append>K</template>
|
||||
</el-input>
|
||||
<span class="input-help">{{ $t('nginx.clientHeaderBufferSizeHelper') }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="client_max_body_size" prop="client_max_body_size">
|
||||
<el-input clearable v-model.number="form.client_max_body_size">
|
||||
<template #append>MB</template>
|
||||
</el-input>
|
||||
<span class="input-help">{{ $t('nginx.clientMaxBodySizeHelper') }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="keepalive_timeout" prop="keepalive_timeout">
|
||||
<el-input clearable v-model.number="form.keepalive_timeout"></el-input>
|
||||
<span class="input-help">{{ $t('nginx.keepaliveTimeoutHelper') }}</span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="1"><br /></el-col>
|
||||
<el-col :span="9">
|
||||
<el-form-item label="gzip" prop="gzip">
|
||||
<el-select v-model="form.gzip">
|
||||
<el-option :label="'on'" :value="'on'"></el-option>
|
||||
<el-option :label="'off'" :value="'off'"></el-option>
|
||||
</el-select>
|
||||
<span class="input-help">{{ $t('nginx.gzipHelper') }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="gzip_min_length" prop="gzip_min_length">
|
||||
<el-input clearable v-model.number="form.gzip_min_length">
|
||||
<template #append>KB</template>
|
||||
</el-input>
|
||||
<span class="input-help">{{ $t('nginx.gzipMinLengthHelper') }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="gzip_comp_level" prop="gzip_comp_level">
|
||||
<el-input clearable v-model.number="form.gzip_comp_level"></el-input>
|
||||
<span class="input-help">{{ $t('nginx.gzipCompLevelHelper') }}</span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<el-button type="primary" @click="submit(nginxFormRef)" :loading="loading">
|
||||
{{ $t('commons.button.save') }}
|
||||
</el-button>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { Nginx } from '@/api/interface/nginx';
|
||||
import { GetNginxConfigByScope, UpdateNginxConfigByScope } from '@/api/modules/nginx';
|
||||
import { Rules } from '@/global/form-rules';
|
||||
import i18n from '@/lang';
|
||||
import { ElMessage, FormInstance } from 'element-plus';
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
|
||||
let req = ref<Nginx.NginxScopeReq>({
|
||||
scope: 'http-per',
|
||||
});
|
||||
let updateReq = ref<Nginx.NginxConfigReq>({
|
||||
scope: 'http-per',
|
||||
operate: 'update',
|
||||
params: {},
|
||||
});
|
||||
let data = ref();
|
||||
let form = ref({
|
||||
server_names_hash_bucket_size: 512,
|
||||
client_header_buffer_size: 32,
|
||||
client_max_body_size: 50,
|
||||
keepalive_timeout: 60,
|
||||
gzip_min_length: 1,
|
||||
gzip_comp_level: 2,
|
||||
gzip: 'on',
|
||||
});
|
||||
let nginxFormRef = ref();
|
||||
let loading = ref(false);
|
||||
|
||||
const variablesRules = reactive({
|
||||
server_names_hash_bucket_size: [Rules.number],
|
||||
client_header_buffer_size: [Rules.number],
|
||||
client_max_body_size: [Rules.number],
|
||||
keepalive_timeout: [Rules.number],
|
||||
gzip: [Rules.requiredSelect],
|
||||
gzip_min_length: [Rules.requiredSelect],
|
||||
gzip_comp_level: [Rules.number],
|
||||
});
|
||||
|
||||
const getParams = async () => {
|
||||
const res = await GetNginxConfigByScope(req.value);
|
||||
data.value = res.data;
|
||||
for (const param of res.data) {
|
||||
if (param.params.length === 0) {
|
||||
continue;
|
||||
}
|
||||
if (param.name == 'gzip') {
|
||||
form.value.gzip = param.params[0];
|
||||
} else {
|
||||
form.value[param.name] = Number(param.params[0].match(/\d+/g));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const submit = async (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return;
|
||||
await formEl.validate((valid) => {
|
||||
if (!valid) {
|
||||
return;
|
||||
}
|
||||
loading.value = true;
|
||||
let params = {
|
||||
gzip: form.value.gzip,
|
||||
server_names_hash_bucket_size: String(form.value.server_names_hash_bucket_size),
|
||||
client_header_buffer_size: String(form.value.client_header_buffer_size) + 'k',
|
||||
client_max_body_size: String(form.value.client_max_body_size) + 'm',
|
||||
keepalive_timeout: String(form.value.keepalive_timeout),
|
||||
gzip_min_length: String(form.value.gzip_min_length) + 'k',
|
||||
gzip_comp_level: String(form.value.gzip_comp_level),
|
||||
};
|
||||
updateReq.value.params = params;
|
||||
UpdateNginxConfigByScope(updateReq.value)
|
||||
.then(() => {
|
||||
ElMessage.success(i18n.global.t('commons.msg.updateSuccess'));
|
||||
getParams();
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getParams();
|
||||
});
|
||||
</script>
|
@ -14,7 +14,7 @@
|
||||
v-model="content"
|
||||
:readOnly="true"
|
||||
/>
|
||||
<div style="float: right; margin-top: 10px">
|
||||
<div style="margin-top: 10px">
|
||||
<el-button type="primary" @click="submit()" :loading="loading">
|
||||
{{ $t('commons.button.save') }}
|
||||
</el-button>
|
||||
|
Loading…
x
Reference in New Issue
Block a user