操作系统启动过程一般分为五个阶段:(centos7为例)
上电后,主板BIOS运行POST(Power on self test)代码,进行开机自检,检查硬件:CPU、内存、显卡、硬盘、CD-ROM、串口、并口、软驱等。
自检硬件没有问题时候,这里以BIOS为例,BIOS将会直接找硬盘的第一个扇区,找到前446字节,将MBR加载到内存中,MBR将告诉程序下一阶段去哪里找系统的grub引导。此阶段属于grub第1阶段。grub还有1.5阶段和2阶段。
主要操作是装载stage1,装载stage1.5,装载stage2。
然后读取/boot/grub.conf文件显示启动菜单,装载所选的kernel和initrd文件到内存中。
grub启动三阶段:
stage1: 引导安装在MBR中的引导程序(bootloader)
stage1.5: mbr之后的扇区,让stage1中的bootloader能识别stage2所在的分区上的文件系统;
stage2:读取存放在磁盘上的grub(存放位置:/boot/grub),grub的配置文件:/boot/grub/grub.conf,在etc目录下有此文件的连接文件:/etc/grub.conf
加载内核,核心开始解压,启动一些最核心的程序。
为了让内核足够的轻小,硬件驱动并没放在内核文件里面。
kernel内核开始初始化,用systemd来代替centos6以前的init程序
先执行initrd.target
包括挂载/etc/fstab文件中系统,挂载之后,就可以切换到根目录。
从initramfs根文件系统切换到磁盘的根目录
systemd执行默认target配置
centos7表面有“运行级别”这个概念,实际是为了兼容以前的系统,每个所谓“运行级别”都有对应的软连接指向,默认的启动级别/etc/systemd/system/default.target,根据它的指向可以找到系统要进入到哪个模式。
模式:
0 ==> runlevel0.target, poweroff.target
1 ==> runlevel1.target, rescue.target
2 ==> runlevel2.target, multi-user.target
3 ==> runlevel3.target, multi-user.target
4 ==> runlevel4.target, multi-user.target
5 ==> runlevel5.target, graphical.target
6 ==> runlevel6.target, reboot.target
systemd执行sysinit.target
systemd启动multi-user.target下的本机与服务器服务
systemd执行multi-user.target下面的/etc/rc.d/rc.local
systemd执行multi-user.target下的getty.target及登录服务
getty.target是启动终端的systemd对象。如果到此步骤,系统没有指定启动图形桌面,到此就可以结束,如果需要启动图形界面,要在此基础上启动桌面程序。
systemd执行graphical图形化需要的服务
至此系统启动完成,可以正常使用。
内核命令行参数(也称为内核参数)仅用于在引导时自定义Linux的行为。
内核命令行参数保存在boot/grub/grub.cfg配置文件中,该文件为 由GRUB2引导加载程序生成。不要编辑此配置文件。仅对该文件所做的更改,由配置脚本制作。
内核可调参数用于在引导时或在系统运行时按需自定义Linux的行为。 一些硬件参数仅在引导时指定,并且一旦系统运行就无法更改,但是大多数硬件参数可以根据需要进行更改,并在下次引导时永久设置。
使用sysctl命令
sysctl命令用于列出,读取和设置内核可调参数。 当列出或读取或临时设置或永久设置可调参数时,它可以过滤可调参数。
要在引导时覆盖默认值,还可以在/etc/sysctl.d中手动填充文件。
在Linux系统下,使用sysctl命令可以查看和修改系统参数,添加一个系统参数的方法:
在source/net/ipv4/sysctl_net_ipv4.c文件中有这样一个结构体数组
static struct ctl_table ipv4-table[] = {
......
},
{
......
}
......
在目录/proc/sys/net/ipv4/下面所有的系统参数都得先到这里注册,下面给出一个具体例子。
{
.procname = "tcp_vegas_alpha",
.data = &sysctl_tcp_vegas_alpha,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec
},
{
.procname = "tcp_vegas_beta",
.data = &sysctl_tcp_vegas_alpha,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec
}
这两个参数是拥塞控制算法Vegas在拥塞控制阶段调节cwnd用的。
这里是struct ctl_table的具体定义。
/* 结构位置:include/linux/sysctl.h */
struct ctl_table
{
const char *procname; /* Text ID for /proc/sys, or zero */
void *data;
int maxlen;
umode_t mode;
struct ctl_table *child; /* Deprecated */
proc_handler *proc_handler; /* Callback for text formatting */
struct ctl_tabel_poll *poll;
void *extral;
void *extra2;
};
现在简单介绍一下这些结构体成员变量。
*procname 表示在/proc/sys/下显示的文件名称,
*data 表示对应于内核中的变量名称,
maxlen 表示允许的最大长度,
mode 表示访问权限,
proc_handler表示回调函数,有一些常用取值:
porc_dointvec 读写包含一个或多个整数的数组,
proc_dostring 读写一个字符串,
proc_dointvec_minmax 写的整数必须在min~max范围内。
用于TCP的内核参数在source/include/net/tcp.h声明。
/* 进入tcp.h文件可以看到大量的变量声明,这里只列出上文提及到的两个变量 */
...
extern int sysctl_tcp_vegas_alpha;
extern int sysctl_tcp_vegas_beta
...
内核参数的定义可能在不同的文件中,这个根据内核参数的用途而定。
systcl_tcp_vegas_alpha和sysctl_tcp_vegas_beta这两个变量的定义位置:
source/net/ipv4/tcp_retrans.c
int sysctl_tcp_vegas_alpha = 2;
int sysctl_tcp_vegas_beta = 4;
经过上面这些步骤,内核参数就添加成功了,当我们编译重启系统后,就会发现在目录:/proc/sys/net/ipv4/下有两个文件分别是tcp_vegas_alpha和tcp_vegas_beta,以后就可以通过echo命令动态修改这两个值。
下列文件所在目录:/proc/sys/net/ipv4/
名称 | 默认值 | 描述 |
---|---|---|
tcp_syn_retries | 5 | 对于一个新建连接,内核要发送多少个 SYN 连接请求才决定放弃。不应该大于255,默认值是5,对应于180秒左右时间。。(对于大负载而物理通信良好的网络而言,这个值偏高,可修改为2.这个值仅仅是针对对外的连接,对进来的连接,是由tcp_retries1决定的) |
tcp_synack_retries | 5 | 对于远端的连接请求SYN,内核会发送SYN + ACK数据报,以确认收到上一个 SYN连接请求包。这是所谓的三次握手( threeway handshake)机制的第二个步骤。这里决定内核在放弃连接之前所送出的 SYN+ACK 数目。不应该大于255,默认值是5,对应于180秒左右时间。 |
tcp_keepalive_time | 7200 | TCP发送keepalive探测消息的间隔时间(秒),用于确认TCP连接是否有效。防止两边建立连接但不发送数据的攻击 |
tcp_keepalive_probes | 9 | TCP发送keepalive探测消息的间隔时间(秒),用于确认TCP连接是否有效。 |
tcp_keepalive_intvl | 75 | 探测消息未获得响应时,重发该消息的间隔时间(秒)。默认值为75秒。 (对于普通应用来说,这个值有一些偏大,可以根据需要改小.特别是web类服务器需要改小该值,15是个比较合适的值) |
tcp_retries1 | 3 | 放弃回应一个TCP连接请求前﹐需要进行多少次重试。RFC规定最低的数值是3 |
tcp_retries2 | 15 | 在丢弃激活(已建立通讯状况)的TCP连接之前﹐需要进行多少次重试。默认值为15,根据RTO的值来决定,相当于13-30分钟(RFC1122规定,必须大于100秒).(这个值根据目前的网络设置,可以适当地改小) |
tcp_orphan_retries | 7 | 在近端丢弃TCP连接之前﹐要进行多少次重试。默认值是7个﹐相当于 50秒 - 16分钟﹐视 RTO 而定。如果您的系统是负载很大的web服务器﹐那么也许需要降低该值﹐这类 sockets 可能会耗费大量的资源。另外参的考tcp_max_orphans。(事实上做NAT的时候,降低该值也是好处显著的) |
tcp_fin_timeout | 60 | 对于本端断开的socket连接,TCP保持在FIN-WAIT-2状态的时间。对方可能会断开连接或一直不结束连接或不可预料的进程死亡。默认值为 60 秒 |
tcp_max_tw_buckets | 180000 | 系统在同时所处理的最大 timewait sockets 数目。如果超过此数的话﹐time-wait socket 会被立即砍除并且显示警告信息。之所以要设定这个限制﹐纯粹为了抵御那些简单的 DoS 攻击﹐不过﹐如果网络条件需要比默认值更多﹐则可以提高它(或许还要增加内存)。(事实上做NAT的时候最好可以适当地增加该值) |
tcp_tw_recycle | 0 | 打开快速 TIME-WAIT sockets 回收。除非得到技术专家的建议或要求﹐请不要随意修改这个值。(做NAT的时候,建议打开它) |
tcp_tw_reuse | 8192 | 系统所能处理不属于任何进程的TCP sockets最大数量。假如超过这个数量﹐那么不属于任何进程的连接会被立即reset,并同时显示警告信息。之所以要设定这个限制﹐纯粹为了抵御那些简单的 DoS 攻击﹐千万不要依赖这个或是人为的降低这个限制。如果内存大更应该增加这个值。(这个值Redhat AS版本中设置为32768,但是很多防火墙修改的时候,建议该值修改为2000) |
tcp_abort_on_overflow | 0 | 当守护进程太忙而不能接受新的连接,就象对方发送reset消息,默认值是false。这意味着当溢出的原因是因为一个偶然的猝发,那么连接将恢复状态。只有在你确信守护进程真的不能完成连接请求时才打开该选项,该选项会影响客户的使用。(对待已经满载的sendmail,apache这类服务的时候,这个可以很快让客户端终止连接,可以给予服务程序处理已有连接的缓冲机会,所以很多防火墙上推荐打开它) |
tcp_syncookies | 0 | 只有在内核编译时选择了CONFIG_SYNCOOKIES时才会发生作用。当出现syn等候队列出现溢出时象对方发送syncookies。目的是为了防止syn flood攻击。 |
tcp_stdurg | 0 | 使用 TCP urg pointer 字段中的主机请求解释功能。大部份的主机都使用老旧的 BSD解释,因此如果您在 Linux打开它﹐或会导致不能和它们正确沟通。 |
等等。
所处目录/proc/sys/net/ipv4/netfilter/
文件需要打开防火墙才会存在
名称 | 默认值 | 描述 |
---|---|---|
ip_conntrack_max | 65536 | 系统支持的最大ipv4连接数,默认65536(事实上这也是理论最大值),同时这个值和你的内存大小有关,如果内存128M,这个值最大8192,1G以上内存这个值都是默认65536,这个值受/proc/sys/net/ipv4/ip_conntrack_max限制 |
ip_conntrack_tcp_timeout_established | 432000 | 已建立的tcp连接的超时时间,默认432000,也就是5天。影响:这个值过大将导致一些可能已经不用的连接常驻于内存中,占用大量链接资源,从而可能导致NAT ip_conntrack: table full的问题。建议:对于NAT负载相对本机的 NAT表大小很紧张的时候,可能需要考虑缩小这个值,以尽早清除连接,保证有可用的连接资源;如果不紧张,不必修改 |
ip_conntrack_tcp_timeout_time_wait | 120 | time_wait状态超时时间,超过该时间就清除该连接 |
ip_conntrack_tcp_timeout_close_wait | 60 | close_wait状态超时时间,超过该时间就清除该连接 |
ip_conntrack_tcp_timeout_fin_wait | 120 | fin_wait状态超时时间,超过该时间就清除该连接 |
等等。
文件所处目录/proc/sys/net/core/
名称 | 默认值 | 描述 |
---|---|---|
netdev_max_backlog | 1024 | 每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目,对重负载服务器而言,该值需要调高一点。 |
somaxconn | 128 | 用来限制监听(LISTEN)队列最大数据包的数量,超过这个数量就会导致链接超时或者触发重传机制。web应用中listen函数的backlog默认会给我们内核参数的net.core.somaxconn限制到128,而nginx定义的NGX_LISTEN_BACKLOG默认为511,所以有必要调整这个值。对繁忙的服务器,增加该值有助于网络性能 |
wmem_default | 129024 | 默认的发送窗口大小(以字节为单位) |
rmem_default | 129024 | 默认的接收窗口大小(以字节为单位) |
rmem_max | 129024 | 最大的TCP数据接收缓冲 |
wmem_max | 129024 | 最大的TCP数据发送缓冲 |
等等。