如何查看linux服务器的配置

如何查看linux服务器的配置,第1张

1、首先,连接相应linux主机,进入到linux命令行状态下,等待输入shell指令。

2、在linux命令行下输入shell指令:cat /proc/cpuinfo,按回车,会看到cpu的信息。

3、输入shell指令:fdisk -l,按回车,会看到硬盘的信息。

1、查看apache当前并发访问数:

#对比httpd.conf中MaxClients的数字差距多少。

netstat -an | grep ESTABLISHED | wc -l

2、查看httpd进程数(即prefork模式下Apache能够处理的并发请求数):

ps aux|grep httpd|wc -l

3、可以使用如下参数查看数据

ps -ef|grep httpd|wc -l

#1388

#统计httpd进程数,连个请求会启动一个进程,使用于Apache服务器。

#表示Apache能够处理1388个并发请求,这个值Apache可根据负载情况自动调整。

netstat -nat|grep -i "80"|wc -l

#4341

#netstat -an会打印系统当前网络链接状态,而grep -i "80"是用来提取与80端口有关的连接的,wc -l进行连接数统计。

#最终返回的数字就是当前所有80端口的请求总数。

netstat -na|grep ESTABLISHED|wc -l

#376

#netstat -an会打印系统当前网络链接状态,而grep ESTABLISHED 提取出已建立连接的信息。 然后wc -l统计。

#最终返回的数字就是当前所有80端口的已建立连接的总数。

netstat -nat||grep ESTABLISHED|wc

#可查看所有建立连接的详细记录

4、查看Apache的并发请求数及其TCP连接状态:

 

netstat -n | awk '/^tcp/ {++S[$NF]} END {for (a in S) print a, S[a]}'

(这条语句是从 新浪互动社区事业部 新浪互动社区事业部技术总监王老大那儿获得的,非常不错)返回结果示例:

 

 

LAST_ACK 5

SYN_RECV 30

ESTABLISHED 1597

FIN_WAIT1 51

FIN_WAIT2 504

TIME_WAIT 1057

其中:

SYN_RECV表示正在等待处理的请求数;

ESTABLISHED表示正常数据传输状态;

TIME_WAIT表示处理完毕,等待超时结束的请求数。

5、输出每个ip的连接数,以及总的各个状态的连接数

netstat -n | awk '/^tcp/ {n=split($(NF-1),array,":")if(n<=2)++S[array[(1)]]else++S[array[(4)]]++s[$NF]++N} END {for(a in S){printf("%-20s %s\n", a, S[a])++I}printf("%-20s %s\n","TOTAL_IP",I)for(a in s) printf("%-20s %s\n",a, s[a])printf("%-20s %s\n","TOTAL_LINK",N)}'

1、sys_connect

对于客户端来说,当创建了一个套接字后,就可以连接它了。

case SYS_CONNECT:

err = sys_connect(a0, (struct sockaddr __user *)a1, a[2])

break[/code]

asmlinkage long sys_connect(int fd, struct sockaddr __user *uservaddr, int addrlen)

{

struct socket *sock

char address[MAX_SOCK_ADDR]

int err

sock = sockfd_lookup(fd, &err)

if (!sock)

goto out

err = move_addr_to_kernel(uservaddr, addrlen, address)

if (err <0)

goto out_put

err = security_socket_connect(sock, (struct sockaddr *)address, addrlen)

if (err) goto out_put

err = sock->ops->connect(sock, (struct sockaddr *) address, addrlen,

sock->file->f_flags)

out_put:

sockfd_put(sock)

out:

return err

}

跟其它 *** 作类似,sys_connect 接着调用 inet_connect:

/*

*Connect to a remote host. There is regrettably still a little

*TCP 'magic' in here.

*/

int inet_stream_connect(struct socket *sock, struct sockaddr *uaddr,

int addr_len, int flags)

{

struct sock *sk = sock->sk

int err

long timeo

lock_sock(sk)

if (uaddr->sa_family == AF_UNSPEC) {

err = sk->sk_prot->disconnect(sk, flags)

sock->state = err ? SS_DISCONNECTING : SS_UNCONNECTED

goto out

}

提交的协议簇不正确,则断开连接。

switch (sock->state) {

default:

err = -EINVAL

goto out

case SS_CONNECTED:

err = -EISCONN

goto out

case SS_CONNECTING:

err = -EALREADY

/* Fall out of switch with err, set for this state */

break[/code] socket 处于不正确的连接状态,返回相应的错误值。

case SS_UNCONNECTED:

err = -EISCONN

if (sk->sk_state != TCP_CLOSE)

goto out

/*调用协议的连接函数*/

err = sk->sk_prot->connect(sk, uaddr, addr_len)

if (err <0)

goto out

/*协议方面的工作已经处理完成了,但是自己的一切工作还没有完成,所以切换至正在连接中*/

sock->state = SS_CONNECTING

/* Just entered SS_CONNECTING statethe only

* difference is that return value in non-blocking

* case is EINPROGRESS, rather than EALREADY.

*/

err = -EINPROGRESS

break

}

对于 TCP的实际的连接,是通过调用 tcp_v4_connect()函数来实现的。

二、tcp_v4_connect函数

对于 TCP 协议来说,其连接,实际上就是发送一个 SYN 报文,在服务器的应到到来时,回答它一个 ack 报文,也就是完成三次握手中的第一和第三次。

要发送 SYN 报文,也就是说,需要有完整的来源/目的地址,来源/目的端口,目的地址/端口由用户态提交,但是问题是没有自己的地址和端口,因为并没有调 用过 bind(2),一台主机,对于端口,可以像 sys_bind()那样,从本地未用端口中动态分配一个,那地址呢?因为一台主机可能会存在多个 IP地 址,如果随机动态选择,那么有可能选择一个错误的来源地址,将不能正确地到达目的地址。换句话说,来源地址的选择,是与路由相关的。

调用路由查找的核心函数 ip_route_output_slow(),在没有提供来源地址的情况下,会根据实际情况,调用 inet_select_addr()函数来选择一个合适的。同时,如果路由查找命中,会生成一个相应的路由缓存项,这个缓存项,不但对当前发送 SYN 报 文有意义,对于后续的所有数据包,都可以起到一个加速路由查找的作用。这一任务,是通过 ip_route_connect()函数完成的,它返回相应的路由缓存项(也就是说,来源地址也在其中了):

static inline int ip_route_connect(struct rtable **rp, u32 dst,

u32 src, u32 tos, int oif, u8 protocol,

u16 sport, u16 dport, struct sock *sk)

{ struct flowi fl = { .oif = oif,

.nl_u = { .ip4_u = { .daddr = dst,

.saddr = src,

.tos = tos } },

.proto = protocol,

.uli_u = { .ports =

{ .sport = sport,

.dport = dport } } }

int err

if (!dst || !src) {

err = __ip_route_output_key(rp, &fl)

if (err)

return err

fl.fl4_dst = (*rp)->rt_dst

fl.fl4_src = (*rp)->rt_src

ip_rt_put(*rp)

*rp = NULL

}

return ip_route_output_flow(rp, &fl, sk, 0)

}

首先,构建一个搜索 key fl,在搜索要素中,来源地址/端口是不存在的。所以,当通过__ip_route_output_key 进行查找时,第一次是不会命中缓存的。 __ip_route_output_key 将继续调用ip_route_output_slow()函数,在路由表中搜索,并返回一个合适的来源地址, 并且生成一个路由缓存项。 路由查找的更多细节,我会在另一个贴子中来分析。

/* This will initiate an outgoing connection. */

int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)

{

struct inet_sock *inet = inet_sk(sk)

struct tcp_sock *tp = tcp_sk(sk)

struct sockaddr_in *usin = (struct sockaddr_in *)uaddr

struct rtable *rt

u32 daddr, nexthop

int tmp

int err

if (addr_len <sizeof(struct sockaddr_in))

return -EINVAL

if (usin->sin_family != AF_INET)

return -EAFNOSUPPORT

校验地址长度和协议簇。

nexthop = daddr = usin->sin_addr.s_addr

将下一跳地址和目的地址的临时变量都暂时设为用户提交的地址。

if (inet->opt &&inet->opt->srr) {

if (!daddr)

return -EINVAL

nexthop = inet->opt->faddr

}

如果使用了来源地址路由,选择一个合适的下一跳地址。

tmp = ip_route_connect(&rt, nexthop, inet->saddr,

RT_CONN_FLAGS(sk), sk->sk_bound_dev_if,

IPPROTO_TCP,

inet->sport, usin->sin_port, sk)

if (tmp <0)

return tmp

if (rt->rt_flags &(RTCF_MULTICAST | RTCF_BROADCAST)) {

ip_rt_put(rt)

return -ENETUNREACH

}

进行路由查找,并校验返回的路由的类型,TCP是不被允许使用多播和广播的。

if (!inet->opt || !inet->opt->srr)

daddr = rt->rt_dst

更新目的地址临时变量——使用路由查找后返回的值。

if (!inet->saddr)

inet->saddr = rt->rt_src

inet->rcv_saddr = inet->saddr

如果还没有设置源地址,和本地发送地址,则使用路由中返回的值。

if (tp->rx_opt.ts_recent_stamp &&inet->daddr != daddr) {

/* Reset inherited state */

tp->rx_opt.ts_recent = 0

tp->rx_opt.ts_recent_stamp = 0

tp->write_seq = 0

}

if (sysctl_tcp_tw_recycle &&

!tp->rx_opt.ts_recent_stamp &&rt->rt_dst == daddr) {

struct inet_peer *peer = rt_get_peer(rt)

/* VJ's idea. We save last timestamp seen from

* the destination in peer table, when entering state TIME-WAIT

* and initialize rx_opt.ts_recent from it, when trying new connection.

*/

if (peer &&peer->tcp_ts_stamp + TCP_PAWS_MSL >= xtime.tv_sec) {

tp->rx_opt.ts_recent_stamp = peer->tcp_ts_stamp

tp->rx_opt.ts_recent = peer->tcp_ts

}

}

这个更新初始状态方面的内容,还没有去分析它。

inet->dport = usin->sin_port

inet->daddr = daddr

保存目的地址及端口。

tp->ext_header_len = 0

if (inet->opt)

tp->ext_header_len = inet->opt->optlen

tp->rx_opt.mss_clamp = 536

设置最小允许的 mss 值

tcp_set_state(sk, TCP_SYN_SENT)

套接字状态被置为 TCP_SYN_SENT,

err = tcp_v4_hash_connect(sk)

if (err)

goto failure

动态选择一个本地端口,并加入 hash 表,与bind(2)选择端口类似。

err = ip_route_newports(&rt, inet->sport, inet->dport, sk)

if (err)

goto failure

/* OK, now commit destination to socket. */

__sk_dst_set(sk, &rt->u.dst)

tcp_v4_setup_caps(sk, &rt->u.dst)

因为本地端口已经改变,使用新端口,重新查找路由,并用新的路由缓存项更新 sk 中保存的路由缓存项。

if (!tp->write_seq)

tp->write_seq = secure_tcp_sequence_number(inet->saddr,

inet->daddr,

inet->sport,

usin->sin_port)

为 TCP报文计算一个 seq值(实际使用的值是 tp->write_seq+1)。

inet->id = tp->write_seq ^ jiffies

err = tcp_connect(sk)

rt = NULL

if (err)

goto failure

return 0

tp_connect()函数用来根据 sk 中的信息,构建一个完成的 syn 报文,并将它发送出去。在分析 tcp栈的实现时再来分析它。

根据 TCP协议,接下来的问题是,

1、可能收到了服务器的应答,则要回送一个 ack 报文;

2、如果超时还没有应答,则使用超时重发定时器;


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/7634953.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-08
下一篇 2023-04-08

发表评论

登录后才能评论

评论列表(0条)

保存