一本码簿

众里寻码千百度,那段却在github处。

1
wget -qO- https://haies.cn/assets/checkname.js

使用说明

checkname 是一个基于 Node.js 的命令行工具,用于检查和自动修复文件及目录名称,确保它们能够同时在 Windows 11macOSUbuntu 系统中正常使用,便于跨平台文件共享。工具会检查文件名是否包含禁止字符、是否超长、是否存在空格等不可见字符,并按照预定策略进行规范化处理,同时自动处理重名冲突。

安装与运行

  • 环境要求:Node.js 12.0 或更高版本(建议使用 LTS 版本)。
  • 获取脚本:将脚本保存为 checkname.js
  • 运行方式:在终端中执行 node checkname.js [参数] [目录1] [目录2] ...

基本用法

1
node checkname.js [-p] <目录1> [<目录2> ...]
  • -p:处理模式。
    • 若指定此参数,脚本会尝试读取目标目录下最新的日志文件,并根据日志记录对不符合规范的文件/目录进行重命名操作。
    • 如果目录下没有日志文件,则先执行完整检查并生成日志,然后立即根据该日志进行处理。
    • 处理完成后,日志文件会被更新,记录每个条目的处理结果(新路径、状态等)。
  • 不指定 -p:仅检查模式。脚本遍历目录,找出所有不符合规范的文件和目录,并将记录保存到新生成的日志文件中(不会修改任何文件)。

使用示例

示例 1:仅检查目录 /home/user/share

1
node checkname.js /home/user/share

输出:

1
2
3
4
处理目录: /home/user/share
仅检查模式,不会修改文件
检查完成,发现 3 个不符合规范的条目
日志已保存: /home/user/share/checkname_20250302_143022.jsonl

此时目录下会生成日志文件,记录不合规条目的详细信息。你可以查看日志决定是否进行下一步处理。

示例 2:处理目录(基于已有日志)

1
node checkname.js -p /home/user/share

假设目录下已有日志 checkname_20250302_143022.jsonl

1
2
3
4
5
处理目录: /home/user/share
使用现有日志: checkname_20250302_143022.jsonl
开始处理 3 个条目...
处理完成,日志已更新: checkname_20250302_143022.jsonl
统计: 已处理 2, 错误 0, 跳过 1

脚本会读取日志,重命名其中两个文件/目录,并更新日志状态。跳过的条目可能是因为原名称已合规(无需修改)。

示例 3:处理多个目录,且目录无现有日志

1
node checkname.js -p /mnt/data /mnt/docs

输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
处理目录: /mnt/data
未找到现有日志,将先执行检查...
检查完成,发现 5 个不符合规范的条目
已生成日志: checkname_20250302_144512.jsonl
开始处理 5 个条目...
处理完成,日志已更新: checkname_20250302_144512.jsonl
统计: 已处理 5, 错误 0, 跳过 0

处理目录: /mnt/docs
未找到现有日志,将先执行检查...
检查完成,发现 2 个不符合规范的条目
已生成日志: checkname_20250302_144513.jsonl
开始处理 2 个条目...
处理完成,日志已更新: checkname_20250302_144513.jsonl
统计: 已处理 2, 错误 0, 跳过 0

示例 4:查看日志内容

1
cat /home/user/share/checkname_20250302_143022.jsonl

输出示例:

1
2
{"type":"file","originalPath":"/home/user/share/a*b?.txt","newPath":null,"issues":["invalid_char"],"status":"pending","timestamp":"2025-03-02T14:30:22.123Z"}
{"type":"dir","originalPath":"/home/user/share/这是一个非常长的目录名称中文英文混合......","newPath":null,"issues":["too_long"],"status":"pending","timestamp":"2025-03-02T14:30:22.456Z"}

处理后的日志会更新 newPathstatus

相关说明

1. 规范性规则

  • 禁止字符:包含以下任一字符的名称被视为不合规:
    • <>:"/\|?* (Windows 文件系统禁止的字符)
    • ASCII 控制字符(0x00–0x1F)
    • 所有 Unicode 空白字符(包括空格、制表符、换行符等)
  • 长度限制:文件名(包括扩展名)的 UTF-8 编码字节数不得超过 255 字节(这是 Linux 的极限值,也是 Windows 和 macOS 的安全上限)。中文字符通常占 3 字节,需要特别注意。
  • 忽略条目:脚本会自动跳过以下类型的文件和目录(及其内部所有内容):
    • 以点(.)开头的隐藏文件/目录
    • 名称为 node_modulesdistbuildbindebug 的目录(不区分大小写)

2. 处理策略

当发现不合规的名称时,按以下顺序进行修正:

  1. 删除非法字符:移除所有禁止字符。
  2. 长度缩减:如果删除非法字符后仍超长,则对主名(不含扩展名)依次应用以下规则,直到字节数达标:
    • 删除特殊字符(非字母、数字、下划线 _、连字符 -)。
    • 将连续重复 4 次以上的字符缩减为 4 次(例如 "aaaaa""aaaa")。
    • 从主名末尾逐个删除字符。
  3. 重名冲突处理:修正后的名称若与同目录下已有条目重名,则自动添加序号 (1)(2)…… 直至不冲突。添加序号时会确保总长度不超限,必要时会进一步截断主名。

3. 日志文件

  • 命名格式checkname_YYYYMMDD_HHMMSS.jsonl(例如 checkname_20250302_143022.jsonl),保存在被分析的目录下。

  • 格式:JSON Lines,每行一条记录,包含以下字段:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    {
    "type": "file|dir", // 条目类型
    "originalPath": "/绝对/路径/原名称", // 原始完整路径
    "newPath": "/绝对/路径/新名称", // 处理后的路径(仅处理模式有值)
    "issues": ["invalid_char", "too_long"], // 不合规原因
    "status": "pending|processed|error|skipped", // 状态
    "error": "错误信息(如果有)", // 处理失败时的错误信息
    "timestamp": "2025-03-02T14:30:22.123Z" // 记录生成时间
    }
  • 作用:日志既是检查结果的记录,也是处理模式的输入。处理模式只会处理 statuspending 的条目,并更新其状态为 processederrorskipped

4. 处理模式详解

  • 基于现有日志:若目录下已有日志文件,脚本会自动选择最新的一个,读取其中的记录,然后尝试处理所有状态为 pending 的条目。处理完成后,日志文件会被覆盖更新。
  • 无日志时:如果目录下没有日志文件,则先执行完整检查,生成新日志,然后立即根据该日志进行处理。这相当于一次完成“检查+处理”。
  • 重复运行:可以多次运行处理模式,每次只会处理尚未处理的条目(pending 状态)。已处理(processed)、出错(error)或跳过(skipped)的记录不会重复操作。

注意事项

  • 备份重要数据:处理模式会实际修改文件名,建议首次使用时先运行不带 -p 的检查模式,查看日志确认后再执行处理。
  • 权限问题:确保脚本对目标目录有读写权限,否则处理可能失败。
  • 跨平台兼容:修正后的文件名仍可能在某些极端情况下不兼容(例如保留字如 CONPRN 等,Windows 有保留设备名),本工具未处理这些情况,请自行留意。
  • 日志累积:多次运行处理模式会不断更新同一个日志文件,如需保留历史记录,请手动备份旧日志。
  • 并发安全:脚本为串行处理,不会同时修改多个文件,避免冲突。

wget -qO- https://haies.cn/assets/svn_server_tool.sh

使用说明

在服务器端直接查看和统计 SVN 代码仓库信息,无需通过客户端连接。

功能

  • 目录内容查看:查看 SVN 仓库目录结构,仅显示指定目录的第一层内容(非递归)
  • 代码修改历史查询:查看文件或目录的所有修改记录,包括版本号、作者、时间、提交信息
  • 代码提交统计分析:统计提交情况,按作者统计提交次数和百分比,显示提交时间范围

基本用法

1
./svn_server_tool.sh <功能> <仓库路径> [目录/文件路径]
  • 功能参数(第一个参数):ls列出目录、log查看历史、stat统计提交
  • 仓库路径(第二个参数):SVN 仓库物理路径,如/var/svn/repos/myproject
  • 目标路径(第三个参数):ls为可选,logstat为必填(仓库内相对路径)

使用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 查看仓库根目录
./svn_server_tool.sh ls /var/svn/repos/myproject

# 查看指定目录
./svn_server_tool.sh ls /var/svn/repos/myproject /trunk/src

# 查看文件修改历史
./svn_server_tool.sh log /var/svn/repos/myproject /trunk/src/main.java

# 查看目录修改历史
./svn_server_tool.sh log /var/svn/repos/myproject /trunk/src

# 统计文件提交情况
./svn_server_tool.sh stat /var/svn/repos/myproject /trunk/src/main.java

# 统计目录提交情况
./svn_server_tool.sh stat /var/svn/repos/myproject /trunk/src

1
wget -qO- https://haies.cn/assets/tar_batch.sh

使用说明

智能压缩指定目录内文件数量较多的文件夹,自动根据目录深度和文件数量应用不同压缩规则,并排除文档、图片、视频、音频等特定文件类型。

该脚本特别适合处理日志目录、临时文件目录、上传目录等包含大量小文件的场景,能有效减少 inode 使用量,提升文件系统性能。

基本用法

1
./tar_batch.sh [目标目录]
  • 目标目录:可选参数,不指定时默认处理脚本所在目录
  • 处理深度:3-5 级目录,按从浅到深顺序

使用示例

1
2
./tar_batch.sh                 # 压缩当前目录
./tar_batch.sh /path/to/data # 压缩指定目录

相关说明

压缩规则

目录深度 条件 操作
< 4 不含排除文件类型,文件数 50-100 压缩
= 4 不含排除文件类型,文件数 > 50 压缩
> 4 无条件 压缩

排除的文件类型

  • 文档:.txt .pdf .doc .docx .xls .xlsx .ppt .pptx .odt .md .rtf
  • 图片:.jpg .jpeg .png .gif .bmp .tiff .svg .webp
  • 视频:.mp4 .avi .mov .mkv .flv .wmv .m4v .webm
  • 音频:.mp3 .wav .flac .aac .ogg .m4a .wma

输出说明

执行后,符合条件的目录会被压缩,并在同级位置生成:

  • 单卷包目录名.tar.gz
  • 多卷包目录名_archive/ 文件夹(内含分卷文件)

特性说明

  • 终端实时显示当前正在压缩的文件名
  • 在目标目录生成带时间戳的日志文件

1
wget -qO- https://haies.cn/assets/tar_single.sh

使用说明

大容量单目录分卷压缩、解压工具,支持 gzip、zstd(推荐)、xz 三种压缩算法,提供创建、解压、测试三种操作模式。

核心特性

  • 自动检测压缩格式,解压和测试时无需手动指定算法
  • 提供分卷校验和验证,确保数据完整性
  • 彩色日志输出,包含时间戳,便于跟踪和审计
  • 默认使用并行压缩工具,处理大文件时效率更高

基本用法

1
./tar_single.sh -[操作方式][压缩算法] [操作对象]
  • 操作方式c创建、x解压、t测试
  • 压缩算法(仅创建时需要):z gzip(默认)、s zstd(推荐)、o xz(高压缩比)

使用示例

1
2
3
4
5
6
7
8
9
10
# 创建压缩包
./tar_single.sh -cz /path/to/data # gzip
./tar_single.sh -cs /path/to/data # zstd
./tar_single.sh -co /path/to/data # xz

# 解压压缩包(自动检测格式)
./tar_single.sh -x /path/to/archive_dir

# 测试完整性(自动检测格式)
./tar_single.sh -t /path/to/archive_dir

1
wget -qO- https://haies.cn/assets/deduplicate.sh

使用说明

deduplicate 是一个 Bash 脚本,用于递归分析指定目录下的重复文件和目录(内容完全相同),并根据用户选择执行删除或仅记录日志。

核心规则

  • 重复范围:仅在同一父目录下判定重复(文件和目录分开处理)
  • 遍历顺序:按目录深度从浅到深处理,先处理子目录重复,再处理文件重复
  • 保留策略:对于每个重复组,保留文件名最短且修改时间最早的一项,其余标记为待删除

自动忽略

以下项目不参与分析,也不会出现在日志中:

  • 以点(.)开头的文件和目录(隐藏项)
  • 名为 node_modulesdistbuildbindebug 的目录(不区分大小写)

日志文件

在每个待分析目录下生成独立的日志文件,文件名格式为 .deduplicate_YYYYMMDD_HHMMSS.log

日志仅记录重复项,每行格式为:

1
[时间戳] | 组ID | 绝对路径 | 状态

状态包括 KEEP(保留)、TO_DEL(待删除)、DELETED(已删除)。

删除模式

通过 -d 选项启用。如果指定目录下已有脚本生成的日志,则直接读取日志中状态为 TO_DEL 且仍存在的项目并执行删除,同时将对应日志行状态更新为 DELETED(不新增行)。如果无日志,则正常分析并直接删除重复项,同样只更新原日志行状态。

注意事项

⚠️ 删除不可恢复:脚本使用 rm -rf 直接删除文件和目录,请务必先备份重要数据,并在测试环境中验证脚本行为。

  • 权限要求:脚本需要对待分析目录具有读取和执行权限,对需删除项具有写权限
  • 性能提示:目录重复检测依赖 diff -rq,对于包含大量文件的目录可能较慢,请耐心等待
  • 日志积累:日志文件会永久保留,每次运行会生成新日志。删除模式下,多次运行可复用已有日志,仅更新状态

基本用法

1
deduplicate [-d] dir1 [dir2 ...]
  • -d:可选参数,启用删除模式。不加此参数时,仅将重复项记录到日志,不执行任何删除。
  • dir1 dir2 ...:必需参数,至少指定一个待分析的目录(绝对路径或相对路径均可)。

脚本会对每个目录独立处理,生成各自的日志文件。

使用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 示例 1:仅分析单个目录(不删除)
./deduplicate /home/user/documents

#分析 `/home/user/documents` 下的重复项,结果记录到 `/home/user/documents/.deduplicate_20260228_093012.log`。屏幕显示扫描进度和发现的重复组。

# 示例 2:分析多个目录
./deduplicate /home/user/docs /home/user/backup

#分别分析两个目录,各自生成日志文件,互不影响。

# 示例 3:分析并删除重复项(无现有日志)
./deduplicate -d /mnt/data/projects

#分析 `/mnt/data/projects`,发现重复组后直接删除待删除项,日志中对应行状态从 `TO_DEL` 变为 `DELETED`。屏幕显示删除进度。

# 示例 4:已有日志情况下再次运行删除模式
#假设之前已运行分析(不带 `-d`),生成了日志文件 `.deduplicate_20260228_093012.log`,其中包含一些 `TO_DEL` 项。现在执行:
./deduplicate -d /mnt/data/projects

#脚本会自动找到该目录下最新的日志,读取其中所有 `TO_DEL` 且仍存在的项目并删除,同时将日志中对应行更新为 `DELETED`。如果日志中已无 `TO_DEL` 项,则输出提示并结束。

查看日志内容

日志文件示例片段:

1
2
3
4
[2026-02-28 09:17:07] | G001 | /mnt/d/tmp/test/xs/凡人修仙传-- 忘语 -- 2017.epub | KEEP
[2026-02-28 09:17:07] | G001 | /mnt/d/tmp/test/xs/凡人修仙传-- 忘语 -- 2017 - 副本.epub | DELETED
[2026-02-28 09:17:07] | G002 | /mnt/d/tmp/test/xs/斗罗大陆 -- 唐家三少.mobi | KEEP
[2026-02-28 09:17:07] | G002 | /mnt/d/tmp/test/xs/斗罗大陆 -- 唐家三少 - 副本.mobi | DELETED

其中 G001G002 为组ID,每个组内先显示保留项(KEEP),再按文件名升序显示已删除项(DELETED)。

附录:脚本依赖

  • Bash 4.0 或更高版本
  • 标准命令:findsortstatsedsha256sumdiffrm
  • 确保脚本具有可执行权限:chmod +x deduplicate

如有任何问题或建议,请根据实际情况调整脚本或联系脚本维护者。

大型语言模型(LLM)是一个基于深度神经网络(DNN)的复杂系统。
其核心是通过海量数据训练,将文本转化为高维向量,并基于统计学
规律预测下一个词的概率分布,再通过反向传播(Backpropagation)
算法动态调整数以亿计的参数(Parameters),从而让向量编码的语义
知识(Semantic Knowledge)不断优化。

整个过程可类比于培养一位”学者”:

  • 参数规模(Model Scale):其神经基础
  • Transformer架构及其自注意力机制:其核心思维方式
  • 训练数据:其学习的”书籍”
  • 计算量:其投入的”资源”
  • 涌现能力(Emergent Abilities):量变引发的质变与创造性”顿悟”
  • 指令微调与人类对齐:社会化的沟通与伦理教育
  • 多模态能力(Multimodal Capabilities):扩展感知与交互的维度
  • 推理效率(Inference Efficiency):决定实际场景中的响应速度和实用性

这些特征相互关联,共同定义了大模型的综合能力(Capabilities)与
实用价值。

一、核心概念:理解AI如何”思考”与”生成”

🌐 基石认知

  • Transformer架构:现代大模型核心,通过”注意力机制”动态聚焦
    关键词(如读句时识别主谓宾),实现高效语义建模。

  • 向量与维度:文字→高维数字向量(如”猫”=[0.2, -1.7, 3.1…]);
    维度=特征数量(768维=768个语义特征),维度越高表达越精细。

  • 参数≠维度:参数是模型内部可学习的权重(如Qwen-Max约100亿参数),
    训练即优化参数以压缩语言规律;向量是输入经参数计算后的实时
    语义表示。

  • 训练实质:将海量文本中的模式”编码”进参数,使模型能将新输入
    映射为有意义的向量分布。

  • 生成公式

    输出内容 = 模型(参数) + Context(对话历史/文档) + Prompt(当前指令)

    ✅ 黄金法则:Prompt清晰具体 + Context提供必要背景
    (例:”基于上文需求,用Python写…”)

🔁 关键延伸

  • 强化学习(RLHF):通过人类偏好反馈微调模型,使输出更安全、
    有用(Claude/GPT系列核心优化手段)。
  • RAG(检索增强生成):先从向量库检索相关知识(如企业文档),
    再交由LLM生成答案——解决模型”不知道私有/最新信息”的核心方案

二、技术框架:构建AI应用的”骨架”

框架 核心价值 典型场景
LangChain / LlamaIndex 连接LLM与工具链(API/数据库)、管理对话流 智能客服、文档问答系统
RAG Pipeline 检索(向量库)+ 生成(LLM)双阶段架构 企业知识库、论文助手
pgvector PostgreSQL官方向量扩展 数据库内直接做语义搜索(”找相似产品描述”)
PGAI生态 PostgreSQL + pgvector/pgml等AI插件 减少数据搬运,数据库内嵌智能
LangGraph 构建多智能体(Agent)工作流 复杂任务拆解(写报告→画图→发邮件)

💡 实施路径:LangChain + pgvector 搭建简易RAG(GitHub模板丰富)


三、工具生态:分类与安全实践

📦 本地模型工具

工具 说明 ⚠️ 安全必读
Ollama 跨平台开源框架,支持Qwen/Llama/Gemma等百款模型本地运行;2025年7月推出Win/macOS桌面版 🔒 国家网信办2025年3月通报:默认配置存在未授权访问风险!✅ 必做:修改端口+设密码、禁用公网暴露、运行ollama serve --secure加固

🤝 AI协作工具

工具 定位 使用条件
Claude Cowork Anthropic 2026年1月发布,官方定义为”Claude Code for the rest of your work” ✅ 仅macOS(Windows版规划中)✅ 需Claude Max订阅✅ 通过Claude Desktop侧边栏启动💡 场景:整理下载文件夹、发票转Excel、会议笔记生成报告
Manus 多智能体可视化编排平台 适合非代码用户设计Agent工作流
阶跃AI(StepFun) 国产大模型平台(GLM系列) 中文场景优化,支持私有化部署

🤖 智能体平台

工具 背景 🔒 部署铁律
Moltbot(原Clawdbot) Peter Steinberger开发,2026年1月27日因Anthropic商标争议强制更名(GitHub星标8.1万+) 严禁在主力电脑全权限运行!✅ 首选:腾讯云Lighthouse / 阿里云轻量服务器✅ 必做:moltbot security audit定期扫描 + 严格限制邮箱/API权限💡 口号更新:”同样的龙虾灵魂,全新的虾壳”(图标保留)

💻 开发环境工具

类型 代表工具 说明
AI原生IDE Cursor, Trae, Windsurf 深度集成代码生成/调试,支持”对话式编程”
终端增强 Claude Code、Warp(AI命令解释)、Fig 命令行智能提示,降低CLI门槛

四、主流模型

模型系列 公司 特点 推荐场景
Claude 3.5 (Opus/Sonnet/Haiku) Anthropic Sonnet综合能力领先,Haiku极速廉价 复杂推理、长文档处理、多语言代码
Qwen (通义千问) 阿里巴巴 开源友好(Qwen-Max/Plus/Coder),中文深度优化 国内部署、代码写作、多模态
DeepSeek 深度求索 中文代码能力突出,API性价比高 中文项目开发、算法题解答
GLM4.7 智谱AI Edge轻量高效,130B开源 移动端部署、科研实验
Llama 3 / GPT-4o Meta / OpenAI 开源标杆 / 多模态响应快 学术研究、国际项目

✅ 选择策略:

  • 国内用户:GLM、Qwen、DeepSeek(访问快、中文强)
  • 国际场景:Claude 3.5 Sonnet(当前综合能力标杆)
  • 本地部署:Qwen/Mistral开源系列 + Ollama(注意安全加固!)

五、Claude能力体系:从代码到全场景协作

🔑 核心能力组件(Claude.ai平台)

概念 说明 实战价值
MCP(Model Context Protocol) 安全连接外部工具的”通用插座”(VS Code/数据库/Figma) 让Claude调用真实环境能力
Skills 预置能力模块(”解释代码””生成测试”) 一键启用,减少Prompt编写
Agents 扮演角色自主行动(”前端工程师Agent”) 结合MCP完成多步骤任务
Rules 用户设定约束(”注释用中文””禁改config”) 规范AI行为,提升可靠性
Script 用户可编写自定义脚本(Python/Shell/JS),通过MCP注册,完成特定任务 实现高度定制化自动化(如调用内部API、处理私有数据格式、执行部署命令)
Plugins 通过MCP接入的扩展(Figma→设计图转代码) 扩展应用场景边界
  1. 三种模式

    • 📝 聊天模式:日常问答
    • 💻 代码模式:专注代码生成/调试(自动识别代码块)
    • 🤖 Projects模式:管理长上下文项目(上传整个文件夹,跨文件理解)
  2. 上下文管理

    • 支持200K+ tokens上下文,可上传PDF/代码库/设计稿
    • Projects中文件自动关联,提问时智能引用相关代码
  3. 代码生成

    • Prompt:添加需求,制定PLAN
    • 🎨 上传设计图:上传设计图,明确界面
    • 🧠 Skills触发:固定开发要求
    • 💻 hook调用:格式化代码

以下是对Dan Koe长文《How to fix your entire life in one day》主要观点的总结,分为核心逻辑、关键方法论和行动建议三个部分,便于理解与实践:

一、核心逻辑:认知死亡与身份重生

  1. 颠覆式认知变革:改变的本质是“意识的迁移”,需彻底打破现有思维框架(如“农民讨论皇帝用金锄头”的比喻),承认当前认知局限是问题的根源。
  2. 杀死旧身份,诞生新自我:必须主动“干掉现在的自己”,通过身份重构(而非零星习惯调整)实现根本转变。身份决定视角,视角决定世界。
  3. 舒适区的危险:温水煮青蛙式的“还凑合”生活是最大陷阱,真正的痛苦反而是改变的催化剂。

二、关键方法论:打破惯性,重塑系统

  1. 反向愿景法(Anti-Vision)
  • 聚焦“不想成为谁”:通过具象化5年后若不改变的惨淡生活(如“悲惨的周二早晨”),用恐惧驱动行动。
  • 痛苦作为燃料:经历“失调(忍无可忍)→ 不确定(迷茫)→ 发现(爆发)”三阶段。
  1. 打断自动驾驶,强制反思
  • 设置随机闹钟:通过提问打断日常惯性(如“我在逃避什么?”“此刻行为让我靠近理想还是远离?”)。
  • 深层自我追问:剖析隐藏行为动机(如拖延本质是逃避评判,而非缺乏自律)。
  1. 人生游戏化(Gamification)
  • 将生活设计为可操作的“游戏系统”:设定目标(BOSS)、分解任务(关卡)、即时反馈(经验值)、建立抗干扰“力场”。
  • 接纳混乱,策略性冗余:如俄罗斯方块中“平整堆叠”应对不确定的生活挑战,避免依赖完美解决方案。

三、行动建议:一日重启程序

  1. 上午:掘地三尺看清现状:直面当前困境,诊断深层问题。
  2. 白天:持续打断惯性:通过闹钟提问、环境重构(如更换工作场景)摆脱舒适区。
  3. 晚上:压缩洞见为行动结构
  • 身份重新定位:明确“我是谁”(新身份认同)。
  • 构建可执行系统:将新身份转化为具体行为准则与每日习惯。
  1. 长期维持:反馈循环与身份强化
  • 践行八步循环:目标→感知现实→学习→行动→反馈→内化认同→防御干扰→新目标。
  • 成为“通才型思考者”:融合多领域知识,提升系统思维。

四、颠覆性洞见

  • 行动胜于言语:改变始于行为,而非口号(如减肥者需先内化新生活方式,而非等待结果)。
  • 智慧即人生掌控:通过“设定目标→行动→感知→比较→调整”的反馈循环,持续迭代。
  • 概率与韧性:接受生活随机性,构建抗脆弱系统(如预留冗余空间)。

总结:文章强调改变需从认知颠覆开始,通过反向激励、系统性重构和游戏化思维,将“身份重生”转化为可操作的日常实践,最终在混乱中建立掌控感。

希望这篇总结能帮助你快速掌握Dan Koe的核心思想!如果需要进一步探讨某个观点,请随时告诉我。
by Qwen3-Max

以下是针对生产环境的GeoServer系统配置与数据发布完整教程,
涵盖Docker化部署、影像与矢量发布全流程。

一、系统配置:基于Docker部署

1. 目录结构与文件准备

1
2
3
4
5
6
geoserver-production/          # 项目根目录
├── docker-compose.yml # Docker Compose 编排文件
├── .env # 环境变量文件(用于隔离敏感信息)
├── geoserver_data/ # GeoServer 主数据目录
├── geoserver_gwc/ # GeoWebCache 瓦片缓存
└── geoserver_logs/ # 应用日志目录

2. 关键环境变量详解(部署核心)

karotza/docker-geoserver 完全通过环境变量配置 GeoServer 核心行为,
以下是启动容器时最关键的环境变量分类及说明:

| 参数名称 | 描述与作用 | 建议值 / 示例 | 关键配置要点 |
| :— | :— | :— |
| GEOSERVER_DATA_DIR | GeoServer 主数据目录,用于存储工作区、数据存储、样式等所有配置信息。 | /opt/geoserver_data/data | 必须通过卷(volumes)挂载到宿主机,实现配置持久化,避免容器重启后数据丢失。 |
| GEOWEBCACHE_CACHE_DIR | GeoWebCache 瓦片缓存目录,用于存储预生成的栅格式或矢量瓦片文件。 | /opt/geoserver_data/gwc | 同样必须挂载持久化。 |

  1. 生产环境建议使用高速存储(如SSD)。

  2. 需定期清理旧缓存或设置磁盘配额。 |
    | GEOSERVER_ADMIN_USER | 管理员用户名。出于安全考虑,建议修改默认值。 | 自定义(如:gs_admin) | 与强密码配合使用。仅在初始设置时生效,之后在Web界面修改。 |
    | GEOSERVER_ADMIN_PASSWORD | 管理员密码。这是最关键的安全设置。 | 自定义(强密码) | 必须修改。使用高强度密码(如:MyGeo0S3rv3r!2024)。可通过.env文件管理,避免硬编码。 |
    | INITIAL_MEMORY | JVM 堆内存初始大小。 | 2g | 通常设置为与 MAXIMUM_MEMORY 相同,以避免运行时动态调整带来的性能开销。 |
    | MAXIMUM_MEMORY | JVM 堆内存最大大小。对性能影响最大。 | 4g8g | 1. 黄金法则:不超过宿主机可用物理内存的75%。 |

  3. 对于大量瓦片或高并发,建议设置为 8g 或更高。 |
    | STABLE_EXTENSIONS | 预安装的官方稳定插件列表。用逗号分隔。 | vector-tiles,monitor,importer | 1. vector-tiles(矢量瓦片)是必选项。

  4. monitor 用于生产监控。

  5. importer 方便数据导入。 |
    | COMMUNITY_EXTENSIONS | 预安装的社区插件列表。用逗号分隔。 | control-flow,backup-restore | 1. control-flow 可控制并发请求,防止过载。

  6. backup-restore 便于配置备份。 |
    | GEOSERVER_CONTEXT_ROOT | Web 应用的上下文路径(URL路径)。 | /geoserver | 默认即为 /geoserver,访问地址为 http://host:port/geoserver。非特殊需求无需修改。 |
    | ROOT_WEBAPP_REDIRECT | 是否将根路径(/)重定向到 GeoServer 应用。 | true | 设置为 true 后,访问 http://host:8080/ 会自动跳转到 http://host:8080/geoserver/web,非常便利。 |
    | CONSOLE_HANDLER_LEVEL | 控制台日志输出级别,影响 Docker 日志的详细程度。 | INFO | 1. INFO:常规生产级别,记录重要事件。

  7. DEBUG:调试时使用,日志量巨大。

  8. WARN:仅记录警告和错误。 |

将上表参数整合到一个 docker-compose.yml 文件中,其核心部分如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
services:
geoserver:
image: karotza/geoserver:latest
container_name: prod_geoserver
environment:
- GEOSERVER_ADMIN_USER=${GEOSERVER_ADMIN_USER}
- GEOSERVER_ADMIN_PASSWORD=${GEOSERVER_ADMIN_PASSWORD}
- GEOSERVER_DATA_DIR=/opt/geoserver/data_dir
- GEOWEBCACHE_CACHE_DIR=/opt/geoserver/gwc
- INITIAL_MEMORY=${INITIAL_MEMORY}
- MAXIMUM_MEMORY=${MAXIMUM_MEMORY}
- STABLE_EXTENSIONS=${STABLE_EXTENSIONS}
- COMMUNITY_EXTENSIONS=${COMMUNITY_EXTENSIONS}
- ROOT_WEBAPP_REDIRECT=true
- CONSOLE_HANDLER_LEVEL=${CONSOLE_HANDLER_LEVEL}
volumes:
- ./geoserver_data:/opt/geoserver/data_dir
- ./geoserver_gwc:/opt/geoserver/gwc
- ./geoserver_logs:/opt/geoserver/logs
ports:
- "8080:8080"

3. 日常运维命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 1. 前台启动(调试用,实时看日志)
docker-compose up

# 2. 后台启动(生产环境首选,不占用终端)
docker-compose up -d

# 3. 强制重新构建(仅修改Dockerfile/镜像后使用,修改环境变量无需此参数)
docker-compose up -d --build

# 4. 停止容器(保留容器和数据)
docker-compose stop

# 5. 重启容器(修改配置后生效)
docker-compose restart geoserver

# 6. 停止并删除容器(保留数据卷,仅删容器)
docker-compose down

# 7. 查看实时日志(排查启动/运行问题)
docker-compose logs -f geoserver

# 8. 查看最近100行日志(快速定位错误)
docker-compose logs --tail=100 geoserver

# 9. 进入容器(手动安装插件/调试)
docker exec -it prod_geoserver /bin/bash

核心配置优先级:数据目录持久化(必配)> 密码修改(必改)> 内存分配(性能关键)> 插件/跨域(按需配置)。

在 GeoServer 中发布 GeoTIFF 格式影像并启用瓦片缓存(通过 GeoWebCache, GWC)的标准步骤如下,适用于大多数 Web 地图应用场景。


二、影像数据发布

1. 准备 GeoTIFF 文件

  • 确保文件具有正确的地理参考信息(坐标系、范围等)。
  • 建议使用 EPSG:3857(cgcs2000)、EPSG:4326(cgcs2000_3_gk_120E)、EPSG:4490(WGS84)或 EPSG:4326(Web Mercator)以兼容主流地图客户端。

2. 登录 GeoServer 管理界面

  • 默认地址:http://localhost:8080/geoserver

3. 创建 Coverage Store

  • 导航:数据 > Stores > Add new Store
  • 选择 GeoTIFF(位于 “Raster Data Sources” 下)
  • 配置参数:
    • Workspace:选择或新建工作空间
    • Data Source Name:输入名称(如 my_geotiff_store
    • URL:填写 GeoTIFF 文件路径(如 file:/path/to/your/image.tif
    • 点击 Save

4. 发布图层(Layer)

  • GeoServer 会自动跳转到图层发布页面
  • 设置关键参数:
    • Name:图层名称(如 my_raster_layer
    • Declared SRS:建议设为文件实际坐标系(如 EPSG:3857)
    • Bounding Boxes:点击 “Compute from data” 和 “Compute from SRS bounds”
    • 保存图层

5. 启用并配置瓦片缓存(GWC)

  • 进入:Tile Caching > Tile Layers
  • 找到刚发布的图层(如 workspace:my_raster_layer),点击进入
  • 配置缓存选项:
    • Enabled:勾选
    • Grid Sets:至少勾选 EPSG:4326 和/或 EPSG:3857
    • Formats:选择输出格式(如 image/pngimage/jpeg
    • (可选)设置缓存目录、过期策略等

6. 预生成(Seed)瓦片(可选但推荐)

  • 在同一页面点击 Seed/Truncate
  • 选择:
    • Operation: Seed
    • Grid Set: 如 EPSG:3857
    • Zoom Start / Stop: 指定要缓存的级别(如 0 到 12)
    • Format: 与上一步一致
    • 点击 Submit 开始切片(后台运行)

7. 访问瓦片服务

  • WMS(推荐用于瓦片地图)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    http://localhost:8080/geoserver/gwc/service/wmts?
    REQUEST=GetCapabilities&
    SERVICE=WMTS&
    VERSION=1.0.0&
    LAYER=workspace:my_raster_layer&
    STYLE=&
    TILEMATRIXSET=EPSG:4326&
    TILEMATRIX={z}&
    TILEROW={y}&
    TILECOL={x}&
    FORMAT=image/png
  • TMS

    1
    http://localhost:8080/geoserver/gwc/service/tms/1.0.0/workspace:my_raster_layer@EPSG:4326@png/{z}/{x}/{-y}.png

提示

  • 首次访问未缓存的瓦片时,GeoServer 会动态生成并自动缓存。
  • 预切片(Seed)可显著提升高并发下的性能。
  • 确保 GeoServer 有足够磁盘空间存放缓存(默认在 GEOSERVER_DATA_DIR/gwc)。

通过以上步骤,即可成功在 GeoServer 中发布 GeoTIFF 影像,并通过内置的 GeoWebCache 实现高效瓦片服务。

三、ESRI ARCGIS影像瓦片发布

瓦片数据准备

确保ArcGIS瓦片目录结构正确:

1
2
3
4
5
6
7
arcgis-cache/
├── conf.xml # 瓦片方案配置文件
├── _alllayers/ # 瓦片数据目录
│ ├── L00/ # 金字塔层级
│ ├── L01/
│ └── ...
└── ArcGIS_瓦片_使用说明.txt

步骤 1:获取并安装 ArcGIS 瓦片插件

  1. 下载插件

    • GeoWebCache 官网 下载对应版本的 ArcGIS 插件(如 gwc-arcgiscache-1.25.4.jar
    • 确保插件版本与 GeoServer 版本匹配
  2. 安装插件

    1
    2
    # 将插件复制到 GeoServer 的 lib 目录
    cp gwc-arcgiscache-1.25.4.jar /path/to/geoserver/webapps/geoserver/WEB-INF/lib/

步骤 2:配置 GeoServer

2.1 配置缓存目录(可选但推荐)

  1. 编辑 geoserver/webapps/geoserver/WEB-INF/web.xml

    1
    2
    3
    4
    <context-param>
    <param-name>GEOWEBCACHE_CACHE_DIR</param-name>
    <param-value>/path/to/your/cache/directory</param-value>
    </context-param>
  2. 重启 GeoServer 使配置生效

2.2 配置 geowebcache.xml

  1. 编辑 geoserver/data_dir/gwc/geowebcache.xml

  2. <layers> 标签内添加 ArcGIS 瓦片配置:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <layers>
    <arcgisLayer>
    <name>your_layer_name</name>
    <tilingScheme>/path/to/your/conf.xml</tilingScheme>
    <!-- 可选:指定切片目录(默认为 conf.xml 同级 _allLayers) -->
    <tileCachePath>/path/to/your/tiles</tileCachePath>
    <!-- 可选:若 ArcGIS 使用十六进制层级名(如 L00),设为 true -->
    <hexZoom>false</hexZoom>
    </arcgisLayer>
    </layers>

    参数说明

    • name:在 GeoServer 中显示的图层名称
    • tilingScheme:ArcGIS 生成的 conf.xml 文件路径
    • tileCachePath:瓦片存储目录(与 ArcGIS 生成的瓦片目录一致)

步骤 3:发布瓦片

  1. 重启 GeoServer(使插件和配置生效)

  2. 验证瓦片服务

    • 访问 http://your-geoserver/geoserver/gwc/service/wmts?REQUEST=GetCapabilities
    • 检查响应中是否包含你的 ArcGIS 瓦片图层
  3. 预览瓦片

    • 进入 GeoServer 管理界面:http://your-geoserver/geoserver/web
    • 导航到 Tile Layers > 选择你的图层 > Preview
    • 选择合适的坐标系和格式进行预览

4. 性能优化配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!-- geoserver-data/gwc/geowebcache.xml 优化配置 -->
<gwcConfiguration xmlns="http://geowebcache.org/schema/1.12.0">
<layers>
<!-- 其他 wmsLayer 可共存 -->

<arcgisLayer>
<name>naturalearth</name>
<tilingScheme>/opt/cache/naturalearth/Layers/conf.xml</tilingScheme>
<tileCachePath>/opt/cache/naturalearth/_allLayers</tileCachePath>
<hexZoom>false</hexZoom>
</arcgisLayer>

</layers>
</gwcConfiguration>

关键配置说明

配置项 说明 示例
tilingScheme ArcGIS 的 conf.xml 文件路径 /opt/geoserver/gwc/arcgis-cache/conf.xml
tileCachePath 瓦片存储目录 /opt/geoserver/gwc/arcgis-cache/_allLayers
name GeoServer 中显示的图层名称 arcgis-cache
hexZoom 是否使用十六进制缩放级别 false

验证瓦片服务

瓦片服务 URL 格式:

1
2
3
4
5
6
7
8
9
10
11
http://localhost:8080/geoserver/gwc/service/wmts?
REQUEST=GetCapabilities&
SERVICE=WMTS&
VERSION=1.0.0&
LAYER=workspace:your_layer_name&
STYLE=&
TILEMATRIXSET=EPSG:4326&
TILEMATRIX={z}&
TILEROW={y}&
TILECOL={x}&
FORMAT=image/png

常见问题解决

  1. 瓦片路径不匹配

    • 检查 tilingSchemetileCachePath 路径是否与实际瓦片目录一致
    • 确保路径使用正斜杠 /(Windows 系统中可使用正斜杠)
  2. 插件未加载

    • 检查 WEB-INF/lib 中是否包含插件 JAR 文件
    • 重启 GeoServer
  3. 瓦片显示异常

    • 检查瓦片坐标系是否与 GeoServer 一致
    • 确认瓦片范围与坐标系匹配

四、矢量数据发布教程

在 GeoServer 中基于 PostgreSQL/PostGIS 数据库发布 WMS(Web Map Service)
矢量瓦片(Vector Tiles,如 MVT/PBF 格式) 是现代 Web GIS 应用的核心能力。
以下是清晰、完整的配置步骤总结:

前提条件

  1. PostgreSQL + PostGIS 已安装并启用
    • 确保目标表已添加空间索引(CREATE INDEX ON table USING GIST(geom);
    • 表中包含 geometrygeography 类型字段
  2. GeoServer 已安装(建议 2.20+)
  3. PostGIS 插件已启用(通常默认包含)

步骤一:在 GeoServer 中连接 PostgreSQL 数据库

  • 进入 Data > Stores > Add new Store

  • 选择 PostGIS (JNDI not required)(或直接选 “PostGIS”)

  • 配置参数:

    1
    2
    3
    4
    5
    6
    7
    8
    Workspace:          your_workspace (e.g., "cite")
    Data Source Name: postgis_store
    Host: your-db-host (e.g., localhost)
    Port: 5432
    Database: your_db_name
    Schema: public (or your schema)
    User: db_user
    Password: db_password
  • 勾选 “Expose primary keys”(对矢量瓦片性能有帮助)

  • 点击 Save

若使用 Docker 部署 GeoServer,确保容器能访问 PostgreSQL(网络互通)。


步骤二:发布矢量图层(WMS 基础)

  • 在 Store 创建后,点击 Publish 发布新图层
  • 设置:
    • Declared SRS: 与数据一致(如 EPSG:4326EPSG:3857
    • Bounding Boxes: 点击 “Compute from data” 和 “Compute from SRS bounds”
    • 配置样式(Style):
    • 可使用默认 polygon, line, point 样式
    • 或自定义 SLD/CSS 样式

此时 WMS 服务已可用:

1
2
3
4
5
6
7
8
9
10
http://localhost:8080/geoserver/wms?
service=WMS&
version=1.1.0&
request=GetMap&
layers=workspace:layer_name&
styles=&
bbox=minx,miny,maxx,maxy&
width=800&height=600&
srs=EPSG:4326&
format=image/png

步骤三:启用矢量瓦片(MVT / PBF)支持

GeoServer 从 2.11+ 开始原生支持 Mapbox Vector Tiles (MVT) 格式。

确认 MVT 输出格式已启用

  • 进入 Settings > Global Settings
  • 检查 Vector Tile Formats 是否包含 application/vnd.mapbox-vector-tile(通常默认启用)

若未显示,需确认 gt-mbtilesgt-vectortiles 插件已安装(现代版本通常内置)。

配置图层的矢量瓦片输出

  • 进入图层编辑页:Layers > your_layer > Tile Caching

  • Tile Image Formats 中勾选:

    • application/vnd.mapbox-vector-tile
  • (可选)在 Vector Tile 选项卡中:

    • 设置 Clipping(是否裁剪到瓦片边界)
    • 设置 Simplification(简化几何以提升性能)

预生成或动态请求矢量瓦片

方式 A:动态请求(推荐用于交互式地图)

客户端直接请求 MVT 瓦片 URL:

1
http://localhost:8080/geoserver/gwc/service/tms/1.0.0/workspace:layer_name@EPSG:4326@pbf/{z}/{x}/{-y}.pbf

注意:TMS 使用 -y(翻转 Y 轴),而 XYZ 用 y。Leaflet/OpenLayers 通常用 TMS 模式。

或通过 WMS 兼容接口(GeoServer 特有):

1
2
3
4
5
6
7
8
9
10
http://localhost:8080/geoserver/workspace/wms?
service=WMS&
version=1.1.0&
request=GetMap&
layers=layer_name&
format=application/vnd.mapbox-vector-tile&
tiled=true&
tileOrigin=lon,lat&
width=256&height=256&
bbox={bbox}

方式 B:预切片缓存(高并发场景)

  • 进入 Tile Caching > Seed/Truncate
  • 选择:
    • Format: application/vnd.mapbox-vector-tile
    • Grid Set: EPSG:4326(Web Mercator)
    • Zoom levels: 如 0–14
    • 点击 Submit 后台生成 .pbf 缓存

缓存路径:GEOSERVER_DATA_DIR/gwc/workspace_layer_name_EPSG_4326/application.x-protobuf.type=mapbox-vector/...


客户端调用示例(OpenLayers)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// WMS 图层(栅格)
const wmsLayer = new ol.layer.TileWMS({
source: new ol.source.TileWMS({
url: 'http://localhost:8080/geoserver/wms',
params: { LAYERS: 'workspace:layer_name' }
})
});

// 矢量瓦片图层(MVT)
const mvtLayer = new ol.layer.VectorTile({
source: new ol.source.VectorTile({
format: new ol.format.MVT(),
url: 'http://localhost:8080/geoserver/gwc/service/tms/1.0.0/' +
'workspace:layer_name@EPSG:4326@pbf/{z}/{x}/{-y}.pbf'
})
});

性能优化建议

优化项 说明
空间索引 确保 PostGIS 表有 GIST 索引
主键暴露 Store 中勾选 Expose primary keys
简化几何 在 Vector Tile 设置中启用简化
限制属性 在图层”Fields”选项卡中只发布必要字段
缓存策略 高频访问区域预瓦片(Seed)
内存调优 增加 GeoServer JVM 内存(如 -Xmx4g

验证清单

  • PostgreSQL 表含有效 geometry 字段
  • GeoServer 成功连接 PostGIS Store
  • WMS 图层可预览(PNG/JPEG)
  • 图层启用了 application/vnd.mapbox-vector-tile 格式
  • 能通过 TMS/WMS 接口获取 .pbf 瓦片
  • 客户端(如 OpenLayers、MapLibre)成功加载矢量瓦片

一、现象描述与原因解析

问题现象

在 Windows 11 笔记本上,开启移动热点(设置 → 网络和 Internet → 移动热点 → 编辑 → 网络频带),如果选择 5GHz 频段,系统提示 “所选网络波段不可用”,但是无线显卡本身是支持5GHz频段的。
设置频段
错误提示

原因分析

Windows 11 的移动热点功能(基于 WLAN Hosted Network 或 Wi-Fi Direct Virtual Adapter)会动态检测无线网卡的射频环境。当未连接任何 Wi-Fi(如仅通过有线网络上网)时,系统无法确认当前环境是否允许使用 5 GHz 频段。受中国无线电法规限制(国家码 CN),系统默认屏蔽 DFS 信道(52–144),导致其尝试启用受限信道时触发”所选网络波段不可用”错误。关键机制:系统仅在检测到设备已成功连接 5 GHz 合规信道(如 UNII-3 的 149/153/157/161/165)后,才允许启用 5 GHz 热点。因此,必须先连接 5 GHz Wi-Fi(保持连接),系统方能”学习”到环境合规性,后续即可开启 5 GHz 热点并断开原 Wi-Fi。

UNII频段 频率范围 信道范围 中心频率 中国法规限制 是否可用
UNII-1 5.15~5.25 GHz 36, 40, 44, 48 5180, 5200, 5220, 5240 MHz 仅限室内使用 ✅ 可用(但仅限室内)
UNII-2A 5.25~5.35 GHz 52, 56, 60, 64 5260, 5280, 5300, 5320 MHz 仅限室内使用 ✅ 可用(但仅限室内)
UNII-2C 5.47~5.725 GHz 100-144(以4为步长) 5500-5720 MHz 完全不可用(中国缺失) ❌ 不可用
UNII-3 5.725~5.825 GHz 149, 153, 157, 161, 165 5745, 5765, 5785, 5805, 5825 MHz 所有场景可用 ✅ 可用(推荐使用)

二、系统服务检查与显卡配置

检查系统服务

  1. 按 Win + R 输入 services.msc
  2. 确保 WLAN AutoConfig 和 Internet Connection Sharing (ICS) 服务正在运行

无线网卡设置

笔记本设置(设备管理器 > 网络适配器 > Intel Wi-Fi AX211 > 属性 > 高级)
无线网卡高级属性

以下是结合场景需求的必要设置项

1. 首选频带

  • 适用场景:希望无线网卡优先连接5GHz或6GHz频段(避开2.4GHz频段的设备拥挤、干扰问题)。
  • 说明:默认可能无频带优先级(或优先2.4GHz),手动设置“首选5GHz/6GHz”后,网卡会优先搜索并连接该频段信号。

2. 超高频段(6GHz)

  • 适用场景:当无线路由器支持 Wi - Fi 6E(即支持6GHz频段) 时,需开启此选项。
  • 说明:6GHz频段可提供更高网速、更低延迟,但需路由器硬件及固件支持6GHz,否则默认关闭(因6GHz需生态支持,普通家庭路由器可能不开放该频段)。

3. 唤醒幻数据包

  • 适用场景:需通过**局域网唤醒(Wake - on - LAN)**远程控制处于待机/关机状态的电脑(如远程访问家庭电脑)。
  • 说明:默认可能关闭,开启后允许特定网络数据包唤醒设备(需配合路由器设置“转发唤醒包”功能)。

4. 漫游主动性

  • 适用场景
    • 若移动中(如在房间走动)发现“信号弱但网卡不主动切换热点,导致卡顿/网速慢”,可调高数值(如3 - 4,数值越高切换越积极);
    • 若“频繁无故切换热点导致短暂断线”,可调低数值(如1 - 2,降低切换积极性)。
  • 说明:默认为“中等”(数值2 - 3),若无网络体验问题无需调整。

5. 信道宽度(2.4GHz频段)

  • 适用场景:2.4GHz频段干扰严重(如老旧小区、多路由器密集区域)。
  • 说明:默认“自动”可能选择40MHz,但干扰多时易断连;手动固定为20MHz可提升稳定性(5GHz/6GHz频段默认“自动”一般无需改,除非有特殊速度/稳定需求)。

其他说明

“无线模式、MIMO、节能卸载(ARP/GTK/NS)、传输电源、数据包合并、吞吐量助推器、与40MHz信道不兼容、U - APSD支持”等选项,默认设置已适配多数场景,无需手动干预,驱动会自动协商最优参数。
当移动

总结:仅当遇到6GHz路由器适配、远程唤醒、频段优先级、漫游切换异常、2.4GHz干扰严重等问题时,需针对性调整上述5类设置;其他选项保持默认即可获得最佳兼容性与性能。


三、开启 5GHz 移动热点

🔧 步骤 1:配置路由器为合规 5GHz 信道(必须!)

  1. 打开浏览器,输入路由器管理地址(如 192.168.1.1)。
  2. 登录后,进入 无线设置 > 5GHz 频段
  3. 将信道手动设置为
    149(推荐,干扰最少)或 153/157/161/165
    避免:自动选择、52–144 信道(DFS 信道)。
  4. 保存设置并重启路由器。

💡 为什么必须?这是让 Windows 识别合规环境的关键!
示例:TP-Link 路由器设置路径:无线设置 > 5GHz > 信道:149


📱 步骤 2:连接合规 5GHz Wi-Fi(保持连接)

  1. 在 Windows 11 任务栏右下角点击 网络图标
  2. 选择您的 5GHz Wi-Fi 网络(名称中含“5G”或“5GHz”)。
  3. 输入密码连接。
  4. 保持连接状态,不要断开!(系统需此过程学习合规环境)

✅ 此步骤是“解锁”5GHz 热点的关键!
检查:手机连接该 Wi-Fi 后,在 Wi-Fi 设置中查看“频段”是否显示“5GHz”


📡 步骤 3:开启 5GHz 移动热点

  1. 打开 设置 > 网络和 Internet > 移动热点
  2. 点击 “编辑”(位于“网络频带”下方)。
  3. 在下拉菜单中选择 “5 GHz” → 点击 “保存”
  4. 打开 移动热点开关

✅ 系统此时已识别为合规环境,5GHz 选项不再灰显


📱 步骤 4:断开第一步的 Wi-Fi 连接

  1. 在任务栏网络图标中,点击 当前连接的 5GHz Wi-Fi
  2. 选择 “断开”
  3. 移动热点将保持开启状态,无需重新设置!

✅ 验证:用手机连接热点,进入手机 Wi-Fi 设置 → 查看“频段”是否显示 5GHz


三、总结

步骤 作用
1. 路由器设为信道 149 创建合规 5GHz 环境(中国允许的信道)
2. 连接该 Wi-Fi Windows 学习到环境合规 → 临时解锁 5GHz 热点
3. 开启 5GHz 热点 系统基于学习到的环境,允许使用 5GHz
4. 断开 Wi-Fi 系统保留“合规环境”状态 → 热点持续使用 5GHz(无需重连)

最终效果
Windows 11 笔记本只要不关机即可使用 5GHz 移动热点,重新开机后需要重新执行WLAN连上5GHz热点→开启5GHz移动热点→断开WLAN5GHz热点的过程。

本文实现了一套安全、模块化、生产端的 Nginx 反向代理方案,核心功能包括:

  1. 统一代理支持:通过 Nginx 同时提供 HTTP 和 TCP 反向代理;
  2. 真实客户端信息透传:使用标准代理头(如 X-Real-IP、X-Forwarded-For)确保后端服务获取原始请求信息;
  3. 跨域控制(CORS):允许所有域名跨域请求,但仅限 IP 白名单中的客户端;
  4. 独立 IP 白名单:通过单独的 geo 配置文件实现访问控制,默认拒绝所有非白名单 IP,支持动态更新无需重启;
  5. 全局限制策略:统一设置最大上传文件大小(10MB)和响应空闲超时(60秒);
  6. 按需缓存与维护模式:仅对 /api/ 接口启用缓存,并支持通过文件开关快速切换维护页面。

整套方案采用配置分离、职责清晰、Docker 友好的设计,兼顾安全性、可维护性与高性能,适用于企业级生产环境。

📁 整体目录结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/etc/nginx/
├── nginx.conf # 全局配置文件
├── conf.d/
│ ├── http.conf # HTTP代理配置
│ ├── db.stream # 数据库代理配置
│ └── maintenance.conf # 维护界面独立配置
├── security/
│ ├── blacklist.conf
│ ├── whitelist.conf
│ ├── rate-limiting.conf
│ ├── security_rules.conf
│ ├── security_checks.conf
│ ├── blacklist.ip
│ └── whitelist.ip
├── proxy_params # 通用代理头配置
├── cache_params # 缓存配置
└── cors_params # 跨域控制独立配置

1. 统一配置

1.1 TCP和HTTP配置(/etc/nginx/nginx.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# 全局配置:TCP 代理和全局参数
stream {
# TCP 代理配置(独立于 HTTP)
include /etc/nginx/conf.d/*.stream;
}

http {
# === 全局控制(所有 HTTP 代理生效) ===
include /etc/nginx/mime.types;
default_type application/octet-stream;

# 性能优化
sendfile on;
tcp_nopush on;
tcp_nodelay on;
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain application/json text/css application/javascript;
keepalive_timeout 65;
keepalive_requests 1000;
types_hash_max_size 2048;
server_tokens off;
client_header_buffer_size 1k;
large_client_header_buffers 4 8k;

# 超时控制
proxy_connect_timeout 30s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;

# 缓冲区优化
proxy_buffer_size 4k;
proxy_buffers 8 4k;
proxy_busy_buffers_size 8k;
proxy_temp_file_write_size 8k;

# 上传文件控制
client_max_body_size 500M;
client_body_buffer_size 1m;
client_body_temp_path /tmp/nginx_body;
client_body_timeout 300s;
proxy_request_buffering on;

set $block_access 0;
set $block_reason "";

# 日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'rt=$request_time uct="$upstream_connect_time" '
'uht="$upstream_header_time" urt="$upstream_response_time"';

log_format security 'time=$time_iso8601 client=$realip_remote_addr '
'xff="$http_x_forwarded_for" method=$request_method '
'uri="$request_uri" status=$status '
'user_agent="$http_user_agent" '
'blocked=$block_access block_reason=$block_reason '
'rate_limit=$rate_limit_zone cache_status=$upstream_cache_status';

log_format json_combined escape=json
'{"time":"$time_iso8601",'
'"remote_addr":"$realip_remote_addr",'
'"x_forwarded_for":"$http_x_forwarded_for",'
'"method":"$request_method",'
'"uri":"$request_uri",'
'"status":$status,'
'"body_bytes_sent":$body_bytes_sent,'
'"request_time":$request_time,'
'"http_referrer":"$http_referer",'
'"http_user_agent":"$http_user_agent",'
'"is_whitelisted":$whitelist_ip,'
'"is_blacklisted":$blacklist_ip}';

# 访问日志
access_log /var/log/nginx/access.log main buffer=32k flush=5s;
access_log /var/log/nginx/security.log security;
access_log /var/log/nginx/audit/audit-$(date +%Y-%m-%d).log json_combined;
error_log /var/log/nginx/error.log warn;

# 真实IP处理(去掉SLB、CDN等内网IP)
set_real_ip_from 10.0.0.0/8;
set_real_ip_from 192.168.0.0/16;
real_ip_header X-Forwarded-For;
real_ip_recursive on;

# 通用代理头(复用)
include proxy_params;

# === 接口缓存配置(全局定义,独立文件生效) ===
# 缓存配置
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=api_cache:10m
max_size=1g inactive=60m use_temp_path=off;
proxy_cache_path /var/cache/nginx/static levels=1:2 keys_zone=static_cache:100m
max_size=10g inactive=365d use_temp_path=off;

# 限制并发连接数
limit_conn_zone $binary_remote_addr zone=per_ip:10m;
limit_conn_zone $server_name zone=per_server:10m;

# 包含安全配置
include /etc/nginx/security/*.conf;

# 包含所有独立配置
include /etc/nginx/conf.d/*.conf;
}

💡 关键配置

  • TCP 代理独立在 stream 块(不能与 HTTP 混合)
  • 全局上传大小/超时设置在 http 块(避免重复配置)
  • 缓存路径全局定义,独立配置文件只指定作用域
  • 缓存路径 /var/cache/nginx 需在 Docker 容器中挂载(-v /host/cache:/var/cache/nginx

1.2 传递客户端的真实信息配置(/etc/nginx/proxy_params

1
2
3
4
5
6
7
8
9
# /etc/nginx/proxy_params
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Server $hostname;

1.3 HTTP接口缓存配置(/etc/nginx/cache_params

1
2
3
4
5
6
7
# /etc/nginx/cache_params
proxy_cache api_cache;
proxy_cache_valid 200 302 1d; # 200/302 缓存 1 天
proxy_cache_valid 404 1m; # 404 缓存 1 分钟
proxy_cache_use_stale error timeout updating;
proxy_cache_background_update on;
proxy_cache_lock on;

💡 缓存机制

  • 200/302 响应缓存 1 天(86400 秒)
  • 404 响应缓存 1 分钟
  • 缓存过期后,若后端返回 200 则更新缓存

1.4 CORS跨域控制配置/etc/nginx/cors_params

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# /etc/nginx/cors_params
# 允许所有域名(CORS 配置)
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-SinceCache-Control,Content-Type,Authorization' always;

# 处理预检请求
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-WithIf-Modified-Since,Cache-Control,Content-Type,Authorization' always;
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}

💡 关键配置

  • always 参数确保响应头始终添加(避免缓存干扰)

2. 独立代理配置文件(/etc/nginx/conf.d/

✅ 2.1 HTTP 代理(http.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 仅处理特定域名的 HTTP 代理
server {
listen 80;
server_name api.example.com;

location / {
# 限流(白名单豁免)
if ($rate_limit_exempt != 1) {
limit_req zone=$rate_limit_zone burst=20 nodelay;
limit_req_status 429;
}
proxy_pass http://backend:8080; # Docker 服务名
include cache_params;
}
}

✅ 2.2 TCP代理(db.conf

1
2
3
4
5
6
7
8
9
10
11
    upstream mysql_backend {
server db:3306; # Docker 服务名
}

server {
listen 3306;
proxy_pass mysql_backend;
proxy_connect_timeout 1s; # TCP 连接超时
proxy_timeout 10s; # TCP 响应超时
}
}

✅ 2.3 维护界面(maintenance.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 仅对根路径生效(维护模式时重定向)
server {
# 维护模式开关
set $maintenance_mode off;

# 通过环境变量控制维护模式
if ($maintenance_mode = on) {
return 503;
}

# 维护页面配置
error_page 503 @maintenance;
location @maintenance {
# 静态维护页面
root /usr/share/nginx/html;
try_files /maintenance.html =503;

# 或者重定向到外部维护页面
# return 307 https://maintenance.example.com;
}

# API特殊处理(返回JSON)
location /api/ {
if ($maintenance_mode = on) {
add_header Content-Type application/json;
return 503 '{"status":503,"message":"系统维护中,请稍后再试"}';
}

proxy_pass http://backend-service:8080;
}
}

3. 安全配置文件(/etc/nginx/security/

✅ 3.1 限流控制(rate-limiting.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# /etc/nginx/security/rate-limiting.conf

# 限流区域定义
limit_req_zone $binary_remote_addr zone=global_limit:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=100r/s;
limit_req_zone $binary_remote_addr zone=login_limit:10m rate=3r/m;
limit_req_zone $binary_remote_addr zone=search_limit:10m rate=5r/s;
limit_req_zone $binary_remote_addr zone=static_limit:10m rate=500r/s;

# 基于请求URI的限流区域映射
map $request_uri $rate_limit_zone {
default global_limit;

# API接口
~*/api/v1/ api_limit;
~*/api/v2/ api_limit;

# 认证接口
~*/auth/login login_limit;
~*/oauth/token login_limit;
~*/user/login login_limit;

# 搜索接口
~*/search search_limit;
~*/query search_limit;
~*/find search_limit;

# 静态资源
~*\.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ static_limit;

# 管理接口
~*/admin/ global_limit;
~*/system/ global_limit;
}

# 白名单不限流
map $whitelist_ip $rate_limit_exempt {
0 0;
1 1;
}

# 连接数限制
limit_conn per_ip 10;
limit_conn per_server 1000;

✅ 3.2 黑白名单控制(blacklist.confwhitelist.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# /etc/nginx/security/blacklist.conf

# 全局黑名单设置
geo $blacklist_ip {
default 0;

# 动态黑名单(从文件读取)
include /etc/nginx/security/blacklist.ip;

# 静态黑名单
10.0.0.0/8 1;
192.168.1.100 1;
172.16.0.0/12 1;
}

# /etc/nginx/security/whitelist.conf
# 全局白名单设置
geo $whitelist_ip {
default 0;

# 动态白名单(从文件读取)
include /etc/nginx/security/whitelist.ip;

# 静态白名单
10.0.0.0/8 1;
192.168.1.100 1;
172.16.0.0/12 1;
}

# API白名单路径
map $request_uri $whitelist_path {
default 0;

# 健康检查
/health 1;
/status 1;
/ping 1;

# 监控
/metrics 1;
/nginx-status 1;

# 静态资源
~*\.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot|mp4|webm|mp3)$ 1;

# 公开API
/api/v1/public/ 1;
/api/v1/docs 1;
/swagger-ui 1;

# 机器人协议
/robots.txt 1;
/sitemap.xml 1;
/favicon.ico 1;
}
1
2
3
4
5
6
7
8
9
10
# /etc/nginx/security/blacklist.ip(whitelist.ip)

# 格式:IP/CIDR 标志值;
# 可以通过脚本动态更新

# 恶意IP示例
203.0.113.1 1;
198.51.100.0/24 1;
10.20.30.40 1;

✅ 3.3 综合安全控制(blacklist.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# security/security-rules.conf


# 恶意User-Agent检测
map $http_user_agent $bad_bot {
default 0;

# 已知恶意爬虫
~*(ahrefs|mj12bot|semrushbot|masscan) 1;
~*(sqlmap|nmap|nikto|dirbuster) 1;
~*(nessus|openvas|acunetix|nessus) 1;

# 垃圾机器人
~*(spammer|scraper|harvest|collector) 1;

# 可疑模式
~*[0-9]{10}bot 1;
~*bot[0-9]{10} 1;
"" 1;

# 允许的友好爬虫
~*(baiduspider|googlebot|bingbot|yandexbot|duckduckbot) 0;
~*(slurp|twitterbot|facebookexternalhit|linkedinbot) 0;

# 正常浏览器和工具
~*(Mozilla|Chrome|Safari|Firefox|Edge|Opera) 0;
~*(curl|wget|python-requests|PostmanRuntime) 0;
}

# 恶意请求检测
map $request_uri $bad_request {
default 0;

# 路径遍历
~*(\.\./|\.\.\\|/%2e%2e|/%252e%252e) 1;

# 敏感文件
~*(/etc/passwd|/etc/shadow|/proc/self|/etc/hosts) 1;
~*(\.git/|\.svn/|\.hg/|\.bzr/|\.DS_Store) 1;
~*(\.env|config\.php|settings\.py|web\.config) 1;

# 管理后台
~*(phpmyadmin|adminer|wp-admin|/admin/login|/manager/html) 1;

# SQL注入模式
~*(union\s+select.*from) 1;
~*(sleep\(|benchmark\(|waitfor\s+delay) 1;
~*(load_file\(|into\s+outfile|into\s+dumpfile) 1;
~*(select\s+.*from.*where.*=.*\() 1;

# XSS攻击
~*(<script|javascript:|onload=|onerror=|alert\(|confirm\(|prompt\() 1;

# 命令注入
~*(\|\s*sh|\|\s*bash|\|\s*cmd|\;\s*rm\s+|\;\s*wget\s+) 1;

# 可疑文件
~*\.(asp|aspx|jsp|php|pl|py|sh|cgi|exe|dll|bat|cmd)$ 1;

# 扫描特征
~*(/w00tw00t|test.cgi|xmlrpc.php|/vendor/phpunit) 1;
}

# 错误页面映射
map $block_reason $block_error_page {
default /errors/403.html;
"blacklist_ip" /errors/403.html;
"bad_bot" /errors/444.html;
"bad_request" /errors/403.html;
"rate_limit" /errors/429.html;
"whitelist_only" /errors/403.html;
}

# 访问控制决策
map "$whitelist_ip:$maintenance_mode" $access_allowed {
# 规则优先级:白名单 > 维护模式

# 1. 白名单IP直接允许(即使维护模式)
"~^1:.+" 1;
# 2. 其他情况拒绝
default 0;
}

# 维护模式检测
map $maintenance_mode $is_maintenance {
default 0;
"on" 1;
"yes" 1;
"true" 1;
"1" 1;
}

✅ 3.4 安全检查(security-checks.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# security/security-checks.conf

# 初始化阻塞原因
set $block_reason "";
set $block_access 0;

# 1. 白名单路径检查(直接通过)
if ($whitelist_path = 1) {
set $block_access 0;
return 200; # 继续处理请求,但标记为不阻止
}

# 2. 访问控制决策
if ($access_allowed = 0) {
set $block_access 1;

if ($whitelist_ip = 0) {
set $block_reason "whitelist_only";
}

if ($maintenance_mode = "on" && $whitelist_ip = 0) {
set $block_reason "maintenance_mode";
return 503;
}
}

# 3. 黑名单检查(白名单可以覆盖)
if ($whitelist_ip != 1) {
if ($blacklist_ip = 1) {
set $block_access 1;
set $block_reason "blacklist_ip";
access_log /var/log/nginx/blocked.log security;
return 403;
}
}

# 4. 恶意User-Agent检查
if ($bad_bot = 1) {
set $block_access 1;
set $block_reason "bad_bot";
access_log /var/log/nginx/bad_bots.log combined;
return 444;
}

# 5. 恶意请求检查
if ($bad_request = 1) {
set $block_access 1;
set $block_reason "bad_request";
access_log /var/log/nginx/attack.log combined;
return 403;
}

🐳 Docker 部署关键配置

1. docker-compose.yml 示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# docker-compose.yml
version: '3.8'

services:
nginx:
build: .
container_name: nginx-proxy
restart: unless-stopped
ports:
- "80:80"
- "443:443"
environment:
- NGINX_ENV=production
- BACKEND_SERVICE=backend:8080
- MAINTENANCE_MODE=${MAINTENANCE_MODE:-off}
- API_KEY_WHITELIST=${API_KEY_WHITELIST:-}
- INTERNAL_NETWORK=172.16.0.0/12
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./conf.d:/etc/nginx/conf.d:ro
- ./security:/etc/nginx/security:ro
- ./templates:/etc/nginx/templates:ro
- ./ssl:/etc/nginx/ssl:ro
- ./html:/usr/share/nginx/html:ro
- ./logs:/var/log/nginx
- ./scripts:/scripts:ro
- dynamic_data:/etc/nginx/dynamic
networks:
- proxy-network
healthcheck:
test: ["CMD", "/scripts/health-check.sh"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"

backend:
image: ${BACKEND_IMAGE:-your-backend:latest}
container_name: backend-app
restart: unless-stopped
environment:
- VIRTUAL_HOST=app.example.com
- VIRTUAL_PORT=8080
networks:
- proxy-network
expose:
- "8080"

networks:
proxy-network:
driver: bridge
ipam:
config:
- subnet: 172.16.0.0/12

volumes:
dynamic_data:

2. nginx容器Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# Dockerfile
FROM nginx:1.24-alpine

# 安装必要工具
RUN apk add --no-cache \
curl \
jq \
certbot \
certbot-nginx \
bash \
gettext \
openssl \
geoip \
geoip-dev \
libmaxminddb \
libmaxminddb-dev \
&& rm -rf /var/cache/apk/*

# 安装nginx模块
RUN apk add --no-cache nginx-mod-http-geoip2

# 创建目录结构
RUN mkdir -p \
/etc/nginx/security \
/etc/nginx/dynamic \
/etc/nginx/templates \
/usr/share/nginx/html/errors \
/scripts \
/var/log/nginx/audit

# 复制配置文件
COPY nginx.conf /etc/nginx/
COPY conf.d/ /etc/nginx/conf.d/
COPY security/ /etc/nginx/security/
COPY templates/ /etc/nginx/templates/
COPY ssl/ /etc/nginx/ssl/
COPY html/ /usr/share/nginx/html/
COPY scripts/ /scripts/

# 设置权限
RUN chmod +x /scripts/*.sh \
&& chown -R nginx:nginx /var/log/nginx \
&& chmod 600 /etc/nginx/security/.htpasswd \
&& chmod 644 /etc/nginx/security/*.map \
&& chmod 755 /etc/nginx/dynamic

# 生成SSL证书(如果不存在)
RUN if [ ! -f /etc/nginx/ssl/cert.pem ]; then \
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/nginx/ssl/key.pem \
-out /etc/nginx/ssl/cert.pem \
-subj "/C=CN/ST=State/L=City/O=Organization/CN=localhost"; \
fi

# 生成强DH参数
RUN if [ ! -f /etc/nginx/ssl/dhparam.pem ]; then \
openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048; \
fi

# 健康检查
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD /scripts/health-check.sh

# 启动脚本
ENTRYPOINT ["/scripts/entrypoint.sh"]

🛠️ 生产环境验证建议

  1. 测试跨域

    1
    curl -H "Origin: https://frontend.example.com" -X OPTIONS http://api.example.com/api/test

    应返回 204 No Content 且包含 CORS 头

  2. 测试维护模式

    1
    2
    3
    4
    5
    6
    # 启用维护
    export MAINTENANCE_MODE=on


    # 访问应返回 503
    curl -I http://example.com
  3. 测试缓存

    1
    2
    3
    4
    5
    # 第一次请求(应返回 200)
    curl -I http://api.example.com/api/data

    # 第二次请求(应返回 200 from cache)
    curl -I http://api.example.com/api/data

✅ 总结

功能 位置 作用范围 Docker 适配关键点
TCP 代理 nginx.conf (stream) 全局 独立于 HTTP,端口映射 3306:3306
上传大小/超时 nginx.conf (http) 全局 全局生效,避免重复配置
HTTP 代理 http_proxy.conf 按域名生效 通过 Docker 网络解析服务名
跨域控制 cors.conf /api/ always 参数确保头始终添加
接口缓存 cache.conf /api/ 缓存路径挂载到主机,避免容器重启丢失
维护界面 maintenance.conf 仅根路径 通过文件开关,无需重启 Nginx

💡 为什么这样设计?

  1. 全局配置:TCP 和基础参数(上传/超时)放在全局,避免重复且易于全局调整
  2. 独立文件:每个功能模块独立配置,符合“单一职责原则”
  3. Docker 适配
    • 所有挂载路径(/var/cache/nginx, /var/www/maintenance)在主机定义
    • 服务名通过 Docker 网络自动解析(backend:8080
    • 维护模式通过文件开关,无需修改 Nginx 配置
0%