使用反向代理的理解

在浏览器中访问一个资源时,通常需要知道提供该资源的服务器IP地址和服务的端口号。然而,直接使用IP地址和端口号访问资源不仅不友好,而且难以记忆。例如,访问 http://example.com:8080 这样的URL不仅不美观,用户体验也较差。为了解决这个问题,我们可以使用域名来指向服务器,但端口号的问题依然存在。

目标:让用户仅通过域名访问资源,而无需关心端口号。端口号的问题由服务器端自行处理。

为此,我们可以使用反向代理或Cloudflare的Origin Rules来优雅地解决端口问题。以下是优化后的解决方案和详细说明。


解决方案一:反向代理

什么是反向代理?

**反向代理(Reverse Proxy)**是一种服务器架构模式,它位于客户端和目标服务器之间,接收客户端的请求,并将请求转发到后端的目标服务器。通过这种方式,客户端只需要知道反向代理服务器的地址(通常是域名),而无需关心后端服务器的具体IP和端口。

反向代理的工作流程

  1. 客户端请求
    • 用户在浏览器中输入 http://example.com,请求访问某个资源。
  2. DNS解析
    • DNS服务器将 example.com 解析为反向代理服务器的IP地址。
  3. 反向代理接收请求
    • 反向代理服务器接收到客户端的请求。
  4. 请求转发
    • 反向代理根据配置将请求转发到后端的目标服务器(例如 http://localhost:8080)。
  5. 响应返回
    • 目标服务器处理请求并返回响应,反向代理再将响应返回给客户端。

![nginx.png][1]

反向代理的优点

  • 隐藏后端服务器的真实IP地址和端口号,增强安全性。
  • 支持负载均衡和复杂的请求路由。
  • 提高用户体验,用户只需记住域名即可访问资源。

反向代理的缺点

  • 需要自行搭建和管理反向代理服务器(如Nginx或Caddy),维护成本较高。

解决方案二:Cloudflare Origin Rules

什么是Cloudflare Origin Rules?

Cloudflare Origin Rules 是Cloudflare提供的一种功能,允许你自定义流量如何从Cloudflare的边缘节点转发到你的源服务器。通过Origin Rules,你可以灵活地修改请求的目标地址、端口和协议,而无需用户在URL中指定端口号。

Cloudflare Origin Rules的功能

  1. 修改请求的目标地址
    • 例如,将 example.com 的请求转发到 origin.example.com192.168.1.1:8080
    • 这类似于反向代理的功能,可以隐藏源服务器的真实地址。
  2. 修改端口
    • 如果源服务器运行在非标准端口(如 8080),可以通过Origin Rules将流量转发到该端口,而用户无需在URL中指定端口。
  3. 修改协议
    • 例如,将HTTP请求转发到HTTPS源服务器,或者反之。
  4. 基于条件转发
    • 根据请求的域名、路径、地理位置等条件,将流量转发到不同的源服务器。

使用Cloudflare Origin Rules隐藏服务器IP和端口

假设你的源服务器运行在 192.168.1.1:8080,你希望通过Cloudflare隐藏源服务器的真实地址和端口,用户只需访问 https://example.com

  1. 在Cloudflare中设置DNS
    • example.com 的DNS记录指向Cloudflare的IP地址(启用橙色云图标)。
  2. 配置Origin Rules
    • 在Cloudflare控制台中,进入 Rules > Origin Rules
    • 创建一个规则,将 example.com 的请求转发到 192.168.1.1:8080
    • 例如:
      • 规则条件Hostname 等于 example.com
      • 操作:设置目标端口为 8080
  3. 结果
    • 用户访问 https://example.com,Cloudflare会将请求转发到 192.168.1.1:8080,而用户无需知道源服务器的真实地址和端口。

Cloudflare Origin Rules的优点

  • 无需自行搭建和管理服务器,管理更简单。
  • 集成Cloudflare的其他功能(如CDN、安全防护等),提升性能和安全性。

Cloudflare Origin Rules的缺点

  • 功能相对有限,可能无法满足复杂的路由需求。
  • 依赖Cloudflare的服务,可能受限于其定价和服务条款。

反向代理与Cloudflare Origin Rules的比较

方案 优点 缺点
反向代理 - 支持复杂路由和负载均衡
- 灵活性高
- 需要自行搭建和管理服务器
- 维护成本较高
Cloudflare Origin Rules - 无需搭建服务器,管理简单
- 集成其他功能
- 功能相对有限
- 依赖Cloudflare服务

总结

反向代理和Cloudflare Origin Rules都是隐藏服务器IP地址和端口号的有效方法,解决了用户直接访问IP和端口带来的不便。

  • 如果你需要更灵活的路由和负载均衡功能,推荐使用反向代理(如Nginx或Caddy)。
  • 如果你希望简化管理和利用Cloudflare的CDN和安全功能,推荐使用Cloudflare Origin Rules。

根据你的具体需求和资源,选择适合的方案即可。
[1]: https://images.228610.xyz/2025/03/c5507a9581655a9c071d2e81376fdb45.webp

源服务器证书与边缘证书

问题背景:

我在nginx中添加的是源服务器证书,但是网站证书有效期显示的是边缘证书3个月,而不是源服务器证书的15年


1. 源服务器证书和边缘证书的关系

源服务器证书

  • 定义:源服务器证书是安装在你的服务器(Nginx)上的 SSL 证书,用于加密 Cloudflare 和你的服务器之间的通信。
  • 作用:确保 Cloudflare 和你的服务器之间的数据传输是加密的。
  • 有效期:你提到源服务器证书的有效期是 15 年,这可能是你手动生成的自签名证书或从其他证书颁发机构(CA)获取的证书。

边缘证书

  • 定义:边缘证书是 Cloudflare 提供的 SSL 证书,用于加密用户浏览器和 Cloudflare 之间的通信。
  • 作用:确保用户浏览器和 Cloudflare 之间的数据传输是加密的。
  • 有效期:Cloudflare 的边缘证书通常是自动管理的,有效期较短(通常为 3 个月),但 Cloudflare 会自动续期,因此你不需要手动管理。

关系

  • 用户浏览器 ↔ 边缘证书 ↔ Cloudflare ↔ 源服务器证书 ↔ 你的服务器
  • 用户浏览器和 Cloudflare 之间的通信使用 边缘证书
  • Cloudflare 和你的服务器之间的通信使用 源服务器证书

2. 为什么网站证书有效期显示为 3 个月?

当你通过浏览器访问网站时,浏览器检查的是 边缘证书(即 Cloudflare 提供的证书),而不是你的源服务器证书。因此,浏览器显示的证书有效期是 Cloudflare 边缘证书的有效期,通常是 3 个月。

原因

  • Cloudflare 的边缘证书是自动管理的,有效期较短(3 个月),但 Cloudflare 会自动续期。
  • 这种设计是为了提高安全性,因为短有效期的证书可以减少证书泄露的风险。

3. 如何验证源服务器证书的有效期?

如果你想验证源服务器证书的有效期(15 年),可以通过以下方式:

方法 1:直接连接到源服务器

  • 使用 openssl 命令连接到你的源服务器,查看证书信息:

    1
    openssl s_client -connect your-server-ip:443 -servername dashboard.maka.us.kg
  • 在输出中查找证书的有效期。

方法 2:通过 Cloudflare 的“源服务器”设置

  • 登录 Cloudflare 控制台,进入 SSL/TLS源服务器
  • 查看你上传的源服务器证书信息,确认其有效期。

4. 如何确保源服务器证书正确配置?

步骤 1:生成或获取源服务器证书

  • 如果你使用的是自签名证书,可以使用以下命令生成:

    1
    openssl req -x509 -newkey rsa:2048 -keyout privkey.pem -out fullchain.pem -days 5475 -nodes -subj "/CN=dashboard.maka.us.kg"
    • -days 5475 表示 15 年有效期。
  • 如果你使用的是 Let’s Encrypt 或其他 CA 的证书,确保证书文件(fullchain.pemprivkey.pem)已正确生成。

步骤 2:配置 Nginx

  • 在 Nginx 配置中指定源服务器证书的路径:

    1
    2
    ssl_certificate /www/sites/dashboard.maka.us.kg/ssl/fullchain.pem;
    ssl_certificate_key /www/sites/dashboard.maka.us.kg/ssl/privkey.pem;

步骤 3:测试配置

  • 使用 nginx -t 测试配置是否正确:

    1
    nginx -t
  • 重启 Nginx 以应用配置:

    1
    systemctl restart nginx

步骤 4:验证源服务器证书

  • 使用 openssl 命令验证源服务器证书是否生效:

    1
    openssl s_client -connect your-server-ip:443 -servername dashboard.maka.us.kg

5. 总结

  • 源服务器证书 用于加密 Cloudflare 和你的服务器之间的通信。
  • 边缘证书 用于加密用户浏览器和 Cloudflare 之间的通信。
  • 浏览器显示的证书有效期是 Cloudflare 边缘证书的有效期(3 个月),而不是源服务器证书的有效期(15 年)。

socat 入门指南:快速搭建 TCP和UDP 中转服务

Socat 是一个强大的命令行工具,用于在两个数据流之间建立连接。它不仅可以用于代理流量,还可以转发任何类型的网络流量,包括 TCP、UDP、SSL 等。

安装 socat

1
apt install socat -y

启动中转服务

基本用法

Socat 的基本语法如下:

1
socat <协议>-LISTEN:<监听端口>,fork <协议>:<目的主机IP>:<端口>

例如,以下命令将监听本地的 UDP 端口 59823,并将所有接收到的数据转发到 213.4.2.359823 端口:

1
socat UDP4-LISTEN:59823,fork UDP:213.4.2.3:59823
  • UDP4-LISTEN:59823:表示 socat 将在本地监听 UDP 端口 59823
  • fork:表示 socat 将为每个连接创建一个新的子进程,允许多个客户端同时连接。
  • UDP:213.4.2.3:59823:表示 socat 将把所有接收到的数据转发到 213.4.2.359823 端口。

后台运行

默认情况下,socat 会阻塞当前终端会话。如果希望 socat 在后台运行,可以在命令末尾添加 & 符号:

1
socat UDP4-LISTEN:59823,fork UDP:213.4.2.3:59823 &

使用 nohup 防止进程终止

如果希望在关闭终端后 socat 仍然运行,可以使用 nohup 命令:

1
nohup socat UDP4-LISTEN:59823,fork UDP4:213.4.2.3:59823 >/dev/null 2>&1 &
  • nohup:防止进程因终端关闭而终止。
  • >/dev/null 2>&1:将输出重定向到 /dev/null,避免生成日志文件。

优化端口绑定

可以使用 reuseaddr 参数来优化端口绑定,防止端口被占用:

1
nohup socat UDP4-LISTEN:59823,reuseaddr,fork UDP4:213.4.2.3:59823 >/dev/null 2>&1 &
  • reuseaddr:允许 socat 在端口被占用时重新绑定。

终止所有 socat 进程

如果需要终止所有 socat 进程,可以使用以下命令:

1
2
3
4
5
# 查找所有 socat 进程的 PID
pgrep socat

# 终止所有相关进程
sudo kill -9 $(pgrep socat)

使用 systemd 托管服务(推荐)

为了更方便地管理 socat 服务,可以使用 systemd 来托管服务。

创建 systemd 服务文件

创建文件 /etc/systemd/system/socat-udp.service,内容如下:

1
2
3
4
5
6
7
8
9
10
11
[Unit]
Description=Socat UDP Forwarding
After=network.target

[Service]
ExecStart=/usr/bin/socat UDP4-LISTEN:59823,reuseaddr UDP4:213.136.83.240:59823
Restart=on-failure
User=root

[Install]
WantedBy=multi-user.target
  • ExecStart:指定 socat 启动命令。
  • Restart=on-failure:在服务失败时自动重启。
  • User=root:以 root 用户身份运行服务。

启用并启动服务

1
2
3
sudo systemctl daemon-reload
sudo systemctl start socat-udp
sudo systemctl enable socat-udp
  • daemon-reload:重新加载 systemd 配置。
  • start:启动服务。
  • enable:设置服务开机自启。

检查服务状态

1
sudo systemctl status socat-udp

删除服务

如果需要删除 socat 服务,可以按照以下步骤操作:

停止并禁用服务

1
2
3
4
5
# 停止服务
sudo systemctl stop socat-udp

# 禁用开机自启
sudo systemctl disable socat-udp

删除服务文件

1
sudo rm /etc/systemd/system/socat-udp.service

重新加载 systemd 配置

1
sudo systemctl daemon-reload

验证服务是否已删除

1
2
3
4
5
# 检查服务状态(预期输出 "not found")
systemctl status socat-udp

# 确认服务文件已删除
ls /etc/systemd/system/socat-udp.service

额外清理(可选)

  1. 终止残留进程:
1
2
3
4
5
# 查找进程 PID
pgrep socat

# 终止进程
sudo kill -9 <PID>
  1. 清理日志:
1
2
3
4
5
# 查看服务日志
journalctl -u socat-udp

# 清理日志(谨慎操作)
sudo journalctl --vacuum-time=1d # 保留最近 1 天的日志
  1. 删除专用用户/组(如有):
1
2
sudo userdel <用户名>
sudo groupdel <组名>

使用场景:通过 socat 转发本地 SSH 流量

背景

假设你有一台远程服务器(IP 为 203.0.113.1),它运行着 SSH 服务,监听端口 22。然而,由于某些原因(比如防火墙限制),你无法直接通过 203.0.113.1:22 访问这台服务器。你有一台中转服务器(IP 为 198.51.100.1),它可以直接访问目标服务器。现在,你希望通过中转服务器将本地机器的 SSH 流量转发到目标服务器。

目标

  • 在本地机器上,通过访问中转服务器的某个端口(例如 2222),间接连接到目标服务器的 SSH 服务(203.0.113.1:22)。

步骤

1. 在中转服务器上安装 socat

首先,在中转服务器(198.51.100.1)上安装 socat

1
2
sudo apt update
sudo apt install socat -y

2. 在中转服务器上启动 socat 转发服务

在中转服务器上运行以下命令,将本地端口 2222 的流量转发到目标服务器的 22 端口:

1
socat TCP4-LISTEN:2222,fork TCP:203.0.113.1:22
  • TCP4-LISTEN:2222:在中转服务器上监听 TCP 端口 2222
  • fork:允许多个客户端同时连接。
  • TCP:203.0.113.1:22:将流量转发到目标服务器的 22 端口。

3. 在本地机器上通过中转服务器连接目标服务器

现在,你可以在本地机器上通过中转服务器的 2222 端口连接到目标服务器的 SSH 服务:

1
ssh -p 2222 user@198.51.100.1
  • -p 2222:指定连接中转服务器的 2222 端口。
  • user@198.51.100.1:使用中转服务器的 IP 地址和用户名。

4. 验证连接

如果一切正常,你会通过中转服务器成功连接到目标服务器的 SSH 服务。


关键名词解释

  1. TCP4-LISTEN

    • 表示 socat 监听一个 TCP 端口。
    • 例如:TCP4-LISTEN:2222 表示监听本地的 2222 端口。
  2. fork

    • 允许多个客户端同时连接到监听端口。
    • 如果没有 forksocat 只能处理一个连接,后续连接会被拒绝。
  3. TCP:<目标IP>:<目标端口>

    • 表示将流量转发到指定的目标 IP 和端口。
    • 例如:TCP:203.0.113.1:22 表示将流量转发到 203.0.113.122 端口。
  4. nohup

    • 防止进程因终端关闭而终止。
    • 例如:nohup socat ... & 可以让 socat 在后台运行,即使关闭终端也不会停止。
  5. reuseaddr

    • 允许 socat 在端口被占用时重新绑定。
    • 例如:TCP4-LISTEN:2222,reuseaddr 可以避免端口冲突。

进阶:使用 systemd 托管 socat 服务

如果你希望 socat 服务在中转服务器上长期运行,可以使用 systemd 托管服务。

1. 创建 systemd 服务文件

在中转服务器上创建文件 /etc/systemd/system/socat-ssh.service,内容如下:

1
2
3
4
5
6
7
8
9
10
11
[Unit]
Description=Socat SSH Forwarding
After=network.target

[Service]
ExecStart=/usr/bin/socat TCP-LISTEN:2222,reuseaddr,fork TCP:203.0.113.1:22
Restart=on-failure
User=root

[Install]
WantedBy=multi-user.target

2. 启用并启动服务

运行以下命令启用并启动服务:

1
2
3
sudo systemctl daemon-reload
sudo systemctl start socat-ssh
sudo systemctl enable socat-ssh

3. 检查服务状态

运行以下命令检查服务状态:

1
sudo systemctl status socat-ssh

总结

Socat非常适合简单的 TCP/UDP 流量转发和调试,如作为中转节点转发流量。担并不能担任反向代理,对于复杂Web 流量或高并发场景,socat并不适用,需要使用NginxCaddy

相关链接:

  1. Caddy 基本使用指南
  2. Nginx 安装与基本使用指南

vscode C++环境搭建

C++插件:

  1. 快速生成类,快捷键:Alt+X

    1
    C++ Class Creator
  2. 代码格式化,快捷键:shift+alt+f

    1
    Clang-Format
  3. 使用clangd索引

    1
    clangd
  4. CMake Tools

  5. 快速生成文档

    1
    Doxygen Documentation Generator
  6. Makefile Tools

  7. C/C++ 用于配置clang-tidy,只使用其调试和clang-tidy功能,下面的settings配置默认关闭其自动生成函数定义功能

  8. 快速生成if,for,switch,try等结构

    1
    C/C++ Snippets
  9. C/C++ Include Guard

其他插件:

  1. JetBrains Darcula Theme:主题(推荐),电脑需要安装jetbrains字体, JetBrains Mono 字体下载页面
  2. JetBrains Icon Theme:图标(推荐)
  3. JetBrains IDE Keymap(推荐)
  4. Remote - SSH:远程连接(推荐)
  5. Todo Tree ,设置TODO,NOTE等标签 (推荐)
  6. GitHub Copilot

本地settings.json

其中一些软件地址需要自行修改,注意使用,防止与自己之前的配置冲突或覆盖

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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
{
"editor.fontFamily": "'JetBrains Mono', Consolas, 'Courier New', monospace",
"editor.fontSize": 16,
"workbench.colorTheme": "JetBrains Darcula Theme",
"workbench.iconTheme": "vscode-jetbrains-icon-theme",
"cmake.pinnedCommands": [
"workbench.action.tasks.configureTaskRunner",
"workbench.action.tasks.runTask"
],
"files.autoSave": "afterDelay",
"github.copilot.enable": {
"*": true,
"plaintext": false,
"markdown": false,
"scminput": false
},
"update.mode": "start",
"redhat.telemetry.enabled": false,
"cmake.showConfigureWithDebuggerNotification": false,
// 解决cmake输出中文乱码问题
"files.encoding": "utf8",
"cmake.outputLogEncoding": "UTF-8",
//解决终端乱码问题
// "terminal.integrated.profiles.windows": {
// "PowerShell": {
// "source": "PowerShell",
// "args": [
// "-NoExit",
// "-Command",
// "chcp 65001"
// ]
// },
// "Command Prompt": {
// "path": "C:\\Windows\\System32\\cmd.exe",
// "args": [
// "/K",
// "chcp 65001"
// ]
// }
// },
"terminal.integrated.defaultProfile.windows": "PowerShell", //默认打开终端为PowerShell
"clangd.detectExtensionConflicts": false,
"git.openRepositoryInParentFolders": "always",
"security.workspace.trust.enabled": false,
"security.workspace.trust.emptyWindow": false,
"[cpp]": {
"editor.defaultFormatter": "xaver.clang-format"
},
"clang-format.executable": "D:/clang-format/clang-format.exe",
"clang-format.fallbackStyle": "None",
"clang-format.language.apex.fallbackStyle": "None",
"clang-format.language.apex.style": "None",
"clangd.path": "D:/clangd_18.1.3/bin/clangd.exe",
"editor.quickSuggestionsDelay": 0,
"workbench.startupEditor": "none",
"explorer.autoReveal": false,
"editor.cursorStyle": "block",
"C_Cpp.intelliSenseEngine": "disabled",//会跟clangd冲突,启用后代码提示会变慢,不开启的话无法使用自动生成函数定义功能
"C_Cpp.codeAnalysis.runAutomatically": true,
"C_Cpp.configurationWarnings": "disabled",
"C_Cpp.codeFolding": "disabled",
"C_Cpp.formatting": "clangFormat",
"C_Cpp.codeAnalysis.clangTidy.enabled": true,
"C_Cpp.autocomplete": "disabled",//应该是关闭代码补全提示,使用clangd即可
"C_Cpp.default.cppStandard": "c++17",
"C_Cpp.default.cStandard": "c17",
"C_Cpp.enhancedColorization": "enabled",
"C_Cpp.codeAnalysis.clangTidy.useBuildPath": true,
"C_Cpp.default.compileCommands": "${workspaceFolder}/build/compile_commands.json",
"C_Cpp.codeAnalysis.clangTidy.config": "${workspaceFolder}/.clang-tidy",
//todo-tree
"todo-tree.highlights.defaultHighlight": {
"icon": "alert",
"type": "tag",
"background": "#e8cd37", // 高亮背景颜色
"color": "#000000", // 字体颜色
"fontWeight": "bold"
},
"todo-tree.regex.regex": "(TODO|FIXME|NOTE)", // 正则表达式,用于匹配关键字
"todo-tree.general.tags": [
"TODO",
"FIXME",
"NOTE"
], // 自定义标签
"todo-tree.highlights.customHighlight": {
"TODO": {
"icon": "check",
"background": "#e65a30",
"color": "#FFFFFF",
"fontWeight": "bold"
},
"FIXME": {
"icon": "bug",
"background": "#ed2e6e",
"color": "#FFFFFF",
"fontWeight": "bold"
},
"NOTE": {
"icon": "info",
"background": "#2596f2",
"color": "#FFFFFF",
"fontWeight": "bold"
}
},
"todo-tree.tree.autoRefresh": true, // 自动刷新
"todo-tree.general.rootFolder": "${workspaceFolder}",
"todo-tree.filtering.includeGlobs": [
"**/*" // Include only files in the current workspace
],
"todo-tree.filtering.excludeGlobs": [
"**/build/**",
"**/bin/**",
"**/.cache/**",
"**/.vscode/**",
"**/.git/**",
],
"todo-tree.tree.scanMode": "workspace",
"git.enableSmartCommit": true,
"editor.unicodeHighlight.invisibleCharacters": false,
"editor.unicodeHighlight.ambiguousCharacters": false,
"makefile.configureOnOpen": false,
"workbench.editor.limit.enabled": true,
"workbench.editor.limit.value": 8,
"workbench.tree.renderIndentGuides": "always",
"workbench.tree.expandMode": "doubleClick",
"window.commandCenter": false,
"github.copilot.selectedCompletionModel": "gpt-4o-copilot",
"editor.accessibilitySupport": "off",
}

远程settings.json

其中一些软件地址需要自行修改,注意使用,防止与自己之前的配置冲突或覆盖

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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
{
"editor.fontFamily": "'JetBrains Mono', Consolas, 'Courier New', monospace",
"editor.fontSize": 16,
"workbench.colorTheme": "JetBrains Darcula Theme",
"workbench.iconTheme": "vscode-jetbrains-icon-theme",
"cmake.pinnedCommands": [
"workbench.action.tasks.configureTaskRunner",
"workbench.action.tasks.runTask"
],
"files.autoSave": "afterDelay",
"github.copilot.enable": {
"*": true,
"plaintext": false,
"markdown": false,
"scminput": false
},
"update.mode": "start",
"redhat.telemetry.enabled": false,
"cmake.showConfigureWithDebuggerNotification": false,
// 解决cmake输出中文乱码问题
"files.encoding": "utf8",
"cmake.outputLogEncoding": "UTF-8",
//解决终端乱码问题
// "terminal.integrated.profiles.windows": {
// "PowerShell": {
// "source": "PowerShell",
// "args": [
// "-NoExit",
// "-Command",
// "chcp 65001"
// ]
// },
// "Command Prompt": {
// "path": "C:\\Windows\\System32\\cmd.exe",
// "args": [
// "/K",
// "chcp 65001"
// ]
// }
// },
"terminal.integrated.defaultProfile.windows": "PowerShell", //默认打开终端为PowerShell
"clangd.detectExtensionConflicts": false,
"git.openRepositoryInParentFolders": "always",
"security.workspace.trust.enabled": false,
"security.workspace.trust.emptyWindow": false,
"[cpp]": {
"editor.defaultFormatter": "xaver.clang-format"
},
"clang-format.executable": "D:/clang-format/clang-format.exe",
"clang-format.fallbackStyle": "None",
"clang-format.language.apex.fallbackStyle": "None",
"clang-format.language.apex.style": "None",
"clangd.path": "D:/clangd_18.1.3/bin/clangd.exe",
"editor.quickSuggestionsDelay": 0,
"workbench.startupEditor": "none",
"explorer.autoReveal": false,
"editor.cursorStyle": "block",
"C_Cpp.intelliSenseEngine": "disabled",//会跟clangd冲突,启用后代码提示会变慢,不开启的话无法使用自动生成函数定义功能
"C_Cpp.codeAnalysis.runAutomatically": true,
"C_Cpp.configurationWarnings": "disabled",
"C_Cpp.codeFolding": "disabled",
"C_Cpp.formatting": "clangFormat",
"C_Cpp.codeAnalysis.clangTidy.enabled": true,
"C_Cpp.autocomplete": "disabled",
"C_Cpp.default.cppStandard": "c++17",
"C_Cpp.default.cStandard": "c17",
"C_Cpp.enhancedColorization": "enabled",
"C_Cpp.codeAnalysis.clangTidy.useBuildPath": true,
"C_Cpp.default.compileCommands": "${workspaceFolder}/build/compile_commands.json",
"C_Cpp.codeAnalysis.clangTidy.config": "${workspaceFolder}/.clang-tidy",
//todo-tree
"todo-tree.highlights.defaultHighlight": {
"icon": "alert",
"type": "tag",
"background": "#e8cd37", // 高亮背景颜色
"color": "#000000", // 字体颜色
"fontWeight": "bold"
},
"todo-tree.regex.regex": "(TODO|FIXME|NOTE)", // 正则表达式,用于匹配关键字
"todo-tree.general.tags": [
"TODO",
"FIXME",
"NOTE"
], // 自定义标签
"todo-tree.highlights.customHighlight": {
"TODO": {
"icon": "check",
"background": "#e65a30",
"color": "#FFFFFF",
"fontWeight": "bold"
},
"FIXME": {
"icon": "bug",
"background": "#ed2e6e",
"color": "#FFFFFF",
"fontWeight": "bold"
},
"NOTE": {
"icon": "info",
"background": "#2596f2",
"color": "#FFFFFF",
"fontWeight": "bold"
}
},
"todo-tree.tree.autoRefresh": true, // 自动刷新
"todo-tree.general.rootFolder": "${workspaceFolder}",
"todo-tree.filtering.includeGlobs": [
"**/*" // Include only files in the current workspace
],
"todo-tree.filtering.excludeGlobs": [
"**/build/**",
"**/bin/**",
"**/.cache/**",
"**/.vscode/**",
"**/.git/**",
],
"todo-tree.tree.scanMode": "workspace",
"git.enableSmartCommit": true,
"editor.unicodeHighlight.invisibleCharacters": false,
"editor.unicodeHighlight.ambiguousCharacters": false,
"makefile.configureOnOpen": false,
"workbench.editor.limit.enabled": true,
"workbench.editor.limit.value": 8,
"workbench.tree.renderIndentGuides": "always",
"workbench.tree.expandMode": "doubleClick",
"window.commandCenter": false,
"github.copilot.selectedCompletionModel": "gpt-4o-copilot",
}

.clang-tidy

这是在网上找的clion默认的clang-tidy文件

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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
---
Checks: >
clang-diagnostic-*,
clang-analyzer-*,
-*,
bugprone-argument-comment,
bugprone-assert-side-effect,
bugprone-bad-signal-to-kill-thread,
bugprone-branch-clone,
bugprone-copy-constructor-init,
bugprone-dangling-handle,
bugprone-dynamic-static-initializers,
bugprone-fold-init-type,
bugprone-forward-declaration-namespace,
bugprone-forwarding-reference-overload,
bugprone-inaccurate-erase,
bugprone-incorrect-roundings,
bugprone-integer-division,
bugprone-lambda-function-name,
bugprone-macro-parentheses,
bugprone-macro-repeated-side-effects,
bugprone-misplaced-operator-in-strlen-in-alloc,
bugprone-misplaced-pointer-arithmetic-in-alloc,
bugprone-misplaced-widening-cast,
bugprone-move-forwarding-reference,
bugprone-multiple-statement-macro,
bugprone-no-escape,
bugprone-not-null-terminated-result,
bugprone-parent-virtual-call,
bugprone-posix-return,
bugprone-reserved-identifier,
bugprone-sizeof-container,
bugprone-sizeof-expression,
bugprone-spuriously-wake-up-functions,
bugprone-string-constructor,
bugprone-string-integer-assignment,
bugprone-string-literal-with-embedded-nul,
bugprone-suspicious-enum-usage,
bugprone-suspicious-include,
bugprone-suspicious-memset-usage,
bugprone-suspicious-missing-comma,
bugprone-suspicious-semicolon,
bugprone-suspicious-string-compare,
bugprone-swapped-arguments,
bugprone-terminating-continue,
bugprone-throw-keyword-missing,
bugprone-too-small-loop-variable,
bugprone-undefined-memory-manipulation,
bugprone-undelegated-constructor,
bugprone-unhandled-self-assignment,
bugprone-unused-raii,
bugprone-unused-return-value,
bugprone-use-after-move,
bugprone-virtual-near-miss,
cert-dcl21-cpp,
cert-dcl58-cpp,
cert-err34-c,
cert-err52-cpp,
cert-err58-cpp,
cert-err60-cpp,
cert-flp30-c,
cert-msc50-cpp,
cert-msc51-cpp,
cert-str34-c,
cppcoreguidelines-interfaces-global-init,
cppcoreguidelines-narrowing-conversions,
cppcoreguidelines-pro-type-member-init,
cppcoreguidelines-pro-type-static-cast-downcast,
cppcoreguidelines-slicing,
google-default-arguments,
google-explicit-constructor,
google-runtime-operator,
hicpp-exception-baseclass,
hicpp-multiway-paths-covered,
misc-misplaced-const,
misc-new-delete-overloads,
misc-no-recursion,
misc-non-copyable-objects,
misc-throw-by-value-catch-by-reference,
misc-unconventional-assign-operator,
misc-uniqueptr-reset-release,
modernize-avoid-bind,
modernize-concat-nested-namespaces,
modernize-deprecated-headers,
modernize-deprecated-ios-base-aliases,
modernize-loop-convert,
modernize-make-shared,
modernize-make-unique,
modernize-pass-by-value,
modernize-raw-string-literal,
modernize-redundant-void-arg,
modernize-replace-auto-ptr,
modernize-replace-disallow-copy-and-assign-macro,
modernize-replace-random-shuffle,
modernize-return-braced-init-list,
modernize-shrink-to-fit,
modernize-unary-static-assert,
modernize-use-auto,
modernize-use-bool-literals,
modernize-use-emplace,
modernize-use-equals-default,
modernize-use-equals-delete,
modernize-use-nodiscard,
modernize-use-noexcept,
modernize-use-nullptr,
modernize-use-override,
modernize-use-transparent-functors,
modernize-use-uncaught-exceptions,
mpi-buffer-deref,
mpi-type-mismatch,
openmp-use-default-none,
performance-faster-string-find,
performance-for-range-copy,
performance-implicit-conversion-in-loop,
performance-inefficient-algorithm,
performance-inefficient-string-concatenation,
performance-inefficient-vector-operation,
performance-move-const-arg,
performance-move-constructor-init,
performance-no-automatic-move,
performance-noexcept-move-constructor,
performance-trivially-destructible,
performance-type-promotion-in-math-fn,
performance-unnecessary-copy-initialization,
performance-unnecessary-value-param,
portability-simd-intrinsics,
readability-avoid-const-params-in-decls,
readability-const-return-type,
readability-container-size-empty,
readability-convert-member-functions-to-static,
readability-delete-null-pointer,
readability-deleted-default,
readability-inconsistent-declaration-parameter-name,
readability-make-member-function-const,
readability-misleading-indentation,
readability-misplaced-array-index,
readability-non-const-parameter,
readability-redundant-control-flow,
readability-redundant-declaration,
readability-redundant-function-ptr-dereference,
readability-redundant-smartptr-get,
readability-redundant-string-cstr,
readability-redundant-string-init,
readability-simplify-subscript-expr,
readability-static-accessed-through-instance,
readability-static-definition-in-anonymous-namespace,
readability-string-compare,
readability-uniqueptr-delete-release,
readability-use-anyofallof
WarningsAsErrors: ''
HeaderFilterRegex: ''
CheckOptions:
- key: modernize-replace-auto-ptr.IncludeStyle
value: llvm
- key: performance-move-const-arg.CheckTriviallyCopyableMove
value: "true"
- key: modernize-use-auto.MinTypeNameLength
value: "5"
- key: readability-static-accessed-through-instance.NameSpecifierNestingThreshold
value: "3"
- key: bugprone-reserved-identifier.Invert
value: "false"
- key: bugprone-unused-return-value.CheckedFunctions
value: "::std::async;::std::launder;::std::remove;::std::remove_if;::std::unique;::std::unique_ptr::release;::std::basic_string::empty;::std::vector::empty;::std::back_inserter;::std::distance;::std::find;::std::find_if;::std::inserter;::std::lower_bound;::std::make_pair;::std::map::count;::std::map::find;::std::map::lower_bound;::std::multimap::equal_range;::std::multimap::upper_bound;::std::set::count;::std::set::find;::std::setfill;::std::setprecision;::std::setw;::std::upper_bound;::std::vector::at;::bsearch;::ferror;::feof;::isalnum;::isalpha;::isblank;::iscntrl;::isdigit;::isgraph;::islower;::isprint;::ispunct;::isspace;::isupper;::iswalnum;::iswprint;::iswspace;::isxdigit;::memchr;::memcmp;::strcmp;::strcoll;::strncmp;::strpbrk;::strrchr;::strspn;::strstr;::wcscmp;::access;::bind;::connect;::difftime;::dlsym;::fnmatch;::getaddrinfo;::getopt;::htonl;::htons;::iconv_open;::inet_addr;::isascii;::isatty;::mmap;::newlocale;::openat;::pathconf;::pthread_equal;::pthread_getspecific;::pthread_mutex_trylock;::readdir;::readlink;::recvmsg;::regexec;::scandir;::semget;::setjmp;::shm_open;::shmget;::sigismember;::strcasecmp;::strsignal;::ttyname"
- key: cert-dcl16-c.NewSuffixes
value: "L;LL;LU;LLU"
- key: readability-inconsistent-declaration-parameter-name.Strict
value: "false"
- key: modernize-use-override.AllowOverrideAndFinal
value: "false"
- key: modernize-pass-by-value.ValuesOnly
value: "false"
- key: modernize-loop-convert.IncludeStyle
value: llvm
- key: cert-str34-c.DiagnoseSignedUnsignedCharComparisons
value: "false"
- key: bugprone-suspicious-string-compare.WarnOnLogicalNotComparison
value: "false"
- key: readability-redundant-smartptr-get.IgnoreMacros
value: "true"
- key: bugprone-argument-comment.CommentNullPtrs
value: "0"
- key: bugprone-suspicious-string-compare.WarnOnImplicitComparison
value: "true"
- key: modernize-use-emplace.TupleTypes
value: "::std::pair;::std::tuple"
- key: modernize-use-emplace.TupleMakeFunctions
value: "::std::make_pair;::std::make_tuple"
- key: cppcoreguidelines-narrowing-conversions.WarnOnFloatingPointNarrowingConversion
value: "true"
- key: bugprone-argument-comment.StrictMode
value: "0"
- key: modernize-use-nodiscard.ReplacementString
value: "[[nodiscard]]"
- key: modernize-loop-convert.MakeReverseRangeHeader
value: ""
- key: modernize-replace-random-shuffle.IncludeStyle
value: llvm
- key: modernize-use-bool-literals.IgnoreMacros
value: "true"
- key: bugprone-unhandled-self-assignment.WarnOnlyIfThisHasSuspiciousField
value: "true"
- key: google-readability-namespace-comments.ShortNamespaceLines
value: "10"
- key: bugprone-suspicious-string-compare.StringCompareLikeFunctions
value: ""
- key: modernize-avoid-bind.PermissiveParameterList
value: "false"
- key: modernize-use-override.FinalSpelling
value: final
- key: performance-move-constructor-init.IncludeStyle
value: llvm
- key: modernize-loop-convert.UseCxx20ReverseRanges
value: "true"
- key: modernize-use-noexcept.ReplacementString
value: ""
- key: performance-type-promotion-in-math-fn.IncludeStyle
value: llvm
- key: modernize-loop-convert.NamingStyle
value: CamelCase
- key: bugprone-suspicious-include.ImplementationFileExtensions
value: "c;cc;cpp;cxx"
- key: cppcoreguidelines-pro-type-member-init.UseAssignment
value: "false"
- key: bugprone-suspicious-missing-comma.SizeThreshold
value: "5"
- key: bugprone-suspicious-include.HeaderFileExtensions
value: ";h;hh;hpp;hxx"
- key: performance-no-automatic-move.AllowedTypes
value: ""
- key: performance-for-range-copy.WarnOnAllAutoCopies
value: "false"
- key: bugprone-argument-comment.CommentIntegerLiterals
value: "0"
- key: modernize-loop-convert.MakeReverseRangeFunction
value: ""
- key: readability-inconsistent-declaration-parameter-name.IgnoreMacros
value: "true"
- key: hicpp-multiway-paths-covered.WarnOnMissingElse
value: "false"
- key: modernize-pass-by-value.IncludeStyle
value: llvm
- key: bugprone-sizeof-expression.WarnOnSizeOfThis
value: "true"
- key: bugprone-string-constructor.WarnOnLargeLength
value: "true"
- key: bugprone-too-small-loop-variable.MagnitudeBitsUpperLimit
value: "16"
- key: bugprone-argument-comment.CommentFloatLiterals
value: "0"
- key: bugprone-argument-comment.CommentCharacterLiterals
value: "0"
- key: modernize-use-nullptr.NullMacros
value: "NULL"
- key: modernize-make-shared.IgnoreMacros
value: "true"
- key: bugprone-dynamic-static-initializers.HeaderFileExtensions
value: ";h;hh;hpp;hxx"
- key: bugprone-suspicious-enum-usage.StrictMode
value: "false"
- key: performance-unnecessary-copy-initialization.AllowedTypes
value: ""
- key: bugprone-suspicious-missing-comma.MaxConcatenatedTokens
value: "5"
- key: modernize-use-transparent-functors.SafeMode
value: "false"
- key: cppcoreguidelines-narrowing-conversions.PedanticMode
value: "false"
- key: modernize-make-shared.IgnoreDefaultInitialization
value: "true"
- key: bugprone-not-null-terminated-result.WantToUseSafeFunctions
value: "true"
- key: modernize-make-shared.IncludeStyle
value: llvm
- key: bugprone-string-constructor.LargeLengthThreshold
value: "8388608"
- key: misc-throw-by-value-catch-by-reference.CheckThrowTemporaries
value: "true"
- key: cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField
value: "0"
- key: modernize-use-override.IgnoreDestructors
value: "false"
- key: performance-inefficient-vector-operation.EnableProto
value: "false"
- key: modernize-make-shared.MakeSmartPtrFunction
value: "std::make_shared"
- key: modernize-loop-convert.MaxCopySize
value: "16"
- key: bugprone-argument-comment.CommentStringLiterals
value: "0"
- key: portability-simd-intrinsics.Suggest
value: "false"
- key: cppcoreguidelines-explicit-virtual-functions.IgnoreDestructors
value: "1"
- key: performance-for-range-copy.AllowedTypes
value: ""
- key: modernize-make-shared.MakeSmartPtrFunctionHeader
value: "<memory>"
- key: modernize-make-unique.IgnoreMacros
value: "true"
- key: bugprone-sizeof-expression.WarnOnSizeOfConstant
value: "true"
- key: readability-redundant-string-init.StringNames
value: "::std::basic_string_view;::std::basic_string"
- key: modernize-make-unique.IgnoreDefaultInitialization
value: "true"
- key: modernize-use-emplace.ContainersWithPushBack
value: "::std::vector;::std::list;::std::deque"
- key: modernize-make-unique.IncludeStyle
value: llvm
- key: bugprone-argument-comment.CommentBoolLiterals
value: "0"
- key: bugprone-argument-comment.CommentUserDefinedLiterals
value: "0"
- key: modernize-use-override.OverrideSpelling
value: override
- key: readability-redundant-declaration.IgnoreMacros
value: "true"
- key: performance-inefficient-string-concatenation.StrictMode
value: "false"
- key: google-readability-braces-around-statements.ShortStatementLines
value: "1"
- key: modernize-make-unique.MakeSmartPtrFunction
value: "std::make_unique"
- key: cppcoreguidelines-pro-type-member-init.IgnoreArrays
value: "false"
- key: bugprone-reserved-identifier.AllowedIdentifiers
value: ""
- key: modernize-use-emplace.IgnoreImplicitConstructors
value: "false"
- key: modernize-make-unique.MakeSmartPtrFunctionHeader
value: "<memory>"
- key: modernize-use-equals-delete.IgnoreMacros
value: "true"
- key: bugprone-misplaced-widening-cast.CheckImplicitCasts
value: "false"
- key: bugprone-suspicious-missing-comma.RatioThreshold
value: "0.200000"
- key: modernize-loop-convert.MinConfidence
value: reasonable
- key: misc-throw-by-value-catch-by-reference.MaxSize
value: "-1"
- key: performance-unnecessary-value-param.AllowedTypes
value: ""
- key: modernize-use-noexcept.UseNoexceptFalse
value: "true"
- key: google-readability-namespace-comments.SpacesBeforeComments
value: "2"
- key: cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic
value: "1"
- key: bugprone-argument-comment.IgnoreSingleArgument
value: "0"
- key: bugprone-sizeof-expression.WarnOnSizeOfIntegerExpression
value: "false"
- key: performance-faster-string-find.StringLikeClasses
value: "::std::basic_string;::std::basic_string_view"
- key: bugprone-assert-side-effect.CheckFunctionCalls
value: "false"
- key: bugprone-string-constructor.StringNames
value: "::std::basic_string;::std::basic_string_view"
- key: bugprone-assert-side-effect.AssertMacros
value: assert,NSAssert,NSCAssert
- key: llvm-qualified-auto.AddConstToQualified
value: "0"
- key: cert-str34-c.CharTypdefsToIgnore
value: ""
- key: google-readability-function-size.StatementThreshold
value: "800"
- key: llvm-else-after-return.WarnOnConditionVariables
value: "0"
- key: cert-msc51-cpp.DisallowedSeedTypes
value: "time_t,std::time_t"
- key: bugprone-sizeof-expression.WarnOnSizeOfCompareToConstant
value: "true"
- key: bugprone-reserved-identifier.AggressiveDependentMemberLookup
value: "false"
- key: modernize-use-equals-default.IgnoreMacros
value: "true"
- key: modernize-raw-string-literal.DelimiterStem
value: lit
- key: misc-throw-by-value-catch-by-reference.WarnOnLargeObjects
value: "false"
- key: modernize-raw-string-literal.ReplaceShorterLiterals
value: "false"
- key: modernize-use-emplace.SmartPointers
value: "::std::shared_ptr;::std::unique_ptr;::std::auto_ptr;::std::weak_ptr"
- key: bugprone-dangling-handle.HandleClasses
value: "std::basic_string_view;std::experimental::basic_string_view"
- key: performance-inefficient-vector-operation.VectorLikeClasses
value: "::std::vector"
- key: modernize-use-auto.RemoveStars
value: "false"
- key: portability-simd-intrinsics.Std
value: ""
- key: performance-unnecessary-value-param.IncludeStyle
value: llvm
- key: modernize-replace-disallow-copy-and-assign-macro.MacroName
value: DISALLOW_COPY_AND_ASSIGN
- key: llvm-else-after-return.WarnOnUnfixable
value: "0"
- key: readability-simplify-subscript-expr.Types
value: "::std::basic_string;::std::basic_string_view;::std::vector;::std::array"

.clang-format

这是从clion上导出的

# Generated from CLion C/C++ Code Style settings
BasedOnStyle: LLVM
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: None
AlignOperands: Align
AllowAllArgumentsOnNextLine: false
AllowAllConstructorInitializersOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: false
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterReturnType: None
AlwaysBreakTemplateDeclarations: Yes
BreakBeforeBraces: Allman
BraceWrapping:
  AfterCaseLabel: false
  AfterClass: false
  AfterControlStatement: Never
  AfterEnum: false
  AfterFunction: false
  AfterNamespace: false
  AfterUnion: false
  BeforeCatch: false
  BeforeElse: false
  IndentBraces: false
  SplitEmptyFunction: false
  SplitEmptyRecord: true
BreakBeforeBinaryOperators: None
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeColon
BreakInheritanceList: BeforeColon
ColumnLimit: 100
CompactNamespaces: false
ContinuationIndentWidth: 8
IndentCaseLabels: true
IndentPPDirectives: None
IndentWidth: 4
KeepEmptyLinesAtTheStartOfBlocks: true
MaxEmptyLinesToKeep: 1
NamespaceIndentation: All
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PointerAlignment: Right
ReflowComments: false
SpaceAfterCStyleCast: true
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 0
SpacesInAngles: false
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
TabWidth: 4
UseTab: Never

windows搭建CMake+Qt环境

一、安装Qt:

  1. 官网链接:https://download.qt.io/archive/online_installers/
  2. 使用镜像:.\qt-unified-windows-x64-4.6.1-online --mirror https://mirrors.ustc.edu.cn/qtproject

注意,windows下建议使用MSVC编译套件,因为发现有些库只能MSVC才能使用,如QtWebEngine

image-20250419201547803

二、配置环境

以Qt 5.15.2为例,其他同理

1.添加环境变量

  • D:\Qt\5.15.2\mingw81_64\bin
  • D:\Qt\5.15.2\mingw81_64\lib

将以上路径添加到环境变量中,防止找不到库文件

也可以添加下面两个,方便vscode找到编译套件

  • D:\Qt\Tools\mingw810_64\bin
  • D:\Qt\Tools\mingw810_64\lib

2.添加编译套件

1、clion配置

PixPin_2025-02-23_14-23-51

2、vscode配置

PixPin_2025-02-27_20-37-34

3、vs2022配置

以Qt 6.5.3为例,其他同理

安装插件:Qt VS Tools

配置插件:添加编译套件

image-20250419201103520

三、添加外部工具和插件

1、clion添加外部工具

PixPin_2025-02-27_20-40-48

  • qt-designer
    • Program: D:\Qt\5.15.2\mingw81_64\bin\designer.exe
    • Arguments:$FileName$
    • Working directory:$ProjectFileDir$
    • 点击高级选项,勾选:Synchronize files after executionOpen console for tool output
  • qt-uic
    • Program: D:\Qt\5.15.2\mingw81_64\bin\uic.exe
    • Arguments:$FileName$ -o ui_$FileNameWithoutExtension$.h
    • Working directory:$FileDir$
    • 高级选项同上
  • qt-Assistant
    • Program: D:\Qt\5.15.2\mingw81_64\bin\assistant.exe
    • Arguments:不填
    • Working directory:D:\Qt\5.15.2\mingw81_64\bin
    • 高级选项:不做勾选

2、vscode安装插件

  • Qt tools 作者:tonka3000,右键ui文件可选择打开qt-designer

3、vs2022添加外部工具

右键点击ui文件,选择Open with…,然后点击add添加designer外部工具,argument不用填,选择designer路径添加即可,然后点击Set as Default设置为默认打开方式,以后双击ui文件就能使用Qt Designer打开了

image-20250420211911113

四、cmake使用

1.项目结构

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
qt-game-example/
├── bin/ # 构建输出目录(可执行文件)
├── CMakeLists.txt # 顶层CMake配置文件
├── main.cpp # 程序入口文件
├── resources/ # 资源文件目录
│ ├── res.qrc # Qt资源文件(包含图片、音乐等)
│ ├── images/ # 图片资源
│ │ └── example.png
│ └── music/ # 音乐资源
│ └── background.mp3
├── core/ # 核心逻辑模块
│ ├── include/ # 头文件
│ │ ├── CoreLogic.h
│ │ └── DataManager.h
│ ├── CoreLogic.cpp
│ ├── DataManager.cpp
│ └── CMakeLists.txt # core模块的CMake配置文件
├── ui/ # 用户界面模块
│ ├── include/ # 头文件
│ │ ├── MainWindow.h
│ │ └── WidgetUtils.h
│ ├── forms/ # Qt UI文件
│ │ └── mainwindow.ui # Qt Designer生成的UI文件
│ ├── MainWindow.cpp
│ ├── WidgetUtils.cpp
│ └── CMakeLists.txt # ui模块的CMake配置文件
├── CMakeCache.txt # CMake缓存(由构建生成)
└── cmake-build-debug/ # 构建目录(由CMake生成)

2.示例CMakeLists.txt文件

以下是基于上述结构生成的CMakeLists.txt文件,包含顶层和子模块的配置。

1. 顶层 CMakeLists.txt
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
cmake_minimum_required(VERSION 3.28)
project(qt-game-example)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_AUTOMOC ON) # 自动处理Qt元对象(Q_OBJECT等)
set(CMAKE_AUTORCC ON) # 自动处理Qt资源文件
set(CMAKE_AUTOUIC ON) # 自动处理Qt UI文件
set(CMAKE_PREFIX_PATH "D:/Qt/5.15.2/mingw81_64") # Qt安装路径(根据你的环境调整)
set(QRC_SOURCE_FILES ${PROJECT_SOURCE_DIR}/resources/res.qrc)#添加资源文件

#如果 .ui 文件不在源文件目录中,CMake 无法找到它们,就会报错或忽略,CMAKE_AUTOUIC_SEARCH_PATHS 是一个列表变量,
#指定额外的目录路径,告诉 CMake 在这些目录中搜索 .ui 文件,它解决了 .ui 文件与源文件不在同一目录时的查找问题。
set(CMAKE_AUTOUIC_SEARCH_PATHS ${PROJECT_SOURCE_DIR}/ui/forms)

set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) # 可执行文件输出目录

# 查找Qt组件
find_package(Qt5 COMPONENTS
Core
Gui
Widgets
REQUIRED
)

include_directories(
${PROJECT_SOURCE_DIR}/core/include
${PROJECT_SOURCE_DIR}/ui/include
)


# 添加子目录
add_subdirectory(core)
add_subdirectory(ui)

# 添加可执行文件
add_executable(${PROJECT_NAME} main.cpp ${QRC_SOURCE_FILES})

# 链接库
target_link_libraries(${PROJECT_NAME}
PRIVATE
core
ui
Qt5::Core
Qt5::Gui
Qt5::Widgets
)

2. core/CMakeLists.txt

1
2
3
4
5
6
7
8
9
10
11
12
13
cmake_minimum_required(VERSION 3.28)
project(core)

#收集头文件
file(GLOB HEADER_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h)
# 收集源文件
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} SRC_LIST)

# 创建库
add_library(${PROJECT_NAME} ${SRC_LIST} ${HEADER_SOURCE_FILES})

# 链接Qt核心库
target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Core)
3. ui/CMakeLists.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
cmake_minimum_required(VERSION 3.28)
project(ui)

# 收集UI文件
file(GLOB UI_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/forms/*.ui)
# 收集头文件
file(GLOB HEADER_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h)
# 收集源文件
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} SRC_LIST)

# 创建库
add_library(${PROJECT_NAME} ${SRC_LIST} ${UI_SOURCE_FILES} ${HEADER_SOURCE_FILES})

# 链接Qt库
target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Core Qt5::Widgets)

五、vs2022额外注意

vs2022在创建带UI的类时,UI文件编译后的类命名可能与其他软件命名的不太一样,如下面的UI类名为TestClass

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#pragma once

#include <QMainWindow>
#include "ui_Test.h"

class Test : public QMainWindow
{
Q_OBJECT

public:
Test(QWidget *parent = nullptr);
~Test();

private:
Ui::TestClass ui;
};

如这里,UI文件的类名在后面添加了Class,而且,成员函数的声明方式也不同,这里没有使用指针声明类成员,跟其他软件的不一样,如Qt Creator,可以看到,UI类名字与类名相同都是Test,类成员声明方式是指针,如果没有注意,迁移项目到vs2022可能会导致一些错误。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#ifndef TEST_H
#define TEST_H

#include <QDialog>

namespace Ui
{
class Test;
}

class Test : public QDialog
{
Q_OBJECT

public:
explicit Test(QWidget* parent = nullptr);
~Test();

private:
Ui::Test* ui;
};

#endif // TEST_H

在默认创建的CMakeLists.txt文件也有一些区别,vs2022没有直接添加下面配置

1
2
3
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)

而是通过一个qt.cmake文件引入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#CMakeLists.txt内部调用qt.cmake中的配置
qt_standard_project_setup()

#qt.cmake
if(QT_VERSION VERSION_LESS 6.3)
macro(qt_standard_project_setup)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
endmacro()
endif()

if(QT_VERSION VERSION_LESS 6.0)
macro(qt_add_executable name)
if(ANDROID)
add_library(name SHARED ${ARGN})
else()
add_executable(${ARGV})
endif()
endmacro()
endif()

生成的二进制文件命令也不是add_executable,而是qt_add_executable

1
qt_add_executable(${PROJECT_NAME} ${PROJECT_SOURCES})

MSBuild构建项目时添加Qt其他模块

项目属性>Qt Project Settings>Qt Modules>Select Mudules

image-20250419212814240

勾选需要的模块,然后点击OK,确定退出项目属性编辑,这样就能添加Qt的其他模块了

image-20250419212848376

PicGo搭建Cloudflare R2图床教程

1、创建R2存储

  • 创建R2对象存储,如下图:我是绑定了PayPal,账单邮寄地址不需要真实地址,你也可以填写真实地址

PixPin_2025-02-23_10-36-31

  • 点击创建存储桶

PixPin_2025-02-23_10-44-28

随便填写一个桶名,位置自行填写,这里我就是使用自动分配了,任何点击 创建存储桶

PixPin_2025-02-23_10-45-24

点击设置

c3c40cd0aa1923bb5908f2df1c1d07a2

点击连接域添加自定义域,假设我有一个example.com域名,这里就填写images.example.com

PixPin_2025-02-23_10-48-38

填写域名后点击继续,再点击连接域,状态变为活动表明成功添加自定义域,如果不更新,刷新一下页面

PixPin_2025-02-23_10-55-23

然后划到下面,删除对象生命周期规则的规则,点击删除

PixPin_2025-02-23_10-58-31

2、配置PicGo

  • PicGo官网下载连接:https://github.com/Molunerfinn/picgo/releases

    注意:2.3.1这个版本好像无法搜索插件?我是直接下载了最新的2.4.0-beta.9测试版本

  • 安装s3插件,点击搜索s3即可安装,这里还推荐几个插件,如下图的tinypngwebp

    • tinypng:压缩图片
    • webp:将图片格式转换为webp

    经过测试,发现现执行webp转换格式再执行tinypng压缩图片

PixPin_2025-02-23_11-06-35

  • 配置图床

返回cloudflare R2页面,点击管理API令牌,再点击创建API令牌

PixPin_2025-02-23_11-18-01

令牌名称随意,指定存储桶为我们创建的存储桶,然后滑到底部点击创建API令牌,然后不要退出cloudflare页面,后面要用

PixPin_2025-02-23_11-19-39

返回PicGo,点击Amazon S3配置图床信息

  1. 应用密钥ID就是创建令牌得到的:访问密钥 ID(Access Key ID)
  2. 应用密钥:填写机密访问密钥(Secret Access Key)
  3. 桶名填写 R2 中创建的 Bucket 名称,如创建R2的桶的名字 images
  4. 自定义节点:填写为 S3 客户端使用管辖权地特定的终结点

PixPin_2025-02-23_11-16-08

代理自行填写,自定义输出URL模板填写你自己的域名,上面我们创建时使用的是:images.example.com

PixPin_2025-02-23_11-28-58

然后点击底部的确定即可完成图床搭建。

3、其他

  • 配置缓存,打开cloudflare,进入你自己的域名,点击缓存,点击Cache Rules,创建一条规则

PixPin_2025-02-23_11-37-36

配置自行填写:

  1. 边缘 TTL:一个月
  2. 浏览器 TTL:8小时

然后点击保存

PixPin_2025-02-23_11-38-14

  • 创建压缩规则,根据情况填写相关规则即可,然后点击保存

PixPin_2025-02-23_11-42-36

点击规则,点击页面规则,创建一个页面规则,点击保存页面规则

PixPin_2025-02-23_11-47-09

Serv00 平台搭建 Socks5 代理节点与自动化保活教程

该教程整合了以下几位大佬的教程

  1. CMLiussss:Serv00/CT8:从注册到部署SOCKS5代理,一步到位自动续期保活教程,SOCKS5可用于edgetunnel解锁ChatGPT
  2. hkfires : Serv00服务器优雅的保活方案
  3. 秋风于渭水 : 用GitHub Actions 搭建网页状态监控系统 Upptime

步骤1.申请端口

  1. 登录你帐号对应的 panel 面板
  2. 面板左侧 > Port reservation > 选择 Add port 标签栏 > 勾选 Random > +Add

PixPin_2025-01-26_16-32-12.webp

选择 Port list 标签栏 > 记录你分配到的TCP端口号

PixPin_2025-01-26_21-24-46.webp

步骤2.开启管理执行权限

  1. 登录你帐号对应的 panel 面板
  2. 面板左侧 > 选择 Run your own applications 标签栏 > Enabled ; 使其Status变成 ✅Enabled即可

PixPin_2025-01-26_16-35-39.webp

步骤3.执行一键安装Sock5节点脚本

使用ssh连接serv00,执行以下脚本

1
bash <(curl -s https://raw.githubusercontent.com/cmliu/socks5-for-serv00/main/install-socks5.sh)

注意:在输入socks5端口号时,输入申请端口时记录的TCP端口号即可,其余参数可以自行输入任意内容;(如果不清楚nezha-agent等内容,照着填就行),由于本教程没有用到crontab,可以不添加 crontab 守护进程的计划任务。

PixPin_2025-01-26_16-38-07.webp

步骤4:创建域名

  • 登录Serv00面板,删除注册后自带的网站

PixPin_2025-01-26_16-46-38.webp

  • 点击Delete(purge website files)清空网站文件

PixPin_2025-01-26_16-49-23.webp

  • 创建新网站,域名填写你想用的域名,我这里使用的是注册时自带的,网站类型设置为Node.js,程序版本选择NOde.js v22.4.1(你的版本可能更高,选择最新的即可)
    PixPin_2025-01-26_16-52-12.webp

步骤5:配置nodejs启动Sock5代理进程

  • SSH登录Serv00,输入cd domains/你的网站域名/public_nodejs/
  • 由于Serv00的Apache设置的是静态优先,因而此处public文件夹下不能有index.html,否则会显示静态页面,而不会执行nodejs程序,我选择的是直接将public改名为static,执行mv public static
  • 执行npm22 install express

PixPin_2025-01-26_16-53-21.webp

  • /home/你的用户名/domains/你的网站域名/public_nodejs目录下创建以下app.js文件并修改app.js的第7行,填写你自己的Serv00用户名.

    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
    const express = require("express");
    const path = require("path");
    const exec = require("child_process").exec;
    const app = express();
    const port = 3000;

    const user = "Serv00登录用户名"; //此处修改为Serv00的用户名
    const pName = "s5";

    app.use(express.static(path.join(__dirname, 'static')));

    function keepWebAlive() {
    const currentDate = new Date();
    const formattedDate = currentDate.toLocaleDateString();
    const formattedTime = currentDate.toLocaleTimeString();

    exec(`pgrep -laf ${pName}`, (err, stdout) => {
    const Process = `/home/${user}/.${pName}/${pName} -c /home/${user}/.${pName}/config.json`;

    if (stdout.includes(Process)) {
    console.log(`${formattedDate}, ${formattedTime}: Web Running`);
    } else {
    exec(`nohup ${Process} >/dev/null 2>&1 &`, (err) => {
    if (err) {
    console.log(`${formattedDate}, ${formattedTime}: Keep alive error: ${err}`);
    } else {
    console.log(`${formattedDate}, ${formattedTime}: Keep alive success!`);
    }
    });
    }
    });
    }

    setInterval(keepWebAlive, 10 * 1000);

    app.listen(port, () => {
    console.log(`Server is listening on port ${port}!`);
    });

    修改完成后public_nodejs目录下应该和我一样

PixPin_2025-01-26_16-56-22.webp

  • 自此部署完成,用浏览器输入一下你创建的网站域名,正常就能看到默认的页面

PixPin_2025-01-26_16-59-28.webp

  • 页面能够正常显示,返回SSH终端,输入ps aux可以看到新开了nodejs进程,稍带片刻,就能看到你的代理进程成功启动了

    PixPin_2025-01-26_17-00-17.webp

  • Nodejs程序运行日志可以通过面板网站的log中查看,也可以在SSH终端里查看,日志文件的完整路径为/home/你的用户名/domains/你的网站域名/logs/error.log

SOCKS代理进程由Nodejs进程负责保活,10秒钟检查一次,因此后续只需要关注Nodejs进程的保活就可以了,Nodejs进程的保活可以手动访问网站进行,也可以通过自动化方案监控网站进行

步骤六:配置upptime自动化网页监控网站

upptime自动化网页监控网站不需要有服务器,只需要有Github账号就能够进行部署

  1. 访问 Upptime 项目

  2. 点击 【Use this template】按钮
    PixPin_2025-01-26_17-10-06.webp

    注意:这是个模版项目,所以不要像常见的项目那样,去直接点右上角的fork。

  3. 创建repo

PixPin_2025-01-26_17-11-30.webp

  • 输入 Repository name(比如upptime)
  • 勾选 【Include all branches】
  • 点击 【Create repository from temple】
  1. 配置upptime仓库

PixPin_2025-01-26_17-13-29.webp

  • 进入你刚才repo到自己账号下的项目
  • 点右上角的 【Settings】
  • 在左侧 【Code and automation】 下找到 【Pages】
  • 将 【Branch】 设置为 【gh-pages】
  • 点击 【Save】
  1. 给 Upptime-bot 设置 Repository Secret

    因为这个项目是利用bot实现自动化提交,需要给予bot,commit和publish的权限,所以我们需要设定一个Personal Access Token

    1. 点击网页右上角自己的头像,点 【Settings】

    2. 点击左侧最下方的【Developer settings】

    3. 点击左侧下方的【Personal access tokens】 ,点击左上角的 【Generate new token】

    4. 点击 【tokens (classic)】->【Generate new token】->【Generate new token (classic)】

      1. Note: upptime
      2. Select scopes:勾选【repo】和【workflow】(你直接勾workflow,repo就全勾上了)
      3. Expiration:选【No expiration】(无期限)
      4. 点击页面最下方的 【Generate token】

    PixPin_2025-01-26_17-19-05.webp

  2. 复制token,注意一定要在这里复制好,错过这个页面你就再也看不到token了

  3. 返回你repo的Upptime项目。点击 【Settings】,展开左侧的【Secrets】,点击【Actions 】 点击【 New repository secret】

PixPin_2025-01-26_17-20-24.webp

  1. 给bot设定token
  • Name: GH_PAT
  • Value: 上边第5步里复制的 token
  • 点击 【Add secret】
  1. 回到你repo的upptime项目,点击【Code】,点击 【.upptimerc.yml】,修改.upptimerc.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
    # 【】以及其中的内容,为说明文字,需要替换为你自己的设置。
    # 『』以及其中的内容,为示例参数,需要替换为你自己的设置。

    #你的GitHub username
    owner: 【你的 GitHub username】『tjsky』

    #你的GitHub repo name
    repo: 【你的 repo name】『upptime』


    #下边写的时候一定注意代码的缩进让,“-” 都在同一个竖线上,“name”和“url”也都在同一个竖线上,层次不齐的代码高几率直接报错
    sites:
    - name: 【要监控的第一个网页的名称】『Google』
    url: 【要监控的第一个网页的域名】『https://www.google.com』
    - name: 【要监控的第二个网页的名称】『Wikipedia』
    url: 【要监控的而网页的域名】『https://en.wikipedia.org』



    # A-如果你的监控控制台页面,打算使用github的默认域名,则使用如下设置。和下边B设置互斥,请二选一
    status-website:
    baseUrl: 【/你的 repo name】『/upptime』

    # B-如果你的监控控制台页面,打算使用自己所有的域名,则使用如下设置,和上边A设置互斥,请二选一
    status-website:
    cname: 【你的域名】『upptime.tjsky.net』

    #自定义状态页面的navbar名称与链接
    logoUrl: 【控制台网页logo地址】『https://raw.githubusercontent.com/upptime/upptime.js.org/master/static/img/icon.svg』
    name:【控制台网页名字】 『Upptime』
    introTitle: 【网页标题】『这里可以随便写的啦,比如写:这是使用upptime构建的开源网页状态监控页』
    introMessage: 【网页简介】『这里可以随便写的啦』
    navbar:
    - title: Status
    href: /
    - title: GitHub
    href: https://github.com/OWNER/REPO

    • 例如:

        
      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
      # Change these first
      owner: makabaka # Your GitHub organization or username, where this repository lives
      repo: serv00-keep # The name of this repository

      sites:
      - name: serv00
      url: https://abc.serv00.net
      - name: serv00
      url: https://edf.serv00.net

      status-website:
      # Add your custom domain name, or remove the `cname` line if you don't have a domain
      # Uncomment the `baseUrl` line if you don't have a custom domain and add your repo name there
      # cname: demo.upptime.js.org
      baseUrl: /serv00-keep

      logoUrl: https://raw.githubusercontent.com/upptime/upptime.js.org/master/static/img/icon.svg
      name: Upptime
      introTitle: serv00-keep
      introMessage: serv00 保活
      navbar:
      - title: Status
      href: /
      - title: GitHub
      href: https://github.com/$OWNER/$REPO
    1. 修改完成后在点击页面最下的【Commit changes】按钮,提交修改。
    2. 启动GitHub Actions

    PixPin_2025-01-26_17-27-09.webp

    一般情况下,在你修改.upptimerc.yml后,Actions就会自动开始运行。你会看到一个黄圈圈在转。运行成功会显示绿色的勾,运行失败会显示红色的叉。如果出现红叉,一般都是你修改yml文件时,什么地方写错了,比如少打了一个字母啊,空格漏了啊,代码对齐有问题,少写了什么必须设置的参数,什么参数设置错误了。请仔细检查。

    1. 访问监控状态页面

    PixPin_2025-01-26_17-30-10.webp

    1. 进入你刚才repo到自己账号下的项目
    2. 点右上角的 【Settings】
    3. 在左侧 【Code and automation】 下找到 【Pages】
    4. Your site is live at XXXXXX这里就是你的监控状态页面啦
    5. Active Incidents 显示目前的异常事件,Live Status 显示目前监控状态,Past Incidents 显示过去的异常事件

    实际上就是在你的repo仓库页面

    PixPin_2025-01-26_17-31-14.webp

    1. 汉化配置页,把如下内容粘贴到.upptimerc.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
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      i18n:
      activeIncidents: 活动事件
      allSystemsOperational: 所有系统都可以正常运行
      incidentReport: "事件 #NUMBER 报告 →"
      activeIncidentSummary: 在DATE 打开,有 POSTS 个帖子
      incidentTitle: 事件NUMBER 的详细信息
      incidentDetails: 事件详细信息
      incidentFixed: 已修复
      incidentOngoing: 正在进行
      incidentOpenedAt: 开始于
      incidentClosedAt: 结束于
      incidentSubscribe: 订阅更新
      incidentViewOnGitHub: GitHub 上查看
      incidentCommentSummary: AUTHOR 在DATE 发布
      incidentBack: 返回所有事件
      pastIncidents: 过去的事件
      pastIncidentsResolved: POSTS 个问题在MINUTES 分钟内得到解决
      liveStatus: 实时状态
      overallUptime: "总体正常运行时间: UPTIME"
      overallUptimeTitle: 总体正常运行时间
      averageResponseTime: "平均响应时间:TIMEms"
      averageResponseTimeTitle: 平均响应时间
      sevelDayResponseTime: 7 天响应时间
      responseTimeMs: 响应时间(毫秒)
      ms: 毫秒
      loading: 加载中
      navGitHub: GitHub
      footer: gd1214b保留所有权利。 Copyright © 2021 gd1214b. All Rights Reserved.
      rateLimitExceededTitle: 超出速率限制
      rateLimitExceededIntro: 您已超过一小时内可以执行的请求数,因此您必须等待才能再次访问此网站。或者,您可以添加 GitHub 个人访问令牌以继续使用本网站。
      rateLimitExceededWhatDoesErrorMean: 这个错误是什么意思?本网站使用 GitHub API 访问有关我们网站状态的实时数据。默认情况下,GitHub 允许每个 IP 地址每小时 60 个请求,您已经消耗了这些请求。
      rateLimitExceededErrorHowCanFix: 我该如何解决?
      rateLimitExceededErrorFix: 您可以再等一个小时,您的 IP 地址限制将恢复。或者,您可以添加您的 GitHub 个人访问令牌,这将为您提供每小时额外 5,000 个请求。
      rateLimitExceededGeneratePAT: 了解如何生成个人访问令牌
      rateLimitExceededHasSet: 您有一个个人访问令牌集。
      rateLimitExceededRemoveToken: 删除令牌
      rateLimitExceededGitHubPAT: GitHub 个人访问令牌
      rateLimitExceededCopyPastePAT: 复制并粘贴您的令牌
      rateLimitExceededSaveToken: 保存令牌
      errorTitle: 发生错误
      errorIntro: 尝试获取最新状态详细信息时出错。
      errorText: 您可以稍后再试。
      errorHome: 转到主页
      pastScheduledMaintenance: 过去的预定维护
      scheduledMaintenance: 定期维护
      scheduledMaintenanceSummaryStarted: DATE 开始,持续DURATION 分钟
      scheduledMaintenanceSummaryStarts: DATE 开始,持续DURATION 分钟
      startedAt: 开始在
      startsAt: 开始于
      duration: 持续时间
      durationMin: $DURATION 分钟
      incidentCompleted: 已完成
      incidentScheduled: 已预定
      url: "链接"
      status: "状态"
      history: "历史"
      responseTime: "响应时间"
      uptime: "正常运行时间"
      up: "? 正常运行"
      degraded: "? 运行缓慢"
      down: "? 停机"
      responseTimeGraphAlt: "响应时间图像"
      responseTimeDay: "24 小时响应时间"
      responseTimeWeek: "7 天正常运行时间"
      responseTimeMonth: "30天的正常运行时间"
      responseTimeYear: "1年的正常运行时间"
      uptimeDay: "24 小时正常运行时间"
      uptimeWeek: "7 天正常运行时间"
      uptimeMonth: "30天的正常运行时间"
      uptimeYear: "1年的正常运行时间"
      liveStatusHtmlComment: "<! -实时状态- >"
      degradedPerformance: "? 性能降低"
      completeOutage: "? 全部停机"
      partialOutage: "? 部分停机"

    至此,全部教程结束,再次感谢几位大佬!

nginx 安装与基本使用指南

Nginx 反向代理配置与基础使用指南

Nginx 是一个高性能的 Web 服务器和反向代理服务器,广泛用于处理高并发请求、负载均衡和静态文件服务。如果不了解反向代理是什么,可以参考这篇文章


1. 安装 Nginx

1.1 在 Ubuntu/Debian 上安装

1
sudo apt update && sudo apt install nginx

1.2 启动与验证

启动 Nginx 并设置开机自启:

1
2
sudo systemctl start nginx
sudo systemctl enable nginx

访问 http://你的服务器IP,若看到 Nginx 欢迎页面,说明安装成功。确保 80 端口未被占用。


2. Nginx 配置文件结构

  • 主配置文件/etc/nginx/nginx.conf(全局设置,通常无需修改)。
  • 站点配置文件/etc/nginx/sites-available/(配置文件存放处)和 /etc/nginx/sites-enabled/(启用的配置文件软链接)或 /etc/nginx/conf.d/(直接启用的配置文件)。

3. 典型使用场景

3.1 静态文件服务

场景:通过 example.com 提供静态文件(如 HTML、CSS)。

配置

1
2
3
4
5
6
7
8
9
10
server {
listen 80;
server_name example.com;

location / {
root /var/www/html;
index index.html index.htm;
try_files $uri $uri/ =404;
}
}

关键字解释

  • listen 80;:监听 80 端口(HTTP 默认端口)。
  • server_name example.com;:处理该域名的请求。
  • root /var/www/html;:静态文件目录。
  • index index.html index.htm;:默认访问的文件顺序。
  • try_files:按顺序尝试查找文件,若都不存在则返回404。

3.2 反向代理

场景:将 example.com 的请求转发到 localhost:8080

配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
server {
listen 80;
server_name example.com;

location / {
proxy_pass http://localhost:8080;
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_connect_timeout 60s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
}
}

关键字解释

  • proxy_pass:将请求转发到指定地址。
  • proxy_set_header:传递客户端信息(如真实 IP 和协议)。
  • 超时配置:防止长时间连接占用资源。

3.3 HTTP 重定向到 HTTPS

场景:强制所有 HTTP 请求跳转到 HTTPS。

配置

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
server {
listen 80;
server_name example.com;

# 添加 $request_uri 确保路径和参数被保留
return 301 https://$host$request_uri;
}

server {
listen 443 ssl;
server_name example.com;

ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;

# 添加 SSL 安全配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';

location / {
proxy_pass http://localhost:8080;
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;
}
}

关键字解释

  • return 301:永久重定向到 HTTPS。
  • listen 443 ssl;:启用 HTTPS。
  • ssl_certificatessl_certificate_key:指定证书和私钥路径。
  • ssl_protocolsssl_ciphers:指定加密协议和算法,提高安全性。

3.4 负载均衡

场景:将请求分发到多个后端服务器。

配置

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
upstream backend {
# 添加负载均衡算法
least_conn;
server 192.168.1.101:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.102:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.103:8080 max_fails=3 fail_timeout=30s;

# 添加备用服务器
server 192.168.1.104:8080 backup;
}

server {
listen 80;
server_name example.com;

location / {
proxy_pass http://backend;
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;

# 添加健康检查间隔
health_check interval=10 fails=3 passes=2;
}
}

关键字解释

  • upstream:定义后端服务器组。
  • least_conn:使用最少连接数算法分配请求。
  • max_failsfail_timeout:定义失败条件和超时时间。
  • backup:备用服务器,仅在主服务器不可用时使用。
  • health_check:定期检查后端服务器健康状态。

3.5 路径匹配与请求转发

场景:根据不同路径转发到不同服务。

配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
nginxCopyserver {
listen 80;
server_name example.com;

# API 请求转发
location /api/ {
proxy_pass http://localhost:8080/;
# 注意:proxy_pass 末尾有 / 会去除 location 匹配部分
}

# 静态资源处理
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
root /var/www/static;
expires 7d;
add_header Cache-Control "public, max-age=604800";
}

# 默认路由
location / {
proxy_pass http://localhost:3000;
}
}

关键字解释

  • location /api/:匹配 /api/ 开头的路径。
  • location ~*:使用正则表达式匹配,不区分大小写。
  • expiresadd_header:设置缓存控制。

3.6 日志查看

1
2
3
4
5
6
7
8
9
10
11
12
server {
listen 80;
server_name example.com;

# 自定义访问日志格式
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log warn;

location / {
proxy_pass http://localhost:8080;
}
}
  • 访问日志/var/log/nginx/access.log 或自定义路径
  • 错误日志/var/log/nginx/error.log 或自定义路径

实时查看:

1
tail -f /var/log/nginx/access.log

4. 测试和重载配置

验证配置是否正确:

1
sudo nginx -t

重载配置:

1
sudo systemctl reload nginx

Git 安装和基本使用指南

Git 是一个分布式版本控制系统,广泛用于代码管理和协作开发。无论是个人项目还是团队协作,Git 都能帮助你高效地管理代码的版本、记录变更历史、解决冲突等。

1. 安装 Git 和基本配置

1.1 安装 Git

在 Linux 上安装

在大多数 Linux 发行版上,Git 可以通过包管理器安装。以 Ubuntu 为例:

1
2
sudo apt update
sudo apt install git

在 macOS 上安装

macOS 用户可以通过 Homebrew 安装 Git:

1
brew install git

在 Windows 上安装

Windows 用户可以从 Git 官网 下载安装程序,按照提示完成安装。

1.2 验证安装

安装完成后,可以通过以下命令验证 Git 是否安装成功:

1
git --version

如果看到类似 git version 2.x.x 的输出,说明 Git 安装成功。

1.3 配置 Git

安装完成后,需要配置 Git 的用户名和邮箱,这些信息会记录在每次提交中。

1
2
git config --global user.name "你的名字"
git config --global user.email "你的邮箱"

可以通过以下命令查看配置信息:

1
git config --list

一、Git基础

  1. 拉取远程仓库到本地

    1
    git clone 地址连接(https/ssh)
  2. 查看分支提交记录

    1
    git log
  3. 查看当前本地使用的分支

    1
    git branch
  4. 查看远程主仓库使用的分支

    1
    git branch -r
  5. 查看文件提交状态

    1
    git status
  6. 将文件改动添加到暂存区

    1
    2
    git add 文件名(只添加特定文件)
    git add .(提交全部)
  7. 将暂存区中的文件改动提交到本地仓库的代码分支上

    1
    git commit -m "说明,介绍内容"
  8. 将本地仓库推送到远程仓库

    1
    git push origin master:master

    将本地的master(第一个)分支提交到远程的origin/master分支上

    如果本地仓库和远程仓库名称相同,则可以省略为:git push origin master

  9. 拉取(更新)远程代码到本地

    1
    git pull origin <branch-name>

二、进阶-Git各阶段版本回退

2.1、工作区修改,但未提交到暂存区

1
2
3
4
5
1.比较简单,可以手动删除修改
2.如果修改的比较多,可以通过如下命令放弃特定文件的修改
git checkout -- 文件名
如果要放弃全部文件的修改,使用如下命令
git checkout -- .

原理:使用本地仓库中的文件或内容覆盖掉已修改的文件或内容

2.2、已添加到暂存区,但未提交

1
git reset HEAD

使用上面 的命令从暂存区中删除

2.3、已提交到本地仓库,但未发布到远程仓库

1
2
3
4
5
6
1.撤销提交,但保留所有代码更改在暂存区:
git reset --soft HEAD~1
2.撤销提交和暂存,但保留代码在工作目录:
git reset --mixed HEAD~1
3.彻底删除提交和所有相关的代码更改:
git reset --hard HEAD~1

2.4、已提交到远程仓库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1.先回退本地仓库,再强制更新远程仓库(不推荐,注意别把别人的代码也回退了!)
git reset --hard HEAD~1
git push -f origin master

2.使用revert重新创建一个提交,利用revert取消掉错误操作
#撤销最近一次提交
git revert HEAD

# 或者使用具体的 commit hash
git revert 2b8f7d1
#执行命令后,Git 会自动创建一个新的提交,并弹出一个文本编辑器,让你编辑这次撤销操作的提交信息,然后将这个提交push即可
git push origin master
#这个操作同时会删除掉本地修改,所以如果想恢复修改,可以使用cherry-pick
git cherry-pick -n 42e2cdafa6f80e06fa37f3bfb6c159f56e42b873(错误提交的commitID)

revert创建的提交与MySQL的undo log类似,它根据错误提交的修改,生成一个反向操作,抵消掉错误操作

三、冲突处理

场景:

起始点: 小张和小亮都从远程仓库拉取了最新代码。此时,他们本地的版本 (V1) 和远程仓库的版本 (V1) 是同步的

小张的工作: 小张完成了他的业务代码,并将本地代码更新到 V2。当他尝试推送时,成功了。为什么呢?因为他之前的本地版本 (V1) 与远程仓库的 V1 是同步的。Git 认为这是一个从 V1 到 V2 的直接、线性的更新,所以接受了。现在,远程仓库的版本是 V2。

小亮的困境: 当小张在工作并推送时,小亮也在进行修改。他的本地版本仍然是 V1,但远程仓库已经更新到了 V2。当小亮尝试推送他的 V1 更改时,Git 检测到冲突。Git 的规则是,如果你的本地分支落后于远程分支,你不能直接推送更改。这是为了防止无意中覆盖他人的工作。

解决方案:

拉取最新更改

1
git pull origin <branch-name>

拉取后,Git 可能会自动合并更改。但是,如果小张和小亮修改了同一个文件中的相同行,Git 将无法判断应该保留哪个更改。这时就会发生合并冲突。小亮需要手动编辑冲突的文件,决定保留哪些更改(或将它们组合),然后将冲突标记为已解决。解决所有冲突后,小亮将合并后的更改提交到他的本地仓库。最后就能提交到远程仓库了

四、分支处理

4.1、查看当前所在分支

1
git branch -vv

4.2、创建并切换到分支

1
2
3
4
git checkout -b 分支名
相当于下面两条命令
git branch 分支名
git checkout 分支名

创建分支的好处,减少在主分支上直接修改代码,减少在提交时发生冲突

4.3、切换分支

1
git checkout 分支名

4.4、合并分支

1
git merge 分支名

注意,merge操作需要切换到你要合并到的分支,正常情况下是主分支

第二,这里合并是在本地仓库上合并,此时还没有在远程仓库上合并,所以需要将master的最新合并后的代码推送到远程仓库

分支合并也可以不切换到master分支,可以使用如下命令推送到远程仓库的主分支上

1
git push orgin 分支名:master

4.5、删除分支

1
git branch -d 分支名

4.6、合并分支时的冲突处理

有一个远程仓库,小张和小亮都从远程拉取了最新的代码。小张创建了一个新分支来实现新业务功能,而小亮直接在本地 master 分支上修改代码,并推送到了远程仓库。小张在本地切换到 master 分支并执行 pull 操作后,尝试将自己的新分支合并到 master 时,出现错误:自动合并失败,因为代码存在冲突。

解决方案:手动修改冲突文件,保留正确代码,然后重新将修改后的文件添加到暂存区,提交并推送到远程

4.7、切换远程分支开发

由于迭代开发,第一代稳定了,为了拓展新功能打算开发第二代,于是在远程仓库上创建了一个新的分支dev,我们需要切换本地分支用于追踪这个dev分支。

创建一个同名的本地分支并最终远程dev分支

1
2
3
git fetch origin #先拉取远程仓库的最新信息,否则会找不到远程的dev分支
git branch -r #查看远程dev分支是否存在
git checkout -b dev origin/dev #创建一个同名的本地分支并最终远程dev分支

后续推送到dev分支使用如下命令

1
git push origin dev

五、git 一般工作流

  1. 在远程仓库上创建个人开发分支并在本地创建一个分支关联个人开发分支(git push -u origin 远程分支名
  2. 个人本地分支推送到远程分支
  3. 提交个人远程代码分支和目标代码合入分支的MR(PR),相关负责人负责CR
  4. 相关负责人提出意见,本人修改相应代码后推送到对应的远程代码分支上
  5. 代码意见处理完,相关负责人进行代码merge
  6. 删除个人远程代码分支 (git push origin :远程分支名)

docker安装-国内服务器

1. 更新系统包

1
2
sudo apt update
sudo apt upgrade -y

2. 安装依赖包

1
apt install curl vim wget gnupg dpkg apt-transport-https lsb-release ca-certificates

3. 添加Docker官方GPG密钥

添加阿里云的GPG密钥

1
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

或者添加官方的GPG密钥

1
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

4. 添加Docker仓库

将阿里云的APT仓库添加到系统中:

1
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

或者官方的APT仓库

1
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

5. 更新APT包索引

更新APT包索引以包含Docker仓库中的包:

1
sudo apt update

6. 安装Docker

安装Docker CE(社区版):

1
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

7. 启动并启用Docker服务

启动Docker服务并设置为开机自启:

1
2
sudo systemctl start docker
sudo systemctl enable docker

8. 验证安装

验证Docker是否安装成功:

1
sudo docker --version

你应该会看到类似以下的输出:

1
Docker version 20.10.12, build e91ed57

9. 添加用户到Docker组(可选)

为了避免每次使用Docker时都需要sudo,可以将当前用户添加到docker组:

1
sudo usermod -aG docker $USER

然后,注销并重新登录以使更改生效。

10.更换 DNS 服务器

编辑 /etc/resolv.conf,添加可靠 DNS:

1
2
nameserver 8.8.8.8
nameserver 114.114.114.114

11.配置代理

  • 创建代理配置文件
1
2
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo nano /etc/systemd/system/docker.service.d/http-proxy.conf

添加内容(注意协议为 http://):注意HTTPS_PROXY也是http,没有s

1
2
3
[Service]
Environment="HTTP_PROXY=http://127.0.0.1:7897"
Environment="HTTPS_PROXY=http://127.0.0.1:7897"
  • 重启 Docker 服务
1
2
sudo systemctl daemon-reload
sudo systemctl restart docker
  • 验证配置生效
1
2
3
systemctl show docker --property Environment
# 预期输出:
# Environment=HTTP_PROXY=http://127.0.0.1:7897 HTTPS_PROXY=http://127.0.0.1:7897

12. 测试Docker

运行一个简单的Docker容器来测试安装是否成功:

1
docker run hello-world

如果一切正常,你应该会看到一条欢迎信息,表示Docker已经成功安装并运行。

如果报错:这个错误表明当前用户没有权限访问 Docker 守护进程。通常,Docker 需要 root 权限或用户必须属于 docker 组才能运行 Docker 命令

1
2
3
4
5
ubuntu@ip-172-31-23-31:~$ sudo usermod -aG docker $USER
ubuntu@ip-172-31-23-31:~$ docker run hello-world
docker: permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Head "http://%2Fvar%2Frun%2Fdocker.sock/_ping": dial unix /var/run/docker.sock: connect: permission denied.
See 'docker run --help'.
ubuntu@ip-172-31-23-31:~$

可能是使用ssh连接服务器,重新登录以应用组更改即可