Linux磁盘占用100%怎么排查,大文件查找清理方法
前言
服务器跑着跑着突然网站打不开了,SSH 也反应变慢,一查磁盘使用率 100%。这是运维中非常常见的问题。磁盘满了不仅影响服务正常运行,还可能导致数据丢失、日志写不进去等严重后果。本文就手把手教你怎么快速定位磁盘占用大的文件,以及怎么安全清理。
第一步:查看整体磁盘使用情况
先用 df 命令看看哪个分区满了:
df -h
参数说明:
-h:以人类可读的方式显示(G、M)
输出示例:
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 40G 38G 2.0G 95% /
devtmpfs 7.8G 0 7.8G 0% /dev
tmpfs 7.8G 0 7.8G 0% /dev/shm
tmpfs 7.8G 480M 7.8G 6% /run
tmpfs 7.8G 0 7.8G 0% /sys/fs/cgroup
看 Use% 那一列,如果哪个分区到了 100% 或者 90% 以上,那就是问题所在。比如上面 /dev/vda1 用了 95%,根分区快满了。
第二步:定位哪个目录占用最大
知道哪个分区满了,接下来找是哪个目录占了最多空间。用 du 命令:
1. 查看根目录下各目录的大小
du -sh /* 2>/dev/null
参数说明:
-s:只显示总计,不显示每个子目录-h:人类可读格式2>/dev/null:忽略权限不足的报错信息
输出示例:
0 /bin
100M /boot
...
15G /home
20G /var
3G /usr
从输出可以看出 /var 目录占了 20G,是大头。
2. 继续往下查 /var 目录
du -sh /var/* 2>/dev/null | sort -rh | head -10
参数说明:
sort -rh:按大小倒序排列head -10:只显示前10个最大的
输出示例:
15G /var/log
3G /var/lib
1G /var/cache
...
继续往下查,直到找到具体是哪个文件最大。
第三步:查找最大的单个文件
如果目录太大不好定位,直接找整个系统里最大的文件:
1. 查找大于100M的文件
find / -type f -size +100M -exec ls -lh {} \; 2>/dev/null | awk '{print $5, $9}'
参数说明:
-type f:只找文件,不找目录-size +100M:找大于100M的文件2>/dev/null:忽略权限报错
2. 按大小排序显示前20个最大文件
find / -type f -size +10M -exec ls -lh {} \; 2>/dev/null | sort -k5 -rh | head -20
这样就能列出系统里最大的20个文件,一目了然。
常见的磁盘占用大户
根据经验,Linux 磁盘占用大通常是这几个地方:
1. 日志文件(/var/log)
这是最常见的。服务跑久了日志文件会越来越大,尤其是:
- Nginx 访问日志、错误日志
- MySQL 慢查询日志、错误日志
- 系统日志 messages、syslog
排查方法:
du -sh /var/log/* | sort -rh | head -10
2. 已删除但仍被进程占用的文件
有时候你删掉了大文件,但磁盘空间没释放,因为还有进程在占用这个文件的句柄。
排查方法:
lsof | grep deleted
如果看到很多 deleted 状态的文件,说明有进程占用着已删除的文件。重启对应的进程就能释放空间。
3. 缓存文件(/var/cache)
yum 下载的缓存包、APT 的缓存都在这里,时间久了会积累很多。
清理方法:
yum clean all
4. Docker 镜像和容器
如果用了 Docker,镜像、容器、日志都会占很多空间。
排查方法:
docker system df
清理方法:
docker system prune -a
安全清理方法
找到大文件后,不要直接 rm -rf 删了就完事,要注意安全:
1. 日志文件:清空而不是删除
如果是日志文件,不要删文件本身,而是清空内容:
> /var/log/nginx/access.log
或者:
echo "" > /var/log/nginx/access.log
这样文件还在,但内容清空了,不会影响正在写入的进程。
2. 大文件:先确认再删除
删之前一定要确认这个文件是不是真的不需要了:
ls -lh /path/to/file
head -20 /path/to/file # 看看内容是什么
确认没问题再删:
rm -f /path/to/file
3. 已删除但被占用的文件
如果删掉文件后空间没释放,找到占用的进程并重启:
lsof | grep deleted
# 找到对应的 PID,重启服务
systemctl restart nginx
常见坑
坑1:用 du 查到的大小和 df 不一致
有时候 df 显示磁盘满了,但 du -sh /* 加起来远没到那个数。这通常是因为:
- 有已删除但仍被进程占用的文件
- 挂载点下还有其他挂载
解决: 用 lsof | grep deleted 找被占用的已删除文件,重启对应进程释放空间。
坑2:删了文件空间没释放
这就是上面说的坑——文件被进程占用着,虽然删了但空间没释放。必须重启进程才能释放。
坑3:直接删日志文件导致服务异常
很多人直接 rm -f /var/log/nginx/access.log,结果 Nginx 还在往这个已经不存在的文件里写,日志就丢了。正确做法是清空内容而不是删除文件:> /var/log/nginx/access.log。
总结
排查磁盘占用的标准流程:
df -h看哪个分区满了du -sh /* | sort -rh找最大的目录find / -type f -size +100M找最大的文件- 确认文件用途后再清理
- 日志文件清空内容,不要直接删文件
日常运维建议配置 logrotate 自动切割日志,避免日志越积越大。
遇到问题加QQ23979811 协助处理
CentOS7 关闭SELinux详细步骤,临时+永久关闭
前言
刚装完 CentOS7,部署网站的时候老是遇到各种权限问题:文件明明权限对了还是访问不了,端口也开了就是连不上。排查半天发现是 SELinux 在捣乱。SELinux 是 CentOS 自带的强制访问控制安全机制,安全性很高,但对新手来说确实不太友好。本文详细讲一下怎么临时和永久关闭 SELinux,以及关闭前需要知道的注意事项。
什么是 SELinux
SELinux(Security-Enhanced Linux)是 Linux 内核的一个安全模块,提供强制访问控制(MAC)机制。它比传统的自主访问控制(DAC)更严格,不仅看文件权限,还看进程和文件的安全上下文(SELinux 标签)。
CentOS7 默认开启 SELinux,这也是为什么很多新手部署完网站各种报错的原因——Nginx、PHP、MySQL 的进程和文件上下文不匹配,SELinux 直接拦截。
查看 SELinux 状态
在关闭之前,先看看 SELinux 当前是什么状态:
getenforce
输出可能是:
Enforcing:强制模式,SELinux 正在拦截违规操作Permissive:宽容模式,只记录警告不拦截Disabled:已关闭
也可以用这个命令看更详细的信息:
sestatus
输出示例:
SELinux status: enabled
SELinuxfs mount: /sys/fs/selinux
SELinux root directory: /etc/selinux
Loaded policy name: targeted
Current mode: enforcing
Mode from config file: enforcing
Policy MLS status: enabled
Policy deny_unknown status: allowed
临时关闭 SELinux(重启后失效)
如果你只是临时测试一下,不想改配置文件,可以用这个方法:
setenforce 0
setenforce 0 表示切换到 Permissive 宽容模式,SELinux 不会再拦截操作,但会在日志里记录。这个命令立即生效,不需要重启。
验证一下:
getenforce
应该输出 Permissive。
注意: 这种方式重启服务器后 SELinux 会重新开启,所以只是临时生效。
永久关闭 SELinux(重启后依然关闭)
要永久关闭,需要修改配置文件:
1. 编辑 SELinux 配置文件
vi /etc/selinux/config
2. 修改 SELINUX 的值
找到这一行:
SELINUX=enforcing
改成:
SELINUX=disabled
3. 保存退出,重启服务器
reboot
重启后再验证一下:
getenforce
应该输出 Disabled。
三种模式说明
SELinux 有三种模式,大家可以根据需求选择:
| 模式 | 说明 |
|---|---|
enforcing |
强制模式,SELinux 强制执行策略,违规操作直接拦截 |
permissive |
宽容模式,只记录警告日志,不拦截操作 |
disabled |
完全关闭 SELinux |
建议: 如果只是临时调试,可以用 permissive 模式,既能放行所有操作,又能通过日志看到哪些操作被 SELinux 拦截了。生产环境如果实在搞不懂 SELinux,再考虑完全关闭。
常见坑
坑1:改了配置文件没重启就以为关了
很多朋友改完 /etc/selinux/config 文件,马上用 getenforce 查看,发现还是 Enforcing,就以为没改成功。其实配置文件改了之后必须重启服务器才会生效。临时生效用 setenforce 0,永久生效必须重启。
坑2:改了 SELINUX=disabled 但还有问题
有时候即使把 SELinux 关了,之前设置的安全上下文标签还在,可能会导致一些奇怪的问题。如果遇到这种情况,可以重启服务器彻底解决。
坑3:生产环境直接关闭有安全风险
SELinux 是一道安全防线,生产环境直接完全关闭会降低系统安全性。建议先尝试把模式改成 permissive,看看日志里哪些操作被拦截了,再针对性地调整上下文标签,而不是直接全部关掉。
总结
CentOS7 关闭 SELinux 的两种方式:
临时关闭(立即生效,重启失效):
setenforce 0
永久关闭(重启后生效):
- 编辑
/etc/selinux/config - 把
SELINUX=enforcing改成SELINUX=disabled - 重启服务器
新手刚部署完服务器,先临时关了跑通业务,后面再慢慢研究 SELinux 的配置,别一上来就跟它死磕。
遇到问题加QQ23979811 协助处理
Linux查看服务器开放端口,netstat和ss命令使用教程
前言
部署完网站后,经常需要确认某个端口是否真的开放了,或者排查服务有没有正常监听。Linux 下最常用的两个工具就是 netstat 和 ss。netstat 是老经典,几乎所有系统都自带;ss 是 iproute2 套件里的新工具,性能更好、信息更全。本文把这两个命令的常用用法都整理出来,新手照着抄就行。
netstat 命令用法
1. 查看所有监听端口
netstat -tlnp
参数说明:
-t:只显示 TCP 连接-l:只显示监听状态的端口-n:以数字形式显示端口号,不做域名解析-p:显示占用端口的进程名和 PID
输出示例:
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1234/sshd
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 5678/nginx
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 5678/nginx
2. 查看 UDP 端口
netstat -ulnp
把 -t 换成 -u 就是查看 UDP 端口。
3. 查看所有端口(TCP+UDP)
netstat -tulnp
4. 查看指定端口是否被占用
netstat -tlnp | grep 80
如果 80 端口被占用,会输出对应的进程信息。
5. 查看所有网络连接(不只是监听)
netstat -an
-a 表示显示所有连接,不只是监听状态的。
ss 命令用法
ss 是 netstat 的替代品,在服务器上性能更好,尤其是连接数很多的时候。
1. 查看所有监听端口
ss -tlnp
参数和 netstat 基本一样:
-t:TCP-l:监听状态-n:数字形式-p:显示进程
2. 查看 UDP 端口
ss -ulnp
3. 查看所有端口(TCP+UDP)
ss -tulnp
4. 查看指定端口
ss -tlnp | grep 443
5. 查看所有已建立的连接
ss -tn state established
可以用来统计当前服务器有多少个活跃连接。
6. 查看某个IP的连接
ss -tn dst 192.168.1.100
查看和 192.168.1.100 之间的所有连接。
两个命令的区别
| 对比项 | netstat | ss |
|---|---|---|
| 性能 | 连接数多的时候很慢 | 非常快 |
| 来源 | net-tools 包 | iproute2 包 |
| 兼容性 | 几乎所有 Linux 都有 | 新系统默认自带 |
| 功能 | 基础网络查询 | 更丰富的过滤功能 |
建议: 日常排查用 ss 更高效,老系统上找不到 ss 再用 netstat。
常见坑
坑1:看不到进程信息
执行 netstat -tlnp 或 ss -tlnp 时,如果看不到 PID/Program name 那一列,说明你不是 root 用户。加上 sudo 再执行:
sudo netstat -tlnp
sudo ss -tlnp
坑2:端口显示是 :: 而不是 0.0.0.0
0.0.0.0:80 表示监听所有 IPv4 地址的 80 端口;:::80 表示监听所有 IPv6 地址的 80 端口(同时也兼容 IPv4)。这两种都能从外网访问,不用担心。
坑3:查不到端口但服务明明启动了
检查一下服务是不是只监听了 127.0.0.1。如果 Local Address 显示的是 127.0.0.1:80,那外网是访问不了的,只能本机访问。需要修改服务配置监听 0.0.0.0。
总结
查看 Linux 开放端口记住这几个核心命令就够了:
- 常用查看:
ss -tlnp或netstat -tlnp - 查指定端口:
ss -tlnp | grep 端口号 - 查UDP端口:
ss -ulnp
日常排查优先用 ss,速度快信息全;老系统没 ss 再用 netstat。
遇到问题加QQ23979811 协助处理
CentOS7 firewalld开放80、443端口永久生效命令
前言
刚装好 CentOS7 服务器,部署完 Nginx 网站后,外网却访问不了?十有八九是防火墙没放行端口。CentOS7 默认用 firewalld 代替了旧版的 iptables,很多刚接触的朋友不太熟悉操作。本文就详细讲解如何在 CentOS7 上永久开放 80、443 等常用端口,以及操作中容易踩的坑。
操作步骤
1. 检查 firewalld 运行状态
首先确认防火墙服务是否正在运行:
systemctl status firewalld
如果显示 active (running) 说明防火墙已启动。如果没启动,先启动它:
systemctl start firewalld
systemctl enable firewalld
2. 查看当前已开放的端口
firewall-cmd --list-ports
这个命令会列出当前防火墙放行的所有端口。
3. 永久开放 80 端口
firewall-cmd --permanent --add-port=80/tcp
参数说明:
--permanent:永久生效,不加这个参数重启防火墙后就失效--add-port=80/tcp:开放 80 端口,协议为 TCP
4. 永久开放 443 端口
firewall-cmd --permanent --add-port=443/tcp
5. 同时开放多个端口
如果需要一次性开放多个端口,可以这样写:
firewall-cmd --permanent --add-port=80/tcp --add-port=443/tcp --add-port=8080/tcp
6. 开放端口范围
如果要开放一整段端口,比如 3000 到 4000:
firewall-cmd --permanent --add-port=3000-4000/tcp
7. 重载防火墙使配置生效
修改完规则后,必须重载才能生效:
firewall-cmd --reload
8. 验证端口是否开放成功
firewall-cmd --list-ports
如果输出里能看到 80/tcp 443/tcp 就说明开放成功了。
9. 移除开放的端口(如果需要)
firewall-cmd --permanent --remove-port=8080/tcp
firewall-cmd --reload
常见坑
坑1:忘了加 --permanent 参数
很多朋友执行了 firewall-cmd --add-port=80/tcp,当时测试是通的,但重启服务器或者重启防火墙后就又不通了。原因就是没加 --permanent,这种方式只是临时生效,重启后规则丢失。
解决: 开放端口时一定要加 --permanent 参数,然后执行 firewall-cmd --reload 重载配置。
坑2:改完规则忘了 reload
执行完 --add-port 后,规则只是写入了配置文件,还没有真正生效。必须执行 firewall-cmd --reload 才能让新规则生效。
坑3:以为开放了端口就一定能访问
防火墙只是第一道关卡。如果网站还是访问不了,还要检查:
- Nginx/Apache 是否启动并监听了对应端口
- 安全组(云服务器)是否也放行了端口
- 服务器内部的应用是否正常运行
坑4:用了 iptables 命令却不生效
CentOS7 默认是 firewalld 管理防火墙,如果你用 iptables 命令添加规则,firewalld 重启后会把规则覆盖掉。要么用 firewalld 命令,要么先关掉 firewalld 再用 iptables。
总结
CentOS7 开放端口的核心命令就是三步:
firewall-cmd --permanent --add-port=端口号/tcp添加规则firewall-cmd --reload重载生效firewall-cmd --list-ports验证结果
记住 --permanent 和 --reload 这两个关键点,90% 的问题都能解决。
遇到问题加QQ23979811 协助处理
Nginx报502 Bad Gateway完整排查思路(PHP-FPM场景)
Nginx 出现 502 Bad Gateway 是最常见的报错之一,90% 的情况都是 PHP-FPM 出了问题。下面是完整的排查思路,按顺序一步步来,基本都能解决。
1. 先看 PHP-FPM 是否在运行
systemctl status php-fpm
如果显示 failed 或 inactive,直接重启:
systemctl restart php-fpm
注意:CentOS 7 一般是
php-fpm,Ubuntu 可能是php7.4-fpm之类的,看你装的版本。
2. 看 Nginx 错误日志(最关键)
tail -f /var/log/nginx/error.log
常见错误信息:
错误1:connect() failed (111: Connection refused) while connecting to upstream
说明 PHP-FPM 没启动,或者监听地址不对。
错误2:upstream timed out
PHP 脚本执行超时了,或者 PHP-FPM 进程不够用。
错误3:Primary script unknown
Nginx 配置里的 SCRIPT_FILENAME 路径不对,找不到 PHP 文件。
3. 检查 Nginx 配置是否正确
nginx -t
如果显示 test is successful 说明配置语法没问题。
重点检查 fastcgi_pass 这一行:
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000; # 或者 unix:/run/php-fpm/www.sock
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
常见问题:
- fastcgi_pass 地址和 PHP-FPM 实际监听地址不一致
- SCRIPT_FILENAME 路径写错了
4. 检查 PHP-FPM 监听地址
netstat -tlnp | grep php-fpm
或者:
ss -tlnp | grep php-fpm
看 PHP-FPM 是监听在 9000 端口还是 unix sock 文件,然后和 Nginx 配置里的 fastcgi_pass 对应上。
5. 检查 PHP-FPM 进程数是否够
看 PHP-FPM 配置:
vi /etc/php-fpm.d/www.conf
重点参数:
pm = dynamic
pm.max_children = 50
pm.start_servers = 20
pm.min_spare_servers = 10
pm.max_spare_servers = 30
如果访问量大,进程数不够就会 502。
6. 检查 PHP 错误日志
tail -f /var/log/php-fpm/www-error.log
有时候 PHP 代码本身报错,也会导致 502。
7. 其他常见原因
磁盘满了
df -h
内存不够
free -h
如果内存不足,PHP-FPM 进程会被杀掉,也会 502。
SELinux 没关
参考我之前的文章,关掉 SELinux 试试。
排查顺序总结
- 重启 PHP-FPM → 看能不能恢复
- 看 Nginx 错误日志 → 定位具体错误
- 检查 Nginx 配置 → fastcgi_pass 和 SCRIPT_FILENAME
- 检查 PHP-FPM 状态 → 监听地址、进程数
- 检查系统资源 → 磁盘、内存
- 检查 SELinux
遇到服务器、Nginx、MySQL 报错,可以加微信远程协助排查问题。
CentOS7 firewalld开放80、443端口永久生效命令
CentOS 7 默认使用 firewalld 作为防火墙管理工具。很多新手搭建网站后发现外网访问不了,90% 都是因为 80、443 端口没开放。下面是完整的操作步骤,照抄就能用。
1. 先确认防火墙状态
systemctl status firewalld
如果显示 active (running) 说明防火墙正在运行,需要继续下面的操作。如果是 inactive 那就是防火墙没开,问题不在这里。
2. 开放 80 端口(HTTP)
firewall-cmd --zone=public --add-port=80/tcp --permanent
参数说明:
--zone=public:作用域为公共区域--add-port=80/tcp:开放 80 端口,TCP 协议--permanent:永久生效,不加这个重启服务器就失效了
3. 开放 443 端口(HTTPS)
firewall-cmd --zone=public --add-port=443/tcp --permanent
4. 一次性开放多个端口
如果需要同时开放多个端口,可以一条命令搞定:
firewall-cmd --zone=public --add-port=80/tcp --add-port=443/tcp --permanent
5. 重载防火墙使配置生效
⚠️ 重点:开放端口后必须重载,否则不生效!
firewall-cmd --reload
6. 查看已开放的端口
确认一下端口有没有真正开放成功:
firewall-cmd --list-ports
正常会输出类似:
80/tcp 443/tcp
7. 常用其他端口开放命令
SSH 端口(默认22,建议改成别的):
firewall-cmd --zone=public --add-port=22/tcp --permanent
MySQL 端口(如果需要远程连接数据库):
firewall-cmd --zone=public --add-port=3306/tcp --permanent
Redis 端口:
firewall-cmd --zone=public --add-port=6379/tcp --permanent
8. 移除/关闭已开放的端口
如果某个端口不需要了,想关掉:
firewall-cmd --zone=public --remove-port=8080/tcp --permanent
firewall-cmd --reload
常见坑
-
加了
--permanent还是不生效?
忘记firewall-cmd --reload了。永久配置写入后必须重载才会加载到运行时。 -
端口开放了还是访问不了?
检查云服务商的安全组(阿里云/腾讯云/华为云都有这个东西),防火墙和安全组是两层,都要开。 -
firewalld 命令找不到?
CentOS 7 最小化安装可能没装,执行yum install firewalld -y安装。 -
临时开放端口(重启就失效)
去掉--permanent参数就是临时开放,重启或 reload 后自动关闭。
遇到服务器、Nginx、MySQL 报错,可以加微信远程协助排查问题。
MySQL 索引优化技巧
MySQL 索引优化技巧
索引是数据库性能的关键,加对了查询快十倍,加错了反而更慢。
1. 索引类型
主键索引:主键自带索引,一张表只能一个。
普通索引:最基本的索引,加速查询。
CREATE INDEX idx_name ON user(name);
唯一索引:字段值不能重复。
CREATE UNIQUE INDEX idx_email ON user(email);
联合索引:多个字段组合的索引。
CREATE INDEX idx_name_age ON user(name, age);
2. 索引失效的情况
1)like 以 % 开头
-- 索引失效
SELECT * FROM user WHERE name LIKE '%张';
-- 索引生效
SELECT * FROM user WHERE name LIKE '张%';
2)对字段做函数运算
-- 索引失效
SELECT * FROM user WHERE LEFT(name,1) = '张';
-- 索引生效
SELECT * FROM user WHERE name LIKE '张%';
3)联合索引不满足最左前缀
联合索引 (name, age):
-- 生效
SELECT * FROM user WHERE name = '张三';
-- 生效
SELECT * FROM user WHERE name = '张三' AND age = 25;
-- 失效
SELECT * FROM user WHERE age = 25;
4)隐式类型转换
-- phone 是 varchar
-- 索引失效
SELECT * FROM user WHERE phone = 13800001111;
-- 索引生效
SELECT * FROM user WHERE phone = '13800001111';
3. 查看索引使用情况
-- 查看执行计划
EXPLAIN SELECT * FROM user WHERE name = '张三';
-- 重点看 type 字段:
-- system > const > eq_ref > ref > range > index > ALL
-- 最差是 ALL(全表扫描)
4. 索引优化原则
- 为高频查询加索引:不要乱加
- 区分度高的字段优先:性别这种区分度低的不加
- 联合索引把最常用的放左边
- 索引不是越多越好:增删改会变慢
- 避免索引冗余:(a,b) 包含了 (a)
5. 慢查询排查
-- 开启慢查询
SET GLOBAL slow_query_log = ON;
SET GLOBAL long_query_time = 2;
-- 查看慢查询日志
SHOW VARIABLES LIKE 'slow_query_log_file';
总结
MySQL 索引优化核心:
- 联合索引满足最左前缀
- like 不要以 % 开头
- 不要对字段做函数运算
- 用 EXPLAIN 看执行计划
- 慢查询找出来再优化
搞懂这些,数据库性能提升一大截。
Git 常用命令汇总
Git 常用命令汇总
Git 是现在开发必备工具,整理一份常用命令清单,收藏备用。
1. 初始化和克隆
# 初始化新仓库
git init
# 克隆远程仓库
git clone https://github.com/user/repo.git
# 克隆指定分支
git clone -b dev https://github.com/user/repo.git
2. 查看状态
# 查看工作区状态
git status
# 查看提交历史
git log
# 查看简洁历史
git log --oneline --graph
# 查看文件改动
git diff
3. 添加和提交
# 添加所有文件到暂存区
git add .
# 添加指定文件
git add file.php
# 提交到本地仓库
git commit -m "修复bug"
# 提交并跳过验证
git commit --no-verify -m "修复bug"
4. 分支操作
# 查看本地分支
git branch
# 查看所有分支(包括远程)
git branch -a
# 创建新分支
git branch dev
# 切换分支
git checkout dev
# 创建并切换分支
git checkout -b dev
# 删除分支
git branch -d dev
# 强制删除分支
git branch -D dev
5. 远程操作
# 拉取远程更新
git pull
# 推送本地提交
git push
# 推送本地新分支到远程
git push -u origin dev
# 删除远程分支
git push origin --delete dev
6. 撤销操作
# 撤销工作区修改
git checkout -- file.php
# 撤销暂存区
git reset HEAD file.php
# 回退到上一个版本
git reset --hard HEAD^
# 回退到指定版本
git reset --hard commit_id
# 撤销上次提交(保留修改)
git reset --soft HEAD^
7. 合并和变基
# 合并分支
git merge dev
# 变基
git rebase master
# 取消合并
git merge --abort
8. 标签操作
# 打标签
git tag v1.0.0
# 查看标签
git tag
# 推送标签
git push origin v1.0.0
# 推送所有标签
git push origin --tags
总结
Git 常用命令核心:
- 查看:status / log / diff
- 提交:add / commit
- 分支:branch / checkout / merge
- 远程:pull / push
- 撤销:reset / checkout
记住这些,日常 Git 操作基本够用了。
Nginx 日志分析技巧
Nginx 日志分析技巧
Nginx 日志是排查问题、分析流量的重要工具。学会看日志,网站问题排查效率翻倍。
1. 日志位置
# 默认访问日志
/var/log/nginx/access.log
# 默认错误日志
/var/log/nginx/error.log
可以在 nginx.conf 里自定义:
access_log /var/log/nginx/www.access.log;
error_log /var/log/nginx/www.error.log;
2. 日志格式
默认日志格式:
127.0.0.1 - - [04/Oct/2026:10:00:00 +0800] "GET / HTTP/1.1" 200 612 "https://www.baidu.com/" "Mozilla/5.0..."
各字段含义:
- IP 地址
- 请求时间
- 请求方法和路径
- 状态码
- 响应大小
- 来源页面
- User-Agent
3. 常用分析命令
# 查看访问量前10的IP
awk '{print $1}' access.log | sort | uniq -c | sort -nr | head 10
# 查看访问量前10的页面
awk '{print $7}' access.log | sort | uniq -c | sort -nr | head 10
# 查看状态码分布
awk '{print $9}' access.log | sort | uniq -c | sort -nr
# 查看 404 请求
grep ' 404 ' access.log
# 查看 502 错误
grep ' 502 ' access.log
4. 排查问题
排查 502 错误:
grep ' 502 ' access.log | tail 20
排查慢请求:
开启慢日志:
slow_request_log /var/log/nginx/slow.log;
slow_request_time 5s;
排查爬虫:
grep 'Baiduspider' access.log
grep 'Googlebot' access.log
5. 流量统计
# 今天总访问量
grep '04/Oct/2026' access.log | wc -l
# 今天总流量
grep '04/Oct/2026' access.log | awk '{sum+=$10} END {print sum/1024/1024 " MB"}'
# 每小时访问量
awk '{print $4}' access.log | cut -d: -f2 | uniq -c
6. 日志切割
日志太大要切割,用 logrotate:
# /etc/logrotate.d/nginx
/var/log/nginx/*.log {
daily
missingok
rotate 30
compress
notifempty
create 0640 nginx adm
postrotate
systemctl reload nginx
endscript
}
7. 常用工具
- GoAccess:实时日志分析工具
- ELK:Elasticsearch + Logstash + Kibana
- Zabbix:监控告警
总结
Nginx 日志分析核心:
- 位置:/var/log/nginx/
- 命令:awk + sort + uniq
- 排查:看状态码、看慢请求
- 切割:用 logrotate
学会这些,日常日志分析基本够用了。
Docker 常用命令大全
Docker 常用命令大全
Docker 命令不多,但记不住还是很麻烦。整理一份常用命令清单,收藏备用。
1. 镜像命令
# 拉取镜像
docker pull nginx:latest
# 查看本地镜像
docker images
# 删除镜像
docker rmi nginx:latest
# 搜索镜像
docker search nginx
# 导出镜像
docker save -o nginx.tar nginx:latest
# 导入镜像
docker load -i nginx.tar
2. 容器命令
# 启动容器(后台运行)
docker run -d --name mynginx -p 80:80 nginx
# 查看运行中的容器
docker ps
# 查看所有容器(包括停止的)
docker ps -a
# 停止容器
docker stop mynginx
# 启动已停止的容器
docker start mynginx
# 重启容器
docker restart mynginx
# 删除容器
docker rm mynginx
# 强制删除运行中的容器
docker rm -f mynginx
3. 进入容器
# 进入容器(bash)
docker exec -it mynginx bash
# 进入容器(sh)
docker exec -it mynginx sh
# 查看容器日志
docker logs mynginx
# 实时查看日志
docker logs -f mynginx
# 查看容器详情
docker inspect mynginx
4. 文件操作
# 从容器复制文件到宿主机
docker cp mynginx:/etc/nginx/nginx.conf ./
# 从宿主机复制文件到容器
docker cp ./index.html mynginx:/usr/share/nginx/html/
5. 端口和网络
# 查看容器端口映射
docker port mynginx
# 查看容器 IP
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' mynginx
6. 清理命令
# 停止所有容器
docker stop $(docker ps -q)
# 删除所有停止的容器
docker container prune
# 删除所有未使用的镜像
docker image prune
# 删除所有未使用的资源(危险操作)
docker system prune -a
7. Docker Compose 常用命令
# 启动所有服务
docker-compose up -d
# 停止所有服务
docker-compose down
# 查看服务状态
docker-compose ps
# 查看日志
docker-compose logs -f
# 重启某个服务
docker-compose restart nginx
总结
Docker 常用命令核心:
- 镜像:pull / images / rmi
- 容器:run / ps / stop / start / rm
- 进入:exec -it
- 日志:logs -f
- 清理:prune
记住这些,日常 Docker 操作基本够用了。
PHP Composer 入门指南
PHP Composer 入门指南
Composer 是 PHP 的依赖管理工具,现在做 PHP 开发不用 Composer 几乎不可能。
1. 安装 Composer
# Linux/Mac
curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer
# Windows 直接下载安装包
# https://getcomposer.org/Composer-Setup.exe
验证安装:
composer -V
2. 换国内镜像(必须)
官方镜像太慢,一定要换国内镜像:
# 阿里云镜像
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
# 腾讯云镜像
composer config -g repo.packagist composer https://mirrors.tencent.com/composer/
3. 初始化项目
# 进入项目目录
cd myproject
# 初始化 composer.json
composer init
或者手动创建 composer.json:
{
"name": "my/project",
"require": {
"monolog/monolog": "^2.0"
}
}
4. 常用命令
# 安装依赖
composer install
# 更新依赖
composer update
# 安装某个包
composer require monolog/monolog
# 卸载某个包
composer remove monolog/monolog
# 自动加载
composer dump-autoload
5. 自动加载
// 引入自动加载文件
require __DIR__ . '/vendor/autoload.php';
// 然后就可以直接用第三方库了
$log = new Monolog\Logger('name');
6. composer.json 详解
{
"name": "项目名",
"description": "项目描述",
"type": "project",
"require": {
"php": ">=7.4",
"monolog/monolog": "^2.0",
"guzzlehttp/guzzle": "^7.0"
},
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
}
7. 版本号说明
^2.0:兼容 2.0 到 3.0(不包含 3.0)~2.0:兼容 2.0 到 2.1(不包含 2.1)*:任意版本2.0.*:2.0.x 版本
总结
Composer 核心:
- 安装:一行命令
- 换镜像:必须换国内源
- 常用:install / update / require / remove
- 自动加载:require vendor/autoload.php
搞懂这些,Composer 日常开发就够用了。
MySQL 事务隔离级别
MySQL 事务隔离级别详解
事务是数据库并发控制的基础,搞懂四个隔离级别,才能解决脏读、幻读问题。
1. 事务 ACID 特性
- 原子性(Atomicity):要么全成功,要么全回滚
- 一致性(Consistency):事务前后数据一致
- 隔离性(Isolation):事务之间互不干扰
- 持久性(Durability):提交后永久保存
2. 四种隔离级别
MySQL 有四种隔离级别,从上到下越来越严格:
读未提交(READ UNCOMMITTED)
- 可以读到别人还没提交的数据
- 会出现脏读
- 几乎没人用
读提交(READ COMMITTED)
- 只能读到别人已经提交的数据
- 解决了脏读,但会出现不可重复读
- Oracle、SQL Server 默认级别
可重复读(REPEATABLE READ)
- 同一个事务里,读多次结果都一样
- 解决了脏读、不可重复读
- MySQL InnoDB 默认级别
- InnoDB 用间隙锁解决了幻读
串行化(SERIALIZABLE)
- 事务一个一个排队执行
- 最安全,但性能最差
- 几乎没人用
3. 三种读问题
脏读:读到了别人还没提交的数据,别人回滚了,你读到的就是脏数据。
不可重复读:同一个事务里,两次读同一行数据,结果不一样(别人中间改了并提交了)。
幻读:同一个事务里,两次查同一个范围,行数不一样(别人中间插了新行)。
4. 查看和设置隔离级别
-- 查看当前隔离级别
SELECT @@global.tx_isolation;
SELECT @@session.tx_isolation;
-- 设置全局隔离级别
SET GLOBAL tx_isolation = 'READ-COMMITTED';
-- 设置当前会话隔离级别
SET SESSION tx_isolation = 'READ-COMMITTED';
5. 实际应用建议
- 默认就好:MySQL 默认的可重复读已经够用
- 高并发场景:可以降到读提交,提升并发性能
- 金融级场景:用串行化,绝对安全
- 大多数业务:默认级别就行,不用折腾
6. 代码示例
// PDO 事务示例
try {
$pdo->beginTransaction();
$pdo->exec("UPDATE account SET money = money - 100 WHERE id = 1");
$pdo->exec("UPDATE account SET money = money + 100 WHERE id = 2");
$pdo->commit();
} catch (Exception $e) {
$pdo->rollBack();
echo "转账失败:" . $e->getMessage();
}
总结
MySQL 事务隔离级别核心:
- 读未提交:脏读
- 读提交:不可重复读
- 可重复读:默认级别,解决幻读
- 串行化:最安全最慢
大多数业务用默认的可重复读就够了。
PHP 字符串处理技巧
PHP 字符串处理常用技巧
字符串处理是 PHP 开发最常用的操作,掌握这些函数,写代码效率翻倍。
1. 截取字符串
// 截取前 5 个字符
substr("hello world", 0, 5); // hello
// 截取从第 6 个开始到结尾
substr("hello world", 6); // world
// 中文字符串截取(用 mb_)
mb_substr("你好世界", 0, 2, "UTF-8"); // 你好
注意:中文要用 mb_substr,不能用 substr,否则会乱码。
2. 替换字符串
// str_replace(替换所有)
str_replace("world", "PHP", "hello world"); // hello PHP
// str_ireplace(不区分大小写)
str_ireplace("WORLD", "PHP", "hello world");
// preg_replace(正则替换)
preg_replace("/\d/", "", "abc123def"); // abcdef
3. 查找字符串
// 查找位置(找不到返回 false)
strpos("hello world", "world"); // 6
// 查找最后出现位置
strrpos("hello world hello", "hello"); // 12
// 判断是否包含(PHP 8+)
str_contains("hello world", "world"); // true
// 判断开头
str_starts_with("hello world", "hello"); // true
// 判断结尾
str_ends_with("hello world", "world"); // true
4. 格式化字符串
// 去除首尾空格
trim(" hello "); // hello
// 只去左边/右边
ltrim(" hello"); // hello
rtrim("hello "); // hello
// 转小写/大写
strtolower("Hello"); // hello
strtoupper("hello"); // HELLO
// 首字母大写
ucfirst("hello"); // Hello
// 每个单词首字母大写
ucwords("hello world"); // Hello World
5. 字符串和数组转换
// 字符串转数组
explode(",", "a,b,c"); // ["a","b","c"]
// 数组转字符串
implode(",", ["a","b","c"]); // a,b,c
// 重复字符串
str_repeat("ab", 3); // ababab
// 字符串长度
strlen("hello"); // 5
mb_strlen("你好", "UTF-8"); // 2
6. 常用技巧
// 生成随机字符串
substr(md5(time()), 0, 8);
// 脱敏手机号
substr_replace("13812345678", "****", 3, 4); // 138****5678
// 截取摘要(带省略号)
mb_strlen($text) > 10 ? mb_substr($text, 0, 10) . "..." : $text;
// 清除 HTML 标签
strip_tags("<p>hello</p>"); // hello
总结
PHP 字符串处理核心函数:
- 截取:substr / mb_substr
- 替换:str_replace / preg_replace
- 查找:strpos / str_contains
- 格式化:trim / strtolower / ucwords
- 转换:explode / implode
记住这些,日常开发基本够用了。
Linux 防火墙配置技巧
Linux 防火墙配置技巧
服务器安全第一步就是配好防火墙,只开需要的端口,其他全关。
1. firewalld(CentOS 7+ 默认)
# 查看状态
firewall-cmd --state
# 查看已开放端口
firewall-cmd --list-ports
# 开放端口
firewall-cmd --permanent --add-port=80/tcp
firewall-cmd --permanent --add-port=443/tcp
# 开放多个端口
firewall-cmd --permanent --add-port=8000-9000/tcp
# 开放指定 IP 访问
firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='192.168.1.100' port protocol='tcp' port=3306 accept"
# 重载配置(必须重载才生效)
firewall-cmd --reload
# 删除端口
firewall-cmd --permanent --remove-port=8080/tcp
2. ufw(Ubuntu 默认)
# 查看状态
ufw status
# 开启防火墙
ufw enable
# 允许 SSH
ufw allow 22
# 允许 80 和 443
ufw allow 80
ufw allow 443
# 允许指定 IP
ufw allow from 192.168.1.100 to any port 3306
# 拒绝某个 IP
ufw deny from 1.2.3.4
# 删除规则
ufw delete allow 8080
3. iptables(经典)
# 查看规则
iptables -L -n
# 允许 22 端口
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# 允许 80 端口
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# 允许本地回环
iptables -A INPUT -i lo -j ACCEPT
# 允许已建立的连接
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# 默认拒绝其他
iptables -P INPUT DROP
# 保存规则(CentOS)
service iptables save
4. 安全建议
- 只开必要端口:SSH、HTTP、HTTPS,其他全关
- SSH 改端口:不要用默认 22,改成其他端口
- 限制 SSH 登录 IP:只允许你的 IP 登录 SSH
- 数据库不对外暴露:MySQL、Redis 只允许本地访问
- 定期查看日志:/var/log/secure 看有没有暴力破解
5. 常用端口速查
- 22:SSH
- 80:HTTP
- 443:HTTPS
- 3306:MySQL
- 6379:Redis
- 8080:应用端口
总结
Linux 防火墙核心:
- CentOS 用 firewalld
- Ubuntu 用 ufw
- 只开必要端口
- 数据库不对外暴露
- SSH 限制 IP 访问
配好防火墙,服务器安全提升一大截。
Nginx 负载均衡配置
Nginx 负载均衡配置实战
网站流量大了,单台服务器扛不住,就得用负载均衡。Nginx 做负载均衡很简单,几行配置就行。
1. 基本配置
http {
upstream backend {
server 192.168.1.101:80;
server 192.168.1.102:80;
server 192.168.1.103:80;
}
server {
listen 80;
server_name www.example.com;
location / {
proxy_pass http://backend;
}
}
}
默认是轮询(round robin),请求轮流分到三台服务器。
2. 四种分配策略
轮询(默认):一个一个来。
权重(weight):按比例分配,性能好的服务器多分担。
upstream backend {
server 192.168.1.101 weight=3;
server 192.168.1.102 weight=2;
server 192.168.1.103 weight=1;
}
3:2:1 的比例,第一台分一半请求。
ip_hash:同一个 IP 固定分到同一台服务器,解决 session 问题。
upstream backend {
ip_hash;
server 192.168.1.101;
server 192.168.1.102;
}
least_conn:最少连接数优先,分给当前最闲的服务器。
upstream backend {
least_conn;
server 192.168.1.101;
server 192.168.1.102;
}
3. 健康检查
upstream backend {
server 192.168.1.101 max_fails=3 fail_timeout=30s;
server 192.168.1.102 max_fails=3 fail_timeout=30s;
}
一台服务器挂了,自动从列表里摘掉,恢复了再加回来。
4. 常用参数
- max_fails:失败几次算挂了,默认1次
- fail_timeout:挂了多久再重试,默认10秒
- down:标记服务器下线,不分配请求
- backup:备用服务器,其他都挂了才用
5. 完整示例
upstream backend {
server 192.168.1.101 weight=3 max_fails=3 fail_timeout=30s;
server 192.168.1.102 weight=2 max_fails=3 fail_timeout=30s;
server 192.168.1.103 backup;
}
server {
listen 80;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
总结
Nginx 负载均衡核心:
- upstream 定义服务器组
- 四种策略:轮询、权重、ip_hash、最少连接
- 健康检查自动摘除故障节点
- 生产环境用权重 + 健康检查就够了
搞懂这些,多台服务器集群就跑起来了。
Redis 数据结构详解
Redis 五种数据结构详解
Redis 不只是缓存,它的五种数据结构各有各的用处,搞懂了才能用对地方。
1. String(字符串)
最基础的数据结构,存字符串、数字都行。
SET name "张三"
GET name
INCR count
SET token "abc123" EX 3600
应用场景:缓存用户信息、计数器、分布式锁、会话存储。
2. Hash(哈希)
存键值对,适合存对象。
HSET user:1 name "张三" age 25 city "北京"
HGET user:1 name
HGETALL user:1
应用场景:存用户信息、商品信息,比 String 存 JSON 更省空间。
3. List(列表)
有序列表,可以从头或尾加元素。
LPUSH messages "hello"
LPUSH messages "world"
LRANGE messages 0 -1
应用场景:消息队列、最新消息列表、朋友圈时间线。
4. Set(集合)
无序不重复集合。
SADD tags "PHP"
SADD tags "MySQL"
SMEMBERS tags
SISMEMBER tags "PHP"
应用场景:标签、共同好友、去重。
5. ZSet(有序集合)
每个元素带分数,按分数排序。
ZADD rank 100 "张三"
ZADD rank 90 "李四"
ZREVRANGE rank 0 9 WITHSCORES
应用场景:排行榜、计分板、优先级队列。
总结
五种数据结构各有用处:
- String:简单缓存、计数器
- Hash:存对象
- List:队列、时间线
- Set:去重、标签
- ZSet:排行榜
选对数据结构,性能才能发挥出来。
PHP 数组操作技巧
PHP 数组操作技巧
数组是 PHP 最常用的数据结构,掌握这些技巧,写代码效率翻倍。
1. 数组合并
// 索引数组合并
$arr1 = [1, 2];
$arr2 = [3, 4];
$result = array_merge($arr1, $arr2); // [1,2,3,4]
// 关联数组合并,后面覆盖前面
$arr1 = ['a' => 1, 'b' => 2];
$arr2 = ['b' => 3, 'c' => 4];
$result = array_merge($arr1, $arr2); // ['a'=>1, 'b'=>3, 'c'=>4]
2. 数组去重
// 一维数组去重
$arr = [1, 2, 2, 3, 3, 3];
$result = array_unique($arr); // [1,2,3]
// 二维数组按字段去重
$users = [
['id' => 1, 'name' => '张三'],
['id' => 2, 'name' => '李四'],
['id' => 1, 'name' => '张三'],
];
$ids = array_column($users, 'id');
$unique = array_unique($ids);
3. 数组排序
// 升序
sort($arr);
// 降序
rsort($arr);
// 按键排序
ksort($arr);
// 按值排序,保留键
asort($arr);
4. 数组过滤
// 过滤空值
$arr = [1, 0, '', null, 'a'];
$result = array_filter($arr); // [1, 'a']
// 自定义过滤
$result = array_filter($arr, function($value) {
return $value > 2;
});
5. 数组取值
// 取某一列
$names = array_column($users, 'name');
// 取交集
$arr1 = [1, 2, 3];
$arr2 = [2, 3, 4];
$result = array_intersect($arr1, $arr2); // [2,3]
// 取差集
$result = array_diff($arr1, $arr2); // [1]
6. 常用技巧
// 判断键是否存在
isset($arr['key']);
array_key_exists('key', $arr);
// 随机取一个
$value = array_rand($arr);
// 打乱数组
shuffle($arr);
// 数组合并成字符串
$str = implode(',', $arr);
// 字符串转数组
$arr = explode(',', $str);
总结
PHP 数组函数非常丰富,常用的就这些:合并、去重、排序、过滤、取值。把这些记熟,日常开发基本够用了。
MySQL 锁机制详解
MySQL 锁机制详解
MySQL 锁是并发控制的核心,搞懂锁,才能避免死锁和性能问题。
1. 表锁 vs 行锁
表锁:锁整个表,开销小,并发低。
- MyISAM 用的就是表锁
- 适合读多写少的场景
行锁:锁单行数据,开销大,并发高。
- InnoDB 用的就是行锁
- 适合写多的场景
2. 共享锁 vs 排他锁
共享锁(S锁):读锁,多个读不互斥。
SELECT ... LOCK IN SHARE MODE
排他锁(X锁):写锁,一个写独占。
SELECT ... FOR UPDATE
3. 间隙锁
InnoDB 用间隙锁防止幻读。锁的是一个范围,不是具体行。
比如你查 id > 10 AND id < 20,间隙锁会把这个区间锁住,别人插不进来。
4. 死锁
两个事务互相等对方的锁,都不放,就死锁了。
避免死锁的方法:
- 按相同顺序访问表
- 事务尽量小,快速提交
- 降低隔离级别
- 加索引,减少行锁范围
5. 查看锁状态
-- 查看当前锁
SHOW OPEN TABLES WHERE In_use > 0;
-- 查看 InnoDB 锁
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
-- 查看锁等待
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;
6. 行锁什么时候会变成表锁
行锁失效就会升级成表锁:
- 没用索引
- 索引失效
- 全表扫描
所以加索引不仅是为了查得快,也是为了锁得准。
总结
MySQL 锁的核心:
- InnoDB 默认行锁,MyISAM 是表锁
- 共享锁读、排他锁写
- 间隙锁防幻读
- 死锁要避免:顺序访问、小事务、加索引
搞懂这些,数据库并发问题基本能解决一半。
Linux 文件权限详解
Linux 文件权限详解
Linux 权限是服务器安全的基础,搞懂权限,服务器才不会乱。
1. 查看权限
用 ls -l 查看文件权限:
ls -l file.txt
-rw-r--r-- 1 user group 1024 Oct 4 10:00 file.txt
开头10个字符就是权限:
- 第1个:文件类型(- 普通文件,d 目录)
- 第2-4个:所有者权限
- 第5-7个:所属组权限
- 第8-10个:其他人权限
2. 三种权限
- r(读)= 4
- w(写)= 2
- x(执行)= 1
数字加起来就是权限值:
- 7 = 4+2+1 = rwx
- 6 = 4+2 = rw-
- 5 = 4+1 = r-x
- 4 = 4 = r--
3. 修改权限 chmod
# 给所有者加执行权限
chmod u+x file.txt
# 给所有人只读权限
chmod 444 file.txt
# 所有者读写执行,组和其他人只读
chmod 744 file.txt
4. 修改所有者 chown
# 修改文件所有者
chown user:group file.txt
# 递归修改目录
chown -R user:group /data/www
5. 常用权限
- 普通文件:644(所有者读写,其他人只读)
- 目录:755(所有者读写执行,其他人读执行)
- 脚本文件:755(所有者能执行)
6. 安全建议
- 网站目录不要用 root 所有者
- 上传目录禁止执行权限
- 配置文件权限设为 600,只有所有者能读
总结
Linux 权限核心就是三组(所有者、组、其他人)× 三种(读、写、执行),用数字表示就是 r=4、w=2、x=1。搞懂这个,日常权限管理基本够用了。
Docker 网络模式详解
Docker 四种网络模式详解
Docker 网络是容器通信的基础,搞懂四种网络模式,容器网络就不会乱。
1. bridge 模式(默认)
这是 Docker 默认的网络模式。容器在一个虚拟的 bridge 网络里,每个容器有自己的虚拟 IP,通过 NAT 访问外部网络。
# 启动容器,默认就是 bridge
docker run -d nginx
# 查看容器 IP
docker inspect 容器ID | grep IPAddress
特点:
- 容器之间可以通过 IP 互相访问
- 外部访问需要端口映射
- 适合大多数场景
2. host 模式
容器直接用宿主机的网络,没有独立的网络栈。
docker run -d --net=host nginx
特点:
- 网络性能最好,没有 NAT 开销
- 端口直接用宿主机的,不用映射
- 多个容器不能用同一个端口
适合对性能要求高的场景。
3. none 模式
容器没有网络,完全隔离。
docker run -d --net=none nginx
特点:
- 没有任何网络
- 安全级别最高
- 适合不需要网络的离线计算任务
4. container 模式
新创建的容器和一个已存在的容器共享网络。
docker run -d --net=container:nginx容器ID redis
特点:
- 两个容器共享网络栈
- 可以用 localhost 互相访问
- 适合紧密配合的服务
5. 自定义网络
生产环境推荐用自定义网络,不用默认的 bridge:
# 创建自定义网络
docker network create mynet
# 容器加入自定义网络
docker run -d --net=mynet --name web nginx
docker run -d --net=mynet --name app php
同一个自定义网络里的容器,可以直接用容器名互相访问,不用记 IP。
总结
四种网络模式各有适用场景:
- 日常开发用默认 bridge
- 性能要求高用 host
- 安全要求高用 none
- 容器间通信密集用自定义网络
搞懂这四种模式,Docker 网络基本就够用了。