feat: add comprehensive backend topics and fix build issues
## 新增内容 ### 附录文档扩展 - 扩展前端项目架构文档 (frontend-project-architecture.md) - 扩展后端项目架构文档 (backend-project-architecture.md) - 扩展数据治理文档 (data-governance.md) - 扩展数据可视化文档 (data-visualization.md) - 扩展分布式系统文档 (distributed-systems.md) - 扩展高可用文档 (high-availability.md) - 扩展单体到微服务文档 (monolith-to-microservices.md) - 扩展系统设计方法论文档 (system-design-methodology.md) - 扩展 Docker 容器文档 (docker-containers.md) - 扩展 Kubernetes 文档 (kubernetes.md) - 扩展 Linux 基础文档 (linux-basics.md) - 扩展神经网络文档 (neural-networks.md) ### 新增交互式组件 - 数据治理组件: DataQualityDemo, DataGovernanceFrameworkDemo, DataLineageDemo - 数据可视化组件: ChartTypeSelectorDemo, DashboardLayoutDemo - 分布式系统组件: CAPTheoremDemo, ConsistencyModelsDemo, DistributedChallengesDemo - 高可用组件: AvailabilityCalculatorDemo, FailoverStrategyDemo - 系统设计组件: SystemDesignStepsDemo, CapacityEstimationDemo - Docker 容器组件: DockerArchitectureDemo, DockerLifecycleDemo - Kubernetes 组件: K8sArchitectureDemo, K8sWorkloadsDemo - Linux 基础组件: LinuxFileSystemDemo, LinuxCommandDemo, LinuxPermissionsDemo - 神经网络组件: NeuronDemo, NetworkLayersDemo, NetworkArchitectureDemo - 单体到微服务组件: ArchEvolutionDemo - 项目架构组件: ProjectArchitectureComparisonDemo - 附录导航组件: AppendixFlowMap ### 英文版重构 - 将 en-us 目录重命名为 en - 更新相关配置和组件中的语言代码 ## Bug 修复 - 修复 index.js 中重复的组件导入语句导致的 build 失败 - 恢复被注释的 InvertedIndexDemo 和 SearchRelevanceDemo 导入 - 修复 HomeFeatures.vue 中 en-us 与 config.mjs 中 en 不一致导致的语言切换问题 ## 其他改进 - 添加构建脚本 (scripts/build.mjs) - 更新依赖版本
This commit is contained in:
@@ -1,3 +1,221 @@
|
||||
# Docker 容器化
|
||||
|
||||
> 待实现
|
||||
::: tip 前言
|
||||
**"在我机器上能跑"是开发者最经典的借口,Docker 让这个借口彻底消失。** 容器化技术将应用及其所有依赖打包成一个标准化的单元,确保在任何环境中都能一致运行。它是现代软件交付的基石。
|
||||
:::
|
||||
|
||||
**这篇文章会带你学什么?**
|
||||
|
||||
学完这章后,你将获得:
|
||||
|
||||
- **核心概念**:理解镜像、容器、仓库三大核心概念
|
||||
- **架构对比**:明白容器和虚拟机的本质区别
|
||||
- **实操能力**:掌握 Dockerfile 编写和常用命令
|
||||
- **编排基础**:学会用 Docker Compose 管理多服务应用
|
||||
- **最佳实践**:了解镜像优化、安全加固等生产级实践
|
||||
|
||||
| 章节 | 内容 | 核心概念 |
|
||||
|-----|------|---------|
|
||||
| **第 1 章** | 为什么需要容器 | 环境一致性、资源效率、标准化交付 |
|
||||
| **第 2 章** | 核心概念 | 镜像、容器、仓库、Dockerfile |
|
||||
| **第 3 章** | Docker 生命周期 | 编写、构建、推送、运行、管理 |
|
||||
| **第 4 章** | Docker Compose | 多服务编排、网络、数据卷 |
|
||||
| **第 5 章** | 最佳实践 | 镜像优化、安全、多阶段构建 |
|
||||
|
||||
---
|
||||
|
||||
## 1. 为什么需要容器?
|
||||
|
||||
在容器出现之前,部署一个应用需要在服务器上手动安装运行时、配置环境变量、处理依赖冲突。不同环境(开发、测试、生产)之间的差异是 bug 的温床。
|
||||
|
||||
<DockerArchitectureDemo />
|
||||
|
||||
### 容器解决了什么问题?
|
||||
|
||||
| 问题 | 传统方式 | 容器方式 |
|
||||
|------|---------|---------|
|
||||
| 环境不一致 | "我本地能跑" | 打包所有依赖,到处一致 |
|
||||
| 依赖冲突 | App A 要 Node 14,App B 要 Node 18 | 每个容器独立环境 |
|
||||
| 资源浪费 | 每个 VM 一个完整 OS | 共享内核,MB 级开销 |
|
||||
| 部署慢 | 手动安装配置 | docker run 一条命令 |
|
||||
| 扩容难 | 新建 VM、装环境、部署 | 秒级启动新容器 |
|
||||
|
||||
::: tip 容器的本质
|
||||
容器不是轻量级虚拟机。它的本质是**被隔离的进程**。Linux 内核通过两个机制实现容器:
|
||||
- **Namespace**:隔离进程的视野(PID、网络、文件系统等)
|
||||
- **Cgroups**:限制进程的资源使用(CPU、内存、IO)
|
||||
|
||||
容器里的进程和宿主机上的普通进程没有本质区别,只是被"关在了一个看不到外面的房间里"。
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
## 2. 核心概念
|
||||
|
||||
Docker 的世界围绕三个核心概念:镜像(Image)、容器(Container)、仓库(Registry)。
|
||||
|
||||
| 概念 | 类比 | 说明 |
|
||||
|------|------|------|
|
||||
| 镜像(Image) | 类 / 模板 | 只读的应用模板,包含代码、运行时、库、配置 |
|
||||
| 容器(Container) | 实例 / 对象 | 镜像的运行实例,可读写,有独立的生命周期 |
|
||||
| 仓库(Registry) | 应用商店 | 存储和分发镜像的服务(Docker Hub、ACR、ECR) |
|
||||
| Dockerfile | 配方 / 蓝图 | 定义如何构建镜像的文本文件 |
|
||||
| 数据卷(Volume) | 外接硬盘 | 持久化数据,容器删除后数据不丢失 |
|
||||
|
||||
### 镜像的分层结构
|
||||
|
||||
Docker 镜像由多个只读层(Layer)叠加而成,每条 Dockerfile 指令创建一层:
|
||||
|
||||
```
|
||||
┌─────────────────────────┐
|
||||
│ CMD ["node", "app.js"] │ ← 启动命令层
|
||||
├─────────────────────────┤
|
||||
│ COPY . /app │ ← 应用代码层(经常变)
|
||||
├─────────────────────────┤
|
||||
│ RUN npm install │ ← 依赖安装层(偶尔变)
|
||||
├─────────────────────────┤
|
||||
│ FROM node:18-alpine │ ← 基础镜像层(很少变)
|
||||
└─────────────────────────┘
|
||||
```
|
||||
|
||||
::: tip 为什么分层很重要?
|
||||
Docker 会缓存每一层。如果某一层没有变化,构建时会直接复用缓存。所以 Dockerfile 中应该把**变化频率低的指令放在前面**(如安装依赖),**变化频率高的放在后面**(如复制代码)。这样大部分构建都能命中缓存,速度快很多。
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
## 3. Docker 生命周期
|
||||
|
||||
从编写 Dockerfile 到容器运行,Docker 的工作流程是一条清晰的流水线。
|
||||
|
||||
<DockerLifecycleDemo />
|
||||
|
||||
### Dockerfile 常用指令速查
|
||||
|
||||
| 指令 | 作用 | 示例 |
|
||||
|------|------|------|
|
||||
| `FROM` | 指定基础镜像 | `FROM node:18-alpine` |
|
||||
| `WORKDIR` | 设置工作目录 | `WORKDIR /app` |
|
||||
| `COPY` | 复制文件到镜像 | `COPY package.json ./` |
|
||||
| `RUN` | 构建时执行命令 | `RUN npm install` |
|
||||
| `ENV` | 设置环境变量 | `ENV NODE_ENV=production` |
|
||||
| `EXPOSE` | 声明端口(仅文档作用) | `EXPOSE 3000` |
|
||||
| `CMD` | 容器启动命令 | `CMD ["node", "app.js"]` |
|
||||
| `ENTRYPOINT` | 容器入口点(不易被覆盖) | `ENTRYPOINT ["nginx"]` |
|
||||
|
||||
---
|
||||
|
||||
## 4. Docker Compose:多服务编排
|
||||
|
||||
真实项目通常不止一个容器。一个 Web 应用可能需要:应用服务器 + 数据库 + Redis + Nginx。Docker Compose 用一个 YAML 文件定义和管理多个容器。
|
||||
|
||||
### docker-compose.yml 示例
|
||||
|
||||
```yaml
|
||||
version: '3.8'
|
||||
services:
|
||||
app:
|
||||
build: .
|
||||
ports:
|
||||
- "3000:3000"
|
||||
environment:
|
||||
- DB_HOST=db
|
||||
- REDIS_HOST=redis
|
||||
depends_on:
|
||||
- db
|
||||
- redis
|
||||
|
||||
db:
|
||||
image: postgres:15-alpine
|
||||
volumes:
|
||||
- db-data:/var/lib/postgresql/data
|
||||
environment:
|
||||
- POSTGRES_PASSWORD=secret
|
||||
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
|
||||
volumes:
|
||||
db-data:
|
||||
```
|
||||
|
||||
### Compose 核心概念
|
||||
|
||||
| 概念 | 说明 | 示例 |
|
||||
|------|------|------|
|
||||
| services | 定义各个容器服务 | app、db、redis |
|
||||
| volumes | 持久化数据卷 | db-data 保存数据库文件 |
|
||||
| networks | 自定义网络(默认自动创建) | 服务间通过服务名互相访问 |
|
||||
| depends_on | 启动顺序依赖 | app 依赖 db 和 redis |
|
||||
| environment | 环境变量 | 数据库密码、连接地址 |
|
||||
|
||||
::: tip 服务发现
|
||||
在 Docker Compose 中,服务名就是主机名。app 容器可以直接用 `db:5432` 访问数据库,用 `redis:6379` 访问 Redis,不需要知道 IP 地址。这是 Docker 内置 DNS 的功劳。
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
## 5. 最佳实践
|
||||
|
||||
### 5.1 多阶段构建(Multi-stage Build)
|
||||
|
||||
多阶段构建是优化镜像大小的利器。构建阶段安装所有工具和依赖,最终阶段只保留运行时需要的文件。
|
||||
|
||||
```dockerfile
|
||||
# 构建阶段
|
||||
FROM node:18-alpine AS builder
|
||||
WORKDIR /app
|
||||
COPY package*.json ./
|
||||
RUN npm ci
|
||||
COPY . .
|
||||
RUN npm run build
|
||||
|
||||
# 运行阶段
|
||||
FROM node:18-alpine
|
||||
WORKDIR /app
|
||||
COPY --from=builder /app/dist ./dist
|
||||
COPY --from=builder /app/node_modules ./node_modules
|
||||
EXPOSE 3000
|
||||
CMD ["node", "dist/server.js"]
|
||||
```
|
||||
|
||||
### 5.2 镜像优化清单
|
||||
|
||||
| 优化项 | 做法 | 效果 |
|
||||
|--------|------|------|
|
||||
| 选择小基础镜像 | 用 `alpine` 而非 `ubuntu` | 镜像从 ~200MB 降到 ~50MB |
|
||||
| 合并 RUN 指令 | 多个命令用 `&&` 连接 | 减少镜像层数 |
|
||||
| 使用 .dockerignore | 排除 node_modules、.git 等 | 加速构建,减小上下文 |
|
||||
| 多阶段构建 | 分离构建和运行环境 | 最终镜像不含构建工具 |
|
||||
| 固定版本号 | `node:18.17-alpine` 而非 `node:latest` | 构建可重复 |
|
||||
|
||||
### 5.3 安全实践
|
||||
|
||||
| 实践 | 说明 |
|
||||
|------|------|
|
||||
| 不用 root 运行 | `USER node` 指定非 root 用户 |
|
||||
| 扫描漏洞 | `docker scout` 或 Trivy 扫描镜像 |
|
||||
| 最小权限 | 只安装必要的包,不装调试工具 |
|
||||
| 不硬编码密钥 | 用环境变量或 Docker Secrets |
|
||||
| 定期更新基础镜像 | 及时修复安全漏洞 |
|
||||
|
||||
---
|
||||
|
||||
## 总结
|
||||
|
||||
Docker 容器化是现代软件交付的基础设施,理解它对于任何开发者都至关重要。
|
||||
|
||||
回顾本章的关键要点:
|
||||
|
||||
1. **容器 vs 虚拟机**:容器共享宿主内核,更轻量、更快,但隔离性略弱于 VM
|
||||
2. **核心三件套**:镜像(模板)、容器(实例)、仓库(分发)
|
||||
3. **Dockerfile**:分层构建,利用缓存,变化少的指令放前面
|
||||
4. **Docker Compose**:用 YAML 定义多服务应用,服务名即主机名
|
||||
5. **生产实践**:多阶段构建减小镜像、alpine 基础镜像、非 root 运行
|
||||
|
||||
## 延伸阅读
|
||||
|
||||
- [Docker 官方文档](https://docs.docker.com/) - 最权威的参考资料
|
||||
- [Docker Getting Started](https://docs.docker.com/get-started/) - 官方入门教程
|
||||
- [Dockerfile Best Practices](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/) - 官方最佳实践指南
|
||||
- [Docker Compose 文档](https://docs.docker.com/compose/) - Compose 完整参考
|
||||
|
||||
@@ -1,3 +1,192 @@
|
||||
# Kubernetes 编排
|
||||
|
||||
> 待实现
|
||||
::: tip 前言
|
||||
**Docker 解决了"打包"问题,Kubernetes 解决了"管理"问题。** 当你有几十上百个容器需要部署、扩缩容、故障恢复时,手动管理是不现实的。Kubernetes(K8s)就是容器的"操作系统",它自动化了容器化应用的部署、扩展和运维。
|
||||
:::
|
||||
|
||||
**这篇文章会带你学什么?**
|
||||
|
||||
学完这章后,你将获得:
|
||||
|
||||
- **架构理解**:掌握 K8s 控制平面和工作节点的组成
|
||||
- **核心资源**:熟悉 Pod、Deployment、Service 等核心概念
|
||||
- **声明式管理**:理解"声明期望状态,系统自动收敛"的思想
|
||||
- **运维能力**:了解滚动更新、自动扩缩容、健康检查等机制
|
||||
- **实战入门**:能用 kubectl 和 YAML 部署一个完整应用
|
||||
|
||||
| 章节 | 内容 | 核心概念 |
|
||||
|-----|------|---------|
|
||||
| **第 1 章** | 为什么需要 K8s | 容器编排的挑战 |
|
||||
| **第 2 章** | K8s 架构 | 控制平面、工作节点、etcd |
|
||||
| **第 3 章** | 核心资源 | Pod、Deployment、Service、Ingress |
|
||||
| **第 4 章** | 声明式管理 | YAML、kubectl、控制循环 |
|
||||
| **第 5 章** | 运维实践 | 滚动更新、HPA、健康检查 |
|
||||
|
||||
---
|
||||
|
||||
## 1. 为什么需要 Kubernetes?
|
||||
|
||||
Docker 让单个容器的打包和运行变得简单,但当你面对以下场景时,手动管理就力不从心了:
|
||||
|
||||
| 挑战 | 描述 | K8s 的解决方案 |
|
||||
|------|------|---------------|
|
||||
| 多实例部署 | 一个服务需要运行 10 个副本 | Deployment 自动管理副本数 |
|
||||
| 故障恢复 | 某个容器挂了需要自动重启 | 控制器自动检测并重建 Pod |
|
||||
| 服务发现 | 容器 IP 会变,怎么找到对方? | Service 提供稳定的 DNS 和 IP |
|
||||
| 滚动更新 | 更新版本时不能停服 | 逐步替换旧 Pod,零停机 |
|
||||
| 弹性伸缩 | 流量高峰自动扩容 | HPA 根据 CPU/内存自动调整副本数 |
|
||||
| 资源调度 | 把容器放到最合适的机器上 | Scheduler 智能调度 |
|
||||
|
||||
::: tip K8s 的核心思想:声明式
|
||||
你不需要告诉 K8s "启动 3 个容器"(命令式),而是告诉它 "我要 3 个副本在运行"(声明式)。K8s 会持续监控,确保实际状态与你声明的期望状态一致。如果一个 Pod 挂了,它会自动创建新的来补上。
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
## 2. Kubernetes 架构
|
||||
|
||||
K8s 集群由控制平面(Control Plane)和工作节点(Worker Node)组成。
|
||||
|
||||
<K8sArchitectureDemo />
|
||||
|
||||
### 一次请求的完整路径
|
||||
|
||||
```
|
||||
用户请求 → Ingress Controller → Service → kube-proxy → Pod(容器)
|
||||
↑
|
||||
Endpoint 列表(由 Service 维护)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. 核心资源对象
|
||||
|
||||
K8s 通过各种"资源对象"来描述集群的期望状态。
|
||||
|
||||
<K8sWorkloadsDemo />
|
||||
|
||||
### 资源对象分类
|
||||
|
||||
| 类别 | 资源 | 用途 |
|
||||
|------|------|------|
|
||||
| 工作负载 | Pod、Deployment、StatefulSet、DaemonSet、Job | 运行应用 |
|
||||
| 网络 | Service、Ingress、NetworkPolicy | 服务发现和流量管理 |
|
||||
| 配置 | ConfigMap、Secret | 配置和敏感数据管理 |
|
||||
| 存储 | PersistentVolume、PersistentVolumeClaim | 持久化存储 |
|
||||
| 调度 | Node、Namespace、ResourceQuota | 资源隔离和限制 |
|
||||
|
||||
---
|
||||
|
||||
## 4. 声明式管理与 kubectl
|
||||
|
||||
### 控制循环(Reconciliation Loop)
|
||||
|
||||
K8s 的核心工作机制是控制循环:
|
||||
|
||||
```
|
||||
观察(Observe)→ 比较(Diff)→ 行动(Act)→ 观察...
|
||||
↓ ↓ ↓
|
||||
读取实际状态 与期望状态对比 执行修正操作
|
||||
```
|
||||
|
||||
你声明 `replicas: 3`,控制器发现只有 2 个 Pod 在运行,就会创建 1 个新的。这个循环每隔几秒执行一次,确保系统始终向期望状态收敛。
|
||||
|
||||
### kubectl 常用命令
|
||||
|
||||
| 命令 | 作用 | 示例 |
|
||||
|------|------|------|
|
||||
| `kubectl apply -f` | 应用 YAML 配置 | `kubectl apply -f deployment.yaml` |
|
||||
| `kubectl get` | 查看资源列表 | `kubectl get pods -o wide` |
|
||||
| `kubectl describe` | 查看资源详情 | `kubectl describe pod my-app-xxx` |
|
||||
| `kubectl logs` | 查看 Pod 日志 | `kubectl logs -f my-app-xxx` |
|
||||
| `kubectl exec` | 进入 Pod 终端 | `kubectl exec -it my-app-xxx -- sh` |
|
||||
| `kubectl delete` | 删除资源 | `kubectl delete -f deployment.yaml` |
|
||||
| `kubectl scale` | 手动扩缩容 | `kubectl scale deploy my-app --replicas=5` |
|
||||
|
||||
::: tip apply vs create
|
||||
`kubectl create` 是命令式的——"创建这个资源",如果已存在会报错。`kubectl apply` 是声明式的——"确保资源是这个状态",不存在就创建,已存在就更新。生产环境中应该始终使用 `apply`。
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
## 5. 运维实践
|
||||
|
||||
### 5.1 滚动更新与回滚
|
||||
|
||||
Deployment 默认使用滚动更新策略:逐步创建新版本 Pod,同时逐步终止旧版本 Pod。
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxSurge: 1 # 最多多创建 1 个 Pod
|
||||
maxUnavailable: 0 # 不允许有 Pod 不可用
|
||||
```
|
||||
|
||||
| 操作 | 命令 |
|
||||
|------|------|
|
||||
| 更新镜像 | `kubectl set image deploy/my-app app=my-app:2.0` |
|
||||
| 查看更新状态 | `kubectl rollout status deploy/my-app` |
|
||||
| 查看历史版本 | `kubectl rollout history deploy/my-app` |
|
||||
| 回滚到上一版本 | `kubectl rollout undo deploy/my-app` |
|
||||
|
||||
### 5.2 自动扩缩容(HPA)
|
||||
|
||||
HPA(Horizontal Pod Autoscaler)根据 CPU、内存或自定义指标自动调整 Pod 副本数。
|
||||
|
||||
```yaml
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: my-app-hpa
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: my-app
|
||||
minReplicas: 2
|
||||
maxReplicas: 10
|
||||
metrics:
|
||||
- type: Resource
|
||||
resource:
|
||||
name: cpu
|
||||
target:
|
||||
type: Utilization
|
||||
averageUtilization: 70
|
||||
```
|
||||
|
||||
### 5.3 健康检查(Probe)
|
||||
|
||||
K8s 通过三种探针监控 Pod 的健康状态:
|
||||
|
||||
| 探针 | 作用 | 失败后果 |
|
||||
|------|------|---------|
|
||||
| livenessProbe | 检测容器是否存活 | 重启容器 |
|
||||
| readinessProbe | 检测容器是否就绪 | 从 Service 摘除,不接收流量 |
|
||||
| startupProbe | 检测容器是否启动完成 | 启动期间不执行其他探针 |
|
||||
|
||||
::: tip 探针的重要性
|
||||
没有配置健康检查的 Pod,K8s 只能通过进程是否存在来判断健康状态。但很多时候进程还在,服务已经不响应了(比如死锁、OOM 边缘)。配置 livenessProbe 可以让 K8s 自动重启这些"假死"的容器。
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
## 总结
|
||||
|
||||
Kubernetes 是容器编排的事实标准,理解它的核心概念是云原生开发的基础。
|
||||
|
||||
回顾本章的关键要点:
|
||||
|
||||
1. **声明式管理**:告诉 K8s "我要什么",而不是"怎么做",控制循环自动收敛
|
||||
2. **架构分层**:控制平面负责决策,工作节点负责执行,etcd 存储状态
|
||||
3. **核心资源**:Pod(最小单元)、Deployment(副本管理)、Service(服务发现)、Ingress(外部入口)
|
||||
4. **运维自动化**:滚动更新零停机、HPA 弹性伸缩、探针自动故障恢复
|
||||
5. **配置分离**:ConfigMap 和 Secret 让配置与镜像解耦
|
||||
|
||||
## 延伸阅读
|
||||
|
||||
- [Kubernetes 官方文档](https://kubernetes.io/zh-cn/docs/) - 最权威的中文参考
|
||||
- [Kubernetes the Hard Way](https://github.com/kelseyhightower/kubernetes-the-hard-way) - 从零手动搭建 K8s 集群
|
||||
- [The Illustrated Children's Guide to Kubernetes](https://www.cncf.io/phippy/) - CNCF 出品的趣味入门
|
||||
- [Kubernetes Patterns](https://www.oreilly.com/library/view/kubernetes-patterns-2nd/9781098131678/) - K8s 设计模式
|
||||
|
||||
@@ -1,3 +1,397 @@
|
||||
# Linux 基础
|
||||
|
||||
> 待实现
|
||||
::: tip 前言
|
||||
**服务器的世界,Linux 是绝对的主角。** 全球超过 90% 的服务器运行 Linux,从你每天用的微信到 Google 搜索,背后都是 Linux 在支撑。作为开发者,掌握 Linux 基础不是可选项,而是必修课。
|
||||
:::
|
||||
|
||||
**这篇文章会带你学什么?**
|
||||
|
||||
学完这章后,你将获得:
|
||||
|
||||
- **文件系统**:理解 Linux 目录结构和"一切皆文件"的哲学
|
||||
- **常用命令**:掌握文件操作、文本处理、进程管理等核心命令
|
||||
- **权限模型**:理解用户、组、权限的概念
|
||||
- **Shell 基础**:了解管道、重定向、环境变量等 Shell 核心概念
|
||||
- **实战技能**:学会日志查看、进程排查、网络诊断等运维基本功
|
||||
|
||||
| 章节 | 内容 | 核心概念 |
|
||||
|-----|------|---------|
|
||||
| **第 1 章** | 文件系统 | 目录结构、一切皆文件 |
|
||||
| **第 2 章** | 常用命令 | 文件、文本、进程、网络 |
|
||||
| **第 3 章** | 权限模型 | 用户、组、rwx、sudo |
|
||||
| **第 4 章** | Shell 基础 | 管道、重定向、变量、脚本 |
|
||||
| **第 5 章** | 实战场景 | 日志排查、性能诊断 |
|
||||
|
||||
---
|
||||
|
||||
## 1. 文件系统:一切皆文件
|
||||
|
||||
Linux 最核心的哲学之一就是**一切皆文件**。普通文件是文件,目录是文件,硬盘是文件,甚至网络连接、进程信息都是文件。这个统一的抽象让你可以用同一套工具(读、写、权限控制)操作几乎所有系统资源。
|
||||
|
||||
<LinuxFileSystemDemo />
|
||||
|
||||
### 目录结构速记
|
||||
|
||||
把 Linux 文件系统想象成一棵倒过来的树:
|
||||
|
||||
```
|
||||
/ ← 根目录(树根)
|
||||
├── home/ ← 用户的家(你的文件都在这)
|
||||
├── etc/ ← 配置文件(系统的"设置面板")
|
||||
├── var/ ← 变化的数据(日志、缓存)
|
||||
├── usr/ ← 用户安装的程序
|
||||
├── tmp/ ← 临时文件(重启就没了)
|
||||
├── proc/ ← 进程信息(虚拟的,不占磁盘)
|
||||
├── dev/ ← 设备文件(硬盘、终端)
|
||||
├── bin/ ← 基础命令(ls、cp、mv)
|
||||
├── sbin/ ← 系统管理命令(需要 root)
|
||||
├── opt/ ← 第三方软件
|
||||
└── root/ ← root 用户的家目录
|
||||
```
|
||||
|
||||
### 路径的两种写法
|
||||
|
||||
| 类型 | 格式 | 示例 | 说明 |
|
||||
|------|------|------|------|
|
||||
| 绝对路径 | 从 `/` 开始 | `/home/alice/code/app.js` | 从根目录出发,不会歧义 |
|
||||
| 相对路径 | 从当前目录开始 | `./code/app.js` 或 `../config` | `.` 是当前目录,`..` 是上级目录 |
|
||||
|
||||
::: tip "一切皆文件"的威力
|
||||
想知道 CPU 信息?读文件:`cat /proc/cpuinfo`
|
||||
想知道内存使用?读文件:`cat /proc/meminfo`
|
||||
想产生随机数?读文件:`cat /dev/urandom`
|
||||
想丢弃输出?写文件:`echo "no thanks" > /dev/null`
|
||||
|
||||
不需要专门的 API,读写文件就够了。这就是 Unix 哲学的优雅之处。
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
## 2. 常用命令
|
||||
|
||||
Linux 命令遵循一个统一的格式:`命令 [选项] [参数]`。比如 `ls -la /home` 中,`ls` 是命令,`-la` 是选项,`/home` 是参数。
|
||||
|
||||
<LinuxCommandDemo />
|
||||
|
||||
### 最常用的 10 个命令
|
||||
|
||||
如果只能记住 10 个命令,记这些:
|
||||
|
||||
| 命令 | 用途 | 记忆技巧 |
|
||||
|------|------|----------|
|
||||
| `ls` | 列出文件 | list |
|
||||
| `cd` | 切换目录 | change directory |
|
||||
| `cat` | 查看文件 | concatenate |
|
||||
| `grep` | 搜索文本 | global regular expression print |
|
||||
| `find` | 查找文件 | 就是 find |
|
||||
| `ps` | 查看进程 | process status |
|
||||
| `tail -f` | 实时看日志 | 看文件"尾巴",-f 是 follow |
|
||||
| `chmod` | 改权限 | change mode |
|
||||
| `curl` | 发 HTTP 请求 | client URL |
|
||||
| `ssh` | 远程登录 | secure shell |
|
||||
|
||||
### 命令组合的艺术
|
||||
|
||||
Linux 的强大不在于单个命令,而在于**命令组合**。通过管道 `|` 把多个简单命令串起来,解决复杂问题:
|
||||
|
||||
```bash
|
||||
# 找出占用 CPU 最多的 5 个进程
|
||||
ps aux --sort=-%cpu | head -6
|
||||
|
||||
# 统计日志中出现最多的错误类型
|
||||
grep "ERROR" app.log | awk '{print $4}' | sort | uniq -c | sort -rn | head -10
|
||||
|
||||
# 查找大于 100MB 的文件
|
||||
find / -size +100M -type f 2>/dev/null
|
||||
|
||||
# 实时监控日志中的错误
|
||||
tail -f /var/log/app.log | grep --color "ERROR"
|
||||
```
|
||||
|
||||
::: tip Unix 哲学
|
||||
"做一件事,做好它。" 每个命令只负责一个功能,通过管道组合实现复杂操作。这就是为什么 Linux 命令都很短小——它们是积木,不是瑞士军刀。
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
## 3. 权限模型
|
||||
|
||||
Linux 是多用户系统,权限模型是安全的基石。每个文件都有三组权限,分别控制**所有者(Owner)**、**所属组(Group)**、**其他人(Others)**能做什么。
|
||||
|
||||
### 读懂 `ls -l` 的输出
|
||||
|
||||
```bash
|
||||
$ ls -l app.js
|
||||
-rwxr-xr-- 1 alice developers 2048 Jan 15 10:30 app.js
|
||||
│├──┤├──┤├──┤ │ │ │
|
||||
│ │ │ │ │ │ └── 文件大小
|
||||
│ │ │ │ │ └── 所属组
|
||||
│ │ │ │ └── 所有者
|
||||
│ │ │ └── 其他人权限:r-- (只读)
|
||||
│ │ └── 组权限:r-x (读+执行)
|
||||
│ └── 所有者权限:rwx (读+写+执行)
|
||||
└── 文件类型:- 普通文件,d 目录,l 链接
|
||||
```
|
||||
|
||||
### 权限的三种操作
|
||||
|
||||
| 权限 | 字母 | 数字 | 对文件的含义 | 对目录的含义 |
|
||||
|------|------|------|-------------|-------------|
|
||||
| 读 | `r` | 4 | 查看文件内容 | 列出目录内容(ls) |
|
||||
| 写 | `w` | 2 | 修改文件内容 | 创建/删除目录中的文件 |
|
||||
| 执行 | `x` | 1 | 运行程序/脚本 | 进入目录(cd) |
|
||||
|
||||
<LinuxPermissionsDemo />
|
||||
|
||||
### 数字权限速算
|
||||
|
||||
三个数字分别代表 Owner、Group、Others 的权限,每个数字是 r(4) + w(2) + x(1) 的和:
|
||||
|
||||
```
|
||||
chmod 755 script.sh
|
||||
7 = rwx (4+2+1) → 所有者:读+写+执行
|
||||
5 = r-x (4+0+1) → 组:读+执行
|
||||
5 = r-x (4+0+1) → 其他人:读+执行
|
||||
```
|
||||
|
||||
| 常见权限 | 含义 | 典型用途 |
|
||||
|---------|------|---------|
|
||||
| `644` | rw-r--r-- | 普通文件(所有者可写,其他人只读) |
|
||||
| `755` | rwxr-xr-x | 可执行文件/目录 |
|
||||
| `600` | rw------- | 私密文件(如 SSH 密钥) |
|
||||
| `777` | rwxrwxrwx | 所有人可读写执行(危险,避免使用) |
|
||||
|
||||
### sudo:临时获取超级权限
|
||||
|
||||
普通用户权限有限,有些操作需要 root 权限。`sudo` 让你临时以 root 身份执行命令:
|
||||
|
||||
```bash
|
||||
# 普通用户无法修改系统配置
|
||||
$ vim /etc/nginx/nginx.conf
|
||||
# Permission denied
|
||||
|
||||
# 用 sudo 临时提权
|
||||
$ sudo vim /etc/nginx/nginx.conf
|
||||
# 输入你的密码后可以编辑
|
||||
|
||||
# 切换到 root 用户(谨慎使用)
|
||||
$ sudo su -
|
||||
```
|
||||
|
||||
::: warning 最小权限原则
|
||||
永远不要用 `chmod 777` 解决权限问题,这等于把门锁拆了。正确做法是搞清楚谁需要什么权限,精确授予。同样,不要长期以 root 身份操作,只在必要时用 `sudo`。
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
## 4. Shell 基础
|
||||
|
||||
Shell 是你和 Linux 内核之间的"翻译官"。你输入命令,Shell 解释并交给内核执行。最常用的 Shell 是 **Bash**(大多数 Linux 发行版默认)和 **Zsh**(macOS 默认)。
|
||||
|
||||
### 管道与重定向
|
||||
|
||||
这是 Shell 最强大的两个特性:
|
||||
|
||||
| 符号 | 名称 | 作用 | 示例 |
|
||||
|------|------|------|------|
|
||||
| `|` | 管道 | 把前一个命令的输出作为后一个的输入 | `cat log | grep ERROR` |
|
||||
| `>` | 输出重定向 | 把输出写入文件(覆盖) | `echo "hello" > file.txt` |
|
||||
| `>>` | 追加重定向 | 把输出追加到文件末尾 | `echo "world" >> file.txt` |
|
||||
| `<` | 输入重定向 | 从文件读取输入 | `wc -l < file.txt` |
|
||||
| `2>` | 错误重定向 | 把错误信息写入文件 | `cmd 2> error.log` |
|
||||
| `2>&1` | 合并输出 | 把错误和正常输出合并 | `cmd > all.log 2>&1` |
|
||||
|
||||
### 环境变量
|
||||
|
||||
环境变量是 Shell 中的"全局配置",影响命令的行为:
|
||||
|
||||
```bash
|
||||
# 查看所有环境变量
|
||||
env
|
||||
|
||||
# 查看某个变量
|
||||
echo $PATH
|
||||
echo $HOME
|
||||
|
||||
# 临时设置(只在当前 Shell 有效)
|
||||
export API_KEY="abc123"
|
||||
|
||||
# 永久设置(写入配置文件)
|
||||
echo 'export API_KEY="abc123"' >> ~/.bashrc
|
||||
source ~/.bashrc # 让配置立即生效
|
||||
```
|
||||
|
||||
| 常见变量 | 含义 | 示例值 |
|
||||
|---------|------|--------|
|
||||
| `$PATH` | 命令搜索路径 | `/usr/local/bin:/usr/bin:/bin` |
|
||||
| `$HOME` | 用户主目录 | `/home/alice` |
|
||||
| `$USER` | 当前用户名 | `alice` |
|
||||
| `$PWD` | 当前工作目录 | `/var/log` |
|
||||
| `$SHELL` | 当前使用的 Shell | `/bin/bash` |
|
||||
|
||||
### Shell 脚本入门
|
||||
|
||||
把多个命令写进一个文件,就是 Shell 脚本。它是自动化运维的起点:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# deploy.sh - 简单的部署脚本
|
||||
|
||||
APP_DIR="/opt/myapp"
|
||||
LOG_FILE="/var/log/deploy.log"
|
||||
|
||||
echo "$(date) - 开始部署..." >> $LOG_FILE
|
||||
|
||||
# 拉取最新代码
|
||||
cd $APP_DIR && git pull origin main
|
||||
|
||||
# 安装依赖
|
||||
npm install --production
|
||||
|
||||
# 重启服务
|
||||
pm2 restart myapp
|
||||
|
||||
echo "$(date) - 部署完成" >> $LOG_FILE
|
||||
```
|
||||
|
||||
```bash
|
||||
# 给脚本执行权限并运行
|
||||
chmod +x deploy.sh
|
||||
./deploy.sh
|
||||
```
|
||||
|
||||
::: tip 脚本调试技巧
|
||||
在脚本开头加 `set -ex`:`-e` 让脚本遇到错误立即退出(而不是继续执行),`-x` 会打印每条执行的命令(方便排查问题)。这两个选项在生产脚本中几乎是标配。
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
## 5. 实战场景
|
||||
|
||||
理论学完了,来看几个开发中最常遇到的实战场景。
|
||||
|
||||
### 5.1 日志排查
|
||||
|
||||
服务出问题,第一反应就是看日志。以下是日志排查的常用套路:
|
||||
|
||||
```bash
|
||||
# 1. 实时跟踪日志(最常用)
|
||||
tail -f /var/log/app/error.log
|
||||
|
||||
# 2. 搜索特定时间段的错误
|
||||
grep "2024-01-15 14:" error.log | grep "ERROR"
|
||||
|
||||
# 3. 统计每小时的错误数量
|
||||
grep "ERROR" app.log | awk '{print substr($1,1,13)}' | uniq -c
|
||||
|
||||
# 4. 查看最近 100 行日志
|
||||
tail -100 app.log
|
||||
|
||||
# 5. 在多个日志文件中搜索
|
||||
grep -r "OutOfMemory" /var/log/app/
|
||||
```
|
||||
|
||||
### 5.2 进程排查
|
||||
|
||||
应用卡死、CPU 飙高、内存泄漏——这些问题都需要从进程入手:
|
||||
|
||||
```bash
|
||||
# 查看 CPU 占用最高的进程
|
||||
ps aux --sort=-%cpu | head -10
|
||||
|
||||
# 查看内存占用最高的进程
|
||||
ps aux --sort=-%mem | head -10
|
||||
|
||||
# 查找特定进程
|
||||
ps aux | grep "node"
|
||||
|
||||
# 查看进程的详细信息(包括线程)
|
||||
top -Hp <PID>
|
||||
|
||||
# 查看进程打开的文件
|
||||
lsof -p <PID>
|
||||
|
||||
# 优雅终止进程(SIGTERM)
|
||||
kill <PID>
|
||||
|
||||
# 强制终止(SIGKILL,最后手段)
|
||||
kill -9 <PID>
|
||||
```
|
||||
|
||||
### 5.3 网络诊断
|
||||
|
||||
服务连不上?先搞清楚是网络问题还是应用问题:
|
||||
|
||||
```bash
|
||||
# 测试目标是否可达
|
||||
ping -c 4 google.com
|
||||
|
||||
# 检查端口是否开放
|
||||
telnet db-server 3306
|
||||
# 或者用 nc
|
||||
nc -zv db-server 3306
|
||||
|
||||
# 查看本机监听的端口
|
||||
ss -tlnp
|
||||
# 或
|
||||
netstat -tlnp
|
||||
|
||||
# DNS 解析检查
|
||||
dig api.example.com
|
||||
nslookup api.example.com
|
||||
|
||||
# 测试 HTTP 接口
|
||||
curl -v http://localhost:3000/health
|
||||
|
||||
# 查看网络连接状态统计
|
||||
ss -s
|
||||
```
|
||||
|
||||
### 5.4 磁盘空间排查
|
||||
|
||||
磁盘满了是线上最常见的故障之一:
|
||||
|
||||
```bash
|
||||
# 查看各分区使用情况
|
||||
df -h
|
||||
|
||||
# 找出占用空间最大的目录
|
||||
du -sh /* 2>/dev/null | sort -rh | head -10
|
||||
|
||||
# 进一步定位大目录
|
||||
du -sh /var/log/* | sort -rh | head -10
|
||||
|
||||
# 查找大文件(>100MB)
|
||||
find / -type f -size +100M 2>/dev/null | head -20
|
||||
|
||||
# 清理常见的空间占用
|
||||
# 清理旧日志
|
||||
sudo journalctl --vacuum-size=500M
|
||||
# 清理 Docker 无用镜像
|
||||
docker system prune -a
|
||||
```
|
||||
|
||||
::: tip 线上排查口诀
|
||||
**"一看日志,二看进程,三看网络,四看磁盘"**。90% 的线上问题都能通过这四步定位到原因。养成习惯后,排查效率会大幅提升。
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
## 总结
|
||||
|
||||
Linux 是开发者的必备技能,掌握基础就能应对大部分日常开发和运维场景。
|
||||
|
||||
回顾本章的关键要点:
|
||||
|
||||
1. **一切皆文件**:Linux 用文件抽象统一了对硬件、进程、网络等资源的访问方式
|
||||
2. **命令组合**:单个命令功能简单,通过管道 `|` 组合才能发挥真正威力
|
||||
3. **权限模型**:Owner/Group/Others × Read/Write/Execute,用数字(如 755)快速设置
|
||||
4. **Shell 基础**:管道、重定向、环境变量、脚本是自动化的基石
|
||||
5. **实战排查**:日志 → 进程 → 网络 → 磁盘,四步定位大部分线上问题
|
||||
|
||||
## 延伸阅读
|
||||
|
||||
- [Linux 命令大全](https://man7.org/linux/man-pages/) - Linux man pages 官方文档
|
||||
- [The Linux Command Line](https://linuxcommand.org/tlcl.php) - 免费的 Linux 命令行入门书
|
||||
- [Linux Journey](https://linuxjourney.com/) - 交互式 Linux 学习网站
|
||||
- [explainshell.com](https://explainshell.com/) - 输入命令自动解释每个参数的含义
|
||||
|
||||
Reference in New Issue
Block a user