参考:DevOps入门小结
Git版本控制
核心流程
四大核心区域定义
- 工作区(Working Directory):即本地电脑中存放项目文件的实际目录,是开发者日常编写代码、修改文件的区域,文件状态分为 “未跟踪(Untracked)” 和 “已跟踪(Tracked)”。
- 未跟踪:新创建的文件,Git 未记录其任何版本信息;
- 已跟踪:曾通过
git add纳入版本控制的文件,包括 “已修改(Modified)”“已暂存(Staged)”“未修改(Unmodified)” 三种状态。
- 暂存区(Staging Area/Index):是 Git 中的 “临时缓冲区”,位于
.git目录内,用于存放待提交的文件变更。通过git add命令可将工作区的修改同步到暂存区,暂存区的内容会在执行git commit时被提交到本地仓库。 - 本地仓库(Local Repository):位于项目根目录的
.git隐藏文件夹,是 Git 存储版本历史的核心区域。包含所有提交记录、分支信息、对象数据库(存储文件内容、提交对象等),即使断开网络也能完整查看历史和管理版本。 - 远程仓库(Remote Repository):位于服务器(如 GitHub、GitLab、自建 Git 服务器)的共享仓库,用于团队成员同步代码、协同开发。通过
git push将本地仓库的提交推送到远程,通过git pull/fetch从远程获取他人的提交。
命令与状态转换
| 命令 | 作用 | 状态转换 |
|---|---|---|
git add <文件> |
将工作区修改添加到暂存区 | 未跟踪 → 已暂存;已修改 → 已暂存 |
git commit -m "备注" |
将暂存区内容提交到本地仓库 | 已暂存 → 未修改 |
git push <远程> <分支> |
本地仓库提交推送到远程仓库 | 本地提交 → 远程提交 |
git checkout -- <文件> |
丢弃工作区未暂存的修改 | 已修改 → 未修改 |
git reset HEAD <文件> |
将暂存区的修改撤回到工作区 | 已暂存 → 已修改 |
协同操作
git fetch:仅获取,不合并
- 原理:从远程仓库拉取本地尚未有的提交记录,更新本地的远程跟踪分支(如
origin/main),但不会修改本地当前工作分支的代码。 - 流程:
git fetch origin main→ 拉取远程main分支的新提交 → 存储到本地origin/main分支 → 本地main分支保持不变。 - 优势:可在合并前通过
git diff main origin/main查看远程提交与本地的差异,评估是否会引发冲突,更安全可控。
git pull:获取并合并
- 原理:
git pull本质是git fetch+git merge的组合命令,拉取远程提交后会自动将其合并到本地当前工作分支。 - 流程:
git pull origin main→ 先执行git fetch origin main→ 再执行git merge origin/main into main→ 直接更新本地工作分支代码。 - 优势:操作简洁,一步完成 “获取 + 合并”,适合快速同步代码;劣势:若存在冲突,会直接进入合并冲突解决流程,新手可能难以处理。
最佳实践
团队协作优先使用 git fetch + git merge 组合
|
|
若确认远程提交与本地无冲突(如个人分支同步),可直接用 git pull 简化操作;
避免在多人协作的公共分支(如 main)上直接使用 git pull,建议先切换到个人分支,合并后再提交 PR/MR。
分支管理
核心分支概念
- 主分支(main/master):存放稳定可发布的代码,通常不允许直接提交,仅通过合并其他分支更新;
- 功能分支(feature/*):用于开发新功能,从主分支创建,功能完成后合并回主分支;
- 修复分支(hotfix/*):用于修复生产环境紧急 bug,从主分支创建,修复后同时合并回主分支和开发分支。
核心命令:
-
创建并切换到新分支:
git checkout -b <new_branch>- 原理:等价于
git branch <new_branch>(创建分支) +git checkout <new_branch>(切换分支);
- 原理:等价于
-
合并分支:
git merge <branch>-
原理:将指定分支的代码合并到当前所在分支;
-
如功能开发完成后,将
feature/login合并到main分支:1 2git checkout main # 切换到主分支 git merge feature/login # 合并功能分支 -
冲突处理:若合并时出现代码冲突(同一文件同一位置被不同修改),Git 会标记冲突文件,需手动编辑冲突内容后,执行
git add <冲突文件>+git commit完成合并。
-
-
删除分支:
git branch -d <branch>- 作用:删除已合并到主分支的无用分支,清理分支结构;
- 强制删除:若分支未合并(如废弃的功能分支),需用
git branch -D <branch>(大写 D)强制删除;
历史管理
git reset –hard <commit_id>:本地强制回滚
- 原理:将本地仓库、暂存区、工作区强制重置到指定的提交版本,丢弃该版本之后的所有提交记录;
- 直接修改本地版本历史,操作不可逆(丢弃的提交无法通过常规命令恢复),仅适用于本地未推送的提交。
- 严禁在公共分支使用!!
git revert <commit_id>:创建反向提交
- 原理:不删除原有提交记录,而是创建一个新的 “反向提交”,抵消指定提交的修改内容,保持版本历史的完整性;
- 修改会生成新的提交,可正常推送到远程仓库,适合撤销已推送到公共分支的错误提交。
- 公共分支优先使用
Docker与容器化
之前的文档写得比较详细了。
网络服务和转发
Nginx 反向代理配置
|
|
内网穿透
SSH 反向隧道
原理:
通过 SSH 连接将内网服务的端口 “反向映射” 到公网服务器(有公网 IP),使得公网用户可通过公网服务器的指定端口访问内网服务。
持久化隧道(autossh):
autossh 可自动检测 SSH 连接状态并重启隧道,确保稳定性:
|
|
- 适用场景:轻量需求(如个人博客、小型服务),无需额外服务端配置(仅需公网服务器支持 SSH)。
Frp 的 C/S 工作模式
Frp 是专门的内网穿透工具,采用客户端(frpc)/ 服务端(frps)架构,支持 TCP、UDP、HTTP 等多种协议,功能更强大。
工作原理:
- 服务端(frps):部署在有公网 IP 的服务器,监听客户端连接和用户访问请求。
- 客户端(frpc):部署在内网机器,与服务端建立长连接,将内网服务端口映射到服务端。
配置示例:
-
服务端(frps.ini):
1 2 3[common] bind_port = 7000 # 与客户端通信的端口 vhost_http_port = 8080 # HTTP 服务统一端口(可选)启动:
frps -c frps.ini -
客户端(frpc.ini):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17[common] server_addr = public-server-ip # 服务端公网 IP server_port = 7000 # 服务端 bind_port # 映射内网 SSH 服务(22 端口) [ssh] type = tcp local_ip = 127.0.0.1 local_port = 22 remote_port = 6000 # 访问服务端 6000 端口 → 内网 22 端口 # 映射内网 Web 服务(8080 端口) [web] type = http local_ip = 127.0.0.1 local_port = 8080 custom_domains = web.example.com # 绑定域名(需 DNS 解析到服务端 IP)启动:
frpc -c frpc.ini
零配置网络
具体使用看以前文章,这里分析原理
Tailscale 是基于 WireGuard 协议的零配置 VPN 工具,可快速构建跨网络的私有网络(如办公室、家庭、云服务器之间),实现设备间直接通信。
相当于让分散的网络组成一个私有网络,实现跨网直连
核心原理:
- P2P 直连:通过 STUN 协议检测设备是否可直接通信,优先建立点对点连接(无需中转服务器),速度快、延迟低。
- 中继 fallback:若设备位于严格 NAT 后无法直连,自动通过 Tailscale 中继服务器转发(加密传输)。
- 身份认证:基于 Tailscale 账号系统(支持 Google、GitHub 等 OAuth 登录),设备加入网络需管理员授权,安全可控。
- DNS 与子网路由:自动分配虚拟 IP(如
100.x.y.z),支持自定义 DNS 名称(如my-laptop.tailnet-name.ts.net),可通过子网路由暴露整个内网(如办公室网段)。优势场景:
- 远程办公:在家访问公司内网服务器,无需复杂 VPN 配置;
- 多地域设备组网:云服务器(AWS / 阿里云)、本地服务器、个人电脑组成私有网络,互访无感知;
- 安全通信:所有流量通过 WireGuard 加密,且无需暴露公网端口。
Q:为什么普通网络下 “跨网直连” 很难?
- NAT 隔离:家用 / 公司路由器会给设备分配 “内网 IP”(如
192.168.x.x),这些 IP 只在路由器内部有效,互联网上看不见。路由器通过 “NAT 转换” 把内网 IP 映射到唯一的公网 IP 上,但这个公网 IP 通常是动态的,且路由器会阻止外部主动访问内网设备。 - 防火墙限制:公司 / 家庭网络的防火墙会默认拦截陌生的外部连接,防止被攻击。
- 没有统一身份:两台设备不知道对方是谁,无法验证 “是否允许通信”。
Q:Tailscale 如何解决这些问题?
-
P2P 直连:绕开 “中间商”,设备直接对话
-
Tailscale 优先让设备之间 “直接握手”,不用经过第三方服务器转发,速度最快。
-
关键技术:STUN 协议STUN 协议的作用是让设备 “发现自己在互联网中的真实位置”。比如:
- 家里的电脑会先问 Tailscale 的 STUN 服务器:“我在互联网上的地址和端口是多少?”
- STUN 服务器回复:“你当前的公网 IP 是
203.0.113.5,端口是50000(路由器给你分配的临时端口)。” - 公司的服务器也会做同样的操作,得到自己的公网 IP 和端口。
- Tailscale 再把这两个 “地址 + 端口” 告诉对方,两台设备就可以直接发送数据了(比如家里电脑直接访问公司服务器的
203.0.113.10:50001)。
-
中继 fallback:实在连不上?找 “中介” 帮忙
如果设备在 “严格的 NAT 环境” 下(比如某些公司网络、校园网),STUN 也无法让它们直连,这时 Tailscale 会自动切换到 “中继模式”。
- 原理:Tailscale 会在全球部署多台 “中继服务器(DERP 服务器)”,两台设备都先连接到同一台中继服务器,数据通过中继转发。
- 安全性:即使经过中继,数据也是端到端加密的(中继服务器看不到内容),只有通信的两台设备能解密。
-
身份认证:确保 “连对人”,防止陌生人闯入
Tailscale 用一套严格的身份体系确保只有授权设备能加入网络:
- 账号绑定:所有设备必须登录同一个 Tailscale 账号(支持 Google、GitHub 等账号登录),相当于 “家庭住址”,只有这个 “家庭” 的设备才能互相看到。
- 授权机制:新设备登录后,需要管理员在 Tailscale 后台手动 “批准” 才能加入网络(类似小区门禁,保安确认后才放行)。
- 加密证书:每台设备会生成一对加密密钥,由 Tailscale 的 “密钥服务器” 颁发证书,通信时用证书验证对方身份(确保不是伪装的设备)。
-
子网路由:让 “整个内网” 都加入虚拟网络
-
如果你想让虚拟网络里的设备访问 “整个公司内网”(比如公司内网有
192.168.1.x网段的多台服务器),不用每台都装 Tailscale,只需: -
在内网找一台 “网关设备”(比如一台服务器)安装 Tailscale,并配置 “子网路由”,告诉 Tailscale:“我能访问
192.168.1.0/24这个网段”。 -
其他设备(如家里的电脑)就可以通过这台网关设备访问公司内网的所有机器(如
192.168.1.100)。
-
Q:为什么能绕过防火墙?
- 因为这个连接是由 “内网设备主动发起” 的,大多数防火墙会允许 “主动发起的连接的返回数据”。
文件服务
具体看以前文章,这里做一下整合
文件服务用于跨设备、跨系统共享文件,SMB/CIFS 适合 Windows 环境,SFTP 基于 SSH 更安全通用。
SMB/CIFS(Samba):Windows 友好的文件共享
Samba 实现了 SMB 协议,可让 Linux 与 Windows、macOS 无缝共享文件。
核心配置(/etc/samba/smb.conf):
|
|
用户管理:
- Samba 依赖系统用户,但密码独立管理:
|
|
访问方式:
- Windows:
Win + R输入\\samba-server-ip\public,输入 Samba 用户名密码; - Linux:
smbclient //samba-server-ip/public -U alice或挂载到本地mount -t cifs //server/public /mnt -o username=alice。
SFTP(基于 SSH):安全的文件传输
SFTP 是 SSH 的子协议,无需额外服务,仅需开启 SSH 服务即可使用,适合跨平台且对安全性要求高的场景。
限制用户目录(ChrootDirectory):
默认 SFTP 允许用户访问整个系统,通过配置可限制用户仅能访问指定目录(增强安全性):
-
修改 SSH 配置(
/etc/ssh/sshd_config):1 2 3 4 5 6 7 8 9# 注释原 Subsystem sftp /usr/lib/openssh/sftp-server Subsystem sftp internal-sftp # 使用内置 SFTP 模块 # 针对 sftpuser 组的配置 Match Group sftpuser ChrootDirectory /var/sftp/%u # 限制根目录(必须为 root 所有,权限 755) ForceCommand internal-sftp # 强制使用 SFTP,禁止 SSH 登录 AllowTcpForwarding no X11Forwarding no -
创建用户和目录:
1 2 3 4 5 6 7 8 9 10 11 12 13 14# 创建 sftpuser 组 sudo groupadd sftpuser # 创建用户(禁止登录 shell) sudo useradd -m -g sftpuser -s /usr/sbin/nologin sftp_alice # 设置密码 sudo passwd sftp_alice # 创建 Chroot 目录(权限必须正确,否则登录失败) sudo mkdir -p /var/sftp/sftp_alice/upload sudo chown root:root /var/sftp/sftp_alice # 根目录必须为 root 所有 sudo chmod 755 /var/sftp/sftp_alice sudo chown sftp_alice:sftpuser /var/sftp/sftp_alice/upload # 子目录可写 -
重启 SSH 服务:
sudo systemctl restart sshd
访问方式:
- 命令行:
sftp sftp_alice@server-ip(默认端口 22); - 图形工具:FileZilla、WinSCP(输入主机、端口、用户名密码)。
数据与应用
补充一下自动化备份
自动化备份:crontab 定时任务
通过 Linux 的crontab设置定时任务,可实现 MySQL 自动备份,避免人工操作遗漏。
(1)编写备份脚本(mysql_backup.sh)
|
|
- 注意:脚本中直接写密码有安全风险,建议通过
~/.my.cnf配置无密码登录(见下方补充)。
(2)添加执行权限
|
|
(3)设置crontab定时任务
|
|
- 格式说明:
分 时 日 月 周 命令,0 3 * * *表示每天 3 点 0 分执行。
(4)补充:无密码登录配置(~/.my.cnf)
|
|
设置权限:chmod 600 ~/.my.cnf,避免密码泄露。
Python 后端
Python 后端框架基于不同的网关协议,分为同步(WSGI)和异步(ASGI)两类
WSGI 与 ASGI:协议本质与区别
WSGI(Web Server Gateway Interface):同步网关协议
- WSGI 是 Python Web 应用与 Web 服务器(如 Nginx、Gunicorn)之间的标准接口,定义了二者的通信规范,仅支持同步请求处理。
- 工作原理:
- 客户端请求到达 Web 服务器(如 Nginx),转发给 WSGI 服务器(如 Gunicorn);
- WSGI 服务器为每个请求创建一个线程 / 进程,调用应用框架(如 Flask)的处理函数;
- 处理函数同步执行(执行期间线程 / 进程被阻塞),完成后返回响应。
- 代表框架:Flask、Django(默认)。
- 局限性:
- 面对 IO 密集型任务(如数据库查询、网络请求)时,线程 / 进程会被阻塞,无法处理其他请求,并发能力有限;
- 不支持 WebSocket 等长连接协议。
ASGI(Asynchronous Server Gateway Interface):异步网关协议
- ASGI 是 WSGI 的继任者,支持同步和异步请求处理,专为高并发和长连接场景设计。
- 工作原理:
- 基于事件循环(Event Loop)机制,用少量线程处理大量请求;
- 遇到 IO 操作(如等待数据库响应)时,会释放当前线程去处理其他请求,IO 完成后再回调继续执行;
- 原生支持 WebSocket、HTTP/2 等协议。
- 代表框架:FastAPI、Starlette、Django 3.0+(异步视图)。
- 优势:
- 处理 IO 密集型任务时,并发能力比 WSGI 高 10 倍以上;
- 支持长连接和异步语法,适合实时应用(如聊天、通知)。
FastAPI
FastAPI 是基于 ASGI 的高性能框架,原生支持异步语法和数据校验,开发效率和运行性能兼具。
async/await 异步语法
用于定义异步函数,实现非阻塞 IO 操作,提升并发能力。
-
基础示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18from fastapi import FastAPI import asyncio app = FastAPI() # 异步路由函数(用async def定义) @app.get("/async") async def async_endpoint(): # 模拟IO操作(如数据库查询、网络请求) await asyncio.sleep(1) # 非阻塞等待1秒(不占用线程) return {"message": "异步响应"} # 同步路由函数(用def定义,兼容同步代码) @app.get("/sync") def sync_endpoint(): # 同步IO操作(会阻塞线程) time.sleep(1) return {"message": "同步响应"} -
关键规则:
- 用
async def定义的函数可使用await调用其他异步函数(如异步数据库驱动asyncpg); - 若调用同步 IO 函数(如
requests.get),需用async def+ 线程池(避免阻塞事件循环); - 异步函数中不能有阻塞操作(如
time.sleep),必须用await调用异步版本(如asyncio.sleep)。
- 用
Pydantic 数据校验
FastAPI 依赖 Pydantic 库实现请求数据的自动校验和类型转换,确保输入数据符合预期。
-
示例:请求体校验
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15from fastapi import FastAPI from pydantic import BaseModel, EmailStr, Field app = FastAPI() # 定义数据模型(继承BaseModel) class User(BaseModel): name: str = Field(..., min_length=2, max_length=50) # 必传,字符串长度限制 age: int = Field(None, ge=0, le=120) # 可选,整数范围0-120 email: EmailStr # 自动验证邮箱格式 # 接收并校验请求体 @app.post("/users/") async def create_user(user: User): return {"user": user.dict(), "message": "用户创建成功"} -
校验效果:
- 若请求体不符合模型(如
age=-5、email="invalid"),FastAPI 会自动返回 422 错误,包含详细校验信息; - 支持自动类型转换(如字符串
"25"转为整数25); - 可通过
Field定义额外约束(如默认值、描述、正则匹配)。
- 若请求体不符合模型(如
-
适用场景:
- 请求参数(路径参数、查询参数、请求体)校验;
- 响应数据格式化(确保输出结构一致);
- 数据模型文档自动生成(FastAPI 的 Swagger 文档会基于 Pydantic 模型展示参数说明)。
AI 与 Agent
看以前文章