Redis 常用数据类型

Redis 常用数据类型

Redis 不只是缓存,它有 5 种常用数据类型,用对了能解决很多问题。

1. String(字符串)

最基本的类型,一个 key 对应一个 value。

# 设置
SET name "张三"

# 读取
GET name

# 自增(计数器)
INCR page_view

# 设置过期时间(秒)
EXPIRE token 3600

# 查看过期时间
TTL token

适用场景: 缓存、计数器、分布式锁。

2. Hash(哈希)

适合存对象。

# 设置字段
HSET user:1 name "张三" age 25

# 获取字段
HGET user:1 name

# 获取所有字段
HGETALL user:1

# 删除字段
HDEL user:1 age

适用场景: 用户信息、商品信息。

3. List(列表)

有序队列,先进先出。

# 从左边插入
LPUSH messages "消息1"
LPUSH messages "消息2"

# 从右边插入
RPUSH messages "消息3"

# 从左边弹出
LPOP messages

# 查看列表
LRANGE messages 0 -1

适用场景: 消息队列、最新消息列表。

4. Set(集合)

无序不重复。

# 添加元素
SADD tags "PHP" "MySQL" "Linux"

# 查看所有元素
SMEMBERS tags

# 判断是否存在
SISMEMBER tags "PHP"

# 交集
SINTER set1 set2

适用场景: 标签、共同好友、去重。

5. ZSet(有序集合)

每个元素带分数,按分数排序。

# 添加元素
ZADD rank 100 "张三"
ZADD rank 90 "李四"
ZADD rank 80 "王五"

# 查看排行(从高到低)
ZREVRANGE rank 0 -1 WITHSCORES

# 获取排名
ZREVRANK rank "张三"

适用场景: 排行榜、热度排序。

总结

类型 特点 适用场景
String 简单键值 缓存、计数器
Hash 存对象 用户信息
List 有序队列 消息队列
Set 不重复 标签、去重
ZSet 带分数排序 排行榜

Redis 用熟了,能解决很多业务问题。


emer 发布于  2026-10-7 07:15 

MySQL 性能优化实战

MySQL 性能优化实战

数据库慢是网站性能的大问题,这篇讲实战优化方法,从几个方面下手。

1. 慢查询排查

先找到慢SQL,再优化。

开启慢查询日志:

-- 查看是否开启
SHOW VARIABLES LIKE 'slow_query_log%';

-- 开启慢查询
SET GLOBAL slow_query_log = ON;

-- 设置慢查询阈值(秒)
SET GLOBAL long_query_time = 1;

用 explain 分析:

EXPLAIN SELECT * FROM users WHERE name = '张三';

重点看:

  • type:有没有用到索引(ref/const 好,ALL 全表扫描坏)
  • key:实际用的索引
  • rows:扫描行数

2. 索引优化

建索引原则:

  • where 条件经常用的字段建索引
  • 联合索引最左前缀原则
  • 避免建太多索引,影响写入

查看索引:

SHOW INDEX FROM users;

建索引:

-- 普通索引
CREATE INDEX idx_name ON users(name);

-- 联合索引
CREATE INDEX idx_name_age ON users(name, age);

-- 唯一索引
CREATE UNIQUE INDEX idx_email ON users(email);

3. SQL 优化

**不要 SELECT ***

-- 坏
SELECT * FROM users WHERE id = 1;

-- 好
SELECT id, name, email FROM users WHERE id = 1;

避免 LIKE 前导模糊:

-- 坏(用不到索引)
SELECT * FROM users WHERE name LIKE '%张%';

-- 好(能用索引)
SELECT * FROM users WHERE name LIKE '张%';

大表分页优化:

-- 坏(深度分页慢)
SELECT * FROM users LIMIT 100000, 10;

-- 好(子查询先定位)
SELECT * FROM users 
WHERE id >= (SELECT id FROM users LIMIT 100000, 1) 
LIMIT 10;

4. 表结构优化

  • 用合适的数据类型(能用 int 就别用 bigint)
  • 字段尽量 NOT NULL
  • 大表分表分库

5. 配置优化

my.cnf 常用配置:

# 缓冲池大小(内存的 70%)
innodb_buffer_pool_size = 1G

# 连接数
max_connections = 500

# 慢查询日志
slow_query_log = 1
long_query_time = 1

6. 总结

MySQL 优化三步走:

  1. 找慢SQL: 慢查询日志 + explain
  2. 加索引: where 条件字段
  3. 优化SQL: 不写 SELECT *,避免全表扫描

数据库优化不是一蹴而就,要持续监控和调整。


emer 发布于  2026-10-7 07:14 

Docker 常用命令汇总

Docker 常用命令汇总

Docker 现在是开发必备工具,整理一份常用命令清单,记不住随时翻。

1. 镜像管理

# 查看本地镜像
docker images

# 搜索镜像
docker search nginx

# 拉取镜像
docker pull nginx:latest

# 删除镜像
docker rmi nginx:latest

# 导出镜像
docker save -o nginx.tar nginx:latest

# 导入镜像
docker load -i nginx.tar

2. 容器管理

# 查看运行中的容器
docker ps

# 查看所有容器(包括停止的)
docker ps -a

# 启动容器
docker start nginx

# 停止容器
docker stop nginx

# 重启容器
docker restart nginx

# 删除容器
docker rm nginx

# 强制删除运行中的容器
docker rm -f nginx

3. 运行容器

# 后台运行 nginx
docker run -d --name mynginx -p 80:80 nginx

# 参数说明:
# -d:后台运行
# --name:容器名
# -p:端口映射(主机:容器)
# -v:目录挂载(主机:容器)

# 进入容器内部
docker exec -it mynginx bash

# 查看容器日志
docker logs mynginx

# 实时查看日志
docker logs -f mynginx

4. 查看容器信息

# 查看容器详细信息
docker inspect mynginx

# 查看容器占用资源
docker stats

# 查看容器端口映射
docker port mynginx

5. 数据卷

# 创建数据卷
docker volume create mydata

# 查看所有数据卷
docker volume ls

# 挂载数据卷运行容器
docker run -d -v mydata:/data nginx

# 删除数据卷
docker volume rm mydata

6. Docker Compose

# 启动服务
docker-compose up -d

# 停止服务
docker-compose down

# 查看服务状态
docker-compose ps

# 查看日志
docker-compose logs -f

docker-compose.yml 示例:

version: '3'
services:
  nginx:
    image: nginx
    ports:
      - "80:80"
    volumes:
      - ./html:/usr/share/nginx/html

7. 清理命令

# 删除所有停止的容器
docker container prune

# 删除所有无用镜像
docker image prune -a

# 删除所有无用数据卷
docker volume prune

# 一键清理所有无用资源
docker system prune -a

总结

Docker 常用命令就这几类:

  • 镜像: pull / images / rmi
  • 容器: run / ps / stop / rm / exec
  • 日志: logs / stats
  • Compose: up / down

日常开发把这些命令用熟就够了,不用背,多敲几次自然记住。


emer 发布于  2026-10-7 07:12 

PHP 常用设计模式

PHP 常用设计模式

设计模式不是玄学,是前人踩坑总结出来的套路。这篇讲 PHP 开发中最常用的几个。

1. 单例模式(最常用)

保证一个类只有一个实例,节省资源。

class Database
{
    private static $instance = null;
    private $pdo;

    // 构造函数私有化,禁止外部 new
    private function __construct()
    {
        $this->pdo = new PDO('mysql:host=127.0.0.1;dbname=blog', 'root', '123456');
    }

    // 禁止克隆
    private function __clone() {}

    public static function getInstance()
    {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    public function query($sql)
    {
        return $this->pdo->query($sql);
    }
}

// 使用
$db = Database::getInstance();
$db->query("SELECT * FROM users");

适用场景: 数据库连接、日志类、配置类。

2. 工厂模式

根据参数创建不同对象,不用直接 new。

interface Logger
{
    public function write($message);
}

class FileLogger implements Logger
{
    public function write($message)
    {
        file_put_contents('log.txt', $message . "\n", FILE_APPEND);
    }
}

class DatabaseLogger implements Logger
{
    public function write($message)
    {
        // 写入数据库
    }
}

class LoggerFactory
{
    public static function create($type)
    {
        switch ($type) {
            case 'file':
                return new FileLogger();
            case 'database':
                return new DatabaseLogger();
            default:
                throw new Exception("不支持的日志类型");
        }
    }
}

// 使用
$logger = LoggerFactory::create('file');
$logger->write("这是一条日志");

3. 观察者模式

对象状态变化时自动通知依赖它的对象。

interface Observer
{
    public function update($event);
}

class Order
{
    private $observers = [];

    public function addObserver(Observer $observer)
    {
        $this->observers[] = $observer;
    }

    public function pay()
    {
        // 支付逻辑
        echo "订单支付成功\n";

        // 通知所有观察者
        foreach ($this->observers as $observer) {
            $observer->update('pay_success');
        }
    }
}

class SendSmsObserver implements Observer
{
    public function update($event)
    {
        if ($event == 'pay_success') {
            echo "发送支付成功短信\n";
        }
    }
}

class SendEmailObserver implements Observer
{
    public function update($event)
    {
        if ($event == 'pay_success') {
            echo "发送支付成功邮件\n";
        }
    }
}

// 使用
$order = new Order();
$order->addObserver(new SendSmsObserver());
$order->addObserver(new SendEmailObserver());
$order->pay();

适用场景: 事件系统、消息通知。

4. 策略模式

定义一系列算法,让它们可以互相替换。

interface PayStrategy
{
    public function pay($amount);
}

class AlipayStrategy implements PayStrategy
{
    public function pay($amount)
    {
        echo "支付宝支付 {$amount} 元\n";
    }
}

class WechatPayStrategy implements PayStrategy
{
    public function pay($amount)
    {
        echo "微信支付 {$amount} 元\n";
    }
}

class OrderPay
{
    private $strategy;

    public function setStrategy(PayStrategy $strategy)
    {
        $this->strategy = $strategy;
    }

    public function pay($amount)
    {
        $this->strategy->pay($amount);
    }
}

// 使用
$orderPay = new OrderPay();
$orderPay->setStrategy(new AlipayStrategy());
$orderPay->pay(100);

总结

常用设计模式就这几个:

  • 单例模式: 全局唯一对象(数据库连接)
  • 工厂模式: 统一创建对象
  • 观察者模式: 事件通知
  • 策略模式: 算法切换

设计模式不是为了用而用,是解决特定问题的。项目小就别硬套,过度设计比没有设计更糟。


emer 发布于  2026-10-7 07:11 

Nginx 配置 HTTPS 详解

Nginx 配置 HTTPS 详解

现在网站都要求上 HTTPS,Nginx 配置 HTTPS 是运维必备技能。

1. 申请 SSL 证书

免费证书推荐:

  • Let's Encrypt(免费 90 天)
  • 阿里云/腾讯云免费 DV 证书

用 acme.sh 申请 Let's Encrypt:

# 安装 acme.sh
curl https://get.acme.sh | sh

# 申请证书
~/.acme.sh/acme.sh --issue -d www.example.com --webroot /www/wwwroot/example.com/

# 安装证书
~/.acme.sh/acme.sh --install-cert -d www.example.com \
  --key-file /www/server/ssl/private.key \
  --fullchain-file /www/server/ssl/cert.crt

2. Nginx 基础 HTTPS 配置

server {
    listen 443 ssl;
    server_name www.example.com;

    # 证书文件
    ssl_certificate     /www/server/ssl/cert.crt;
    ssl_certificate_key /www/server/ssl/private.key;

    # SSL 优化
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;

    root /www/wwwroot/example.com;
    index index.html index.php;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

3. HTTP 自动跳转 HTTPS

server {
    listen 80;
    server_name www.example.com;
    return 301 https://$server_name$request_uri;
}

4. 优化 HTTPS 性能

开启 HTTP/2:

listen 443 ssl http2;

HSTS 强制 HTTPS:

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

开启 OCSP Stapling:

ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 114.114.114.114 valid=300s;

5. 常见问题

1)证书不生效:

  • 检查证书路径对不对
  • 证书文件格式是否正确
  • Nginx 配置重载了吗

2)混合内容问题:

  • 页面里有 http:// 的资源,浏览器会拦截
  • 全部改成 https:// 或 // 协议相对路径

3)证书过期:

  • 免费证书 90 天过期
  • 用 acme.sh 自动续期
# acme.sh 自动安装了定时任务
crontab -l | grep acme

6. 检查配置

# 检查 Nginx 配置
nginx -t

# 重载配置
nginx -s reload

# 测试证书
curl -I https://www.example.com

总结

Nginx 配置 HTTPS 要点:

  • 申请 SSL 证书
  • 配置 443 端口和证书路径
  • HTTP 跳转 HTTPS
  • 开启 HTTP/2 和 SSL 优化
  • 设置自动续期

现在没有 HTTPS 的网站浏览器都标"不安全",赶紧给网站配上。


emer 发布于  2026-10-7 07:10 

MySQL 备份恢复实战

MySQL 备份与恢复实战

数据库备份是运维的基本功,万一数据丢了,没有备份就完蛋了。这篇整理常用的备份恢复方法。

1. mysqldump 逻辑备份

最常用的备份工具,生成 SQL 文件。

备份整个数据库:

mysqldump -u root -p123456 blog > blog_$(date +%Y%m%d).sql

备份单张表:

mysqldump -u root -p123456 blog users > users.sql

备份所有数据库:

mysqldump -u root -p123456 --all-databases > all.sql

常用参数:

  • --databases:指定多个数据库
  • --single-transaction:InnoDB 一致性备份,不锁表
  • --routines:备份存储过程和函数
  • --triggers:备份触发器

2. 恢复数据

# 恢复整个数据库
mysql -u root -p123456 blog < blog_20261007.sql

# 登录后恢复
mysql -u root -p123456
mysql> use blog;
mysql> source /root/blog_20261007.sql;

3. 压缩备份

数据大的时候,直接存 SQL 太占空间,压缩一下:

# 备份并压缩
mysqldump -u root -p123456 blog | gzip > blog_$(date +%Y%m%d).sql.gz

# 恢复压缩备份
gunzip < blog_20261007.sql.gz | mysql -u root -p123456 blog

4. 全量+增量备份

大数据量不能每天全量备份,用 binlog 做增量。

全量备份:

mysqldump -u root -p123456 --single-transaction --master-data=2 blog > full.sql

增量恢复:

# 先恢复全量
mysql -u root -p123456 blog < full.sql

# 再按时间点恢复 binlog
mysqlbinlog --start-datetime="2026-10-07 10:00:00" \
            --stop-datetime="2026-10-07 14:00:00" \
            /var/lib/mysql/binlog.000001 | mysql -u root -p123456

5. 物理备份(冷备)

直接拷贝数据文件,速度快,但需要停库。

# 停库
systemctl stop mysqld

# 拷贝数据目录
cp -r /var/lib/mysql /backup/mysql_$(date +%Y%m%d)

# 启动
systemctl start mysqld

6. 定时备份脚本

写个脚本每天自动备份:

#!/bin/bash
BACKUP_DIR="/data/backup/mysql"
DATE=$(date +%Y%m%d)
USER="root"
PASS="123456"

# 创建目录
mkdir -p $BACKUP_DIR

# 备份并压缩
mysqldump -u$USER -p$PASS --single-transaction blog | gzip > $BACKUP_DIR/blog_$DATE.sql.gz

# 删除7天前的备份
find $BACKUP_DIR -name "*.sql.gz" -mtime +7 -delete

加到 crontab:

0 3 * * * /bin/bash /root/mysql_backup.sh

7. 恢复注意事项

  • 恢复前先测试备份文件能不能用,别等真出事了才发现备份坏了
  • 大表恢复慢,别在线上高峰期操作
  • 字符集要一致,恢复前先检查
  • 恢复前先备份当前数据,防止恢复出错

总结

MySQL 备份三件事:

  • 定期备份,别偷懒
  • 备份后要测试能不能恢复
  • 重要数据异地备份

数据无价,备份一定要做好。


emer 发布于  2026-10-7 07:09 

Nginx配置HTTPS证书,http自动跳转https

前言

现在网站都要上 HTTPS,搜索引擎也更喜欢 HTTPS 的网站。本文讲一下 Nginx 怎么配置 HTTPS 证书,以及怎么把 HTTP 请求自动跳转到 HTTPS。

第一步:申请 SSL 证书

免费证书(Let's Encrypt)

用 certbot 自动申请:

# 安装 certbot
yum install certbot python3-certbot-nginx -y

# 自动申请并配置
certbot --nginx -d www.example.com -d example.com

certbot 会自动修改 Nginx 配置,不用手动改。

自己上传证书

如果是从阿里云、腾讯云申请的证书,下载 Nginx 版本的,一般有两个文件:

  • xxx.crt(证书文件)
  • xxx.key(私钥文件)

上传到服务器:

mkdir -p /etc/nginx/ssl

把两个文件传到 /etc/nginx/ssl/ 目录下。

第二步:Nginx 配置 HTTPS

编辑 Nginx 配置文件:

vi /etc/nginx/conf.d/example.conf

配置内容:

server {
    listen       443 ssl http2;
    server_name  www.example.com example.com;

    # 证书路径
    ssl_certificate      /etc/nginx/ssl/xxx.crt;
    ssl_certificate_key  /etc/nginx/ssl/xxx.key;

    # SSL 优化配置
    ssl_session_cache    shared:SSL:10m;
    ssl_session_timeout  10m;
    ssl_ciphers  HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers  on;

    # 网站根目录
    root  /var/www/html;
    index index.html index.php;

    location / {
        try_files $uri $uri/ =404;
    }
}

第三步:HTTP 自动跳转 HTTPS

在同一个配置文件里,加一个 80 端口的 server:

# HTTP 跳转 HTTPS
server {
    listen       80;
    server_name  www.example.com example.com;
    return 301 https://$host$request_uri;
}

这样访问 http://www.example.com 就会自动跳转到 https://www.example.com。

第四步:检查配置并重载

检查 Nginx 配置有没有语法错误:

nginx -t

没问题就重载:

nginx -s reload

完整配置示例

# HTTP 跳转 HTTPS
server {
    listen       80;
    server_name  www.example.com example.com;
    return 301 https://$host$request_uri;
}

# HTTPS 配置
server {
    listen       443 ssl http2;
    server_name  www.example.com example.com;

    ssl_certificate      /etc/nginx/ssl/xxx.crt;
    ssl_certificate_key  /etc/nginx/ssl/xxx.key;

    ssl_session_cache    shared:SSL:10m;
    ssl_session_timeout  10m;
    ssl_ciphers  HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers  on;

    root  /var/www/html;
    index index.html index.php;

    location / {
        try_files $uri $uri/ =404;
    }
}

常见坑

坑1:证书文件路径不对

配置里写的证书路径和实际路径不一致,Nginx 启动报错。

解决: 确认证书文件确实在配置写的那个位置。

坑2:443 端口没开放

配置了 HTTPS 但访问不了。

原因: 防火墙没开 443 端口。

解决:

firewall-cmd --permanent --add-service=https
firewall-cmd --reload

坑3:跳转死循环

HTTP 跳 HTTPS 后又跳回 HTTP,无限循环。

原因: 用了 CDN 或者负载均衡,后端以为还是 HTTP。

解决: Nginx 配置里加:

set $flag 0;
if ($http_x_forwarded_proto = 'http') {
    set $flag 1;
}
if ($flag = 1) {
    return 301 https://$host$request_uri;
}

坑4:证书过期了

HTTPS 证书一般一年有效期,忘了续签就会过期。

解决: 用 certbot 的话自动续签:

certbot renew

加个定时任务自动续签:

0 3 1 * * certbot renew --quiet

总结

步骤 命令/操作
申请证书 certbot --nginx -d 域名
配置 HTTPS 写 443 端口的 server 块
HTTP 跳转 return 301 https://$host$request_uri
检查配置 nginx -t
重载 nginx -s reload
开防火墙 firewall-cmd --permanent --add-service=https

提醒: HTTPS 证书要定期续签,别等过期了才想起。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-6 08:07 

Nginx报502 Bad Gateway完整排查思路(PHP-FPM场景)

前言

502 Bad Gateway 是 Nginx 最常见的报错之一,尤其是 LNMP 架构下,Nginx 把 PHP 请求转发给 PHP-FPM,PHP-FPM 出问题了 Nginx 就报 502。本文讲一下完整的排查思路。

502 是什么意思

502 表示 Nginx 作为反向代理,去请求后端服务(PHP-FPM)的时候,后端没响应或者报错了。

注意: 502 不是 Nginx 的问题,是后端 PHP-FPM 的问题。

排查步骤

第一步:检查 PHP-FPM 服务是否在运行

systemctl status php-fpm

如果显示 inactive (dead),说明 PHP-FPM 挂了,启动它:

systemctl start php-fpm
systemctl enable php-fpm

第二步:检查 Nginx 和 PHP-FPM 的通信配置

看 Nginx 配置里的 fastcgi_pass 对不对:

grep fastcgi_pass /etc/nginx/nginx.conf

常见的配置:

# 用 socket 文件
fastcgi_pass unix:/run/php-fpm/www.sock;

# 用 TCP 端口
fastcgi_pass 127.0.0.1:9000;

问题1:socket 文件路径不对

Nginx 配置里写的 socket 路径和 PHP-FPM 实际的不一致。

PHP-FPM 的 socket 路径在 /etc/php-fpm.d/www.conf 里:

grep listen /etc/php-fpm.d/www.conf

确保两边路径一致。

问题2:端口被占

如果用 9000 端口,检查一下是不是被别的进程占了:

lsof -i:9000

第三步:看错误日志

Nginx 错误日志:

tail -f /var/log/nginx/error.log

PHP-FPM 错误日志:

tail -f /var/log/php-fpm/error.log

PHP 慢日志:

tail -f /var/log/php-fpm/www-slow.log

根据日志里的报错信息找原因。

第四步:常见原因

原因1:PHP-FPM 进程数不够

访问量大的时候,PHP-FPM 进程都被占满了,新请求排队超时。

解决: 增加 PHP-FPM 进程数。

编辑 /etc/php-fpm.d/www.conf:

pm.max_children = 50
pm.start_servers = 20
pm.min_spare_servers = 10
pm.max_spare_servers = 30

改完重启:

systemctl restart php-fpm

原因2:PHP 脚本执行超时

PHP 脚本执行时间太长,超过了 Nginx 的超时时间。

解决: 调大超时时间。

Nginx 配置里:

fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;

PHP 配置里:

max_execution_time = 300

原因3:PHP 内存不足

PHP-FPM 进程内存溢出,导致进程崩溃。

解决: 调大 PHP 内存限制:

memory_limit = 256M

或者减少 PHP-FPM 进程数,避免内存不够。

原因4:文件权限不对

Nginx 运行的用户和 PHP-FPM 运行的用户不一致,导致 PHP-FPM 读不到文件。

解决: 确保 Nginx 和 PHP-FPM 用同一个用户(一般是 www)。

PHP-FPM 配置 /etc/php-fpm.d/www.conf:

user = www
group = www

然后把网站文件的属主改成 www:

chown -R www:www /var/www/html

第五步:重启所有服务

改完配置后重启:

systemctl restart php-fpm
systemctl restart nginx

常见坑

坑1:只重启了 Nginx

改了 PHP 配置但只重启了 Nginx,PHP-FPM 还是老配置。

解决: PHP 配置改了要重启 PHP-FPM,Nginx 配置改了要重启 Nginx。

坑2:socket 文件权限不对

PHP-FPM 的 socket 文件权限是 600,Nginx 用户读不到。

解决: 改 socket 文件权限:

listen.mode = 0666

或者改 socket 文件的属主:

listen.owner = www
listen.group = www

坑3:PHP-FPM 挂了但没自动重启

PHP-FPM 进程崩溃了,没人自动拉起来。

解决: 配置 systemd 自动重启:

systemctl edit php-fpm

加:

[Service]
Restart=always
RestartSec=2

总结

502 排查步骤:

  1. 先看 PHP-FPM 是不是挂了 → systemctl status php-fpm
  2. 再看 Nginx 配置对不对 → fastcgi_pass 路径/端口
  3. 看错误日志 → Nginx error.log + PHP-FPM error.log
  4. 常见原因 → 进程数不够、超时太短、权限不对、内存不足

记住:502 问题出在后端,不是 Nginx 的锅。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-6 08:06 

Linux查看系统运行级别,multi-user.target详解

前言

经常听到别人说"运行级别 3"、"运行级别 5",这是什么意思?CentOS7 之后用 systemd 代替了老的 SysVinit,运行级别也变成了 target。本文讲一下怎么查看和切换系统运行级别。

老的运行级别(SysVinit)

老系统(CentOS6 之前)用数字表示运行级别:

级别 含义
0 关机
1 单用户模式(救援模式)
2 多用户模式(无 NFS)
3 完全多用户模式(命令行,服务器常用)
4 未使用
5 图形界面模式
6 重启

新的 target(systemd)

CentOS7 之后用 target 代替了数字运行级别:

target 对应老级别 含义
poweroff.target 0 关机
rescue.target 1 救援模式
multi-user.target 3 命令行模式(服务器常用)
graphical.target 5 图形界面模式
reboot.target 6 重启

查看当前运行级别

systemctl 命令

systemctl get-default

输出:

multi-user.target

就是当前默认的运行级别是命令行模式。

老命令(还能用)

runlevel

输出类似:

N 3

第一个是上次运行级别(N 表示没有),第二个是当前运行级别。

切换运行级别

临时切换(重启后恢复)

systemctl isolate 目标target

比如从图形界面切到命令行:

systemctl isolate multi-user.target

或者从命令行切到图形界面:

systemctl isolate graphical.target

永久切换(重启后生效)

systemctl set-default 目标target

比如默认启动到命令行模式:

systemctl set-default multi-user.target

默认启动到图形界面:

systemctl set-default graphical.target

常用操作

进入救援模式

系统出问题了进不去?进救援模式:

systemctl rescue

进入紧急模式

更底层的救援模式:

systemctl emergency

关机

systemctl poweroff

或者:

systemctl halt

重启

systemctl reboot

常见坑

坑1:图形界面切命令行后黑屏

执行了 isolate multi-user.target,屏幕黑了。

原因: 这是正常的,切到命令行模式就是黑屏,只有终端提示符。

解决: 输入用户名密码登录就行。

坑2:设置了 multi-user.target 但还是进图形界面

执行了 set-default multi-user.target,但重启后还是进图形界面。

原因: 可能有多个桌面管理器在抢着启动。

解决: 确认一下:

systemctl get-default

应该显示 multi-user.target。如果不对,再执行一次。

坑3:把运行级别设成 0 或 6 了

不小心设成了 poweroff.target 或 reboot.target。

后果: 一开就关机或者一开就重启,无限循环。

解决: 进救援模式改回来。

总结

命令 作用
systemctl get-default 查看当前默认运行级别
systemctl set-default multi-user.target 设置为命令行模式
systemctl set-default graphical.target 设置为图形界面模式
systemctl isolate multi-user.target 临时切到命令行
systemctl isolate graphical.target 临时切到图形界面
runlevel 老命令查看运行级别

服务器一般用 multi-user.target(命令行模式),更省资源、更稳定。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-6 08:05 

CentOS7 安装图形界面,最小化安装升级

前言

很多人装 CentOS7 的时候选了最小化安装,后来发现想用图形界面怎么办?不用重装,直接在线装就行。本文讲一下怎么从命令行升级到带图形界面的版本。

先更新系统

装图形界面前先把系统更新一下:

yum update -y

安装 GNOME 桌面

方法一:安装 GNOME 桌面(推荐)

yum groupinstall -y "GNOME Desktop"

这个安装包比较大,大概几个 G,需要等一会儿。

方法二:安装带图形界面的服务器版

yum groupinstall -y "Server with GUI"

这个比 GNOME Desktop 多一些服务器相关的工具。

设置默认启动方式

查看当前默认启动方式

systemctl get-default

输出 multi-user.target 就是命令行模式,graphical.target 就是图形界面模式。

设置默认启动到图形界面

systemctl set-default graphical.target

设置默认启动到命令行

如果以后想改回命令行:

systemctl set-default multi-user.target

重启生效

reboot

重启之后就会进入图形界面了。

不重启直接进入图形界面

如果不想重启,可以直接启动图形界面:

startx

或者:

systemctl isolate graphical.target

常见坑

坑1:yum 安装报错

安装的时候报错,下载失败。

原因: yum 源没配好。

解决: 先换国内 yum 源(参考之前的 yum 源更换教程),然后再装。

坑2:安装完了还是命令行

装完重启后还是进命令行。

原因: 没设置默认启动方式。

解决:

systemctl set-default graphical.target
reboot

坑3:服务器装图形界面很卡

云服务器上装了图形界面之后特别卡。

原因: 图形界面占内存和 CPU 很多,云服务器配置一般不高。

建议: 生产服务器不要装图形界面,命令行更省资源。如果确实需要图形界面,用 VNC 或者远程桌面连。

坑4:安装包太大下载慢

几个 G 的包下载半天。

解决: 先换国内 yum 源,速度会快很多。

总结

步骤 命令
更新系统 yum update -y
安装 GNOME 桌面 yum groupinstall -y "GNOME Desktop"
设置默认图形界面 systemctl set-default graphical.target
重启 reboot

提醒: 生产服务器建议用命令行模式,更稳定、更省资源。图形界面只在测试或者个人电脑上用。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-6 08:03 

Linux查看端口被哪个进程占用,lsof命令

前言

启动服务的时候提示 "Address already in use",端口被占了,但不知道被哪个进程占了?这时候就需要用 lsof 或者 netstat 命令来查一下。本文讲一下怎么用。

lsof 命令

安装

CentOS 最小化安装可能没有 lsof:

yum install -y lsof

查看某个端口被哪个进程占用

lsof -i:端口号

比如看 80 端口被谁占了:

lsof -i:80

输出类似:

COMMAND  PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
nginx   1234  root    6u  IPv4  12345      0t0  TCP *:http (LISTEN)

重点看:

  • PID:进程号
  • COMMAND:进程名

知道了 PID 之后,想杀掉就用 kill PID。

查看所有正在监听的端口

lsof -i -P -n | grep LISTEN

输出所有处于监听状态的端口和对应的进程。

netstat 命令

安装

来自 net-tools 包:

yum install -y net-tools

查看端口被哪个进程占用

netstat -tlnp | grep 端口号

比如看 80 端口:

netstat -tlnp | grep :80

输出类似:

tcp   0   0 0.0.0.0:80   0.0.0.0:*   LISTEN   1234/nginx

最后一列就是 PID/进程名。

参数解释

参数 含义
-t 显示 TCP 连接
-l 只显示监听状态的
-n 显示数字,不解析域名
-p 显示进程名和 PID

查看所有监听端口

netstat -tlnp

fuser 命令

查看端口被哪个进程占用

fuser 端口号/tcp

比如:

fuser 80/tcp

输出:

80/tcp:              1234

直接显示 PID,简单粗暴。

杀掉占用端口的进程

fuser -k 80/tcp

直接把占用 80 端口的进程杀掉。

常见场景

场景1:启动 Nginx 提示端口被占

nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)

查一下:

lsof -i:80

发现是旧的 nginx 进程没杀掉,直接杀:

kill 1234

或者:

fuser -k 80/tcp

场景2:3306 端口不知道被谁占了

lsof -i:3306

发现是 MySQL 进程,正常的。

场景3:找出所有被占用的端口

netstat -tlnp

列出所有正在监听的端口。

常见坑

坑1:lsof 命令找不到

执行 lsof 提示 command not found。

原因: 没装 lsof 包。

解决:

yum install -y lsof

坑2:普通用户看不到其他用户的进程

用普通用户执行 lsof,看不到 root 的进程。

原因: 权限不够。

解决: 加 sudo 或者切 root:

sudo lsof -i:80

坑3:端口明明没被占但提示被占

服务明明没启动,但启动时提示端口被占。

原因: 可能有 TIME_WAIT 状态的连接还没释放。

解决: 等一会儿再试,或者改端口。

坑4:杀了进程端口还是没释放

杀掉进程了,但端口还是显示被占。

原因: 进程还在退出中,等几秒就好了。

总结

命令 作用
lsof -i:端口号 查看端口被哪个进程占用
netstat -tlnp \| grep :端口号 用 netstat 查端口
fuser 端口号/tcp 查看端口对应的 PID
fuser -k 端口号/tcp 杀掉占用端口的进程

最常用的就是 lsof -i:端口号,一眼就能看到进程名和 PID。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-6 08:02 

Linux上传下载文件,rz和sz命令使用

前言

经常需要从本地电脑上传文件到服务器,或者把服务器上的文件下载到本地。除了用 FTP 工具,还有更简单的 rz 和 sz 命令,直接在终端里就能操作。本文讲一下怎么用。

安装 lrzsz

rz 和 sz 命令来自 lrzsz 包,CentOS 最小化安装可能没有:

yum install -y lrzsz

Ubuntu 的话:

apt install -y lrzsz

rz 上传文件(从本地上传到服务器)

基本用法

直接输入:

rz

执行后会弹出一个文件选择窗口,选你要上传的文件,点确定就开始上传了。

注意: 文件会上传到你当前所在的目录。

指定文件名

上传后直接改成指定名字:

rz -y 新文件名

-y 是覆盖同名文件。

上传多个文件

执行 rz 之后在文件选择窗口可以按住 Ctrl 多选。

sz 下载文件(从服务器下载到本地)

下载单个文件

sz 文件名

比如下载 index.html:

sz index.html

执行后会弹出保存窗口,选保存位置就开始下载了。

下载多个文件

sz 文件1 文件2 文件3

比如:

sz a.txt b.txt c.txt

下载整个目录(先打包)

sz 不能直接下载目录,要先打包:

tar -zcvf backup.tar.gz /var/www/html
sz backup.tar.gz

常见使用场景

场景1:上传配置文件

# 先进入要上传的目录
cd /etc/nginx/conf.d/

# 上传
rz

选本地的 nginx 配置文件,上传完就直接放到这个目录了。

场景2:下载日志文件

# 进入日志目录
cd /var/log/nginx/

# 下载访问日志
sz access.log

场景3:上传压缩包

本地把项目打包成 zip,然后:

cd /var/www/html/
rz

选本地的项目 zip 文件,上传完再解压。

常见坑

坑1:rz 命令找不到

执行 rz 提示 command not found。

原因: 没装 lrzsz 包。

解决:

yum install -y lrzsz

坑2:上传的文件不知道去哪了

执行了 rz,但不知道文件上传到哪了。

原因: 文件上传到你当前所在的目录。

解决: 上传前先 pwd 看一下当前目录在哪。

坑3:用了某些 SSH 工具不支持 rz/sz

有些 SSH 客户端(比如 Windows 自带的 cmd)不支持 rz/sz。

原因: rz/sz 需要终端支持 ZModem 协议。

解决: 用支持的 SSH 工具,比如 Xshell、SecureCRT、FinalShell、MobaXterm。

坑4:大文件上传慢

上传几百 M 的文件特别慢。

原因: rz/sz 走的是 SSH 通道,速度不快。

解决: 大文件用 SFTP 或者专门的传输工具(FileZilla)更快。

坑5:上传的文件是乱码

上传完中文文件名变成乱码。

原因: 编码问题。

解决: 用英文文件名,或者先打包成 zip 再上传。

总结

命令 作用
rz 从本地上传文件到服务器
sz 文件名 从服务器下载文件到本地

前提: 要先装 lrzsz 包,而且 SSH 工具要支持 ZModem 协议。

小文件用 rz/sz 很方便,大文件还是用 SFTP 吧。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-6 08:01 

CentOS7 关闭防火墙,永久关闭firewalld

前言

刚装好的 CentOS7 默认开了防火墙,很多端口都访问不了。有时候为了省事想直接关掉防火墙,本文讲一下怎么操作,以及临时关和永久关的区别。

查看防火墙状态

先看看防火墙现在是开还是关:

systemctl status firewalld

输出里有 active (running) 就是开着,inactive (dead) 就是关了。

或者用:

firewall-cmd --state

输出 running 就是开着,not running 就是关了。

临时关闭防火墙

只关掉当前运行状态,重启后又会自动开起来:

systemctl stop firewalld

永久关闭防火墙

永久关闭,重启后也不会再开:

systemctl stop firewalld
systemctl disable firewalld

两条命令一起执行,先停掉当前的,再禁止开机自启。

重新开启防火墙

如果以后又想开起来:

systemctl start firewalld
systemctl enable firewalld

验证是否关闭成功

执行完之后再看一下状态:

systemctl status firewalld

应该显示 inactive (dead)。

常见坑

坑1:只 stop 了但没 disable

执行了 systemctl stop firewalld,但重启后防火墙又自己开起来了。

原因: 只停了当前运行,没关开机自启。

解决: 还要执行 systemctl disable firewalld。

坑2:关了防火墙但还是访问不了

防火墙关了,但外部还是访问不了网站。

原因: 除了系统防火墙,云服务商还有一层安全组。

解决: 去云服务商控制台(阿里云、腾讯云、华为云等)的安全组里,把对应的端口也开放了。

坑3:Ubuntu 用的不是 firewalld

在 Ubuntu 上执行 firewalld 命令报错。

原因: Ubuntu 默认用 ufw 防火墙,不是 firewalld。

解决: Ubuntu 关防火墙用:

ufw stop
ufw disable

坑4:关闭防火墙不安全

直接关了防火墙,服务器暴露在公网上很危险。

建议: 生产环境不要直接关防火墙,而是只开放需要的端口。比如只开 80、443、22 端口,其他都关。

总结

操作 命令
查看防火墙状态 systemctl status firewalld
临时关闭 systemctl stop firewalld
永久关闭 systemctl stop firewalld && systemctl disable firewalld
开启防火墙 systemctl start firewalld
开机自启 systemctl enable firewalld

注意: 生产环境建议不要直接关防火墙,用开放指定端口的方式更安全。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-6 08:00 

Linux查看所有服务,systemctl命令大全

前言

CentOS7 之后用 systemctl 管理服务,代替了老的 service 和 chkconfig 命令。本文把常用的 systemctl 命令都整理出来,新手照着用就行。

查看服务

查看所有服务

systemctl list-units --type=service

列出所有正在运行的服务。

查看所有服务(包括没运行的)

systemctl list-unit-files --type=service

查看正在运行的服务

systemctl list-units --type=service --state=running

查看某个服务状态

systemctl status 服务名

比如看 nginx 状态:

systemctl status nginx

输出会显示服务是否在运行、PID、内存占用、最近日志等。

启动和停止服务

启动服务

systemctl start 服务名

比如:

systemctl start nginx

停止服务

systemctl stop 服务名

比如:

systemctl stop nginx

重启服务

systemctl restart 服务名

比如:

systemctl restart nginx

重载配置(不重启)

修改了配置文件后,用 reload 重载,不用重启:

systemctl reload 服务名

比如:

systemctl reload nginx

平滑重启(reload 不行就用这个)

systemctl reload-or-restart 服务名

设置开机自启

开启开机自启

systemctl enable 服务名

比如:

systemctl enable nginx

关闭开机自启

systemctl disable 服务名

比如:

systemctl disable nginx

查看是否开机自启

systemctl is-enabled 服务名

输出 enabled 就是开机自启,disabled 就是不是。

其他常用操作

查看服务是否在运行

systemctl is-active 服务名

输出 active 就是在运行,inactive 就是没运行。

查看服务日志

journalctl -u 服务名

比如看 nginx 日志:

journalctl -u nginx

实时看服务日志

journalctl -u 服务名 -f

和 tail -f 一样,实时输出最新日志。

查看服务开机自启状态

systemctl list-unit-files --type=service | grep enabled

列出所有开机自启的服务。

常见服务名

服务名 对应服务
nginx Nginx 网页服务
httpd Apache 网页服务
mysqld MySQL 数据库
firewalld 防火墙
crond 定时任务
sshd SSH 远程连接
php-fpm PHP 解析
redis Redis 缓存

常见坑

坑1:服务名写错了

执行 systemctl 报错 Unit xxx.service could not be found。

原因: 服务名写错了。

解决: 先列一下所有服务,找到正确的服务名:

systemctl list-unit-files --type=service | grep 关键词

坑2:启动了服务但还是访问不了

服务显示 active,但外部还是访问不了。

原因: 防火墙没开端口,或者服务本身配置错了。

解决: 先看防火墙开了没,再看服务日志:

journalctl -u 服务名

坑3:开机自启了但重启后没起来

设置了 enable,但重启后服务还是没启动。

原因: 服务配置有问题,启动失败了。

解决: 看日志找原因:

journalctl -u 服务名

坑4:用了老命令 service

执行 service nginx start 能用,但不推荐了。

原因: 这是老命令,新系统都用 systemctl。

解决: 换成 systemctl start nginx。

总结

操作 命令
查看所有服务 systemctl list-units --type=service
查看服务状态 systemctl status 服务名
启动服务 systemctl start 服务名
停止服务 systemctl stop 服务名
重启服务 systemctl restart 服务名
重载配置 systemctl reload 服务名
开机自启 systemctl enable 服务名
关闭开机自启 systemctl disable 服务名
查看日志 journalctl -u 服务名

systemctl 就这几个常用命令,记住就够用了。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-6 07:59 

Linux怎么修改主机名,永久生效方法

前言

新装好的服务器默认主机名是 localhost 或者一串乱七八糟的字符,不好区分。怎么改成自己想要的名字,而且重启后还生效?本文讲一下。

查看当前主机名

先看看现在主机名是什么:

hostname

输出类似:

localhost.localdomain

修改主机名的方法

方法一:hostnamectl(推荐,CentOS7+)

这是最方便的方法,一条命令永久生效:

hostnamectl set-hostname 新主机名

比如改成 web-server:

hostnamectl set-hostname web-server

注意: 主机名只能用小写字母、数字、横杠(-),不能用下划线、中文、空格。

方法二:修改配置文件

编辑 /etc/hostname 文件:

vi /etc/hostname

把里面的内容改成新的主机名,保存退出。

然后重启生效:

reboot

或者不重启,手动让它生效:

hostname 新主机名

方法三:临时修改

只改当前运行时的主机名,重启后就恢复:

hostname 新主机名

注意: 这个只是临时生效,重启后还是原来的。

修改后验证

重新登录一下 SSH,或者执行:

bash

让当前 shell 生效,然后看:

hostname

应该显示新的主机名了。

同时修改 hosts

有些服务(比如 MySQL)会用到主机名,最好同时把 /etc/hosts 也改一下:

vi /etc/hosts

找到类似这一行:

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4

在后面加上新主机名:

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4 web-server

保存退出。

常见坑

坑1:改了主机名但命令行没变

执行了 hostnamectl set-hostname,但命令行前面还是显示旧的。

原因: 当前 shell 会话没刷新。

解决: 退出重新登录 SSH,或者执行 bash 开个新 shell。

坑2:重启后又变回原来的

改了主机名,重启之后又变回去了。

原因: 只执行了 hostname 新名字(临时修改),没改配置文件。

解决: 用 hostnamectl set-hostname 新名字 永久修改。

坑3:主机名有大写或者下划线

主机名用了大写字母或者下划线,有些服务报错。

原因: 主机名规范要求只能用小写字母、数字、横杠。

正确写法: web-server-01
错误写法: Web_Server_01

坑4:改了主机名导致服务连不上

改了主机名之后,某些服务连不上数据库或者其他服务。

原因: 那些服务里配置的还是旧主机名。

解决: 把相关服务的配置里的主机名也改过来,或者同时改 /etc/hosts 做映射。

总结

方法 命令 是否永久
hostnamectl hostnamectl set-hostname 新名字 是(推荐)
修改 /etc/hostname 编辑文件后重启 是
hostname hostname 新名字 否(临时)

推荐用 hostnamectl set-hostname,一条命令搞定,永久生效。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-6 07:58 

Linux查看网卡信息,ip addr和ifconfig命令

前言

想知道服务器有几块网卡、IP 地址是多少、MAC 地址是多少?Linux 下有两个常用命令:ip addr 和 ifconfig。本文讲一下它们的用法和区别。

ip addr 命令(推荐)

现在新的 Linux 系统都推荐用 ip 命令,功能比 ifconfig 更强大。

查看所有网卡信息

ip addr

或者简写:

ip a

输出类似:

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:16:3e:12:34:56 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.100/24 brd 192.168.1.255 scope global eth0
       valid_lft forever preferred_lft forever

输出解释

字段 含义
lo 本地回环网卡
eth0 物理网卡名称
state UP 网卡状态是开启的
link/ether MAC 地址
inet IP 地址
/24 子网掩码(255.255.255.0)

只看 IP 地址

不想看那么多信息,只看 IP:

ip addr show eth0 | grep inet

或者更简洁:

ip a s eth0

只看 IPv4 地址

ip -4 addr

查看网卡统计信息

ip -s link

能看到收发包、丢包等统计信息。

ifconfig 命令(老命令)

ifconfig 是老命令,来自 net-tools 包,现在慢慢被淘汰了,但很多老用户还是习惯用。

安装

CentOS 最小化安装可能没有:

yum install -y net-tools

查看所有网卡

ifconfig

输出类似:

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.100  netmask 255.255.255.0  broadcast 192.168.1.255
        ether 00:16:3e:12:34:56  txqueuelen 1000  (Ethernet)
        RX packets 12345  bytes 1234567 (1.2 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 6789  bytes 987654 (987.6 KB)
        TX errors 0  dropped 0  overruns 0  carrier 0

只看某个网卡

ifconfig eth0

查看 lo 网卡

ifconfig 默认不显示 lo(回环网卡),要看的话加 -a:

ifconfig -a

ip 和 ifconfig 的区别

对比项 ip addr ifconfig
新老 新命令,推荐 老命令,逐步淘汰
包 iproute2 包(默认装) net-tools 包(要单独装)
功能 更强大 基本够用
输出 信息更全 简洁

其他常用命令

查看路由表

ip route

或者老命令:

route -n

查看 DNS 配置

cat /etc/resolv.conf

查看网卡连接状态

cat /sys/class/net/eth0/carrier

输出 1 表示网线插着,0 表示没插。

查看网卡速率

ethtool eth0 | grep Speed

常见坑

坑1:ifconfig 命令找不到

执行 ifconfig 提示 command not found。

原因: CentOS7 最小化安装不带 net-tools 包。

解决:

yum install -y net-tools

或者直接用 ip addr,不用装包。

坑2:网卡名不是 eth0

新系统网卡名可能是 ens33、ens33、enp0s3 之类的。

原因: CentOS7 用了新的网卡命名规则。

解决: 先 ip addr 看一下实际网卡名是什么,然后替换。

坑3:IP 地址不对

看到的 IP 地址和你预期的不一样。

原因: 可能有多个网卡,或者是云服务器的内网 IP,不是公网 IP。

解决: 先 ip addr 看所有网卡,确认哪个是你要的。

坑4:网卡 down 了

网卡状态是 DOWN,连不上网。

解决: 手动开启:

ip link set eth0 up

或者:

ifconfig eth0 up

总结

命令 作用
ip addr 查看所有网卡信息(推荐)
ip a 简写
ip a s eth0 只看 eth0 网卡
ifconfig 老命令查看网卡
ifconfig eth0 只看 eth0
ip route 查看路由表

现在都推荐用 ip addr,功能更全,还不用额外装包。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-6 07:54 

CentOS7 防火墙开放端口范围,一次性开放多个端口

前言

有时候需要一次性开放很多端口,或者开放一段端口范围,一个个加太麻烦。CentOS7 的 firewalld 支持开放端口范围,也支持一次性开放多个端口,本文讲一下怎么操作。

查看当前开放的端口

先看看现在防火墙开了哪些端口:

firewall-cmd --list-ports

输出类似:

80/tcp 443/tcp 8080/tcp

开放单个端口

永久开放

firewall-cmd --permanent --add-port=80/tcp

然后重载生效:

firewall-cmd --reload

开放 UDP 端口

把 tcp 改成 udp 就行:

firewall-cmd --permanent --add-port=53/udp
firewall-cmd --reload

一次性开放多个端口

方法一:一条命令加多个

firewall-cmd --permanent --add-port=80/tcp --add-port=443/tcp --add-port=8080/tcp
firewall-cmd --reload

多个 --add-port 用空格分开就行。

方法二:开放端口范围

如果要开放一段连续的端口,比如 8000 到 9000:

firewall-cmd --permanent --add-port=8000-9000/tcp
firewall-cmd --reload

这样 8000 到 9000 之间所有 TCP 端口都开放了。

方法三:同时开放 TCP 和 UDP

firewall-cmd --permanent --add-port=53/tcp --add-port=53/udp
firewall-cmd --reload

移除端口

移除单个端口

firewall-cmd --permanent --remove-port=8080/tcp
firewall-cmd --reload

移除端口范围

firewall-cmd --permanent --remove-port=8000-9000/tcp
firewall-cmd --reload

常见场景

场景1:开放 20 到 80 之间的所有端口

firewall-cmd --permanent --add-port=20-80/tcp
firewall-cmd --reload

场景2:同时开放 HTTP 和 HTTPS 服务

firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reload

场景3:只允许某个 IP 访问某个端口

这个更安全,只允许 192.168.1.100 访问 3306 端口:

firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='192.168.1.100' port protocol='tcp' port='3306' accept"
firewall-cmd --reload

常见坑

坑1:加了端口没生效

执行了 add-port 但还是访问不了。

原因: 没加 --permanent,或者没 reload。

解决: 一定要加 --permanent 参数,然后执行 firewall-cmd --reload。

坑2:端口范围写反了

写成了 9000-8000,报错。

原因: 范围必须从小到大写。

正确写法: 8000-9000/tcp
错误写法: 9000-8000/tcp

坑3:防火墙没启动

执行 firewall-cmd 报错。

原因: firewalld 服务没启动。

解决:

systemctl start firewalld
systemctl enable firewalld

坑4:开了端口但还是访问不了

防火墙开了端口,但是外部还是访问不了。

原因: 除了防火墙,还有可能是云服务商的安全组没开。

解决: 去云服务商控制台(阿里云、腾讯云等)的安全组里,把对应的端口也开放了。

总结

操作 命令
开放单个端口 firewall-cmd --permanent --add-port=80/tcp
开放多个端口 firewall-cmd --permanent --add-port=80/tcp --add-port=443/tcp
开放端口范围 firewall-cmd --permanent --add-port=8000-9000/tcp
移除端口 firewall-cmd --permanent --remove-port=8080/tcp
查看已开放端口 firewall-cmd --list-ports
重载生效 firewall-cmd --reload

记住:加完端口一定要 --reload 才生效。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-6 07:53 

Linux查看历史命令,history命令使用技巧

前言

在服务器上敲了很多命令,突然想找之前执行过的某条命令,怎么办?history 命令就能帮你查看历史命令。本文讲一下 history 的常用用法和技巧。

基本用法

查看历史命令

history

输出会列出你执行过的所有命令,每条前面有个编号,比如:

  100  yum install -y wget
  101  systemctl restart nginx
  102  df -h

执行第 N 条历史命令

用 !编号 直接执行:

!101

就会重新执行第 101 条命令。

执行上一条命令

几种方式都行:

!!

或者按向上方向键,再回车。

搜索历史命令

输入开头几个字母,然后按 Ctrl + R:

(reverse-i-search)`sys': systemctl restart nginx

会搜索你输入过的包含这个关键词的历史命令,找到之后回车执行。

再按一次 Ctrl + R 会继续往前找下一个匹配的。

常用技巧

只看最近 N 条

history 10

只看最近 10 条命令。

搜索历史命令里的关键词

history | grep 关键词

比如找所有包含 nginx 的命令:

history | grep nginx

执行最近一条以某个关键词开头的命令

!关键词

比如最近一条以 yum 开头的命令:

!yum

会直接执行最近一次输入的 yum 开头的命令。

替换上一条命令里的内容

比如上一条命令是 cp file1.txt file2.txt,想改成 mv file1.txt file2.txt:

^cp^mv

这样就把上一条命令里的 cp 替换成 mv 再执行。

清空历史命令

清空当前会话的历史

history -c

注意:这个只是清空当前内存里的历史,还没写入文件。

清空历史文件

history -w

把当前内存里的历史写入文件(覆盖掉旧的)。

彻底清空

history -c
history -w

两步一起执行,彻底清空所有历史命令。

删除某一条历史命令

history -d 编号

比如删除第 100 条:

history -d 100

历史命令保存在哪

历史命令默认保存在:

~/.bash_history

每个用户都有自己的 .bash_history 文件。

查看历史文件

cat ~/.bash_history

修改历史记录条数

默认记录 1000 条,可以改:

echo "HISTSIZE=10000" >> /etc/profile
echo "HISTFILESIZE=10000" >> /etc/profile
source /etc/profile

改成记录 10000 条。

常见坑

坑1:history 看不到刚执行的命令

刚执行完的命令,history 里没有。

原因: 历史命令是在退出会话的时候才写入文件的,当前会话的历史在内存里。

解决: 执行 history 就能看到当前会话的所有命令,包括刚执行的。

坑2:history -c 清不干净

执行了 history -c,但重新登录后又出来了。

原因: 只清了内存,没清文件。

解决: 还要执行 history -w 写入文件。

坑3:别人 history 能看到我输的密码

不小心在命令行里输了密码,比如 mysql -uroot -p123456,history 里就有了。

解决:

  1. 执行完之后赶紧删掉那条历史:history -d 编号
  2. 以后输密码不要直接写在命令里,用交互式输入:mysql -uroot -p,然后回车再输密码

坑4:多开几个终端,历史命令对不上

开了多个 SSH 窗口,在这个窗口执行的命令,另一个窗口 history 里看不到。

原因: 每个终端会话有自己的内存历史,退出时才写入文件。

解决: 这是正常现象,不用纠结。

总结

命令 作用
history 查看历史命令
history 10 只看最近 10 条
!101 执行第 101 条历史命令
!! 执行上一条命令
!yum 执行最近一条 yum 开头的命令
history \| grep nginx 搜索包含 nginx 的历史命令
history -c 清空当前会话历史
Ctrl + R 搜索历史命令

日常用得最多的就是 Ctrl + R 搜索 和 history | grep,效率很高。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-6 07:51 

Linux压缩解压命令大全,tar、zip、unzip用法

前言

服务器上经常需要压缩文件或者解压上传的压缩包,tar、zip、unzip 这些命令怎么用?本文把最常用的压缩解压命令都整理出来,一次讲清楚。

tar 命令(最常用)

tar 是 Linux 下最常用的打包压缩工具,支持 gzip、bzip2、xz 等多种压缩格式。

参数速记

参数 含义
-c 创建新的打包文件
-x 解压
-z 用 gzip 压缩(.tar.gz)
-j 用 bzip2 压缩(.tar.bz2)
-J 用 xz 压缩(.tar.xz)
-v 显示过程
-f 指定文件名(必须放最后)

压缩成 .tar.gz

最常用的,把目录打包成 tar.gz:

tar -zcvf 打包名.tar.gz 要打包的目录

比如把 /var/www/html 打包成 backup.tar.gz:

tar -zcvf backup.tar.gz /var/www/html

解压 .tar.gz

tar -zxvf 文件名.tar.gz

比如:

tar -zxvf backup.tar.gz

解压到指定目录

加 -C 参数:

tar -zxvf backup.tar.gz -C /目标目录

比如解压到 /tmp 目录:

tar -zxvf backup.tar.gz -C /tmp

只看不解压

tar -ztvf 文件名.tar.gz

列出压缩包里的文件列表,不解压。

.tar.bz2 格式

比 gzip 压缩率更高,但更慢:

# 压缩
tar -jcvf backup.tar.bz2 /var/www/html

# 解压
tar -jxvf backup.tar.bz2

.tar.xz 格式

压缩率最高,最慢:

# 压缩
tar -Jcvf backup.tar.xz /var/www/html

# 解压
tar -Jxvf backup.tar.xz

zip 和 unzip

安装

CentOS 最小化安装可能没有 zip/unzip:

yum install -y zip unzip

压缩成 zip

zip -r 打包名.zip 要打包的目录

比如:

zip -r backup.zip /var/www/html

-r 是递归,把目录下所有文件都打进去。

解压 zip

unzip 文件名.zip

比如:

unzip backup.zip

解压到指定目录

unzip 文件名.zip -d /目标目录

比如解压到 /tmp:

unzip backup.zip -d /tmp

只看不解压

unzip -l 文件名.zip

列出 zip 包里的文件列表。

解压到指定目录并覆盖

unzip -o 文件名.zip -d /目标目录

-o 是覆盖,不提示。

其他压缩格式

gz 格式(单文件压缩)

# 压缩
gzip 文件名

# 解压
gunzip 文件名.gz

bz2 格式

# 压缩
bzip2 文件名

# 解压
bunzip2 文件名.bz2

常见坑

坑1:解压后目录结构不对

解压完发现多套了一层目录。

原因: 打包的时候是带路径打的。

解决: 解压前先看一下压缩包里的结构:

tar -ztvf 文件名.tar.gz

或者 zip 用:

unzip -l 文件名.zip

坑2:解压时磁盘空间不足

解压到一半报错 No space left on device。

原因: 磁盘满了。

解决: 先看一下磁盘空间:

df -h

清理空间后再解压。

坑3:tar 参数顺序不对

执行 tar 报错。

原因: -f 参数必须放最后,后面紧跟文件名。

正确写法: tar -zcvf backup.tar.gz /目录
错误写法: tar -fzc backup.tar.gz /目录

坑4:zip 命令找不到

执行 zip 提示 command not found。

原因: 没装 zip 包。

解决:

yum install -y zip unzip

总结

格式 压缩命令 解压命令
.tar.gz tar -zcvf 名.tar.gz 目录 tar -zxvf 名.tar.gz
.tar.bz2 tar -jcvf 名.tar.bz2 目录 tar -jxvf 名.tar.bz2
.zip zip -r 名.zip 目录 unzip 名.zip
.gz gzip 文件名 gunzip 文件名.gz

最常用的就是 tar -zcvf 压缩 和 tar -zxvf 解压,记住这两个就够用了。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-6 07:50 

Linux查看系统启动时间,uptime命令详解

前言

想知道服务器从上次开机到现在跑了多久?或者想看系统负载?uptime 命令一行就能搞定。本文详细讲一下这个命令的用法。

uptime 命令

基本用法

直接输入:

uptime

输出类似:

 07:49:21 up  2:15,  1 user,  load average: 0.00, 0.01, 0.05

输出解释

字段 含义
07:49:21 当前系统时间
up 2:15 系统已经运行了 2 小时 15 分钟
1 user 当前有 1 个用户登录
load average: 0.00, 0.01, 0.05 1分钟、5分钟、15分钟的平均负载

常用参数

显示漂亮一点

uptime -p

输出类似:

up 2 hours, 15 minutes

显示系统启动时间

uptime -s

输出类似:

2026-10-06 05:34:21

这就是系统上次启动的具体时间。

查看系统启动时间的其他方法

who 命令

who -b

输出类似:

system boot  2026-10-06 05:34

last 命令

last reboot | head -5

列出最近几次重启记录:

reboot   system boot  3.10.0-1160.el7. Fri Oct  6 05:34 - 07:49  (02:15)
reboot   system boot  3.10.0-1160.el7. Thu Oct  5 09:12 - 22:00  (12:47)

systemd-analyze

systemd-analyze

显示系统启动花了多长时间:

Startup finished in 1.234s (kernel) + 2.345s (initrd) + 10.123s (userspace) = 13.702s

负载(load average)怎么看

uptime 最后三个数字是负载,很多人不知道怎么判断高不高。

三个数字的含义

  • 第一个:1 分钟平均负载
  • 第二个:5 分钟平均负载
  • 第三个:15 分钟平均负载

怎么判断高不高

负载和 CPU 核心数有关:

  • 负载 < CPU核心数:正常
  • 负载 ≈ CPU核心数:刚好饱和
  • 负载 > CPU核心数:过载了

查看 CPU 核心数

nproc

输出就是核心数。

比如你的服务器是 4 核 CPU:

  • 负载 1.0:很闲
  • 负载 4.0:刚好跑满
  • 负载 8.0:过载了

常见坑

坑1:负载高但 CPU 不高

负载很高,但 top 看 CPU 使用率不高。

原因: 可能是 I/O 等待高(磁盘读写慢),或者有大量进程在排队。

解决: 用 top 看 %wa 列(I/O 等待),如果高就是磁盘问题。

坑2:up 时间不对

uptime 显示的运行时间和你印象中的不一样。

原因: 系统可能自动重启过,或者你记错了。

解决: 用 last reboot 看历史重启记录。

坑3:1 user 不对

uptime 显示只有 1 个用户,但你明明看到好几个人登录。

原因: 显示的是登录会话数,不是用户数。同一个用户开多个 SSH 连接会算多个会话。

解决: 用 w 命令看详细的在线用户。

总结

命令 作用
uptime 看运行时间和负载
uptime -p 漂亮格式显示运行时间
uptime -s 显示系统启动时间
who -b 看系统启动时间
last reboot 看历史重启记录
nproc 看 CPU 核心数

日常运维用 uptime 一行就能看个大概,很方便。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-6 07:49