Python技术博客专栏 - 模块七:微服务架构与容器化部署
作者:耿雨飞 | 难度:中级 | 阅读时间:45分钟
导读
无论你用的是 FastAPI 还是 Django,你的代码最终都跑在 Linux 上;无论你的微服务拆得多精细,它们之间的通信都依赖网络协议。Linux 命令和网络知识是后端工程师的"空气"——平时感觉不到它的存在,但一旦出了问题(服务器 CPU 飙升、接口超时、DNS 解析失败),不会用就寸步难行。
本篇将系统梳理后端开发中最高频使用的 Linux 命令、Shell 脚本编写技巧、Systemd 服务管理、TCP/IP 和 HTTP 协议核心知识、Nginx 配置实战以及安全运维基础。不追求大而全,只讲面试会问、工作会用的内容。
学习目标
完成本篇学习后,你将能够:
- 熟练运用 Linux 命令排查服务器性能问题
- 编写实用的 Shell 脚本完成运维自动化任务
- 深入理解 TCP 三次握手/四次挥手、TLS 握手流程
- 掌握 Nginx 反向代理、负载均衡的配置方法
- 建立基本的服务器安全防护意识
一、Linux 常用命令
1.1 文件管理四剑客
find——按条件搜索文件:
# 查找7天前修改的日志文件find/var/log-name"*.log"-mtime+7-typef# 查找大于100MB的文件find/-size+100M-typef2>/dev/null# 查找并删除临时文件(-exec 执行命令)find/tmp-name"*.tmp"-mtime+3-execrm-f{}\;# 查找Python项目中所有包含 "TODO" 的文件find.-name"*.py"-execgrep-l"TODO"{}\;grep——文本内容搜索:
# 递归搜索目录下所有文件grep-rn"database_url"/app/config/# 正则匹配(-E 扩展正则)grep-E"ERROR|CRITICAL"/var/log/app.log# 排除目录grep-rn"import"--include="*.py"--exclude-dir=".venv"# 统计匹配行数grep-c"500"access.log# 显示匹配前后上下文grep-B3-A5"Traceback"/var/log/app.logawk——列处理与统计:
# 打印第1列和第4列(默认空格分隔)awk'{print $1, $4}'access.log# 统计HTTP状态码分布awk'{print $9}'access.log|sort|uniq-c|sort-rn# 计算响应时间平均值(假设第10列是响应时间)awk'{sum+=$10; count++} END {print sum/count}'access.log# 按条件过滤:只看5xx错误awk'$9 >= 500 {print $0}'access.logsed——流式文本编辑:
# 替换文件中的字符串(-i 原地修改)sed-i's/old_host/new_host/g'config.yaml# 删除空行sed-i'/^$/d'file.txt# 在第5行后插入内容sed-i'5a\new_line_content'file.txt# 打印第10-20行sed-n'10,20p'large_file.log1.2 进程管理
| 命令 | 用途 | 常用姿势 |
|---|---|---|
ps aux | 查看所有进程 | `ps aux |
top/htop | 实时监控进程 | 按 M 按内存排序,P 按 CPU 排序 |
kill -9 PID | 强制杀进程 | 慎用,优先用kill -15(SIGTERM) |
kill -15 PID | 优雅终止 | 给进程机会处理完当前请求 |
nohup cmd & | 后台运行+忽略挂断 | nohup python app.py > app.log 2>&1 & |
lsof -i :8000 | 查看端口占用 | 排查端口冲突 |
strace -p PID | 跟踪系统调用 | 排查进程卡死原因 |
信号(Signal)对比:
SIGTERM (15):优雅终止,进程可以捕获并清理资源SIGKILL (9):强制杀死,进程无法捕获,可能导致数据丢失SIGHUP (1):终端挂断,很多守护进程用它来重载配置SIGUSR1/USR2:用户自定义,常用于日志轮转
1.3 网络诊断
# ss:查看网络连接(替代 netstat)ss-tlnp# TCP监听端口 + 进程名ss-s# 连接状态统计ss state time-wait|wc-l# TIME_WAIT 数量# tcpdump:抓包分析tcpdump-ieth0 port80-wcapture.pcap# 抓HTTP包tcpdump-ianyhost10.0.0.5-nn# 抓特定主机流量tcpdump-ieth0'tcp[tcpflags] & tcp-syn != 0'# 只抓SYN包# curl:HTTP 请求调试curl-vhttps://api.example.com/health# 显示详细握手过程curl-o/dev/null-s-w"time_total: %{time_total}s\n"URL# 只看耗时curl-XPOST-H"Content-Type: application/json"\-d'{"key":"value"}'http://localhost:8000/api# dig/nslookup:DNS 解析digexample.com# 查看A记录digexample.com +trace# 追踪完整解析路径1.4 系统资源监控
# 内存:free -h$free-htotal usedfreeshared buff/cache available Mem: 16G8.2G1.5G 512M6.3G7.1G Swap: 4G 200M3.8G# 关键指标:看 available 而非 free(buff/cache 可回收)# 磁盘:df -h / du -shdf-h# 各分区使用情况du-sh/var/log/*# 各目录大小# IO:iostat -x 1iostat-x1# 每秒刷新,关注 %util 和 await# %util > 80% 表示磁盘接近饱和# await > 10ms 表示IO等待严重# 系统负载:uptime / vmstatuptime# 1/5/15分钟平均负载vmstat1# 每秒刷新:r(运行队列) b(阻塞) si/so(swap)性能排查"五步法":
top:看 CPU 和内存的大致情况iostat -x 1:排查磁盘 IO 瓶颈ss -s:看网络连接状态是否异常dmesg | tail:看内核是否有 OOM 等错误strace -p PID:定位具体进程卡在什么系统调用上
二、Shell 脚本编写
2.1 基础语法
#!/bin/bashset-euopipefail# 严格模式:出错即退出、未定义变量报错、管道错误传播# 变量APP_NAME="web-app"LOG_DIR="/var/log/${APP_NAME}"DATE=$(date+%Y%m%d)# 条件判断if[-f"${LOG_DIR}/app.log"];thenecho"Log file exists"elif[-d"${LOG_DIR}"];thenecho"Log directory exists but no log file"elsemkdir-p"${LOG_DIR}"fi# 循环forserverinweb-01 web-02 web-03;doecho"Checking${server}..."ssh"${server}""uptime"done# 函数check_service(){localservice_name=$1ifsystemctl is-active--quiet"${service_name}";thenecho"[OK]${service_name}is running"return0elseecho"[FAIL]${service_name}is not running"return1fi}check_service nginx check_service postgresqlset -euo pipefail的含义:
-e:任何命令失败(非零退出)立即退出脚本-u:引用未定义的变量时报错(而非当空字符串)-o pipefail:管道中任一命令失败则整个管道失败
这三个选项是生产脚本的必备设置,能避免大量隐蔽 Bug。
2.2 实用脚本模板
日志清理脚本:
#!/bin/bashset-euopipefailLOG_DIR="/var/log/myapp"KEEP_DAYS=30MAX_SIZE_MB=500echo"[$(date)] Starting log cleanup..."# 删除超过30天的日志find"${LOG_DIR}"-name"*.log"-mtime+${KEEP_DAYS}-deleteecho"Deleted logs older than${KEEP_DAYS}days"# 压缩超过500MB的日志(保留原始文件名.gz)find"${LOG_DIR}"-name"*.log"-size+${MAX_SIZE_MB}M\-execgzip{}\;echo"Compressed logs larger than${MAX_SIZE_MB}MB"# 报告当前磁盘使用echo"Current disk usage:$(du-sh${LOG_DIR}|cut-f1)"服务健康检查脚本:
#!/bin/bashset-euopipefailSERVICES=("nginx""postgresql""redis-server")ENDPOINTS=("http://localhost:8000/health""http://localhost:8001/health")ALERT_WEBHOOK="https://hooks.slack.com/services/xxx"alert(){localmessage=$1curl-s-XPOST"${ALERT_WEBHOOK}"\-H'Content-Type: application/json'\-d"{\"text\":\"[ALERT]${message}\"}">/dev/null}# 检查 systemd 服务forsvcin"${SERVICES[@]}";doif!systemctl is-active--quiet"${svc}";thenalert"${svc}is down on$(hostname)"systemctl restart"${svc}"# 尝试自动恢复fidone# 检查 HTTP 端点forurlin"${ENDPOINTS[@]}";dostatus=$(curl-s-o/dev/null-w"%{http_code}""${url}"||echo"000")if["${status}"!="200"];thenalert"Health check failed:${url}returned${status}"fidone三、Systemd 服务管理
3.1 编写 Service 文件
Systemd 是现代 Linux(CentOS 7+、Ubuntu 16.04+)的 init 系统,管理所有系统服务的启动和监控。
# /etc/systemd/system/myapp.service [Unit] Description=My Python Web Application After=network.target postgresql.service redis.service Wants=postgresql.service redis.service [Service] Type=exec User=appuser Group=appuser WorkingDirectory=/opt/myapp Environment=APP_ENV=production EnvironmentFile=/opt/myapp/.env ExecStart=/opt/myapp/.venv/bin/uvicorn main:app \ --host 0.0.0.0 --port 8000 --workers 4 ExecReload=/bin/kill -HUP $MAINPID ExecStop=/bin/kill -TERM $MAINPID Restart=on-failure RestartSec=5 StartLimitBurst=5 StartLimitIntervalSec=60 # 安全加固 NoNewPrivileges=true ProtectSystem=strict ProtectHome=true ReadWritePaths=/var/log/myapp /opt/myapp/data # 资源限制 LimitNOFILE=65536 MemoryMax=2G [Install] WantedBy=multi-user.target关键配置说明:
| 配置项 | 含义 |
|---|---|
After= | 在指定服务之后启动(只控制顺序,不强制依赖) |
Wants= | 弱依赖(依赖不存在也不影响本服务) |
Type=exec | 主进程启动即视为服务就绪(适合 uvicorn/gunicorn) |
Restart=on-failure | 非正常退出时自动重启 |
RestartSec=5 | 重启间隔5秒 |
StartLimitBurst=5 | 60秒内最多重启5次(防止无限重启) |
ProtectSystem=strict | 只读挂载文件系统(安全加固) |
LimitNOFILE=65536 | 最大文件描述符数 |
3.2 常用管理命令
# 生命周期管理systemctl start myapp# 启动systemctl stop myapp# 停止systemctl restart myapp# 重启systemctl reload myapp# 重载配置(不中断服务)systemctlenablemyapp# 开机自启systemctl disable myapp# 取消开机自启# 状态检查systemctl status myapp# 详细状态(包括最近日志)systemctl is-active myapp# 是否在运行systemctl is-enabled myapp# 是否开机自启# 修改 service 文件后必须执行systemctl daemon-reload# 日志查看(journalctl)journalctl-umyapp-f# 实时跟踪日志journalctl-umyapp--since"1h ago"# 最近1小时journalctl-umyapp-perr# 只看错误级别journalctl-umyapp --no-pager-n100# 最近100行四、网络基础
4.1 TCP/IP 协议栈
应用层 HTTP, gRPC, DNS, SMTP ↕ 传输层 TCP(可靠)/ UDP(快速) ↕ 网络层 IP, ICMP(路由寻址) ↕ 链路层 Ethernet, WiFi(物理传输)4.2 TCP 三次握手与四次挥手
三次握手(建立连接):
Client Server │ │ │──── SYN (seq=x) ──────────→│ ① 客户端发起连接请求 │ │ │←── SYN+ACK (seq=y,ack=x+1)─│ ② 服务端确认并同步 │ │ │──── ACK (ack=y+1) ─────────→│ ③ 客户端确认 │ │ │ 连接已建立 │为什么是三次而非两次?防止旧的重复连接请求突然到达服务端,导致服务端白白建立无效连接。第三次握手让客户端确认"我确实想建立这个连接"。
四次挥手(关闭连接):
Client Server │ │ │──── FIN (seq=u) ───────────→│ ① 客户端请求关闭 │ │ │←── ACK (ack=u+1) ──────────│ ② 服务端确认(可能还有数据要发) │ │ │←── FIN (seq=v) ────────────│ ③ 服务端数据发完,也请求关闭 │ │ │──── ACK (ack=v+1) ─────────→│ ④ 客户端确认 │ │ │ TIME_WAIT (2MSL) │ 客户端等待2MSL后关闭为什么是四次而非三次?TCP 是全双工的,每个方向需要独立关闭。服务端收到 FIN 后可能还有数据要发送,所以 ACK 和 FIN 分开发送。
TIME_WAIT 的作用:
- 确保最后的 ACK 能到达对端(如果丢了,对端会重发 FIN)
- 让网络中残留的旧报文消亡,避免影响新连接
生产中 TIME_WAIT 过多的处理:
# 查看 TIME_WAIT 数量ss-s|grepTIME-WAIT# 内核参数调优(/etc/sysctl.conf)net.ipv4.tcp_tw_reuse=1# 允许复用TIME_WAIT连接net.ipv4.tcp_max_tw_buckets=20000# TIME_WAIT最大数量net.ipv4.tcp_fin_timeout=30# FIN_WAIT_2 超时时间4.3 HTTP/HTTPS 协议
HTTP/1.1 vs HTTP/2 vs HTTP/3:
| 特性 | HTTP/1.1 | HTTP/2 | HTTP/3 |
|---|---|---|---|
| 传输层 | TCP | TCP | QUIC (UDP) |
| 多路复用 | 无(队头阻塞) | 有(二进制帧) | 有 |
| 头部压缩 | 无 | HPACK | QPACK |
| 服务器推送 | 无 | 支持 | 支持 |
| 连接建立 | TCP 3次 + TLS 2次 | 同 HTTP/1.1 | 0-RTT(首次1-RTT) |
| 队头阻塞 | 应用层+传输层 | 传输层仍有 | 完全解决 |
TLS 1.3 握手流程(1-RTT):
Client Server │ │ │── ClientHello ───────────────────→│ │ (支持的密码套件、密钥共享参数) │ │ │ │←─ ServerHello + Certificate ─────│ │ (选定密码套件、证书、密钥共享) │ │ │ ← 此时已可计算对称密钥 │── Finished ──────────────────────→│ │ │ │←─ Finished ──────────────────────│ │ │ │ 开始加密传输(共1个RTT) │TLS 1.3 相比 TLS 1.2 的改进:
- 握手从 2-RTT 降为 1-RTT(首次),支持 0-RTT(重连)
- 移除不安全的算法(RSA 密钥交换、RC4、SHA-1)
- 前向保密(Forward Secrecy)成为默认要求
4.4 DNS 解析流程
用户输入 www.example.com │ ▼ 浏览器 DNS 缓存 → 命中则直接返回 │ Miss ▼ 操作系统 DNS 缓存 (/etc/hosts) │ Miss ▼ 本地 DNS 服务器(递归解析器) │ Miss ▼ 根域名服务器 → 返回 .com 的 NS 地址 │ ▼ .com 顶级域名服务器 → 返回 example.com 的 NS 地址 │ ▼ example.com 权威服务器 → 返回 www.example.com 的 A 记录(IP)DNS 记录类型:
- A:域名 → IPv4 地址
- AAAA:域名 → IPv6 地址
- CNAME:域名别名 → 另一个域名
- MX:邮件交换记录
- TXT:文本记录(常用于域名验证、SPF)
- NS:指定域名的权威DNS服务器
4.5 正向代理 vs 反向代理
正向代理(代理客户端): 反向代理(代理服务端): Client → [Proxy] → Server Client → [Reverse Proxy] → Server - 客户端知道代理的存在 - 客户端不知道代理的存在 - 代理代表客户端发请求 - 代理代表服务端接请求 - 用途:翻墙、缓存、访问控制 - 用途:负载均衡、SSL终止、缓存 - 例:Squid、V2Ray - 例:Nginx、HAProxy、Envoy4.6 Nginx 配置实战
# /etc/nginx/conf.d/myapp.conf # 上游服务组(负载均衡) upstream myapp_backend { least_conn; # 最少连接策略 server 127.0.0.1:8000 weight=3; server 127.0.0.1:8001 weight=2; server 127.0.0.1:8002 backup; # 备用节点 keepalive 32; # 与上游保持长连接 } server { listen 443 ssl http2; server_name api.example.com; # SSL 配置 ssl_certificate /etc/ssl/certs/example.com.pem; ssl_certificate_key /etc/ssl/private/example.com.key; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; # 安全头 add_header X-Frame-Options DENY; add_header X-Content-Type-Options nosniff; add_header Strict-Transport-Security "max-age=31536000" always; # API 反向代理 location /api/ { proxy_pass http://myapp_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; # 超时设置 proxy_connect_timeout 5s; proxy_read_timeout 30s; proxy_send_timeout 10s; # 错误时切换到下一个上游 proxy_next_upstream error timeout http_502 http_503; } # 静态资源(直接由Nginx提供) location /static/ { alias /opt/myapp/static/; expires 30d; add_header Cache-Control "public, immutable"; } # 健康检查端点(不记录日志) location /health { proxy_pass http://myapp_backend; access_log off; } } # HTTP → HTTPS 重定向 server { listen 80; server_name api.example.com; return 301 https://$server_name$request_uri; }Nginx 负载均衡策略:
| 策略 | 指令 | 特点 |
|---|---|---|
| 轮询 | 默认 | 平均分配 |
| 加权轮询 | weight=N | 按权重分配 |
| 最少连接 | least_conn | 优先分配给连接数少的 |
| IP哈希 | ip_hash | 同一客户端固定后端(会话保持) |
| 一致性哈希 | hash $key consistent | 缓存友好 |
五、安全运维
5.1 SSH 密钥管理
# 生成密钥对(Ed25519 比 RSA 更安全更快)ssh-keygen-ted25519-C"gengyufei@company.com"# 将公钥部署到服务器ssh-copy-id-i~/.ssh/id_ed25519.pub user@server# SSH 配置文件(~/.ssh/config)Host prod-* User deploy IdentityFile ~/.ssh/id_ed25519 StrictHostKeyCheckingyesHost prod-web-01 HostName10.0.1.10 Host prod-web-02 HostName10.0.1.11SSH 安全加固(/etc/ssh/sshd_config):
# 禁止密码登录(只允许密钥)PasswordAuthentication no PubkeyAuthenticationyes# 禁止 root 直接登录PermitRootLogin no# 限制登录用户AllowUsers deploy appuser# 修改默认端口(减少扫描攻击)Port22022# 超时断开ClientAliveInterval300ClientAliveCountMax25.2 防火墙配置
firewalld(CentOS 7+ / RHEL 8+):
# 查看当前规则firewall-cmd --list-all# 开放端口firewall-cmd--permanent--add-port=443/tcp firewall-cmd--permanent--add-port=8000/tcp# 只允许特定IP访问firewall-cmd--permanent--add-rich-rule=' rule family="ipv4" source address="10.0.0.0/24" port port="5432" protocol="tcp" accept'# 重载生效firewall-cmd--reloadiptables(底层,适合精细控制):
# 基本策略:默认拒绝入站iptables-PINPUT DROP iptables-PFORWARD DROP iptables-POUTPUT ACCEPT# 允许已建立的连接iptables-AINPUT-mstate--stateESTABLISHED,RELATED-jACCEPT# 允许本地回环iptables-AINPUT-ilo-jACCEPT# 允许SSH(限制源IP)iptables-AINPUT-s10.0.0.0/24-ptcp--dport22022-jACCEPT# 允许HTTP/HTTPSiptables-AINPUT-ptcp--dport80-jACCEPT iptables-AINPUT-ptcp--dport443-jACCEPT# 限制连接速率(防DDoS)iptables-AINPUT-ptcp--dport80-mlimit--limit100/s --limit-burst200-jACCEPT5.3 日志审计
# 查看登录记录last# 成功登录lastb# 失败登录who# 当前在线用户# 查看sudo操作记录grep"sudo"/var/log/auth.log# auditd 审计系统# 监控关键文件修改auditctl-w/etc/passwd-pwa-kuser_modify auditctl-w/etc/ssh/sshd_config-pwa-kssh_config# 查看审计日志ausearch-kuser_modify--starttoday5.4 容器安全基线
| 检查项 | 推荐做法 | 原因 |
|---|---|---|
| 运行用户 | 非 root(USER appuser) | 防止容器逃逸获得宿主机root |
| 基础镜像 | 定期更新,扫描漏洞 | CVE漏洞修复 |
| 能力限制 | --cap-drop ALL --cap-add NET_BIND_SERVICE | 最小权限原则 |
| 只读文件系统 | --read-only+ tmpfs 挂载 | 防止容器内被篡改 |
| 资源限制 | --memory --cpus | 防止单容器耗尽主机资源 |
| 镜像签名 | Docker Content Trust | 确保镜像来源可信 |
| 网络隔离 | 自定义network,最小连通性 | 减少攻击面 |
面试高频题汇总
Q1:如何排查一个 Linux 服务器的性能问题?
系统性排查方法(USE 方法):对每种资源检查 Utilization(使用率)、Saturation(饱和度)、Errors(错误)。
实际排查步骤:
先看大盘:
top或htop- CPU 使用率高?看哪个进程占用最多
- 内存使用率高?看是否有内存泄漏
- Load Average 高?和 CPU 核数对比
CPU 瓶颈:
top→ 按 P 排序 → 找到高 CPU 进程perf top或py-spy(Python 进程)找热点函数vmstat 1→ 看r列(运行队列长度)
内存瓶颈:
free -h→ 看 available 是否充足vmstat 1→ 看si/so(swap in/out),非零说明内存不足dmesg | grep OOM→ 是否触发了 OOM Killer
IO 瓶颈:
iostat -x 1→%util > 80%表示磁盘饱和iotop→ 找出高 IO 的进程await > 10ms表示 IO 等待严重
网络瓶颈:
ss -s→ 大量 TIME_WAIT 或 CLOSE_WAIT 异常sar -n DEV 1→ 网络带宽是否打满netstat -s | grep retransmit→ 丢包重传
Q2:HTTP 和 HTTPS 的区别是什么?TLS 握手的流程?
核心区别:
| 维度 | HTTP | HTTPS |
|---|---|---|
| 协议 | 明文传输 | TLS 加密传输 |
| 端口 | 80 | 443 |
| 安全性 | 可被窃听、篡改 | 机密性+完整性+身份认证 |
| 性能 | 无额外开销 | TLS握手增加1-2 RTT |
| 证书 | 不需要 | 需要CA签发证书 |
TLS 1.3 握手(1-RTT):
- Client → Server:ClientHello(支持的密码套件 + 密钥共享参数)
- Server → Client:ServerHello + 证书 + 密钥共享 + Finished
- Client 验证证书(CA链验证)→ 计算对称密钥 → 发送 Finished
- 握手完成,后续全部对称加密传输
TLS 保证了三个安全属性:
- 机密性:对称加密(AES-GCM/ChaCha20)
- 完整性:MAC(消息认证码)
- 身份认证:数字证书(CA签名 → 证明服务器身份)
Q3:Nginx 的反向代理是如何工作的?
工作流程:
- 客户端发送请求到 Nginx(如
https://api.example.com/api/users) - Nginx 根据
server_name和location匹配规则 - 将请求转发到
proxy_pass指定的上游服务(如http://127.0.0.1:8000) - Nginx 收到上游响应后返回给客户端
Nginx 在反向代理中的核心价值:
- 负载均衡:多个上游实例间分发流量
- SSL终止:Nginx处理HTTPS解密,后端只需HTTP
- 静态资源分离:静态文件直接由Nginx返回,不经过应用服务器
- 缓存:缓存上游响应,减少后端压力
- 连接管理:与后端保持长连接(keepalive),减少TCP开销
- 安全防护:隐藏后端真实地址、限流、防DDoS
关键配置:
proxy_set_header X-Real-IP:传递真实客户端IPproxy_next_upstream:后端出错时自动切换到下一个upstream keepalive:与后端保持连接复用
Q4:TCP 三次握手和四次挥手的过程?
三次握手:
- SYN:客户端发送 SYN=1,seq=x(“我想建立连接”)
- SYN+ACK:服务端回复 SYN=1,ACK=1,seq=y,ack=x+1(“同意,我也想建立”)
- ACK:客户端回复 ACK=1,ack=y+1(“确认,连接建立”)
为什么三次:防止历史重复连接的 SYN 请求到达服务端后建立无效连接(服务端发了 SYN+ACK 后如果客户端不回 ACK,服务端会超时关闭)。
四次挥手:
- FIN:客户端发送 FIN(“我数据发完了”)
- ACK:服务端确认(“收到,但我可能还有数据”)
- FIN:服务端发送 FIN(“我也发完了”)
- ACK:客户端确认(进入 TIME_WAIT 等待 2MSL)
为什么四次:TCP 全双工,每个方向需要独立关闭。步骤 2 和 3 不能合并,因为服务端收到 FIN 后可能还有数据要发送。
TIME_WAIT(2MSL):
- MSL = Maximum Segment Lifetime(通常60秒)
- 目的1:确保最后的 ACK 能到达(如果丢了对方会重发 FIN)
- 目的2:让网络中残留的旧报文全部消亡
本章总结
| 知识域 | 核心要点 |
|---|---|
| 命令行 | find/grep/awk/sed 四剑客处理日志和配置文件 |
| 进程管理 | SIGTERM 优于 SIGKILL,掌握信号的含义 |
| 性能排查 | top→iostat→ss→dmesg→strace 五步法 |
| Shell脚本 | set -euo pipefail是生产脚本的标配 |
| Systemd | 理解 service 文件各字段含义,掌握 journalctl |
| TCP | 三次握手防止旧连接、四次挥手因为全双工 |
| TLS | 1.3 一个RTT完成握手,保证机密性+完整性+身份认证 |
| Nginx | 反向代理的核心:负载均衡+SSL终止+静态分离 |
| 安全 | 禁密码登录+非root运行+最小权限+定期审计 |
下一篇预告
第23篇:Python 测试策略 – 从单元测试到集成测试
代码写好还不够,如何证明它是正确的?下一篇我们将深入 pytest 框架的 fixture 机制与参数化测试、Mock 的正确使用时机、异步代码的测试方法、FastAPI/Django 的 API 测试实践,以及代码覆盖率的合理目标设定,帮你建立系统的测试策略。
Python技术博客专栏| 第22篇 / 共25篇
上一篇:Docker与Kubernetes容器化部署
下一篇:Python测试策略