From c844f4c7844053ce5904a3cf6d748ea54ef00186 Mon Sep 17 00:00:00 2001 From: ryan Date: Wed, 18 Mar 2026 22:15:40 +0800 Subject: [PATCH] =?UTF-8?q?[=E4=BC=98=E5=8C=96]=20=E6=9B=B4=E6=96=B0HTTPS?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=EF=BC=8C=E5=90=AF=E7=94=A8reuseport=E5=92=8C?= =?UTF-8?q?epoll=E4=BA=8B=E4=BB=B6=E6=A8=A1=E5=9E=8B=EF=BC=8C=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E6=80=A7=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/app-config.md | 1 + openflare_server/common/constants.go | 4 ++-- openflare_server/router/api_phase1_test.go | 4 ++-- openflare_server/service/config_version.go | 2 +- openflare_server/service/https_phase1_test.go | 10 ++++++++-- .../performance/components/performance-page.tsx | 12 ++++++------ .../features/settings/components/settings-page.tsx | 8 ++++---- 7 files changed, 24 insertions(+), 17 deletions(-) diff --git a/docs/app-config.md b/docs/app-config.md index 24e79a6e..f51d2b31 100644 --- a/docs/app-config.md +++ b/docs/app-config.md @@ -85,6 +85,7 @@ OpenResty 性能参数与缓存参数继续统一保存在 `Option` 表。当前 * `OpenRestyResolvers` 由管理端性能页面维护,支持填写多个 DNS 服务器 IP;留空时不额外生成 `resolver` 指令。 * `OpenRestyCacheEnabled` 用于启用缓存基础设施与全局默认参数;实际是否缓存、按 URL / 后缀 / 路径等命中策略由各条 `proxy_routes` 单独决定,不再默认对所有规则开启缓存。 +* 默认事件模型为 `epoll`,并默认开启 `multi_accept`;HTTPS 监听默认附带 `reuseport`,以改善多 worker 下的连接分发。 ### 1.5 前端构建环境变量 | 环境变量 | 作用 | 默认值 | diff --git a/openflare_server/common/constants.go b/openflare_server/common/constants.go index 2228637c..34045ea2 100644 --- a/openflare_server/common/constants.go +++ b/openflare_server/common/constants.go @@ -60,8 +60,8 @@ var GeoIPProvider = "ipinfo" var OpenRestyWorkerProcesses = "auto" var OpenRestyWorkerConnections = 4096 var OpenRestyWorkerRlimitNofile = 65535 -var OpenRestyEventsUse = "" -var OpenRestyEventsMultiAcceptEnabled = false +var OpenRestyEventsUse = "epoll" +var OpenRestyEventsMultiAcceptEnabled = true var OpenRestyKeepaliveTimeout = 65 var OpenRestyKeepaliveRequests = 1000 var OpenRestyClientHeaderTimeout = 15 diff --git a/openflare_server/router/api_phase1_test.go b/openflare_server/router/api_phase1_test.go index 4288a9fa..9de7a5ac 100644 --- a/openflare_server/router/api_phase1_test.go +++ b/openflare_server/router/api_phase1_test.go @@ -341,8 +341,8 @@ func TestPhase1HTTPSAndCertificateImportLifecycle(t *testing.T) { if !strings.Contains(version.MainConfig, "include __OPENFLARE_ROUTE_CONFIG__;") { t.Fatal("expected active config to render managed main config") } - if !strings.Contains(version.RenderedConfig, "listen 443 ssl http2;") { - t.Fatal("expected active config to render https listener with http2 enabled") + if !strings.Contains(version.RenderedConfig, "listen 443 ssl http2 reuseport;") { + t.Fatal("expected active config to render https listener with http2, reuseport enabled") } if !strings.Contains(version.RenderedConfig, "return 301 https://$host$request_uri;") { t.Fatal("expected active config to render redirect server") diff --git a/openflare_server/service/config_version.go b/openflare_server/service/config_version.go index 9d9433cb..125245dc 100644 --- a/openflare_server/service/config_version.go +++ b/openflare_server/service/config_version.go @@ -829,7 +829,7 @@ func renderHTTPRedirectServer(domain string) string { func renderHTTPSServer(domain string, originURL string, originHost string, certificateID uint, customHeaders []ProxyRouteCustomHeaderInput, cacheConfig routeCacheConfig, upstreamConfig routeUpstreamConfig, cfg openRestyConfigSnapshot) string { certPath := fmt.Sprintf("%s/%s", nginxCertDirPlaceholder, certificateCertFileName(certificateID)) keyPath := fmt.Sprintf("%s/%s", nginxCertDirPlaceholder, certificateKeyFileName(certificateID)) - return fmt.Sprintf("server {\n listen 443 ssl http2;\n server_name %s;\n ssl_certificate %s;\n ssl_certificate_key %s;\n\n location / {\n%s%s%s }\n}\n\n", domain, certPath, keyPath, renderProxyHeaderBlock(originURL, originHost, customHeaders, upstreamConfig), renderRouteCacheBlock(cacheConfig, cfg), renderProxyPassBlock(originURL, upstreamConfig, cfg)) + return fmt.Sprintf("server {\n listen 443 ssl http2 reuseport;\n server_name %s;\n ssl_certificate %s;\n ssl_certificate_key %s;\n\n location / {\n%s%s%s }\n}\n\n", domain, certPath, keyPath, renderProxyHeaderBlock(originURL, originHost, customHeaders, upstreamConfig), renderRouteCacheBlock(cacheConfig, cfg), renderProxyPassBlock(originURL, upstreamConfig, cfg)) } func renderConnectionUpgradeMap() string { diff --git a/openflare_server/service/https_phase1_test.go b/openflare_server/service/https_phase1_test.go index 2e3e246f..241a9446 100644 --- a/openflare_server/service/https_phase1_test.go +++ b/openflare_server/service/https_phase1_test.go @@ -66,11 +66,17 @@ func TestCreateTLSCertificateAndRenderHTTPSConfig(t *testing.T) { if strings.Contains(result.Version.MainConfig, "resolver ") { t.Fatal("expected main config to omit resolver directive when no resolvers are configured") } + if !strings.Contains(result.Version.MainConfig, "use epoll;") { + t.Fatal("expected main config to default to epoll event model") + } + if !strings.Contains(result.Version.MainConfig, "multi_accept on;") { + t.Fatal("expected main config to default multi_accept to on") + } if strings.Contains(result.Version.MainConfig, "allow 127.0.0.1;") { t.Fatal("expected main config to avoid hard-coded allow rules on observability server") } - if !strings.Contains(result.Version.RenderedConfig, "listen 443 ssl http2;") { - t.Fatal("expected rendered config to include https server block with http2 enabled") + if !strings.Contains(result.Version.RenderedConfig, "listen 443 ssl http2 reuseport;") { + t.Fatal("expected rendered config to include https server block with http2 and reuseport enabled") } if strings.Contains(result.Version.RenderedConfig, `if ($host != "app.example.com") {`) { t.Fatal("expected rendered config to avoid per-route host guard") diff --git a/openflare_server/web/features/performance/components/performance-page.tsx b/openflare_server/web/features/performance/components/performance-page.tsx index 81a0baab..5cc59e69 100644 --- a/openflare_server/web/features/performance/components/performance-page.tsx +++ b/openflare_server/web/features/performance/components/performance-page.tsx @@ -34,8 +34,8 @@ const defaultPerformanceFields = { OpenRestyWorkerProcesses: 'auto', OpenRestyWorkerConnections: '4096', OpenRestyWorkerRlimitNofile: '65535', - OpenRestyEventsUse: '', - OpenRestyEventsMultiAcceptEnabled: false, + OpenRestyEventsUse: 'epoll', + OpenRestyEventsMultiAcceptEnabled: true, OpenRestyKeepaliveTimeout: '65', OpenRestyKeepaliveRequests: '1000', OpenRestyClientHeaderTimeout: '15', @@ -76,9 +76,9 @@ const performanceFieldTooltips: Record = { worker_rlimit_nofile: '提升 worker 可打开的文件描述符上限,避免高并发下连接或文件句柄不足。', events_use: - '指定事件驱动模型。Linux 常见是 epoll,留空时由 OpenResty 自动选择。', + '指定事件驱动模型。默认使用 epoll,Linux 高并发场景通常优先选择它。', multi_accept: - '开启后,worker 会尽可能一次接受多个新连接,适合高吞吐接入场景。', + '默认开启。worker 会尽可能一次接受多个新连接,适合高吞吐接入场景。', keepalive_timeout: '客户端 Keep-Alive 空闲保持时间,单位秒。', keepalive_requests: '单个长连接允许复用的最大请求数。', client_header_timeout: '读取客户端请求头的超时时间,单位秒。', @@ -206,10 +206,10 @@ export function PerformancePage() { optionMap.OpenRestyWorkerConnections ?? '4096', OpenRestyWorkerRlimitNofile: optionMap.OpenRestyWorkerRlimitNofile ?? '65535', - OpenRestyEventsUse: optionMap.OpenRestyEventsUse ?? '', + OpenRestyEventsUse: optionMap.OpenRestyEventsUse ?? 'epoll', OpenRestyEventsMultiAcceptEnabled: toBoolean( optionMap.OpenRestyEventsMultiAcceptEnabled, - false, + true, ), OpenRestyKeepaliveTimeout: optionMap.OpenRestyKeepaliveTimeout ?? '65', OpenRestyKeepaliveRequests: diff --git a/openflare_server/web/features/settings/components/settings-page.tsx b/openflare_server/web/features/settings/components/settings-page.tsx index 98b87e91..22f5710c 100644 --- a/openflare_server/web/features/settings/components/settings-page.tsx +++ b/openflare_server/web/features/settings/components/settings-page.tsx @@ -78,8 +78,8 @@ const defaultOperationFields = { OpenRestyWorkerProcesses: 'auto', OpenRestyWorkerConnections: '4096', OpenRestyWorkerRlimitNofile: '65535', - OpenRestyEventsUse: '', - OpenRestyEventsMultiAcceptEnabled: false, + OpenRestyEventsUse: 'epoll', + OpenRestyEventsMultiAcceptEnabled: true, OpenRestyKeepaliveTimeout: '65', OpenRestyKeepaliveRequests: '1000', OpenRestyClientHeaderTimeout: '15', @@ -348,10 +348,10 @@ export function SettingsPage() { optionMap.OpenRestyWorkerConnections ?? '4096', OpenRestyWorkerRlimitNofile: optionMap.OpenRestyWorkerRlimitNofile ?? '65535', - OpenRestyEventsUse: optionMap.OpenRestyEventsUse ?? '', + OpenRestyEventsUse: optionMap.OpenRestyEventsUse ?? 'epoll', OpenRestyEventsMultiAcceptEnabled: toBoolean( optionMap.OpenRestyEventsMultiAcceptEnabled, - false, + true, ), OpenRestyKeepaliveTimeout: optionMap.OpenRestyKeepaliveTimeout ?? '65', OpenRestyKeepaliveRequests: