Linux
2021-02-04 14:20:00 1 举报HUP 1 终端断线
INT 2 中断(同 Ctrl + C)Kill-2:功能类似于Ctrl+C是程序在结束之前,能够保存相关数据,然后再退出。
QUIT 3 退出(同 Ctrl + )
TERM 15 终止
KILL 9 强迫终止
CONT 18 持续(与STOP相反, fg/bg号令)
STOP 19 暂停(同 Ctrl + Z)
原文链接:https://blog.csdn.net/llljjlj/article/details/89913629
ctrl-c 是发送 SIGINT 信号,
ctrl-z 是发送 SIGSTOP信号
ctrl-d 不是发送信号,而是表示一个特殊的二进制值,表示 EOF
第二种方法是,忽略某个信号,对该信号不做任何处理,就象未发生过一样。
第三种方法是,对该信号的处理保留系统的默认值,这种缺省操作,对大部分的信号的缺省操作是使得进程终止。进程通过系统调用signal来指定进程对某个信号的处理行为。
信号在进程中注册
信号的执行和注销
vmstat的常规用法:vmstat interval times即每隔interval秒采样一次,共采样times次,如果省略times,则一直采集数据,直到用户手动停止为止。
1.负载:时间,登陆用户数,系统平均负载;
2.进程:运行,睡眠,停止,僵尸;
3.cpu:用户态,核心态,NICE,空闲,等待IO,中断等;
4.内存:总量,已用,空闲(系统角度),缓冲,缓存;
5.交换分区:总量,已用,空闲
任务区域默认显示:进程ID,有效用户,进程优先级,NICE值,进程使用的虚拟内存,物理内存和共享内存,进程状态,CPU占用率,内存占用率,累计CPU时间,进程命令行信息。
如下:dstat –cdlmnpsy
可以以非交互的方式使用:iotop –bod interval,查看每个进程的I/O,可以使用pidstat,pidstat –d instat。
使用方法:pidstat –d interval;pidstat还可以用以统计CPU使用信息:pidstat –u interval;统计内存信息:Pidstat –r interval。
▪ 可以横向或者纵向滚动浏览进程列表,以便看到所有的进程和完整的命令行。
▪ 在启动上,比top更快。
▪ 杀进程时不需要输入进程号。
▪ htop支持鼠标操作。
▲常见用法:
netstat –npl 可以查看你要打开的端口是否已经打开。
netstat –rn 打印路由表信息。
netstat –in 提供系统上的接口信息,打印每个接口的MTU,输入分组数,输入错误,输出分组数,输出错误,冲突以及当前的输出队列的长度。
查看文件系统阻塞 lsof /boot
查看端口号被哪个进程占用 lsof -i : 3306
查看用户打开哪些文件 lsof –u username
查看进程打开哪些文件 lsof –p 4838
查看远程已打开的网络链接 lsof –i @192.168.34.128
▪ 杀掉某一程序的方法:ps aux | grep mysqld | grep –v grep | awk ‘{print $2 }’ xargs kill -9
▪ 杀掉僵尸进程:ps –eal | awk ‘{if ($2 == “Z”){print $4}}’ | xargs kill -9
性能调优工具如 perf,Oprofile 等的基本原理都是对被监测对象进行采样,最简单的情形是根据 tick 中断进行采样,即在 tick 中断内触发采样点,在采样点里判断程序当时的上下文。假如一个程序 90% 的时间都花费在函数 foo() 上,那么 90% 的采样点都应该落在函数 foo() 的上下文中。运气不可捉摸,但我想只要采样频率足够高,采样时间足够长,那么以上推论就比较可靠。因此,通过 tick 触发采样,我们便可以了解程序中哪些地方最耗时间,从而重点分析。
1、 perf list
2、 perf stat
3、 perf top
4、 perf record/report
ipcs:报告进程间通信设施状态,关于当前活动消息队列、共享内存段、信号量、远程队列和本地队列标题。
ipcrm:删除消息队列、信号集、或者共享内存标识
quota:磁盘管理命令。显示磁盘使用情况和限额
repquota:磁盘管理命令。报告磁盘空间限制的状况,清楚得知每位用户或每个群组已使用多少空间
edquota:磁盘管理命令。编辑用户或群组的quota
quotacheck:磁盘管理命令。检查磁盘的使用空间与限制,执行quotacheck指令,扫描挂入系统的分区,并在各分区的文件系统根目录下产生quota.user和quota.group文件,设置用户和群组的磁盘空间限制。
quoton:磁盘管理命令。启动系统quota限制硬盘使用空间
sysctl:配置与显示在/proc/sys目录中的内核参数。一个允许您改变正在运行中的Linux系统的接口。它包含一些 TCP/IP 堆栈和虚拟内存系统的高级选项, 这可以让有经验的管理员提高引人注目的系统性能。用sysctl可以读取设置超过五百个系统变量。基于这点,sysctl(8) 提供两个功能:读取和修改系统设置。可以使用sysctl修改系统变量,也可以通过编辑sysctl.conf文件来修改系统变量。
tethereal:类似tcpdump的抓包工具
iptraf:网络流量实时监控工具
nfsstat:查看NFS服务器状态,显示关于NFS和到内核的远程过程调用(RPC)接口的统计信息,也可以使用该命令重新初始化该信息
mrtg:监控网络链路流量负载的工具软件,通过snmp协议得到设备的流量信息,并将流量负载以包含PNG格式的图形的HTML 文档方式显示给用户,以非常直观的形式显示流量负载
ntop:监控网络流量工具,同时提供命令行输入和web页面,可应用于嵌入式web服务
mkswap:设置交换区(swap area),可将磁盘分区或文件设为Linux的交换区
swapon:激活/开启swap
swapoff:关闭swap
ulimit:控制/限定shell程序的资源
有时我们需要执行一个程序,并且这个程序比较重要而且比较紧急,而CPU空闲的资源也比较少,这个时候我们就需要来调整这个程序的进程优先级,来给这个程序分配更多的CPU资源并且优先执行。
Linux下的renice和nice都是调整进程优先级的工具,优先级的值的范围是(-20至19),-20为最高优先级,19为最低优先级,默认程序进程的优先级为0。
通过PID修改指令cat优先级为-20命令:
renice -n -20 -p 80886进程绑定(一个进程可以绑定在一个或者多个CPU上)例如,taskset -pc 0-3 10790
独占CPU
编辑/proc/sys/kernel/中的文件,修改内核参数。
#cd /proc/sys/kernel/
# ls /proc/sys/kernel/
一般可能需要编辑的是pid_max和threads-max,增大进程数量和线程数量,如下:
# sysctl kernel.threads-max
kernel.threads-max = 8192
# sysctl kernel.threads-max=10000
kernel.threads-max = 10000
查看系统用户所有限制值:ulimit -a
设置用户open files(用户可以打开文件的最大数目):ulimit -n 4096。执行该命令非root用户只能设置到4096。想要设置到8192需要sudo权限或者root用户。可解决toomany open file 问题,默认 1024
修改/proc/sys/vm/下的系统参数vm.dirty_background_bytes:默认值为0, 触发pdflush后台回写的脏存储器量;
vm.dirty_background_ratio:默认值10, 触发pdflush后台回写脏系统存储器百分比;
vm.dirty_bytes:默认值为0,触发一个写入进程开始回写的脏存储器量;
vm.dirty_ratio:默认值为20,触发一个写入进程开始回写的脏系统存储器比例;
vm.dirty_expire_centisecs:默认值为3000,使用pdflush的脏存储器最小时间;
vm.dirty_writeback_centisecs:默认值为500,pdflush活跃时间间隔(0为停用);
vm.min_free_kbytes:默认值为 dynamic,设置期望的空闲存储器量(一些内核自动分配器能消耗它);
vm.overconmmit_memory:默认值为0,0表示利用探索法允许合理的国度分配;1表示一直国度分配;3表示禁止国度分配;
vm.swappiness:默认值为60,相对于页面高速缓存回收更倾向用交换释放存储器的程度;
vm.vfs_cache_pressure:默认值为100,表示回收高速缓存的目录和inode对象的程度。较低的值会保留更多;0意味着从不回收,容器导致存储器耗尽的情况
vm.min_free_kbytes = 1024
# sysctl -w vm.min_free_kbytes=2508
vm.min_free_kbytes = 2508
quoton
sysctl
boot line:
elevator
ilde:空闲磁盘调度,该调度策略是在当前系统没有其他进程需要进行磁盘IO时,才能进行磁盘;因此该策略对当前系统的影响基本为0;当然,该调度策略不能带有任何优先级参数;目前,普通用户是可以使用该调度策略(自从内核2.6.25开始)。
Best effort:是缺省的磁盘IO调度策略;(1)该调度策略可以指定优先级参数(范围是0~7,数值越小,优先级越高);(2)针对处于同一优先级的程序将采round-robin方式;(3)对于best effort调度策略,8个优先级等级可以说明在给定的一个调度窗口中时间片的大小。(4)目前,普调用户(非root用户)是可以使用该调度策略。(5)在内核2.6.26之前,没有设置IO优先级的进程会使用“none”作为调度策略,但是这种策略使得进程看起来像是采用了best effort调度策略,因为其优先级是通过关于cpu nice有关的公式计算得到的:io_priority = (cpu_nice + 20) / 5。(6)在内核2.6.26之后,如果当前系统使用的是CFQ调度器,那么如果进程没有设置IO优先级级别,将采用与内核2.6.26之前版本同样的方式,推到出io优先级级别。
Real time:实时调度策略,如果设置了该磁盘IO调度策略,则立即访问磁盘,不管系统中其他进程是否有IO。因此使用实时调度策略,需要注意的是,该访问策略可能会使得其他进程处于等待状态。
参数说明:
-c class :class表示调度策略,其中0 for none, 1 for real time, 2 for best-effort, 3 for idle。
-n classdata:classdata表示IO优先级级别,对于best effort和real time,classdata可以设置为0~7。
-p pid:指定要查看或设置的进程号或者线程号,如果没有指定pid参数,ionice will run the listed program with the given parameters。
-t :忽视设置优先级时产生的错误。
COMMAND:表示命令名
实例:
# ionice -c 3 -p 89
设置进程号为89的进程的调度策略是idle。
# ionice -c 2 -n 0 bash
运行bash,调度策略是best-effort,最高优先级。
# ionice -p 89 91
打印进程号为89和91进程的调度策略和IO优先级。
#ionice -c3 -p$$
将当前的进程(就是shell)磁盘IO调度策略设置为idle类型.
通过cgroup为进程或进程组提供存储设备资源控制机制。一般很少用到,不用考虑。
可调参数
/sys/block/sda/queue/scheduler:选择I/O调度器策略,是空操作、最后期限、an还是cfq;
# mkfs -t reiserfs -j /dev/sdc1
文件系统即使在建立后,本身也可以通过命令调优;
tune2fs (ext2/ext3)
reiserfstune (reiserfs)
jfs_tune (jfs)
deadline – Deadline I/O scheduler
as – Anticipatory I/O scheduler
cfq – Complete Fair Queuing scheduler
noop – Noop I/O scheduler
可以编辑/etc/yaboot.conf文件修改参数elevator得到。
# vi /etc/yaboot.conf
image=/vmlinuz-2.6.9-11.EL
label=linux
read-only
initrd=/initrd-2.6.9-11.EL.img
root=/dev/VolGroup00/LogVol00
append=”elevator=cfq rhgb quiet”
RO RA SSZ BSZ StartSec Size Device
…
rw 256 512 4096 0 71096640 /dev/sdb
rw 256 512 4096 32 71094240 /dev/sdb1
[root@overflowuid ~]# blockdev –setra 2048 /dev/sdb1
[root@overflowuid ~]# blockdev –report
RO RA SSZ BSZ StartSec Size Device
…
rw 2048 512 4096 0 71096640 /dev/sdb
rw 2048 512 4096 32 71094240 /dev/sdb1
iwconfig
sysctl
Settings for eth0:
Supported ports: [ TP ]
Supported link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Full
Supports auto-negotiation: Yes
Advertised link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Full
Advertised auto-negotiation: Yes
Speed: 100Mb/s
Duplex: Half
Port: Twisted Pair
PHYAD: 0
Transceiver: internal
Auto-negotiation: on
Supports Wake-on: d
Wake-on: d
Current message level: 0×00000007 (7)
Link detected: yes
#ethtool -s eth0 duplex full
#ifconfig eth0 mtu 9000 up
在数据传输时,由于IEEE的规定最大的帧规定为1,500比特(主机在早期的半双功网络中),所以需要数传输需要经过 数据的切要 --- 传输 ---数据组合 的过程。而使用的最大帧越小,传输包的量就越大,计算量相应会多,而产生的后果是:
a:增加主机的计算量,消耗CPU资源;
b:影响网络传输的速度。
而使用大帧优点自然也不言而喻 ———— 降低CPU计算量、加快数据传输。修改MTU值
上面啰嗦了一大堆,修改帧大小实际需要的操作就是修改MTU(Maximum Transmission Unit)值,即修改最大传输单元。修改方法如下:
1、ifconfig命令修改
- ifconfig ${Interface} mtu ${SIZE} up
- ifconfig eth1 mtu 9000 up
这个是最通用的方法,对所有的linux 发行版本都有效。缺点就是重启后失效,需要在开机项中加载
196608 262144 393216
# cat /proc/sys/net/core/rmem_default
135168
# cat /proc/sys/net/core/rmem_max
131071
# cat /proc/sys/net/core/wmem_default
135168
# cat /proc/sys/net/core/wmem_max
131071
# cat /proc/sys/net/core/optmem_max
20480
# cat /proc/sys/net/core/netdev_max_backlog
300
# sysctl net.core.rmem_max
net.core.rmem_max = 131071
# sysctl -w net.core.rmem_max=135168
net.core.rmem_max = 135168
net.ipv4.tcp_tw_reuse = 0
# sysctl -w net.ipv4.tcp_tw_reuse=1
net.ipv4.tcp_tw_reuse = 1
# sysctl net.ipv4.tcp_tw_recycle
net.ipv4.tcp_tw_recycle = 0
# sysctl -w net.ipv4.tcp_tw_recycle=1
net.ipv4.tcp_tw_recycle = 1
编辑内核文件/etc/sysctl.conf,加入以下内容:
net.ipv4.tcp_syncookies = 1 表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;
net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;
net.ipv4.tcp_tw_recycle = 1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。
net.ipv4.tcp_fin_timeout 修改系默认的 TIMEOUT 时间
然后执行 /sbin/sysctl -p 让参数生效.
/etc/sysctl.conf是一个允许改变正在运行中的Linux系统的接口,它包含一些TCP/IP堆栈和虚拟内存系统的高级选项,修改内核参数永久生效。
简单来说,就是
打开系统的TIMEWAIT重用和快速回收
。
如果以上配置调优后性能还不理想,可继续修改一下配置:
vi /etc/sysctl.conf
net.ipv4.tcp_keepalive_time = 1200
默认值是7200(2小时)
当keepalive打开的情况下,TCP发送keepalive消息的频率。(由于目前网络攻击等因素,造成了利用这个进行的攻击很频繁,曾经也有cu的朋友提到过,说如果2边建立了连接,然后不发送任何数据或者rst/fin消息,那么持续的时间是不是就是2小时,空连接攻击? tcp_keepalive_time就是预防此情形的.我个人在做nat服务的时候的修改值为1800秒)
net.ipv4.ip_local_port_range = 1024 65000
#表示用于向外连接的端口范围。缺省情况下很小:32768到61000,改为1024到65000。
net.ipv4.tcp_max_syn_backlog = 8192
#表示SYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数。
net.ipv4.tcp_max_tw_buckets = 5000
#表示系统同时保持TIME_WAIT套接字的最大数量,如果超过这个数字,TIME_WAIT套接字将立刻被清除并打印警告信息。
默认为180000,改为5000。对于Apache、Nginx等服务器,上几行的参数可以很好地减少TIME_WAIT套接字数量,但是对于 Squid,效果却不大。此项参数可以控制TIME_WAIT套接字的最大数量,避免Squid服务器被大量的TIME_WAIT套接字拖死。
net.ipv4.tcp_keepalive_time = 30
net.ipv4.tcp_keepalive_intvl = 10
探测消息发送的频率,乘以tcp_keepalive_probes就得到对于从开始探测以来没有响应的连接杀除的时间。默认值为75秒,也就是没有活动的连接将在大约11分钟以后将被丢弃。(对于普通应用来说,这个值有一些偏大,可以根据需要改小.特别是web类服务器需要改小该值,15是个比较合适的值)
net.ipv4.tcp_keepalive_probes = 2
默认值是9
TCP发送keepalive探测以确定该连接已经断开的次数。(注意:保持连接仅在SO_KEEPALIVE套接字选项被打开是才发送.次数默认不需要修改,当然根据情形也可以适当地缩短此值.设置为5比较合适)
net.ipv4.tcp_syncookies=1
net.ipv4.tcp_tw_reuse=1
net.ipv4.tcp_tw_recycle=1(已废弃)
net.ipv4.tcp_fin_timeout = 5(对于本端断开的socket连接,TCP保持在FIN_WAIT_2状态的时间。对方可能会断开连接或一直不结束连接或不可预料的进程死亡。默认值为 60 秒)
/sbin/sysctl -p
- 用户程序可以访问任意内存,容易破坏操作系统,造成崩溃
- 同时运行多个程序特别困难
- 基址寄存器与界限寄存器可以简单的动态重定位,每个内存地址送到内存之前,都会自动加上基址寄存器的内容。
- 交换技术把一个进程完全调入内存,使该进程运行一段时间,然后把它存回磁盘。空闲进程主要存在磁盘上,所以当他们不运行时就不会占用内存。
- 如果用户程序可以寻址内存的每个字节,就有很大的可能破坏操作系统,造成系统崩溃
- 同时运行多个程序十分困难 地址空间创造了一个新的内存抽象,地址空间是一个进程可用于寻址内存的一套地址的集合。每个进程都有一个自己的地址空间,并且这个地址空间独立于其它进程的地址空间。使用基址寄存器和界限器可以实现。
虚拟内存实际上可以比物理内存大。当访问虚拟内存时,会通过MMU(内存管理单元)去匹配对应的物理地址,而如果虚拟内存的页并不存在于物理内存中,会产生缺页中断,从磁盘中取得缺的页放入内存,如果内存已满,还会根据某种算法将磁盘中的页换出。
而虚拟内存和物理内存的匹配是通过页表实现,页表存在MMU中,页表中每个项通常为32位,既4byte,除了存储虚拟地址和页框地址之外,还会存储一些标志位,比如是否缺页,是否修改过,写保护等。可以把MMU想象成一个接收虚拟地址项返回物理地址的方法。
因为页表中每个条目是4字节,现在的32位操作系统虚拟地址空间会是2的32次方,即使每页分为4K,也需要2的20次方 * 4字节 = 4M的空间,为每个进程建立一个4M的页表并不明智。因此在页表的概念上进行推广,产生二级页表,二级页表每个对应4M的虚拟地址,而一级页表去索引这些二级页表,因此32位的系统需要1024个二级页表,虽然页表条目没有减少,但内存中可以仅仅存放需要使用的二级页表和一级页表,大大减少了内存的使用。
引入多级页表的原因是避免把全部页表一直存在内存中。
链接:https://www.jianshu.com/p/2b11639905ec
页表的目的是把虚拟页面映射为页框,从数学的角度来说,页表是一个函数,它的参数是,虚拟页号,结果是物理页框号。通过这个函数可以把虚拟地址中的虚拟页面域替换为页框域,从而形成物理地址。
page_flags_t flags; 页标志符
atomic_t _count; 页引用计数
atomic_t _mapcount; 页映射计数
unsigned long private; 私有数据指针
struct address_space *mapping; 该页所在地址空间描述结构指针,用于内容为文件的页帧
pgoff_t index; 该页描述结构在地址空间radix树page_tree中的对象索引号即页号
struct list_head lru; 最近最久未使用struct slab结构指针链表头变量
void *virtual; 页虚拟地址
};
_count:计数值为-1表示未被使用。
virtual:页在虚拟内存中的地址,对于不能永久映射到内核空间的内存(比如高端内存),该值为NULL;需要事必须动态映射这些内存。
Linux采用虚拟内存技术。进程的内存空间只是虚拟内存(或者叫作逻辑内存),而程序的运行需要的是实实在在的内存,即物理内存(RAM)。在必要时,操作系统会将程序运行中申请的内存(虚拟内存)映射到RAM,让进程能够使用物理内存。
内存区域可包含的对象:
代码段(text section): 可执行文件代码
数据段(data section): 可执行文件的已初始化全局变量(静态分配的变量和全局变量)。
bss段:程序中未初始化的全局变量,零页映射(页面的信息全部为0值)。
进程用户空间栈的零页映射(进程的内核栈独立存在并由内核维护)
每一个诸如C库或动态连接程序等共享库的代码段、数据段和bss也会被载入进程的地址空间
任何内存映射文件
任何共享内存段
任何匿名的内存映射(比如由malloc()分配的内存)
这些内存区域不能相互覆盖,每一个进程都有不同的内存片段。
struct vm_area_struct *mmap;
rb_root_t mm_rb;
...
atomic_t mm_users;
atomic_t mm_count;
struct list_head mmlist;
...
};
mm_count: 代表mm_struct的主引用计数,当该值为0说明没有任何指向该mm_struct结构体的引用,结构体会被撤销。
mmap和mm_rb:描述的对象都是相同的
mmap以链表形式存放, 利于高效地遍历所有元素
mm_rb以红黑树形式存放,适合搜索指定元素
mmlist:所有的mm_struct结构体都通过mmlist连接在一个双向链表中,该链表的首元素是init_mm内存描述符,它代表init进程的地址空间。
在进程的进程描述符(<linux/sched.h>中定义的task_struct结构体)中,mm域记录该进程使用的内存描述符。故current->mm代表当前进程的内存描述符。
fork()函数 利用copy_mm函数复制父进程的内存描述符,子进程中的mm_struct结构体通过allcote_mm()从高速缓存中分配得到。通常,每个进程都有唯一的mm_struct结构体,即唯一的进程地址空间。
当子进程与父进程是共享地址空间,可调用clone(),那么不再调用allcote_mm(),而是仅仅是将mm域指向父进程的mm,即 tsk->mm = current->mm。
相反地,撤销内存是exit_mm()函数,该函数会进行常规的撤销工作,更新一些统计量。
内核线程
没有进程地址空间,即内核线程对应的进程描述符中mm=NULL
内核线程直接使用前一个进程的内存描述符,仅仅使用地址空间中和内核内存相关的信息
- 顶级页表:页全局目录(PGD),指向二级页目录;
- 二级页表:中间页目录(PMD),指向PTE中的表项;
- 最后一级:页表(PTE),指向物理页面。
多数体系结构,搜索页表工作由硬件完成。每个进程都有自己的页表(线程会共享页表)。为了加快搜索,实现了翻译后缓冲器(TLB),作为将虚拟地址映射到物理地址的硬件缓存。还有写时拷贝方式共享页表,当fork()时,父子进程共享页表,只有当子进程或父进程试图修改特定页表项时,内核才创建该页表项的新拷贝,之后父子进程不再共享该页表项。可见,利用共享页表可以消除fork()操作中页表拷贝所带来的消耗。
对于普通进程对应的内存空间包含5种不同的数据区:
- 代码段
- 数据段
- BSS段
- 堆:动态分配的内存段,大小不固定,可动态扩张(malloc等函数分配内存),或动态缩减(free等函数释放);
- 栈:存放临时创建的局部变量;