linux常用命令
LS -L的单位模式是字节,就是B
查看当前linux登录用户
[root@iZbp1ftp5sm9osyxgoq7qgZ etc]# who
root pts/0 2025-04-01 10:53 (49.90.24.53)
root pts/1 2025-04-01 12:04 (8.139.99.243)
root pts/2 2025-04-01 14:15 (49.90.73.122)
[root@iZbp1ftp5sm9osyxgoq7qgZ etc]# w
15:46:13 up 5:01, 7 users, load average: 0.00, 0.03, 0.05
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root pts/0 49.90.24.53 10:53 3:33m 0.16s 0.06s -bash
root pts/3 49.90.73.122 15:36 5.00s 0.03s 0.00s w
root pts/4 49.90.73.122 15:39 5:33 0.04s 0.01s ssh 120.26.49.197
[root@iZbp1ftp5sm9osyxgoq7qgZ etc]# users
root root root root root root root
内核
查看当前内核版本
[root@aliyunn home]# uname -a
Linux aliyunn 3.10.0-1160.119.1.el7.x86_64 #1 SMP Tue Jun 4 14:43:51 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
[root@aliyunn home]# cat /proc/version
Linux version 3.10.0-1160.119.1.el7.x86_64 (mockbuild@kbuilder.bsys.centos.org) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) ) #1 SMP Tue Jun 4 14:43:51 UTC 2024
#查看操作系统的发行版本信息
[root@aliyunnaliyunn yum.repos.d]# cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)
#还有可能是ubuntun的系统
cat /etc/os-release | which apt #这个也能判断这个系统
#这个文件里面可能显示有ubuntun的系统
| 操作系统版本 | 内核版本 | 发布时间 |
|---|---|---|
| CentOS 7.0 (1406) | 3.10.0-123 | 2014年 |
| CentOS 7.9 (2009) | 3.10.0-1160 | 2020年 |
| CentOS 7.9 + 更新 | 3.10.0-1160.119.1 | 2023年 |
操作系统的发行版本 ,反映用户空间工具链和软件包的版本。内核版本 ,决定硬件驱动和核心功能的支持情况。
1、操作系统发行版本:用户空间工具链和软件包的版本。
2、内核是操作系统的核心,直接与硬件交互,负责:
硬件驱动 :CPU、内存、硬盘、网卡、GPU 等硬件的驱动程序。
核心功能 :进程调度、内存管理、文件系统、网络协议栈、安全模块(如 SELinux)等。
内核版本决定了系统对硬件的支持程度和核心功能的特性。例如:
硬件兼容性 :较新的内核支持新硬件(如 NVMe SSD、Wi-Fi 6 网卡)。
功能增强 :新内核可能引入新特性(如 cgroups v2、eBPF)。
性能优化 :改进 I/O 调度、网络协议栈效率等。
查看可使用的内核(已安装的)
#在grub的配置文件里面查看菜单项
#sudo awk -F\' '/menuentry / {print $2}' /boot/grub2/grub.cfg
[root@aliyunnaliyunn ~]# awk -F\' '$1=="menuentry " {print i++ " : " $2}' /etc/grub2.cfg
0 : CentOS Linux (3.10.0-1160.119.1.el7.x86_64) 7 (Core)
1 : CentOS Linux (3.10.0-1160.el7.x86_64) 7 (Core)
2 : CentOS Linux (0-rescue-88b247814be64fbf8fa045566b89ce3e) 7 (Core)
查看当前默认内核启动项
[root@aliyunn modprobe.d]# grub2-editenv list
saved_entry=CentOS Linux (3.10.0-1160.119.1.el7.x86_64) 7 (Core)
[root@aliyunnaliyunn ~]# grub2-editenv list
saved_entry=1
[root@aliyunn modprobe.d]# uname -r
3.10.0-1160.119.1.el7.x86_64
#默认内核启动项就是当前内核版本,说明启动的时候没有动态修改
更改默认启动内核项
# 通过内核文件路径
sudo grub2 --set-default /boot/vmlinuz-3.10.0-1160.el7.x86_64
#通过索引
[root@aliyunnaliyunn ~]# grub2-set-default 0
[root@aliyunnaliyunn ~]# reboot
[root@aliyunnaliyunn ~]# uname -r
3.10.0-1160.el7.x86_64
#对比上面的uname,发现已经更改了
上面几个文件的关系
升级内核(有问题)
CentOS 7 的默认内核是 3.10.0 系列,但可以通过第三方仓库(如 ELRepo)升级到更高版本(如 5.4.163 或 5.15.8)。
启动流程
BIOS/UEFI 初始化
- 硬件自检(POST):检测 CPU、内存、存储设备等硬件状态。
- 引导设备选择:按预设顺序(如硬盘、U 盘、网络)查找可启动设备。
引导程序加载(GRUB)
-
BIOS 模式:从硬盘的 MBR(主引导记录) 加载 GRUB 第一阶段代码。
-
UEFI 模式:从 EFI 系统分区(ESP) 加载 GRUB 的 .efi 文件。
配置文件:/boot/grub2/grub.cfg(自动生成,不建议手动编辑)。
核心任务:
- 显示启动菜单(选择内核版本或恢复模式)。
- 加载内核文件(vmlinuz-<版本>)和初始内存盘(initramfs-<版本>.img)。
- 传递启动参数(如根文件系统位置 root=/dev/sda1)。
内核加载阶段
-
内核文件:/boot/vmlinuz-<版本>(压缩的内核镜像)。
-
initramfs 作用:
- 提供临时根文件系统,加载必要的硬件驱动(如磁盘控制器、文件系统驱动)。
- 挂载真正的根文件系统(/dev/sda1 或 LVM 卷)。
-
内核初始化流程:
-
解压自身并接管硬件控制权。
-
从 initramfs 加载驱动模块。
-
挂载根文件系统,定位真正的根设备 (/):根据 GRUB 传递的 root= 参数或探测设备。切换根文件系统 (Pivot Root):
/init 脚本将 /sysroot 挂载点切换为新的根目录 (chroot /sysroot)。
卸载旧的 initramfs 根文件系统,释放内存。
-
并切换到用户空间(/sbin/init 或 systemd)。
-
systemd 作为 PID 1 进程启动,是整个用户空间进程的父进程。它按依赖关系并行启动服务单元。
用户空间初始化阶段
systemd 自身初始化:
- 读取配置文件 (/etc/systemd/system.conf, /etc/systemd/user.conf)。
- 挂载核心虚拟文件系统 (/proc, /sys, /dev, /run)。
- 设置主机名、时区、Locale。
单用户直接进入root shell阶段了,没有后面的文件系统挂载。
使用场景:修复 /etc/fstab 错误【未挂载非root文件系统】、重置 root 密码【centOS7+如下】
- 使用 rd.break 中断 initramfs,直接进入 root shell(无需密码)。
- 使用 rescue.target 时,默认通过 sulogin --force 跳过密码验证。
解析默认目标 (default.target):
- default.target 是一个指向实际目标单元的符号链接(如 graphical.target 或 multi-user.target)。
启动基础目标 (sysinit.target, basic.target):
- sysinit.target: 启动系统初始化所需服务:
- 加载内核模块 (modprobe)。
- 设备管理 (udev): 检测硬件、创建设备节点 (/dev)、应用规则。
- 文件系统挂载 (local-fs.target): 挂载 /etc/fstab 中非根分区的文件系统。
- 文件系统检查 (fsck): 检查非根文件系统(根文件系统已在 initramfs 阶段检查)。
- 交换空间激活 (swap.target)。
- 随机数生成器初始化。
- basic.target: 提供基本系统环境(完成 sysinit.target 后启动):
- 套接字 (sockets.target)、基础硬件支持 (hardware.target)、时间同步 (time-sync.target) 就绪。
启动主目标 (multi-user.target 或 graphical.target):
- multi-user.target (多用户命令行):
- 启动网络服务 (network.target, network-online.target)。
- 启动登录管理器 (getty.target): 在 TTY 上启动 getty 登录提示。
- 启动非图形关键服务(SSH, cron, dbus, printing 等)。
- graphical.target (图形界面):
- 依赖并包含 multi-user.target。
- 启动显示管理器 (display-manager.service): GDM, SDDM, LightDM 等。
- 显示管理器启动 X11/Wayland 服务器和桌面环境会话。
启动用户会话:
- 用户在 TTY 或图形登录界面输入凭证。
- getty 或 Display Manager 启动用户登录 shell 或桌面会话管理器。
- 用户登录成功,进入交互式环境。
故障
- GRUB 阶段失败:菜单不显示、无法找到内核/initrd。检查 /boot/grub/grub.cfg,重新生成 (grub-mkconfig -o /boot/grub/grub.cfg),修复 GRUB 安装 (grub-install),检查分区/UEFI 设置。
- 内核/initramfs 加载失败:卡在 GRUB 后黑屏或报错。检查内核参数(root=, 文件系统类型),确保 vmlinuz 和 initramfs 文件存在且匹配,重建 initramfs (mkinitrd 或 update-initramfs -u)。
- initramfs 阶段失败:常见于驱动缺失(无法识别磁盘/LVM/加密卷)、fsck 失败、根设备找不到。查看内核启动信息,进入 initramfs shell 手动检查设备、模块、挂载。
- systemd 启动服务失败:卡在某个服务启动信息。使用 journalctl -b 查看启动日志,systemctl status
检查具体服务状态,systemctl isolate rescue.target 进入救援模式修复配置。
查看glibc版本
①
[root@kmissitdb05 etc]# ldd --version
ldd (GNU libc) 2.12
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.
②
[root@kmissitdb05 lib64]# ll /lib64 | grep libc
-rwxr-xr-x 1 root root 1926520 Feb 17 2016 libc-2.12.so
lrwxrwxrwx. 1 root root 18 May 5 2014 libcap-ng.so.0 -> libcap-ng.so.0.0.0
-rwxr-xr-x. 1 root root 18672 Nov 5 2010 libcap-ng.so.0.0.0
lrwxrwxrwx. 1 root root 14 May 5 2014 libcap.so.2 -> libcap.so.2.16
-rwxr-xr-x 1 root root 19016 Aug 23 2011 libcap.so.2.16
lrwxrwxrwx. 1 root root 19 May 5 2014 libcgroup.so.1 -> libcgroup.so.1.0.37
-rwxr-xr-x 1 root root 74048 Feb 23 2012 libcgroup.so.1.0.37
-rwxr-xr-x 1 root root 197064 Feb 17 2016 libcidn-2.12.so
lrwxrwxrwx 1 root root 15 Apr 15 2016 libcidn.so.1 -> libcidn-2.12.so
lrwxrwxrwx. 1 root root 17 May 5 2014 libcom_err.so.2 -> libcom_err.so.2.1
-rwxr-xr-x 1 root root 17256 Mar 6 2012 libcom_err.so.2.1
-rwxr-xr-x 1 root root 43392 Feb 17 2016 libcrypt-2.12.so
lrwxrwxrwx. 1 root root 22 May 5 2014 libcryptsetup.so.1 -> libcryptsetup.so.1.1.0
-rwxr-xr-x 1 root root 97072 Feb 29 2012 libcryptsetup.so.1.1.0
lrwxrwxrwx 1 root root 16 Apr 15 2016 libcrypt.so.1 -> libcrypt-2.12.so
lrwxrwxrwx 1 root root 12 Apr 15 2016 libc.so.6 -> libc-2.12.so
③
[root@kmissitdb05 lib64]# rpm -q glibc
glibc-2.12-1.166.el6_7.7.x86_64
glibc-2.12-1.166.el6_7.7.i686
DNS服务
查看本机的DNS服务器
[root@iZbp1ftp5sm9osyxgoq7qgZ ~]# cat /etc/resolv.conf
options timeout:2 attempts:3 rotate single-request-reopen
; generated by /usr/sbin/dhclient-script
nameserver 100.100.2.136 #nameserver行即当前使用的DNS服务器地址
nameserver 100.100.2.138
本地域名解析
当程序(如浏览器、SSH、Ping)需要将主机名转换为 IP 时,默认会先查询 /etc/host,再查询 DNS。
nslookup 和 dig 是直接查询 DNS 的工具,会绕过 hosts 文件。
修改此文件后无需重启系统,立即生效(但已缓存的程序可能需要重启)。
[root@aliyunn ~]# vi /etc/hosts
添加: 1.2.3.4 www.baidu.com
[root@aliyunn ~]# ping www.baidu.com
PING www.baidu.com (1.2.3.4) 56(84) bytes of data.
#ping不通,但是显示1.2.3.4.和hosts文件一致
验证DNS服务器
[root@localhost yum.repos.d] nslookup www.baidu.com #【dns地址】可以指定,就不去文件里面找dns服务地址了
Server: 192.168.78.2 # 当前使用的 DNS 服务器地址
Address: 192.168.78.2#53 # DNS 服务器地址和端口(53 是 DNS 服务默认端口)
Non-authoritative answer: # 非权威应答(应答内容来自缓存或递归查询,非权威服务器直接给出)
www.baidu.com canonical name = www.a.shifen.com. # CNAME 记录(别名指向)
Name: www.a.shifen.com # 规范名称(真实域名)
Address: 180.101.51.73 # IPv4 地址 1
Address: 180.101.49.44 # IPv4 地址 2
[root@localhost yum.repos.d] dig www.baidu.com
#没有预先安装这两个命令的
sudo yum install bind-utils
搭建DNS服务
将机器A的dns服务器的地址配置成机器B的IP地址,B所在的dns服务器如果没有配置权威区域zone,机器B就代替这个机器A去查询了,并将结果返回给A
DNS 递归解析流程(当 B 不是权威服务器时)
#安装DNS服务端
sudo apt install bind9 bind9utils
#配置为权威服务器
vi /etc/named.conf
option:全局配置
zone:区域文件
配置主从:
#主服务器
options {
directory "/var/named";
allow-transfer { 192.168.1.11; 192.168.1.12; }; //功能 :指定哪些 IP 地址或网段可以向当前 DNS 服务器请求区域传输。
notify yes; // 变更时通知从服务器
recursion no; // 关闭递归
};
zone "example.com" {
type master;
file "example.com.zone";
allow-update { none; };
};
#从服务器
zone "example.com" {
type slave;
file "slaves/example.com.zone";
masters { 192.168.1.10; }; // 指向主服务器
};
#配置keepalived。添加一个虚拟ip
内网DNS服务
内网权威的DNS服务器
# /etc/named.conf (BIND示例)
options {
# 关键1:彻底关闭递归(仅权威服务)
recursion no; # ⚠️ 禁用递归
allow-recursion { none; }; # 双重确认
# 关键2:仅允许内网客户端查询
allow-query { 192.168.37.0/24; }; # 限制内网访问
};
zone "example.com" {
type master;
file "/etc/bind/zones/example.com.zone"; #这个里面有记录
# 允许内网查询此区域
allow-query { 192.168.37.0/24; };
};
外网递归的DNS服务器
# /etc/named.conf
options {
# 仅提供递归服务(无权威区域)
recursion yes;
# 关键:仅允许内网客户端使用递归
allow-recursion { 192.168.37.0/24; };
# 禁止外部访问(可选)
listen-on { 192.168.37.100; }; # 只监听内网接口
};
内网权威DNS 仅 负责 *.example.com 解析,禁用递归功能(不查询外部)
外网递归DNS 仅 负责公网域名解析(如 google.com),不托管任何权威区域
客户端需配置 两个DNS服务器,但通过策略确保:
- 内网域名 → 强制指向内网权威DNS
- 外网域名 → 指向外网递归DNS
1、/etc/resolv.conf的配置:
# /etc/resolv.conf (Linux客户端)
# 优先级:先尝试内网DNS,若失败则用外网DNS(不完美)
nameserver 192.168.37.41 # 内网权威DNS
nameserver 192.168.37.100 # 外网递归DNS
当查询 public-site.com 时,会先询问 192.168.37.41(因无记录而超时),然后才用 192.168.37.100
2、DNSmasq智能分流
# 安装DNSmasq(轻量级DNS转发器)
sudo apt install dnsmasq
# /etc/dnsmasq.conf
# 指定内网域名走权威DNS
server=/example.com/192.168.37.41
# 其他所有域名走外网递归DNS
server=192.168.37.100
# 可选:禁止使用其他DNS
strict-order
#客户端:
$ nslookup db1.example.com # → 直连 192.168.37.41(无延迟)
$ nslookup github.com # → 直连 192.168.37.100(无内网查询)
查看路由表(网关)
[root@iZbp1ftp5sm9osyxgoq7qgZ ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 172.23.191.253 0.0.0.0 UG 0 0 0 eth0 #0000一般就是网关
169.254.0.0 0.0.0.0 255.255.0.0 U 1002 0 0 eth0
172.23.176.0 0.0.0.0 255.255.240.0 U 0 0 0 eth0
[root@iZbp1ftp5sm9osyxgoq7qgZ network-scripts]# ip route
default via 172.23.191.253 dev eth0 #via后面就是网关
169.254.0.0/16 dev eth0 scope link metric 1002
172.23.176.0/20 dev eth0 proto kernel scope link src 172.23.180.36
#ip 命令是 Linux 系统中用于全面管理网络栈的核心工具,它取代了传统的 ifconfig、route、arp 等多个独立命令,是iproute2软件包的一部分。
arp
arping -U -I $interface -s $vip $gw -c 5
-U:发送 Unsolicited ARP(主动宣告,非应答)。
-I $interface:指定发送 ARP 的网卡(如 eth0)。
-s $vip:设置 ARP 包的源 IP 为 VIP(如 192.168.1.100)。
$gw:目标 IP(通常是网关或广播地址 255.255.255.255)。
-c 5:发送 5 次 ARP 包。
通过 eth0 广播声明:“IP 地址 $vip 现在属于我的 MAC 地址”,强制刷新交换机/网关的 ARP 表。当 VIP 迁移到新节点时,立即通知网关更新 ARP 缓存,避免流量仍发往旧节点(减少脑裂问题)。
#当主节点故障时,备用节点执行以上命令,接管 VIP 并立即更新网关的 ARP 表,实现无缝切换。
arp协议
- ARP 请求(ARP Request):用于询问网络上的所有主机谁拥有特定的 IP 地址。
- ARP 响应(ARP Reply):用于回答 ARP 请求,提供对应 IP 地址的 MAC 地址。
网络发送包到最后网段后,需要通过MAC地址发送
1. ARP 请求和响应流程
ARP 请求:当主机 A 需要向主机 B 发送数据包时,它首先需要知道主机 B 的 MAC 地址。如果主机 A 的 ARP 缓存中没有主机 B 的 MAC 地址,它会广播一个 ARP 请求消息到整个本地网络。这个请求消息包含主机 A 的 IP 地址、主机 A 的 MAC 地址、以及主机 B 的 IP 地址。
ARP 响应:主机 B 收到 ARP 请求后,检查请求中的 IP 地址是否是自己的。如果是,它会生成一个 ARP 响应消息,包含主机 B 的 MAC 地址,并将这个响应发送回主机 A。主机 A 收到 ARP 响应后,将主机 B 的 MAC 地址存储到 ARP 缓存中,以便以后使用。
数据包发送:一旦主机 A 得到主机 B 的 MAC 地址,它就可以使用这个 MAC 地址将数据包发送到主机 B。
2. ARP 缓存
为了提高效率,主机会维护一个 ARP 缓存,用于存储 IP 地址和 MAC 地址的映射。ARP 缓存的条目通常有一个过期时间,以便在地址发生变化时能够及时更新。
ip命令
| 功能 | 传统命令 | ip 命令 | 优势 |
|---|---|---|---|
| 接口状态 | ifconfig | ip link | 支持更多设备类型 |
| IP 管理 | ifconfig | ip address | CIDR 表示法更精确 |
| 路由管理 | route | ip route | 支持策略路由 |
| ARP 管理 | arp | ip neigh | 更好的缓存控制 |
| 隧道管理 | iptunnel | ip tunnel | 统一配置接口 |
查看网卡--不一定能找到网关
#centOS通用,CentOS 7/8仍支持此方式,但需安装 network-scripts 包(CentOS 8 默认不安装)。
[root@iZbp1ftp5sm9osyxgoq7qgZ network-scripts] cat /etc/sysconfig/network-scripts/ifcfg-eth0 | grep GATEWAY
/etc/sysconfig/network-scripts/ifcfg-<网卡名>
第一张网卡:/etc/sysconfig/network-scripts/ifcfg-eth0
第二张网卡:/etc/sysconfig/network-scripts/ifcfg-ens33
#/etc/sysconfig/network文件定义全局默认值,network-scripts/ifcfg-eth0存放单个网络接口的详细配置,每个接口对应一个文件。
#CentOS7开始:默认使用 NetworkManager。CentOS8/9:强烈推荐此方式,传统 network-scripts 已被废弃。
配置文件路径
/etc/NetworkManager/system-connections/<连接名>.nmconnection
#如/etc/NetworkManager/system-connections/ens33.nmconnection
#命令行:nmcli, nmtui
#管理网卡
service network restart # CentOS 6
systemctl restart network # CentOS 7/8(需 network-scripts)
ethtool+网卡流程
ethtool - utility for controlling network drivers and hardware --工作在硬件和物理层
ifconfig和ip命令:数据链路层(L2)和网络层(L3)
- ifconfig 直接操作网络接口驱动(如 eth0 的驱动),这些驱动位于内核的 数据链路层。它通过 Linux 内核的 ioctl 系统调用与网络设备交互,因此能获取物理层/链路层状态(如接口启停、错误计数等)。
ethtool命令:物理层(L1)和数据链路层(L2)
- ethtool 直接操作网卡硬件寄存器(通过内核驱动),控制物理层参数(如速率、双工模式)和数据链路层特性(如校验卸载)。
网卡驱动:核心工作在 数据链路层(帧处理/DMA/中断),同时向下控制物理层(寄存器操作)、向上对接网络层(提供 net_device 接口)。
NIC(Network Interface Card) ,即 网络接口卡 ,是计算机或服务器用于连接网络的硬件设备。
收数据包的流程
- 网卡收到数据包。
- 将数据包从网卡硬件缓存转移到服务器内存中。
- 通知内核处理。
- 经过 TCP/IP 协议逐层处理。
- 应用程序通过 read() 从 socket buffer读取数据。
NIC和驱动交互
NIC 在接收到数据包之后,首先需要将数据同步到内核中,这中间的桥梁是 rx ring buffer。它是由 NIC 和驱动程序共享的一片区域,事实上,rx ring buffer 存储的并不是实际的 packet 数据,而是一个描述符,这个描述符指向了它真正的存储地址,具体流程如下:
- 驱动在内存中分配一片缓冲区用来接收数据包,叫做 sk_buffer;
- 将上述缓冲区的地址和大小(即接收描述符),加入到 rx ring buffer。描述符中的缓冲区地址是 DMA 使用的物理地址;
- 驱动通知网卡有一个新的描述符;
- 网卡从 rx ring buffer 中取出描述符,从而获知缓冲区的地址和大小;
- 网卡收到新的数据包;
- 网卡将新数据包通过 DMA 直接写到 sk_buffer 中。
当驱动处理速度跟不上网卡收包速度时,驱动来不及分配缓冲区,NIC 接收到的数据包无法及时写到 sk_buffer,就会产生堆积,当 NIC 内部缓冲区写满后,就会丢弃部分数据,引起丢包。这部分丢包为 rx_fifo_errors,在 /proc/net/dev 中体现为 fifo 字段增长,在 ifconfig 中体现为 overruns 指标增长。
驱动与 Linux 内核交互
数据包已经被转移到了 sk_buffer 中。前文提到,这是驱动程序在内存中分配的一片缓冲区,并且是通过 DMA 写入的,这种方式不依赖 CPU 直接将数据写到了内存中,意味着对内核来说,其实并不知道已经有新数据到了内存中。那么如何让内核知道有新数据进来了呢?答案就是中断,通过中断告诉内核有新数据进来了,并需要进行后续处理。
当 NIC 把数据包通过 DMA 复制到内核缓冲区 sk_buffer 后,NIC 立即发起一个硬件中断。CPU 接收后,首先进入上半部分,网卡中断对应的中断处理程序是网卡驱动程序的一部分,之后由它发起软中断,进入下半部分,开始消费 sk_buffer 中的数据,交给内核协议栈处理。
ifconfig命令
用ifconfig命令配置的网卡信息,在网卡重启后机器重启后,配置就不存在。要想将上述的配置信息永远的存的电脑里,那就要修改网卡的配置文件了。
#查看网卡信息
[root@aliyun network-scripts]# ifconfig eth0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
#UP(代表网卡开启状态)RUNNING(代表网卡的网线被接上)MTU:最大传输单元:1500字节。
inet 172.23.180.36 netmask 255.255.240.0 broadcast 172.23.191.255
inet6 fe80::216:3eff:fe2c:9448 prefixlen 64 scopeid 0x20<link>
ether 00:16:3e:2c:94:48 txqueuelen 1000 (Ethernet) #以太网
RX packets 467215 bytes 228400156 (217.8 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 294372 bytes 43738999 (41.7 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
#启停网卡
ifconfig eth0 up
ifconfig eth0 down
#配置ip地址
[root@localhost ~]# ifconfig eth0 192.168.2.10
[root@localhost ~]# ifconfig eth0 192.168.2.10 netmask 255.255.255.0
[root@localhost ~]# ifconfig eth0 192.168.2.10 netmask 255.255.255.0 broadcast 192.168.2.255
#修改mac地址
ifconfig eth0 hw ether 00:AA:BB:CC:dd:EE
#启停arp协议
ifconfig eth0 arp #开启网卡eth0 的arp协议
ifconfig eth0 -arp #关闭网卡eth0 的arp协议
#添加ip
ifconfig eth0 add 192.168.1.100 netmask 255.255.255.255
ip addr add ip地址/32 dev eth0 #(更推荐的方式)
丢包排查
物理上排查:
(1) 查看工作模式是否正常
[root@localhost ~]# ethtool eth0 | egrep 'Speed|Duplex'
Speed: 1000Mb/s
Duplex: Full
(2) 查看检验是否正常
[root@localhost ~]# ethtool -S eth0 | grep crc
rx_crc_errors: 0
Speed,Duplex,CRC 之类的都没问题,基本可以排除物理层面的干扰。
包错误
1、RX dropped(接收丢包)
表示数据包已进入网卡的 Ring Buffer(环形缓冲区) ,但在拷贝到内存时因系统资源不足被丢弃。
原因:
- 内存不足 :系统内存不足,无法分配 skb(socket buffer)缓存。
- 队列满 :内核协议栈处理速度跟不上 Ring Buffer 数据流(如应用层未及时读取数据)。
解决:
-
调整 Ring Buffer 大小 通过ethtool -G 增大 Ring Buffer(需网卡支持):
sudo ethtool -G eth0 rx 4096 tx 4096 # 调整 RX/TX 队列大小 -
确保应用程序及时处理数据包(如调整 net.core.netdev_max_backlog 参数)
2、RX overruns(FIFO 溢出)
表示网卡硬件 FIFO 缓冲区溢出,数据包在进入 Ring Buffer 前被丢弃。
原因:
- 流量突增 :瞬时流量超过网卡硬件缓冲区容量。
- CPU 中断处理瓶颈 :CPU 无法及时处理网卡中断(如所有中断集中在单核)。
- 中断合并(Interrupt Coalescing)未启用 :频繁中断导致 CPU 过载。
解决:
-
检查中断分布,确认网卡中断是否均匀分配到多核:
cat /proc/interrupts | grep eth0若所有中断集中在 core0,需配置 IRQ 亲和性(见下一段)。
-
启用中断合并 :通过 ethtool -C启用中断合并(降低中断频率):
sudo ethtool -C eth0 rx-usecs 100 rx-frames 5 # 每 100 微秒或 5 个包触发一次中断
Smart NIC
为适应高速网络,现代网卡中普遍卸载了部分 L3-L4 层的处理逻辑(e.g. 校验和计算、传输层分片重组等),来减轻 Host CPU 的处理负担。甚至有些网卡(e.g. RDMA 网卡)还将整个 L4 层的处理都卸载到硬件上,以完全解放 Host CPU。得益于这些硬件卸载技术,Host OS 的网络协议栈处理才能与现有的高速网络相匹配。
统网卡的工作模式 :
传统网卡(硬件)仅负责物理层(L1)和数据链路层(L2)的基础功能。所有L3(网络层/IP)和L4(传输层/TCP/UDP)的处理都需要CPU通过软件协议栈完成。
例如:每个数据包的校验和验证、TCP分片重组、分段重组都要消耗CPU周期
现代网卡:
增加了专用处理单元(ASIC/FPGA/可编程逻辑),将原本需要CPU处理的协议栈功能前移到网卡硬件。这就像给网卡增加了"协处理器",形成分布式处理架构。
传统模式:数据→网卡→CPU→内存→应用
RDMA模式:数据→网卡→直接写入内存(绕过CPU)实现真正的"零拷贝"和"零CPU占用"-----上面得就是,直接通知cpu来个硬中断就可以了。
典型卸载功能
TSO(TCP Segmentation Offload):是一种利用网卡对大数据包进行分片,从而减小 CPU 负荷的一种技术。
LRO(Large Receive Offload):将网卡接收到的多个数据包合并成一个大的数据包,然后再传递给网络协议栈处理的技术。这样提系统接收数据包的能力,减轻 CPU 负载。
亲和性
在多核 CPU 的服务器上,合理地利用每个 CPU 核心能大幅提升性能。如果你的应用程序支持多线程,可以通过调整任务的 CPU 亲和性(CPU affinity)来将不同的进程分配给不同的核心,避免 CPU 资源的浪费。
# 使用 taskset 将进程绑定到指定的 CPU 核心
taskset -c 0,1 my_process # 绑定进程到 0 号和 1 号核心
通过这种方式,你能够更好地利用多核 CPU 的计算能力,提高并发处理能力。特别是对于一些计算密集型任务,合理的 CPU 亲和性设置可以大幅提高执行效率。
cpu中断相关的
#示例输出 :
#/proc/interrupts,它实时记录了系统中所有中断(Interrupts)的详细统计信息。
[root@aliyun network-scripts]# cat /proc/interrupts
27: 340013 0 PCI-MSI-edge virtio2-input.0
28: 1 263139 PCI-MSI-edge virtio2-output.0
字段解释 :
27:中断号。
340013:CPU0 上该中断的总触发次数。
0:CPU1 上该中断的触发次数。
PCI-MSI-edge:中断类型(如 MSI 是消息信号中断)。
virtio2-input.0:关联的硬件设备(如网卡)。
#/proc/irq
提供每个中断号的详细配置和统计信息 ,是按中断号分目录的结构化数据。路径格式:/proc/irq/<irq_num>/,如 /proc/irq/27/。
#smp_affinity :设置中断绑定的 CPU 核心(即 中断亲和性 )。
示例:echo 3 > /proc/irq/27/smp_affinity 将中断 27 绑定到 CPU0 和 CPU1。
cpu进程相关的
taskset 是 Linux 中专门用于查看和设置进程 CPU 亲和性的工具。
#查看亲和性
1、taskset -p <PID>
[root@kmissitdb05 network-scripts]# taskset -p 10068
pid 10068's current affinity mask: 3
2、每个进程的亲和性信息存储在 /proc/<PID>/status 文件中。
cat /proc/<PID>/status | grep Cpus_allowed
Cpus_allowed: f
Cpus_allowed_list: 0-3
#Cpus_allowed:十六进制掩码(如 f 表示允许 CPU0-3)。
#Cpus_allowed_list:直观的 CPU 列表(如 0-3)。
cpu内存相关的
NUMA由来
NUMA(Non-Uniform Memory Access),即非一致性内存访问,是一种关于多个CPU如何访问内存的架构模型,早期,在计算机系统中,CPU是这样访问内存的:
在这种架构中,所有的CPU都是通过一条总线来访问内存,我们把这种架构叫做SMP架构(Symmetric Multi-Processor),也就是对称多处理器结构。可以看出来,SMP架构有下面4个特点:
- CPU和CPU以及CPU和内存都是通过一条总线连接起来
- CPU都是平等的,没有主从关系
- 所有的硬件资源都是共享的,即每个CPU都能访问到任何内存、外设等
- 内存是统一结构和统一寻址的(UMA, Uniform Memory Architecture)
SMP架构在CPU核不多的情况下,问题不明显,有实验证明,SMP服务器CPU利用率最好的情况是2至4个CPU:
但是随着CPU多核技术的发展,一颗物理CPU中集成了越来越多的core,导致SMP架构的性能瓶颈越来越明显,因为所有的处理器都通过一条总线连接起来,因此随着处理器的增加,系统总线成为了系统瓶颈,另外,处理器和内存之间的通信延迟也较大。
为了解决SMP架构下不断增多的CPU Core导致的性能问题,NUMA架构应运而生,NUMA调整了CPU和内存的布局和访问关系,具体示意如下图:
在NUMA架构中,将CPU划分到多个NUMA Node中,每个Node有自己独立的内存空间和PCIE总线系统。各个CPU间通过QPI总线进行互通。
CPU访问不同类型节点内存的速度是不相同的,访问本地节点的速度最快,访问远端节点的速度最慢,即访问速度与节点的距离有关,距离越远访,问速度越慢,所以叫做非一致性内存访问,这个访问内存的距离我们称作Node Distance。
虽然NUMA很好的解决了SMP架构下CPU大量扩展带来的性能问题,但是其自身也存在着不足,当Node节点本地内存不足时,需要跨节点访问内存,节点间的访问速度慢,从而也会带来性能的下降。所以我们在编写应用程序时,要充分利用NUMA系统的这个特点,尽量的减少不同CPU模块之间的交互,避免远程访问资源,如果应用程序能有方法固定在一个CPU模块里,那么应用的性能将会有很大的提升。
NUMA架构下的CPU和内存分布
在Linux系统上,可以查看到NUMA架构下CPU和内存的分布情况,不过在这之前,我们先得理清几个概念:
- Socket:表示一颗物理 CPU 的封装(物理 CPU 插槽),简称插槽。为了避免将逻辑处理器和物理处理器混淆,Intel 将物理处理器称为插槽,Socket表示可以看得到的真实的CPU核 。
- Core:物理 CPU 封装内的独立的一组程序执行的硬件单元,比如寄存器,计算单元等,Core表示的是在同一个物理核内逻辑层面的核。同一个物理CPU的多个Core,有自己独立的L1和L2 Cache,共享L3 Cache。
- Thread:使用超线程技术虚拟出来的逻辑 Core,需要 CPU 支持。为了便于区分,逻辑 Core 一般被写作 Processor。在具有 Intel 超线程技术的处理器上,每个内核可以具有两个逻辑处理器,这两个逻辑处理器共享大多数内核资源(如内存缓存和功能单元)。此类逻辑处理器通常称为 Thread 。超线程可以在一个逻辑核等待指令执行的间隔(等待从cache或内存中获取下一条指令),把时间片分配到另一个逻辑核。高速在这两个逻辑核之间切换,让应用程序感知不到这个间隔,误认为自己是独占了一个核。对于每个逻辑线程,拥有完整独立的寄存器集合和本地中断逻辑,共享执行单元和一二三级Cache,超线程技术可以带来20%~30%的性能提升。
- Node:即NUMA Node,包含有若干个 CPU Core 的组。一般一个槽对应一个node节点,可以通过lscpu查看出来。
numactl命令
numactl --hardware(numactl -H)
available: 1 nodes (0)
node 0 cpus: 0 1
node 0 size: 1756 MB
node 0 free: 147 MB
node distances:
node 0
0: 10
这个主机上面的node节点只有一个,不太容易得到真实的架构
node distances:
node 0 1 2 3
0: 10 20 30 40
1: 20 10 50 60
2: 30 50 10 70
3: 40 60 70 10
可以得到如下图
+----------------+ +----------------+
| Node 0 | | Node 1 |
| CPUs: 0-3 |<----->| CPUs: 4-7 |
| Mem: 32GB | 20 | Mem: 32GB |
+----------------+ +----------------+
| 30 | 50
v v
+----------------+ +----------------+
| Node 2 | | Node 3 |
| CPUs: 8-11 |<----->| CPUs: 12-15 |
| Mem: 32GB | 70 | Mem: 32GB |
+----------------+ +----------------+
其中访问本地内存的延迟为10,数值代表访问延时
numactl --cpunodebind=0 --membind=1 myprogram
分开指定cpu和内存
- 高 CPU 密集型任务:绑定 CPU 到特定节点(--cpunodebind)。
- 高内存带宽需求任务:绑定内存到特定节点(--membind)。
numactl --cpunodebind=0,1 --membind=0 myprogram:绑定两个cpu
服务监听
[root@aliyun]# netstat -utlnp ss -tulnp
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
udp 0 0 0.0.0.0:712 0.0.0.0:* 545/rpcbind
udp 0 0 0.0.0.0:68 0.0.0.0:* 795/dhclient
udp 0 0 0.0.0.0:111 0.0.0.0:* 545/rpcbind
udp 0 0 127.0.0.1:323 0.0.0.0:* 24809/chronyd
- -u :仅显示 UDP 协议的连接(TCP 连接不显示)。
- -t: tcp
- -l :显示 监听状态 (LISTEN)的套接字(即正在等待连接的服务)。
- -n :以 数字形式 显示地址和端口(不解析为域名或服务名称)。
- -p :显示 关联进程的 PID 和名称 (需 root 权限)
UDP 服务不显示 LISTEN 状态 是正常现象,因为 UDP 是无连接协议。所以state状态列(对于 UDP,通常为空;对于 TCP,可能是LISTEN、ESTABLISHED等)。
Recv-Q:接收队列中未被应用程序处理的字节数。不是网卡的,这个是内核中的协议栈里面的。表示 已到达本机并由内核接收 ,但 尚未被应用程序读取 的数据量(单位:字节)。
# 查看接收缓冲区最大值(Recv-Q)
sysctl net.core.rmem_max
# 查看发送缓冲区最大值(Send-Q)
sysctl net.core.wmem_max
Local Address:
0.0.0.0 :表示服务监听 所有网络接口 (即任何 IP 地址都可以访问该服务)
127.0.0.1:表示服务仅监听 本地回环接口 (只能通过本机访问,外部无法访问)。
具体 IP 地址 :服务绑定到特定网卡的 IP(如 192.168.1.100:80)。仅允许内网访问。
Foreign Address:显示与本地服务或连接 通信的远程 IP 地址和端口 。
对于TCP 服务(如 0.0.0.0:22)显示为 0.0.0.0:*,因为尚未有客户端连接。
对于 UDP 服务(如 0.0.0.0:68),始终显示为 0.0.0.0:*,因为 UDP 是无连接协议。
192.168.1.5:12345 表示客户端 IP 为 192.168.1.5,使用端口 12345 连接到本地服务。
查看开启的端口
netstat 获取监听连接 → grep 过滤 LISTEN → awk 取地址列 → awk 拆分出端口 → 排序去重
netstat -lntp 2>/dev/null | grep LISTEN | awk '{print $4}' | awk -F':' '{print $NF}' | sort | uniq
ss -lntp | grep LISTEN | awk '{print $4}' | awk -F':' '{print $NF}' | sort | uniq
测试服务连通性
telnet
命令格式:telnet ip port
指定 TCP 端口是否开放和可达,测试 SMTP、HTTP 等网络服务的连通性。仅能测试tcp的端口
工作原理是:尝试与目标 IP 的指定端口建立 TCP 三次握手(SYN → SYN-ACK → ACK)
| 连接状态 | 显示信息 | 含义 |
|---|---|---|
| 端口开放 | Connected to 192.168.1.100... | TCP 连接成功建立,端口可用 |
| 端口关闭 | Connection refused | 目标主机拒绝连接(无服务监听或防火墙拒绝) |
| 网络不通 | Connection timed out | 网络路径不通(防火墙阻断、路由问题或主机宕机) |
| 域名解析失败 | Unknown host | DNS 无法解析主机名 |
| 协议不支持 | 显示乱码或异常响应 | 端口开放但协议不匹配(如用 Telnet 连 HTTPS 端口) |
缺点:不适用 UDP/加密协议测试
nc
命令格式:nc [选项] [主机名] [端口号],命令比较强大端口扫描之类的
$nc -z -v -n 192.168.1.1 21-25
z 参数告诉netcat使用0 IO,连接成功后立即关闭连接, 不进行数据交换.
v 参数指详细输出.
n 参数告诉netcat 不要使用DNS反向查询IP地址的域名.
以上命令会打印21到25 所有开放的端口。
tcpdump抓包
tcpdump -i eth0 src host 1.2.3.4 and src port 8080 -c 30:捕获源IP地址为1.2.3.4,并且源端口为8080的数据包30个,且数据源来自eth0.
tcpdump host 192.168.1.113:使用host指定需要监听的主机。
查看/修改主机名
使用 hostnamectl修改后,部分服务可能需要重启或用户重新登录才能识别新主机名。
#查看hostname
[root@iZbp1ftp5sm9osyxgoq7qgZ home]# cat /etc/host #和/etc/hosts文件区分
cat: /etc/host: No such file or directory
[root@iZbp1ftp5sm9osyxgoq7qgZ home]# cat /etc/hostname
iZbp1ftp5sm9osyxgoq7qgZ
[root@iZbp1ftp5sm9osyxgoq7qgZ home]# hostname
iZbp1ftp5sm9osyxgoq7qgZ
#修改hostname
[root@aliyun home]# vim /etc/hostname #重启生效
[root@aliyun home]# bash
[root@aliyun home]# bash
[root@aliyun home]# hostnamectl set-hostname aliyunn #立即生效
[root@aliyun home]# bash
[root@aliyunn home]#
shell配置文件
| ①登录交互式:需要用户登录 | ③非登录交互式:不需要用户登录认证即可启动的 Shell |
|---|---|
| ②登录非交互:需要用户登录, | ④非登录非交互:再非登录交互式的基础上,不接受用户输入【脚本】 |
①③是常见的,一个是通过用户登录,然后进入shell等待用户输入。一个是不用用户登录
非交互是基本上是脚本,登录非交互就是强制脚本在登录模式下运行。
0、bash_profile:登陆时加载环境变量
1、bashrc:定义别名、函数、交互式 Shell 的终端行为(如 PS1 提示符)。交互功能(别名、提示符、补全)
→ 放入 ~/.bashrc(交互式Shell加载)所以登录交互式也会调用这个文件。
2、BASH_ENV 文件(如 ~/.bash_env):专门为非交互式 Shell 定制的配置(如脚本所需变量)。
配置文件加载规则
| Shell类型 | 加载的配置文件 | 典型场景 |
|---|---|---|
| 登录交互式 | 1. /etc/profile 2. ~/.bash_profile → ~/.bash_login → ~/.profile 3. ~/.bashrc(通过调用) |
SSH登录、su -、控制台启动 |
| 登录非交互式 | 1. /etc/profile 2. ~/.bash_profile → ~/.bash_login → ~/.profile |
ssh user@host 'command' |
| 非登录交互式 | 1. /etc/bash.bashrc 2. ~/.bashrc |
终端新标签页、GUI终端 |
| 非登录非交互式 | 1. $BASH_ENV指向的文件(如有设置) 2. 不加载任何配置文件(默认) |
执行脚本 bash script.sh |
时间
linux时间:
CST(中国标准时间):也称为北京时间。在时区划分上,属于东八区,即比UTC时间早8小时,标记为UTC+8。
default_time_zone = '+8:00'
#mysql配置文件中的时间。
UTC(世界协调时间):它是一种基于原子时的时间标准,UTC是国际时间标准,不受任何单一国家控制。
系统时钟存储的是 UTC 时间: 无论用户所在的时区是什么,Linux 内核维护的系统时钟 (System Clock) 始终存储的是 Coordinated Universal Time。这是一个全球统一的时间标准,没有夏令时 (DST) 变化。
时区定义文件: 时区信息存储在 /usr/share/zoneinfo/ 目录下的一系列二进制文件中(如 Asia/Shanghai, America/New_York)。这些文件包含了该时区相对于 UTC 的标准偏移量以及夏令时 (DST) 转换规则(起始/结束日期和时间,以及转换时的偏移量变化)。
本地时间: 用户和大多数应用程序看到的时间(例如 date 命令的输出,桌面环境显示的时间,文件时间戳的 ls -l 显示)是 本地时间。这是根据系统时钟 (UTC) 和当前生效的时区规则计算出来的。
[root@aliyun ~]# file /etc/localtime
/etc/localtime: symbolic link to ../usr/share/zoneinfo/Asia/Shanghai'
系统时钟存储的是UTC时间戳,时区转换是应用层按需进行的。
[ 硬件时钟 (RTC) ] (通常存储 UTC)
^
| (hwclock --systohc / -w) [NTP/关机时]
| 写入精确UTC
|
v (hwclock --hctosys / -s) [系统启动时]
[ 系统时钟 (Kernel) ] <------------> [ NTP 守护进程 ]
| (存储和维护 UTC) (同步上游 UTC)
|
| (gettimeofday(), clock_gettime())
v
[ 用户空间应用程序 ] [ 时区规则文件 ]
| (需要本地时间) (/etc/localtime -> /usr/share/zoneinfo/...)
|--------------------------------------> (读取)
|
v (localtime(), strftime())
[ 本地时间显示/使用 ]
NTP (ntpd/chronyd):同步上游服务器的 UTC 时间。校正本地 UTC 系统时钟(通过 slew 或 step)。可选地将校正后的 UTC 系统时钟写回硬件时钟 (hwclock --systohc)。完全不涉及时区计算。 NTP 只关心精确的 UTC。
ntp服务,默认只会同步系统时间。如果想要让ntp同时同步硬件时间,可以设置/etc/sysconfig/ntpd文件,在/etc/sysconfig/ntpd文件中,添加【SYNC_HWCLOCK=yes】这样,就可以让硬件时间与系统时间一起同步。
linux系统时间
inux中有两个时钟系统,分别是系统时间和硬件时间
date可以打印/设定系统时间.
打印系统时间时,date命令会通过调用clock_gettime函数获取时间,同时会通过localtime文件(时区文件)计算出本地的时间.
设定系统时间时,date命令会通过读取localtime文件(时区文件)确定本地的时区,再调用clock_settime函数计算出本地的时间.
hwclock可以打印/设定硬件时钟
硬件时钟 (RTC) :是一个物理硬件芯片,由主板上的CMOS电池供电。
hwclock --show,它读取的是RTC芯片当前寄存器的值,就是系统启动时RTC的初始时间(假设启动后RTC没被手动改过)加上这段时间RTC自身漂移累积的量。
hwclock --systohc,定时写回硬件
补偿RTC漂移: 将准确的UTC“刻录”到RTC上,覆盖掉它这段时间积累的漂移误差。
为下次启动提供更好的初始值,从RTC读出来的初始时间会更接近真实的UTC。
写回方式:①ntp中配置定时任务 ②系统关机时自动执行 ③手动执行sudo hwclock --systohc
date, hwclock 与 NTP
系统启动 (Boot):
- BIOS/UEFI 加载内核。
- 内核初始化。
- hwclock --hctosys 被执行 (通常由 init 脚本/systemd 服务调用):
- 读取 硬件时钟 (RTC) 时间 (例如 2023-10-27 08:00:00,可能误差较大)。
- 立即设置系统时钟 (System Clock) 为这个时间。此时 date 命令显示的就是这个不太准的时间。
- 系统继续启动,启动各种服务。
- NTP 守护进程 (ntpd 或 chronyd) 启动:
- 连接到配置的上游时间服务器。
- 发现系统时钟 (2023-10-27 08:00:00) 与网络时间 (2023-10-27 08:00:15 UTC) 有 15 秒的偏移。
- 关键动作 (NTP 的核心): NTP 不会立即用 date -s 或 hwclock --hctosys 跳跃式地校正 15 秒!这样做会破坏依赖时间的应用。
- NTP 的校正方式:
- 缓慢调整 (slew): 通过 adjtimex() 系统调用,细微地调整内核时钟的 频率 (tick rate)。例如,让系统时钟稍微走快或走慢一点(可能是百万分之几秒的调整)。这样,系统时钟会 逐渐地、平滑地 追上那 15 秒的差距。这个过程可能需要几分钟甚至几十分钟,但对系统运行是透明的、无冲击的。date 命令显示的时间会平滑地接近正确时间。
- 大偏移校正 (step): 如果初始偏移量非常大(例如超过 1000 秒),NTP 守护进程可能会选择在启动时进行一次跳跃式校正(settimeofday),因为缓慢调整耗时太长且不现实。之后再进行缓慢调整。这取决于守护进程的配置 (-x 选项或 makestep 指令 in chrony)。
系统运行中 (Runtime):
- NTP 守护进程持续运行:
- 监控与上游服务器的连接和偏移。
- 持续进行缓慢的频率调整 (slew),以补偿本地时钟的固有漂移(走得快/慢)和网络延迟带来的微小偏移。
- 保持系统时钟 (System Clock) 高度精确 (通常误差在毫秒级或更好)。此时 date 命令显示的是经过 NTP 精确同步后的时间。
- date 命令:读取的是经过 NTP 校正后的精确系统时钟。
- hwclock --show:读取的是物理 RTC 芯片的时间,它仍然保持启动时的那个不太准的时间 (2023-10-27 08:00:00),或者上次被更新时的时间。NTP 的缓慢调整 (slew) 只影响系统时钟,不会实时更新硬件时钟! 硬件时钟的值在此期间保持不变(除了它自身的微小漂移)。
系统关闭 (Shutdown) / 定期更新 (Optional):
- 关键协同点 (hwclock --systohc):
- 为了让硬件时钟在下次启动时能提供一个更好的初始时间,NTP 守护进程或者系统关机脚本通常会执行 hwclock --systohc。
- 这个命令将当前精确的系统时钟 (System Clock) 的值写入到硬件时钟 (RTC)。
- 效果: 硬件时钟被更新为与 NTP 同步后的精确时间 (例如 2023-10-27 08:45:30 UTC)。这样,下次系统启动执行 hwclock --hctosys 时,初始化的系统时间就会非常接近正确时间,NTP 只需要进行微小的调整 (slew) 即可。
- 谁触发 --systohc?
- NTP 守护进程配置: ntpd 通常有 -s (systohc) 或 -l (lockopt) 选项,或者通过 ntp.conf 中的 rtcsync 指令(对于某些系统/驱动)来安排定期(如每 11 分钟尝试一次,或成功同步后)执行 hwclock --systohc。chronyd 可以通过 rtcsync 指令启用类似功能(通常每小时同步一次)。
- 系统关机脚本: 很多发行版在关机或重启的脚本中会执行 hwclock --systohc,确保关机前将精确的系统时间保存到 RTC。
- 手动执行: 管理员也可以在确认时间准确后手动执行 sudo hwclock --systohc。
在虚拟化环境中情况更复杂。虚拟机通常没有物理RTC,而是由hypervisor模拟。这时硬件时钟实际是保存在宿主机的内存或文件里,漂移特性可能不同。不过基础原则不变:仍然需要定期将系统时钟同步给虚拟硬件时钟。
时间同步
ntp服务
ntpd不仅仅是时间同步服务器,它还可以做客户端与标准时间服务器进行同步时间,而且是平滑同步,并非ntpdate立即同步,在生产环境中慎用ntpdate,两者不可同时运行。
当作为服务端时,NTPd 会响应其他客户端(如局域网内的设备)的时间请求。当作为客户端时,NTPd 会向配置中的上层时间服务器(如 pool.ntp.org 或其他 NTP 服务器)发起时间同步请求。
NTPD在和时间服务器的同步过程中,会把BIOS计时器的振荡频率偏差——或者说Local Clock的自然漂移(drift)——记录下来。这样即使网络有问题,本机仍然能维持一个相当精确的走时。
# 客户端角色:指定上游时间服务器
server 0.pool.ntp.org iburst
server 1.pool.ntp.org iburst
# 服务端角色:允许局域网内其他设备同步本机时间
restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap
tpdate:手动同步(慎用):适合临时性修复场景。
安装并执行:
# Redhat/CentOS
yum install ntpdate
# Ubuntu/Debian
sudo apt install ntpdate
# 域名方式同步
ntpdate ntp.internal.company.com
# IP地址方式
ntpdate 10.0.0.2
#配置文件
cat /etc/ntp.conf
server 0.rhel.pool.ntp.org
server 1.rhel.pool.ntp.org
server 2.rhel.pool.ntp.org
[root@kmissitdb05 ~]# ntpdate -q 0.rhel.pool.ntp.org
server 46.76.211.157, stratum 0, offset 0.000000, delay 0.00000
server 194.182.121.14, stratum 0, offset 0.000000, delay 0.00000
server 85.55.73.43, stratum 0, offset 0.000000, delay 0.00000
server 120.29.183.184, stratum 0, offset 0.000000, delay 0.00000
5 Jun 15:38:04 ntpdate[21304]: no server suitable for synchronization found
- 优点:使用简单
- 缺点:只同步一次,不会自动保持同步
ntp配置文件
cat /etc/ntp.conf
driftfile /var/lib/ntp/drift
pidfile /var/run/ntpd.pid
logfile /var/log/ntp.log
# Access Control Support
restrict default kod nomodify notrap nopeer noquery
restrict -6 default kod nomodify notrap nopeer noquery
restrict 127.0.0.1
restrict 192.168.0.0 mask 255.255.0.0 nomodify notrap nopeer noquery
restrict 172.16.0.0 mask 255.240.0.0 nomodify notrap nopeer noquery
restrict 100.64.0.0 mask 255.192.0.0 nomodify notrap nopeer noquery
# local clock
server 127.127.1.0
fudge 127.127.1.0 stratum 10
restrict ntp.aliyun.com nomodify notrap nopeer noquery
restrict ntp.cloud.aliyuncs.com nomodify notrap nopeer noquery
restrict ntp1.aliyun.com nomodify notrap nopeer noquery
server ntp.aliyun.com iburst minpoll 4 maxpoll 10
server ntp.cloud.aliyuncs.com iburst minpoll 4 maxpoll 10
server ntp1.aliyun.com iburst minpoll 4 maxpoll 10
- restrict开头的标识:限制哪些客户端可以访问本地 NTP 服务,防止滥用。
- server开头标识:指定外部 NTP 服务器进行时间同步
- 本地时钟:配置本地时钟作为备选时间源,优先级较低。作为ntp服务不可用时的备选。
restrict中的字段
noquery:禁止客户端通过 NTP 查询命令(如 ntpq、ntpdate、ntpdc)获取服务器的状态信息或时间数据 ,如果服务器配置了 noquery,客户端执行 ntpq -c host ntp-server 会失败。
nomodify:禁止客户端修改 NTP 服务器的配置或运行参数 (如动态调整服务器列表、频率补偿值等)。客户端通过 ntpdc 发送的修改请求会被拒绝。
nopeer:禁止客户端与服务器建立对等(peer)模式的连接 (即客户端不能作为对端服务器与服务器交互)。
notrap:禁用 NTP 的 trap 子协议 (即客户端不能注册异步告警事件)。防止客户端通过 trap 协议向服务器发送大量无意义的事件请求,消耗服务器资源。避免利用 trap 协议发起拒绝服务(DoS)攻击。
kod(Kiss-o'-Death):当客户端的请求被拒绝时,服务器发送 Kiss-o'-Death(KoD)包通知客户端原因 。
未指定限制参数 :默认情况下,restrict 不带任何参数时,表示允许该地址完全访问 NTP 服务 (即没有 noquery、nomodify 等限制)。
ntpdc
可以查看 NTP 服务器/客户端的连接状态、配置参数、延迟、偏移等信息。支持动态调整配置(如启用/禁用对端服务器)。
chronyd:持续同步
从 7版本起推荐使用 chrony 取代 ntpd,适用于长期运行的生产服务器。
优点:持续后台同步、精度高、资源占用低
配置步骤:
# 安装并启动chrony服务
yum install chrony
systemctl enable --now chronyd
# 编辑配置文件
vim /etc/chrony.conf
# 替换为阿里云 NTP
server ntp.aliyun.com iburst
# 注意:有些版本配置中server改为了pool
# 重启服务
systemctl restart chronyd
# 查看状态
chronyc tracking
chronyc sources
状态显示
Chrony 有两个核心组件:
chronyd 守护进程,主要用于调整内核中运行的系统时间和时间服务器同步。它确定计算机增减时间的比率,并对此进行调整补偿。类似于ntpd
客户端配置:
server pool.ntp.org iburst # 作为客户端同步外部时间源服务端配置:
allow 192.168.1.0/24 # 允许局域网客户端同步 local stratum 10 # 作为本地时间源(stratum 层级
chronyc 是 chrony 套件的命令行接口,允许用户与运行中的 chronyd 服务进行交互,例如进行配置更改、获取状态报告等,类似于 ntpq 用于 ntpd。
[root@iZbp1ftp5sm9osyxgoq7qgZ ~]# chronyc tracking #显示当前时间同步状态
Reference ID : 64643D58 (100.100.61.88) # 当前同步的NTP服务器
Stratum : 2 # 时间层级(值越小越接近原子钟),这个是自身所在层级
Ref time (UTC) : Tue Jun 03 06:08:01 2025 # 最后一次成功同步的UTC时间
System time : 0.000158132 seconds slow of NTP time # 系统时钟落后NTP的时间
Last offset : -0.000169316 seconds # 最后一次时钟调整的偏移量
RMS offset : 0.000169316 seconds # 长期平均偏移量
Frequency : 43.523 ppm slow # 系统时钟的自然漂移速度(负值表示时钟走得慢)
Residual freq : +5.961 ppm # 未补偿的时钟漂移
Skew : 0.007 ppm # 频率误差的估计值
Root delay : 0.002172367 seconds # 到根时间服务器的总延迟
Root dispersion : 0.010318740 seconds # 最大时间误差估计
Update interval : 1.3 seconds # 两次同步的时间间隔
Leap status : Normal # 闰秒状态(Normal=无闰秒调整)
System time: 0.000158132 slow:系统时钟比 NTP 时间 慢 0.158 毫秒(极佳状态,误差 <1ms)
Stratum: 2:时间源层级为 2(直接连接 Stratum 1 原子钟源)
Frequency: 43.523 ppm slow:系统时钟每天慢 43.523 × 0.0864 ≈ 3.76 秒(需 Chrony 持续校准)
[root@iZbp1ftp5sm9osyxgoq7qgZ ~]# chronyc sources #显示所有时间源状态
210 Number of sources = 9
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
^* 100.100.61.88 1 4 17 12 +66us[ -103us] +/- 11ms
^+ 203.107.6.88 2 4 17 13 -2835us[-3004us] +/- 18ms
^+ 121.199.69.55 2 4 17 12 +413us[ +243us] +/- 15ms
^+ 100.100.3.1 2 4 17 13 -17us[ -187us] +/- 2756us
^+ 100.100.3.2 2 4 17 13 +361us[+4972us] +/- 2906us
^- 100.100.3.3 2 4 65 8 +487us[ +487us] +/- 2713us
^+ 100.100.5.1 2 4 17 13 +445us[ +275us] +/- 25ms
^+ 100.100.5.2 2 4 17 13 +2036us[+1867us] +/- 24ms
^- 100.100.5.3 2 4 17 12 -2086us[-2086us] +/- 27ms
MS 源状态标记:
*=当前同步源
+=候选源
-=不可用源
Name/IP 时间源地址
Stratum 时间源层级(1=最高),这个是同步的时间机器所在的层级
阿里云数据中心部署 原子钟集群(铷/铯原子钟) + 卫星授时(GPS/北斗)
Poll 轮询间隔(2^n秒,4=16秒)
Reach 最近8次查询的成功率(八进制,17=二进制001111=最近4/8次成功)
LastRx 上次收到响应时间(秒)
Last sample 时间偏移量:[原始值] +/- 误差范围(示例:+66微秒 ±11毫秒)
可实现方式
没有运行ntpd服务,通过定时任务来实现时间同步。
[root@dbchaospredb112 cron.hourly]# crontab -l
*/20 * * * * /usr/sbin/ntpdate 10.242.39.22 1>/dev/null 2>/dev/null
#00 00 * * * /nmon/nmon_x86_rhel6 -f -N -m /nmon -s 60 -c 1440 -y
0 18 * * * /usr/sbin/logrotate /etc/logrotate.d/syslog
#00 01 * * * find /opt/nmon /nmon -name *.nmon -atime +30 -exec rm {} \;
52 11 * * * sh /opt/CMDB_SERVER_INFO/start_cmdb_gather.sh 1>/dev/null 2>/dev/null
* * * * * /opt/promes/exporter/mysqld_exporter/mysqld_exporter-0.11.0.linux-amd64/check_alive.sh mysqld_exporter
* * * * * /opt/promes/exporter/node_exporter_p18/node_exporter-0.18.1.linux-amd64/check_alive.sh node_exporter
每20分钟同步一下时间
无法同步问题
- 确保 UDP 123 端口未被防火墙或安全组阻断
- DNS 解析正常(或直接使用 IP)
可以使用nslookup查看DNS解析是否正确
- 可使用以下命令测试 NTP 是否正常返回时间:
ntpdate -q ntp.internal.company.com
# 或者直接ping IP地址
#ntpdate 会通过 DNS 解析 ntp.internal.company.com 的 IP 地址。如果解析失败(如域名不存在或网络问题),命令会报错并终止。发送 NTP 查询请求:ntpdate 会向 ntp.internal.company.com 发送一个 NTP 查询数据包 (基于 UDP 协议,端口 123)。由于 -q 参数的存在,ntpdate 不会修改本地系统时间 ,仅输出查询结果。
[root@kmissitdb05 ~]# ntpdate -q 10.237.165.9
server 10.237.165.9, stratum 4, offset 0.001923, delay 0.02580
5 Jun 15:34:25 ntpdate[19534]: adjust time server 10.237.165.9 offset 0.001923 sec
定时任务
Cron的组成部分
- Cron守护进程:这是一个常驻后台的程序,负责定时检查、调度和执行crontab文件中指定的任务。
- Crontab文件:
- 用户级crontab:每个用户可以通过crontab -e命令编辑自己的任务计划。这些任务只对当前用户有效。【root用户切换别的用户,该用户执行crontab -e之后,就会在/var/spool/cron/下创建一个用户同名文件,打开就是定时任务】
- 系统级crontab:位于/etc/crontab,通常由系统管理员管理,可以执行系统级任务。
[root@dbchaospredb112 etc]# ll | grep cron
-rw-r--r--. 1 root root 541 Mar 4 2011 anacrontab
drwxr-xr-x. 2 root root 4096 May 5 2014 cron.d
drwxr-xr-x. 2 root root 4096 Mar 21 2024 cron.daily
-rw-r--r--. 1 root root 0 Mar 4 2011 cron.deny
drwxr-xr-x. 2 root root 4096 May 5 2014 cron.hourly
drwxr-xr-x. 2 root root 4096 May 5 2014 cron.monthly
-rw-r--r--. 1 root root 457 Jun 3 2011 crontab #用户级别的定时任务的增删改查
drwxr-xr-x. 2 root root 4096 Jun 3 2011 cron.weekly
#除了crontab,其他的不用管也不用动
定时任务写法:
#频率:
分钟、小时、日、月、星期几-------从小到大,除了周
* :表示任意值(即“每”)。
例如:* * * * * 表示 每分钟 执行。
*/n :表示步进(即“每隔 n”)。
例如:*/20 * * * * 表示 每 20 分钟 执行。
, :表示列表(多个值)。
例如:0,30 * * * * 表示 每小时的第 0 和 30 分钟 执行。
- :表示范围。
例如:0 8-18 * * * 表示 每天 8:00 到 18:00 每小时 执行。
哪一个带星号,就是每那个字段的。
#添加和查看
crontab -e #等同于vi /var/spool/cron/root
crontab -l #等同于cat /var/spool/cron/root
故障:
命令在shell中执行成功,但是在任务中执行失败,可能的原因就是,这个命令不在/bin和/usr/bin目录下
1、这种命令直接写绝对路径
2、定时任务运行脚本的时候,脚本开头重新设置环境变量。
#! /bin/bash
export PATH=/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin
#或者
export PATH=$PATH:/opt/au1200_rm/build_tools/bin #部分追加上
查看软件配置仓库
[root@iZbp1ftp5sm9osyxgoq7qgZ network-scripts]# ls /etc/yum.repos.d
CentOS-Base.repo epel.repo
[root@iZbp1ftp5sm9osyxgoq7qgZ yum.repos.d]# cat CentOS-Base.repo
[base]
name=CentOS-$releasever
enabled=1
failovermethod=priority
baseurl=http://mirrors.cloud.aliyuncs.com/centos/$releasever/os/$basearch/
gpgcheck=1
gpgkey=http://mirrors.cloud.aliyuncs.com/centos/RPM-GPG-KEY-CentOS-7
#查看可用的软件仓库
Repolist command-specific options:
--all show all repos
--enabled show enabled repos (default)
--disabled show disabled repos
REPOSITORY Repository specification
[admin@gtest ~]$ yum repolist --all
repo id repo name status
alinux3-module alinux3-module enabled
alinux3-module-debuginfo linux3-module-debuginfo disabled
alinux3-os alinux3-os enabled
alinux3-os-debuginfo alinux3-os-debuginfo disabled
alinux3-plus alinux3-plus enabled
配置软件仓库源
cp /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
下载新的 http://mirrors.aliyun.com/repo/Centos-7.repo,并命名为CentOS-Base.repo
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
或者
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
清除缓存
yum clean all # 清除系统所有的yum缓存
yum makecache # 生成yum缓存
#可以直接删除仓库文件的名字,不过需要清除缓存。
#yum配置文件
cat yum.conf
[main]
gpgcheck=1
installonly_limit=3
clean_requirements_on_remove=True
best=True
skip_if_unavailable=False
exclude=httpd nginx php mysql mairadb python-psutil python2-psutil
#在 yum.conf 中配置的 exclude 列表中的软件包,在任何 yum 操作中都会被排除
密钥
安装第三方仓库--mysql
MySQL 官方提供了仓库的 RPM 安装包,可以自动配置仓库信息和 GPG 密钥。
https://dev.mysql.com/downloads/repo/yum/下找机器架构类型
例如:
#下载软件仓库配置包:wget https://dev.mysql.com/get/mysql80-community-release-el7-11.noarch.rpm
noarch代表“no architecture”,即该RPM包不依赖特定的硬件架构,通常包含纯脚本、文档、配置文件或元数据。类似的还有zabbix也是这种第三方仓库。
#安装:sudo rpm -ivh mysql80-community-release-el7-11.noarch.rpm
#通过rpm -qi查看这个安装包
Package for installation of setup/configuration files required for
installation of MySQL packages by yum.
#通过rpm -ql查看
[admin@gtest yum.repos.d]$ rpm -ql https://dev.mysql.com/get/mysql80-community-release-el7-11.noarch.rpm
warning: https://dev.mysql.com/get/mysql80-community-release-el7-11.noarch.rpm: Header V4 RSA/SHA256 Signature, key ID 3a79bd29: NOKEY
/etc/pki/rpm-gpg/RPM-GPG-KEY-mysql
/etc/pki/rpm-gpg/RPM-GPG-KEY-mysql-2022
/etc/pki/rpm-gpg/RPM-GPG-KEY-mysql-2023
/etc/yum.repos.d/mysql-community-debuginfo.repo
/etc/yum.repos.d/mysql-community-source.repo
/etc/yum.repos.d/mysql-community.repo
#包含密钥文件和仓库文件
每个启用GPG验证的软件仓库都应该有一个对应的GPG密钥。
- MySQL仓库 → RPM-GPG-KEY-mysql
- EPEL仓库 → RPM-GPG-KEY-EPEL-8
- CentOS官方仓库 → RPM-GPG-KEY-CentOS-Official
GPG key at file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql (0x5072E1F5) is already installed The GPG keys listed for the "MySQL 8.0 Community Server" repository are already installed but they are not correct for this package.Check that the correct key URLs are configured for this repository.. Failing package is: mysql-community-client-8.0.42-1.el8.x86_64
系统已经安装了名为 RPM-GPG-KEY-mysql 的密钥文件,但这个密钥不适用于当前要安装的 MySQL 包 (mysql-community-client-8.0.42)。验证失败的软件包具体名称,系统当前使用的密钥文件路径。
报错原因:密钥存在但不正确。可能是官方更新了本地没更新
处理方法:
1、临时解决
①删除密钥:rpm -e
②导入新密钥:rpm --import
[admin@gtest etc]$ sudo rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql
[admin@gtest rpm-gpg]$ pwd
/etc/pki/rpm-gpg
[admin@gtest rpm-gpg]$ ll
total 32
-rw-r--r-- 1 root root 1627 Jun 10 2022 RPM-GPG-KEY-EPEL-8
-rw-r--r-- 1 root root 27824 Oct 4 2019 RPM-GPG-KEY-mysql
③验证新密钥可用性:rpm -Kv <package.rpm>
2、永久解决:修改为动态获取gpd
#我仓库指定获取验证文件的位置
[admin@gtest yum.repos.d]$ yum info mysql-community-client-8.0.42
#找到安装包提供仓库
[admin@gtest yum.repos.d]$ cat mysql-community.repo
[mysql80-community]
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql
#修改为动态获取
gpgkey=https://repo.mysql.com/RPM-GPG-KEY-mysql # 动态获取最新密钥
配置文件 yum.conf
metadata_expire=90m 的含义是:YUM 认为本地的元数据缓存会在 90 分钟后“过期”(expire),而不是“被删除”(delete)。
过期 (Expire): 当 YUM 执行操作(如 yum search, yum install, yum check-update)时,它会检查本地缓存的元数据是否已经超过了 90 分钟。
如果 没超过(<90m),YUM 就直接使用本地缓存,速度非常快。
如果 超过了(>90m),YUM 就会连接远程仓库服务器,下载最新的元数据来更新本地缓存,然后使用新的元数据进行操作。这个过程会比直接使用缓存慢一些。
删除 (Delete): 删除缓存的操作不会自动发生。这些元数据文件会一直物理存在于你的硬盘上,直到你手动运行 yum clean 命令 或者因为磁盘空间不足被系统清理。
cachedir=/var/cache/yum/$basearch/$releasever #缓存rpm包得位置
keepcache=0 #决定在软件包成功安装后,是否保留下载到缓存目录的 RPM 包。不保活缓存元数据。
logfile=/var/log/yum.log #指定 YUM 操作日志的存放路径。所有 YUM 的执行历史、安装/更新/删除的软件包记录都会写在这个文件里。
软件包相关命令
RPM命令
1、安装软件包
sudo rpm -ivh package.rpm
- -i:安装包
- -v:显示详细信息
- -h:显示安装进度条
2. 升级软件包
sudo rpm -Uvh package.rpm
- -U:升级包(如果未安装则安装)
3. 卸载软件包
sudo rpm -e package_name
- -e:卸载包
4. 查询已安装的包
rpm -qa | grep package_name
- -q:查询
- -a:所有已安装的包
5. 显示软件包详细信息
rpm -qi package_name
- -i:显示版本、依赖、安装路径等信息
6. 列出软件包中的文件
rpm -ql package_name
-l:列出该包安装的所有文件
7.查看文件属于哪个包
rpm -qf /path/to/file
8.查看包得依赖
rpm -qpR package_name
yum 命令
1. 安装软件包
sudo yum install package_name
- 对应 rpm -ivh :自动下载并安装包及其依赖。
2. 更新软件包
sudo yum update package_name
- 对应 rpm -Uvh :升级包及其依赖。
3. 卸载软件包
sudo yum remove package_name
- 对应 rpm -e :卸载包及其不再需要的依赖。
4. 列出所有已安装的包
yum list | grep package_name
- 查看安装软件包的安装仓库。
yum list installed
- 对应 rpm -qa :显示所有已安装的包。
yum list available:显示软件仓库中可安装但未安装的软件包。
yum list updates:显示可升级的已安装软件包(仓库中有新版本)。
5. 查询包是否安装
yum list installed package_name
- 对应 rpm -q :检查包是否安装。
6. 搜索软件包
yum search keyword
- 对应 rpm -qa | grep keyword :根据关键词搜索包。
7. 显示包的详细信息
yum info package_name
- 对应 rpm -qi :显示包的版本、依赖、仓库来源等。
8. 查看包包含哪些文件
yum provides package_name
- 对应 rpm -ql :列出包安装的文件。
服务管理
在 CentOS 7 及更新的版本中,系统采用了 systemd作为默认的初始化系统(替代传统的 SysVinit,CentOS 6/RHEL 6)
两个系统: SysVinit和systemd
#老版本:/etc/init.d/
(1)直接调用 /etc/init.d/ 下的脚本
/etc/init.d/<服务名> start # 启动服务
/etc/init.d/<服务名> stop # 停止服务
/etc/init.d/<服务名> restart # 重启服务
/etc/init.d/<服务名> status # 查看服务状态
(2)service 是对 /etc/init.d/ 脚本的封装
service <服务名> start # 启动服务
service <服务名> stop # 停止服务
service <服务名> restart # 重启服务
service <服务名> status # 查看状态
chkconfig <服务名> on/off #开机自启动
#新版本
/usr/lib/systemd/system/ # 系统默认安装的服务配置文件
/etc/systemd/system/ # 管理员自定义或覆盖的服务配置文件(优先级更高)
#命令
(1)启动/停止/重启服务
systemctl start <服务名> # 启动服务
systemctl stop <服务名> # 停止服务
systemctl restart <服务名> # 重启服务
systemctl reload <服务名> # 重新加载配置(不重启)
(2)启用/禁用开机自启
systemctl enable <服务名> # 启用开机自启
systemctl disable <服务名> # 禁用开机自启
(3)查看服务状态
systemctl status <服务名> # 查看服务详细状态
systemctl is-active <服务名> # 检查服务是否正在运行
#列出所有的unit-file
systemctl list-unit-files
自定义systemd的unit-file
[Unit]
Description=My Custom Application # 服务描述
After=network.target # 指定依赖(如网络就绪后启动)
[Service]
Type=simple # 服务类型simple(默认,直接运行主进程)、forking(后台守护进程)、notify(通知 systemd 启动完成)等。
User=myappuser # 以哪个用户身份运行
Group=myappgroup # 以哪个用户组身份运行
WorkingDirectory=/path/to/app # 工作目录
#WorkingDirectory 的作用:在服务启动时,自动为进程设定一个“默认路径”,所有相对路径都基于此路径解析。
ExecStart=/path/to/app/bin/myapp # 启动命令的绝对路径
Restart=on-failure # 失败时自动重启
Environment="KEY=value" # 设置环境变量
[Install]
WantedBy=multi-user.target # 设置开机启动的目标 类似于老版本的chkconfig
chkconfig
chkconfig 是 SysVinit 系统(传统 Linux 初始化系统)中用于管理服务启动项的工具。它通过 符号链接 将服务脚本(位于 /etc/init.d/)注册到不同的 运行级别(Runlevel) 中。
chkconfig 会修改 /etc/rc[0-6].d/ 目录下的符号链接,决定服务在对应运行级别是否自动启动。
chkconfig 在 systemd 系统中仅为兼容性保留:实际底层调用 systemctl。systemctl enable myapp.service将服务绑定到指定的目标(Target),实现开机自启
设置服务在不同运行级别(runlevel)下的启动状态
查看和管理服务的启动配置。
SysVinit 系统通过「运行级别」定义系统启动后的状态。以下是 CentOS 6 及更早版本的运行级别:
| 运行级别 | 描述 |
|---|---|
| 0 | 关机 |
| 1 | 单用户模式(维护模式) |
| 2 | 多用户模式(无网络) |
| 3 | 多用户模式(命令行) |
| 4 | 保留未使用 |
| 5 | 图形界面模式 |
| 6 | 重启 |
chkconfig 常用命令
# 查看指定服务的启动配置
chkconfig --list <服务名>
示例:chkconfig --list httpd
输出:httpd 0:off 1:off 2:on 3:on 4:on 5:on 6:off
2:on 表示在运行级别 2 下开机自启动,其他同理。
# 启用服务在默认运行级别(2,3,4,5)下开机自启动
chkconfig <服务名> on
# 禁用服务开机自启动
chkconfig <服务名> off
# 指定运行级别(例如仅在级别3和5启用)
chkconfig --level 35 <服务名> on
示例:
chkconfig httpd on # 启用 Apache 开机启动
chkconfig mysqld off # 禁用 MySQL 开机启动
#添加/删除服务到 chkconfig 管理
# 添加服务(需确保服务脚本在 /etc/init.d/ 下)
chkconfig --add <服务名>
# 删除服务
chkconfig --del <服务名>
示例:
chkconfig --add myapp # 添加自定义服务 myapp
chkconfig --del myapp # 删除 myapp
四、服务脚本的 chkconfig 配置
每个服务脚本(位于 /etc/init.d/)的头部注释中需要定义 chkconfig 参数,例如:
#!/bin/bash
# chkconfig: 2345 90 10
# description: My Custom Service
chkconfig: 2345 90 10
2345:服务在运行级别 2、3、4、5 下启用。
90:启动优先级(数值越小,启动越早)。
10:停止优先级(数值越小,停止越晚)。
description:服务的描述信息。
chkconfig --add myapp 后,系统会根据脚本中的配置,在 /etc/rc.d/rc[0-6].d/ 目录中生成符号链接,例如:
/etc/rc.d/rc3.d/S90myapp → 在运行级别 3 启动时,以优先级 90 启动服务。
/etc/rc.d/rc3.d/K10myapp → 在运行级别 3 停止时,以优先级 10 停止服务。
chkconfig添加服务
chkconfig --add 的操作
执行 chkconfig --add httpd 时:
解析元数据:
读取 /etc/init.d/httpd 中的 # chkconfig: 行,获取默认的运行级别和优先级。
生成符号链接:
在 /etc/rc*.d/ 目录中创建符合规则的符号链接:
启动链接:
在指定的运行级别目录(如 rc2.d、rc3.d 等)中创建以 S## 开头的链接,指向服务脚本。
示例:/etc/rc3.d/S90httpd -> /etc/init.d/httpd
S 表示 "Start",90 是启动优先级。
停止链接:
在未启用的运行级别目录中创建以 K## 开头的链接。
示例:/etc/rc1.d/K10httpd -> /etc/init.d/httpd
K 表示 "Kill",10 是停止优先级。
#在 Linux 系统中,目录名 rc2.d 中的 rc 是 "run commands" 的缩写,直译为“运行命令”。这一术语源自早期的 Unix 系统,用于表示系统在特定阶段(如启动或切换运行级别)需要执行的命令脚本。
------------
ls -l /etc/rc2.d/
输出示例:
lrwxrwxrwx 1 root root 20 Jan 01 00:00 S10network -> ../init.d/network
lrwxrwxrwx 1 root root 15 Jan 01 00:00 S90httpd -> ../init.d/httpd
lrwxrwxrwx 1 root root 13 Jan 01 00:00 K10iptables -> ../init.d/iptables
S10network:优先级为 10,启动网络服务。
S90httpd:优先级为 90,启动 Apache 服务。
K10iptables:优先级为 10,停止防火墙服务(如果从其他运行级别切换至此)。
rc目录
-
系统启动 → 执行 rc.sysinit(初始化系统)
-
根据 /etc/inittab 进入默认运行级别(如 3 或 5)
-
执行 rc 脚本 → 处理对应 rcN.d/ 目录:
-
按顺序执行所有 K* 脚本(停止不需要的服务)
-
按顺序执行所有 S* 脚本(启动需要的服务)
这两个都是符号链接到/etc/init.d目录下的文件
/etc/init.d是符号链接到/etc/rc.d/init目录下。
-
-
最后执行 rc.local(用户自定义命令)
chkconfig精准控制运行级别(如仅级别3启动),rc.local是全局执行(所有级别最后都会运行)这里面的内容。
新版本rc
systemd不再通过rc脚本和rcN.d目录来管理服务,而是通过单元文件。
- 每个target定义了一组需要启动的单元(服务、挂载点等)以及它们的依赖关系。
- 服务单元(.service)代替了init.d中的脚本。
- 在target中,服务是并行启动的(按照依赖关系),而不是按数字顺序串行。
1、直接通过systemd启动
2、/etc/systemd/system/default.target进入默认级别
检查 .wants 目录:
- 加载 /etc/systemd/system/multi-user.target.wants/ 中的服务:管理员自定义开机服务
- 加载 /usr/lib/systemd/system/multi-user.target.wants/ 中的服务:发行版默认开机服务
3、执行rc-local.service
sysconfig目录
用于存储系统和服务相关的配置文件
文件/目录路径 用途说明
/etc/sysconfig/network 全局网络配置,如主机名、网关、NIS 域名等。
/etc/sysconfig/selinux SELinux 模式配置(如 enforcing、permissive、disabled)。
/etc/sysconfig/network-scripts/ 网卡配置文件(如 ifcfg-eth0),定义 IP 地址、子网掩码、DNS 等。
/etc/sysconfig/firewalld Firewalld 守护进程配置,如默认区域、日志设置。
/etc/sysconfig/grub GRUB 引导加载器配置,用于生成 grub.cfg(如内核启动参数)。
/etc/sysconfig/httpd Apache 服务环境变量,如 OPTIONS 参数(传递给 httpd 进程)。
/etc/sysconfig/iptables-config IPTables 工具配置,定义规则保存路径、IPv6 支持等。
/etc/sysconfig/kernel 内核模块加载配置,控制启动时加载的模块。
系统级配置 :/etc/sysconfig/(Red Hat 系)或 /etc/default/(Debian 系)。
服务专属配置 :通常放在 /etc/
历史兼容性 :部分配置文件仍直接放在 /etc/(如 hosts, netconfig)。早期 Linux 系统没有 /etc/sysconfig/,许多配置直接存放在 /etc/下,后续版本为了兼容性保留了这一习惯。
service服务
在使用service 服务 start|stop|status命令的时候,如果不知道服务加不加d还是什么,可以到/etc/init.d/下找文件,就是启动脚本。
cat test
#!/bin/bash
case "$1" in
start)
echo "Starting..."
;;
stop)
echo "Stopping..."
;;
restart)
echo "Restarting..."
;;
status)
echo "Status..."
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
exit 1
;;
esac
有这个就是一个模型,直接可以使用service test status。
新老版本对比
老版本直接去/etc/init.d目录下去找。
新版本先去/etc/init.d目录下去找,找不到后,重定向到如下目录
Redirecting to /bin/systemctl status sshd.service
sysctl+systemctl
/etc/sysctl.conf
内核参数的静态配置文件,用于在系统启动时设置内核参数(如网络优化、内存管理、文件系统限制)。
/etc/sysctl.d/
内核参数的模块化配置文件目录,允许将配置分散到多个文件(如 10-network.conf、20-security.conf)。
优先级高于 sysctl.conf(同名参数以 sysctl.d 中的配置为准)。
避免直接修改 sysctl.conf,通过独立文件管理不同用途的配置。
/etc/systemd/system/
Systemd 服务管理器的核心配置目录,用于定义系统服务(.service)、挂载点(.mount)、定时任务(.timer)等。
systemctl 是 Systemd 的核心命令行工具,用于管理系统的 服务(services)、挂载点(mounts)、定时任务(timers) 等资源(统称为 单元,即 units)。
sysconfig 和 systemd 的关系
- sysconfig:
是传统服务的配置中心,存放环境变量和启动参数。 - systemd:
通过 .service 文件定义服务行为,并可通过 EnvironmentFile 指令加载 sysconfig 中的配置,实现兼容性和灵活性。
systemctl 的作用
- 是管理 Systemd 单元的 统一入口,覆盖服务的全生命周期(启动、停止、监控、依赖管理)。
- 提供现代服务管理功能(如日志集成 journalctl、资源限制 CPUQuota、按需启动等)。
- 配置文件和服务绑定,这些配置文件的位置由服务自身定义,与 Systemd 无关。
单元文件的核心位置
| 目录 | 作用 | 优先级 |
|---|---|---|
| /usr/lib/systemd/system/ | 软件包安装的默认单元文件(如 nginx.service、mysqld.service) | 最低 |
| /etc/systemd/system/ | 管理员自定义的单元文件 或 覆盖默认配置的符号链接 | 最高 |
| /run/systemd/system/ | 运行时动态生成的单元文件(临时配置,重启后失效) | 中 |
service的作用
-
service 命令本质上是一个 Shell 脚本,它会根据参数找到 /etc/init.d/ 中对应的脚本并执行。
-
在 SysVinit 系统中,每个服务需要一个初始化脚本(通常位于 /etc/init.d/ 目录下),该脚本定义了如何启动(start)、停止(stop)、重启(restart)服务以及检查状态(status)。
-
/etc/sysconfig/ 目录存放服务的配置文件或环境变量,供 /etc/init.d/ 脚本读取。比如MySQL 的配置文件可能位于 /etc/sysconfig/mysqld,定义 MYSQLD_OPTS="--port=3306"。
-
服务启动时,/etc/init.d/mysqld 脚本会主动加载 /etc/sysconfig/mysqld 中的变量:
# /etc/init.d/mysqld 脚本片段 if [ -f /etc/sysconfig/mysqld ]; then . /etc/sysconfig/mysqld # 加载配置 fi配置变量(如 MYSQLD_OPTS)会被拼接到启动命令中:
mysqld_safe $MYSQLD_OPTS >/dev/null &
解耦配置与脚本:用户无需修改 /etc/init.d/ 脚本,只需编辑 /etc/sysconfig/ 中的文件即可调整服务行为。
/etc/sysconfig/
如上
举例ssh
老系统:
配置文件由服务定义
服务单元:/etc/init.d/sshd 或 /etc/init.d/ssh
新系统:
配置文件:/etc/ssh/sshd_config
服务单元:systemctl
[root@aliyunn system]# systemctl status sshd
● sshd.service - OpenSSH server daemon
Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2025-04-01 10:44:42 CST; 1 months 18 days ago
Docs: man:sshd(8)
man:sshd_config(5)
Main PID: 1263 (sshd)
CGroup: /system.slice/sshd.service
└─1263 /usr/sbin/sshd -D
[root@aliyunn test]# service sshd status
Redirecting to /bin/systemctl status sshd.service #重定向
● sshd.service - OpenSSH server daemon
Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2025-04-01 10:44:42 CST; 1 months 18 days ago
当 /etc/systemd/system/ 中没有同名单元文件或覆盖配置时,Systemd 会直接使用 /usr/lib/systemd/system/sshd.service 作为服务定义。
在 /etc/systemd/system/ 中放置同名单元文件(如 sshd.service)会 完全替代 /usr/lib/systemd/system/sshd.service。
新老对比
- /etc/sysconfig 在 systemd 中的作用 :
- 保留原用途 :许多服务(尤其是从 SysV 迁移至 systemd 的服务)仍通过 /etc/sysconfig 中的配置文件定义参数。
- 通过 EnvironmentFile 引用 :systemd 服务单元文件(如 /usr/lib/systemd/system/iptables.service)可能使用 EnvironmentFile 指令指向 /etc/sysconfig/
文件,从而加载配置。
- systemd 的主要配置目录 :
- 服务单元文件 :/etc/systemd/system/ 和 /usr/lib/systemd/system/
这是 systemd 的核心配置目录,定义了服务的启动逻辑、依赖关系等(如 sshd.service)。 - 全局配置 :/etc/systemd/
包含系统级配置(如 system.conf、journald.conf 等)。
- 服务单元文件 :/etc/systemd/system/ 和 /usr/lib/systemd/system/
/etc/sysconfig 是 sysinit 与 systemd 的共用目录 ,只是 systemd 通过更灵活的 EnvironmentFile 机制加载其内容,而非直接依赖 SysV 脚本。
统计命令
统计文件、文件夹数量
正则表达式中
^表示匹配行的开始,$表示匹配行的结束。
统计当前文件夹下文件的个数:
ls -l |grep "^-"|wc -l
统计当前文件夹下目录的个数:
ls -l |grep "^d"|wc -l
统计当前文件夹下文件的个数,包括子文件夹里的 :
ls -lR|grep "^-"|wc -l
统计文件夹下目录的个数,包括子文件夹里的:
ls -lR|grep "^d"|wc -l
列出所有文件
ls -l :列出当前文件夹的
ls -lR:列出当前文件夹,和子文件夹的
tcpdump抓包
网络上的流量、数据包,非常的多,因此要想抓到我们所需要的数据包,就需要我们定义一个精准的过滤器,把这些目标数据包,从巨大的数据包网络中抓取出来。学习抓包工具,其实就是学习如何定义过滤器的过程。而在 tcpdump 里,过滤器的实现,都是通过一个又一个的参数组合起来,一个参数不够精准,那就再加一个,直到我们能过滤掉无用的数据包,只留下我们感兴趣的数据包。
tcpdump option proto type direction
proto 类过滤器:根据协议进行过滤,可识别的关键词有: tcp, udp, icmp, ip, ip6, arp, rarp,ether,wlan, fddi, tr, decnet
type 类过滤器:可识别的关键词有:host, net, port, portrange,这些词后边需要再接参数。
direction 类过滤器:根据数据流向进行过滤,可识别的关键字有:src, dst,同时你可以使用逻辑运算符进行组合,比如 src or dst
tcpdump -i any -nn 'host 223.5.5.5 and icmp'
#作用:监听所有网络接口(-i any)的 ICMP 流量,并过滤出与 IP 223.5.5.5 相关的数据包。
关键参数:
-i any:监听所有网卡(如 eth0、wlan0、lo 等)。
-nn:禁用域名和端口解析(直接显示 IP 和端口号)。
host 223.5.5.5:仅捕获目标或源 IP 为 223.5.5.5 的流量。
icmp:仅捕获 ICMP 协议(即 ping 使用的协议)。
新开一个窗口,从本机ping,查看从哪个网卡出
ping 223.5.5.5
grep过滤
grep -v [[:space:]]*# httpd.conf
#以#开头的或者以空格+#开头的
-V是反转的意思
[[:space:]]表示所有的空格,比如制表符等一系列的
*:匹配零个或者多个
vim编辑器
移动光标
在普通模式下
- 方向键上/k:光标向上移动。
- 方向键下/j:光标向下移动。
- 方向键左/h:光标向左移动。
- 方向键右/l【是L的小写】:光标向右移动。
在插入模式下
- 只能通过上、下、左、右方向键移动光标
插入内容
在普通模式下,按i,I,a,A,o,O中任一字符即可进入插入模式。
- i:在当前字符的左边插入。
- I【i的大写】:在当前行的行首插入 。
- a:在当前字符的右边插入。
- A:在当前行的行尾插入。
- o:在当前行下面插入一个新行。
- O:在当前行上面插入一个新行。
复制和粘贴
类似于Word文档编辑器里Ctrl+C和Ctrl+V。在普通模式下:
- yy:复制光标所在的行内容。可以直接使用p进行粘贴。
- nyy:n为数字。例如2yy,复制光标所在行和下一行内容,即复制2行。
- p:粘贴到光标所在的下一行。
- P:粘贴到光标所在的上一行。
删除
做好是用插入模式下的delete
在普通模式下
- 删除单个字符:按键盘 x键删除当前光标所在位置的字符。
- 删除整行:按键盘 dd删除当前行。类似于Word里Ctrl+X,可以直接使用p进行粘贴。
撤销 u
替换
进入 Vim 的命令模式 (按 Esc 键确保退出编辑模式)。
举例:
①elrepo.org/linux 替换为 mirrors.aliyun.com/elrepo
#基础格式
%s/原先的/现在的/ g:全局 空:如果不加 g(global),仅替换每行的第一个匹配项 。
%s#elrepo.org/linux#mirrors.aliyun.com/elrepo#g
%s/elrepo.org\/linux/mirrors.aliyun.com\/elrepo/g
上面两个都可以,但是因为要替换的内容里面有斜杠,替换命令里面也有,所以可以使用#,也可以使用转义。
② 注释掉以 mirrorlist= 开头的行
:%s/^mirrorlist=/#mirrorlist=/
查看文件所在分区(挂载点)
df <文件(夹)路径>
[root@aliyunn mysql]# pwd
/var/lib/mysql
[root@aliyunn mysql]# df -h ./undo_001
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 40G 9.8G 28G 27% /
mount命令
mount是用于将文件系统连接到 Linux 文件系统目录结构中的命令,在 Linux 中,文件系统必须连接(挂载)到目录中才能访问其内容。这个命令可以手动执行,也会在系统启动时自动执行。
挂载
mount [-t 文件系统类型] [-o 选项] 设备 文件夹
sudo mount -t ext4 /dev/sda1 /mnt/data
# /dev/sda1 是物理设备的路径,ext4 是该设备上的文件系统类型。
sudo mount -t tmpfs none /mnt/ramdisk # 用 none 明确表示无物理设备
#物理设备挂载:需同时指定 设备路径 和 文件系统类型。
#虚拟文件系统挂载:设备参数为占位符(none 或类型名),文件系统类型必须正确。
#设备指的是:
分区、U盘、ISO文件、NFS等
查看挂载信息
挂载参数:这些参数直接影响文件系统的性能、数据一致性、安全性以及与硬件的交互方式。
[root@aliyunn etc]# cat mtab
sysfs /sys sysfs rw,nosuid,nodev,noexec,relatime 0 0
proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0
devtmpfs /dev devtmpfs rw,nosuid,size=888676k,nr_inodes=222169,mode=755 0 0
[root@aliyunn etc]# mount
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
devtmpfs on /dev type devtmpfs (rw,nosuid,size=888676k,nr_inodes=222169,mode=755)
/dev/vda1 on / type ext4 (rw,relatime,data=ordered)
mount命令输出格式
<文件系统类型、分区> on <挂载点> type <文件系统类型> (<挂载选项>)
(rw,nosuid,nodev)
挂载选项:
rw:可读可写
nosuid:禁止执行 setuid/setgid 权限
nodev:禁止解析设备文件
mode=755:目录默认权限
ro:只读
noexec:禁止执行文件
部分挂载参数作用:
1、sync / async:控制文件写入磁盘的方式。
sync :所有文件操作(如 write())立即同步写入磁盘,确保数据持久化。
优点 :数据安全性高,适合关键业务(如银行交易日志)。
缺点 :性能低(每次写入都要等待磁盘确认)。
async(默认) :允许数据先缓存在内存中,延迟写入磁盘。
优点 :大幅提升性能(利用内存缓存减少磁盘 I/O)。
缺点 :断电或崩溃可能导致缓存数据丢失。2、data=journal / data=ordered / data=writeback:作用 :针对日志文件系统(如 ext4、XFS),控制数据日志的写入模式。
data=journal :
数据和元数据都写入日志,确保崩溃后数据一致性。
缺点 :性能较低(双倍写入日志和数据)。
data=ordered (默认):
仅元数据写入日志,数据按顺序写入磁盘(确保元数据和数据的一致性)。
优点 :性能与安全性平衡。
data=writeback :
元数据写入日志,数据异步写入(可能丢失未刷盘的数据)。
适用场景 :对性能要求极高但可容忍少量数据丢失的场景。
如果对文件系统的数据安全性和性能都有一定要求,建议在mount命令中不指定任何参数挂载文件系统。该命令会默认携带defaults参数,defaults默认包括rw、atime、suid、dev、exec、async、auto、nouser、delalloc、data=ordered、barrier和nodiscard,不再需要指定其他挂载参数。
数据安全性要求较高:在mount命令中使用rw、atime、sync、barrier、data=journal参数挂载文件系统。
性能要求较高:在mount命令中使用defaults、noatime、nodiratime、nobarrier、nodelalloc、data=writeback参数挂载文件系统。
getconf,AIO,fallocate
get system configuration)命令用于查询系统配置变量的值。
getconf PAGE_SIZE 查看系统内存分页大小
getconf LONG_BIT 看linux是32位还是64位最简单的方法
getconf -a 查看全部系统变量
对于mysql来说:
fallocate 和 posix_fallocate 是用于预分配文件磁盘空间。
传统的:当使用 write() 系统调用向文件末尾写入数据时,如果文件当前大小不足以容纳新数据,文件系统会自动扩展文件大小。这个时候会导致两个问题。①物理不连续,增加寻道事件 ②无法预先知道空间是否足够,如果空间不足,立即失败,可能会导致运行时因空间不足导致崩溃。
AIO(Asynchronous I/O) 是用于异步 I/O 操作 的机制。
在MySQL中,InnoDB使用AIO进行数据文件的读写,同时在创建临时表时使用posix_fallocate来预分配空间。
查看文件系统是否支持
1、在对应的文件系统里面执行fallocate命令,可验证这个文件系统是否支持fallocate
fallocate命令
可以查看文件系统是否支持POSIX_FALLOCATE。这个命令可以快速为文件分配空间,而不需要实际写入任何数据。
命令格式
fallocate [选项] 文件
常见的选项包括:
-l 或 --length:预分配的长度。
-o 或 --offset:文件开始的偏移量。
创建一个1GB大小的空文件
fallocate -l 1G testfile
在现有文件中预留空间
fallocate -o 500M -l 1G testfile
#在现有文件中,从500MB的位置开始预留1GB的空间。
2、posix_fallocate文件系统是否支持通过下面命令来查看(需要首先c库支持)
-rw-r--r-- 1 root root 0 May 29 16:27 testfile2
[root@gtest mysql]# python3 -c 'import os; fd = os.open("/var/lib/mysql/testfile2", os.O_CREAT|os.O_WRONLY); os.posix_fallocate(fd, 0, 1073741824); os.close(fd)'
[root@gtest mysql]# echo $?
0
[root@gtest mysql]# ll
total 2097160
-rw-r--r-- 1 root root 1073741824 May 29 16:25 testfile
-rw-r--r-- 1 root root 1073741824 May 29 16:27 testfile2
3、文件系统是否支持AIO
[root@gtest mysql]# touch aio_testfile
[root@gtest mysql]# TEST_FILE="/var/lib/mysql/aio_testfile"
[root@gtest mysql]# dd if=/dev/zero of=$TEST_FILE bs=1M count=1024
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 6.06402 s, 177 MB/s
[root@gtest mysql]# ll
total 3145740
-rw-r--r-- 1 root root 1073741824 May 29 16:35 aio_testfile
-rw-r--r-- 1 root root 1073741824 May 29 16:25 testfile
-rw-r--r-- 1 root root 1073741824 May 29 16:27 testfile2
[root@gtest mysql]# cat << EOF > aio_test.c
> #include <libaio.h>
> #include <fcntl.h>
> #include <stdio.h>
> int main() {
> io_context_t ctx = 0;
> if (io_setup(10, &ctx) < 0) {
> perror("io_setup failed");
> return 1;
> }
> printf("AIO supported on this filesystem!\n");
> io_destroy(ctx);
> return 0;
> }
> EOF
[root@gtest mysql]# gcc aio_test.c -laio -o aio_test
[root@gtest mysql]# sudo -u mysql ./aio_test $TEST_FILE
AIO supported on this filesystem!
#输出 AIO supported on this filesystem! → 支持
#输出 io_setup failed: Operation not supported → 不支持
内核支持
#AIO
[root@gtest mysql]# grep CONFIG_AIO /boot/config-$(uname -r)
CONFIG_AIO=y
#fallocate
使用 fallocate 命令创建文件能否说明内核和文件系统都支持
#posix_fallcate 这个是c库+文件系统
posix_fallocate 是 POSIX 标准函数 ,其行为取决于 C 库实现(如 glibc) 和 文件系统支持
内核支持 :posix_fallocate 可能调用 fallocate(需内核支持),也可能回退到 write() + truncate() 模拟预分配(无需内核/文件系统支持)。
C 库(如 glibc) 提供的是 函数接口的实现 ,其底层是否调用内核取决于具体函数和系统环境,通过getconf _POSIX_FALLOCATE查看是否支持posix_fallocate。
验证posix_fallcate是否调用了内核中的fallocate
# 编写测试程序 test_fallocate.c
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
int main() {
int fd = open("testfile", O_WRONLY | O_CREAT, 0644);
if (fd == -1) {
perror("open");
return 1;
}
off_t offset = 0;
off_t len = 1024 * 1024 * 1024; // 1GB
int ret = posix_fallocate(fd, offset, len);
if (ret != 0) {
if (ret == ENOSYS) {
printf("posix_fallocate 不支持\n");
} else {
printf("posix_fallocate 失败: %s\n", strerror(ret));
}
} else {
printf("posix_fallocate 成功\n");
}
close(fd);
unlink("testfile");
return 0;
}
#编译运行
gcc -o test_fallocate test_fallocate.c
strace -f -o debug.log ./test_fallocate
#cat debug.log
查看是否有fallocate(3, 0, 0, 1073741824) = 0
IO
Linux读文件的核心路径:用户态read() → 虚拟文件系统 → 具体文件系统 → 页缓存 → 块层 → 设备驱动
/sys/block/sda 提供设备的元数据和控制接口(如扇区数、队列深度)。
/dev/sda 提供设备的数据访问接口(如读写文件系统)。
系统中能够随机(不需要按顺序)访问固定大小数据片(chunks)的硬件设备称作块设备,这些固定大小的数据片就称作块。最常见的块设备为硬盘,其他的还有软盘驱动器、闪存等,它们都是以安装文件系统的方式使用的。
另一种基本的设备类型是字符设备。字符设备按照字符流的方式被有序访问,像串口和键盘就属于字符设备。
对于这两种类型的设备,它们的区别在于是否可以随机访问数据。内核对块设备的管理需要有一个专门提供服务的子系统,对字符设备的管理则不需要。
快设备
块设备中最小的可寻址单位是扇区。扇区大小一般是 2 的整数倍,最常见的是 512 字节。扇区的大小是设备的物理属性。
在软件层面上,最小逻辑可寻址单元为块。块是文件系统的一种抽象,只能基于块来访问文件系统。虽然物理磁盘寻址是按照扇区进行的,但是内核执行的所有操作都是按照块进行的。所以块不能比扇区还小,只能倍数于扇区大小。
扇区是设备的最小寻址单元,也被称为 “硬扇区” 或 “设备块”;同样地,块是文件系统的最小寻址单元,也被称为 “文件块” 或 “I/O 块”。
文件读取
逻辑 I/O(应用层视角):应用程序通过 read()和write()操作文件或设备,read(fd, buf, 1024) 表示从文件描述符 fd 的当前偏移量开始读取 1024 字节数据到用户缓冲区 buf。
物理 I/O(内核视角):内核通过以下机制将逻辑 I/O 拆分为物理 I/O 请求:
①页缓存:Linux 使用页缓存(Page Cache)作为文件数据的缓存层,所有文件读写操作都优先与页缓存交互
②文件系统通过 inode 和 address_space 管理文件数据块的逻辑地址(文件内偏移)到磁盘物理块地址的映射。
③内核将逻辑 I/O 请求拆分为多个物理 I/O 请求,每个请求对应一个连续的物理存储区域。相邻的物理 I/O 请求会被合并(如使用 bio 结构的合并机制)【bio中就有磁盘设备了】
struct bio {
struct bio *bi_next; /* 请求链表指针 */
struct block_device *bi_bdev; /* 目标块设备(如 /dev/sda) */
sector_t bi_sector; /* 目标扇区号 */
struct bio_vec *bi_io_vec; /* 数据缓冲区的 bio_vec 数组 */
unsigned int bi_vcnt; /* bio_vec 数量 */
unsigned int bi_size; /* IO 数据大小(字节) */
// 其他字段...
};
//submit_bio() 将 bio 提交到 bi_bdev 对应的请求队列。
//调度器(如 deadline)根据 bi_bdev 的队列配置进行调度。
LVM
LVM通过设备映射器(Device Mapper)创建虚拟块设备(如/dev/dm-0)
文件系统直接操作这些虚拟设备,LVM再将I/O请求映射到物理设备(PV),也就是真实块设备。
④块设备层(如 I/O 调度器):当 I/O 请求到达块层时,内核会通过 generic_make_request 函数将 bio(Block I/O)转换为 request(设备驱动可处理的请求)。这一过程的核心目标是 合并连续或相邻的 I/O 请求,减少实际硬件操作次数,提升存储性能。在请求进入驱动前,全局优化多个进程的 I/O:如,合并相邻请求和按算法排序(如电梯算法)
#合并条件
1、物理地址连续:多个 bio 请求的磁盘物理块(LBA 地址)必须连续。
2、请求类型相同:同为读或同为写操作。
3、合并后大小未超限:总大小不超过 /sys/block/xxx/queue/max_sectors_kb 定义的值。
cat /sys/block/sda/queue/max_sectors_kb:单个 request 允许的最大数据量(单位:KB)
第一个功能跟虚拟文件系统的功能类似。向上,为文件系统和应用程序,提供访问块设备的标准接口;向下,把各种异构的磁盘设备抽象为统一的块设备,并提供统一框架来管理这些设备的驱动程序。
第二个功能,通用块层包括块设备 I/O 队列和 I/O 调度器。会给文件系统和应用程序发来的 I/O 请求排队,并通过重新排序、请求合并等方式,提高磁盘读写的效率。
[Linux 内核支持四种I/O调度算法,分别是NONE、NOOP、CFQ以及DeadLine]
调度算法
NONE ,更确切来说,并不能算 I/O 调度算法。因为它完全不使用任何I/O调度器,对文件系统和应用程序的I/O其实不做任何处理,常用在虚拟机中(此时磁盘I/O调度完全由物理机负责)。
NOOP ,是最简单的一种 I/O 调度算法。它实际上是一个先入先出的队列,只做一些最基本的请求合并,常用于 SSD 磁盘。
CFQ(Completely Fair Scheduler),也被称为完全公平调度器,是现在很多发行版的默认 I/O 调度器,它为每个进程维护了一个 I/O 调度队列,并按照时间片来均匀分布每个进程的 I/O 请求。类似于进程 CPU 调度,CFQ 还支持进程 I/O 的优先级调度,所以它适用于运行大量进程的系统,像是桌面环境、多媒体应用等。
DeadLine 调度算法,分别为读、写请求创建了不同的 I/O 队列,可以提高机械磁盘的吞吐量,并确保达到最终期限(deadline)的请求被优先处理。DeadLine 调度算法,多用在 I/O 压力比较重的场景,比如数据库等。
单队列:每个设备只有一个请求队列
在单队列模型中,每个存储设备(如 /dev/sda)维护一个全局 request_queue,该队列既是软件队列也是硬件队列的逻辑表示。
队列结构 :
- 所有请求进入同一个 request_queue,通过 spinlock 保护。
- 调度器(如 deadline、cfq)在此队列中排序和合并请求。
无独立硬件队列
- 驱动通过 request_fn() 回调函数从队列中取出请求并提交到硬件。
block Layer的双队列【blk_mp模型才有, blk-sq (Single Queue) - 传统模型 (≤ Linux 3.13)】
Hardware dispatch queues"是块层与驱动的协作层
- Software queues(软件队列):每个cpu一个
- 位于块层核心(blk-mq框架)
- 作用:接收上层BIO请求,进行合并、排序(通过I/O调度器如deadline)--放入硬件队列
- 特点:每个CPU核心有独立队列,避免全局锁竞争
- Hardware dispatch queues(硬件分发队列):硬件队列数量取决于设备能力(NVMe多队列,SATA单队列)
- 位于驱动层入口(由驱动注册)
- 作用:将处理后的请求传递给设备驱动
- 实际位置:属于驱动层,但由块层统一管理.
⑤request 被放入每个块设备的请求队列(request_queue)。
设备初始化时,驱动通过 blk_mq_alloc_tag_set() 向块层注册【SATA驱动为每个设备注册一个硬件队列】
// 驱动注册硬件能力
struct blk_mq_tag_set {
unsigned int nr_hw_queues; // 硬件队列数 ← SATA=1, NVMe=32
unsigned int queue_depth; // 硬件队列深度 ← /sys/block/sda/device/queue_depth
// 块层创建的队列实例
struct request_queue {
struct elevator_queue *elevator; // 调度器实例 ← /sys/block/sda/queue/scheduler
unsigned int nr_requests; // 总请求槽位 ← /sys/block/sda/queue/nr_requests
...
};
#位于device子目录下,说明它是设备特定的
只读文件:/sys/block/sda/device/queue_depth:硬件队列深度,表示设备驱动层允许的未完成 I/O 请求数 (NCQ能力),SATA:32,SAS:256 作用于硬件控制器层
#作用域Linux 块设备层,位于queue子目录下,属于块层管理的参数。
可写文件:/sys/block/sda/queue/nr_requests:软件队列深度 - 块设备层缓存的请求数,是软件缓存池大小。
可写文件:/sys/block/sda/queue/scheduler
#
软件队列 :CPU 的“排队窗口”,避免锁竞争。
硬件队列 :设备的“柜台”,直接对接物理设备
CPUs Software Queues Hardware Queues
---- ---------------- ----------------
CPU 0 ───► SW Queue 0 ───┐
CPU 1 ───► SW Queue 1 ───┤──► HW Queue 0 (Device A)
... │
CPU 7 ───► SW Queue 7 ───┘
CPU 0 ───► SW Queue 0 ───┐
CPU 1 ───► SW Queue 1 ───┤──► HW Queue 0 (Device B)
... │
CPU 7 ───► SW Queue 7 ───┘
图:sata驱动,硬件队列只有一个的情况下
设备驱动(如 AHCI 或 NVMe 驱动)通过调用peek_request将其取出。将其封装为硬件可识别的命令(如 SCSI 命令或 NVMe 命令)。从操作系统的 request_queue取出多个请求(最多 32 个),通过 SATA 接口发送到磁盘控制器的缓存区。
- ✅ NVMe:驱动注册 多个硬件分发队列 → 直接映射到物理多队列
- ✅ SATA:驱动注册 单个硬件分发队列 → 受限于 AHCI 单队列协议
- ❗ 所有驱动都使用 blk-mq框架,但硬件队列数由设备能力决定
物理IO(硬件视角):⑥物理 I/O 执行 :存储设备(如 SSD/HDD)重新排序并执行实际的数据读写操
组件:磁盘控制器调度(NCQ) 硬件层面的局部优化:基于磁头位置重排序、缓存数据、管理物理介质访问
典型技术:SATA NCQ、SAS TCQ、NVMe 多队列
#TCQ (Tagged Command Queuing ,标签命令队列)是 SCSI 接口标准 中的一项关键技术,与 SATA 的 NCQ(Native Command Queuing)类似,但属于不同的硬件接口协议
SATA/SAS 设备的处理流程(单队列模型)
NCQ 优化:控制器对32个请求排序,减少磁头移动,但 不改变串行本质
即使 nr_requests=1024,实际并行度仍受限于 queue_depth=32
+-----------------------+
| 块设备层 |
| nr_requests=128 | ← 软件队列 (缓存128请求)
+-----------------------+
↓ 调度器排序/合并
+-----------------------+
| 设备驱动层 |
| queue_depth=32 | ← 硬件队列 (NCQ能力)
+-----------------------+
↓
+-----------------------+
| 磁盘控制器 |
| 实际串行执行请求 | ← 即使缓存32请求也需逐个处理!
+-----------------------+
NVMe 设备的处理流程(多队列并行模型)
+-----------------------+
| 块设备层 |
| nr_requests=1024 | ← 总软件队列
+-----------------------+
↓
+-----------------------+
| 多队列调度 |
| (如 mq-deadline) | ← 分配请求到不同硬件队列
+-----------------------+
↓
+-----------------------+ +-----------------------+
| 硬件队列0 | | 硬件队列1 | ...
| queue_depth=1024 | | queue_depth=1024 | ← 每个队列独立
+-----------------------+ +-----------------------+
↓ ↓
+-----------------------------------------------------+
| NVMe控制器 |
| 并行处理所有队列请求 | ← 真正的硬件并行!
+-----------------------------------------------------+
优化点:NVMe 多队列设备内部有多个处理引擎,可同时执行不同队列的 I/O 请求。
多数 Linux 发行版默认启用 irqbalance 服务,尝试自动分配中断到不同核心。对于单队列设备,只有一个中断号 → 无法分散到多核心。多队列设备的中断机制,每个队列都有独立中断号(IRQ)
参考文件:
进程限制
资源
Linux 上的 cat /proc/$pid/limits 命令提供有关特定进程的资源限制的信息,其中 $pid 是相关进程的进程 ID (pid)。该文件是 /proc 文件系统的一部分。
#limit条目
Max process limit:用户可以创建的最大进程数。它限制了用户可以生成的进程数量
Max open files:进程可以拥有的最大文件描述符数量。这会影响进程可以同时打开的文件、套接字等的数量
Max locked memory:可以锁定到 RAM 中的最大内存量,防止其被换出
Max address space:进程可以分配的最大虚拟地址空间量,其中包括内存、堆和堆栈
Max CPU time:进程可使用的最大 CPU 时间。以秒为单位
Max file locks:进程可以拥有的文件锁的最大数量
Max number of threads:进程可以创建的最大线程数
Max user time:进程在用户空间中花费的最长时间(以秒为单位)(即不包括内核时间)
Max virtual memory:进程可以分配的虚拟内存总量,通常控制进程内存使用的上限
Max file size:进程创建文件的最大大小
Max data size:进程数据段的最大大小(包括堆和数据)
Max stack size:进程堆栈的最大大小
Max core file size:核心转储文件(core dump)的最大大小
Max resident set:驻留内存(RSS,物理内存)的最大大小
Max pending signals:进程可排队的最大信号数
Max msgqueue size:POSIX 消息队列的最大大小
Max realtime priority:实时调度优先级的最大值
Max realtime timeout:实时任务的最大超时时间(微秒)
权限
Capabilities
传统的 Unix 权限模型中,程序要么以普通用户身份运行,要么通过 SUID 提权到 root(例如 /usr/bin/passwd)。这种机制存在安全隐患:如果程序有漏洞,攻击者可能获得完整的 root 权限。
Capabilities 将 root 权限拆分为多个独立的权限(能力) ,允许程序仅获得完成任务所需的最小权限。例如,一个程序只需要发送 ICMP 包(如 ping),就可以只赋予它 CAP_NET_RAW,而不是完整的 root 权限。
[root@gtest admin]# getcap /usr/bin/ping
/usr/bin/ping = cap_net_admin,cap_net_raw+p
#使用admin用户测试
[admin@gtest ~]$ whoami
admin
[admin@gtest ~]$ ip route
default via 172.24.63.253 dev eth0 proto dhcp metric 100
172.24.0.0/18 dev eth0 proto kernel scope link src 172.24.36.139 metric 100
[admin@gtest ~]$ ping 172.24.63.253
PING 172.24.63.253 (172.24.63.253) 56(84) bytes of data.
64 bytes from 172.24.63.253: icmp_seq=1 ttl=64 time=0.096 ms
64 bytes from 172.24.63.253: icmp_seq=2 ttl=64 time=0.080 ms
64 bytes from 172.24.63.253: icmp_seq=3 ttl=64 time=0.080 ms
^C
--- 172.24.63.253 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 39ms
rtt min/avg/max/mdev = 0.080/0.085/0.096/0.010 ms
目录和文件
在Linux中,对文件的访问权限取决于文件的权限位和父目录的权限位,一旦一个文件被打开,后续的读写操作不再检查父目录的权限,而是只检查文件本身的权限以及打开文件时使用的文件描述符。
目录有执行权限(x),允许其他用户"穿越"该目录,进入目录/访问元数据。cd +ll
查看进程打开的文件句柄
sudo ls -l /proc/10799/fd
mysqld中的错误日志目录权限:
/var (drwxr-xr-x root)
└── lib (drwxr-xr-x root)
└── mysql (drwxr-x--- mysql)
└── error.log (rw-r----- mysql)
这个使得,所有用户都能够进入lib下查看mysql这个目录存在,但是cd不进去mysql1目录。
错误日志只有mysql用户和root用户可以打开
用户
admin用户sudo启动
【普通用户无法启动】
[root@gtest etc]# ps -ef | grep mysqld
root 10798 8220 0 10:06 pts/0 00:00:00 sudo /usr/local/mysql/bin/mysqld --defaults-file=/usr/local/etc/my1.cnf
mysql 10799 10798 1 10:06 pts/0 00:00:08 /usr/local/mysql/bin/mysqld --defaults-file=/usr/local/etc/my1.cnf
root 11692 11327 0 10:18 pts/0 00:00:00 grep --color=auto mysqld
出现了两个mysqld进程,一个是root用户启动的,一个是mysql用户启动的。pid10799的父进程为10798。
父进程 (PID 10798):由 sudo 启动,拥有 root 权限,执行初始化需要特权的操作。
①绑定特权端口 (如 3306)
②读取受保护的配置文件 (/usr/local/etc/my1.cnf)
③访问数据目录 (通常 /var/lib/mysql 需要 root 创建)
子进程 (PID 10799):实际服务进程,降权到 mysql 用户。处理客户端连接和数据存储即使被入侵,攻击者也只能获得 mysql 用户权限。
#通过getpcaps查看进程能力(Capabilities)
[admin@gtest etc]$ ps -ef | grep mysqld
root 14260 12820 0 10:59 pts/1 00:00:00 sudo /usr/local/mysql/bin/mysqld --defaults-file=/usr/local/etc/my1.cnf
mysql 14261 14260 12 10:59 pts/1 00:00:04 /usr/local/mysql/bin/mysqld --defaults-file=/usr/local/etc/my1.cnf
admin 14507 14427 0 11:00 pts/0 00:00:00 grep --color=auto mysqld
[admin@gtest etc]$ getpcaps 14260
Capabilities for 14260': = cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,cap_audit_read+ep
[admin@gtest etc]$ getpcaps 14261
Capabilities for 14261': =
以root启动的是父进程,它启动后立即启动子进程(mysql用户),然后父进程可能会退出(或者等待子进程,但这里父进程是sudo,它可能会等待子进程结束)。但在这个例子中,我们看到父进程(10798)和子进程(10799)同时存在,这是因为父进程(sudo)在等待子进程结束。
[root@gtest etc]# kill -9 10798
[root@gtest etc]# ps -ef | grep mysqld
mysql 10799 1 0 10:06 pts/0 00:00:14 /usr/local/mysql/bin/mysqld --defaults-file=/usr/local/etc/my1.cnf
root 13179 11327 0 10:49 pts/0 00:00:00 grep --color=auto mysqld
[root@gtest etc]# mysql -uroot -p -h127.1
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 10
mysql>
- kill掉父进程并没有对子进程造成影响,还能继续登录。
- kill掉子进程,父进程也会结束
root用户启动
[root@iZ2zea1vmj1kuz57gg836hZ etc]# mysqld --defaults-file=/usr/local/etc/my1.cnf
[root@gtest ~]$ ps -ef | grep mysqld
mysql 13436 11327 29 10:51 pts/0 00:00:04 mysqld --defaults-file=/usr/local/etc/my1.cnf
admin 13544 12820 0 10:51 pts/1 00:00:00 grep --color=auto mysqld
直接就没有了以root启动的用户,所以选择直接root启动mysqld。
wget命令
使用wget下载一个大文件时,如果前台下载的话,ssh一旦断开就不显示当前进度了,想要看这个进度如何可以使用下面几个方法。使用后台下载的话,会告诉日志打印到哪个文件。
[root@8f9fbda9bb48 ~]# wget -b http://cn.wordpress.org/wordpress-3.1-zh_CN.zip
Continuing in background, pid 835.
Output will be written to 'wget-log'.
后台下载:wget -b + url
实时查看:tail -f wget-log
当使用-f参数时,命令的行为会稍有不同。“tail -f” 文件名会持续显示指定文件的最后部分内容,并且随着文件内容的更新实时刷新显示。退出需要ctrl+c。
看目前的进度:cat wget-log
proc/pid
1. 进程基本信息
| 文件名 | 作用 | 可获取信息 | 存在原因 |
|---|---|---|---|
| cmdline | 启动命令参数 | MySQL 的完整启动命令(如 mysqld --defaults-file=/etc/mysql/my.cnf) | 诊断启动配置问题 |
| comm | 进程名 | 进程名称(如 mysqld) | 标识进程 |
| stat | 进程状态 | CPU 使用时间、状态代码、优先级等 20+ 项统计 | 系统监控工具(top/ps)数据源 |
| status | 易读状态摘要 | 内存使用、信号状态、UID/GID、线程数等 | 人类可读的进程概览 |
| cwd | 当前工作目录 | 进程工作目录(符号链接) | 定位文件路径问题 |
2. 内存管理
| 文件名 | 作用 | 可获取信息 | 存在原因 |
|---|---|---|---|
| maps | 内存映射 | 加载的共享库、堆栈地址、文件映射区域 | 分析内存泄漏、库依赖 |
| smaps | 扩展内存映射 | 每个映射区的 RSS/PSS/Swap 使用详情 | 精确内存占用分析 |
| pagemap | 物理页映射 | 虚拟页到物理页的映射关系 | 高级内存分析 |
| mem | 原始内存访问 | 直接读取进程内存(需 root) | 调试器(gdb)底层支持 |
| oom_score | OOM 优先级 | 内存不足时被终止的优先级(0-1000) | 系统 OOM Killer 决策依据 |
3. 文件系统 & I/O
| 文件名 | 作用 | 可获取信息 | 存在原因 |
|---|---|---|---|
| fd/(目录) | 打开的文件描述符 | 所有打开的文件、socket、管道等 | 监控资源泄漏 |
| io | I/O 统计 | 磁盘读写字节数、系统调用次数 | 分析 I/O 性能瓶颈 |
| mountinfo | 挂载点信息 | 文件系统挂载源、选项、ID | 排查存储访问问题 |
4. 线程 & 调度
| 文件名 | 作用 | 可获取信息 | 存在原因 |
|---|---|---|---|
| task/(目录) | 线程信息 | 每个线程的子目录(含相同文件集) | 监控多线程应用 |
| sched | 调度策略 | 调度策略(CFS/RT)、优先级 | 调优数据库优先级 |
| schedstat | 调度统计 | CPU 时间片、等待延迟 | 分析 CPU 竞争问题 |
| wchan | 休眠原因 | 进程阻塞时等待的内核函数 | 诊断卡顿问题 |
5. 系统环境
| 文件名 | 作用 | 可获取信息 | 存在原因 |
|---|---|---|---|
| environ | 环境变量 | MYSQL_HOME、LD_PRELOAD 等 | 诊断环境配置问题 |
| auxv | ELF 解释器信息 | 程序入口地址、平台类型 | 二进制加载支持 |
| cgroup | 控制组信息 | CPU/内存限制路径(Docker/K8s) | 容器环境监控 |
| ns/(目录) | 命名空间 | IPC/Network/PID 等命名空间 ID | 容器隔离分析 |
6. 安全相关
| 文件名 | 作用 | 可获取信息 | 存在原因 |
|---|---|---|---|
| uid_map | 用户 ID 映射 | 容器内外 UID 映射关系 | 容器安全支持 |
| loginuid | 登录用户 ID | 启动进程的用户 ID | 审计跟踪 |
| attr/(目录) | 安全属性 | SELinux/AppArmor 上下文 | 强制访问控制 |
git
https://juejin.cn/post/7245176801491894333#heading-20
平台
deepseek R1满血
https://blog.aerr.cn/3793.html
在线IDE
https://www.mycompiler.io/new/python
https://www.mycompiler.io/
网站运维检测平台
https://boce.aliyun.com/detect/ping
备案流程
https://www.wangsu.com/beian

浙公网安备 33010602011771号