详解linux里的backlog参数

问题

我们在linux上服务器起了一个serversocket,并且设置了backlog为2,并没有让serversock.accept()

在客户端上,我们一个一个的启动了连接socket, 当连接数目超过3的时候,客户端依然可以继续新建连接。

什么是backlog

说起backlog, 都会想起socket编程中的listen backlog 参数,而这个backlog 是linux内核中处理的backlog么?

int listen(int sockfd, int backlog)

listen 中的backlog解释

The backlog argument defines the maximum length to which the queue of pending connections for sockfd may grow. If a connection request arrives when the queue is full, the client may receive an error with an indication of ECONNREFUSED or, if the underlying protocol supports retransmission, the request may be ignored so that a later reattempt at connection succeeds.

实际上在linux内核2.2版本以后,backlog参数控制的是已经握手成功的还在accept queue的大小。

握手过程中的结构体

struct request_sock_queue {
/*Points to the request_sock accept queue, when after 3 handshake will add the request_sock from syn_table to here*/
    struct request_sock    *rskq_accept_head;
    struct request_sock    *rskq_accept_tail;
    rwlock_t        syn_wait_lock;
    u8            rskq_defer_accept;
    /* 3 bytes hole, try to pack */
    struct listen_sock    *listen_opt;
};
struct listen_sock {
    u8            max_qlen_log; /*2^max_qlen_log is the length of the accpet queue, max of max_qlen_log is 10. (2^10=1024)*/
    /* 3 bytes hole, try to use */
    int            qlen; /* qlen is the current length of the accpet queue*/
    int            qlen_young;
    int            clock_hand;
    u32            hash_rnd;
    u32            nr_table_entries; /*nr_table_entries is the number of the syn_table,max is 512*/
    struct request_sock    *syn_table[0];
};
struct request_sock {
	struct request_sock		*dl_next; /* Must be first member! */
	u16				mss;
	u8				retrans;
	u8				cookie_ts; /* syncookie: encode tcpopts in timestamp */
	/* The following two fields can be easily recomputed I think -AK */
	u32				window_clamp; /* window clamp at creation time */
	u32				rcv_wnd;	  /* rcv_wnd offered first time */
	u32				ts_recent;
	unsigned long			expires;
	const struct request_sock_ops	*rsk_ops;
	struct sock			*sk;
	u32				secid;
	u32				peer_secid;
};
struct sock{
	unsigned short		sk_ack_backlog;
	unsigned short		sk_max_ack_backlog;
}

首先在linux里可以简单的认为有2个队列,一个就是在握手过程中的队列,而另一个就是握手成功的队列

简单的描述一下3个结构体

request_sock

是每一个client的连接(无论是握手成功,还是不成功) 里面的 expires代表的是这个request在队列里的存活时间,而 *sk 就是连接成功的socket的数目

request_sock_queue

rskq_accept_head 队列,也就是握手成功的队列,*listen_opt 是指listen过程中的sock

listen_sock

*syn_table 是指握手没有成功的队列,而qlen,qlen_young 分别指的是队列的长度和队列新成员的个数

在结构体中,我们已经清楚的看到了一个listen_sock中的syn_table,另一个是request_sock_queue中的rskq_accept_head,这就是我们刚才说的两个队列,一个是为正在握手的队列,另一个是已经握手成功的队列。

我们在上面都看到了结构体中只是看到了未握手的队列的长度,并没有看到握手的队列长度统计,实际上握手成功的队列长度是在sock 结构中

sock

当握手成功后每一个client就是一个sock, sk_ack_backlog 是队列长度,而sk_max_ack_backlog是指最大的队列长度

在这里我们会有疑问,难道是没个连接上的 sock都会保留队列的长度么?实际上在此时的sock 代表的是server端listen 的sock而不是客户端的sock,也就是在握手没有成功的过程中,在linux使用的sock都是server的listen的sock, 对客户端只是保留成request_sock

TCP握手的几个阶段

收到客户端的syn请求 ->将这个请求放入syn_table中去->服务器端回复syn-ack->收到客户端的ack->放入accept queue中

我们把整个过程分为5个部分,其中将请求放入syn_table和accept queue中的过程也是backlog相关的,在下面我们会详细阐述。

我们先简单的描述一下几个tcp的操作函数,下面针对的也是ip4协议的

const struct inet_connection_sock_af_ops ipv4_specific = {
	.queue_xmit	   = ip_queue_xmit,
	.send_check	   = tcp_v4_send_check,
	.rebuild_header	   = inet_sk_rebuild_header,
	.conn_request	   = tcp_v4_conn_request,
	.syn_recv_sock	   = tcp_v4_syn_recv_sock,
	.remember_stamp	   = tcp_v4_remember_stamp,
	.net_header_len	   = sizeof(struct iphdr),
	.setsockopt	   = ip_setsockopt,
	.getsockopt	   = ip_getsockopt,
	.addr2sockaddr	   = inet_csk_addr2sockaddr,
	.sockaddr_len	   = sizeof(struct sockaddr_in),
	.bind_conflict	   = inet_csk_bind_conflict,
#ifdef CONFIG_COMPAT
	.compat_setsockopt = compat_ip_setsockopt,
	.compat_getsockopt = compat_ip_getsockopt,
#endif
};

在刚才所说的两个步骤,也就是结构体中的 conn_request 和 syn_recv_sock,  所对应的函数是 tcp_v4_conn_request 和 tcp_v4_syn_recv_sock

我们所重点关注的主要是方法中的drop逻辑

tcp_v4_conn_request 函数

int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
{
	/* Never answer to SYNs send to broadcast or multicast */
	if (skb_rtable(skb)->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST))
		goto drop;

	/* TW buckets are converted to open requests without
	 * limitations, they conserve resources and peer is
	 * evidently real one.
	 */
	if (inet_csk_reqsk_queue_is_full(sk) && !isn) {
#ifdef CONFIG_SYN_COOKIES
		if (sysctl_tcp_syncookies) {
			want_cookie = 1;
		} else
#endif
		goto drop;
	}

	/* Accept backlog is full. If we have already queued enough
	 * of warm entries in syn queue, drop request. It is better than
	 * clogging syn queue with openreqs with exponentially increasing
	 * timeout.
	 */
	if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1)
		goto drop;
....
}
1. inet_csk_reqsk_queue_is_full(sk)

判断的是  queue->listen_opt->qlen >> queue->listen_opt->max_qlen_log;

这里有个 qlen 代表的是listen_opt的 syn_table的长度,那什么是max_qlen_log呢?

nr_table_entries = min_t(u32, nr_table_entries, sysctl_max_syn_backlog);
nr_table_entries = max_t(u32, nr_table_entries, 8);
nr_table_entries = roundup_pow_of_two(nr_table_entries + 1);
for (lopt->max_qlen_log = 3;
	     (1 << lopt->max_qlen_log) < nr_table_entries;
	     lopt->max_qlen_log++);

也就是max_qlen 是listen 传入的backlog和sysctl_max_syn_backlog最小值,并且一定大于16 , roudup_pow_of_two 代表着找最靠近nr_table_entries+1的2的倍数 sysctl_max_syn_backlog 就是我们熟悉的

/proc/sys/net/ipv4/tcp_max_syn_backlog

我们看一下listen 函数在kernel的实现

SYSCALL_DEFINE2(listen, int, fd, int, backlog)
{
	struct socket *sock;
	int err, fput_needed;
	int somaxconn;

	sock = sockfd_lookup_light(fd, &err, &fput_needed);
	if (sock) {
		<span style="color: rgb(255, 102, 102);">somaxconn = sock_net(sock->sk)->core.sysctl_somaxconn;
		if ((unsigned)backlog > somaxconn)
			backlog = somaxconn;</span>

		err = security_socket_listen(sock, backlog);
		if (!err)
			err = sock->ops->listen(sock, backlog);

		fput_light(sock->file, fput_needed);
	}
	return err;
}

我们清楚的看到backlog 并不是按照你调用listen的所设置的backlog大小,实际上取的是backlog和somaxconn的最小值

somaxconn的值定义在

/proc/sys/net/core/somaxconn

2.sk_acceptq_is_full

static inline int sk_acceptq_is_full(struct sock *sk)
{
	return sk->sk_ack_backlog > sk->sk_max_ack_backlog;
}
int inet_listen(struct socket *sock, int backlog)
{
    sk->sk_max_ack_backlog = backlog;
}

就是等于我们刚才在前面部分看到的listen中的值

3.inet_csk_reqsk_queue_young

在判断sk_acceptq_is_full 的情况下,同是也要求了判断inet_csk_reqsk_queue_young>1,也就是刚才的结构体listen_sock的qlen_young

qlen_young 是对syn_table的计数,进入 syn_table 加1,出了syn_table  -1

有的人可能会有疑问了

如果accept queue满了,那么qlen_young不就是一直增加,而新来的客户端都会被条件if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1) 而drop syn的ack包,那么客户端会出现connected timeout, 而实际上你在测试linux的环境中会发现并没有出现这样的情况。

实际上linux在server起socket的时候会调用tcp_keepalive_timer启动tcp_synack_timer,会调用函数inet_csk_reqsk_queue_prune

 if (sk->sk_state == TCP_LISTEN) {
		tcp_synack_timer(sk);
		goto out;
}
static void tcp_synack_timer(struct sock *sk)
{
	inet_csk_reqsk_queue_prune(sk, TCP_SYNQ_INTERVAL,
				   TCP_TIMEOUT_INIT, TCP_RTO_MAX);
}

而inet_csk_reqsk_queue_prune会在去检查syn的table, 而删除一些这个request 过期后并且完成retry 的syn ack包的请求

为了提高inet_csk_reqsk_queue_prune的效率,在request_sock 里加入了 expires(才前面的结构体中已经提到过) , 这个expires初始值是hardcode的3HZ 时间, inet_csk_reqsk_queue_prune会轮训syn_table里的已经exprie request, 发现如果还没有到到retry的次数,那么会增加expire的时间直到重试结束,而expire的时间为剩余retry 次数*3HZ ,并且不大于120HZ

关于retry, retry的参数可以通过设置

/proc/sys/net/ipv4/tcp_syn_retries

当然你可以通过设置

/proc/sys/net/ipv4/tcp_abort_on_overflow 为1 不允许syn ack 重试

因为被inet_csk_reqsk_queue_prune函数清除了syn_table,在没有并发的前提下基本上不会出现inet_csk_reqsk_queue_young>1的情况,也就是说不会出现drop sync的情况,在客户端表现,不会出现connect timeout 的情况(这里的实现linux和mac的实现有很大的不同)而刚开始的问题也能得到合理的解释了

通过函数tcp_v4_conn_request的分析,在linux的设计初衷是尽力的允许新的连接握手,而期望服务器端能更快的响应accept.

我们也许会问,刚才的服务器syn ack回去后,如果客户端也回复了ack的话,而此时accept的queue满了,将会如何处理

我们回到前面提到的步骤,处理客户端的ack 函数也就是

tcp_v4_syn_recv_sock 函数

struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
				  struct request_sock *req,
				  struct dst_entry *dst)
{
	struct inet_request_sock *ireq;
	struct inet_sock *newinet;
	struct tcp_sock *newtp;
	struct sock *newsk;
#ifdef CONFIG_TCP_MD5SIG
	struct tcp_md5sig_key *key;
#endif

	if (sk_acceptq_is_full(sk))
		goto exit_overflow;

	if (!dst && (dst = inet_csk_route_req(sk, req)) == NULL)
		goto exit;

	newsk = tcp_create_openreq_child(sk, req, skb);
	if (!newsk)
		goto exit;

	newsk->sk_gso_type = SKB_GSO_TCPV4;
	sk_setup_caps(newsk, dst);

	newtp		      = tcp_sk(newsk);
	newinet		      = inet_sk(newsk);
	ireq		      = inet_rsk(req);
	newinet->inet_daddr   = ireq->rmt_addr;
	newinet->inet_rcv_saddr = ireq->loc_addr;
	newinet->inet_saddr	      = ireq->loc_addr;
	newinet->opt	      = ireq->opt;
	ireq->opt	      = NULL;
	newinet->mc_index     = inet_iif(skb);
	newinet->mc_ttl	      = ip_hdr(skb)->ttl;
	inet_csk(newsk)->icsk_ext_hdr_len = 0;
	if (newinet->opt)
		inet_csk(newsk)->icsk_ext_hdr_len = newinet->opt->optlen;
	newinet->inet_id = newtp->write_seq ^ jiffies;

	tcp_mtup_init(newsk);
	tcp_sync_mss(newsk, dst_mtu(dst));
	newtp->advmss = dst_metric(dst, RTAX_ADVMSS);
	if (tcp_sk(sk)->rx_opt.user_mss &&
	    tcp_sk(sk)->rx_opt.user_mss < newtp->advmss)
		newtp->advmss = tcp_sk(sk)->rx_opt.user_mss;

	tcp_initialize_rcv_mss(newsk);

#ifdef CONFIG_TCP_MD5SIG
	/* Copy over the MD5 key from the original socket */
	key = tcp_v4_md5_do_lookup(sk, newinet->inet_daddr);
	if (key != NULL) {
		/*
		 * We're using one, so create a matching key
		 * on the newsk structure. If we fail to get
		 * memory, then we end up not copying the key
		 * across. Shucks.
		 */
		char *newkey = kmemdup(key->key, key->keylen, GFP_ATOMIC);
		if (newkey != NULL)
			tcp_v4_md5_do_add(newsk, newinet->inet_daddr,
					  newkey, key->keylen);
		newsk->sk_route_caps &= ~NETIF_F_GSO_MASK;
	}
#endif

	__inet_hash_nolisten(newsk, NULL);
	__inet_inherit_port(sk, newsk);

	return newsk;

exit_overflow:
	NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS);
exit:
	NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
	dst_release(dst);
	return NULL;
}

我们看到了熟悉的函数 sk_acceptq_is_full, 而在此时在无函数inet_csk_reqsk_queue_young>1来保护,也就是说在此时如果发现queue是满的,将直接丢弃只是统计了参数LINUX_MIB_LISTENOVERFLOWSLINUX_MIB_LISTENDROPS而这些参数的值可以通过

netstat -s 来查看到

在函数tcp_v4_syn_recv_sock中我们看到tcp_create_openreq_child,此时才clone出一个新的socket ,也就是只有通过了3次握手后,linux才会产生新的socket, 而在3次握手中所传的socket 实际上是server的listen的 socket, 那也就是说这个socket 只有一个状态TCP_LISTEN

netstat的状态

通过在tcp_rcv_state_process可以置socket 的状态,而我们通常使用netstat 中看到这些socket的状态

case TCP_SYN_RECV:
			if (acceptable) {
				tp->copied_seq = tp->rcv_nxt;
				smp_mb();
				tcp_set_state(sk, TCP_ESTABLISHED);

我们看到从 SYN_RECV的状态直接设置成ESTABLISHED,也就是当server收到client的ack回来,状态置为 TCP_SYN_RECV,而马上进入tcp_rcv_state_process函数置为状态ESTABLISHED,基本没有TCP_SYN_RECV 的状态期,但我们通过netstat  的使用,还是会发现有部分socket 还是会处于SYN_RECV状态,实际上这通常是在syn_table的request, 为了显示还没有通过三次握手的连接的状态,这时候request 还在syn table里,并且还没有属于自己的socket对象,linux 把这些信息写到了

/proc/net/tcp

而在TCP_SEQ_STATE_OPENREQ 的情况下(就是 syn synack ack)的3个状态下都显示成TCP_SYN_RECV

static void get_openreq4(struct sock *sk, struct request_sock *req,
			 struct seq_file *f, int i, int uid, int *len)
{
	const struct inet_request_sock *ireq = inet_rsk(req);
	int ttd = req->expires - jiffies;

	seq_printf(f, "%4d: %08X:%04X %08X:%04X"
		" %02X %08X:%08X %02X:%08lX %08X %5d %8d %u %d %p%n",
		i,
		ireq->loc_addr,
		ntohs(inet_sk(sk)->inet_sport),
		ireq->rmt_addr,
		ntohs(ireq->rmt_port),
		TCP_SYN_RECV,
		0, 0, /* could print option size, but that is af dependent. */
		1,    /* timers active (only the expire timer) */
		jiffies_to_clock_t(ttd),
		req->retrans,
		uid,
		0,  /* non standard timer */
		0, /* open_requests have no inode */
		atomic_read(&sk->sk_refcnt),
		req,
		len);
}

而对ESTABLISHED状态,并不需要server.accept,只要在accept queue里就已经变成状态ESTABLISHED

到此这篇关于详解linux里的backlog参数的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Linux和GNU系统的关系详解

    目录 每天都在运行的Linux系统其实是? Linux内核 和 GNU 系统简介 Linux内核 和 GNU 系统之间的关系详解 总结 每天都在运行的Linux系统其实是? 今天广泛使用的 GNU 版本通常被称为“Linux”,而它的许多用户并不知道 它基本上是由GNU 项目开发的 GNU 系统 . Linux内核 和 GNU 系统简介 确实有一个 Linux,这些人正在使用它,但它只是他们使用的系统的一部分.Linux 是内核:系统中的程序,它将机器的资源分配给您运行的其他程序.内核是操作系统

  • Linux系统配置网络详细介绍

    上一篇文章已经安装好了虚拟机和Linux系统了,这次就来简单的说一下LInux系统的网络配置吧 简单介绍Linux的文件夹 bin:存放的是用户的命令 sbin:存放的是root用户的命令 etc:存放的是当前系统的环境配置文件 home:存放用户的 root:存放root用户的 opt:是可以用来存放软件的 usr:其子文件夹-->local也是可以用来存放用户需要的软件的 tmp:表示临时,通常存放日志文件 可视化配置网络 首先得查看一下自己的Linux系统是否链接网络,大家可以打开Linu

  • Linux上搭载Nginx负载均衡配置使用案例详解

    目录 1,这里我们来说下很重要的负载均衡, 那么什么是负载均衡呢? 2, 负载均衡的种类 3, 这里我们只来说Nginx(其他的大家有兴趣可以自行查阅相关文档) 4, 创建两台Nginx服务器 5, 搭建Nginx 搭建Keepalived:(Keepalived需要依赖openssl) 1,这里我们来说下很重要的负载均衡, 那么什么是负载均衡呢? 由于目前现有网络的各个核心部分随着业务量的提高,访问量和数据流量的快速增长,其处理能力和计算强度也相应地增大,使得单一的服务器设备根本无法承担.在此

  • 解决redis在linux上的部署的问题

    1.在官网下载Linux版本redis 2.拷贝到linux服务器上,解压到指定目录 3.解压后得到redis文件夹-----移动到自己知道的文件位置 4.注:redis是c语言编写,需要依托c语言环境 yum install gcc-c++ tcl 进入到redis安装目录 执行 make---------------编译redis 注意:redis6以上版本make编译可能报错,需要升级gcc版本 #第一步 sudo yum install centos-release-scl #第二步 s

  • mongodb linux下集群搭建过程

    mongodb的集群结构如上图 网上有个mongo3.0的集群例子: https://www.jb51.net/article/191388.htm router提供入口,mongo客户端通过router连入集群(本例只配置一个route集群) Config Servers辅助记录数据分片(一个集群) Shard为数据分片集群(本例中配置两个,用于验证分片), 本例中,为每个集群(shard config)三个mongo实例 config与shard为同一个类型的进程mongod route则为

  • Linux快速部署Redis

    有必要么? 对咱们来说,部署服务器环境不是一个高频操作.所以很多同学都不会花很多时间去记忆,一般都是直接百度(连链接都懒得收藏).每次要部署环境的时候就觉得麻烦,从心底里讨厌它.除了消耗时间,还会想:我也不是运维啊,搞这干啥?但对公司来说,你拿钱就得解决问题,况且有多少公司开发运维都有人?所以既然必须要做,那怎样让自己更舒服才重要. 写个脚本 咱们先来写个脚本,对了这里说的是centos.首先在任意目录下新建一个脚本文件: vi redis-install.sh 然后点击[i]开启编辑模式,把下

  • Linux中Go环境配置和GoModule常用操作

    我为什么要学习go语言 当今已经是移动和云计算时代,Go出现在了工业向云计算转型的时刻,简单.高效.内 置并发原语和现代的标准库让Go语言尤其适合云端软件开发(毕竟它就是为此而设计的).到2014年,Go项目拥有了上百的核心贡献者,其生态圈中拥有了数不尽的第三方库和工具(https://godoc.org/),更有很多大公司开始或迁移到go语言,一些重量级的开源云项目,诸如Docker和Kubernetes 都是用Go语言实现的,一些运作基础设置的公司,诸如Google.CloudFlare.C

  • Linux系统下gcc命令使用详解

    目录 一.预处理 二. 编译 三.汇编 四.链接 1.gcc的安装(以Ubuntu为例) sudo apt-get install build-essential 安装完后可以通过 gcc --version 查看版本. 让我们在通过gcc编译可执行文件的过程中掌握其基础应用. 准备: 先在当前目录下 使用vim新建一个.c文件 例如 666.c $ vim 666.c (vim的使用可在我的另一篇博客有详细的叙述,这里不多在赘述) 插入一段代码. #include <stdio.h> mai

  • 详解linux里的backlog参数

    问题 我们在linux上服务器起了一个serversocket,并且设置了backlog为2,并没有让serversock.accept() 在客户端上,我们一个一个的启动了连接socket, 当连接数目超过3的时候,客户端依然可以继续新建连接. 什么是backlog 说起backlog, 都会想起socket编程中的listen backlog 参数,而这个backlog 是linux内核中处理的backlog么? int listen(int sockfd, int backlog) lis

  • 详解Linux中查看jdk安装目录、Linux卸载jdk、rpm命令、rm命令参数

    一.查看jdk安装目录 [root@node001 ~]# whereis java java: /usr/bin/java /usr/local/java #java执行路径 [root@node001 ~]# which java /usr/bin/java #查看JDK安装路径 [root@node001 ~]# echo $JAVA_HOME /usr/local/java/jdk1.7.0_80 [root@node001 ~]# echo $PATH /usr/local/sbin:

  • 详解linux正则表达式(基础正则表达式+扩展正则表达式)

    正则表达式应用非常广泛,例如:php,Python,java等,但在linux中最常用的正则表达式的命令就是grep(egrep),sed,awk等,换句话 说linux三剑客要想能工作的更高效,就一定离不开正则表达式的配合. 1.什么是正则表达式? 简单的说,正则表达式就是为处理大量的字符串而定义的一套规则和方法.通过定义的这些特殊符号的辅助,系统管理员就可以快速过滤.替换或者输出需要的字符串.linux正则表达式一般以行为单位处理的. 2.为什么要学正则表达式 在企业工作中,我们每天做的li

  • 详解Linux重定向用法

    相信大家平时都会有需要复制粘贴数据的时候,如果是打开文件进行复制粘贴,就不可避免的需要较多的鼠标与键盘的操作,就会比较繁琐.那么有没有可以省掉这些繁琐操作的复制粘贴的方法呢? 答案是肯定的,那就是重定向.重定向是一种高效的方法,无需大量的鼠标与键盘操作就可以完成数据的转移.重定向可以分为输入重定向以及输出重定向这两种类型.由于所有程序都有输入或者输出,因此输入和输出的重定向是任何编程语言或脚本语言都自带的功能. 每当你与计算机交互时,重定向就必然会发生.学会使用重定向,不仅可以让你与计算机更好地

  • 详解Linux使用ss命令结合zabbix对socket做监控

    前言 这里我们使用zabbix对其进行监控,使用的是ss命令,不使用netstat命令,因为ss的速度快很多,不信的话可以去测一下哈,一台机器的socket越多,对比越明显.而且ss命令能显示更多的内容,其实我对这两个命令不是特别的熟悉,通过man ss可以看到: 一.ss命令 ss命令用于显示socket状态. 他可以显示PACKET sockets, TCP sockets, UDP sockets, DCCP sockets, RAW sockets, Unix domain socket

  • 详解Linux 主机网络接入配置

    详解Linux 主机网络接入配置 前言: 网络配置是我们在安装好操作系统之后,需要解决的第一步.现时代没有接入网络的主机已然等同于一堆废铁.在网络配置的过程中,通常我们需要配置本机IP地址,缺省网关,DNS,主机名等等.本文主要描述在Linux环境下,主要以传统命令行方式讲解如何将主机接入网络.对于网路配置的新命令如ip,nmcli等等在以后的文章中描述. 一.网络配置概述 主机接入互联网前提:遵循TCP/IP协议栈 配置主机接入TCP/IP网络需要配置的内容:   IP/Netmask   路

  • 详解Linux命令iostat

    Linux系统出现了性能问题,一般我们可以通过top.iostat.free.vmstat等命令来查看初步定位问题.在一个以前看到系统监控工具,总在想那些监控工具的代理,如何收集系统性能信息,io性能,cpu使用,带宽使用等信息,偶然发现,不同系统均提供有性能分析工具的,代理可通过这些命令获取系统性能信息,个人猜测,不知道具体是不是这样的.其中iostat可以给我们提供丰富的IO状态数据,下边就来看一下iostat如何使用,命令能够输出那些信息. 简述 Linux系统中通过iostat我们能查看

  • 详解linux下利用crontab创建定时任务

    Linux下可以利用crontab创建定时任务. 常用搭配 crontab -e 编辑任务 crontab -l 查看所有任务[该用户] crontab -r 取消所有任务[该用户] 任务格式 × × × × × +命令(具体任务) 前5个参数表示时间,依次为: 参数 范围 分钟 0-59 小时 0-23 日期 1-31 月份 1-12 星期 0-6(0代表星期日) 特殊符号 为了精确表示定时,需要一些特殊符号来描述具体的任务执行时间.有以下几个符号: "/" 代表每,每隔多长时间 &

  • 详解Linux文本文件与WIN文本文件换行格式转换命令

    详解Linux文本文件与WIN文本文件换行格式转换命令 前言: 有 时在WIN下编辑好的脚本文件上传到LINUX服务器中不能正常执行,开始误认为是LINUX配置问题,后来发现,是WIN与LINUX存储文件时的换行 符标志不同造成的.在DOS使用的换行符为 ^M$,我们称为CR与LF两个符号.而在Linux中,则仅有LF ($) 这个换行符. 可以用如下命令完成格式转换:$dos2unix,$unix2dos.但这两个命令在UBUNTU发行版本中不存在,可通过: $sudo apt-get ins

  • 详解linux SSH登录流程

    本文给大家详细介绍了ssh 密钥登录远程服务器流程和注意事项,以下是详细内容: 密钥登录比密码登录安全,主要是因为他使用了非对称加密,登录过程中需要用到密钥对.整个登录流程如下: 远程服务器持有公钥,当有用户进行登录,服务器就会随机生成一串字符串,然后发送给正在进行登录的用户. 用户收到远程服务器发来的字符串,使用与远程服务器公钥配对的私钥对字符串进行加密,再发送给远程服务器. 服务器使用公钥对用户发来的加密字符串进行解密,得到的解密字符串如果与第一步中发送给客户端的随机字符串一样,那么判断为登

随机推荐