本文导读很多 Java 开发者登上 Linux 服务器后面对满屏的/etc、/var、/opt、/usr完全不知所措。本文是系列第 2 篇带你彻底搞清楚 Linux 目录结构的设计逻辑并建立一套 Java SaaS 项目的标准化部署目录规范同时讲解 AI 大模型文件的存放最佳实践。一、“一切皆文件”——理解 Linux 的核心哲学在 Windows 里硬件设备、网络连接、系统配置分散在设备管理器、注册表、控制面板等不同的地方。而在 Linux 里有一个非常优雅的设计哲学一切皆文件Everything is a file。这句话不是比喻是字面意思你的硬盘是文件/dev/sda你插入的 U 盘是文件/dev/sdb你的网卡是文件/dev/eth0系统的 CPU 信息是文件/proc/cpuinfo进程之间通信用的管道是文件鼠标键盘等输入设备是文件这意味着什么意味着操作系统里几乎所有东西都可以用读写文件的方式来操作。你可以用cat /proc/meminfo读取内存信息用echo 1 /proc/sys/net/ipv4/ip_forward开启内核路由转发用cat /dev/urandom生成随机数据。这种一致性让 Linux 的工具链极其强大——任何能读写文件的工具都能和系统的任何部分交互。Linux 的文件类型实际上有 7 种类型标识类型名称示例说明-普通文件/etc/hosts文本、二进制、图片等d目录文件/var/log/本质也是文件存储文件名列表l符号链接/usr/bin/python3 - python3.10类似 Windows 快捷方式c字符设备/dev/tty按字符流读写的设备键盘、串口b块设备/dev/sda按块读写的设备硬盘、U盘p命名管道/tmp/test.fifo进程间通信sSocket 文件/var/run/docker.sock网络/本地进程通信用ls -l命令可以看到文件类型标识第一个字符# 查看文件类型第一列第一个字符就是类型标识ls-la/dev/|head-20# 输出示例节选# brw-rw---- 1 root disk 8, 0 Jun 20 10:00 sda ← b 是块设备硬盘# crw-rw-rw- 1 root tty 5, 0 Jun 20 10:00 tty ← c 是字符设备# lrwxrwxrwx 1 root root 4 Jun 20 10:00 rtc - rtc0 ← l 是符号链接# 查看 docker.sock 类型很多 Java 项目会挂载它ls-la/var/run/docker.sock# srw-rw---- 1 root docker 0 Jun 20 10:00 /var/run/docker.sock# 第一个字符 s 表示这是一个 Socket 文件 生产提示理解/var/run/docker.sock是 Socket 文件非常重要。当你的 Spring Boot 应用需要在容器内调用 Docker API比如动态创建容器需要把这个 socket 文件挂载到容器内。如果你不懂一切皆文件的概念就不会理解为什么一个.sock后缀的东西是Docker 的接口。二、Linux 目录树全景图每个目录的职责Linux 遵循FHSFilesystem Hierarchy Standard文件系统层次结构标准来组织目录结构。这是一个国际标准规定了各目录的用途所有主流发行版都遵循它。/根目录 ├── bin/ → 所有用户可用的基础命令ls、cp、mv、cat 等 ├── sbin/ → 系统管理命令reboot、fdisk、iptables 等通常需要 root ├── etc/ → 系统和软件的配置文件最重要的目录之一 ├── var/ → 可变数据日志、缓存、数据库文件等会变化的内容 ├── tmp/ → 临时文件重启后清空不要在这里放重要数据 ├── home/ → 普通用户的主目录/home/ubuntu、/home/dengkui 等 ├── root/ → root 用户的主目录注意不在 /home/ 下 ├── opt/ → 可选的第三方软件手动安装的大型软件包 ├── usr/ → 用户程序和文件最大的目录包含大量子目录 │ ├── bin/ → 用户命令非系统启动必须的 │ ├── lib/ → 程序依赖的库文件.so 动态链接库 │ ├── local/ → 本地安装的软件编译安装的软件默认在这里 │ └── share/ → 共享文件文档、图标、man 手册等 ├── lib/ → 系统启动必需的库文件内核模块也在这里 ├── boot/ → 启动加载器和内核文件grub、vmlinuz、initrd ├── dev/ → 设备文件硬盘、终端、随机数生成器等 ├── proc/ → 虚拟文件系统反映内核和进程状态不占磁盘空间 ├── sys/ → 虚拟文件系统内核和硬件信息比 /proc 更结构化 ├── mnt/ → 临时挂载点手动mount磁盘时常用 ├── media/ → 可移动设备自动挂载点U盘、光盘 ├── run/ → 运行时数据PID 文件、Socket 文件重启后清空 └── srv/ → 服务数据FTP、HTTP 的数据不太常用⚠️ 踩坑记录很多初学者搞不清/bin和/usr/bin的区别。历史上/bin存放系统启动时就需要的命令在/usr分区还没挂载时就能用/usr/bin存放系统正常运行后才需要的命令。在现代的 Ubuntu 22.04 上/bin已经是/usr/bin的符号链接两者是同一个目录这个区别已经消失了。但你在看老教程时会看到这个区分知道历史背景就不会困惑。三、重点目录深度解析3.1 /etc配置文件的家/etc是et cetera等等、其他的缩写历史上存放各种杂项配置现在是所有系统级配置文件的标准存放地。# 查看 /etc 下最常用的配置文件ls/etc/|grep-E^(host|resolv|passwd|fstab|ssh|apt|nginx|mysql)# 一些关键配置文件的作用cat/etc/hosts# 本地 DNS 解析IP 到域名的映射cat/etc/resolv.conf# DNS 服务器配置向哪里查询域名cat/etc/passwd# 用户账户信息不含密码密码在 /etc/shadowcat/etc/fstab# 磁盘挂载配置开机自动挂载的规则cat/etc/hostname# 当前主机名# 查看 SSH 服务配置cat/etc/ssh/sshd_config|grep-v^#|grep-v^$对 Java SaaS 开发者来说/etc里最常接触的是/etc/nginx/→ Nginx 配置目录/etc/mysql/→ MySQL 配置目录/etc/redis/→ Redis 配置目录/etc/systemd/system/→ 自定义 systemd 服务文件⚠️ 踩坑记录/etc/hosts文件是一个经常被忽视的排查入口。很多微服务环境中服务之间通过域名互相调用如果 DNS 解析出问题可以临时在/etc/hosts里加一行IP 域名来绕过先让业务恢复再排查 DNS 根因。另外Docker 容器启动时有自己的/etc/hosts容器内的域名解析和宿主机是隔离的不要混淆。3.2 /var变化的数据var是 “variable” 的缩写存放运行中会不断变化的数据。# 查看 /var 的主要子目录ls-lh/var/# 关键子目录说明ls-lh/var/log/# 日志文件系统日志、应用日志都在这里ls-lh/var/lib/# 应用的持久化数据MySQL数据文件、Docker数据等ls-lh/var/cache/# 缓存文件apt 的包缓存ls-lh/var/run/# 同 /runPID 文件、Socket 文件# 查看系统日志最近 50 行tail-50/var/log/syslog# Ubuntu 系统日志tail-50/var/log/auth.log# 认证日志SSH 登录记录# 查看 MySQL 数据文件位置ls-lh/var/lib/mysql/# 查看 Docker 数据目录大小容器、镜像都在这里du-sh/var/lib/docker/⚠️ 踩坑记录/var/log是生产故障排查的第一现场但也是最常见的磁盘打满元凶。Java 应用如果没有配置 logrotate日志轮转日志文件会无限增长最终把磁盘撑满导致数据库无法写入、应用崩溃。用df -h发现磁盘快满时先用du -sh /var/log/*找出哪个日志文件最大。后续第 13 篇会专门讲日志管理。3.3 /opt第三方软件的标准位置opt是 “optional” 的缩写专门用来存放手动安装的第三方大型软件。包管理器安装的软件apt/dnf会分散在/usr/下而你手动下载的 JDK、Elasticsearch、Kafka 等放在/opt是标准做法。# 查看 /opt 下通常有哪些内容一台配置好的服务器ls-la/opt/# 典型的 /opt 目录结构示例# /opt/jdk/ → JDK 安装目录# /opt/elasticsearch/ → Elasticsearch# /opt/kafka/ → Kafka# /opt/node/ → Node.js# /opt/ollama/ → Ollama 大模型工具3.4 /proc 和 /sys内核的实时仪表盘这两个目录很特殊——它们不是真实的磁盘目录而是内核动态生成的虚拟文件系统占用零磁盘空间实时反映系统状态。# 查看 CPU 信息实时从内核读取cat/proc/cpuinfo|grepmodel name|head-1# 查看内存详情比 free 命令更详细cat/proc/meminfo|head-20# 查看系统运行时间单位秒cat/proc/uptime# 查看某个进程的详情以 PID 1234 为例ls/proc/1234/# 每个进程都在 /proc 下有自己的目录cat/proc/1234/cmdline# 进程启动时的完整命令行cat/proc/1234/status# 进程状态、内存使用等# 查看系统 TCP 连接数对排查 Java 应用连接池泄漏很有用cat/proc/net/tcp|wc-l# 通过 /sys 调整内核参数临时生效重启恢复cat/sys/block/sda/queue/scheduler# 查看磁盘 IO 调度策略 生产提示当 Java 应用出现Too many open files错误可以通过/proc/进程PID/limits查看该进程的文件描述符限制通过/proc/进程PID/fd目录的文件数量来确认当前打开了多少文件。这比用其他工具排查快得多。四、绝对路径 vs 相对路径新手必须搞清楚的区别这是最基础也最容易让新手犯错的概念。绝对路径从根目录/开始的完整路径无论你当前在哪个目录它都指向同一个位置。相对路径相对于当前目录的路径会随着你所在的位置变化而变化。# 查看当前所在目录pwd print working directorypwd# 输出/home/ubuntu# 用绝对路径访问文件从 / 开始永远有效cat/etc/hosts# 用相对路径访问文件相对于当前目录# 假设当前在 /home/ubuntucat../../etc/hosts# ../../ 表示向上两级到 /再进 etc/# 几个特殊的相对路径符号cd~# 回到当前用户的主目录~ 是主目录的简写cd..# 进入上一级目录cd-# 回到上一次所在的目录在两个目录间快速切换非常好用cd.# 当前目录. 表示当前目录.. 表示父目录⚠️ 踩坑记录Shell 脚本里用相对路径是很危险的习惯。脚本的当前目录取决于从哪里调用它在不同位置执行结果可能完全不同。在脚本里一定要用绝对路径或者在脚本开头用cd $(dirname $0)把当前目录切换到脚本所在目录。否则 cron 定时任务执行你的脚本时当前目录是 root 的主目录而不是脚本目录所有相对路径都会失效。五、Java SaaS 项目标准化部署目录规范这是本篇最有实战价值的部分。很多项目因为没有统一的目录规范导致部署混乱、日志难找、备份困难。以下是一套经过生产验证的 Java SaaS 项目目录规范# 建议的标准目录结构/opt/ └── appname/# 应用根目录appname 替换为实际项目名├── current/# 当前运行版本的 JAR 包符号链接或实际文件│ └── app.jar# Spring Boot 打包后的可执行 JAR├── releases/# 历史版本存档蓝绿部署时保留上一个版本│ ├── app-1.0.0.jar │ └── app-1.0.1.jar ├── config/# 外部化配置文件不打入 JAR 包│ ├── application-prod.yml │ └── application-local.yml ├── logs/# 应用日志建议软链到 /var/log/appname/├── temp/# 临时文件文件上传中转└── scripts/# 运维脚本启动、停止、健康检查├── start.sh ├── stop.sh └── health-check.sh /var/log/appname/# 日志文件系统日志规范目录├── app.log# 应用主日志├── error.log# 错误日志└── access.log# 访问日志/var/lib/appname/# 应用持久化数据如本地文件存储用以下命令一键创建这套目录结构# 替换 myapp 为你的实际项目名APP_NAMEmyapp# 创建应用目录结构sudomkdir-p/opt/${APP_NAME}/{current,releases,config,logs,temp,scripts}sudomkdir-p/var/log/${APP_NAME}sudomkdir-p/var/lib/${APP_NAME}# 创建专用运行用户不要用 root 运行 Java 应用sudouseradd-r-s/sbin/nologin-d/opt/${APP_NAME}${APP_NAME}# 设置目录所有权应用目录归专用用户日志目录同样sudochown-R${APP_NAME}:${APP_NAME}/opt/${APP_NAME}sudochown-R${APP_NAME}:${APP_NAME}/var/log/${APP_NAME}sudochown-R${APP_NAME}:${APP_NAME}/var/lib/${APP_NAME}# 验证目录创建结果tree /opt/${APP_NAME}/⚠️ 踩坑记录很多开发者图省事直接用 root 用户跑 Spring Boot 应用这在安全上是非常危险的。一旦应用有安全漏洞被攻击者利用攻击者就直接获得了 root 权限可以对服务器为所欲为。正确做法是创建一个专用的低权限用户上面的useradd -r创建的是系统用户没有 shell 登录权限权限最小化让应用以这个用户身份运行。Spring Boot 的 systemd 服务文件里用Usermyapp指定运行用户后续第 08 篇会详细讲。六、AI 大模型文件的存放最佳实践在 Linux 上部署 Ollama 或 vLLM 时模型文件.gguf、.safetensors格式动辄几 GB 到几十 GB存放位置需要认真规划# Ollama 默认模型存放路径可自定义# 默认~/.ollama/models/ 如果用 root 跑在 /root/.ollama/# 生产环境建议独立挂载大容量磁盘到 /data 目录# 查看 Ollama 当前模型存储位置ls-lh~/.ollama/models/blobs/# 实际的模型文件按哈希存储ls-lh~/.ollama/models/manifests/# 模型元数据# 推荐的生产环境 AI 模型目录结构/data/# 独立大容量磁盘挂载点├── models/# 模型文件根目录│ ├── ollama/# Ollama 模型通过软链或环境变量指向│ ├── huggingface/# HuggingFace 格式模型用于 vLLM│ │ ├── Qwen2.5-7B-Instruct/ │ │ └── DeepSeek-R1-8B/ │ └── gguf/# llama.cpp 使用的 GGUF 格式│ └── qwen2.5-7b-instruct.Q4_K_M.gguf# 通过环境变量修改 Ollama 模型存储路径exportOLLAMA_MODELS/data/models/ollama# 永久生效写入 /etc/environment 或 systemd 服务文件echoOLLAMA_MODELS/data/models/ollama|sudotee-a/etc/environment⚠️ 踩坑记录模型文件绝对不能放在系统盘根分区/下。7B 参数量的模型文件大约 4-15 GB取决于量化级别70B 模型动辄 40-80 GB。如果不独立规划存储很快就会把系统盘撑满轻则应用崩溃重则系统无法启动根分区满了连登录都很困难。生产环境应该单独挂载一块大容量数据盘到/data专门用于存储模型文件和向量数据库数据。七、实用命令速查目录与文件操作# 目录导航 pwd# 显示当前路径cd/var/log# 进入指定目录cd~# 回主目录cd-# 回上次所在目录ls-la# 列出所有文件含隐藏文件详情ls-lhS# 按文件大小排序-S人性化单位-htree-L2/opt# 显示 /opt 目录树最多展开 2 层# 磁盘空间检查 df-h# 查看各分区使用率df-h/opt# 只查某个目录所在分区du-sh/var/log/*# 查看 /var/log 下每个文件/目录的大小du-sh/*2/dev/null# 查看根目录各一级子目录的大小排查磁盘占用# 文件类型查看 file/bin/ls# 查看文件类型会告诉你是 ELF 可执行文件还是脚本file/etc/hosts# 查看文本文件类型readlink-f/usr/bin/python3# 追踪符号链接的最终真实路径八、常见问题解答FAQQ1/usr和/opt都能放软件该选哪个规则是通过包管理器apt/dnf安装的软件放在/usr下自动管理不需要你操心手动下载解压安装的大型软件放在/opt下自己管理。比如用apt install nginx安装的 Nginx 在/usr/sbin/nginx但如果你从官网下载 Nginx 源码自己编译建议安装到/opt/nginx。Q2/tmp和/var/tmp有什么区别/tmp里的文件在系统重启后会被清空实际上是 tmpfs存在内存里/var/tmp里的文件重启后保留存在磁盘上但系统会定期清理超过 30 天未访问的文件。Java 应用的文件上传临时目录不要用/tmp除非你能保证上传在本次会话内完成。Q3/proc里的文件能删除吗不能也删不掉。/proc是内核动态生成的虚拟文件系统不占磁盘空间对里面文件的读写实际是与内核交互不存在真正意义上的删除操作。Q4日志为什么建议放在/var/log而不是应用目录下标准化的目录便于统一管理。运维团队通常会对/var/log配置 logrotate 统一轮转配置 ELK/Loki 统一采集配置监控告警磁盘使用率超 80% 报警。如果日志分散在各个应用目录这些统一管理就很难做。Q5/etc下的配置文件被误改了怎么恢复这正是建议你在修改任何配置文件前先备份原文件的原因sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak。备份了就可以随时恢复sudo cp /etc/nginx/nginx.conf.bak /etc/nginx/nginx.conf。如果系统层面有使用 Git 来管理/etc工具叫etckeeper可以用git diff和git checkout来查看和撤销修改。本篇小结与系列导航 核心结论Linux 目录结构遵循 FHS 标准核心规律是/etc放配置、/var放变化数据含日志、/opt放手动安装软件、/proc和/sys是内核的实时镜像。Java SaaS 项目应建立标准化目录规范应用运行在/opt/appname/日志输出到/var/log/appname/由专用低权限用户运行。AI 大模型文件因体积庞大应独立挂载数据盘存储避免占满系统盘。