feat: 新增 Apache、Tomcat,总计 44 个组件
- Apache: MPM 模型(event/worker/prefork)、SSL、反向代理、模块管理、Gzip - Tomcat: 连接器配置、线程池、AJP、SSL、JVM 内存(Xms/Xmx)、GC 策略
This commit is contained in:
@@ -37,11 +37,13 @@
|
||||
|
||||
---
|
||||
|
||||
## 🧩 支持组件(42 个)
|
||||
## 🧩 支持组件(44 个)
|
||||
|
||||
| 分类 | 组件 | 输出格式 | 核心配置项 |
|
||||
|------|------|----------|------------|
|
||||
| 代理与 Web | **NGINX** | `.conf` | HTTP/HTTPS 端口、域名、SSL 证书、反向代理、Gzip、CORS |
|
||||
| 代理与 Web | **Apache** | `.conf` | MPM 模型(event/worker/prefork)、SSL、反向代理、模块管理 |
|
||||
| 代理与 Web | **Tomcat** | `.xml` | 连接器、线程池、AJP、SSL、JVM 内存、GC 策略 |
|
||||
| 缓存 | **Redis** | `.conf` | 单机/哨兵/集群模式、端口、内存限制、RDB/AOF 持久化、密码 |
|
||||
| 数据库 | **MySQL** | `.cnf` | 版本(5.7/8.0)、Buffer Pool 自动计算、字符集、慢查询、主从复制 |
|
||||
| 数据库 | **PostgreSQL** | `.conf` | 共享缓冲区、WAL 配置、SSL、连接数、慢查询阈值 |
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
</div>
|
||||
|
||||
<div class="sidebar-footer">
|
||||
<el-text size="small" type="info">v1.0.0 · 纯前端生成 · 42 个组件</el-text>
|
||||
<el-text size="small" type="info">v1.0.0 · 纯前端生成 · 44 个组件</el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -0,0 +1,432 @@
|
||||
export const apacheSchema = {
|
||||
id: 'apache',
|
||||
name: 'Apache',
|
||||
icon: 'Monitor',
|
||||
category: '代理与Web',
|
||||
description: '世界上使用最广泛的 HTTP Web 服务器',
|
||||
format: 'conf',
|
||||
fileName: 'httpd.conf',
|
||||
groups: [
|
||||
{
|
||||
title: '基础配置',
|
||||
fields: [
|
||||
{
|
||||
key: 'serverRoot',
|
||||
label: '服务器根目录',
|
||||
type: 'text',
|
||||
default: '/etc/httpd',
|
||||
},
|
||||
{
|
||||
key: 'listen',
|
||||
label: '监听端口',
|
||||
type: 'number',
|
||||
min: 1,
|
||||
max: 65535,
|
||||
default: 80,
|
||||
},
|
||||
{
|
||||
key: 'serverName',
|
||||
label: '服务器域名',
|
||||
type: 'text',
|
||||
placeholder: 'www.example.com:80',
|
||||
default: 'localhost:80',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
key: 'serverAdmin',
|
||||
label: '管理员邮箱',
|
||||
type: 'text',
|
||||
placeholder: 'admin@example.com',
|
||||
default: 'admin@localhost',
|
||||
},
|
||||
{
|
||||
key: 'documentRoot',
|
||||
label: '网站根目录',
|
||||
type: 'text',
|
||||
default: '/var/www/html',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'MPM 模块',
|
||||
fields: [
|
||||
{
|
||||
key: 'mpmModule',
|
||||
label: 'MPM 模型',
|
||||
type: 'select',
|
||||
options: [
|
||||
{ label: 'event - 高并发首选 (推荐)', value: 'event' },
|
||||
{ label: 'worker - 线程池模型', value: 'worker' },
|
||||
{ label: 'prefork - 进程模型 (兼容性最好)', value: 'prefork' },
|
||||
],
|
||||
default: 'event',
|
||||
tip: 'event 适合高并发,prefork 兼容 mod_php',
|
||||
},
|
||||
{
|
||||
key: 'startServers',
|
||||
label: '启动进程数',
|
||||
type: 'number',
|
||||
min: 1,
|
||||
max: 64,
|
||||
default: 4,
|
||||
},
|
||||
{
|
||||
key: 'minSpareThreads',
|
||||
label: '最小空闲线程',
|
||||
type: 'number',
|
||||
min: 1,
|
||||
max: 256,
|
||||
default: 25,
|
||||
dependsOn: { key: 'mpmModule', valueNotIn: ['prefork'] },
|
||||
},
|
||||
{
|
||||
key: 'maxSpareThreads',
|
||||
label: '最大空闲线程',
|
||||
type: 'number',
|
||||
min: 1,
|
||||
max: 1024,
|
||||
default: 75,
|
||||
dependsOn: { key: 'mpmModule', valueNotIn: ['prefork'] },
|
||||
},
|
||||
{
|
||||
key: 'maxRequestWorkers',
|
||||
label: '最大并发数',
|
||||
type: 'number',
|
||||
min: 1,
|
||||
max: 10000,
|
||||
default: 256,
|
||||
},
|
||||
{
|
||||
key: 'threadsPerChild',
|
||||
label: '每进程线程数',
|
||||
type: 'number',
|
||||
min: 1,
|
||||
max: 128,
|
||||
default: 25,
|
||||
dependsOn: { key: 'mpmModule', valueNotIn: ['prefork'] },
|
||||
},
|
||||
{
|
||||
key: 'minSpareServers',
|
||||
label: '最小空闲进程',
|
||||
type: 'number',
|
||||
min: 1,
|
||||
max: 64,
|
||||
default: 5,
|
||||
dependsOn: { key: 'mpmModule', value: 'prefork' },
|
||||
},
|
||||
{
|
||||
key: 'maxSpareServers',
|
||||
label: '最大空闲进程',
|
||||
type: 'number',
|
||||
min: 1,
|
||||
max: 256,
|
||||
default: 10,
|
||||
dependsOn: { key: 'mpmModule', value: 'prefork' },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'HTTPS / SSL',
|
||||
fields: [
|
||||
{
|
||||
key: 'enableSsl',
|
||||
label: '开启 HTTPS',
|
||||
type: 'switch',
|
||||
default: false,
|
||||
},
|
||||
{
|
||||
key: 'sslPort',
|
||||
label: 'HTTPS 端口',
|
||||
type: 'number',
|
||||
min: 1,
|
||||
max: 65535,
|
||||
default: 443,
|
||||
dependsOn: { key: 'enableSsl', value: true },
|
||||
},
|
||||
{
|
||||
key: 'sslCertificate',
|
||||
label: 'SSL 证书路径',
|
||||
type: 'text',
|
||||
default: '/etc/pki/tls/certs/localhost.crt',
|
||||
dependsOn: { key: 'enableSsl', value: true },
|
||||
},
|
||||
{
|
||||
key: 'sslCertificateKey',
|
||||
label: 'SSL 私钥路径',
|
||||
type: 'text',
|
||||
default: '/etc/pki/tls/private/localhost.key',
|
||||
dependsOn: { key: 'enableSsl', value: true },
|
||||
},
|
||||
{
|
||||
key: 'sslProtocols',
|
||||
label: 'TLS 版本',
|
||||
type: 'select',
|
||||
options: [
|
||||
{ label: 'TLSv1.2 + TLSv1.3 (推荐)', value: 'all -SSLv3 -TLSv1 -TLSv1.1' },
|
||||
{ label: 'TLSv1.1 + TLSv1.2 + TLSv1.3', value: 'all -SSLv3 -TLSv1' },
|
||||
{ label: '仅 TLSv1.3', value: 'TLSv1.3' },
|
||||
],
|
||||
default: 'all -SSLv3 -TLSv1 -TLSv1.1',
|
||||
dependsOn: { key: 'enableSsl', value: true },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: '模块管理',
|
||||
fields: [
|
||||
{
|
||||
key: 'enableModRewrite',
|
||||
label: '加载 mod_rewrite',
|
||||
type: 'switch',
|
||||
default: true,
|
||||
tip: 'URL 重写模块',
|
||||
},
|
||||
{
|
||||
key: 'enableModProxy',
|
||||
label: '加载 mod_proxy',
|
||||
type: 'switch',
|
||||
default: false,
|
||||
tip: '反向代理模块',
|
||||
},
|
||||
{
|
||||
key: 'enableModDeflate',
|
||||
label: '加载 mod_deflate',
|
||||
type: 'switch',
|
||||
default: true,
|
||||
tip: '压缩传输模块',
|
||||
},
|
||||
{
|
||||
key: 'enableModExpires',
|
||||
label: '加载 mod_expires',
|
||||
type: 'switch',
|
||||
default: true,
|
||||
tip: '浏览器缓存控制',
|
||||
},
|
||||
{
|
||||
key: 'enableModSecurity',
|
||||
label: '加载 mod_security',
|
||||
type: 'switch',
|
||||
default: false,
|
||||
tip: 'Web 应用防火墙',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: '反向代理',
|
||||
fields: [
|
||||
{
|
||||
key: 'enableProxy',
|
||||
label: '开启反向代理',
|
||||
type: 'switch',
|
||||
default: false,
|
||||
},
|
||||
{
|
||||
key: 'proxyTarget',
|
||||
label: '后端地址',
|
||||
type: 'text',
|
||||
placeholder: 'http://127.0.0.1:8080',
|
||||
default: 'http://127.0.0.1:8080',
|
||||
dependsOn: { key: 'enableProxy', value: true },
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
key: 'proxyPath',
|
||||
label: '代理路径前缀',
|
||||
type: 'text',
|
||||
default: '/',
|
||||
dependsOn: { key: 'enableProxy', value: true },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: '日志与性能',
|
||||
fields: [
|
||||
{
|
||||
key: 'logLevel',
|
||||
label: '日志级别',
|
||||
type: 'select',
|
||||
options: [
|
||||
{ label: 'warn (推荐生产)', value: 'warn' },
|
||||
{ label: 'error', value: 'error' },
|
||||
{ label: 'info', value: 'info' },
|
||||
{ label: 'debug', value: 'debug' },
|
||||
],
|
||||
default: 'warn',
|
||||
},
|
||||
{
|
||||
key: 'enableGzip',
|
||||
label: '开启 Gzip 压缩',
|
||||
type: 'switch',
|
||||
default: true,
|
||||
},
|
||||
{
|
||||
key: 'keepAlive',
|
||||
label: '开启 Keep-Alive',
|
||||
type: 'switch',
|
||||
default: true,
|
||||
},
|
||||
{
|
||||
key: 'maxKeepAliveRequests',
|
||||
label: 'Keep-Alive 最大请求数',
|
||||
type: 'number',
|
||||
min: 0,
|
||||
max: 10000,
|
||||
default: 100,
|
||||
dependsOn: { key: 'keepAlive', value: true },
|
||||
},
|
||||
{
|
||||
key: 'keepAliveTimeout',
|
||||
label: 'Keep-Alive 超时 (秒)',
|
||||
type: 'number',
|
||||
min: 1,
|
||||
max: 300,
|
||||
default: 5,
|
||||
dependsOn: { key: 'keepAlive', value: true },
|
||||
},
|
||||
{
|
||||
key: 'timeout',
|
||||
label: '请求超时 (秒)',
|
||||
type: 'number',
|
||||
min: 10,
|
||||
max: 600,
|
||||
default: 60,
|
||||
},
|
||||
{
|
||||
key: 'serverTokens',
|
||||
label: '隐藏版本信息',
|
||||
type: 'switch',
|
||||
default: true,
|
||||
tip: '不在响应头暴露 Apache 版本',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
export function generateApacheConf(config) {
|
||||
const lines = []
|
||||
lines.push(`# Apache HTTP Server 配置文件 - 由 ConfTemplate 生成`)
|
||||
lines.push(`# 生成时间: ${new Date().toLocaleString('zh-CN')}`)
|
||||
lines.push(``)
|
||||
lines.push(`ServerRoot "${config.serverRoot}"`)
|
||||
lines.push(`Listen ${config.listen}`)
|
||||
lines.push(`ServerName ${config.serverName}`)
|
||||
lines.push(`ServerAdmin ${config.serverAdmin}`)
|
||||
lines.push(`DocumentRoot "${config.documentRoot}"`)
|
||||
lines.push(``)
|
||||
|
||||
if (config.serverTokens) {
|
||||
lines.push(`# 隐藏版本信息`)
|
||||
lines.push(`ServerTokens Prod`)
|
||||
lines.push(`ServerSignature Off`)
|
||||
lines.push(``)
|
||||
}
|
||||
|
||||
// MPM
|
||||
lines.push(`# ======================== MPM 模块 ========================`)
|
||||
lines.push(`<IfModule mpm_${config.mpmModule}_module>`)
|
||||
|
||||
if (config.mpmModule === 'prefork') {
|
||||
lines.push(` StartServers ${config.startServers}`)
|
||||
lines.push(` MinSpareServers ${config.minSpareServers}`)
|
||||
lines.push(` MaxSpareServers ${config.maxSpareServers}`)
|
||||
lines.push(` MaxRequestWorkers ${config.maxRequestWorkers}`)
|
||||
lines.push(` MaxConnectionsPerChild 0`)
|
||||
} else {
|
||||
lines.push(` StartServers ${config.startServers}`)
|
||||
lines.push(` MinSpareThreads ${config.minSpareThreads}`)
|
||||
lines.push(` MaxSpareThreads ${config.maxSpareThreads}`)
|
||||
lines.push(` ThreadsPerChild ${config.threadsPerChild}`)
|
||||
lines.push(` MaxRequestWorkers ${config.maxRequestWorkers}`)
|
||||
lines.push(` MaxConnectionsPerChild 0`)
|
||||
}
|
||||
|
||||
lines.push(`</IfModule>`)
|
||||
lines.push(``)
|
||||
|
||||
// 模块
|
||||
lines.push(`# ======================== 模块加载 ========================`)
|
||||
if (config.enableModRewrite) lines.push(`LoadModule rewrite_module modules/mod_rewrite.so`)
|
||||
if (config.enableModProxy) {
|
||||
lines.push(`LoadModule proxy_module modules/mod_proxy.so`)
|
||||
lines.push(`LoadModule proxy_http_module modules/mod_proxy_http.so`)
|
||||
}
|
||||
if (config.enableModDeflate) lines.push(`LoadModule deflate_module modules/mod_deflate.so`)
|
||||
if (config.enableModExpires) lines.push(`LoadModule expires_module modules/mod_expires.so`)
|
||||
if (config.enableModSecurity) lines.push(`LoadModule security2_module modules/mod_security2.so`)
|
||||
lines.push(`LoadModule dir_module modules/mod_dir.so`)
|
||||
lines.push(`LoadModule mime_module modules/mod_mime.so`)
|
||||
lines.push(`LoadModule log_config_module modules/mod_log_config.so`)
|
||||
lines.push(`LoadModule headers_module modules/mod_headers.so`)
|
||||
lines.push(``)
|
||||
|
||||
// HTTPS
|
||||
if (config.enableSsl) {
|
||||
lines.push(`# ======================== HTTPS / SSL ========================`)
|
||||
lines.push(`LoadModule ssl_module modules/mod_ssl.so`)
|
||||
lines.push(``)
|
||||
lines.push(`<IfModule ssl_module>`)
|
||||
lines.push(` SSLProtocol ${config.sslProtocols}`)
|
||||
lines.push(` SSLCipherSuite HIGH:!aNULL:!MD5`)
|
||||
lines.push(` SSLHonorCipherOrder on`)
|
||||
lines.push(`</IfModule>`)
|
||||
lines.push(``)
|
||||
lines.push(`<VirtualHost *:${config.sslPort}>`)
|
||||
lines.push(` ServerName ${config.serverName}`)
|
||||
lines.push(` SSLEngine on`)
|
||||
lines.push(` SSLCertificateFile "${config.sslCertificate}"`)
|
||||
lines.push(` SSLCertificateKeyFile "${config.sslCertificateKey}"`)
|
||||
lines.push(` DocumentRoot "${config.documentRoot}"`)
|
||||
lines.push(`</VirtualHost>`)
|
||||
lines.push(``)
|
||||
}
|
||||
|
||||
// Gzip
|
||||
if (config.enableGzip) {
|
||||
lines.push(`# ======================== Gzip 压缩 ========================`)
|
||||
lines.push(`<IfModule deflate_module>`)
|
||||
lines.push(` AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css`)
|
||||
lines.push(` AddOutputFilterByType DEFLATE application/javascript application/json application/xml`)
|
||||
lines.push(` DeflateCompressionLevel 6`)
|
||||
lines.push(`</IfModule>`)
|
||||
lines.push(``)
|
||||
}
|
||||
|
||||
// 反向代理
|
||||
if (config.enableProxy) {
|
||||
lines.push(`# ======================== 反向代理 ========================`)
|
||||
lines.push(`<IfModule proxy_module>`)
|
||||
lines.push(` ProxyPreserveHost On`)
|
||||
lines.push(` ProxyPass ${config.proxyPath} ${config.proxyTarget}/`)
|
||||
lines.push(` ProxyPassReverse ${config.proxyPath} ${config.proxyTarget}/`)
|
||||
lines.push(`</IfModule>`)
|
||||
lines.push(``)
|
||||
}
|
||||
|
||||
// 日志
|
||||
lines.push(`# ======================== 日志配置 ========================`)
|
||||
lines.push(`LogLevel ${config.logLevel}`)
|
||||
lines.push(`ErrorLog "logs/error_log"`)
|
||||
lines.push(`CustomLog "logs/access_log" combined`)
|
||||
lines.push(``)
|
||||
|
||||
// Keep-Alive
|
||||
lines.push(`# ======================== Keep-Alive ========================`)
|
||||
lines.push(`KeepAlive ${config.keepAlive ? 'On' : 'Off'}`)
|
||||
if (config.keepAlive) {
|
||||
lines.push(`MaxKeepAliveRequests ${config.maxKeepAliveRequests}`)
|
||||
lines.push(`KeepAliveTimeout ${config.keepAliveTimeout}`)
|
||||
}
|
||||
lines.push(`Timeout ${config.timeout}`)
|
||||
lines.push(``)
|
||||
|
||||
// 目录权限
|
||||
lines.push(`# ======================== 目录权限 ========================`)
|
||||
lines.push(`<Directory "${config.documentRoot}">`)
|
||||
lines.push(` Options FollowSymLinks`)
|
||||
lines.push(` AllowOverride All`)
|
||||
lines.push(` Require all granted`)
|
||||
lines.push(`</Directory>`)
|
||||
|
||||
return lines.join('\n')
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
// ============ 代理与Web ============
|
||||
import { nginxSchema, generateNginxConf } from './nginx'
|
||||
import { apacheSchema, generateApacheConf } from './apache'
|
||||
import { tomcatSchema, generateTomcatServerXml } from './tomcat'
|
||||
|
||||
// ============ 缓存 ============
|
||||
import { redisSchema, generateRedisConf } from './redis'
|
||||
@@ -79,6 +81,8 @@ import { ansiblePlaybookSchema, generateAnsiblePlaybookYaml } from './ansible-pl
|
||||
export const schemas = {
|
||||
// 代理与Web
|
||||
nginx: nginxSchema,
|
||||
apache: apacheSchema,
|
||||
tomcat: tomcatSchema,
|
||||
// 缓存
|
||||
redis: redisSchema,
|
||||
// 数据库
|
||||
@@ -143,6 +147,8 @@ export const schemas = {
|
||||
|
||||
export const generators = {
|
||||
nginx: generateNginxConf,
|
||||
apache: generateApacheConf,
|
||||
tomcat: generateTomcatServerXml,
|
||||
redis: generateRedisConf,
|
||||
mysql: generateMysqlConf,
|
||||
mongodb: generateMongodbConf,
|
||||
@@ -194,7 +200,7 @@ export const categories = [
|
||||
{
|
||||
name: '代理与Web',
|
||||
icon: 'Monitor',
|
||||
items: ['nginx'],
|
||||
items: ['nginx', 'apache', 'tomcat'],
|
||||
},
|
||||
{
|
||||
name: '缓存',
|
||||
@@ -299,6 +305,7 @@ export function getLanguage(format) {
|
||||
toml: 'toml',
|
||||
properties: 'properties',
|
||||
ini: 'ini',
|
||||
xml: 'xml',
|
||||
}
|
||||
return map[format] || 'plaintext'
|
||||
}
|
||||
|
||||
@@ -0,0 +1,417 @@
|
||||
export const tomcatSchema = {
|
||||
id: 'tomcat',
|
||||
name: 'Tomcat',
|
||||
icon: 'Monitor',
|
||||
category: '代理与Web',
|
||||
description: 'Apache Tomcat Java 应用服务器',
|
||||
format: 'xml',
|
||||
fileName: 'server.xml',
|
||||
groups: [
|
||||
{
|
||||
title: '基础配置',
|
||||
fields: [
|
||||
{
|
||||
key: 'port',
|
||||
label: 'Server 关闭端口',
|
||||
type: 'number',
|
||||
min: 1,
|
||||
max: 65535,
|
||||
default: 8005,
|
||||
tip: '用于接收关闭命令的端口',
|
||||
},
|
||||
{
|
||||
key: 'shutdown',
|
||||
label: '关闭命令',
|
||||
type: 'text',
|
||||
default: 'SHUTDOWN',
|
||||
},
|
||||
{
|
||||
key: 'httpPort',
|
||||
label: 'HTTP 连接端口',
|
||||
type: 'number',
|
||||
min: 1,
|
||||
max: 65535,
|
||||
default: 8080,
|
||||
},
|
||||
{
|
||||
key: 'ajpPort',
|
||||
label: 'AJP 连接端口',
|
||||
type: 'number',
|
||||
min: 1,
|
||||
max: 65535,
|
||||
default: 8009,
|
||||
tip: 'Apache 通过 AJP 协议连接 Tomcat',
|
||||
},
|
||||
{
|
||||
key: 'enableAjp',
|
||||
label: '启用 AJP 连接器',
|
||||
type: 'switch',
|
||||
default: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: '连接器配置',
|
||||
fields: [
|
||||
{
|
||||
key: 'maxThreads',
|
||||
label: '最大线程数',
|
||||
type: 'number',
|
||||
min: 10,
|
||||
max: 4096,
|
||||
default: 200,
|
||||
tip: '处理请求的最大线程数',
|
||||
},
|
||||
{
|
||||
key: 'minSpareThreads',
|
||||
label: '最小空闲线程',
|
||||
type: 'number',
|
||||
min: 1,
|
||||
max: 200,
|
||||
default: 10,
|
||||
},
|
||||
{
|
||||
key: 'connectionTimeout',
|
||||
label: '连接超时 (毫秒)',
|
||||
type: 'number',
|
||||
min: 0,
|
||||
max: 120000,
|
||||
default: 20000,
|
||||
},
|
||||
{
|
||||
key: 'maxConnections',
|
||||
label: '最大连接数',
|
||||
type: 'number',
|
||||
min: 1,
|
||||
max: 100000,
|
||||
default: 10000,
|
||||
},
|
||||
{
|
||||
key: 'enableCompression',
|
||||
label: '开启压缩',
|
||||
type: 'switch',
|
||||
default: false,
|
||||
},
|
||||
{
|
||||
key: 'compressionMinSize',
|
||||
label: '压缩最小体积 (字节)',
|
||||
type: 'number',
|
||||
min: 0,
|
||||
max: 10240,
|
||||
default: 2048,
|
||||
dependsOn: { key: 'enableCompression', value: true },
|
||||
},
|
||||
{
|
||||
key: 'compressibleMimeType',
|
||||
label: '压缩 MIME 类型',
|
||||
type: 'text',
|
||||
default: 'text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json',
|
||||
dependsOn: { key: 'enableCompression', value: true },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'HTTPS / SSL',
|
||||
fields: [
|
||||
{
|
||||
key: 'enableSsl',
|
||||
label: '开启 HTTPS',
|
||||
type: 'switch',
|
||||
default: false,
|
||||
},
|
||||
{
|
||||
key: 'httpsPort',
|
||||
label: 'HTTPS 端口',
|
||||
type: 'number',
|
||||
min: 1,
|
||||
max: 65535,
|
||||
default: 8443,
|
||||
dependsOn: { key: 'enableSsl', value: true },
|
||||
},
|
||||
{
|
||||
key: 'keystoreFile',
|
||||
label: 'Keystore 文件路径',
|
||||
type: 'text',
|
||||
placeholder: '/etc/tomcat/keystore.jks',
|
||||
default: '/etc/tomcat/keystore.jks',
|
||||
dependsOn: { key: 'enableSsl', value: true },
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
key: 'keystorePass',
|
||||
label: 'Keystore 密码',
|
||||
type: 'text',
|
||||
placeholder: 'changeit',
|
||||
default: 'changeit',
|
||||
dependsOn: { key: 'enableSsl', value: true },
|
||||
},
|
||||
{
|
||||
key: 'sslProtocol',
|
||||
label: 'SSL 协议',
|
||||
type: 'select',
|
||||
options: [
|
||||
{ label: 'TLS (推荐)', value: 'TLS' },
|
||||
{ label: 'TLSv1.2', value: 'TLSv1.2' },
|
||||
{ label: 'TLSv1.2 + TLSv1.3', value: 'TLSv1.2,TLSv1.3' },
|
||||
],
|
||||
default: 'TLS',
|
||||
dependsOn: { key: 'enableSsl', value: true },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Engine 与 Host',
|
||||
fields: [
|
||||
{
|
||||
key: 'defaultHost',
|
||||
label: '默认主机名',
|
||||
type: 'text',
|
||||
default: 'localhost',
|
||||
},
|
||||
{
|
||||
key: 'appBase',
|
||||
label: '应用部署目录',
|
||||
type: 'text',
|
||||
default: 'webapps',
|
||||
tip: '相对于 CATALINA_BASE',
|
||||
},
|
||||
{
|
||||
key: 'unpackWARs',
|
||||
label: '自动解压 WAR',
|
||||
type: 'switch',
|
||||
default: true,
|
||||
},
|
||||
{
|
||||
key: 'autoDeploy',
|
||||
label: '自动部署',
|
||||
type: 'switch',
|
||||
default: true,
|
||||
tip: '检测到新 WAR 自动部署',
|
||||
},
|
||||
{
|
||||
key: 'deployOnStartup',
|
||||
label: '启动时自动部署',
|
||||
type: 'switch',
|
||||
default: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'JVM 内存',
|
||||
fields: [
|
||||
{
|
||||
key: 'enableJvmArgs',
|
||||
label: '自定义 JVM 参数',
|
||||
type: 'switch',
|
||||
default: false,
|
||||
tip: '设置 JAVA_OPTS 环境变量',
|
||||
},
|
||||
{
|
||||
key: 'xms',
|
||||
label: '初始堆内存 (-Xms)',
|
||||
type: 'select',
|
||||
options: [
|
||||
{ label: '256m', value: '256m' },
|
||||
{ label: '512m', value: '512m' },
|
||||
{ label: '1g', value: '1g' },
|
||||
{ label: '2g', value: '2g' },
|
||||
{ label: '4g', value: '4g' },
|
||||
],
|
||||
default: '512m',
|
||||
dependsOn: { key: 'enableJvmArgs', value: true },
|
||||
},
|
||||
{
|
||||
key: 'xmx',
|
||||
label: '最大堆内存 (-Xmx)',
|
||||
type: 'select',
|
||||
options: [
|
||||
{ label: '512m', value: '512m' },
|
||||
{ label: '1g', value: '1g' },
|
||||
{ label: '2g', value: '2g' },
|
||||
{ label: '4g', value: '4g' },
|
||||
{ label: '8g', value: '8g' },
|
||||
],
|
||||
default: '1g',
|
||||
dependsOn: { key: 'enableJvmArgs', value: true },
|
||||
},
|
||||
{
|
||||
key: 'metaspaceSize',
|
||||
label: 'Metaspace 大小',
|
||||
type: 'select',
|
||||
options: [
|
||||
{ label: '128m', value: '128m' },
|
||||
{ label: '256m', value: '256m' },
|
||||
{ label: '512m', value: '512m' },
|
||||
],
|
||||
default: '256m',
|
||||
dependsOn: { key: 'enableJvmArgs', value: true },
|
||||
},
|
||||
{
|
||||
key: 'gcType',
|
||||
label: 'GC 算法',
|
||||
type: 'select',
|
||||
options: [
|
||||
{ label: 'G1GC (推荐 JDK9+)', value: '-XX:+UseG1GC' },
|
||||
{ label: 'ZGC (推荐 JDK15+)', value: '-XX:+UseZGC' },
|
||||
{ label: 'ParallelGC', value: '-XX:+UseParallelGC' },
|
||||
{ label: 'CMS (JDK8)', value: '-XX:+UseConcMarkSweepGC' },
|
||||
],
|
||||
default: '-XX:+UseG1GC',
|
||||
dependsOn: { key: 'enableJvmArgs', value: true },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: '日志与安全',
|
||||
fields: [
|
||||
{
|
||||
key: 'accessLogEnabled',
|
||||
label: '开启访问日志',
|
||||
type: 'switch',
|
||||
default: true,
|
||||
},
|
||||
{
|
||||
key: 'accessLogPattern',
|
||||
label: '日志格式',
|
||||
type: 'select',
|
||||
options: [
|
||||
{ label: 'common - 通用日志格式', value: 'common' },
|
||||
{ label: 'combined - 组合日志格式 (推荐)', value: 'combined' },
|
||||
{ label: '详细格式 (含响应时间)', value: '%h %l %u %t "%r" %s %b %D "%{Referer}i" "%{User-Agent}i"' },
|
||||
],
|
||||
default: 'combined',
|
||||
dependsOn: { key: 'accessLogEnabled', value: true },
|
||||
},
|
||||
{
|
||||
key: 'enableManager',
|
||||
label: '启用 Manager 应用',
|
||||
type: 'switch',
|
||||
default: false,
|
||||
tip: '生产环境建议通过 CI/CD 部署,禁用 Manager',
|
||||
},
|
||||
{
|
||||
key: 'enableHostManager',
|
||||
label: '启用 Host Manager',
|
||||
type: 'switch',
|
||||
default: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
export function generateTomcatServerXml(config) {
|
||||
const lines = []
|
||||
lines.push(`<?xml version="1.0" encoding="UTF-8"?>`)
|
||||
lines.push(`<!-- Tomcat Server 配置文件 - 由 ConfTemplate 生成 -->`)
|
||||
lines.push(`<!-- 生成时间: ${new Date().toLocaleString('zh-CN')} -->`)
|
||||
lines.push(`<Server port="${config.port}" shutdown="${config.shutdown}">`)
|
||||
lines.push(``)
|
||||
lines.push(` <Listener className="org.apache.catalina.startup.VersionLoggerListener" />`)
|
||||
lines.push(` <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />`)
|
||||
lines.push(` <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />`)
|
||||
lines.push(` <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />`)
|
||||
lines.push(` <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />`)
|
||||
lines.push(``)
|
||||
lines.push(` <GlobalNamingResources>`)
|
||||
lines.push(` <Resource name="UserDatabase" auth="Container"`)
|
||||
lines.push(` type="org.apache.catalina.UserDatabase"`)
|
||||
lines.push(` description="User database"`)
|
||||
lines.push(` factory="org.apache.catalina.users.MemoryUserDatabaseFactory"`)
|
||||
lines.push(` pathname="conf/tomcat-users.xml" />`)
|
||||
lines.push(` </GlobalNamingResources>`)
|
||||
lines.push(``)
|
||||
lines.push(` <Service name="Catalina">`)
|
||||
lines.push(``)
|
||||
|
||||
// HTTP Connector
|
||||
lines.push(` <!-- HTTP 连接器 -->`)
|
||||
lines.push(` <Connector port="${config.httpPort}"`)
|
||||
lines.push(` protocol="HTTP/1.1"`)
|
||||
lines.push(` connectionTimeout="${config.connectionTimeout}"`)
|
||||
lines.push(` maxThreads="${config.maxThreads}"`)
|
||||
lines.push(` minSpareThreads="${config.minSpareThreads}"`)
|
||||
lines.push(` maxConnections="${config.maxConnections}"`)
|
||||
lines.push(` redirectPort="${config.enableSsl ? config.httpsPort : 8443}"`)
|
||||
lines.push(` URIEncoding="UTF-8"`)
|
||||
|
||||
if (config.enableCompression) {
|
||||
lines.push(` compression="on"`)
|
||||
lines.push(` compressionMinSize="${config.compressionMinSize}"`)
|
||||
lines.push(` compressibleMimeType="${config.compressibleMimeType}"`)
|
||||
}
|
||||
|
||||
lines.push(` />`)
|
||||
lines.push(``)
|
||||
|
||||
// AJP Connector
|
||||
if (config.enableAjp) {
|
||||
lines.push(` <!-- AJP 连接器 -->`)
|
||||
lines.push(` <Connector port="${config.ajpPort}"`)
|
||||
lines.push(` protocol="AJP/1.3"`)
|
||||
lines.push(` redirectPort="${config.enableSsl ? config.httpsPort : 8443}"`)
|
||||
lines.push(` secretRequired="false"`)
|
||||
lines.push(` />`)
|
||||
lines.push(``)
|
||||
}
|
||||
|
||||
// HTTPS Connector
|
||||
if (config.enableSsl) {
|
||||
lines.push(` <!-- HTTPS 连接器 -->`)
|
||||
lines.push(` <Connector port="${config.httpsPort}"`)
|
||||
lines.push(` protocol="org.apache.coyote.http11.Http11NioProtocol"`)
|
||||
lines.push(` maxThreads="${config.maxThreads}"`)
|
||||
lines.push(` SSLEnabled="true"`)
|
||||
lines.push(` scheme="https"`)
|
||||
lines.push(` secure="true">`)
|
||||
lines.push(` <SSLHostConfig>`)
|
||||
lines.push(` <Certificate certificateKeystoreFile="${config.keystoreFile}"`)
|
||||
lines.push(` certificateKeystorePassword="${config.keystorePass}"`)
|
||||
lines.push(` type="RSA" />`)
|
||||
lines.push(` </SSLHostConfig>`)
|
||||
lines.push(` </Connector>`)
|
||||
lines.push(``)
|
||||
}
|
||||
|
||||
lines.push(` <Engine name="Catalina" defaultHost="${config.defaultHost}">`)
|
||||
lines.push(``)
|
||||
lines.push(` <Realm className="org.apache.catalina.realm.LockOutRealm">`)
|
||||
lines.push(` <Realm className="org.apache.catalina.realm.UserDatabaseRealm"`)
|
||||
lines.push(` resourceName="UserDatabase"/>`)
|
||||
lines.push(` </Realm>`)
|
||||
lines.push(``)
|
||||
lines.push(` <Host name="${config.defaultHost}"`)
|
||||
lines.push(` appBase="${config.appBase}"`)
|
||||
lines.push(` unpackWARs="${config.unpackWARs}"`)
|
||||
lines.push(` autoDeploy="${config.autoDeploy}"`)
|
||||
lines.push(` deployOnStartup="${config.deployOnStartup}">`)
|
||||
lines.push(``)
|
||||
|
||||
if (config.accessLogEnabled) {
|
||||
lines.push(` <Valve className="org.apache.catalina.valves.AccessLogValve"`)
|
||||
lines.push(` directory="logs"`)
|
||||
lines.push(` prefix="localhost_access_log"`)
|
||||
lines.push(` suffix=".txt"`)
|
||||
lines.push(` pattern="${config.accessLogPattern}" />`)
|
||||
}
|
||||
|
||||
lines.push(` </Host>`)
|
||||
lines.push(` </Engine>`)
|
||||
lines.push(` </Service>`)
|
||||
lines.push(`</Server>`)
|
||||
|
||||
// JVM args as comment
|
||||
if (config.enableJvmArgs) {
|
||||
lines.push(``)
|
||||
lines.push(`<!-- ======================== JVM 参数 (设置为 JAVA_OPTS 环境变量) ======================== -->`)
|
||||
lines.push(`<!--`)
|
||||
lines.push(`JAVA_OPTS="-Xms${config.xms} -Xmx${config.xmx} \\`)
|
||||
lines.push(` -XX:MetaspaceSize=${config.metaspaceSize} -XX:MaxMetaspaceSize=${config.metaspaceSize} \\`)
|
||||
lines.push(` ${config.gcType} \\`)
|
||||
lines.push(` -Djava.awt.headless=true \\`)
|
||||
lines.push(` -Dfile.encoding=UTF-8"`)
|
||||
lines.push(`-->`)
|
||||
}
|
||||
|
||||
return lines.join('\n')
|
||||
}
|
||||
Reference in New Issue
Block a user