mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-19 08:19:15 +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;
|
access_log /var/log/nginx/access.log main;
|
||||||
sendfile on;
|
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;
|
include /etc/nginx/conf.d/*.conf;
|
||||||
}
|
}
|
@ -2,6 +2,7 @@ package v1
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
|
"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/1Panel-dev/1Panel/backend/constant"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
@ -15,3 +16,34 @@ func (b *BaseApi) GetNginx(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
helper.SuccessWithData(c, fileInfo)
|
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 {
|
type NginxConfigReq struct {
|
||||||
Scope NginxScope `json:"scope"`
|
Scope NginxKey `json:"scope"`
|
||||||
Operate NginxOp `json:"operate"`
|
Operate NginxOp `json:"operate"`
|
||||||
WebSiteID uint `json:"webSiteId" validate:"required"`
|
WebSiteID uint `json:"webSiteId"`
|
||||||
Params interface{} `json:"params"`
|
Params interface{} `json:"params"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type NginxScope string
|
type NginxScopeReq struct {
|
||||||
|
Scope NginxKey `json:"scope"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type NginxKey string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Index NginxScope = "index"
|
Index NginxKey = "index"
|
||||||
LimitConn NginxScope = "limit-conn"
|
LimitConn NginxKey = "limit-conn"
|
||||||
SSL NginxScope = "ssl"
|
SSL NginxKey = "ssl"
|
||||||
|
HttpPer NginxKey = "http-per"
|
||||||
)
|
)
|
||||||
|
|
||||||
type NginxOp string
|
type NginxOp string
|
||||||
@ -32,12 +37,21 @@ const (
|
|||||||
ConfigDel NginxOp = "delete"
|
ConfigDel NginxOp = "delete"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ScopeKeyMap = map[NginxScope][]string{
|
var ScopeKeyMap = map[NginxKey][]string{
|
||||||
Index: {"index"},
|
Index: {"index"},
|
||||||
LimitConn: {"limit_conn", "limit_rate", "limit_conn_zone"},
|
LimitConn: {"limit_conn", "limit_rate", "limit_conn_zone"},
|
||||||
SSL: {"ssl_certificate", "ssl_certificate_key"},
|
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 {
|
var RepeatKeys = map[string]struct {
|
||||||
}{
|
}{
|
||||||
"limit_conn": {},
|
"limit_conn": {},
|
||||||
@ -47,6 +61,5 @@ var RepeatKeys = map[string]struct {
|
|||||||
type NginxParam struct {
|
type NginxParam struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
SecondKey string `json:"secondKey"`
|
SecondKey string `json:"secondKey"`
|
||||||
IsRepeatKey bool `json:"isRepeatKey"`
|
|
||||||
Params []string `json:"params"`
|
Params []string `json:"params"`
|
||||||
}
|
}
|
||||||
|
@ -211,18 +211,10 @@ func updateInstall(installId uint, detailId uint) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
//oldDetail, err := appDetailRepo.GetFirst(commonRepo.WithByID(install.AppDetailId))
|
|
||||||
//if err != nil {
|
|
||||||
// return err
|
|
||||||
//}
|
|
||||||
|
|
||||||
detail, err := appDetailRepo.GetFirst(commonRepo.WithByID(detailId))
|
detail, err := appDetailRepo.GetFirst(commonRepo.WithByID(detailId))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
//if oldDetail.LastVersion == detail.Version {
|
|
||||||
// install.CanUpdate = false
|
|
||||||
//}
|
|
||||||
if install.Version == detail.Version {
|
if install.Version == detail.Version {
|
||||||
return errors.New("two version is same")
|
return errors.New("two version is same")
|
||||||
}
|
}
|
||||||
@ -592,3 +584,15 @@ func handleInstalled(installed []model.AppInstall) ([]dto.AppInstalled, error) {
|
|||||||
|
|
||||||
return res, nil
|
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 {
|
type NginxService struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w NginxService) GetNginxConfig() (dto.FileInfo, error) {
|
func (n NginxService) GetNginxConfig() (dto.FileInfo, error) {
|
||||||
nginxApp, err := appRepo.GetFirst(appRepo.WithKey("nginx"))
|
|
||||||
if err != nil {
|
nginxInstall, err := getAppInstallByKey("nginx")
|
||||||
return dto.FileInfo{}, err
|
|
||||||
}
|
|
||||||
nginxInstall, err := appInstallRepo.GetFirst(appInstallRepo.WithAppId(nginxApp.ID))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return dto.FileInfo{}, err
|
return dto.FileInfo{}, err
|
||||||
}
|
}
|
||||||
@ -31,3 +28,21 @@ func (w NginxService) GetNginxConfig() (dto.FileInfo, error) {
|
|||||||
}
|
}
|
||||||
return dto.FileInfo{FileInfo: *info}, nil
|
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) {
|
func getNginxConfig(alias string) (dto.NginxConfig, error) {
|
||||||
var nginxConfig dto.NginxConfig
|
var nginxConfig dto.NginxConfig
|
||||||
nginxApp, err := appRepo.GetFirst(appRepo.WithKey("nginx"))
|
|
||||||
if err != nil {
|
nginxInstall, err := getAppInstallByKey("nginx")
|
||||||
return nginxConfig, err
|
|
||||||
}
|
|
||||||
nginxInstall, err := appInstallRepo.GetFirst(appInstallRepo.WithAppId(nginxApp.ID))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nginxConfig, err
|
return nginxConfig, err
|
||||||
}
|
}
|
||||||
@ -257,7 +254,6 @@ func getNginxConfigByKeys(website model.WebSite, keys []string) ([]dto.NginxPara
|
|||||||
Params: dir.GetParameters(),
|
Params: dir.GetParameters(),
|
||||||
}
|
}
|
||||||
if isRepeatKey(key) {
|
if isRepeatKey(key) {
|
||||||
nginxParam.IsRepeatKey = true
|
|
||||||
nginxParam.SecondKey = dir.GetParameters()[0]
|
nginxParam.SecondKey = dir.GetParameters()[0]
|
||||||
}
|
}
|
||||||
res = append(res, nginxParam)
|
res = append(res, nginxParam)
|
||||||
@ -266,7 +262,7 @@ func getNginxConfigByKeys(website model.WebSite, keys []string) ([]dto.NginxPara
|
|||||||
return res, nil
|
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)
|
nginxConfig, err := getNginxConfig(website.Alias)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -279,7 +275,7 @@ func updateNginxConfig(website model.WebSite, params []dto.NginxParam, scope dto
|
|||||||
Name: p.Name,
|
Name: p.Name,
|
||||||
Parameters: p.Params,
|
Parameters: p.Params,
|
||||||
}
|
}
|
||||||
if p.IsRepeatKey {
|
if isRepeatKey(p.Name) {
|
||||||
server.UpdateDirectiveBySecondKey(p.Name, p.SecondKey, newDir)
|
server.UpdateDirectiveBySecondKey(p.Name, p.SecondKey, newDir)
|
||||||
} else {
|
} else {
|
||||||
server.UpdateDirectives(p.Name, newDir)
|
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)
|
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{}
|
newConfig := &components.Config{}
|
||||||
switch scope {
|
switch scope {
|
||||||
case dto.LimitConn:
|
case dto.LimitConn:
|
||||||
@ -306,11 +302,15 @@ func updateConfig(config *components.Config, scope dto.NginxScope) {
|
|||||||
Name: dir.GetName(),
|
Name: dir.GetName(),
|
||||||
Parameters: dir.GetParameters(),
|
Parameters: dir.GetParameters(),
|
||||||
}
|
}
|
||||||
|
if isRepeatKey(dir.GetName()) {
|
||||||
config.UpdateDirectiveBySecondKey(dir.GetName(), dir.GetParameters()[0], newDir)
|
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
|
var nginxParams []dto.NginxParam
|
||||||
newConfig := &components.Config{}
|
newConfig := &components.Config{}
|
||||||
switch scope {
|
switch scope {
|
||||||
@ -429,7 +429,6 @@ func handleParamMap(paramMap map[string]string, keys []string) []dto.NginxParam
|
|||||||
Params: getParamArray(k, v),
|
Params: getParamArray(k, v),
|
||||||
}
|
}
|
||||||
if isRepeatKey(k) {
|
if isRepeatKey(k) {
|
||||||
param.IsRepeatKey = true
|
|
||||||
param.SecondKey = param.Params[0]
|
param.SecondKey = param.Params[0]
|
||||||
}
|
}
|
||||||
nginxParams = append(nginxParams, param)
|
nginxParams = append(nginxParams, param)
|
||||||
|
@ -16,5 +16,7 @@ func (a *NginxRouter) InitNginxRouter(Router *gin.RouterGroup) {
|
|||||||
baseApi := v1.ApiGroupApp.BaseApi
|
baseApi := v1.ApiGroupApp.BaseApi
|
||||||
{
|
{
|
||||||
groupRouter.GET("", baseApi.GetNginx)
|
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
|
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) {
|
func (h *Http) UpdateDirectives(directiveName string, directive Directive) {
|
||||||
directives := make([]IDirective, len(h.GetDirectives()))
|
directives := h.Directives
|
||||||
index := -1
|
index := -1
|
||||||
for i, dir := range h.GetDirectives() {
|
for i, dir := range directives {
|
||||||
if dir.GetName() == directiveName {
|
if dir.GetName() == directiveName {
|
||||||
index = i
|
index = i
|
||||||
break
|
break
|
||||||
@ -107,3 +107,20 @@ func (h *Http) RemoveDirectives(names []string) {
|
|||||||
func (h *Http) GetBlock() IBlock {
|
func (h *Http) GetBlock() IBlock {
|
||||||
return h
|
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
|
//go:embed index.html
|
||||||
var Index []byte
|
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 {
|
export interface NginxParam {
|
||||||
name: string;
|
name: string;
|
||||||
secondKey: string;
|
secondKey: string;
|
||||||
isRepeatKey: string;
|
|
||||||
params: string[];
|
params: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,15 @@
|
|||||||
import http from '@/api';
|
import http from '@/api';
|
||||||
import { File } from '../interface/file';
|
import { File } from '../interface/file';
|
||||||
|
import { Nginx } from '../interface/nginx';
|
||||||
|
|
||||||
export const GetNginx = () => {
|
export const GetNginx = () => {
|
||||||
return http.get<File.File>(`/nginx`);
|
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>
|
||||||
<el-col :xs="8" :sm="6" :md="4" :lg="3" :xl="6">
|
<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-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-button type="primary" link @click="setting">{{ $t('commons.button.set') }}</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
@ -759,5 +759,15 @@ export default {
|
|||||||
security: '安全',
|
security: '安全',
|
||||||
backup: '备份',
|
backup: '备份',
|
||||||
log: '日志',
|
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') {
|
if (param.name === 'limit_rate') {
|
||||||
console.log(param.params[0].match(/\d+/g)?.join(''));
|
|
||||||
form.rate = Number(param.params[0].match(/\d+/g));
|
form.rate = Number(param.params[0].match(/\d+/g));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
|
<div>
|
||||||
<AppStatus :app-key="'nginx'" @setting="setting" @is-exist="checkExist"></AppStatus>
|
<AppStatus :app-key="'nginx'" @setting="setting" @is-exist="checkExist"></AppStatus>
|
||||||
<LayoutContent v-if="nginxIsExist">
|
<LayoutContent v-if="nginxIsExist">
|
||||||
<br />
|
<br />
|
||||||
@ -13,7 +14,12 @@
|
|||||||
<!-- <el-button type="primary" plain>{{ '修改默认页' }}</el-button>
|
<!-- <el-button type="primary" plain>{{ '修改默认页' }}</el-button>
|
||||||
<el-button type="primary" plain>{{ '默认站点' }}</el-button> -->
|
<el-button type="primary" plain>{{ '默认站点' }}</el-button> -->
|
||||||
</template>
|
</template>
|
||||||
<el-table-column :label="$t('commons.table.name')" fix show-overflow-tooltip prop="primaryDomain">
|
<el-table-column
|
||||||
|
:label="$t('commons.table.name')"
|
||||||
|
fix
|
||||||
|
show-overflow-tooltip
|
||||||
|
prop="primaryDomain"
|
||||||
|
>
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-link @click="openConfig(row.id)">{{ row.primaryDomain }}</el-link>
|
<el-link @click="openConfig(row.id)">{{ row.primaryDomain }}</el-link>
|
||||||
</template>
|
</template>
|
||||||
@ -40,6 +46,7 @@
|
|||||||
<DeleteWebsite ref="deleteRef" @close="search"></DeleteWebsite>
|
<DeleteWebsite ref="deleteRef" @close="search"></DeleteWebsite>
|
||||||
<WebSiteGroup ref="groupRef"></WebSiteGroup>
|
<WebSiteGroup ref="groupRef"></WebSiteGroup>
|
||||||
</LayoutContent>
|
</LayoutContent>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
@ -7,6 +7,9 @@
|
|||||||
<el-collapse-item :title="$t('website.log')" name="2">
|
<el-collapse-item :title="$t('website.log')" name="2">
|
||||||
<ContainerLog ref="dialogContainerLogRef" />
|
<ContainerLog ref="dialogContainerLogRef" />
|
||||||
</el-collapse-item>
|
</el-collapse-item>
|
||||||
|
<el-collapse-item :title="$t('website.nginxPer')" name="3">
|
||||||
|
<NginxPer />
|
||||||
|
</el-collapse-item>
|
||||||
</el-collapse>
|
</el-collapse>
|
||||||
</LayoutContent>
|
</LayoutContent>
|
||||||
</template>
|
</template>
|
||||||
@ -16,6 +19,7 @@ import LayoutContent from '@/layout/layout-content.vue';
|
|||||||
import Source from './source/index.vue';
|
import Source from './source/index.vue';
|
||||||
import { ref, watch } from 'vue';
|
import { ref, watch } from 'vue';
|
||||||
import ContainerLog from '@/components/container-log/index.vue';
|
import ContainerLog from '@/components/container-log/index.vue';
|
||||||
|
import NginxPer from './performance/index.vue';
|
||||||
|
|
||||||
let activeName = ref('1');
|
let activeName = ref('1');
|
||||||
let dialogContainerLogRef = ref();
|
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"
|
v-model="content"
|
||||||
:readOnly="true"
|
:readOnly="true"
|
||||||
/>
|
/>
|
||||||
<div style="float: right; margin-top: 10px">
|
<div style="margin-top: 10px">
|
||||||
<el-button type="primary" @click="submit()" :loading="loading">
|
<el-button type="primary" @click="submit()" :loading="loading">
|
||||||
{{ $t('commons.button.save') }}
|
{{ $t('commons.button.save') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user