主题
计算机基础概念与术语:写给零基础的运维转行者
这份文档是给谁看的
给完全没有 IT 基础、正在转行做运维的人。
如果你:看不懂同事开会时的缩写、搜到一个名词的解释反而更糊涂、 不知道"学到了什么程度算入门"——这份文档就是为你写的。
写作原则:
- 每个概念先说"它要解决什么问题",再说"它是什么"。因为不知道痛点,定义就是死记硬背。
- 每个概念都给一个生活化的类比。类比不精确,但能让你先"有感觉",再抠细节。
- 每个概念都告诉你运维在哪用到它。你不是来考试的,是来干活的。
- 说清容易混淆的概念之间的区别(比如「进程 vs 线程」「TCP vs UDP」)。这是最能体现你懂没懂的地方。
怎么读这份文档
不用从第一页读到最后。它是一本手册,不是一本教材。
- 第一次读:只看每节的"一句话定义"和"生活类比",20 分钟刷完,建立印象。
- 遇到不懂的名词:跳过来查,看"运维在哪用到它"。
- 面试或工作前:看每节的"容易混淆"部分,这是最容易被问到的。
目录
| 部分 | 内容 | 关键词 |
|---|---|---|
| 第一部分 | 计算机是怎么工作的 | CPU、内存、磁盘、进程、操作系统、虚拟化 |
| 第二部分 | 网络基础 | IP、子网、端口、DNS、路由、防火墙、NAT |
| 第三部分 | 网络协议 | TCP/UDP、HTTP/HTTPS、三次握手、TLS |
| 第四部分 | Web 与前后端 | 浏览器、静态动态、反向代理、Cookie、JWT |
| 第五部分 | 数据与存储 | 数据库、索引、事务、缓存、文件系统 |
| 第六部分 | 服务端与中间件 | 中间件、消息队列、微服务、容器、K8s |
| 第七部分 | 运维核心能力 | Shell、脚本、监控、日志、权限 |
| 第八部分 | 工程协作 | Git、CI/CD、环境、配置管理、IaC |
| 第九部分 | 安全基础 | 认证、授权、加密、证书、常见攻击 |
| 第十部分 | 云与架构 | 云服务、负载均衡、高可用、SLA |
| 附录 | 缩写速查、易混淆对照、学习路径 | —— |
第一部分 计算机是怎么工作的
1.1 计算机的本质:一台"看不懂但很快"的机器
一句话:计算机就是按顺序执行一大堆极简单指令的机器,快到你感觉它"聪明"。
它到底在做什么:计算机只会做加减法和条件跳转,但这些操作每秒能执行几十亿次。 复杂功能(比如显示一张图片、播放视频)都是这些简单操作堆出来的。
运维视角:你以后会遇到"CPU 打满""内存溢出""磁盘 IO 高"这类问题。 这些现象的本质是:某个环节的处理速度跟不上请求的到来速度。 理解"计算机资源分几类",你就能定位是哪一类资源不够了。
计算机的四大核心资源(记住这四个,排查问题就有一半思路了):
| 资源 | 作用 | 生活类比 | 不够时会怎样 | 运维常用命令 |
|---|---|---|---|---|
| CPU | 计算 | 厨师的数量 | 请求处理慢、排队、超时 | top / htop |
| 内存 | 临时存放正在用的数据 | 厨师的操作台 | 变慢(开始用硬盘),再严重就 OOM 被杀 | free -h |
| 磁盘 | 长期存放数据 | 仓库货架 | 读写慢、写满了服务崩 | df -h / iostat |
| 网络 | 与外界交换数据 | 传菜口 | 请求超时、丢包 | ping / ss / iftop |
新手最常搞错的一个点
"内存不够,我加个硬盘就好了吧?"——不行,这是两回事。
- 内存(RAM):断电就没了,快,贵。程序运行时的数据放这里。
- 硬盘/磁盘(Disk):断电还在,慢,便宜。数据库文件、日志放这里。
类比:内存是操作台(要能立刻拿到手上的东西),磁盘是仓库(存着但不常用)。 操作台太小,厨师(CPU)就总要跑去仓库拿东西,效率暴跌(这就是"swap",性能会降几十倍)。
1.2 操作系统(OS):硬件的大管家
一句话:操作系统是一个"中间层"程序,帮所有其他程序管理硬件资源。
为什么需要它:如果没有操作系统,每个程序都要自己去操作硬盘的磁头、 处理键盘中断、管理内存地址——程序员会疯掉,而且两个程序可能同时写同一块内存而互相破坏。
操作系统提供的五件事(这五件也是运维天天打交道的):
| 能力 | 说明 | 运维相关 |
|---|---|---|
| 进程管理 | 决定哪个程序什么时候用 CPU,用多少 | 进程卡死、僵尸进程、杀进程 |
| 内存管理 | 给每个进程分配独立内存空间,互不干扰 | OOM、内存泄漏 |
| 文件系统 | 把磁盘抽象成"目录 + 文件" | 权限、软链接、inode 满了 |
| 设备与网络 | 统一的接口访问网卡、磁盘、键盘 | 网卡绑定、驱动 |
| 权限管理 | 谁能做什么 | 这也是安全的基石 |
主流服务器操作系统:
| 系统 | 全称/来源 | 说明 | 服务器占比 |
|---|---|---|---|
| Linux(及各发行版) | 开源 | 服务器绝对主流 | > 95% |
| · CentOS / Rocky / AlmaLinux | RedHat 系 | 企业常用;CentOS 已停止维护,转 Rocky/Alma | 高 |
| · Ubuntu / Debian | Debian 系 | 云上与开发环境常用 | 高 |
| · 麒麟 / 统信 UOS | 国产 | 信创要求场景 | 增长中 |
| Windows Server | 微软 | 老企业内部系统、.NET 应用 | 少 |
| Unix(AIX/Solaris) | IBM/Oracle | 银行核心系统还在用 | 极少但存在 |
运维必须搞清"发行版"和"内核"的区别
很多新人搞混。其实是两层:
- 内核(Kernel):Linux 内核,就是 Linus 写的那个,是所有发行版共用的"心脏"。
uname -r看的是它。 - 发行版(Distribution):内核 + 一堆软件包管理工具 + 默认配置,打包在一起。比如 Ubuntu、Rocky。
为什么重要:你从网上抄的命令跑不通,往往就是因为发行版不同—— CentOS 用 yum/dnf 装软件,Ubuntu 用 apt。 看教程时一定要先确认它的发行版,这是新手最常踩的坑。
1.3 进程、线程、协程:最容易混淆的三个词
这三个词几乎每个 JD 都会提到,但它们的关系常被说错。
先用一个类比:
想象一家餐厅。
- 进程 = 一家餐厅(有自己的店面、厨房、资金,是独立经营的实体)
- 线程 = 餐厅里的员工(共享同一家餐厅的厨房和设备,但各自干各自的活)
- 协程 = 一个员工同时处理多件事(一边炒菜一边看着汤,通过"快速切换"来并行)
准确的区别:
| 维度 | 进程 Process | 线程 Thread | 协程 Coroutine |
|---|---|---|---|
| 定义 | 运行中的程序的实例 | 进程内的执行单元 | 用户态的轻量级"线程" |
| 资源 | 独立的内存空间、文件句柄 | 共享所属进程的内存 | 共享所属线程的栈 |
| 开销 | 大(创建要几十 MB、毫秒级) | 中(几 MB、微秒级) | 极小(几 KB) |
| 切换代价 | 高(要切换页表) | 中(要内核参与) | 极低(用户自己切) |
| 隔离性 | 强(一个进程崩了不影响别人) | 弱(一个线程崩了整个进程挂) | 最弱 |
| 谁调度 | 操作系统 | 操作系统 | 程序自己(或运行时) |
| 数量级 | 几百~几千 | 几千~几万 | 几十万~百万 |
运维在哪里用到它:
ps -ef、top看的是进程。- Nginx 有"worker 进程"和"多线程"两种模式,配置里的
worker_processes就是进程数。 - Java 应用一个进程里跑几百个线程;Go 程序是"协程(goroutine)"模型,能开几十万。
- 排查"线程死锁":Java 用
jstack打印线程栈,看哪个线程卡在等锁。
两个最常见的错误理解
- ❌ "多线程一定比多进程快"。 不一定。 多进程因为隔离性好,一个崩了不影响其他,更稳定; 多线程共享内存,通信快但容易出并发 bug(数据被两个线程同时改坏)。 实际选型看场景:Nginx 用多进程(稳定优先),Java 应用用多线程(性能优先)。
- ❌ "并发就是同时执行"。 并发(Concurrency) = 交替执行(单核也能并发); 并行(Parallelism) = 真正同时执行(必须多核)。 餐厅 1 个厨师来回炒 3 个菜是"并发",3 个厨师各炒一个是"并行"。
1.4 虚拟化与容器:一台机器怎么当多台用
要解决的问题:一台服务器有 64 核 256G 内存,但一个应用只用 2 核 4G,太浪费了。
两代解决方案:
| 方案 | 原理 | 隔离性 | 开销 | 启动速度 | 类比 |
|---|---|---|---|---|---|
| 虚拟机(VM) | 用 Hypervisor 模拟出完整硬件,装一整套操作系统 | 极强(像两台独立电脑) | 大(每个 VM 跑完整 OS,几 GB 内存) | 分钟级 | 盖一栋独立小楼 |
| 容器(Container) | 用 Linux 的 namespace + cgroup 做隔离,共享宿主机内核 | 强(但共享内核) | 小(只打包应用 + 依赖,几十 MB) | 秒级 | 在一栋楼里隔出很多房间 |
关键区别一句话:虚拟机虚拟的是硬件,容器虚拟的是操作系统。
为什么容器会取代虚拟机成为主流:
- 启动快:秒级 vs 分钟级 → 才能做"弹性扩缩容"
- 体积小:镜像几十 MB vs 系统镜像几 GB → 传输和存储便宜
- 资源利用率高:同一台机器能跑更多应用
- "一次构建,处处运行":应用 + 依赖打包在一起,不会出现"我本地能跑,服务器上不行"
别把 Docker 和容器搞混
- 容器是一种技术和理念(Linux 的 namespace/cgroup 能力)。
- Docker是最流行的实现和工具,它让容器变得好用(有镜像、有仓库、有简单命令)。
- 现在还有 containerd(K8s 实际用的运行时)、Podman(无守护进程)等。
类比:容器是"自动挡汽车"这个技术,Docker 是"某个品牌的自动挡汽车"。 K8s 里说的容器运行时(CRI),用的是 containerd 或 CRI-O,不一定是 Docker(K8s 1.24 之后移除了 Docker 支持)。
Docker 的三个核心概念(必须搞清):
| 概念 | 说明 | 类比 |
|---|---|---|
| 镜像 Image | 只读的模板,包含应用和依赖 | 一张"光盘" |
| 容器 Container | 镜像运行起来的实例 | 光盘放进播放器在播放 |
| 仓库 Registry | 存放和分发镜像的地方 | 软件下载站(如 Harbor、Docker Hub) |
容器不是虚拟机,这三点千万别搞错
- 容器里的数据会丢。容器删除,里面的文件就没了。 要持久化必须挂载卷(volume)或存到外部(数据库、对象存储)。 新手最常见的惨案:把数据库跑在容器里,没挂卷,
docker rm之后数据全没了。 - 容器里不要跑"多个守护进程"。容器的设计是"一个容器一个进程"。 想在容器里同时跑 Nginx + PHP + MySQL?那说明你应该拆成三个容器。
- 容器里的 root 不等于宿主机的 root(默认有 namespace 隔离), 但如果配置了
--privileged,那就等于宿主机 root 了,极其危险。
1.5 编程语言速览:你不需要会写,但要看得懂
运维不需要精通编程,但必须能看懂常见语言的特征,因为不同语言的应用部署方式不同。
| 语言 | 特征 | 编译/运行方式 | 运维关注点 | 常见场景 |
|---|---|---|---|---|
| Java | 跨平台、生态庞大、GC 回收内存 | 编译成 .class/.jar,跑在 JVM 上 | 堆内存配置、GC 调优、jstack 排障 | 后端主流(电商、金融) |
| Go | 编译成单个二进制、并发强、内存占用低 | 直接编译成可执行文件 | 交叉编译、二进制部署 | 云原生(K8s、Docker) |
| Python | 语法简单、库多、解释执行 | 解释执行,需装解释器 | 依赖管理(pip/虚拟环境) | 运维脚本、AI、爬虫 |
| Node.js | JS 跑在服务端、适合 IO 密集 | 解释执行,需 node 运行时 | 前端构建、SSR | 前端工具链、BFF 层 |
| PHP | 上手快、Web 经典 | 解释执行,常与 Nginx 配合 | PHP-FPM 进程管理 | 传统 Web、中小网站 |
| C/C++ | 性能极致、手动管理内存 | 编译成二进制 | 依赖库、段错误排查 | 数据库、中间件底层 |
| Shell/Bash | 命令的集合,用于自动化 | 解释执行 | 运维的核心技能 | 脚本、自动化 |
| SQL | 操作数据库的查询语言 | —— | 必须掌握 | 一切数据操作 |
一个判断:JVM 应用的内存问题
Java 应用最经典的运维问题就是内存。你要知道:
- 堆内存(Heap):
-Xmx设置上限,这是 Java 对象待的地方。 - 如果
-Xmx设得比容器 limit 还大 → 容器被 OOMKilled(K8s 常见故障)。 正确做法:-Xmx设为容器 limit 的 70% 左右,留出空间给 JVM 自身(元空间、线程栈、直接内存)。 - Pod 里看不到 JVM 的 OOM:JVM 内存超了是自己抛
OutOfMemoryError, 容器内存超了是被内核 OOMKiller 杀掉(kubectl describe里能看到OOMKilled)。 这两种现象要分清,排查方向完全不同。
第二部分 网络基础
为什么网络对运维如此重要
运维事故里,超过一半和网络有关。 服务连不上、超时、丢包、DNS 解析失败、端口不通、证书过期—— 这些问题每天都在发生。网络基础不牢,你连问题在哪一层都判断不出来。
2.1 网络分层:为什么要把简单的事情搞复杂
先看一个"如果只有一层会怎样"的思考:
你要给朋友发一封信。如果规定"必须自己走过去送",那稍有变化(朋友搬家、要跨国)就麻烦了。
网络分层的核心思想:每一层只解决一类问题,并向上层提供干净的接口。 这样"送信"这件事就拆成了:写内容(应用层)→ 装信封(传输层)→ 写地址路由(网络层)→ 骑车送(链路层)。
OSI 七层 vs TCP/IP 四层(对照记忆):
图 2-1 OSI 七层 vs TCP/IP 四层:理论模型与工程模型的对应关系
记住这个口诀就够了
"物数网传会表应"(从下到上:物理、数据链路、网络、传输、会话、表示、应用)。
但工作中更实用的是记住"每一层出问题时的现象":
| 层 | 典型设备/协议 | 出问题的现象 | 排查工具 |
|---|---|---|---|
| 物理层 | 网线、光模块、网卡 | 完全不通、网卡 down | ethtool、看网口灯 |
| 链路层 | 交换机、ARP、VLAN | 同网段不通、ARP 表异常 | arp -a、ip neigh |
| 网络层 | 路由器、IP、ICMP | ping 不通(跨网段) | ping、traceroute |
| 传输层 | 防火墙、TCP/UDP、端口 | 端口不通、连接被拒 | telnet、nc、ss |
| 应用层 | HTTP、DNS、证书 | 502/404、解析失败、证书报错 | curl、dig、openssl |
排查网络问题的黄金顺序:从下往上,逐层确认。 先 ping 通不通(网络层)→ 再看端口(传输层)→ 再 curl 看应用(应用层)。 不要一上来就怀疑应用代码,90% 的问题在网络和配置。
2.2 IP 地址:互联网的门牌号
一句话:IP 地址是网络中一台设备的唯一标识,让数据能找到目的地。
IPv4 的样子:192.168.1.100,四段数字,每段 0~255(共 32 位)。
两个关键概念:
| 类型 | 说明 | 例子 |
|---|---|---|
| 公网 IP | 全世界唯一,能直接被互联网访问 | 8.8.8.8(Google DNS) |
| 私网 IP | 内网专用,不同内网可以重复,不能直接上公网 | 10.x.x.x、172.16~31.x.x、192.168.x.x |
私网 IP 段(背下来,看到就知道是内网):
| 网段 | 范围 | 常见用途 |
|---|---|---|
| A 类私网 | 10.0.0.0 ~ 10.255.255.255 | 大型企业、云上 VPC |
| B 类私网 | 172.16.0.0 ~ 172.31.255.255 | 中型网络、Docker 默认 |
| C 类私网 | 192.168.0.0 ~ 192.168.255.255 | 家庭、小型办公网络 |
IPv4 地址用完了,IPv6 是怎么回事
IPv4 只有 32 位,约 43 亿个地址,2019 年就分配完了。所以有了:
- NAT(网络地址转换):让一堆私网机器共用 1 个公网 IP 上网。家里路由器就是这么干的。
- IPv6:128 位,理论上给地球上每粒沙子都能分一个地址。 写法如
2001:0db8:85a3::8a2e:0370:7334(可以用::省略连续的 0)。
运维现状:大部分公司还是 IPv4 + NAT,IPv6 在逐步推进(尤其是移动端 App 要求支持 IPv6)。
2.3 子网掩码与 CIDR:地址的"分组"
一句话:子网掩码用来判断"哪些 IP 和我在同一个局域网内,可以直接说话;哪些需要经过路由器"。
CIDR 写法(现在都用这个):192.168.1.0/24
/24表示前 24 位是网络号,后 8 位是主机号。- 所以这个网段能容纳
2^8 - 2 = 254台主机(去掉网络地址.0和广播地址.255)。
常见掩码速查表(运维必备):
| CIDR | 子网掩码 | 可用主机数 | 常见用途 |
|---|---|---|---|
/32 | 255.255.255.255 | 1 | 单个主机(如某个具体 IP 的规则) |
/30 | 255.255.255.252 | 2 | 点对点链路(两台设备直连) |
/28 | 255.255.255.240 | 14 | 小型子网 |
/26 | 255.255.255.192 | 62 | 小部门 |
/24 | 255.255.255.0 | 254 | 最常用(一个 C 类网段) |
/23 | 255.255.254.0 | 510 | 较大网段 |
/22 | 255.255.252.0 | 1022 | K8s 单节点 Pod 网段 |
/16 | 255.255.0.0 | 65534 | 大型网络、K8s Pod 网段 |
怎么快速算? 记住:主机数 = 2^(32 - CIDR位数) - 2。 比如 /24 → 2^(32-24) - 2 = 2^8 - 2 = 254。
一个真实事故:Pod 网段和办公网段冲突
某公司 K8s 集群规划了 Pod 网段 192.168.0.0/16, 而公司办公网正好在用 192.168.1.0/24。 结果:同事在办公室访问集群里某个服务,请求被路由到了自己的电脑上,莫名其妙。 教训:规划 K8s 网段前,必须列出全公司所有已用网段,避开它们。 (K8s 默认 Pod 网段 10.244.0.0/16、Service 网段 10.96.0.0/12, 这两个也很容易和云上 VPC 的 10.0.0.0/8 冲突。)
2.4 端口:一台机器上的"房间号"
一句话:IP 找到机器,端口找到机器上的具体程序。
类比:IP 是大楼地址,端口是房间号。同一栋楼里有很多房间(服务),各干各的。
端口范围:
| 范围 | 名称 | 说明 |
|---|---|---|
| 0 ~ 1023 | 知名端口 | 系统服务专用,普通用户无法绑定(要 root) |
| 1024 ~ 49151 | 注册端口 | 用户程序可用(如 Tomcat 8080) |
| 49152 ~ 65535 | 动态/私有端口 | 客户端连接时临时分配 |
必须记住的常用端口(这些会天天见到):
| 端口 | 服务 | 说明 |
|---|---|---|
| 22 | SSH | 远程登录(最常用) |
| 80 | HTTP | 明文 Web |
| 443 | HTTPS | 加密 Web |
| 3306 | MySQL | 数据库 |
| 6379 | Redis | 缓存 |
| 8080 | Tomcat / 通用 HTTP 备用 | Java Web 常用 |
| 9200 / 9300 | Elasticsearch | HTTP / 集群通信 |
| 8848 / 9848 | Nacos | 控制台+注册 / gRPC 通信 |
| 9092 | Kafka | 消息队列 |
| 9876 / 10911 | RocketMQ | NameServer / Broker |
| 2181 | ZooKeeper | 协调服务 |
| 2379 / 2380 | Etcd | K8s 元数据 / 集群通信 |
| 6443 | K8s API Server | 集群入口 |
| 10250 | Kubelet API | 节点管理 |
| 5672 / 15672 | RabbitMQ | AMQP / 管理界面 |
| 5601 | Kibana | 日志查询界面 |
| 3000 | Grafana | 监控看板默认端口 |
| 9090 | Prometheus | 指标服务 |
| 11800 / 12800 | SkyWalking | OAP gRPC / HTTP |
| 10086 | Harbor | 镜像仓库(本系列文档用的) |
关于"Nacos 8848"这个梗
Nacos 默认端口是 8848(就是珠穆朗玛峰的高度),另外还需要 9848(gRPC,8848+1000)。 新手最常见的坑:只开了 8848,忘了 9848,导致客户端注册不上。 任何中间件部署前,一定要查清它要开哪些端口,不只是一个。 (Nacos 2.x 需要开 8848、9848;如果配了集群还要 7848。)
2.5 DNS:把域名翻译成 IP
一句话:DNS 是互联网的"电话簿",把人记得住的域名翻译成机器用的 IP。
为什么需要它:你能记住 www.baidu.com,但记不住 110.242.68.66。 更重要的是——IP 可能变(换机房、扩节点),域名不变,用户的访问方式就永远不变。
解析的完整过程(一步步拆开):
图 2-5 DNS 递归查询:本地缓存 → 本地 DNS → 根 / TLD / 权威,六级链路
常见的 DNS 记录类型:
| 类型 | 作用 | 例子 |
|---|---|---|
| A | 域名 → IPv4 地址 | www.example.com → 1.2.3.4 |
| AAAA | 域名 → IPv6 地址 | www.example.com → 2001:db8::1 |
| CNAME | 域名 → 另一个域名(别名) | blog.example.com → example.com |
| MX | 邮件服务器 | example.com → mail.example.com |
| TXT | 文本记录(常用于验证所有权) | 域名验证、SPF 反垃圾邮件 |
| NS | 该域名的权威 DNS 服务器 | 委托管理 |
运维最常用的 DNS 命令
| 命令 | 作用 | 例子 |
|---|---|---|
dig | 最详细的 DNS 查询(推荐) | dig +short www.baidu.com |
nslookup | 简单查询(Windows 也有) | nslookup www.baidu.com |
host | 最简单的查询 | host www.baidu.com |
cat /etc/resolv.conf | 看本机用的是哪个 DNS | —— |
cat /etc/hosts | 看本地静态解析 | —— |
排障套路:
ping 域名不通,先ping IP试。IP 通但域名不通 = DNS 问题。dig @8.8.8.8 域名指定 DNS 服务器查询,对比本机结果,判断是不是本地 DNS 的问题。- 服务内部互调失败,检查
/etc/hosts或 CoreDNS(K8s 里)。
关于 /etc/hosts 的一个红线
/etc/hosts 优先级高于 DNS,可以直接写死域名解析。测试时很方便, 但生产环境不要用它做服务发现——因为 IP 一变就全失效,而且每台机器都要改。 生产应该用 DNS 或注册中心(Nacos/Consul)。
2.6 网关、路由与防火墙
网关(Gateway):一句话,当你要访问的 IP 不在本网段时,把数据交给网关,由它转发。
类比:你要寄快递到外省,不会自己送,而是交给当地的快递集散中心(网关),它再帮你转。
默认网关:每台机器配置里那个"所有出网流量都先给它"的地址。
bash
ip route # 查看路由表
# default via 192.168.1.1 dev eth0 ← 这就是默认网关路由表:机器决定"这个包该往哪发"的依据。匹配规则是最长前缀优先(越具体的规则优先)。
防火墙:控制"哪些流量能进、哪些能出"。
| 工具 | 层级 | 特点 | 常用命令 |
|---|---|---|---|
| iptables | 内核 netfilter | 老牌,规则链复杂但灵活 | iptables -L -n |
| firewalld | iptables 的前端 | CentOS/RHEL 默认,有 zone 概念 | firewall-cmd --list-all |
| ufw | iptables 的前端 | Ubuntu 默认,简单 | ufw status |
| nftables | 内核新框架 | iptables 的继任者 | nft list ruleset |
| 云安全组 | 云平台侧 | 云上第一道墙,最常用 | 控制台操作 |
三层"墙"要分清(排查"端口不通"的关键)
一个请求要到达你的服务,可能要穿过三层限制:
- 云安全组(云平台侧,最外层)——90% 的"端口不通"是这里没开
- 系统防火墙(firewalld/iptables,机器侧)
- 应用监听地址——如果程序只监听
127.0.0.1,外面永远访问不到(要监听0.0.0.0)
排查顺序:先确认应用在监听(ss -lntp | grep 端口)→ 再看系统防火墙 → 最后看云安全组。 新手常常折腾半天防火墙,结果是安全组没开。
NAT(网络地址转换):让私网机器能上网,但外部看不到它们。
| 类型 | 说明 | 场景 |
|---|---|---|
| SNAT(源地址转换) | 内网机器出网时,把源 IP 换成公网 IP | 家里路由器让多台设备共享上网 |
| DNAT(目的地址转换) | 把公网 IP:端口 映射到内网某台机器 | 端口映射、把内网服务暴露出去 |
| PAT/NAPT | 用端口区分不同内网连接 | 最常用(IP 复用) |
2.7 常用网络排查命令(背下来,天天用)
这张表建议收藏,是运维日常最常用的命令。
| 命令 | 作用 | 典型用法 | 看什么 |
|---|---|---|---|
ping | 测连通性(ICMP) | ping -c 4 8.8.8.8 | 通不通、延迟、丢包率 |
traceroute | 看路径(逐跳) | traceroute baidu.com | 在哪一跳断了 |
mtr | ping + traceroute 结合 | mtr -r baidu.com | 各跳丢包率(最好用) |
curl | 发 HTTP 请求 | curl -v https://x.com | 完整请求过程、状态码 |
wget | 下载文件 | wget -O f.txt URL | —— |
telnet | 测端口连通 | telnet 1.2.3.4 3306 | 端口通不通 |
nc(netcat) | 网络瑞士军刀 | nc -zv 1.2.3.4 3306 | 扫端口 |
ss | 看连接/监听(推荐) | ss -lntp | 谁在监听、有哪些连接 |
netstat | 同上(已被 ss 取代) | netstat -anp | 老系统还在用 |
ip addr | 看 IP 和网卡 | ip a | 网卡状态、IP 地址 |
ip route | 看路由表 | ip r | 网关、路由规则 |
dig | DNS 查询 | dig +short x.com | 解析结果 |
tcpdump | 抓包(终极手段) | tcpdump -i eth0 port 80 -nn | 真实的数据包 |
nload / iftop | 实时流量监控 | iftop -P | 哪个连接在吃带宽 |
ethtool | 网卡信息 | ethtool eth0 | 速率、双工、错误统计 |
一条"万能"排障链路(按顺序做)
bash
# 假设要排查"从 A 机器访问 B 机器的 8080 端口不通"
# ① 网络层通不通
ping <B的IP>
# ② 端口通不通(传输层)
nc -zv <B的IP> 8080 # 或 telnet <B的IP> 8080
# ③ 在 B 机器上看服务是否在监听
ss -lntp | grep 8080 # 有没有输出?监听的是 0.0.0.0 还是 127.0.0.1?
# ④ 在 B 机器上看防火墙
firewall-cmd --list-all # 或 iptables -L -n
# ⑤ 在 B 机器上看云安全组(控制台)
# ⑥ 应用层是否有问题
curl -v http://<B的IP>:8080/health
# ⑦ 还不行就抓包(终极手段)
tcpdump -i any port 8080 -nn # 在 B 机器上跑,同时从 A 发请求这个顺序的意义:从下往上逐层排除,你能准确定位到"问题在哪一层", 而不是靠猜。这是运维最重要的思维方式——用排除法缩小范围,而不是凭感觉。
第三部分 网络协议
3.1 协议:大家约定的"说话规则"
一句话:协议是通信双方约定的格式和规则,保证"我说的你能听懂"。
类比:中国人之间说中文,这是"协议"。你对着美国人说中文,不是他笨, 而是协议不一致。网络协议就是在规定:数据怎么组织、怎么开始、怎么结束、出错了怎么办。
3.2 TCP 与 UDP:两种传递方式
一句话:
- TCP = 打电话(先接通、确认对方在听、按顺序说话、说错了重说)
- UDP = 发短信/寄明信片(丢出去不管了,快,但不保证到达)
详细对比(重要,面试和工作都常问):
| 维度 | TCP | UDP |
|---|---|---|
| 连接 | 面向连接(要先握手) | 无连接(直接发) |
| 可靠性 | ✅ 保证送达、不丢、不重复 | ❌ 不保证 |
| 顺序 | ✅ 保证按序到达 | ❌ 可能乱序 |
| 速度 | 较慢(要确认、重传) | 快 |
| 头部大小 | 20~60 字节 | 8 字节 |
| 流量控制 | ✅ 有(滑动窗口) | ❌ 无 |
| 拥塞控制 | ✅ 有 | ❌ 无(靠应用自己) |
| 传输方式 | 字节流 | 数据报 |
| 适用 | HTTP、SSH、FTP、数据库 | DNS、视频直播、游戏、VoIP |
怎么选?一句话判断
"丢一点数据有关系吗?"
- 有关系(转账、传文件、看网页)→ TCP
- 没关系(视频卡一帧、游戏丢一个位置更新)→ UDP(因为重传反而更卡)
有意思的是:现代很多协议建立在 UDP 上,然后在应用层自己实现可靠性。 比如 HTTP/3 用的 QUIC 就是基于 UDP 的——因为 UDP 没有 TCP 的"队头阻塞"问题,更快。
3.2.1 三次握手与四次挥手(必考,也必须懂)
三次握手(建立连接):
图 3-2-1 三次握手:SYN → SYN+ACK → ACK,确认双方收发能力都正常
为什么是三次,不是两次? 因为要双方都确认"我能发、也能收"。 两次的话,服务端无法确认"客户端能收到我的包",也无法防止历史失效连接请求突然到达造成错误的连接。
四次挥手(断开连接):
图 3-2-2 四次挥手:FIN → ACK → FIN → ACK,中间那段等待就是 CLOSE_WAIT
为什么是四次? 因为 TCP 是全双工的,两个方向要分别关闭。 服务端收到 FIN 后可能还有数据要发,所以 ACK 和 FIN 不能合并(这点和握手不同)。
运维必知的三种"连接状态异常"(ss / netstat 里的状态)
| 状态 | 含义 | 说明的问题 |
|---|---|---|
| TIME_WAIT | 主动关闭方等待 2MSL | 正常现象。但大量 TIME_WAIT 会耗尽端口 → 调 net.ipv4.tcp_tw_reuse=1 |
| CLOSE_WAIT | 对方已关闭,我方还没关 | ⚠️ 代码 bug:应用收到 FIN 后没调用 close()。大量 CLOSE_WAIT = 应用有连接泄漏 |
| SYN_RECV | 收到 SYN,还没完成握手 | ⚠️ 大量出现可能是SYN Flood 攻击 → 开 syncookies |
排查口诀:
TIME_WAIT多 → 正常或需要调内核参数(短连接多)CLOSE_WAIT多 → 看应用代码,这是应用的问题SYN_RECV多 → 可能被攻击
这三个状态是面试高频题,也是真实排障的切入点,务必记牢。
3.3 HTTP / HTTPS:Web 的语言
3.3.1 HTTP 是什么
一句话:HTTP 是浏览器和服务器之间传网页的协议,特点是"请求-响应"(你问一句,它答一句)。
HTTP 的核心特点:
- 无状态:每个请求都是独立的,服务器不记得你上次来过 → 所以才需要 Cookie/Session/Token
- 明文传输(HTTP)→ 所以有了 HTTPS
- 基于 TCP(HTTP/1.1、HTTP/2)/ 基于 UDP(HTTP/3)
- 可扩展:请求头可以自定义,这是各种业务需求的实现基础
一个 HTTP 请求长什么样:
POST /api/order/create HTTP/1.1 ← 请求行:方法 + 路径 + 版本
Host: api.example.com ← 以下都是「请求头」
User-Agent: Mozilla/5.0
Content-Type: application/json
Authorization: Bearer eyJhbGciOi...
Content-Length: 58
← 空行(分隔头和体)
{"productId": 1001, "quantity": 2} ← 请求体一个 HTTP 响应长什么样:
HTTP/1.1 200 OK ← 状态行
Content-Type: application/json ← 响应头
Content-Length: 45
Set-Cookie: session=abc123; HttpOnly
← 空行
{"orderId": "20260924001", "status": "待支付"} ← 响应体HTTP 方法(动词):
| 方法 | 语义 | 幂等性 | 说明 |
|---|---|---|---|
| GET | 获取资源 | ✅ 幂等 | 不该改变服务器状态(但很多公司违规用) |
| POST | 创建资源 | ❌ 不幂等 | 重复提交会创建多条(所以下单要做幂等) |
| PUT | 全量更新 | ✅ 幂等 | 重复执行结果相同 |
| PATCH | 部分更新 | ❌ | —— |
| DELETE | 删除 | ✅ 幂等 | 删两次和删一次结果一样 |
| HEAD / OPTIONS | 获取头信息 / 预检 | ✅ | CORS 预检用 OPTIONS |
"幂等性"这个词你一定要理解
幂等 = 同一个操作执行一次和执行 N 次,结果相同。
为什么重要:网络一定会重试(超时、重发)。如果接口不幂等, 用户点两次"支付"就可能扣两次钱。
怎么实现幂等:
- 唯一键约束:订单号加唯一索引,重复插入直接失败。
- Token 机制:下单前先领一个 token,提交时带 token,服务端检查并删除(一次性)。
- 状态机:只有"待支付"能转"已支付",已支付的再来直接返回成功(不再处理)。
这是后端最基本的工程素养,运维在做压测和故障复现时也要懂,否则会制造重复数据。
HTTP 状态码(必须记住这些):
| 类 | 含义 | 常见码 |
|---|---|---|
| 1xx | 信息(很少见) | 101 Switching Protocols(WebSocket 升级) |
| 2xx | 成功 | 200 OK、201 Created、204 No Content |
| 3xx | 重定向 | 301 永久重定向、302 临时、304 未修改(缓存有效) |
| 4xx | 客户端错误(你请求有问题) | 400 参数错、401 未认证、403 无权限、404 不存在、429 限流 |
| 5xx | 服务器错误(我的问题) | 500 内部错误、502 网关错误、503 服务不可用、504 网关超时 |
三个最容易被搞混的状态码(运维天天遇到)
| 状态码 | 真实含义 | 常见原因 |
|---|---|---|
| 502 Bad Gateway | 网关连不上上游服务 | 后端服务挂了 / 端口不对 / 后端启动慢 |
| 504 Gateway Timeout | 网关等上游超时 | 后端处理太慢 / 慢 SQL / 死锁 |
| 503 Service Unavailable | 服务主动拒绝(不是崩了) | 过载保护、优雅停机、健康检查未通过 |
排查口诀:
- 502 → 去看后端服务是不是活着(
kubectl get pod、docker ps) - 504 → 去看后端处理耗时(链路追踪、慢日志)
- 503 → 去看是不是在发布/扩容/过载限流
记住:4xx 是"用户的问题",5xx 是"我们的问题"。 监控告警要盯 5xx 率(这是我们的锅),4xx 只需关注异常突增。
3.3.2 HTTPS:给 HTTP 加个保险箱
一句话:HTTPS = HTTP + TLS 加密,防止传输内容被偷看或篡改。
为什么必须用 HTTPS:
- 防窃听:HTTP 是明文,中间任何一跳(路由器、运营商、公共 WiFi)都能看到你的密码。
- 防篡改:运营商劫持 HTTP 流量插广告,就是这个问题。
- 防冒充:证书验证服务器身份,防钓鱼网站。
- 现代浏览器的硬要求:Chrome 对 HTTP 网站标记"不安全"; 很多 API(如摄像头、定位、Service Worker)只在 HTTPS 下可用。
HTTPS 的握手过程(简化版,理解思想即可):
图 3-3-2 HTTPS 握手:先非对称交换密钥,再对称加密通信
为什么用"非对称加密协商 + 对称加密传输"这种组合?
- 非对称加密(RSA/ECC):安全但慢。用它来安全地协商出一个密钥。
- 对称加密(AES):快,但需要双方有同一个密钥。用它来加密实际数据。
一句话总结:用慢的加密方式安全地传一个密钥,然后用这个密钥用快的方式传数据。 这个设计非常经典,理解了它就理解了 HTTPS 的精髓。
证书相关概念:
| 概念 | 说明 |
|---|---|
| CA(证书颁发机构) | 权威机构,给服务器签发证书(如 Let's Encrypt、DigiCert) |
| 证书链 | 服务器证书 → 中间 CA → 根 CA(根 CA 内置在浏览器/系统里) |
| DV / OV / EV 证书 | 域名验证 / 企业验证 / 扩展验证(信任等级递增,价格递增) |
| 通配符证书 | *.example.com 覆盖所有子域名 |
| SAN 证书 | 一张证书覆盖多个域名 |
| Let's Encrypt | 免费证书,90 天有效期,可自动续期(推荐) |
| 自签名证书 | 自己签的,浏览器不信任,只适合内部测试 |
证书相关的三大生产事故
- 证书过期(最常见!)。免费证书 90 天就过期,忘了续期 → 全站无法访问。 必须做的:① 自动续期(certbot timer);② 监控证书剩余有效期(至少提前 15 天告警)。bash
# 查证书剩余天数 echo | openssl s_client -servername www.example.com -connect www.example.com:443 2>/dev/null \ | openssl x509 -noout -dates - 证书链不完整。只配了服务器证书,没配中间证书 → 部分浏览器/App 报错。 排查:
openssl s_client -connect host:443 -showcerts看有没有返回完整链。 - HTTPS 里混了 HTTP 资源。页面是 HTTPS,但图片是
http://→ 浏览器拦截(Mixed Content)。 运维配合排查:看浏览器控制台的警告,或检查静态资源域名是否统一。
3.4 其他必须知道的协议
| 协议 | 端口 | 作用 | 运维用途 |
|---|---|---|---|
| SSH | 22 | 安全远程登录 | 运维的主要工作方式 |
| SFTP / SCP | 22 | 基于 SSH 传文件 | 传文件、备份 |
| FTP / FTPS | 21 | 老式文件传输 | 老系统还在用(明文,不安全) |
| NFS | 2049 | 网络文件系统 | 多机器共享目录 |
| SMTP / POP3 / IMAP | 25/110/143 | 邮件 | 告警邮件 |
| SNMP | 161/162 | 网络设备管理 | 监控交换机/路由器 |
| LDAP | 389 | 目录服务 | 统一认证(AD 域) |
| WebSocket | 80/443 | 全双工长连接 | IM、实时推送、游戏 |
| gRPC | HTTP/2 | 高性能 RPC | 微服务间调用(比 REST 快) |
| Rsync | 873 | 增量文件同步 | 备份、代码发布 |
| NTP | 123 | 时间同步 | 服务器时间必须一致! |
服务器时间不同步会导致什么(新人完全想不到)
"时间不一致"是分布式系统最隐蔽的故障源:
- JWT / Token 校验失败:签发的 token 在另一台机器看来"还没生效"或"已过期"。
- 日志时序错乱:排查故障时,无法确定事件的先后顺序。
- TLS 证书校验失败:本地时间偏差过大,证书被判定无效。
- 分布式锁失效:基于时间的锁在时钟回拨时可能被重复获取。
- 数据库主从异常:binlog 时间戳异常。
- 监控数据错乱:指标时间戳对不上。
必须做的:所有服务器配 NTP 同步,且统一时区(国内统一用 Asia/Shanghai)。
bash
timedatectl # 查看时间与时区
timedatectl set-timezone Asia/Shanghai
systemctl status chronyd # 或 ntpd
chronyc sources -v # 看时间源这条"基础规范"如果没做,后面所有排障都会变成猜谜。
第四部分 Web 与前后端
4.1 一个网页是怎么显示出来的
完整过程(用户视角 3 秒,实际背后几十个步骤):
① 用户在浏览器输入 https://www.example.com
② DNS 解析域名 → 得到 IP(可能解析到 CDN)
③ 建立 TCP 连接(三次握手)
④ TLS 握手(HTTPS 加密协商)
⑤ 浏览器发送 HTTP 请求:「给我首页」
⑥ 服务器返回 HTML(骨架)
⑦ 浏览器解析 HTML,发现要加载 CSS / JS / 图片
⑧ 再次发起多个请求获取这些资源(可能从 CDN 拿,很快)
⑨ 浏览器执行 JS,可能需要再调用后端 API 拿数据
⑩ 渲染出完整页面关键认知:一次页面打开可能发起 50~200 个请求。 这就是为什么需要 CDN、为什么需要 HTTP/2(多路复用)、为什么静态资源要压缩和缓存。
4.2 前端 / 后端 / 全栈
| 角色 | 干什么 | 技术 | 部署产物 |
|---|---|---|---|
| 前端 | 用户看得见的部分 | HTML/CSS/JS、Vue、React | 静态文件(HTML/JS/CSS) |
| 后端 | 数据处理、业务逻辑 | Java/Go/Python/Node | 服务进程 / 容器镜像 |
| 全栈 | 两端都会(小公司常见) | —— | —— |
| 运维 | 让上面两种东西稳定跑起来 | Linux/网络/容器/K8s | —— |
前后端分离,对运维意味着什么(很重要)
传统模式:后端渲染 HTML,前端代码和后端代码在一个项目里。部署一个 war 包就完事。
前后端分离模式:
- 前端是独立项目,构建产物是静态文件(
dist/目录:HTML/CSS/JS)。 - 后端只提供 API(返回 JSON,不返回页面)。
所以运维要管两条发布链路:
| 类型 | 产物 | 发布方式 |
|---|---|---|
| 前端 | dist/ 静态文件 | 传到 Nginx 目录 / 传到 CDN / 传到对象存储 |
| 后端 | jar / 镜像 | 部署到 K8s / 服务器 |
这也是为什么你的 DevOps 流程要能同时处理这两种产物—— 本系列文档《客户端 / 服务端类软件发布》专门讲了这个问题。
4.3 反向代理 vs 正向代理
这两个词非常容易搞混,但用一句话就能分清:
| 正向代理 | 反向代理 | |
|---|---|---|
| 代理谁 | 代理客户端 | 代理服务器 |
| 谁知道 | 服务器不知道真实客户端是谁 | 客户端不知道真实服务器是谁 |
| 谁配置 | 用户/客户端配置 | 服务端配置(用户无感) |
| 典型场景 | 科学上网、公司统一出口、爬虫 | Nginx 负载均衡、CDN、网关 |
| 类比 | 你找人代购(商家不知道是你买的) | 公司前台(访客不知道找的是哪位员工) |
运维说的"反代"通常就是 Nginx。 它的核心用途:
| 用途 | 说明 |
|---|---|
| 负载均衡 | 一个域名对应多台后端,分流 |
| TLS 卸载 | 证书配在 Nginx 上,后端只跑 HTTP(省资源) |
| 静态资源服务 | 直接返回本地文件,不经过后端 |
| 路由分发 | 按 URL 路径分发到不同后端 |
| 限流/防爬 | 在 Nginx 层直接拦截 |
| 缓冲 | 后端慢时先缓冲响应,保护后端(proxy_buffering) |
一段最小的 Nginx 反代配置(正确写法):
nginx
server {
listen 80;
server_name api.example.com;
location /api/ {
proxy_pass http://backend_pool; # 转发到后端(注意结尾斜杠的坑!)
proxy_set_header Host $host; # ★ 必须传,否则后端拿不到真实域名
proxy_set_header X-Real-IP $remote_addr; # ★ 传真实客户端 IP
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 60s; # 等后端响应的超时(★ 大文件/慢接口要调大)
proxy_next_upstream error timeout http_502; # 失败自动重试下一个后端
}
}
upstream backend_pool {
server 192.168.1.10:8080 weight=1 max_fails=3 fail_timeout=30s;
server 192.168.1.11:8080 weight=1 max_fails=3 fail_timeout=30s;
keepalive 32; # ★ 长连接,性能关键
}proxy_pass 结尾有没有斜杠,结果完全不同(经典坑)
| 配置 | 请求 /api/user 转发到后端的路径 |
|---|---|
proxy_pass http://backend; | http://backend/api/user(带前缀) |
proxy_pass http://backend/; | http://backend/user(去掉前缀) |
多一个斜杠,后端就 404。 这是新手最常见的 Nginx 事故之一。 记住规则:proxy_pass 后面只要有 URI(含 /),就会替换掉 location 匹配的部分。
后端拿不到真实用户 IP 的问题
Nginx 反代之后,后端看到的客户端 IP 是 Nginx 的 IP,不是用户真实 IP。 所以要靠 X-Real-IP 和 X-Forwarded-For 头传递。 但这两个头可以被伪造,Nginx 必须覆盖而不是追加(用 proxy_set_header 就会覆盖)。 如果链路有多层代理(CDN → LB → Nginx),X-Forwarded-For 会是一个逗号分隔的列表, 最左边的是最接近用户的(可能是伪造的),最右边的是最近的代理。 正确取法是"从右往左找第一个可信代理之前的地址",很多风控系统就栽在这上面。
4.4 会话管理:Cookie / Session / Token
要解决的问题:HTTP 是无状态的,服务器怎么知道"你还是刚才登录的那个人"?
| 机制 | 存在哪 | 怎么工作 | 优点 | 缺点 |
|---|---|---|---|---|
| Cookie | 浏览器 | 服务器 Set-Cookie,浏览器每次自动带上 | 自动携带,方便 | 大小限制 4KB;可被 XSS 读取 |
| Session | 服务器(内存/Redis) | 服务器存数据,只给浏览器一个 sessionId | 数据在服务端,安全 | 服务端有状态 → 难扩缩容 |
| Token(JWT) | 客户端 | 服务端签发一个自包含的 token,客户端每次带上 | 无状态,易扩展 | 无法主动失效;体积较大 |
JWT 的结构(了解即可):Header.Payload.Signature
- 三部分用
.分隔,都是 Base64 编码(不是加密,只是编码,能解出来看) - 重要认知:JWT 里的信息是"可见但不可改"的(改了签名就对不上)。 所以不要把密码、身份证等敏感信息放进 JWT,因为任何人 Base64 解码就能看到。
分布式系统为什么推荐 Token(JWT)
因为 Session 方案需要"所有服务共享同一份 session 存储"(通常是 Redis), 这引入了对 Redis 的强依赖。Redis 挂了,所有人登录状态失效。 JWT 无状态:服务端不存任何东西,只验签名。 天生适合微服务和扩容。 代价:无法"立刻踢人下线"(要等 token 过期),除非额外维护黑名单。
4.5 跨域(CORS):前端最常撞的墙
问题现象:前端调后端接口,浏览器控制台报 Access to XMLHttpRequest ... has been blocked by CORS policy。
原因:浏览器的同源策略——为了安全,只允许页面访问"同源"(协议+域名+端口都相同)的资源。 http://localhost:3000 调 http://api.example.com 属于跨域。
注意:这是浏览器行为,服务端之间调用不受影响。 (所以用 curl 测试是通的,一到浏览器就报错,很多人会困惑。)
解法(服务端配置响应头):
Access-Control-Allow-Origin: https://www.example.com
Access-Control-Allow-Methods: GET,POST,PUT,DELETE,OPTIONS
Access-Control-Allow-Headers: Content-Type,Authorization
Access-Control-Allow-Credentials: true实际生产做法:
- 生产环境用同一个域名(前端
/api/由 Nginx 反代到后端)→ 没有跨域问题,这是最干净的方案。 - 开发环境用开发服务器代理(Vite/webpack 的 proxy 配置)。
- 万不得已才用 CORS 头,且不要用
Allow-Origin: *配合Credentials: true(浏览器会拒绝,而且不安全)。
运维最容易帮倒忙的地方
开发说"跨域了",运维顺手在 Nginx 加 add_header Access-Control-Allow-Origin *;, 结果:
- 和已有的 CORS 头重复 → 浏览器报"multiple values"错误。
- 用了
*→ 无法携带 Cookie,且允许任何网站调用你的接口(安全风险)。 - 没处理 OPTIONS 预检请求 → 复杂请求直接被拦。
正确做法:跨域优先在应用层解决(框架的 CORS 配置), Nginx 层只在明确需要时加,且要指定具体域名。
第五部分 数据与存储
5.1 数据库:数据的家
一句话:数据库是专门用来结构化存储和高效查询数据的软件。
为什么不能直接用文件存数据:
| 用文件存 | 用数据库 |
|---|---|
| 并发写会互相覆盖 | 有事务和锁保证并发安全 |
| 查询要自己写代码遍历 | SQL 一句搞定,有索引加速 |
| 没有约束,数据容易脏 | 有约束(唯一、外键)保证质量 |
| 断电可能损坏 | 有 WAL 日志保证不丢 |
两大阵营:
| 类型 | 全称 | 特点 | 代表 | 适用 |
|---|---|---|---|---|
| 关系型(SQL) | RDBMS | 表结构固定、支持事务、强一致 | MySQL、PostgreSQL、Oracle | 交易、订单、用户(90% 的业务) |
| 非关系型(NoSQL) | Not Only SQL | 灵活、可扩展、弱一致 | ||
| · 键值 | Key-Value | 极快,只按键查 | Redis、Memcached | 缓存、会话 |
| · 文档 | Document | 存 JSON,结构灵活 | MongoDB | 内容、日志、配置 |
| · 列族 | Column Family | 海量写入 | HBase、Cassandra | 大数据 |
| · 图 | Graph | 关系遍历 | Neo4j | 社交关系、风控 |
| · 时序 | Time Series | 按时间存储 | InfluxDB、TDengine | 监控指标 |
| · 搜索 | Search | 全文检索 | Elasticsearch | 搜索、日志 |
选型速查(问自己三个问题)
- 需要事务和强一致吗?(钱相关)→ 是 → MySQL
- 是"按 key 快速读写"吗?(缓存)→ 是 → Redis
- 要全文搜索或日志检索吗? → 是 → Elasticsearch
其他情况才考虑 MongoDB / HBase / ClickHouse 等。新人最容易犯的错是"为了新技术而选新数据库"——MySQL 能解决 90% 的问题。
5.2 表、行、列、主键、索引
用"Excel 表格"类比:
| 数据库概念 | Excel 类比 | 说明 |
|---|---|---|
| 表 Table | 一个 Sheet | 一类数据的集合 |
| 行 Row / 记录 Record | 一行 | 一条数据 |
| 列 Column / 字段 Field | 一列 | 一个属性 |
| 主键 Primary Key | 唯一标识列 | 每条记录的唯一身份证,不可重复 |
| 外键 Foreign Key | 关联另一张表 | 建立表间关系 |
| 索引 Index | 书的目录 | 加速查询(但占空间、拖慢写入) |
索引的本质:
一本书 500 页,你要找"索引"这个词。没有目录,你得一页页翻(全表扫描); 有了目录,直接翻到对应页码(索引查找)。
索引的关键认知:
| 认知 | 说明 |
|---|---|
| 索引不是越多越好 | 每个索引都要占用空间,且写入时要维护索引(INSERT 变慢) |
| 索引有自己的数据结构 | MySQL InnoDB 用 B+ 树(3~4 层就能索引上亿行) |
| 最左前缀原则 | 联合索引 (a, b, c) 只能被 a、a,b、a,b,c 利用;单独查 b 用不上 |
| 索引失效的常见情况 | ① 对索引列做运算/函数 WHERE YEAR(create_time)=2026 ② 隐式类型转换(字符串列传数字)③ LIKE '%xxx' 前导通配符 ④ OR 连接的列不全有索引 |
| 覆盖索引 | 查询的列都在索引里,就不用回表,极快 |
运维必须能看懂慢 SQL(这是你的核心竞争力之一)
运维虽不写业务代码,但必须能定位慢查询,否则无法给开发提供有效信息。
bash
# ① 开启慢查询日志(MySQL)
SET GLOBAL slow_query_log = ON;
SET GLOBAL long_query_time = 1; # 超过 1 秒就记录
# ② 看哪些 SQL 最慢
mysqldumpslow -s t -t 10 /var/log/mysql/slow.log
# ③ 看具体 SQL 的执行计划 ★ 最重要的一步
EXPLAIN SELECT * FROM orders WHERE user_id = 123 AND status = 1;EXPLAIN 里你必须看的三个字段:
| 字段 | 危险信号 | 含义 |
|---|---|---|
| type | ALL(全表扫描)、index(全索引扫描) | 访问类型,ALL = 最差,ref/range/const 才好 |
| rows | 数字很大(如几百万) | 预估扫描行数,越大越慢 |
| Extra | Using filesort、Using temporary | 需要额外排序/建临时表,性能杀手 |
给开发报慢 SQL 的标准格式: "orders 表的这条 SQL 走了全表扫描(type=ALL,rows=320万), WHERE user_id=? AND status=? 没有可用的联合索引,建议加 (user_id, status) 联合索引。" 这样说,开发会认可你的专业度,而不是觉得你在甩锅。
5.3 事务:要么全成功,要么全失败
一句话:事务是一组操作,要么全部成功,要么全部回滚,中间不会出现"做了一半"的状态。
经典例子:转账。
从 A 扣 100 元 ← 如果这步成功
给 B 加 100 元 ← 这步失败
→ 那 100 元就凭空消失了!事务保证这两步是一个整体:要么都成功,要么都不做。
ACID 四大特性(必背):
| 特性 | 全称 | 含义 | 通俗解释 |
|---|---|---|---|
| A | Atomicity 原子性 | 要么全做,要么全不做 | 不可分割 |
| C | Consistency 一致性 | 数据从一个合法状态到另一个合法状态 | 转账前后总额不变 |
| I | Isolation 隔离性 | 并发事务互不干扰 | 你和别人同时转账互不影响 |
| D | Durability 持久性 | 提交后就永久生效(断电也不丢) | 靠 redo log 实现 |
四种隔离级别(和"脏读/幻读"的对应关系,面试高频):
| 隔离级别 | 脏读 | 不可重复读 | 幻读 | 性能 | 说明 |
|---|---|---|---|---|---|
| 读未提交 Read Uncommitted | ✅ 有 | ✅ | ✅ | 最快 | 能读到别人没提交的数据(危险) |
| 读已提交 Read Committed | ❌ | ✅ | ✅ | 快 | Oracle 默认;同一事务内两次读结果可能不同 |
| 可重复读 Repeatable Read | ❌ | ❌ | ✅ | 中 | MySQL 默认;同一事务内多次读结果一致 |
| 串行化 Serializable | ❌ | ❌ | ❌ | 最慢 | 完全串行,性能极差 |
三个"读"的通俗解释
- 脏读:你看到了别人还没提交的数据,结果人家回滚了 → 你看到的是"假数据"。
- 不可重复读:同一个事务里,你读两次同一行,值变了(因为别人改了并提交了)。
- 幻读:同一个事务里,你查"满足条件的行数",两次查行数不一样(别人插入了新行)。
MySQL 的"可重复读"靠 MVCC(多版本并发控制)实现快照, 同时用"间隙锁"在大部分场景下也避免了幻读,所以 MySQL 实际表现比表格里更好。
生产环境必须注意的三件事
- 事务要尽可能短。长事务会持有锁,阻塞其他请求,还可能撑大 undo log。 反例:在事务里调用外部 HTTP 接口(网络慢 → 锁持有几秒 → 数据库堵死)。
- 死锁。两个事务互相等对方的锁。MySQL 会自动检测并回滚一个, 但你要能从
SHOW ENGINE INNODB STATUS里找到死锁日志,定位是哪两条 SQL。 - 大事务。一次更新 100 万行 → binlog 巨大 → 主从延迟几分钟。 必须分批(如每批 1000 行)。
5.4 缓存:用空间换时间
一句话:把慢存储(数据库)里的热数据放到快存储(内存),加快访问。
为什么快:
| 存储 | 访问延迟 | 类比 |
|---|---|---|
| CPU 缓存 | ~1 ns | 手上的东西 |
| 内存(Redis) | ~100 μs(含网络) | 操作台上的东西,伸手就拿 |
| SSD 磁盘 | ~100 μs | 抽屉里的东西,要开抽屉 |
| 机械硬盘 | ~10 ms | 仓库里的东西,要走过去找 |
| 网络(跨机房) | ~1~50 ms | 去另一个城市取 |
注意:内存比磁盘快 100 倍以上,这就是缓存的全部价值。
缓存"三兄弟"(穿透/击穿/雪崩)—— 详见架构文档 6.4 节
记忆方法:
- 穿透:查不存在的数据 → 缓存没有、数据库也没有 → 每次都要查库。解法:缓存空值 / 布隆过滤器。
- 击穿:一个热 key 过期 → 大量请求同时涌向数据库。解法:互斥锁 / 热 key 永不过期。
- 雪崩:大量 key 同时过期 → 数据库被打垮。解法:TTL 加随机值 / 多级缓存 / 熔断降级。
记忆口诀:穿透是"没有",击穿是"一个",雪崩是"一片"。
5.5 文件系统与磁盘
Linux 文件系统核心概念:
| 概念 | 说明 | 运维相关 |
|---|---|---|
| inode | 存储文件的元信息(权限、大小、位置),不存文件名 | inode 耗尽时,磁盘还有空间却写不进去(常见故障) |
| block | 实际存储数据的最小单元(通常 4KB) | 小文件多会浪费空间 |
| 硬链接 | 多个文件名指向同一 inode | 删一个不影响,删完才释放 |
| 软链接 | 类似 Windows 快捷方式 | 指向路径,原文件删了就失效 |
| 挂载 mount | 把设备关联到目录树 | /etc/fstab 配置开机挂载 |
常用磁盘命令:
| 命令 | 作用 | 例 |
|---|---|---|
df -h | 看各分区的使用率 | 最常用 |
du -sh * | 看当前目录各文件/目录大小 | 找谁占满了磁盘 |
lsblk | 看块设备树 | 看磁盘和分区 |
mount / umount | 挂载/卸载 | —— |
iostat -x 1 | 磁盘 IO 性能 | %util 接近 100% 说明磁盘瓶颈 |
lsof | 看谁在用文件/端口 | lsof +L1 找已被删除但没释放的文件 |
磁盘相关的四个高频故障(务必知道)
- 磁盘写满 → 服务无法写日志、数据库无法写入。 最快的定位方式:
df -h找出哪个分区满了 →du -sh /* 2>/dev/null | sort -rh | head逐层往下钻。 - inode 耗尽:
df -i看。现象是"磁盘有空间但写不进去"。 原因通常是某个目录堆积了海量小文件(如 session 文件、临时文件、日志碎片)。 - 文件已删除但空间没释放:进程还持有文件句柄(
lsof +L1能找到)。 必须重启进程或> /proc/PID/fd/N清空,光删文件没用。 (这是最经典的"磁盘满"疑难问题:日志文件被rm了,但服务没重启,空间一直不释放。) - 日志暴涨:某个服务 debug 日志忘了关,一天写了几十 GB。 做法:日志轮转(logrotate)+ 限制日志级别 + 磁盘配额告警。
第六部分 服务端与中间件
6.1 什么是"服务端"
一句话:服务端就是"一直在运行、等着响应请求"的程序。
它和普通程序的区别:
| 普通程序 | 服务端程序 | |
|---|---|---|
| 生命周期 | 运行完就退出 | 长期运行 |
| 交互 | 和人交互 | 通过网络响应请求 |
| 要求 | 能跑就行 | 高可用、高并发、可监控 |
| 状态 | 无状态 | 可能持有状态(连接、缓存) |
6.2 中间件:到底"中间"在哪
一句话:中间件是不直接实现业务、但业务离不开的通用基础软件。
"中间"的含义:它夹在操作系统和应用之间。 操作系统只提供最基础的能力(文件、进程、网络), 应用需要的是更高级的能力(消息队列、缓存、配置管理)——中间件补上这一层。
操作系统(最底层,只提供原语)
↕
中间件(提供通用能力) ← 就是这一层
↕
应用(业务逻辑)常见中间件分类:
| 类别 | 代表 | 解决什么 |
|---|---|---|
| Web 服务器 | Nginx、Apache、Tomcat、Caddy | 接收 HTTP 请求 |
| 消息队列 | Kafka、RocketMQ、RabbitMQ | 异步、解耦、削峰 |
| 缓存 | Redis、Memcached | 加速读 |
| 数据库中间件 | MyCat、ShardingSphere、ProxySQL | 分库分表、读写分离 |
| 注册/配置中心 | Nacos、Consul、Etcd、Apollo | 服务发现、配置管理 |
| 网关 | Spring Cloud Gateway、Kong、APISIX | 统一入口 |
| RPC 框架 | Dubbo、gRPC、Thrift | 服务间通信 |
| 分布式协调 | ZooKeeper、Etcd | 选主、分布式锁 |
| 任务调度 | XXL-JOB、Quartz、Airflow | 定时任务 |
| 分布式事务 | Seata、TCC | 跨库一致性 |
| 监控/日志 | Prometheus、ELK、SkyWalking | 可观测 |
| 搜索 | Elasticsearch、Solr | 全文检索 |
6.3 Web 服务器:Nginx / Apache / Tomcat 的区别
这是新人最容易混淆的一组,必须分清:
| 软件 | 本质 | 擅长 | 常被误认为 |
|---|---|---|---|
| Nginx | 反向代理 + Web 服务器 | 静态文件、反代、负载均衡(高并发之王) | 「Java 服务器」❌ |
| Apache | Web 服务器 | 动态模块丰富、.htaccess 灵活 | —— |
| Tomcat | Servlet 容器(Java) | 跑 Java Web 应用(war 包) | 「Web 服务器」半对 |
| Jetty | 同上(更轻量) | 嵌入式场景 | —— |
| uWSGI / Gunicorn | Python WSGI 服务器 | 跑 Python Web | —— |
| PHP-FPM | PHP FastCGI 进程管理器 | 跑 PHP | —— |
记住这个黄金组合
Nginx(对外的门面)→ 应用服务器(干活的)
- Java 场景:
Nginx → Tomcat/内嵌 Tomcat 的 Spring Boot - PHP 场景:
Nginx → PHP-FPM - Python 场景:
Nginx → Gunicorn/uWSGI - Node 场景:
Nginx → Node 进程
Nginx 只负责"接客和分流",不负责运行业务逻辑。 (Nginx 也能跑 PHP 但那是通过 FastCGI 转给 PHP-FPM,它自己还是没跑业务代码。)
6.4 微服务:把大系统拆小
单体应用的问题(一个 war/jar 包含所有功能):
- 改一个小功能要重新部署整个应用 → 风险大、发布慢
- 一个模块内存泄漏 → 整个应用挂
- 无法针对热点模块单独扩容(只能整个复制)
- 技术栈被锁死(都用 Java),团队协作冲突多
微服务的解法:按业务拆成独立的小服务,每个服务独立开发、独立部署、独立扩容。
| 维度 | 单体架构 | 微服务架构 |
|---|---|---|
| 部署 | 一个包 | 几十个服务 |
| 发布 | 整体发布 | 独立发布 |
| 扩容 | 整体复制 | 按需扩某个服务 |
| 故障影响 | 全挂 | 局部(需要熔断隔离) |
| 技术栈 | 统一 | 可异构 |
| 运维复杂度 | 低 | 高(需要治理、监控、链路) |
| 团队规模 | 小团队 | 多团队 |
微服务不是银弹,拆分是有代价的
| 代价 | 说明 | 应对 |
|---|---|---|
| 分布式复杂度 | 网络调用会失败、会超时、会重复 | 超时/重试/熔断/幂等 |
| 数据一致性 | 跨服务的事务无法用数据库事务 | 最终一致 + 补偿 + 消息 |
| 排查困难 | 一次请求跨 7 个服务 | 全链路追踪(SkyWalking) |
| 运维成本 | 服务数量爆炸 | K8s + CI/CD + 平台化 |
| 资源开销 | 每个服务都要独立进程 | 服务不宜拆得太细 |
真实建议:团队 < 10 人、QPS < 1000 时,单体 + 模块化就够。微服务是"规模逼出来的选择",不是"先进性的象征"。 (这句话在面试时说出来,会显得你有工程判断力。)
微服务必需的配套(缺一不可):
| 配套 | 作用 | 代表 |
|---|---|---|
| 注册中心 | 服务怎么找到彼此 | Nacos、Consul、Eureka |
| 配置中心 | 配置集中管理 | Nacos、Apollo |
| 网关 | 统一入口、鉴权、限流 | Spring Cloud Gateway、Kong |
| 服务调用 | 服务间通信 | OpenFeign、Dubbo、gRPC |
| 熔断降级 | 防止故障扩散 | Sentinel、Hystrix、Resilience4j |
| 链路追踪 | 排查跨服务问题 | SkyWalking、Jaeger |
| 分布式事务 | 跨服务数据一致 | Seata |
| 容器编排 | 管理几十个服务实例 | K8s(几乎必备) |
记住:没有这些配套就上微服务,是在给自己制造灾难。
6.5 容器与 Kubernetes
(基础概念见 1.4 节,这里讲 K8s 的核心抽象)
K8s 解决的问题:容器多了之后,谁来调度、重启、负载、升级?
核心抽象(用"养宠物 vs 养牛群"理解):
传统运维是"养宠物":给服务器起名字、精心维护、坏了赶紧救。 K8s 时代是"养牛群":不关心具体哪头牛,只关心"总数对不对",死一头就补一头。
| K8s 概念 | 说明 | 对应"牛群"比喻 |
|---|---|---|
| Pod | 最小调度单位 | 一头牛 |
| ReplicaSet | 保证副本数量 | 保证牛群数量 |
| Deployment | 声明式管理 Pod 版本与副本 | 牛群的"品种规范" |
| Service | 一组 Pod 的稳定访问入口 | 牛栏的统一入口 |
| Ingress | 七层入口路由 | 牧场大门 |
| ConfigMap/Secret | 配置与密钥 | 饲料配方 |
| Namespace | 逻辑隔离 | 分栏 |
| Node | 工作节点(一台机器) | 一块草地 |
声明式 vs 命令式(这是 K8s 的灵魂):
| 命令式 | 声明式 | |
|---|---|---|
| 做法 | 告诉系统怎么做(一步步命令) | 告诉系统要什么结果 |
| 例子 | kubectl scale --replicas=3 | YAML 里写 replicas: 3 |
| 好处 | 直观 | 系统自己持续纠正到目标状态(自愈) |
理解"控制器循环"就理解了 K8s
K8s 的核心机制是一个无限循环:"观察当前状态 → 比较期望状态 → 采取行动缩小差距"。
比如你声明要 3 个副本:
- 当前 2 个 → K8s 起 1 个
- 当前 4 个 → K8s 删 1 个
- 某个 Pod 挂了 → K8s 补一个新的
这就是"自愈"能力。 也是为什么 K8s 能在节点故障时自动把 Pod 调度到别的节点。 理解了这个循环,你就能理解为什么"改 YAML 就能生效"、"为什么手动删掉的 Pod 会自动回来"。
6.6 服务通信:从单体调用到微服务调用
| 方式 | 说明 | 特点 |
|---|---|---|
| 进程内调用 | 单体应用内直接调方法 | 最快,无网络开销 |
| HTTP / REST | 用 HTTP 调接口(JSON) | 通用、易调试、性能一般 |
| RPC(Dubbo/gRPC) | 二进制协议,像调本地方法 | 性能高,需接口定义 |
| 消息队列 | 异步通信,不等待响应 | 解耦,但不是请求-响应 |
"同步 vs 异步"的区别(一定要分清):
| 同步调用 | 异步消息 | |
|---|---|---|
| 调用方 | 等待结果 | 发出去就返回 |
| 耦合 | 强(要知道对方地址、接口) | 弱(只知道队列) |
| 故障影响 | 对方挂了我也挂(需熔断) | 对方挂了消息先堆着 |
| 一致性 | 强一致(能立刻知道成败) | 最终一致 |
| 适用 | 必须立即知道结果的(查库存) | 可以稍后处理的(发短信、加积分) |
微服务里最容易造成雪崩的做法
同步调用链太长: A → B → C → D → E,每一环都同步等待。 如果 E 变慢(3 秒),那么 D、C、B、A 的线程全部被占住; A 的线程池很快耗尽 → A 也不可用了 → 整个链路崩塌。这就是"雪崩"。
必须做的三件事:
- 超时:每一环都要设超时(比如 1 秒),不能无限等。
- 熔断:某服务错误率超阈值,直接快速失败(不再调用),给它恢复时间。
- 隔离:给不同下游分配独立的线程池/信号量,避免一个下游拖垮所有。
第七部分 运维核心能力
7.1 Linux:运维的主战场
为什么必须学 Linux:服务器 95% 是 Linux,而且没有图形界面,全靠命令行。
必须掌握的 Linux 技能清单:
| 类别 | 必须会的 | 常见命令 |
|---|---|---|
| 文件操作 | 导航、查看、编辑 | cd ls cp mv rm cat less tail vim find |
| 文本处理 | 运维核心竞争力 | grep awk sed sort uniq wc cut xargs |
| 权限管理 | 权限、属主 | chmod chown umask |
| 进程管理 | 查看、杀进程、后台 | ps top kill nohup jobs systemctl |
| 网络 | 见第二部分 | ss curl ping ip tcpdump |
| 磁盘 | 容量、性能 | df du iostat lsblk |
| 软件包 | 装软件 | yum/dnf(RHEL系)apt(Debian系) |
| 服务管理 | 启停、开机自启 | systemctl start/stop/enable/status |
| 日志 | 看日志 | journalctl tail -f grep |
| 用户与组 | 账号管理 | useradd usermod passwd id |
学习 Linux 的正确姿势(转行者必看)
不要"从第一章学到最后一章",要"带着任务学"。
推荐的任务清单(每个都能逼你学会一批命令):
- 在 Linux 上部署一个静态网站(学会:装 Nginx、改配置、放文件、开防火墙、启服务)
- 写一个脚本每天备份某个目录并保留 7 天(学会:Shell、cron、tar、find、日期处理)
- 分析一个 10GB 的日志文件,找出访问量 Top 10 的 IP(学会:grep、awk、sort、uniq、管道)
- 搭一个 MySQL 主从(学会:装软件、改配置、权限、排错)
- 查出一个"CPU 100%"的进程在干什么(学会:top、ps、strace、jstack)
做完这 5 个任务,你的 Linux 水平就超过大多数"学过 Linux 但没实践过"的人了。
7.2 Shell 脚本:自动化的起点
一句话:Shell 脚本就是把一堆命令写进文件,让它批量执行。
必须掌握的基础语法:
bash
#!/bin/bash
# ↑ 第一行叫 shebang,指定用什么解释器执行
set -euo pipefail
# ↑ 最重要的一行!三个开关:
# -e 遇到错误立即退出(而不是默默继续)
# -u 使用未定义变量时报错(防止手滑删错东西)
# -o pipefail 管道中任何一环失败就算失败
# 没有这一行,脚本出错了还在继续跑,可能造成严重生产事故!
# 变量(注意:等号两边不能有空格!)
NAME="prod-server"
PORT=8080
# 命令替换
TODAY=$(date +%F)
# 判断
if [ "$PORT" -eq 8080 ]; then
echo "端口是 8080"
fi
# 循环
for ip in 192.168.0.24 192.168.0.25 192.168.0.26; do
echo "检查 $ip"
ping -c 1 -W 1 "$ip" >/dev/null 2>&1 && echo " 通" || echo " 不通"
done
# 函数
backup_dir() {
local src="$1" # local 声明局部变量
local dst="$2"
local ts=$(date +%Y%m%d_%H%M%S)
mkdir -p "$dst"
tar -czf "$dst/backup_${ts}.tar.gz" "$src"
echo "备份完成: $dst/backup_${ts}.tar.gz"
}
backup_dir "/data/app" "/backup"Shell 脚本的五个经典陷阱(每个都能造成事故)
| 陷阱 | 后果 | 正确写法 |
|---|---|---|
| 变量不加引号 | 变量含空格时,参数被拆成多个 | "$var" 永远加引号 |
没有 set -e | 前面命令失败,脚本继续跑,把后续搞乱 | 开头加 set -euo pipefail |
rm -rf "$DIR/" 但 DIR 为空 | 删掉根目录! | 先检查:`[ -n "$DIR" ] |
cd 失败后继续执行 | 在错误目录里执行删除/覆盖 | `cd "$DIR" |
用 $(...) 拼命令但没引号 | 命令注入、路径含空格出错 | 用数组:cmd=("$a" "$b"); "${cmd[@]}" |
最危险的一条:
bash
# ❌ 危险!如果 DIR 是空的(比如变量没取到),这会删掉根目录
rm -rf $DIR/*
# ✅ 正确:先校验
[ -n "${DIR}" ] || { echo "DIR 为空,退出"; exit 1; }
[ -d "${DIR}" ] || { echo "目录不存在,退出"; exit 1; }
rm -rf "${DIR:?DIR 未设置}"/ # :? 会在变量为空时报错退出这是真实发生过的重大事故(有人用这样的脚本删掉了整个服务器)。
7.3 定时任务:cron
一句话:让系统按时间自动执行任务。
crontab 格式(五个星号):
图 7-3 cron 五字段:分 时 日 月 周,从左到右依次是粒度从细到粗
常用示例:
| 需求 | 表达式 |
|---|---|
| 每分钟 | * * * * * |
| 每 5 分钟 | */5 * * * * |
| 每天凌晨 2 点 | 0 2 * * * |
| 每周一 9 点 | 0 9 * * 1 |
| 每月 1 号 0 点 | 0 0 1 * * |
| 工作日每小时 | 0 * * * 1-5 |
| 每 30 分钟(8-18 点) | */30 8-18 * * * |
相关命令:
bash
crontab -e # 编辑当前用户的定时任务
crontab -l # 列出
crontab -r # 删除所有(危险)
ls /etc/cron.d/ # 系统级定时任务cron 的五个坑(新人几乎必踩)
- 环境变量不同。cron 执行时没有你的 shell 环境,
PATH很短。 所以脚本里要用绝对路径(/usr/bin/docker而不是docker),或在脚本里显式设置 PATH。 - 工作目录不同。cron 的工作目录是用户的 home,不是你以为的地方。 → 脚本里用绝对路径,或开头
cd /path || exit 1。 - 输出被丢弃。cron 执行的输出会发邮件(通常没人看)。 → 重定向到日志:
* * * * * /path/script.sh >> /var/log/script.log 2>&1 - 任务重叠。上一个还没跑完,下一个又开始了。 → 用
flock加锁:flock -n /tmp/task.lock /path/script.sh %需要转义。cron 里%有特殊含义(表示换行),要用\%。
7.4 监控与日志(基础)
(架构文档第 9 章有完整体系,这里讲基础)
监控的三个层次:
| 层次 | 监控什么 | 例子 |
|---|---|---|
| 基础设施 | 服务器、网络 | CPU、内存、磁盘、网络流量 |
| 中间件 | 数据库、缓存、MQ | 连接数、慢查询、队列积压 |
| 应用/业务 | 服务本身 | QPS、错误率、响应时间、订单量 |
监控的核心心法:先定"什么是正常",再定"怎么告警"
很多新人一上来就装 Prometheus + 配一堆告警,结果告警天天响,没人看。
正确顺序:
- 先明确要保障什么(如"下单接口成功率 > 99.9%")。
- 找到能反映它的指标(下单成功率 = 成功数/总数)。
- 设合理阈值 + 持续时间(错误率 > 1% 持续 2 分钟)。
- 告警要能到人、要可行动。
没有第 1 步的监控,都是在制造噪音。
日志的五个级别(必须理解):
| 级别 | 何时用 | 生产环境 |
|---|---|---|
| DEBUG | 调试细节 | ❌ 绝不要开(量大、含敏感信息、拖慢性能) |
| INFO | 正常的关键流程 | ✅ 开启 |
| WARN | 有异常但可继续 | ✅ 开启,需要关注 |
| ERROR | 出错了 | ✅ 开启,要告警 |
| FATAL | 致命错误 | ✅ 开启,要告警 |
运维看日志的常用命令:
bash
# 实时看日志(最常用)
tail -f /var/log/app/app.log
# 看最后 100 行
tail -n 100 app.log
# 搜索关键字 + 上下文
grep -C 5 "Exception" app.log # 前后各 5 行
# 统计错误数量
grep -c "ERROR" app.log
# 按时间范围查(配合 journalctl)
journalctl -u nginx --since "2026-09-24 10:00:00" --until "2026-09-24 11:00:00"
# ★ 最实用的组合:看某段时间的错误并统计
grep "ERROR" app.log | grep "10:0[0-9]" | awk '{print $5}' | sort | uniq -c | sort -rn | head
# 大文件里找特定请求
grep "traceId=abc123" app.log生产环境看日志的三条纪律
- 不要用
cat看大日志(几十 GB 会把终端卡死)→ 用less或tail。 - 不要在日志里 grep 半天(几十 GB 的 grep 要几分钟)→ 应该用集中日志平台(ELK)。
- 注意日志里的敏感信息(密码、token、身份证)→ 不要复制出去传播。
第八部分 工程协作
8.1 Git:代码的时光机
一句话:Git 是版本控制工具,记录代码的每一次变化,可以随时回退和协作。
为什么需要它:
- 不用 Git:
最终版.doc、最终版2.doc、真正最终版.doc……(这就是没有版本控制的后果) - 用 Git:每次改动有记录、有说明、能对比、能回退、多人不冲突
核心概念:
| 概念 | 说明 | 类比 |
|---|---|---|
| 仓库 Repository | 存放代码和历史的目录 | 一个项目文件夹 |
| 提交 Commit | 一次变更的快照 | 游戏存档点 |
| 分支 Branch | 独立的开发线 | 平行宇宙 |
| 合并 Merge | 把分支合到一起 | 两个宇宙合流 |
| 远程 Remote | 服务器上的仓库(GitLab/GitHub) | 云端备份 |
| 标签 Tag | 给某个提交打标记(如 v1.0.0) | 里程碑 |
核心工作流(必须会):
bash
git clone <url> # 克隆仓库
git checkout -b feature/x # 新建分支
# ... 改代码 ...
git add . # 暂存改动
git commit -m "feat: 添加功能" # 提交
git push origin feature/x # 推送到远程
# 然后在平台上发起 Merge Request / Pull Request分支策略(真实公司常见):
main/master ← 生产分支,只允许通过 MR 合入,受保护
↑
release/* ← 发布分支,从 develop 切出,用于上线
↑
develop ← 开发主线,集成各功能
↑
feature/* ← 功能分支,每人一个
hotfix/* ← 紧急修复分支,从 master 切出,修完合回 master 和 develop运维为什么必须懂 Git
因为现代运维的一切配置都是代码:
- K8s 的 YAML → 放 Git
- Ansible playbook / Terraform → 放 Git
- Nginx 配置、监控规则、告警规则 → 放 Git
- GitOps 的核心思想:Git 是唯一真相来源,改 Git 就等于改线上
不会 Git 的运维,无法参与现代运维工作。 这是硬门槛,不是加分项。
8.2 CI / CD:从代码到上线的自动化
先搞清楚这几个词(容易混):
| 缩写 | 全称 | 含义 | 包含什么 |
|---|---|---|---|
| CI | Continuous Integration 持续集成 | 代码提交后自动构建 + 测试 | 编译、单测、代码扫描、打包 |
| CD | Continuous Delivery 持续交付 | 自动部署到类生产环境,人工点按钮才上生产 | 部署到测试/预发 |
| CD | Continuous Deployment 持续部署 | 自动部署到生产,全自动无人干预 | 全自动上线 |
"持续交付" vs "持续部署" 的区别(面试常问)
- 持续交付(Delivery):流水线自动跑到"待上线"状态,最后一步由人确认。 适合:金融、医疗等高风险场景。
- 持续部署(Deployment):全程无人工干预,测试通过就自动上线。 适合:成熟的互联网公司、低风险变更。
一句话区别:Delivery 是"随时可以发,但要人点一下";Deployment 是"根本不用人点"。
典型 CI 流水线(Jenkins 为例):
① 拉代码 git checkout
② 编译构建 mvn package / npm build
③ 单元测试 mvn test / jest
④ 代码质量扫描 SonarQube(圈复杂度、重复代码、漏洞)
⑤ 依赖安全扫描 Trivy / Dependency-Check(CVE 漏洞)
⑥ 构建镜像 docker build
⑦ 推送镜像 docker push harbor.xxx/prod/app:v1.2.3
⑧ 更新部署清单 (GitOps 模式)改 Git 仓库里的镜像 tag
⑨ 触发部署 Argo CD / kubectl apply
⑩ 验证 健康检查、冒烟测试
⑪ 通知 企微/钉钉通知结果常用 CI/CD 工具:
| 工具 | 特点 | 适用 |
|---|---|---|
| Jenkins | 最老牌、插件最全、灵活 | 绝大多数传统企业 |
| GitLab CI | 和 GitLab 深度集成,配置即代码 | 用 GitLab 的团队 |
| GitHub Actions | 和 GitHub 集成,云上运行 | 开源项目、GitHub 用户 |
| Argo CD | GitOps,K8s 原生 | K8s 环境 |
| Tekton | K8s 原生的流水线 | 云原生团队 |
| Drone / Woodpecker | 轻量、容器原生 | 小团队 |
发布策略(必须知道这四种):
| 策略 | 做法 | 优点 | 缺点 | 适用 |
|---|---|---|---|---|
| 停机发布 | 停旧 → 起新 | 简单 | 服务中断 | 内部系统 |
| 滚动发布 | 一批批替换(K8s 默认) | 不中断、资源省 | 新旧版本同时在线,回滚慢 | 大多数场景 |
| 蓝绿发布 | 新老两套环境,切流量 | 秒级切换、秒级回滚 | 资源翻倍 | 关键业务 |
| 金丝雀发布 | 先给小比例流量试,逐步放大 | 风险最小 | 实现复杂 | 重要变更 |
灰度 / 金丝雀 / 蓝绿 的关系
- 蓝绿:两套完整环境,全量切换(0% → 100%)。
- 金丝雀:一套环境里跑两个版本,按比例逐步放大(1% → 5% → 50% → 100%)。
- 灰度:一个更大的概念——只要不是"所有人都立刻用新版", 都可以叫灰度。金丝雀是灰度的一种实现方式。
口诀:蓝绿是"全切",金丝雀是"渐进",灰度是"统称"。
8.3 环境与配置管理
环境:dev(开发)、test(测试)、uat(验收)、prod(生产)。 (详见架构文档第 1 章)
为什么配置要外置:
❌ 错误做法:把数据库密码写在代码里
→ 换个环境要改代码重新打包
→ 密码进了 Git,所有能看到代码的人都知道了
✅ 正确做法:配置从环境变量 / 配置文件 / 配置中心读取
→ 同一份镜像在多环境复用
→ 敏感信息不进代码仓库十二要素应用(12-Factor App): 这是一套"云原生应用应该怎么设计"的经典方法论,运维应该了解。核心几条:
| 要素 | 含义 |
|---|---|
| 代码库 | 一份代码,多份部署(用配置区分环境) |
| 依赖 | 显式声明依赖(不要依赖系统里已装的东西) |
| 配置 | 存在环境里,不在代码里 |
| 后端服务 | 把数据库/缓存当"附加资源",可随时替换 |
| 构建/发布/运行 | 严格分离三个阶段 |
| 进程 | 应用无状态(状态存到外部) |
| 端口绑定 | 通过端口提供服务,不依赖外部 Web 服务器 |
| 并发 | 用进程模型横向扩展 |
| 易处理 | 快速启动、优雅关闭(这对 K8s 极重要) |
| 开发/生产一致 | 各环境尽量一致 |
| 日志 | 当作事件流输出到 stdout,不要自己管文件 |
| 管理进程 | 一次性任务(迁移、脚本)作为独立进程运行 |
为什么"日志输出到 stdout"很重要
这是容器化的基本要求:
- 如果应用把日志写在
/var/log/app.log,容器删了日志就没了,且采集器要挂载卷才能读到。 - 如果应用把日志输出到 stdout,K8s 会自动收集(
kubectl logs能看到), 日志采集器(Fluent Bit)也能直接从标准输出抓走,不用挂任何卷。
所以上线前要检查一件事:你的应用是不是输出到 stdout/stderr? 如果不是,容器化时会遇到一堆日志问题。
8.4 IaC:基础设施即代码
一句话:用代码来创建和管理服务器、网络、数据库等基础设施,而不是在控制台点鼠标。
为什么重要:
| 点鼠标(传统) | IaC |
|---|---|
| 无法版本管理 | 代码进 Git,有历史、可回滚 |
| 无法复现("上次怎么配的忘了") | 一份代码可以创建一模一样的环境 |
| 容易配错、漏配 | 代码评审,减少人为错误 |
| 无法审计(谁改了什么不知道) | 每次变更有记录 |
| 灾难恢复慢 | 重新执行代码即可 |
主流工具:
| 工具 | 特点 | 学习曲线 |
|---|---|---|
| Terraform | 声明式、云厂商中立、生态最大 | 中 |
| Ansible | 无 Agent(走 SSH)、配置管理强 | 低(运维入门首选) |
| Pulumi | 用真正的编程语言(TS/Python/Go)写 | 中 |
| CloudFormation | AWS 原生 | 中 |
| Helm | K8s 应用的包管理(模板化 YAML) | 中 |
| Kustomize | K8s YAML 的多环境差异化(无模板) | 低 |
Ansible 为什么适合运维入门
它不需要在被管机器上装任何东西(走 SSH,用 Python 执行)。 一句 ansible all -m ping 就能测试 100 台机器的连通性。
yaml
# 一个 Ansible playbook 的样子
- hosts: webservers
become: yes # 用 sudo
tasks:
- name: 安装 Nginx
yum: { name: nginx, state: present }
- name: 启动并开机自启
service: { name: nginx, state: started, enabled: yes }
- name: 拷贝配置
copy: { src: nginx.conf, dest: /etc/nginx/nginx.conf }
notify: 重启 Nginx # 配置变了才重启
handlers:
- name: 重启 Nginx
service: { name: nginx, state: restarted }读起来就像文档,这就是 Ansible 的最大优点。
第九部分 安全基础
9.1 认证 vs 授权(最容易混淆的一对)
| 认证 Authentication | 授权 Authorization | |
|---|---|---|
| 回答的问题 | "你是谁?" | "你能做什么?" |
| 英文 | AuthN | AuthZ |
| 手段 | 密码、验证码、指纹、证书 | 权限表、RBAC |
| 时序 | 先认证 | 后授权 |
| 例子 | 登录 | 登录后能不能删别人的帖子 |
记忆方法
认证 = 验明正身;授权 = 分配权限。 英文里 Authentication 有 "identity(身份)",Authorization 有 "authority(权力)"。
常见的认证方式:
| 方式 | 说明 | 安全等级 |
|---|---|---|
| 用户名 + 密码 | 最基础 | 低(要配合复杂度、失败锁定) |
| 短信验证码 | 二次验证 | 中 |
| MFA / 2FA | 两种以上因素(密码 + 手机/TOTP) | 高(重要系统必须) |
| SSO 单点登录 | 一次登录,全站通用 | 高(企业标配) |
| OAuth2 / OIDC | 授权第三方访问("用微信登录") | 高 |
| 数字证书 | 双向 TLS 认证 | 高(服务间认证) |
| API Key / Token | 程序间认证 | 中(要能轮换) |
授权模型:
| 模型 | 全称 | 说明 |
|---|---|---|
| RBAC | 基于角色的访问控制 | 最常用:用户 → 角色 → 权限 |
| ABAC | 基于属性的访问控制 | 按属性动态判断(部门、时间、地点) |
| ACL | 访问控制列表 | 直接给资源配"谁能访问" |
| 最小权限原则 | Principle of Least Privilege | 只给必需的最小权限(安全第一原则) |
9.2 加密:对称与非对称
| 对称加密 | 非对称加密 | |
|---|---|---|
| 密钥 | 一个密钥(加密解密同一个) | 一对密钥(公钥 + 私钥) |
| 算法 | AES、DES、3DES | RSA、ECC、SM2(国密) |
| 速度 | 快(比非对称快 1000 倍) | 慢 |
| 用途 | 大量数据加密 | 密钥交换、数字签名 |
| 问题 | 密钥怎么安全地传给对方? | 速度慢,不适合大数据 |
实际用法(HTTPS 就是经典组合):
用非对称加密安全地协商出一个「对称密钥」
↓
用这个对称密钥加密后续所有通信数据这个组合同时解决了"安全"和"快"两个问题。(详见 3.3.2 节)
摘要与签名:
| 概念 | 说明 |
|---|---|
| 哈希 / 摘要 | 把任意长度数据变成固定长度的"指纹"(MD5、SHA-256) |
| 特性 | 单向(不可逆)、相同输入必得相同输出、微小改动结果完全不同 |
| 数字签名 | 用私钥对摘要加密 → 别人用公钥验证 → 证明"是我发的、没被改过" |
运维必知的加密相关红线
- MD5 / SHA-1 已不安全(可用于碰撞攻击),密码存储必须用 bcrypt / Argon2 / PBKDF2。 (记住:存密码永远不能"可逆",只能存哈希 + 加盐。)
- 密钥不能硬编码在代码里。用 K8s Secret、Vault、KMS。
- 不要自己发明加密算法。用成熟的库和标准。
- 国密算法(SM2/SM3/SM4)在政务、金融场景是强制要求,需要时会用到(用支持国密的库)。
9.3 常见攻击与防护(运维要能识别)
| 攻击 | 原理 | 防护 |
|---|---|---|
| SQL 注入 | 把 SQL 语句拼进用户输入 | 参数化查询(预编译);WAF |
| XSS 跨站脚本 | 注入 JS 到页面,窃取 Cookie | 输出转义;CSP;Cookie 加 HttpOnly |
| CSRF 跨站请求伪造 | 诱导已登录用户发起请求 | CSRF Token;SameSite Cookie |
| DDoS / CC | 海量请求打满带宽或资源 | CDN + 高防 + 限流 + 弹性扩容 |
| 暴力破解 | 不断试密码 | 失败锁定、验证码、MFA、封 IP |
| 越权 | 改 URL 里的 ID 访问别人的数据 | 服务端校验(不能只靠前端隐藏) |
| 文件上传漏洞 | 上传 webshell(可执行脚本) | 白名单后缀 + 重命名 + 存储与执行分离 |
| SSRF | 让服务器帮你访问内网 | 校验 URL 白名单,禁止访问内网段 |
| 中间人攻击 | 窃听/篡改通信 | HTTPS / mTLS |
| 供应链攻击 | 依赖包被投毒 | 锁定版本、私有仓库、依赖扫描 |
运维能做的防护(不用等安全团队)
- 最小开放端口:只开必需的,其余全关(安全组 + 防火墙)。
- 禁止公网暴露数据库/Redis/ES(这是最严重的问题,网上大量"Redis 未授权访问"导致服务器被控)。
- 删除默认账号和默认密码(Redis、Nacos、RabbitMQ、ES 的默认配置都是裸奔的)。
- 及时打补丁(尤其是对外暴露的服务)。
- 开启所有审计日志(出事了能查)。
- 给中间件加鉴权(Nacos 的
auth.enabled、Redis 的requirepass、ES 的 xpack)。
9.4 最小权限原则:安全的第一性原理
一句话:任何主体(人/程序)只应拥有完成其工作所必需的最小权限。
落地做法:
| 场景 | 反面 | 正面 |
|---|---|---|
| 运维登录 | 所有人共用 root 密码 | 每人独立账号 + 堡垒机 + 按需提权 |
| 应用连数据库 | 用 root 连 | 专用账号,只给需要的库表权限 |
| K8s 权限 | 给所有人 cluster-admin | RBAC 按 namespace 授权 |
| 云账号 | 用主账号 AK | 子账号 + 最小策略 + 定期轮换 |
| CI 流水线 | 挂生产密钥 | 按环境隔离凭据,生产需审批 |
| 容器 | --privileged | 非 root 用户 + 只读根文件系统 |
一个真实的安全事故链条
① 开发为了调试方便,把测试环境的 Redis 端口对公网开放(且无密码)
② 攻击者扫描到,写入 SSH 公钥
③ 拿到测试服务器权限
④ 发现测试服务器能访问内网
⑤ 用同样的方式找到生产 Redis(也是无密码)
⑥ 生产数据被拖走 / 被删库勒索每一步都很小,但加起来就是重大事故。对运维来说,"最小权限"不是教条,而是每天都要做的具体决定。
第十部分 云与架构
10.1 云服务三种模式:IaaS / PaaS / SaaS
用"吃饭"来类比最清楚:
| 模式 | 全称 | 类比 | 你负责 | 例子 |
|---|---|---|---|---|
| IaaS | 基础设施即服务 | 买菜自己做 | 操作系统、中间件、应用、数据 | 云主机 ECS/CVM、云硬盘 |
| PaaS | 平台即服务 | 点外卖(有半成品) | 只负责应用和数据 | 云数据库 RDS、云 K8s、Heroku |
| SaaS | 软件即服务 | 去餐厅吃 | 什么都不用管(只使用) | 企业微信、飞书、Salesforce |
再补两个现在常用的:
| 模式 | 说明 | 例子 |
|---|---|---|
| FaaS / Serverless | 只写函数,按调用付费 | AWS Lambda、腾讯云 SCF |
| BaaS | 后端即服务 | Supabase、Firebase |
云的本质是"责任的转移"
| 层次 | 自建 | IaaS | PaaS | SaaS |
|---|---|---|---|---|
| 应用 | 你 | 你 | 你 | 厂商 |
| 中间件 | 你 | 你 | 厂商 | 厂商 |
| 操作系统 | 你 | 你 | 厂商 | 厂商 |
| 虚拟化 | 你 | 厂商 | 厂商 | 厂商 |
| 服务器/网络 | 你 | 厂商 | 厂商 | 厂商 |
| 机房/电力 | 你 | 厂商 | 厂商 | 厂商 |
越往右,你管得越少,但可控性越低、成本越高。选择依据:你的团队规模 + 业务阶段。小团队用 PaaS 省人力,大公司自建降成本。
10.2 负载均衡(基础)
(详见架构文档第 4.2 节,这里讲基础)
一句话:把流量分到多台服务器,避免单台过载,同时实现高可用。
三个层次:
| 层次 | 工作在哪 | 代表 | 能做什么 |
|---|---|---|---|
| DNS 轮询 | DNS 层 | DNS | 简单分发,无法感知故障 |
| 四层 LB | TCP/UDP | LVS、云 ELB/SLB | 高性能转发 |
| 七层 LB | HTTP | Nginx、Ingress | 按 URL/Header 路由、TLS 卸载 |
健康检查(LB 的核心能力): LB 会定期探测后端是否可用(发 HTTP 请求或 TCP 连接), 不健康的节点自动摘除,恢复了再加回来。这是"高可用"的关键机制。
10.3 高可用(HA):基础知识
一句话:高可用 = 系统在部分组件故障时,仍能继续提供服务。
通俗理解:不要把所有鸡蛋放在一个篮子里。
实现高可用的基本手段(就这四招):
| 手段 | 说明 | 例子 |
|---|---|---|
| 冗余 | 多准备一份,坏了一个还有 | 2 台 Nginx、3 个 MySQL 副本 |
| 故障转移(Failover) | 主挂了自动切到备 | MySQL 主从切换、VIP 漂移 |
| 负载均衡 | 流量分散到多台,一起分担 | LVS、Nginx upstream |
| 隔离 | 限制故障影响范围 | 服务隔离、线程池隔离、机房隔离 |
关键指标(见架构文档第 10 章):
- 可用性:99.9% = 一年停机 8.76 小时
- RTO:能接受停多久
- RPO:能接受丢多少数据
"高可用"最常见的假象
看起来多副本,实际是单点:
- 3 个 Pod 都被调度到了同一个节点 → 节点挂了全挂(要配反亲和性)
- LB 双节点但共用一个机柜/交换机 → 机柜断电全挂
- 数据库主从了,但没有自动切换 → 主库挂了要人工介入半小时
- 监控双实例,但数据存在同一块盘 → 盘坏了两个一起丢
判断方法:问一句"如果我现在拔掉任何一个设备/节点的电源,服务还能用吗?" (架构文档第 12.3 节有完整的"假高可用"陷阱清单)
10.4 常见架构模式
| 模式 | 说明 | 适用 |
|---|---|---|
| 单体 | 一个应用包含所有功能 | 小团队、早期产品 |
| 分层 | 接入层/应用层/数据层 | 几乎所有系统的基础 |
| 微服务 | 按业务拆成多个独立服务 | 中大型、多团队 |
| 事件驱动 | 通过消息传递事件解耦 | 异步流程、实时处理 |
| Serverless | 不用管服务器,只写函数 | 低频、突发、事件触发 |
| SOA | 面向服务的架构(微服务的前身) | 传统企业集成 |
| Lambda 架构 | 批处理层 + 流处理层 | 大数据分析 |
| 网格(Mesh) | 服务间通信交给基础设施层 | 多语言、大规模微服务 |
10.5 学习路径:从零到能上手
给转行者的分阶段计划(每阶段都有明确产出):
| 阶段 | 目标 | 学习内容 | 产出(检验标准) |
|---|---|---|---|
| 0 基础 | 会用电脑 | 文件、软件、命令行的概念 | 不害怕黑色终端窗口 |
| 1 Linux 入门 | 能操作 Linux | 装虚拟机、基础命令、vim、权限 | 能在 Linux 上装软件、配服务 |
| 2 网络基础 | 能排查网络问题 | IP/子网/端口/DNS/HTTP | 能定位"为什么连不上" |
| 3 服务部署 | 能部署一个网站 | Nginx、MySQL、动静分离 | 公网能访问你自己的网站 |
| 4 脚本自动化 | 能写脚本 | Shell、cron、文本处理三剑客 | 能写出自动备份脚本 |
| 5 容器化 | 会用 Docker | 镜像、容器、Dockerfile、Compose | 把应用打包成镜像 |
| 6 编排 | 会用 K8s | Pod/Deployment/Service/Ingress | 在 K8s 上部署微服务 |
| 7 CI/CD | 能搭流水线 | Git、Jenkins、GitOps | 提交代码自动上线 |
| 8 可观测 | 能监控和排障 | Prometheus、Grafana、ELK、SkyWalking | 能看懂监控看板、能查日志定位问题 |
| 9 架构能力 | 能设计系统 | 高可用、容灾、容量规划 | 能画出一套完整架构并解释为什么 |
最重要的学习心法
- 一切以"能跑起来"为准。 看书 100 小时不如动手 10 小时。
- 报错是最好的老师。 不要怕报错,学会"看错误信息 → 搜索 → 定位原因"的循环。
- 建立自己的笔记库。 每个命令、每个坑都记下来,半年后你就是别人眼里的"老手"。
- 不要贪多。 上面的 9 个阶段,一次只推进一个,都动手做完比看完 10 个教程强。
- 善用这条公式:遇到问题 → 先判断在哪一层 → 逐层排除 → 定位后记录。
附录
附录 A:缩写速查表(按字母序)
| 缩写 | 全称 | 中文 | 一句话 |
|---|---|---|---|
| ACK | Acknowledgement | 确认 | TCP 里的"收到" |
| ACL | Access Control List | 访问控制列表 | 谁可以访问什么 |
| API | Application Programming Interface | 应用程序接口 | 程序之间对话的约定 |
| APM | Application Performance Management | 应用性能管理 | 追踪应用性能(如 SkyWalking) |
| ARP | Address Resolution Protocol | 地址解析协议 | IP → MAC 地址 |
| AWS | Amazon Web Services | 亚马逊云 | 全球最大云厂商 |
| CDN | Content Delivery Network | 内容分发网络 | 边缘缓存加速 |
| CI/CD | Continuous Integration / Delivery | 持续集成/交付 | 自动化构建与部署 |
| CIDR | Classless Inter-Domain Routing | 无类别域间路由 | 表示网段的方法(如 /24) |
| CNI | Container Network Interface | 容器网络接口 | K8s 网络插件规范(Calico 等) |
| CPU | Central Processing Unit | 中央处理器 | 计算机的"大脑" |
| CRD | Custom Resource Definition | 自定义资源定义 | 扩展 K8s 对象类型 |
| CSI | Container Storage Interface | 容器存储接口 | K8s 存储插件规范 |
| DAU | Daily Active Users | 日活跃用户 | 每天有多少人用 |
| DNS | Domain Name System | 域名系统 | 域名 → IP |
| DDoS | Distributed Denial of Service | 分布式拒绝服务攻击 | 海量流量打垮服务 |
| DR | Disaster Recovery | 灾难恢复 | 机房级故障的应对 |
| ELB | Elastic Load Balancer | 弹性负载均衡 | 云上负载均衡 |
| ES | Elasticsearch | —— | 搜索/日志引擎 |
| ETL | Extract Transform Load | 抽取转换加载 | 数据处理流程 |
| FaaS | Function as a Service | 函数即服务 | Serverless 函数 |
| gRPC | Google Remote Procedure Call | —— | 高性能 RPC 框架 |
| HA | High Availability | 高可用 | 坏了能自动切 |
| HPA | Horizontal Pod Autoscaler | 水平 Pod 自动伸缩 | 按指标自动扩缩容 |
| HTTP(S) | HyperText Transfer Protocol (Secure) | 超文本传输(安全) | Web 通信协议 |
| IaC | Infrastructure as Code | 基础设施即代码 | 用代码管基础设施 |
| IaaS | Infrastructure as a Service | 基础设施即服务 | 云主机、云网络 |
| ICMP | Internet Control Message Protocol | 网际控制报文协议 | ping 用的协议 |
| IOPS | Input/Output Operations Per Second | 每秒读写次数 | 磁盘性能指标 |
| IP | Internet Protocol | 网际协议 | 网络地址协议 |
| JWT | JSON Web Token | —— | 无状态令牌 |
| K8s | Kubernetes | —— | 容器编排系统(K + 8 个字母 + s) |
| LB | Load Balancer | 负载均衡 | 流量分发 |
| LRU | Least Recently Used | 最近最少使用 | 缓存淘汰策略 |
| MAU | Monthly Active Users | 月活跃用户 | —— |
| MFA | Multi-Factor Authentication | 多因素认证 | 密码 + 手机等 |
| MQ | Message Queue | 消息队列 | 异步通信 |
| MTBF | Mean Time Between Failures | 平均无故障时间 | 稳定性指标 |
| MTTR | Mean Time To Recovery | 平均恢复时间 | 故障恢复速度 |
| NAT | Network Address Translation | 网络地址转换 | 私网访问公网 |
| NFS | Network File System | 网络文件系统 | 共享目录 |
| NIC | Network Interface Card | 网卡 | —— |
| NTP | Network Time Protocol | 网络时间协议 | 时间同步 |
| OLTP/OLAP | Online Transaction/Analytical Processing | 联机事务/分析处理 | 交易型/分析型数据库 |
| OS | Operating System | 操作系统 | 管理硬件的大管家 |
| OSI | Open Systems Interconnection | 开放系统互联 | 网络七层模型 |
| OOM | Out Of Memory | 内存溢出 | 内存不够被杀 |
| PaaS | Platform as a Service | 平台即服务 | 云数据库、云 K8s 等 |
| PID | Process ID | 进程号 | 进程的唯一编号 |
| PII | Personally Identifiable Information | 个人可识别信息 | 手机号、身份证等 |
| POC | Proof of Concept | 概念验证 | 小规模验证可行性 |
| QPS | Queries Per Second | 每秒查询数 | 吞吐量指标 |
| RBAC | Role-Based Access Control | 基于角色的访问控制 | 权限模型 |
| RDS | Relational Database Service | 关系型数据库服务 | 云托管数据库 |
| REST | Representational State Transfer | 表述性状态转移 | 一种 API 风格 |
| RPO | Recovery Point Objective | 恢复点目标 | 能丢多少数据 |
| RTO | Recovery Time Objective | 恢复时间目标 | 能停多久 |
| SaaS | Software as a Service | 软件即服务 | 直接用软件(如飞书) |
| SAN | Storage Area Network | 存储区域网络 | 企业级块存储 |
| SDK | Software Development Kit | 软件开发工具包 | 开发用的库 |
| SLA | Service Level Agreement | 服务等级协议 | 承诺的可用性 |
| SLB | Server Load Balancer | 服务器负载均衡 | 云负载均衡(阿里云叫法) |
| SLI | Service Level Indicator | 服务等级指标 | 衡量 SLO 的度量 |
| SLO | Service Level Objective | 服务等级目标 | 内部目标 |
| SMTP | Simple Mail Transfer Protocol | 简单邮件传输协议 | 发邮件 |
| SNAT | Source NAT | 源地址转换 | 内网出公网 |
| SNMP | Simple Network Management Protocol | 简单网络管理协议 | 监控网络设备 |
| SOA | Service-Oriented Architecture | 面向服务的架构 | 微服务的前身 |
| SPOF | Single Point Of Failure | 单点故障 | 挂一个全挂 |
| SQL | Structured Query Language | 结构化查询语言 | 操作数据库 |
| SSO | Single Sign-On | 单点登录 | 一次登录全站通行 |
| SSD | Solid State Drive | 固态硬盘 | 快,无机械部件 |
| SSH | Secure Shell | 安全外壳 | 远程登录 |
| SSL/TLS | Secure Sockets Layer / Transport Layer Security | 传输层安全 | HTTPS 的加密层 |
| SSRF | Server-Side Request Forgery | 服务端请求伪造 | 让服务器帮你访问内网 |
| TCP | Transmission Control Protocol | 传输控制协议 | 可靠传输 |
| TTL | Time To Live | 生存时间 | DNS/缓存的过期时间 |
| TPS | Transactions Per Second | 每秒事务数 | 吞吐量 |
| UDP | User Datagram Protocol | 用户数据报协议 | 不可靠但快 |
| UAT | User Acceptance Test | 用户验收测试 | 验收环境 |
| VM | Virtual Machine | 虚拟机 | 虚拟出的"电脑" |
| VPC | Virtual Private Cloud | 虚拟私有云 | 云上私网 |
| VPN | Virtual Private Network | 虚拟专用网络 | 加密隧道 |
| WAF | Web Application Firewall | Web 应用防火墙 | 防 Web 攻击 |
| WAL | Write-Ahead Logging | 预写日志 | 先写日志再写数据(保证不丢) |
| XSS | Cross-Site Scripting | 跨站脚本攻击 | 注入 JS |
| YAML | YAML Ain't Markup Language | —— | K8s/CI 的配置文件格式 |
附录 B:易混淆概念对照表(面试高频)
这张表建议背下来,它覆盖了面试里 80% 的"比较题"。
| 概念 A | 概念 B | 核心区别(一句话) |
|---|---|---|
| 进程 | 线程 | 进程独立,线程共享进程内存 |
| 并发 | 并行 | 并发是交替执行,并行是同时执行 |
| 虚拟机 | 容器 | 虚拟机虚拟硬件,容器虚拟操作系统 |
| 镜像 | 容器 | 镜像是模板,容器是运行实例 |
| TCP | UDP | TCP可靠有序,UDP快但不可靠 |
| HTTP | HTTPS | HTTPS = HTTP + 加密 |
| 正向代理 | 反向代理 | 正代代理客户端,反代代理服务器 |
| 认证 | 授权 | 认证是你是谁,授权是你能做什么 |
| 对称加密 | 非对称加密 | 对称一个密钥快,非对称一对密钥慢 |
| 硬链接 | 软链接 | 硬链接指向 inode,软链接指向路径 |
| Cookie | Session | Cookie 存客户端,Session 存服务端 |
| Session | JWT | Session 有状态,JWT 无状态 |
| 主键 | 唯一索引 | 主键只有一个且非空,唯一索引可多个且可空 |
| 脏读 | 不可重复读 | 脏读读到未提交数据,不可重复读是两次读不一致 |
| 不可重复读 | 幻读 | 不可重复读是同一行变了,幻读是行数变了 |
| 缓存穿透 | 缓存击穿 | 穿透查不存在的数据,击穿是一个热 key 失效 |
| 缓存击穿 | 缓存雪崩 | 击穿是单个 key,雪崩是大量 key 同时失效 |
| 同步 | 异步 | 同步等结果,异步发出去就返回 |
| 蓝绿发布 | 金丝雀发布 | 蓝绿全量切换,金丝雀逐步放量 |
| 金丝雀 | 灰度 | 金丝雀是具体手段,灰度是统称 |
| CI | CD | CI 是构建测试,CD 是部署 |
| 持续交付 | 持续部署 | 交付要人点按钮,部署全自动 |
| RTO | RPO | RTO 是能停多久,RPO 是能丢多少 |
| SLA | SLO | SLA 是对外承诺,SLO 是内部目标 |
| 四层 LB | 七层 LB | 四层看 IP+端口,七层看 HTTP 内容 |
| 阻塞 | 非阻塞 | 阻塞等着,非阻塞先干别的 |
| 单体 | 微服务 | 单体一个包,微服务拆成多个 |
| 关系型 | 非关系型 | 关系型有表结构和事务,NoSQL 灵活 |
| IaaS | PaaS | IaaS 给你虚拟机,PaaS 给你运行环境 |
| PaaS | SaaS | PaaS 你还要写应用,SaaS 直接用 |
| 有状态 | 无状态 | 有状态依赖本地数据,无状态可随意替换 |
| 熔断 | 限流 | 熔断是下游挂了先别调,限流是限制请求速率 |
| 熔断 | 降级 | 熔断是停止调用,降级是返回兜底结果 |
| MTTR | MTBF | MTTR 恢复耗时,MTBF 故障间隔 |
附录 C:给转行者的 12 条建议
- 不要试图学完再动手。 学一个知识点就用它做一件小事,做完再学下一个。
- 命令不要背,要理解 + 常用。 记不住
find的参数很正常,会查就行(man、--help、搜索)。 - 建立自己的"命令笔记本"。 每次解决问题后把命令和原因记下来,这是你最宝贵的资产。
- 报错信息是你的导航。 90% 的报错,把关键字贴到搜索引擎都能找到答案。学会提取关键字。
- 搞清"分层"思维。 网络分层、架构分层、排查分层——分层是 IT 世界最重要的组织方式。
- 遇到不懂的组件,先问"没有它会怎样"。 这个问题能帮你跳过 90% 的细节,直接抓住本质。
- 把"现象"和"原因"分开。 "服务 502" 是现象,"后端 Pod 没起来" 是原因。不要看到现象就直接下结论。
- 从下往上排查,不要跳步。 网络不通先
ping,不要一上来就改代码。 - 备份是底线。 任何危险操作前先备份。见过太多"手一抖,数据没了"。
- 记录每一次故障。 时间线、现象、根因、解决方式、改进项——这是你成长最快的方式。
- 看懂别人写的架构图,也试着自己画。 画图是最能检验你是否真懂的练习。
- 不要只学工具,要学"为什么"。 工具会过时(今天 Docker,明天 Podman),原理不会。
结语
这份文档不是让你一次读完的,而是让你放在手边随时查的。
如果你刚开始转行,不要被这么多名词吓到。专业和业余的区别不在于"知道多少",而在于"知道下一步该查什么"。
最后给你一个最简单的判断标准:
当你遇到一个从没见过的问题时,你能说出"这大概是网络/存储/应用层的问题, 我应该先用 X 命令确认,再查 Y",你就已经是一个合格的运维了。
(配套阅读:本系列的《中大型互联网企业全量架构》给出了这些概念在真实公司里的完整组装方式。)