IPVS规则工作在INPUT链上,改变了数据报文形成,直接从INPUT链到达POSTROUTING;
LVS: ipvsadm/ipvs
INPUT: --> POSTROUTING
ipvsadm:
管理服务:
-A: 添加集群服务
-E: 修改集群服务
-D: 删除集群服务
管理RS:
-a: 向已有的集群服务添加realserver
-e:修改添加的realserver
-d: 删除添加的realserver
查看:
-L|-l 查看集群服务
-n: 数字显示IP地址和端口号;
--stats: 显示统计信息
--rate: 速率
--timeout: 显示tcp、tcpfin和udp会话超时时长;
--sort: 排序
--daemon: 显示进程状态以及多播端口的
规则管理
-C: 清空ipvs规则
-S: 保存规则到文件
-R: 从文件中加载规则
DR:
VIP: MAC(DVIP)
arptables:
kernel parameter: 内核参数配置
arp_ignore:接收到ARP请求时的响应级别,定义只对什么级别的网卡进行响应;
0:只要某个接口配置了某个地址,只要请求就响应
1:仅在请求的目标地址配置请求到达的接口上的时候,才给与响应
arp_announce: 定义将自己地址向外通告时通告级别的;
0:将本机任何接口上的任何地址向外通告
1: 试图仅向目标网络通告与其网络匹配的地址;
2: 仅向与本地接口匹配的网络通告;
在DR模型下每一个realserver上都有两个地址,director也有两个地址,当用户的请求报文通过互联网到达路由设备,这个路由设备一定要将报文送给director,不然就没办法实现用户的请求或者调度了,当报文送到director的时候,源IP是CIP,目标IP是VIP,director发现自己主机配置有VIP地址,所以请求的一定是当前主机,因此报文经过PREROUING链到达INPUT链,而监控在INPU链的ipvs规则发现请求的是集群服务,假如监听在80端口的集群服务,一旦发现是集群服务以后,我们ipvs要根据我们的规则lvs类型等等修改报文,当报文送到director的时候在DR模型下,director是不会动IP首部,也不会动TCP首部,它仅仅是将MAC地址拆掉,因为报文目的地就是当前主机,因为目标MAC就是当前主机,拆掉帧首部以后通过查看IP首部和TCP首部,它发现请求报文所访问的是集群服务,因此为了实现DR模型的效果,在原有的IP首部之上封装新的MAC地址,发送的主机是director,于是把网卡的MAC地址作为了报文的源地址,而目标MAC是选择的一个realserver的MAC,它在选择realserver根据算法来挑选的,因此我们必须要高速它,我们每个realserver是什么,当挑选某一个realserver完成以后,它要找到这个realserver的IP地址所对应的MAC,于是找到了realserver的RIP所对应的MAC地址,由此封装目标MAC为所挑选出来的realserver的MAC地址,这样一个报文就直接转发对应的realserver上,假如挑选的是realserver2,realserver2收到以后发现目标MAC是自己,于是拆掉帧首部,它发现用户请求报文源地址是CIP,目标地址是VIP,当前realserver上有VIP,如果没有它不会处理这个报文,因此它一定会每个realserver配置上VIP地址,由于本机上realserver2有VIP地址,于是报文备接收下来并且拆掉了IP首部,并且发现了用户访问的是某一个服务,假如是80,因为用户请求的TCP首部没有做修改,realserver查看到的也是TCP的80端口,如果realserver2上的确有80服务的话,于是把这个请求转交给用户空间的进程,由空间中的进程处理完以后就响应,而请求地址源地址是CIP,目标地址是VIP,因此尽可能让它使用CIP作为目标地址,VIP作为源地址,于是这个响应报文直接被发往客户端,每个realserver的网关指向能够访问互联网的设备,为了实现让每个realserver向外发送响应报文的时候可以把VIP作为源地址,由此我们在每个主机上都配置了VIP地址,而这个请求报文在送达路由设备的时候,我们的路由器将报文真正送达到realserver或director也好,它必须要根据MAC地址来向外转发,因为在同一个网段,由此它怎么知道VIP的MAC地址是什么,它必须要通过ARP广播,realserver和director都可以收到,每个都有可能响应,每个也都有权限和责任响应,这几个VIP如果一同响应的话,我们前面路由就混乱了,它就不知道应该把请求发给谁了,一般可能谁返回的最快,它就认为谁是VIP所对应的MAC地址了,于是就直接响应过去了,很显然这就不符合我们的负载均衡条件了,所以我们必须要保证realserver不能对MAC地址的广播请求给予响应,这三台主机必须要关闭对ARP请求的响应,如果达到这样目的,让我们前端的网关实现报文发送的时候仅仅能够将报文对VIP作为目标发给director,方法有很多种,比如在路由器接口上手动绑定静态解析结果,在路由器上明确说明在VIP对应的MAC地址是director上的MAC,只要绑定再跟VIP通信就不用再请求了,这个绑定是静态的所以也不会失效,它也不会再次发起请求了,但这有个前提,我们这个路由设备自己必须要有操作权限,能够绑定MAC地址,第二种方式,在红帽的主机上,它们引进了有一个程序叫做arptables,类似于iptables,基于MAC地址做访问控制的,我们只需要在三个realserver上定义arptables规则,如果用户ARP广播请求的目标地址是本机的VIP,那么不予响应,或者响应的报文不允许出去,这个报文路由器也接收不到,也就意味着只有directory的响应报文才能到达,第三种方式可以使当linux内核2.4.23以后以及2.6.4以后它们在内核中引入了两个新的内核参数叫arp_ignore和arp_announce,用于限定linux主机对ARP广播请求响应级别,当用户请求被送达到realserver的时候,当配置内核参数的时候,只有directory予以响应,directory将请求转交给realserver,realserver收到以后直接给予响应,默认linux响应报文的源地址一般要配置为报文流出接口的源地址,就算用户请求的是VIP,这个报文响应一定是从eth0出去的,linux中有一种行为报文从那个接口出去,它就尽可能使用这个接口上的IP地址,如果这个接口的地址跟网关不在同一网段内,它就使用这个接口别名上的地址,也就意味着我们接口一定得有一个地址跟网关在同一网关内,由于大家都在同一个网段内,它会使用eth0的RIP作为源地址,客户端没有请求RIP,必须要保证响应报文使用VIP,还需要做出额外配置,这个时候我们只需要在当前主机上,在每一个realserver上再添加一个独特的路由条目即可,这个路由条目就保证用户请求报文的地址一定是通过这个接口响应的报文作为它的源地址,我们需要给它添加一个独特的路由条目,明确说明用户的请求报文应该到达lo:0的地址上,我们的VIP配置在lo:0上,那么响应报文一定要使用对应接口上,请求接口上地址作为它的源地址向外响应,这种方式只需要给它添加一条路由信息即可,我们在这整个过程当中,要求VIP、DIP、RIP等等地址一定要是在同一个网络内的,不在同一个网络内这个网络结构是无法实现正常通信的,但是在现实应用当中,我们实现的未必都在同一个网络内,比如VIP是公网地址,只有一个公网地址,而DIP、RIP等等都是私有地址怎么办,我们VIP响应的接口是不可以的,以VIP作为源地址向外响应是不可以的;
arp_ignore/arp_announce
kernel 2.4.26 and 2.6.4 come with 2 new device flags for tuning the ARP stack: arp_announce and arp_ignore.
arp_announce
Define different restriction levels for announcing the local source IP address from IP packets in ARP requests sent on interface.(主动告诉别人自己的IP地址是什么对应的MAC地址是什么,向外通告本机源地址时候它的通告级别)
arp_ignores
Define different modes for sending replies in response to received ARP requests that resolve local target IP addresses.(当接收到别人请求的时候响应级别的)
arp_announce
arp_announce - INTEGER
0 - (default) Use any local address, configured on any interface.(默认,使用本地任何地址向外通告)
1 - Try to avoid local addresses that are not in the target's subnet for this interface(如果地址不在接口上,尽可能避免向外通告)
2 - Always use the best local address for this target.(总是使用本地最佳地址向外通告)
arp_ignore(当接收到别人请求时候响应级别)
arp_ignore - INTEGER
0 - (default): reply for any local target IP address,configured on any interface(只要某个接口配置了某个地址,只要请求就响应)
1 - replay only if the target IP address is local address(仅仅在目标IP是本地地址并且是配置在这个请求进来接口上才响应)
2 - reply only if the target IP address is local address configured on the incoming interface and both with the sender's IP address are part from same subnet on this interface
3 - do not reply for local addresses configured with scope host,only resolutions for global and link addresses are replied
4-7 - reserved
8 - do not reply for all local addresses
LVS DR模型案例:
环境介绍:director有一块网卡eth0使用vmnet0桥接模式,RS1有一个网卡eth0使用vmnet0桥接模式,RS2有一个网卡eth0使用vmnet0桥接模式;
Director:
Eth0, DIP: 172.16.100.2
Eth0:0, VIP: 172.16.100.1
RS1:
Eth0, RIP1: 172.16.100.7
lo:0, VIP: 172.16.100.1
RS2:
Eth0, RIP2: 172.16.100.8
Lo:0, VIP: 172.16.100.1
DR:
[root@localhost ~]# ifconfig eth0(查看eth0网卡接口信息)
eth0 Link encap:Ethernet HWaddr 00:0C:29:CC:FA:AE
inet addr:172.16.100.2 Bcast:172.16.100.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fecc:faae/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:124496 errors:0 dropped:0 overruns:0 frame:0
TX packets:119719 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:10764125 (10.2 MiB) TX bytes:15860656 (15.1 MiB)
Interrupt:67 Base address:0x2000
[root@localhost ~]# ifconfig eth0:0 172.16.100.1/16(给eth0接口配置别名)
[root@localhost ~]# ifconfig(查看网卡接口信息)
eth0 Link encap:Ethernet HWaddr 00:0C:29:CC:FA:AE
inet addr:172.16.100.2 Bcast:172.16.100.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fecc:faae/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:124628 errors:0 dropped:0 overruns:0 frame:0
TX packets:119828 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:10775059 (10.2 MiB) TX bytes:15879670 (15.1 MiB)
Interrupt:67 Base address:0x2000
eth0:0 Link encap:Ethernet HWaddr 00:0C:29:CC:FA:AE
inet addr:172.16.100.1 Bcast:172.16.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
Interrupt:67 Base address:0x2000
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:44518 errors:0 dropped:0 overruns:0 frame:0
TX packets:44518 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:3791286 (3.6 MiB) TX bytes:3791286 (3.6 MiB)
注意:一定不要上来就配置RS1和RS2的VIP地址,可以先配置RIP地址,必须要先把arp_ignore和arp_announce以后才能配置VIP;
RS1:
[root@localhost ~]# ifconfig eth0(查看eth0网卡接口信息)
eth0 Link encap:Ethernet HWaddr 00:0C:29:B8:44:39
inet addr:172.16.100.7 Bcast:172.16.100.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:feb8:4439/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:80874 errors:0 dropped:0 overruns:0 frame:0
TX packets:75384 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:7081953 (6.7 MiB) TX bytes:9275353 (8.8 MiB)
Interrupt:67 Base address:0x2000
RS2:
[root@localhost ~]# ifconfig eth0(查看eth0网卡接口信息)
eth0 Link encap:Ethernet HWaddr 00:0C:29:D9:86:95
inet addr:172.16.100.8 Bcast:172.16.100.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fed9:8695/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:30340 errors:0 dropped:0 overruns:0 frame:0
TX packets:25265 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:2673129 (2.5 MiB) TX bytes:3109315 (2.9 MiB)
Interrupt:67 Base address:0x2000
[root@localhost ~]# ping 172.16.100.2(ping测试)
PING 172.16.100.2 (172.16.100.2) 56(84) bytes of data.
64 bytes from 172.16.100.2: icmp_seq=1 ttl=64 time=1.31 ms
64 bytes from 172.16.100.2: icmp_seq=2 ttl=64 time=0.200 ms
--- 172.16.100.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.200/0.757/1.315/0.558 ms
[root@localhost ~]# ping 172.16.100.7
PING 172.16.100.7 (172.16.100.7) 56(84) bytes of data.
64 bytes from 172.16.100.7: icmp_seq=1 ttl=64 time=3.79 ms
64 bytes from 172.16.100.7: icmp_seq=2 ttl=64 time=0.140 ms
--- 172.16.100.7 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.140/1.967/3.794/1.827 ms
RS1:
[root@localhost ~]# cd /proc/sys/net/ipv4/(切换到/proc/sys/net/ipv4) [root@localhost ipv4]# cd conf/(切换到conf文件) [root@localhost conf]# ls(查看当前目录文件及子目录) all default eth0 lo [root@localhost conf]# ls all/(查看all目录文件及子目录) accept_local arp_accept arp_ignore disable_xfrm log_martians promote_secondaries secure_redirects tag accept_redirects arp_announce bootp_relay force_igmp_version mc_forwarding proxy_arp send_redirects accept_source_route arp_filter disable_policy forwarding medium_id rp_filter [root@localhost conf]# ls eth0/(查看eth0目录文件及子目录) accept_local arp_accept arp_ignore disable_xfrm log_martians promote_secondaries secure_redirects tag accept_redirects arp_announce bootp_relay force_igmp_version mc_forwarding proxy_arp send_redirects accept_source_route arp_filter disable_policy forwarding medium_id rp_filter [root@localhost conf]# ls lo/(查看lo目录文件及子目录) accept_local arp_accept arp_ignore disable_xfrm log_martians promote_secondaries secure_redirects tag accept_redirects arp_announce bootp_relay force_igmp_version mc_forwarding proxy_arp send_redirects accept_source_route arp_filter disable_policy forwarding medium_id rp_filter 提示:eth0接口和lo0接口任意配置一个都可以,而all接口一定要配置; [root@localhost conf]# sysctl -w net.ipv4.conf.eth0.arp_announce=2(修改内核参数net.ipv4.conf.eth0.arp_announce为2) net.ipv4.conf.eth0.arp_announce = 2 [root@localhost conf]# cat eth0/arp_announce(查看arp_announce文件内容) 2 [root@localhost conf]# sysctl -w net.ipv4.conf.all.arp_announce=2(更改内核参数net.ipv4.conf.all.arp_announce为2) net.ipv4.conf.all.arp_announce = 2 [root@localhost conf]# cat all/arp_announce(查看arp_announce文件内容) 2 [root@localhost conf]# echo 1 > /proc/sys/net/ipv4/conf/eth0/arp_ignore(将arp_ignore文件内容修改为1) [root@localhost conf]# echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore(将arp_ignore文件内容修改为1) [root@localhost conf]# ifconfig lo:0 172.16.100.1/16(给lo口添加别名地址)
测试:通过Windows主机ping测试到达172.16.100.1接口地址;
C:\Users\Smoke>ping 172.16.100.1
正在 Ping 172.16.100.1 具有 32 字节的数据:
来自 172.16.100.1 的回复: 字节=32 时间<1ms TTL=64
来自 172.16.100.1 的回复: 字节=32 时间<1ms TTL=64
来自 172.16.100.1 的回复: 字节=32 时间<1ms TTL=64
来自 172.16.100.1 的回复: 字节=32 时间<1ms TTL=64
172.16.100.1 的 Ping 统计信息:
数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):
最短 = 0ms,最长 = 0ms,平均 = 0ms
C:\Users\Smoke>arp -a(查看arp表)
接口: 172.16.100.254 --- 0x10
Internet 地址 物理地址 类型
172.16.100.1 00-0c-29-cc-fa-ae 动态
DR:
[root@localhost ~]# ifconfig eth0
eth0 Link encap:Ethernet HWaddr 00:0C:29:CC:FA:AE
inet addr:172.16.100.2 Bcast:172.16.100.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fecc:faae/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:124946 errors:0 dropped:0 overruns:0 frame:0
TX packets:120101 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:10800797 (10.3 MiB) TX bytes:15919244 (15.1 MiB)
Interrupt:67 Base address:0x2000
RS2:
[root@localhost ~]# echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce(修改arp_announce文件内容)
[root@localhost ~]# echo 2 > /proc/sys/net/ipv4/conf/eth0/arp_announce(修改arp_announce文件内容)
[root@localhost ~]# echo 1 > /proc/sys/net/ipv4/conf/eth0/arp_ignore(修改arp_ignore文件内容)
[root@localhost ~]# echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore(修改arp_ignore文件内容)
[root@localhost ~]# ifconfig lo:0 172.16.100.1/16(给lo接口配置别名地址)
[root@localhost ~]# ifconfig lo:0(查看lo:0接口信息)
lo:0 Link encap:Local Loopback
inet addr:172.16.100.1 Mask:255.255.0.0
UP LOOPBACK RUNNING MTU:16436 Metric:1
测试:通过Windows主机ping测试到达172.16.100.1接口地址;
C:\Users\Smoke>ping 172.16.100.1
正在 Ping 172.16.100.1 具有 32 字节的数据:
来自 172.16.100.1 的回复: 字节=32 时间=2ms TTL=64
来自 172.16.100.1 的回复: 字节=32 时间<1ms TTL=64
来自 172.16.100.1 的回复: 字节=32 时间<1ms TTL=64
来自 172.16.100.1 的回复: 字节=32 时间<1ms TTL=64
172.16.100.1 的 Ping 统计信息:
数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):
最短 = 0ms,最长 = 2ms,平均 = 0ms
C:\Users\Smoke>arp -a(查看arp表)
接口: 172.16.100.254 --- 0x10
Internet 地址 物理地址 类型
172.16.100.1 00-0c-29-cc-fa-ae 动态
RS1:
[root@localhost ~]# ifconfig lo:0 down(停止lo:0网卡)
[root@localhost ~]# ifconfig lo:0 172.16.100.1 broadcast 172.16.100.1 netmask 255.255.255.255 up(配置lo:0接口地址为172.16.100.1,广播地址为172
.16.100.1,掩码255.255.255.255,并且启用)
[root@localhost ~]# ifconfig lo:0(查看lo:0接口信息)
lo:0 Link encap:Local Loopback
inet addr:172.16.100.1 Mask:255.255.255.255
UP LOOPBACK RUNNING MTU:16436 Metric:1
RS2:
[root@localhost ~]# ifconfig lo:0 down(停止lo:0接口)
[root@localhost ~]# ifconfig lo:0 172.16.100.1 broadcast 172.16.100.1 netmask 255.255.255.255 up(配置lo:0接口地址为172.16.100.1,广播地址172.16
.100.1,掩码255.255.255.255,并且启用)
[root@localhost ~]# ifconfig lo:0(查看lo:0接口信息)
lo:0 Link encap:Local Loopback
inet addr:172.16.100.1 Mask:255.255.255.255
UP LOOPBACK RUNNING MTU:16436 Metric:1
[root@localhost ~]# route add -host 172.16.100.1 dev lo:0(添加路由到达主机172.16.100.1下一跳为lo:0)
RS1:
[root@localhost ~]# route add -host 172.16.100.1 dev lo:0(添加路由到达主机172.16.100.1下一跳为lo:0)
DR:
[root@localhost ~]# route add -host 172.16.100.1 dev eth0:0(添加路由到达主机172.16.100.1下一跳为eth0:0) [root@localhost ~]# curl http://172.16.100.7(访问172.16.100.7的http服务) RS1.magedu.com [root@localhost ~]# curl http://172.16.100.8(访问172.16.100.8的http服务) RS2.magedu.com [root@localhost ~]# ipvsadm -C(清空所有的集群服务规则) [root@localhost ~]# ipvsadm -A -t 172.16.100.1:80 -s wlc(添加集群服务,-t指定协议为tcp,-s指定调度算法) [root@localhost ~]# ipvsadm -a -t 172.16.100.1:80 -r 172.16.100.7 -g -w 2(向集群服务172.16.100.1:80添加realserver,-t指定协议为tcp,-r指定 realserver,-g指定为DR模型,-w指定权重) [root@localhost ~]# ipvsadm -a -t 172.16.100.1:80 -r 172.16.100.8 -g -w 1(向集群服务172.16.100.1:80添加realserver,-t指定协议为tcp,-r指定 realserver,-g指定DR模型,-w指定权重) [root@localhost ~]# ipvsadm -L -n (查看集群服务规则) IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 172.16.100.1:80 wlc -> 172.16.100.8:80 Route 1 0 0 -> 172.16.100.7:80 Route 2 0 0
测试:通过Windows的IE浏览器访问http://172.16.100.1网页,访问的是RS2页面;

刷新后访问的是RS1页面;

测试:假如RS2主机宕机了会出现什么情况;
RS2:
[root@localhost ~]# iptables -A INPUT -p tcp --dport 80 -j REJECT(向filter表的INPUT链添加规则,拒绝到达tcp协议80端口)
测试:通过Windows的IE浏览器访问http://172.16.100.1网页,访问的是RS1页面;

重复刷新页面,当被轮调到RS2主机的http服务的时候,网站卡住了,无法访问,当RS2坏掉了director不知道,没法做健康状况检查,所以就一直坏着,按道理director应该能够进行后端realserver的健康状况检查,但是LVS没有这种功能,但是LVS的director给它添加一个特殊的模块以后可以,叫ldirectord,但ldirectord是在高可用集群中做高可用模型的时候才会用得上;
DR:
Eth0, DIP: 172.16.100.2
Eth0:0, VIP: 172.16.100.1
RS1:
Eth0, RIP1: 172.16.100.7
lo:0, VIP: 172.16.100.1
RS2:
Eth0, RIP2: 172.16.100.8
Lo:0, VIP: 172.16.100.1
Service ipvsadm save
ipvsadm -S
VIP, 路由
RS:
变量:命名的内存空间,在里面可以存储值,而变量有名,通过变量名来引用;
数组:把几个具有相同类型的变量使用一片连续的内存空间进行保存;
Array数组, element: 元素
数组索引
Array_name[index]
Array_name=("element1" "element2")
Array_name[0]="element1"
Array_name[1]="element2"
DR类型中,Director和RealServer的配置脚本示例:
Director脚本:
#!/bin/bash
#
# LVS script for VS/DR
# chkconfig: - 90 10
#
. /etc/rc.d/init.d/functions
#
VIP=172.16.100.1
DIP=172.16.100.2
RIP1=172.16.100.7
RIP2=172.16.100.8
PORT=80
RSWEIGHT1=2
RSWEIGHT2=5
#
case "$1" in
start)
/sbin/ifconfig eth0:1 $VIP broadcast $VIP netmask 255.255.255.255 up(添加虚拟IP)
/sbin/route add -host $VIP dev eth0:0(添加主机路由)
# Since this is the Director we must be able to forward packets
echo 1 > /proc/sys/net/ipv4/ip_forward(打开内核转发)
# Clear all iptables rules.
/sbin/iptables -F(清空iptables规则)
# Reset iptables counters.
/sbin/iptables -Z(将iptables规则清零)
# Clear all ipvsadm rules/services.
/sbin/ipvsadm -C(清空现有的ipvsadm规则)
# Add an IP virtual service for VIP 192.168.0.219 port 80
# In this recipe, we will use the round-robin scheduling method.
# In production, however, you should use a weighted, dynamic scheduling method.
/sbin/ipvsadm -A -t $VIP:80 -s wlc(添加集群服务)
# Now direct packets for this VIP to
# the real server IP (RIP) inside the cluster
/sbin/ipvsadm -a -t $VIP:80 -r $RIP1 -g -w $RSWEIGHT1(向集群服务添加realserver,并且指定权重)
/sbin/ipvsadm -a -t $VIP:80 -r $RIP2 -g -w $RSWEIGHT2(向集群服务添加realserver,并且指定权重)
/bin/touch /var/lock/subsys/ipvsadm &> /dev/null(创建锁文件)
;;
stop)
# Stop forwarding packets
echo 0 > /proc/sys/net/ipv4/ip_forward(关闭内核转发)
# Reset ipvsadm
/sbin/ipvsadm -C(清空ipvsadm规则)
# Bring down the VIP interface
/sbin/ifconfig eth0:0 down(关闭eth0:0虚拟IP)
/sbin/route del $VIP(删除路由)
/bin/rm -f /var/lock/subsys/ipvsadm
echo "ipvs is stopped..."
;;
status)
if [ ! -e /var/lock/subsys/ipvsadm ]; then(如果锁文件不存在,则)
echo "ipvsadm is stopped ..."(显示ipvsadm服务停止)
else
echo "ipvs is running ..."(否则显示ipvs服务运行)
ipvsadm -L -n
fi
;;
*)
echo "Usage: $0 {start|stop|status}"
;;
esac
RealServer脚本:
#!/bin/bash
#
# Script to start LVS DR real server.
# chkconfig: - 90 10
# description: LVS DR real server
#
. /etc/rc.d/init.d/functions
VIP=172.16.100.1
host=`/bin/hostname`
case "$1" in
start)
# Start LVS-DR real server on this machine.
/sbin/ifconfig lo down
/sbin/ifconfig lo up
echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore(设定内核参数)
echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
/sbin/ifconfig lo:0 $VIP broadcast $VIP netmask 255.255.255.255 up(配置lo:0启用VIP)
/sbin/route add -host $VIP dev lo:0(添加路由条目)
;;
stop)
# Stop LVS-DR real server loopback device(s).
/sbin/ifconfig lo:0 down(停止lo:0接口)
echo 0 > /proc/sys/net/ipv4/conf/lo/arp_ignore(修改内核参数)
echo 0 > /proc/sys/net/ipv4/conf/lo/arp_announce
echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce
;;
status)
# Status of LVS-DR real server.
islothere=`/sbin/ifconfig lo:0 | grep $VIP`(判定lo:0是否存在)
isrothere=`netstat -rn | grep "lo:0" | grep $VIP`(查看路由表,是否有lo:0路由)
if [ ! "$islothere" -o ! "isrothere" ];then(判断islothere和isrothere是否存在,不存在,则)
# Either the route or the lo:0 device
# not found.
echo "LVS-DR real server Stopped."(显示服务停止)
else
echo "LVS-DR real server Running."(否则服务允许)
fi
;;
*)
# Invalid entry.
echo "$0: Usage: $0 {start|status|stop}"
exit 1
;;
esac
curl命令选项:
--cacert <file> CA证书 (SSL)
--capath <directory> CA目录 (made using c_rehash) to verify peer against (SSL)
--compressed 要求返回是压缩的形势 (using deflate or gzip)
--connect-timeout <seconds> 设置最大请求时间
-H/--header <line>自定义头信息传递给服务器
-i/--include 输出时包括protocol头信息
-I/--head 只显示文档信息
--interface <interface> 使用指定网络接口/地址
-s/--silent静音模式。不输出任何东西
-u/--user <user[:password]>设置服务器的用户和密码
-p/--proxytunnel 使用HTTP代理
RS健康状态检查脚本示例第一版:
#!/bin/bash
#
VIP=192.168.10.3
CPORT=80
FAIL_BACK=127.0.0.1
FBSTATUS=0
RS=("192.168.10.7" "192.168.10.8")
RSTATUS=("1" "1")
RW=("2" "1")
RPORT=80
TYPE=g
add() {
ipvsadm -a -t $VIP:$CPORT -r $1:$RPORT -$TYPE -w $2
[ $? -eq 0 ] && return 0 || return 1
}
del() {
ipvsadm -d -t $VIP:$CPORT -r $1:$RPORT
[ $? -eq 0 ] && return 0 || return 1
}
while :; do
let COUNT=0
for I in ${RS[*]}; do
if curl --connect-timeout 1 http://$I &> /dev/null; then
if [ ${RSTATUS[$COUNT]} -eq 0 ]; then
add $I ${RW[$COUNT]}
[ $? -eq 0 ] && RSTATUS[$COUNT]=1
fi
else
if [ ${RSTATUS[$COUNT]} -eq 1 ]; then
del $I
[ $? -eq 0 ] && RSTATUS[$COUNT]=0
fi
fi
let COUNT++
done
sleep 5
done
RS健康状态检查脚本示例第二版:
#!/bin/bash
#
VIP=192.168.10.3
CPORT=80
FAIL_BACK=127.0.0.1
RS=("192.168.10.7" "192.168.10.8")
declare -a RSSTATUS
RW=("2" "1")
RPORT=80
TYPE=g
CHKLOOP=3
LOG=/var/log/ipvsmonitor.log
addrs() {
ipvsadm -a -t $VIP:$CPORT -r $1:$RPORT -$TYPE -w $2
[ $? -eq 0 ] && return 0 || return 1
}
delrs() {
ipvsadm -d -t $VIP:$CPORT -r $1:$RPORT
[ $? -eq 0 ] && return 0 || return 1
}
checkrs() {
local I=1
while [ $I -le $CHKLOOP ]; do
if curl --connect-timeout 1 http://$1 &> /dev/null; then
return 0
fi
let I++
done
return 1
}
initstatus() {
local I
local COUNT=0;
for I in ${RS[*]}; do
if ipvsadm -L -n | grep "$I:$RPORT" && > /dev/null ; then
RSSTATUS[$COUNT]=1
else
RSSTATUS[$COUNT]=0
fi
let COUNT++
done
}
initstatus
while :; do
let COUNT=0
for I in ${RS[*]}; do
if checkrs $I; then
if [ ${RSSTATUS[$COUNT]} -eq 0 ]; then
addrs $I ${RW[$COUNT]}
[ $? -eq 0 ] && RSSTATUS[$COUNT]=1 && echo "`date +'%F %H:%M:%S'`, $I is back." >> $LOG
fi
else
if [ ${RSSTATUS[$COUNT]} -eq 1 ]; then
delrs $I
[ $? -eq 0 ] && RSSTATUS[$COUNT]=0 && echo "`date +'%F %H:%M:%S'`, $I is gone." >> $LOG
fi
fi
let COUNT++
done
sleep 5
done
实现测试:能不能把Director上的web服务也启动起来把它也当作一个realserver来用,在Director上已经安装好了web服务,并且已经启动起来了;
DR:
[root@localhost ~]# netstat -tnlp(查看系统服务,-t代表tcp,-n以数字显示,-l监听端口,-p显示服务名称) Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 127.0.0.1:2208 0.0.0.0:* LISTEN 3494/./hpiod tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 3175/portmap tcp 0 0 0.0.0.0:852 0.0.0.0:* LISTEN 3214/rpc.statd tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 3515/sshd tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN 3527/cupsd tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 3564/sendmail tcp 0 0 127.0.0.1:6010 0.0.0.0:* LISTEN 16861/sshd tcp 0 0 127.0.0.1:6013 0.0.0.0:* LISTEN 15823/sshd tcp 0 0 127.0.0.1:6014 0.0.0.0:* LISTEN 16374/sshd tcp 0 0 127.0.0.1:2207 0.0.0.0:* LISTEN 3499/python tcp 0 0 :::80 :::* LISTEN 16919/httpd tcp 0 0 :::22 :::* LISTEN 3515/sshd tcp 0 0 ::1:6010 :::* LISTEN 16861/sshd tcp 0 0 ::1:6013 :::* LISTEN 15823/sshd tcp 0 0 ::1:6014 :::* LISTEN 16374/sshd
测试:通过Windows的IE浏览器http://172.16.100.2页面,可以正常访问;

[root@localhost ~]# echo "<h1>Director.magedu.com</h1>" > /var/www/html/index.html(显示<h1>Director.magedu.com</h1>输出到index.html文件)
测试:通过Windows的IE浏览器http://172.16.100.2页面,可以正常访问;

[root@localhost ~]# ipvsadm -a -t 172.16.100.1:80 -r 127.0.0.1 -g -w 5(向172.16.100.1:80集群服务添加realserver,t指定集群服务协议为tcp,-r指定 realserver,-g指定为DR模型,-w指定权重) [root@localhost ~]# ipvsadm -L -n(查看集群服务规则,-n以数字显示) IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 172.16.100.1:80 wlc -> 127.0.0.1:80 Local 5 0 0 -> 172.16.100.8:80 Route 1 0 0 -> 172.16.100.7:80 Route 2 0 0
测试:通过Windows的IE浏览器访问http://172.16.100.1页面,访问的是Director页面

重新刷新页面,访问的是RS2页面;

重新刷新页面,访问的是RS1页面;

提示:Director本身就是个负责均衡器,它的目的不是为了响应用户访问,而是作为调度器的,要再让它提供其它服务,那么这个调度器性能会大受影响,所以Director这个页面我们通常不会拿来真正用于提供Web服务的,只是在某些紧急情况下使用,比如所有realserver全宕机了,用户访问没有任何一个realserver可以返回页面,这时候可以启用127.0.0.1,而且给它提供一个错误页面,您访问的服务器正处于维护当中,至少不会让用户感到迷茫;
[root@localhost ~]# chkconfig --list ipvsadm(查看ipvsadm服务在相应系统级别启动情况) ipvsadm 0:off 1:off 2:off 3:off 4:off 5:off 6:off [root@localhost ~]# elinks -dump http://172.16.100.7(访问http://172.16.100.7页面,-dump把网页内容直接下载显示出来直接退出命令,不在交互式模式运行) RS1.magedu.com [root@localhost ~]# echo $?(显示上个命令执行的状态码) 0 [root@localhost ~]# elinks -dump http:172.16.100.9(访问http://172.16.100.9页面,-dump把网页内容直接下载显示出来直接退出命令,不在交互式模式运行) ELinks: No route to host [root@localhost ~]# echo $?(显示上个命令执行的状态码) 1
RS1:
[root@localhost ~]# cd /var/www/html/(切换到/var/www/html目录) [root@localhost html]# vim .health_check.html(编辑.health_check.html文件) OK
DR:
[root@localhost ~]# elinks -dump http://172.16.100.7/.health_check.html(访问http://172.16.100.7/.health_check.html页面,-dump把网页内容直接
下载显示出来直接退出命令,不在交互模式允许)
OK
[root@localhost ~]# elinks -dump http://172.16.100.7/.health_check.html | grep "OK" &> /dev/null(访问http://172.16.100.7/.health_check.
html页面将结果送给管道显示OK相关将结果输出正确和错误信息到/dev/null,-dump把网页内容直接下载显示出来直接退出命令,不在交互模式允许)
[root@localhost ~]# echo $?(显示上个命令执行状态码)
0
[root@localhost ~]# man elinks(查看elinks的man帮助手册)
[root@localhost ~]# curl http://172.16.100.7(访问http://172.16.100.7的页面)
RS1.magedu.com
[root@localhost ~]# curl http://172.16.100.9(访问http://172.16.100.9的网页)
curl: (7) couldn't connect to host
[root@localhost ~]# curl --connect-timeout 1 http://172.16.100.9(访问http://172.16.100.9的页面,--connect-timeout设定最大请求超时时间)
curl: (7) couldn't connect to host
[root@localhost ~]# curl -I http://172.16.100.7(访问http://172.16.100.7页面,-I使用head方式请求,只显示文档信息)
HTTP/1.1 200 OK
Date: Sun, 13 Mar 2016 21:07:37 GMT
Server: Apache/2.2.3 (Red Hat)
Last-Modified: Sun, 13 Mar 2016 07:58:34 GMT
ETag: "2e3b3f-f-87e33e80"
Accept-Ranges: bytes
Content-Length: 15
Connection: close
Content-Type: text/html; charset=UTF-8
提示:head方式请求,它不获取网页真正内容,而只是获取页面响应首部,在响应响应首部里面如果能找到第一行的第三段只要2开头的或者3开头的有可能意味着这个页面能访问;
[root@localhost ~]# curl -s http://172.16.100.7(访问http://172.16.100.7页面,-s静音模式,不输出任何东西)
RS1.magedu.com
[root@localhost ~]# curl http://172.16.100.7 &> /dev/null(访问172.16.100.7页面,将输出结果送到/dev/null)
[root@localhost ~]# echo $?(显示上个命令执行状态码)
0
[root@localhost ~]# curl --connect-timeout 1 http://172.16.100.9 &> /dev/null(访问http://172.16.100.9页面将输出结果送到/dev/null,--connect
-timeout设定最大请求超时时间)
[root@localhost ~]# echo $?(显示上个命令执行状态码)
7
[root@localhost ~]# man crul(查看curl的man帮助)
[root@localhost ~]# vim health_check.sh(编辑health_check.sh脚本)
#!/bin/base
#
VIP=172.16.100.1(定义变量VIP,集群服务IP)
RS=("172.16.100.7" "172.16.100.8")(定义数组RS,两个realserver的RIP)
[root@localhost ~]# RS=("172.16.100.7" "172.16.100.8")(声明数组)
[root@localhost ~]# echo $RS{0}(显示数组RS第一个元素)
172.16.100.7{0}
[root@localhost ~]# echo $RS[0](显示数组RS第一个元素)
172.16.100.7[0]
[root@localhost ~]# echo ${RS[0]}(显示RS数组0号元素的值)
172.16.100.7
[root@localhost ~]# echo ${RS[1]}(显示RS数组1号元素的值)
172.16.100.8
[root@localhost ~]# echo $RS(显示数据RS第一个元素)
172.16.100.7
[root@localhost ~]# echo ${#RS}(显示RS第一个元素变量长度)
12
[root@localhost ~]# echo ${#RS[*]}(显示RS数组一个有多少个元素)
2
[root@localhost ~]# vim health_check.sh(编辑health_check.sh脚步)
#!/bin/base
#
VIP=172.16.100.1(定义变量VIP,集群服务IP)
CPORT=80(定义集群服务端口)
FAIL_BACK=127.0.0.1(两个realserver无法访问,失败时候访问使用的地址)
RS=("172.16.100.7" "172.16.100.8")(定义数组RS,两个realserver的RIP)
RW=("2" "1")(定义两个realserver权重)
RPORT=80(定义realserver端口)
[root@localhost ~]# ipvsadm -L -n(查看集群服务规则,-n以数字显示)
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.16.100.1:80 wlc
-> 127.0.0.1:80 Local 5 0 0
-> 172.16.100.8:80 Route 1 0 0
-> 172.16.100.7:80 Route 2 0 0
[root@localhost ~]# echo $RS(显示数组RS中第0号元素的值)
172.16.100.7
[root@localhost ~]# echo ${RS[*]}(显示数组RS中所有元素中的值)
172.16.100.7 172.16.100.8
[root@localhost ~]# echo ${#RS[*]}(显示数组RS中有几个元素有值)
2
[root@localhost ~]# vim health_check.sh(编辑health_check.sh脚步)
#!/bin/base
#
VIP=172.16.100.1(定义变量VIP,集群服务IP)
CPORT=80(定义集群服务端口)
FAIL_BACK=127.0.0.1(两个realserver无法访问,失败时候访问使用的地址)
RS=("172.16.100.7" "172.16.100.8")(定义数组RS,两个realserver的RIP)
RSTATUS=("1" "1")
RW=("2" "1")(定义两个realserver权重)
RPORT=80(定义realserver端口)
let COUNT=0
TYPE=g(集群模式)
add() { (定义函数add)
ipvsadm -a -t $VIP:$CPORT -r $1:$RPORT -$TYPE -w $2(向集群服务添加realserver)
[ $? -eq 0 ] && return 0 || return 1
}
del() {
ipvsadm -d -t $VIP:$CPORT -r $1:$RPORT(从集群服务删除realserver)
[ $? -eq 0 ] && return 0 || return 1
}
for I in ${RS[*]}; do
if curl --connect-timeout 1 http://$I &> /dev/null; then(判断realserver是否在线)
if [ ${RSTATUS[$COUNT]} -eq 0 ]; then
add $I ${RW[$COUNT]}
[ $? -eq 0 ] && RSTATUS[$COUNT]=1
fi
else
if [ ${RSTATUS[$COUNT]} -eq 1 ]; then
del $I
[ $? -eq 0 ] && RSTATUS[$COUNT]=-0
fi
fi
done
[root@localhost ~]# bash -x health_check.sh(测试执行health_check.sh脚步)
+ VIP=172.16.100.1
+ CPORT=80
+ FAIL_BACK=127.0.0.1
+ RS=("172.16.100.7" "172.16.100.8")
+ RSTATUS=("1" "1")
+ RW=("2" "1")
+ RPORT=80
+ let COUNT=0
+ TYPE=g
+ for I in '${RS[*]}'
+ curl --connect-timeout 1 http://172.16.100.7
+ '[' 1 -eq 0 ']'
+ for I in '${RS[*]}'
+ curl --connect-timeout 1 http://172.16.100.8
+ '[' 1 -eq 0 ']'
测试:将realserver主机172.16.100.7停止掉,再测试脚步;
RS1:
[root@localhost ~]# service httpd stop(停止httpd服务) 停止 httpd: [确定]
DR:
[root@localhost ~]# bash -x health_check.sh(执行health_check.sh脚步)
+ VIP=172.16.100.1
+ CPORT=80
+ FAIL_BACK=127.0.0.1
+ RS=("172.16.100.7" "172.16.100.8")
+ RSTATUS=("1" "1")
+ RW=("2" "1")
+ RPORT=80
+ let COUNT=0
+ TYPE=g
+ for I in '${RS[*]}'
+ curl --connect-timeout 1 http://172.16.100.7
+ '[' 1 -eq 1 ']'
+ del 172.16.100.7
+ ipvsadm -d -t 172.16.100.1:80 -r 172.16.100.7:80
No such destination
+ '[' 255 -eq 0 ']'
+ return 1
+ '[' 1 -eq 0 ']'
+ for I in '${RS[*]}'
+ curl --connect-timeout 1 http://172.16.100.8
+ '[' 1 -eq 0 ']'
提示:逻辑有问题;
[root@localhost ~]# ipvsadm -L -n(查看集群服务规则,-n以数字显示)
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.16.100.1:80 wlc
-> 172.16.100.8:80 Route 1 0 0
-> 127.0.0.1:80 Local 5 0 0
RS1:
[root@localhost ~]# service httpd start(启动httpd服务) 启动 httpd: [确定]
DR:
[root@localhost ~]# bash health_check.sh(执行heal_check.sh脚本)
[root@localhost ~]# ipvsadm -L -n(查看集群服务,-n以数字显示)
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.16.100.1:80 wlc
-> 172.16.100.8:80 Route 1 0 0
-> 127.0.0.1:80 Local 5 0 0
[root@localhost ~]# bash -x health_check.sh(执行health_check.sh脚本)
+ VIP=172.16.100.1
+ CPORT=80
+ FAIL_BACK=127.0.0.1
+ RS=("172.16.100.7" "172.16.100.8")
+ RSTATUS=("1" "1")
+ RW=("2" "1")
+ RPORT=80
+ let COUNT=0
+ TYPE=g
+ for I in '${RS[*]}'
+ curl --connect-timeout 1 http://172.16.100.7
+ '[' 1 -eq 0 ']'
+ for I in '${RS[*]}'
+ curl --connect-timeout 1 http://172.16.100.8
+ '[' 1 -eq 0 ']'
[root@localhost ~]# vim health_check.sh(编辑health_check.sh脚本)
#!/bin/base
#
VIP=172.16.100.1(定义变量VIP,集群服务IP)
CPORT=80(定义集群服务端口)
FAIL_BACK=127.0.0.1(两个realserver无法访问,失败时候访问使用的地址)
RS=("172.16.100.7" "172.16.100.8")(定义数组RS,两个realserver的RIP)
RSTATUS=("1" "1")
RW=("2" "1")(定义两个realserver权重)
RPORT=80(定义realserver端口)
let COUNT=0
TYPE=g(集群模式)
add() { (定义函数add)
ipvsadm -a -t $VIP:$CPORT -r $1:$RPORT -$TYPE -w $2(向集群服务添加realserver)
[ $? -eq 0 ] && return 0 || return 1
}
del() {
ipvsadm -d -t $VIP:$CPORT -r $1:$RPORT(从集群服务删除realserver)
[ $? -eq 0 ] && return 0 || return 1
}
for I in ${RS[*]}; do
if curl --connect-timeout 1 http://$I &> /dev/null; then(判断realserver是否在线)
if [ ${RSTATUS[$COUNT]} -eq 0 ]; then
add $I ${RW[$COUNT]}
[ $? -eq 0 ] && RSTATUS[$COUNT]=1
fi
else
if [ ${RSTATUS[$COUNT]} -eq 1 ]; then
del $I
[ $? -eq 0 ] && RSTATUS[$COUNT]=-0
fi
fi
done
[root@localhost ~]# ipvsadm -a -t 172.16.100.1:80 -r 172.16.100.7 -g -w 2(向集群服务172.16.100.1:80添加realserver)
[root@localhost ~]# ipvsadm -L -n(查看集群服务规则,-n以数字显示)
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.16.100.1:80 wlc
-> 172.16.100.7:80 Route 2 0 0
-> 172.16.100.8:80 Route 1 0 0
-> 127.0.0.1:80 Local 5 0 0
RS1:
[root@localhost ~]# service httpd stop(停止httpd服务) 停止 httpd: [确定]
DR:
[root@localhost ~]# bash health_check.sh(执行health_check.sh脚本)
Destination already exists
[root@localhost ~]# ipvsadm -L -n(查看集群服务规则)
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.16.100.1:80 wlc
-> 172.16.100.8:80 Route 1 0 0
-> 127.0.0.1:80 Local 5 0 0
[root@localhost ~]# ipvsadm -a -t 172.16.100.1:80 -r 172.16.100.7 -g -w 2(向集群服务172.16.100.1:80添加realserver)
[root@localhost ~]# bash -x health_check.sh(执行health_check.sh脚本)
+ VIP=172.16.100.1
+ CPORT=80
+ FAIL_BACK=127.0.0.1
+ RS=("172.16.100.7" "172.16.100.8")
+ RSTATUS=("1" "1")
+ RW=("2" "1")
+ RPORT=80
+ let COUNT=0
+ TYPE=g
+ for I in '${RS[*]}'
+ curl --connect-timeout 1 http://172.16.100.7
+ '[' 1 -eq 1 ']'
+ del 172.16.100.7
+ ipvsadm -d -t 172.16.100.1:80 -r 172.16.100.7:80
+ '[' 0 -eq 0 ']'
+ return 0
+ '[' 0 -eq 0 ']'
+ RSTATUS[$COUNT]=0
+ for I in '${RS[*]}'
+ curl --connect-timeout 1 http://172.16.100.8
+ '[' 0 -eq 0 ']'
+ add 172.16.100.8 2
+ ipvsadm -a -t 172.16.100.1:80 -r 172.16.100.8:80 -g -w 2
Destination already exists
+ '[' 255 -eq 0 ']'
+ return 1
+ '[' 1 -eq 0 ']'
[root@localhost ~]# vim health_check.sh(编辑health_check.sh脚本)
#!/bin/base
#
VIP=172.16.100.1(定义变量VIP,集群服务IP)
CPORT=80(定义集群服务端口)
FAIL_BACK=127.0.0.1(两个realserver无法访问,失败时候访问使用的地址)
RS=("172.16.100.7" "172.16.100.8")(定义数组RS,两个realserver的RIP)
RSTATUS=("1" "1")
RW=("2" "1")(定义两个realserver权重)
RPORT=80(定义realserver端口)
let COUNT=0
TYPE=g(集群模式)
add() { (定义函数add)
ipvsadm -a -t $VIP:$CPORT -r $1:$RPORT -$TYPE -w $2(向集群服务添加realserver)
[ $? -eq 0 ] && return 0 || return 1
}
del() {
ipvsadm -d -t $VIP:$CPORT -r $1:$RPORT(从集群服务删除realserver)
[ $? -eq 0 ] && return 0 || return 1
}
for I in ${RS[*]}; do
if curl --connect-timeout 1 http://$I &> /dev/null; then(判断realserver是否在线)
if [ ${RSTATUS[$COUNT]} -eq 0 ]; then
add $I ${RW[$COUNT]}
[ $? -eq 0 ] && RSTATUS[$COUNT]=1
fi
else
if [ ${RSTATUS[$COUNT]} -eq 1 ]; then
del $I
[ $? -eq 0 ] && RSTATUS[$COUNT]=-0
fi
fi
let COUNT++
done
[root@localhost ~]# ipvsadm -L -n(查看集群服务规则,-n以数字显示)
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.16.100.1:80 wlc
-> 172.16.100.8:80 Route 1 0 0
-> 127.0.0.1:80 Local 5 0 0
[root@localhost ~]# ipvsadm -a -t 172.16.100.1:80 -r 172.16.100.7 -g -w 2(向集群服务172.16.100.1:80添加realserver)
[root@localhost ~]# bash -x health_check.sh(执行health_check.sh脚本)
+ VIP=172.16.100.1
+ CPORT=80
+ FAIL_BACK=127.0.0.1
+ RS=("172.16.100.7" "172.16.100.8")
+ RSTATUS=("1" "1")
+ RW=("2" "1")
+ RPORT=80
+ let COUNT=0
+ TYPE=g
+ for I in '${RS[*]}'
+ curl --connect-timeout 1 http://172.16.100.7
+ '[' 1 -eq 1 ']'
+ del 172.16.100.7
+ ipvsadm -d -t 172.16.100.1:80 -r 172.16.100.7:80
+ '[' 0 -eq 0 ']'
+ return 0
+ '[' 0 -eq 0 ']'
+ RSTATUS[$COUNT]=0
+ let COUNT++
+ for I in '${RS[*]}'
+ curl --connect-timeout 1 http://172.16.100.8
+ '[' 1 -eq 0 ']'
+ let COUNT++
[root@localhost ~]# ipvsadm -L -n(查看集群服务规则,-n以数字显示)
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.16.100.1:80 wlc
-> 172.16.100.8:80 Route 1 0 0
-> 127.0.0.1:80 Local 5 0 0
RS1:
[root@localhost ~]# service httpd start(启动httpd服务) 启动 httpd: [确定]
DR:
[root@localhost ~]# bash -x health_check.sh(执行health_check.sh脚本)
+ VIP=172.16.100.1
+ CPORT=80
+ FAIL_BACK=127.0.0.1
+ RS=("172.16.100.7" "172.16.100.8")
+ RSTATUS=("1" "1")
+ RW=("2" "1")
+ RPORT=80
+ let COUNT=0
+ TYPE=g
+ for I in '${RS[*]}'
+ curl --connect-timeout 1 http://172.16.100.7
+ '[' 1 -eq 0 ']'
+ let COUNT++
+ for I in '${RS[*]}'
+ curl --connect-timeout 1 http://172.16.100.8
+ '[' 1 -eq 0 ']'
+ let COUNT++
[root@localhost ~]# ipvsadm -L -n(查看集群规则,-n以数字显示)
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.16.100.1:80 wlc
-> 172.16.100.8:80 Route 1 0 0
-> 127.0.0.1:80 Local 5 0 0
[root@localhost ~]# vim health_check.sh(编辑health_check.sh脚本)
#!/bin/base
#
VIP=172.16.100.1(定义变量VIP,集群服务IP)
CPORT=80(定义集群服务端口)
FAIL_BACK=127.0.0.1(两个realserver无法访问,失败时候访问使用的地址)
RS=("172.16.100.7" "172.16.100.8")(定义数组RS,两个realserver的RIP)
RSTATUS=("1" "1")
RW=("2" "1")(定义两个realserver权重)
RPORT=80(定义realserver端口)
TYPE=g(集群模式)
add() { (定义函数add)
ipvsadm -a -t $VIP:$CPORT -r $1:$RPORT -$TYPE -w $2(向集群服务添加realserver)
[ $? -eq 0 ] && return 0 || return 1
}
del() {
ipvsadm -d -t $VIP:$CPORT -r $1:$RPORT(从集群服务删除realserver)
[ $? -eq 0 ] && return 0 || return 1
}
while :; do
let COUNT=0
for I in ${RS[*]}; do
if curl --connect-timeout 1 http://$I &> /dev/null; then(判断realserver是否在线)
if [ ${RSTATUS[$COUNT]} -eq 0 ]; then
add $I ${RW[$COUNT]}
[ $? -eq 0 ] && RSTATUS[$COUNT]=1
fi
else
if [ ${RSTATUS[$COUNT]} -eq 1 ]; then
del $I
[ $? -eq 0 ] && RSTATUS[$COUNT]=-0
fi
fi
let COUNT++
done
sleep 5
done
[root@localhost ~]# bash health_check.sh(执行health_check.sh脚本)
[root@localhost ~]# ipvsadm -L -n(查看集群服务,-n已数字显示)
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.16.100.1:80 wlc
-> 172.16.100.8:80 Route 1 0 0
-> 127.0.0.1:80 Local 5 0 0
RS1:
[root@localhost ~]# service httpd restart(重启httpd服务) 停止 httpd: [确定] 启动 httpd: [确定]
DR:
[root@localhost ~]# ipvsadm -L -n(查看集群服务规则,-n以数字显示)
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.16.100.1:80 wlc
-> 172.16.100.8:80 Route 1 0 0
-> 127.0.0.1:80 Local 5 0 0
[root@localhost ~]# ipvsadm -a -t 172.16.100.1:80 -r 172.16.100.7 -g -w 2(向集群服务172.16.100.1:80添加realserver)
[root@localhost ~]# bash -x health_check.sh(执行health_check.sh脚本)
+ VIP=172.16.100.1
+ CPORT=80
+ FAIL_BACK=127.0.0.1
+ RS=("172.16.100.7" "172.16.100.8")
+ RSTATUS=("1" "1")
+ RW=("2" "1")
+ RPORT=80
+ TYPE=g
+ :
+ let COUNT=0
+ for I in '${RS[*]}'
+ curl --connect-timeout 1 http://172.16.100.7
+ '[' 1 -eq 0 ']'
+ let COUNT++
+ for I in '${RS[*]}'
+ curl --connect-timeout 1 http://172.16.100.8
+ '[' 1 -eq 0 ']'
+ let COUNT++
+ sleep 5
+ :
+ let COUNT=0
+ for I in '${RS[*]}'
+ curl --connect-timeout 1 http://172.16.100.7
+ '[' 1 -eq 0 ']'
+ let COUNT++
+ for I in '${RS[*]}'
+ curl --connect-timeout 1 http://172.16.100.8
+ '[' 1 -eq 0 ']'
+ let COUNT++
+ sleep 5
RS1:
[root@localhost ~]# service httpd stop(停止httpd服务) 停止 httpd: [确定]
DR:
[root@localhost ~]# ipvsadm -L -n(查看集群服务,-n以数字显示) IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 172.16.100.1:80 wlc -> 172.16.100.8:80 Route 1 0 0 -> 127.0.0.1:80 Local 5 0 0
RS1:
[root@localhost ~]# service httpd start(启动httpd服务) 启动 httpd: [确定]
DR:
[root@localhost ~]# ipvsadm -L -n(查看集群服务,-n以数字显示) IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 172.16.100.1:80 wlc -> 172.16.100.7:80 Route 2 0 0 -> 172.16.100.8:80 Route 1 0 0 -> 127.0.0.1:80 Local 5 0 0
RS2:
[root@localhost ~]# service httpd stop(停止httpd服务) Stopping httpd: [ OK ]
DR:
[root@localhost ~]# ipvsadm -L -n(查看集群服务,-n以数字显示) IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 172.16.100.1:80 wlc -> 172.16.100.7:80 Route 2 0 0 -> 127.0.0.1:80 Local 5 0 0
RS2:
[root@localhost ~]# service httpd start(启动httpd服务) Starting httpd: [ OK ]
DR:
[root@localhost ~]# ipvsadm -L -n(查看集群服务,-n以数字显示)
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.16.100.1:80 wlc
-> 172.16.100.8:80 Route 1 0 0
-> 172.16.100.7:80 Route 2 0 0
-> 127.0.0.1:80 Local 5 0 0
[root@localhost ~]# vim health_check.sh(编辑health_check.sh脚本)
#!/bin/base
#
VIP=172.16.100.1(定义变量VIP,集群服务IP)
CPORT=80(定义集群服务端口)
FAIL_BACK=127.0.0.1(两个realserver无法访问,失败时候访问使用的地址)
RS=("172.16.100.7" "172.16.100.8")(定义数组RS,两个realserver的RIP)
RSTATUS=("1" "1")
RW=("2" "1")(定义两个realserver权重)
RPORT=80(定义realserver端口)
TYPE=g(集群模式)
add() { (定义函数add)
ipvsadm -a -t $VIP:$CPORT -r $1:$RPORT -$TYPE -w $2(向集群服务添加realserver)
[ $? -eq 0 ] && return 0 || return 1
}
del() {
ipvsadm -d -t $VIP:$CPORT -r $1:$RPORT(从集群服务删除realserver)
[ $? -eq 0 ] && return 0 || return 1
}
while :; do
let COUNT=0
for I in ${RS[*]}; do
if curl --connect-timeout 1 http://$I &> /dev/null; then(判断realserver是否在线)
if [ ${RSTATUS[$COUNT]} -eq 0 ]; then
add $I ${RW[$COUNT]}
[ $? -eq 0 ] && RSTATUS[$COUNT]=1
fi
else
if [ ${RSTATUS[$COUNT]} -eq 1 ]; then
del $I
[ $? -eq 0 ] && RSTATUS[$COUNT]=-0
fi
fi
let COUNT++
done
sleep 5
done
[root@localhost ~]# ipvsadm -d -t 172.16.100.1:80 -r 127.0.0.1(从集群服务172.16.10.1:80删除realserver)
[root@localhost ~]# vim health_check.sh(编辑health_check.sh脚本)
#!/bin/base
#
VIP=172.16.100.1(定义变量VIP,集群服务IP)
CPORT=80(定义集群服务端口)
FAIL_BACK=127.0.0.1(两个realserver无法访问,失败时候访问使用的地址)
RS=("172.16.100.7" "172.16.100.8")(定义数组RS,两个realserver的RIP)
RSTATUS=("1" "1")
RW=("2" "1")(定义两个realserver权重)
RPORT=80(定义realserver端口)
TYPE=g(集群模式)
add() { (定义函数add)
ipvsadm -a -t $VIP:$CPORT -r $1:$RPORT -$TYPE -w $2(向集群服务添加realserver)
[ $? -eq 0 ] && return 0 || return 1
}
del() {
ipvsadm -d -t $VIP:$CPORT -r $1:$RPORT(从集群服务删除realserver)
[ $? -eq 0 ] && return 0 || return 1
}
while :; do
let COUNT=0
for I in ${RS[*]}; do
if curl --connect-timeout 1 http://$I &> /dev/null; then(判断realserver是否在线)
if [ ${RSTATUS[$COUNT]} -eq 0 ]; then
add $I ${RW[$COUNT]}
[ $? -eq 0 ] && RSTATUS[$COUNT]=1
fi
else
if [ ${RSTATUS[$COUNT]} -eq 1 ]; then
del $I
[ $? -eq 0 ] && RSTATUS[$COUNT]=-0
fi
fi
let COUNT++
done
sleep 5
done
RS健康状态检查脚本示例第一版:
#!/bin/bash
#
VIP=192.168.10.3
CPORT=80
FAIL_BACK=127.0.0.1
FBSTATUS=0
RS=("192.168.10.7" "192.168.10.8")
RSTATUS=("1" "1")
RW=("2" "1")
RPORT=80
TYPE=g
add() {
ipvsadm -a -t $VIP:$CPORT -r $1:$RPORT -$TYPE -w $2
[ $? -eq 0 ] && return 0 || return 1
}
del() {
ipvsadm -d -t $VIP:$CPORT -r $1:$RPORT
[ $? -eq 0 ] && return 0 || return 1
}
while :; do
let COUNT=0
for I in ${RS[*]}; do
if curl --connect-timeout 1 http://$I &> /dev/null; then
if [ ${RSTATUS[$COUNT]} -eq 0 ]; then
add $I ${RW[$COUNT]}
[ $? -eq 0 ] && RSTATUS[$COUNT]=1
fi
else
if [ ${RSTATUS[$COUNT]} -eq 1 ]; then
del $I
[ $? -eq 0 ] && RSTATUS[$COUNT]=0
fi
fi
let COUNT++
done
sleep 5
done
RS健康状态检查脚本示例第二版:
#!/bin/bash
#
VIP=192.168.10.3
CPORT=80
FAIL_BACK=127.0.0.1
RS=("192.168.10.7" "192.168.10.8")
declare -a RSSTATUS
RW=("2" "1")
RPORT=80
TYPE=g
CHKLOOP=3
LOG=/var/log/ipvsmonitor.log
addrs() {
ipvsadm -a -t $VIP:$CPORT -r $1:$RPORT -$TYPE -w $2
[ $? -eq 0 ] && return 0 || return 1
}
delrs() {
ipvsadm -d -t $VIP:$CPORT -r $1:$RPORT
[ $? -eq 0 ] && return 0 || return 1
}
checkrs() {
local I=1
while [ $I -le $CHKLOOP ]; do
if curl --connect-timeout 1 http://$1 &> /dev/null; then
return 0
fi
let I++
done
return 1
}
initstatus() {
local I
local COUNT=0;
for I in ${RS[*]}; do
if ipvsadm -L -n | grep "$I:$RPORT" && > /dev/null ; then
RSSTATUS[$COUNT]=1
else
RSSTATUS[$COUNT]=0
fi
let COUNT++
done
}
initstatus
while :; do
let COUNT=0
for I in ${RS[*]}; do
if checkrs $I; then
if [ ${RSSTATUS[$COUNT]} -eq 0 ]; then
addrs $I ${RW[$COUNT]}
[ $? -eq 0 ] && RSSTATUS[$COUNT]=1 && echo "`date +'%F %H:%M:%S'`, $I is back." >> $LOG
fi
else
if [ ${RSSTATUS[$COUNT]} -eq 1 ]; then
delrs $I
[ $? -eq 0 ] && RSSTATUS[$COUNT]=0 && echo "`date +'%F %H:%M:%S'`, $I is gone." >> $LOG
fi
fi
let COUNT++
done
sleep 5
done
DR:
arp_ignore = 1
arp_announce = 2
数组: 变量阵列
array_name=("" "")
declare -a A(把A声明为数组)
LVS持久连接(在一定时间内能够将来自同一个客户端的请求始终定向到同一个realserver上去机制,持久连接不关乎调度算法)
无论使用什么算法,LVS持久连接都能够实现在一定时间内,将来自同一个客户端请求派发至此前选定的RS。
持久连接模板(内存缓冲区):
每一个客户端 及分配给它的RS的映射关系
每一个新的客户端来发起连接请求的时候,无论这个客户端的TCP连接是不是已经断开了,只要这个客户端曾经访问过,LVS就会在内存的缓冲区当中,它能够将每一个第一次发起连接请求的客户端的IP和给他所选定的realserver,在一定时间内只要是这个客户端再次访问,它就会查这张表,查连接模版这张表,只要此前这个客户端被分配过realserver,而且尚未超时,仍然在模版里面,那么就会重新分配到同一个realserver上的,因为这个模版中记录了每一个客户端及分配给它的RS的映射关系;
ipvsadm -A|E -t|u|f service-address [-s scheduler]
[-p [timeout]] [-O] [-M netmask](-p [timeout]制定持久连接时长,默认300秒)
在基于SSL回话当中,最需要用到持久连接;
PPC: 将来自于同一个客户端对同一个集群服务的请求,始终定向至此前选定的RS,持久端口连接;
PCC: 将来自于同一个客户端对所有端口的请求,始终定向至此前选定的RS,持久客户端连接;
把所有端口统统定义为集群服务,一律向RS转发;
PNMPP: 持久防火墙标记连接,它能够定义端口
80: RS1
25: 同一个RS
防火标记:
PREROUTING
80:10
23:10
10
80,443
http:
https:
RS1: lamp, discuz
rsync server(inotify+rsync server)
sersync
memcached
来自同一个客户端所有请求,不光是同一个服务,前后不同的请求,哪怕是对不同服务的请求,它也能够定向至同一个realserver;
Types of Persistent Connections
Persistent client connections(PCC),cause all services a client is accessing to persist.(Also called zero port connections.)
Persistent port connections(PPC),which cause a single service to persist.
Persistent Netfilter Marked Packet persistence,which causes packets that have been marked with the iptables utility to persist.
FTP connections(FTP connections require careful handling due to the complex nature of FTP connections).
Expired persistence,which is used internally by the Director to expire connection tracking entries when the persitent connection template expires.
Marking Packets with iptables
For example,say we want to create one-hour persistent port affinity between ports 80 and 443 on VIP 172.16.100.6 for real servers 172.16.100.7 and 172.16.100.8:
/sbin/iptables -F mangle
/sbin/iptables -A PREROUTING -i eth0 -t mangle -p tcp -d 172.16.100.6 --dport 80 -j MARK --set-mark 1
/sbin/iptables -A PREROUTING -i eth0 -t mangle -p tcp -d 172.16.100.6 --dport 443 -j MARK --set-mark 1
/sbin/ipvsadm -A -f 1 -s rr -p 3600
/sbin/ipvsadm -a -f 1 -r 172.16.100.7 -m
/sbin/ipvsadm -a -f 1 -r 172.16.100.8 -m
DR:
[root@localhost ~]# vim health_check.sh(编辑health_check.sh脚本)
#!/bin/bash
#
VIP=172.16.100.1
CPORT=80
FAIL_BACK=127.0.0.1
RS=("172.16.100.7" "172.16.100.8")
declare -a RSSTATUS
RW=("2" "1")
RPORT=80
TYPE=g
CHKLOOP=3
LOG=/var/log/ipvsmonitor.log
addrs() {
ipvsadm -a -t $VIP:$CPORT -r $1:$RPORT -$TYPE -w $2
[ $? -eq 0 ] && return 0 || return 1
}
delrs() {
ipvsadm -d -t $VIP:$CPORT -r $1:$RPORT
[ $? -eq 0 ] && return 0 || return 1
}
checkrs() {
local I=1
while [ $I -le $CHKLOOP ]; do
if curl --connect-timeout 1 http://$1 &> /dev/null; then
return 0
fi
let I++
done
return 1
}
initstatus() {
local I
local COUNT=0
for I in ${RS[*]}; do
if checkrs $I; then
RSSTATUS[$COUNT]=1
else
RSSTATUS[$COUNT]=0
fi
let COUNT++
done
}
initstatus
while :; do
let COUNT=0
for I in ${RS[*]}; do
if checkrs $I; then
if [ ${RSSTATUS[$COUNT]} -eq 0 ]; then
addrs $I ${RW[$COUNT]}
[ $? -eq 0 ] && RSSTATUS[$COUNT]=1 && echo "`date +'%F %H:%M:%S'`, $I is back." >> $LOG
fi
else
if [ ${RSSTATUS[$COUNT]} -eq 1 ]; then
delrs $I
[ $? -eq 0 ] && RSSTATUS[$COUNT]=0 && echo "`date +'%F %H:%M:%S'`, $I is gone." >> $LOG
fi
fi
let COUNT++
done
sleep 5
done
[root@localhost ~]# bash -x health_check.sh(执行health_check.sh脚本)
+ VIP=172.16.100.1
+ CPORT=80
+ FAIL_BACK=127.0.0.1
+ RS=("172.16.100.7" "172.16.100.8")
+ declare -a RSSTATUS
+ RW=("2" "1")
+ RPORT=80
+ TYPE=g
+ CHKLOOP=3
+ LOG=/var/log/ipvsmonitor.log
+ initstatus
+ local I
+ local COUNT=0
+ for I in '${RS[*]}'
+ checkrs 172.16.100.7
+ local I=1
+ '[' 1 -le 3 ']'
+ curl --connect-timeout 1 http://172.16.100.7
+ return 0
+ RSSTATUS[$COUNT]=1
+ let COUNT++
+ for I in '${RS[*]}'
+ checkrs 172.16.100.8
+ local I=1
+ '[' 1 -le 3 ']'
+ curl --connect-timeout 1 http://172.16.100.8
+ return 0
+ RSSTATUS[$COUNT]=1
+ let COUNT++
+ :
+ let COUNT=0
+ for I in '${RS[*]}'
+ checkrs 172.16.100.7
+ local I=1
+ '[' 1 -le 3 ']'
+ curl --connect-timeout 1 http://172.16.100.7
+ return 0
+ '[' 1 -eq 0 ']'
+ let COUNT++
+ for I in '${RS[*]}'
+ checkrs 172.16.100.8
+ local I=1
+ '[' 1 -le 3 ']'
+ curl --connect-timeout 1 http://172.16.100.8
+ return 0
+ '[' 1 -eq 0 ']'
+ let COUNT++
+ sleep 5
RS1:
[root@localhost ~]# service httpd stop(停止httpd服务) 停止 httpd: [确定]
DR:
[root@localhost ~]# ipvsadm -L -n(查看集群服务,-n以数字显示) IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 172.16.100.1:80 wlc -> 172.16.100.8:80 Route 1 0 0 [root@localhost ~]# tail /var/log/ipvsmonitor.log(查看ipvsmonitor.log文件) 2016-03-14 12:43:51, 172.16.100.7 is gone. [root@localhost ~]# tail -f /var/log/ipvsmonitor.log(查看ipvsmonitor.log文件,-f显示文件最新追加的内容) 2016-03-14 12:43:51, 172.16.100.7 is gone.
RS1:
[root@localhost ~]# service httpd start(启动httpd服务) 启动 httpd: [确定]
DR:
[root@localhost ~]# tail -f /var/log/ipvsmonitor.log(查看ipvsmonitor.log文件,-f显示文件最新追加的内容) 2016-03-14 12:43:51, 172.16.100.7 is gone. 2016-03-14 12:52:29, 172.16.100.7 is back. [root@localhost ~]# ipvsadm -L -n(查看集群服务规则,-n以数字显示) IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 172.16.100.1:80 wlc -> 172.16.100.7:80 Route 2 0 0 -> 172.16.100.8:80 Route 1 0 0
RS1:
[root@localhost ~]# service httpd stop(停止httpd服务) 停止 httpd: [确定]
DR:
[root@localhost ~]# ipvsadm -L -n(查看集群服务规则,-n以数字显示) IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 172.16.100.1:80 wlc -> 172.16.100.8:80 Route 1 0 0 [root@localhost ~]# bash health_check.sh(执行health_check.sh脚本)
RS1:
[root@localhost ~]# service httpd start(启动httpd服务) 启动 httpd: [确定]
DR:
[root@localhost ~]# ipvsadm -L -n(查看集群服务规则,-n以数字显示) IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 172.16.100.1:80 wlc -> 172.16.100.7:80 Route 2 0 0 -> 172.16.100.8:80 Route 1 0 0 [root@localhost ~]# tail -f /var/log/ipvsmonitor.log(查看ipvsmonitor.log日志文件) 2016-03-14 12:43:51, 172.16.100.7 is gone. 2016-03-14 12:52:29, 172.16.100.7 is back. 2016-03-14 12:57:36, 172.16.100.7 is gone. 2016-03-14 12:59:44, 172.16.100.7 is back.
RS2:
[root@localhost ~]# service httpd stop(停止httpd服务) Stopping httpd: [ OK ]
DR:
[root@localhost ~]# tail -f /var/log/ipvsmonitor.log(查看ipvsmonitor.log文件内容,-f显示文件最新追加的内容)
2016-03-14 12:43:51, 172.16.100.7 is gone.
2016-03-14 12:52:29, 172.16.100.7 is back.
2016-03-14 12:57:36, 172.16.100.7 is gone.
2016-03-14 12:59:44, 172.16.100.7 is back.
2016-03-14 13:04:37, 172.16.100.8 is gone.
[root@localhost ~]# ipvsadm -L -n(查看集群服务规则,-n以数字显示)
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.16.100.1:80 wlc
-> 172.16.100.7:80 Route 2 0 0
[root@localhost ~]# vim health_check.sh(编辑health_check.sh脚本)
#!/bin/bash
#
VIP=172.16.100.1
CPORT=80
FAIL_BACK=127.0.0.1
RS=("172.16.100.7" "172.16.100.8")
declare -a RSSTATUS
RW=("2" "1")
RPORT=80
TYPE=g
CHKLOOP=3
LOG=/var/log/ipvsmonitor.log
addrs() {
ipvsadm -a -t $VIP:$CPORT -r $1:$RPORT -$TYPE -w $2
[ $? -eq 0 ] && return 0 || return 1
}
delrs() {
ipvsadm -d -t $VIP:$CPORT -r $1:$RPORT
[ $? -eq 0 ] && return 0 || return 1
}
checkrs() {
local I=1
while [ $I -le $CHKLOOP ]; do
if curl --connect-timeout 1 http://$1 &> /dev/null; then
return 0
fi
let I++
done
return 1
}
initstatus() {
local I
local COUNT=0
for I in ${RS[*]}; do
if checkrs $I; then
RSSTATUS[$COUNT]=1
else
RSSTATUS[$COUNT]=0
fi
let COUNT++
done
}
initstatus
while :; do
let COUNT=0
for I in ${RS[*]}; do
if checkrs $I; then
if [ ${RSSTATUS[$COUNT]} -eq 0 ]; then
addrs $I ${RW[$COUNT]}
[ $? -eq 0 ] && RSSTATUS[$COUNT]=1 && echo "`date +'%F %H:%M:%S'`, $I is back." >> $LOG
fi
else
if [ ${RSSTATUS[$COUNT]} -eq 1 ]; then
delrs $I
[ $? -eq 0 ] && RSSTATUS[$COUNT]=0 && echo "`date +'%F %H:%M:%S'`, $I is gone." >> $LOG
fi
fi
let COUNT++
done
sleep 5
done
[root@localhost ~]# man ipvsadm(查看ipvsadm的man帮助)
--persistent-conn(输出持久连接信息)
Output of persistent connection information. The list command with this option will display the persistent connection counter
information of each
server in service listing. The persistent connection is used to forward the actual connections from the same client/network
to the same server.
[root@localhost ~]# ipvsadm -L --persistent-conn(查看集群服务规则,--persistent-conn输出持久连接信息)
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Weight PersistConn ActiveConn InActConn
-> RemoteAddress:Port
TCP 172.16.100.1:http wlc
-> 172.16.100.7:http 2 0 0 0
[root@localhost ~]# ipvsadm -L -c(-c显示当前持久连接模版)
IPVS connection entries
pro expire(过期时长) state(当前连接状态) source virtual destination
测试:通过Windows系统的IE浏览器访问httpd://172.16.100.1页面,多次刷新;

[root@localhost ~]# ipvsadm -L -c(-c显示当前持久连接模版)
IPVS connection entries
pro expire state source virtual destination
TCP 01:37 FIN_WAIT 172.16.100.254:9028 172.16.100.1:http 172.16.100.7:http
TCP 01:36 FIN_WAIT 172.16.100.254:9027 172.16.100.1:http 172.16.100.7:http
TCP 01:40 FIN_WAIT 172.16.100.254:9037 172.16.100.1:http 172.16.100.7:http
TCP 01:39 FIN_WAIT 172.16.100.254:9030 172.16.100.1:http 172.16.100.7:http
TCP 01:39 FIN_WAIT 172.16.100.254:9032 172.16.100.1:http 172.16.100.7:http
TCP 01:40 FIN_WAIT 172.16.100.254:9039 172.16.100.1:http 172.16.100.7:http
TCP 01:41 FIN_WAIT 172.16.100.254:9052 172.16.100.1:http 172.16.100.7:http
TCP 01:39 FIN_WAIT 172.16.100.254:9031 172.16.100.1:http 172.16.100.7:http
TCP 01:41 FIN_WAIT 172.16.100.254:9053 172.16.100.1:http 172.16.100.7:http
TCP 01:39 FIN_WAIT 172.16.100.254:9029 172.16.100.1:http 172.16.100.7:http
TCP 01:40 FIN_WAIT 172.16.100.254:9036 172.16.100.1:http 172.16.100.7:http
TCP 01:40 FIN_WAIT 172.16.100.254:9033 172.16.100.1:http 172.16.100.7:http
[root@localhost ~]# man ipvsadm(查看ipvsadm的man帮助)
ipvsadm -A|E -t|u|f service-address [-s scheduler]
[-p [timeout]] [-O] [-M netmask](-p [timeout]指定时长,持久连接时长)
[root@localhost ~]# ipvsadm -L -n(查看集群服务规则,-n以数字显示)
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.16.100.1:80 wlc
-> 172.16.100.7:80 Route 2 0 0
RS2:
[root@localhost ~]# service httpd start(启动httpd服务) Starting httpd: [ OK ]
DR:
[root@localhost ~]# bash health_check.sh &(执行health_chech.sh脚本,在后台允许) [1] 24352 [root@localhost ~]# ipvsadm -L -n(查看集群服务规则,-n以数字显示) IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 172.16.100.1:80 wlc -> 172.16.100.7:80 Route 2 0 0 [root@localhost ~]# ps aux | grep bash(查看所有终端进程,只显示bash相关) root 24262 0.0 0.1 4988 1532 pts/2 Ss+ 14:08 0:00 -bash root 24289 0.0 0.1 4880 1404 pts/3 Ss+ 14:09 0:00 -bash root 24316 0.0 0.1 4988 1464 pts/4 Ss 14:09 0:00 -bash root 24824 0.0 0.1 4824 1100 pts/2 S 14:14 0:00 bash health_check.sh root 24755 0.0 0.0 4220 608 pts/4 R+ 14:24 0:00 grep bash [root@localhost ~]# tail /var/log/ipvsmonitor.log(查看ipvsmonitor.log文件内容) 2016-03-14 12:43:51, 172.16.100.7 is gone. 2016-03-14 12:52:29, 172.16.100.7 is back. 2016-03-14 12:57:36, 172.16.100.7 is gone. 2016-03-14 12:59:44, 172.16.100.7 is back. 2016-03-14 13:04:37, 172.16.100.8 is gone.
DR2:
[root@localhost ~]# service httpd restart(重启httpd服务) Stopping httpd: [ OK ] Starting httpd: [ OK ]
DR:
[root@localhost ~]# tail /var/log/ipvsmonitor.log(查看ipvsmonitor.log文件内容)
2016-03-14 12:43:51, 172.16.100.7 is gone.
2016-03-14 12:52:29, 172.16.100.7 is back.
2016-03-14 12:57:36, 172.16.100.7 is gone.
2016-03-14 12:59:44, 172.16.100.7 is back.
2016-03-14 13:04:37, 172.16.100.8 is gone.
[root@localhost ~]# kill 24824(杀死24824进程)
[root@localhost ~]# bash -x health_check.sh(执行health_check.sh脚本)
+ VIP=172.16.100.1
+ CPORT=80
+ FAIL_BACK=127.0.0.1
+ RS=("172.16.100.7" "172.16.100.8")
+ declare -a RSSTATUS
+ RW=("2" "1")
+ RPORT=80
+ TYPE=g
+ CHKLOOP=3
+ LOG=/var/log/ipvsmonitor.log
+ initstatus
+ local I
+ local COUNT=0
+ for I in '${RS[*]}'
+ checkrs 172.16.100.7
+ local I=1
+ '[' 1 -le 3 ']'
+ curl --connect-timeout 1 http://172.16.100.7
+ return 0
+ RSSTATUS[$COUNT]=1
+ let COUNT++
+ for I in '${RS[*]}'
+ checkrs 172.16.100.8
+ local I=1
+ '[' 1 -le 3 ']'
+ curl --connect-timeout 1 http://172.16.100.8
+ return 0
+ RSSTATUS[$COUNT]=1
+ let COUNT++
+ :
+ let COUNT=0
+ for I in '${RS[*]}'
+ checkrs 172.16.100.7
+ local I=1
+ '[' 1 -le 3 ']'
+ curl --connect-timeout 1 http://172.16.100.7
+ return 0
+ '[' 1 -eq 0 ']'
+ let COUNT++
+ for I in '${RS[*]}'
+ checkrs 172.16.100.8
+ local I=1
+ '[' 1 -le 3 ']'
+ curl --connect-timeout 1 http://172.16.100.8
+ return 0
+ '[' 1 -eq 0 ']'
+ let COUNT++
+ sleep 5
提示:它检查172.16.100.8是在线的,但他并没有检查172.16.100.8是不是在集群服务中;
[root@localhost ~]# ipvsadm -L -n(查看集群服务规则,-n以数字显示)
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.16.100.1:80 wlc
-> 172.16.100.7:80 Route 2 0 0
RS2:
[root@localhost ~]# service httpd stop(停止httpd服务) Stopping httpd: [ OK ]
DR:
[root@localhost ~]# bash health_check.sh &(执行health_check.sh脚本,后台执行) [1] 24984
RS2:
[root@localhost ~]# service httpd start(启动httpd服务) Starting httpd: [ OK ]
DR:
[root@localhost ~]# ipvsadm -L -n(查看集群服务规则,-n以数字显示) IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 172.16.100.1:80 wlc -> 172.16.100.8:80 Route 1 0 0 -> 172.16.100.7:80 Route 2 0 0 提示:它没有检查原来列表中是不有,只是检查了服务器的健康状况; [root@localhost ~]# ipvsadm -E -t 172.16.100.1:80 -s rr(修改集群分服务172.16.100.1:80的调度算法为rr) [root@localhost ~]# ipvsadm -L -n(查看集群服务规则,-n以数字显示) IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 172.16.100.1:80 rr -> 172.16.100.8:80 Route 1 0 0 -> 172.16.100.7:80 Route 2 0 0
测试:通过Windows的IE浏览器访问http://172.16.100.1页面,连续刷新页面,始终在RS1和RS2之间进行轮训调度切换;

[root@localhost ~]# ipvsadm -E -t 172.16.100.1:80 -s rr -p 600(修改集群服务172.16.100.1:80为持久连接,超时时间为600秒) [root@localhost ~]# ipvsadm -L -n(查看集群服务规则,-n以数字显示) IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 172.16.100.1:80 rr persistent 600 -> 172.16.100.8:80 Route 1 0 0 -> 172.16.100.7:80 Route 2 0 0
测试:通过Windows的IE浏览器访问http://172.16.100.1页面,连续刷新页面,一直都是同一个RS;

[root@localhost ~]# ipvsadm -L -n --persistent-conn(查看集群服务规则,--persistent-conn查看持久连接状况) IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Weight PersistConn ActiveConn InActConn -> RemoteAddress:Port TCP 172.16.100.1:80 rr persistent 600 -> 172.16.100.8:80 1 1 0 18 -> 172.16.100.7:80 2 0 0 0 提示:有一个持久连接被分配到172.16.100.8的realserver上,所以非活动连接非常的大,无论使用什么算法都是持久连接,但是对于不同的集群服务,它的持久算法可能就不一样了;
RS1:
[root@localhost ~]# chkconfig telnet on(让telnet服务向相应系统级别开机自动启动) [root@localhost ~]# service xinetd restart(启动xinetd服务) 停止 xinetd: [确定] 启动 xinetd: [确定] [root@localhost ~]# netstat -tnlp(查看系统服务,-t代表tcp,-n以数字显示,-l监听端口,-p显示协议名称) Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 127.0.0.1:2208 0.0.0.0:* LISTEN 3528/./hpiod tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 3179/portmap tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 3551/sshd tcp 0 0 0.0.0.0:23 0.0.0.0:* LISTEN 18873/xinetd tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN 3565/cupsd tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 3606/sendmail tcp 0 0 0.0.0.0:858 0.0.0.0:* LISTEN 3220/rpc.statd tcp 0 0 127.0.0.1:6011 0.0.0.0:* LISTEN 18766/sshd tcp 0 0 127.0.0.1:2207 0.0.0.0:* LISTEN 3533/python tcp 0 0 :::80 :::* LISTEN 18549/httpd tcp 0 0 :::22 :::* LISTEN 3551/sshd tcp 0 0 ::1:6011 :::* LISTEN 18766/sshd 提示:监听23号端口,说明telnet服务启动起来,telnet是不允许通过root用户远程登录的,于是要添加一个测试普通用户; [root@localhost ~]# useradd hadoop(创建hadoop用户) [root@localhost ~]# passwd hadoop (为hadoop用户添加密码) Changing password for user hadoop. New UNIX password: BAD PASSWORD: it is based on a dictionary word Retype new UNIX password: passwd: all authentication tokens updated successfully.
RS2:
[root@localhost ~]# chkconfig telnet on(让telnet服务在相应系统级别开机自动启动) [root@localhost ~]# service xinetd restart(重启xinetd服务) Stopping xinetd: [ OK ] Starting xinetd: [ OK ] [root@localhost ~]# netstat -tnlp(查看系统服务,-t代表tcp,-n以数字显示,-l监听端口,-p显示协议名称) Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 127.0.0.1:2208 0.0.0.0:* LISTEN 3530/./hpiod tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 3180/portmap tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 3553/sshd tcp 0 0 0.0.0.0:23 0.0.0.0:* LISTEN 10846/xinetd tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN 3567/cupsd tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 3608/sendmail tcp 0 0 127.0.0.1:6011 0.0.0.0:* LISTEN 10655/sshd tcp 0 0 0.0.0.0:859 0.0.0.0:* LISTEN 3221/rpc.statd tcp 0 0 127.0.0.1:2207 0.0.0.0:* LISTEN 3535/python tcp 0 0 :::80 :::* LISTEN 10794/httpd tcp 0 0 :::22 :::* LISTEN 3553/sshd tcp 0 0 ::1:6011 :::* LISTEN 10655/sshd [root@localhost ~]# useradd hadoop(添加用户hadoop) [root@localhost ~]# passwd hadoop(为hadoop用户设置密码) Changing password for user hadoop. New UNIX password: BAD PASSWORD: it is based on a dictionary word Retype new UNIX password: passwd: all authentication tokens updated successfully.
测试:通过Xshell软件telnet两个RS服务器;
[c:\~]$ telnet 172.16.100.8
Connecting to 172.16.100.8:23...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.
Red Hat Enterprise Linux Server release 5.8 (Tikanga)
Kernel 2.6.18-308.el5 on an i686
login: hadoop
Password:
[hadoop@localhost ~]$ /sbin/ifconfig(查看网卡接口信息)
eth0 Link encap:Ethernet HWaddr 00:0C:29:D9:86:95
inet addr:172.16.100.8 Bcast:172.16.100.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fed9:8695/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:37696 errors:0 dropped:0 overruns:0 frame:0
TX packets:30117 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:3372218 (3.2 MiB) TX bytes:3673696 (3.5 MiB)
Interrupt:67 Base address:0x2000
eth1 Link encap:Ethernet HWaddr 00:0C:29:D9:86:9F
inet addr:192.168.10.2 Bcast:192.168.10.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fed9:869f/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:6701 errors:0 dropped:0 overruns:0 frame:0
TX packets:4274 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:586905 (573.1 KiB) TX bytes:433632 (423.4 KiB)
Interrupt:83 Base address:0x2080
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:236 errors:0 dropped:0 overruns:0 frame:0
TX packets:236 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:28007 (27.3 KiB) TX bytes:28007 (27.3 KiB)
lo:0 Link encap:Local Loopback
inet addr:172.16.100.1 Mask:255.255.255.255
UP LOOPBACK RUNNING MTU:16436 Metric:1
[hadoop@localhost ~]$ logout(退出)
[c:\~]$ telnet 172.16.100.7
Connecting to 172.16.100.7:23...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.
Red Hat Enterprise Linux Server release 5.8 (Tikanga)
Kernel 2.6.18-308.el5 on an i686
login: hadoop
Password:
[hadoop@localhost ~]$ /sbin/ifconfig(查看网卡接口信息)
eth0 Link encap:Ethernet HWaddr 00:0C:29:B8:44:39
inet addr:172.16.100.7 Bcast:172.16.100.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:feb8:4439/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:88095 errors:0 dropped:0 overruns:0 frame:0
TX packets:80104 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:7772985 (7.4 MiB) TX bytes:9814998 (9.3 MiB)
Interrupt:67 Base address:0x2000
eth1 Link encap:Ethernet HWaddr 00:0C:29:B8:44:43
inet addr:192.168.10.1 Bcast:192.168.10.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:feb8:4443/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:10273 errors:0 dropped:0 overruns:0 frame:0
TX packets:10095 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:841289 (821.5 KiB) TX bytes:1602771 (1.5 MiB)
Interrupt:83 Base address:0x2080
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:180 errors:0 dropped:0 overruns:0 frame:0
TX packets:180 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:21109 (20.6 KiB) TX bytes:21109 (20.6 KiB)
lo:0 Link encap:Local Loopback
inet addr:172.16.100.1 Mask:255.255.255.255
UP LOOPBACK RUNNING MTU:16436 Metric:1
[hadoop@localhost ~]$ logout(退出)
DR:
[root@localhost ~]# ipvsadm -A -t 172.16.100.1:23 -s rr(创建集群服务172.16.100.1:23,-s指定调度算法) [root@localhost ~]# ipvsadm -a -t 172.16.100.1:23 -r 172.16.100.7 -g -w 2(向集群服务172.16.100.1:23添加realserver服务,-g指定为DR模型,-w指定权重) [root@localhost ~]# ipvsadm -a -t 172.16.100.1:23 -r 172.16.100.8 -g -w 2(向集群服务172.16.100.1:23添加realserver服务,-g制定DR模型,-w制定权重)
测试:通过Xshell软件telnet集群服务172.16.100.1:23;
[c:\~]$ telnet 172.16.100.1
Connecting to 172.16.100.1:23...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.
Red Hat Enterprise Linux Server release 5.8 (Tikanga)
Kernel 2.6.18-308.el5 on an i686
login: hadoop
Password:
Last login: Mon Mar 14 14:27:32 from 172.16.100.254
[hadoop@localhost ~]$ /sbin/ifconfig(查看网卡接口信息)
eth0 Link encap:Ethernet HWaddr 00:0C:29:D9:86:95
inet addr:172.16.100.8 Bcast:172.16.100.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fed9:8695/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:38246 errors:0 dropped:0 overruns:0 frame:0
TX packets:30623 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:3422302 (3.2 MiB) TX bytes:3733379 (3.5 MiB)
Interrupt:67 Base address:0x2000
eth1 Link encap:Ethernet HWaddr 00:0C:29:D9:86:9F
inet addr:192.168.10.2 Bcast:192.168.10.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fed9:869f/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:6717 errors:0 dropped:0 overruns:0 frame:0
TX packets:4288 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:588075 (574.2 KiB) TX bytes:434304 (424.1 KiB)
Interrupt:83 Base address:0x2080
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:240 errors:0 dropped:0 overruns:0 frame:0
TX packets:240 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:28355 (27.6 KiB) TX bytes:28355 (27.6 KiB)
lo:0 Link encap:Local Loopback
inet addr:172.16.100.1 Mask:255.255.255.255
UP LOOPBACK RUNNING MTU:16436 Metric:1
[hadoop@localhost ~]$ logout(退出)
[c:\~]$ telnet 172.16.100.1
Connecting to 172.16.100.1:23...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.
Red Hat Enterprise Linux Server release 5.8 (Tikanga)
Kernel 2.6.18-308.el5 on an i686
login: hadoop
Password:
Last login: Mon Mar 14 14:28:52 from 172.16.100.254
[hadoop@localhost ~]$ /sbin/ifconfig(查看网卡接口信息)
eth0 Link encap:Ethernet HWaddr 00:0C:29:B8:44:39
inet addr:172.16.100.7 Bcast:172.16.100.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:feb8:4439/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:88611 errors:0 dropped:0 overruns:0 frame:0
TX packets:80588 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:7820213 (7.4 MiB) TX bytes:9872046 (9.4 MiB)
Interrupt:67 Base address:0x2000
eth1 Link encap:Ethernet HWaddr 00:0C:29:B8:44:43
inet addr:192.168.10.1 Bcast:192.168.10.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:feb8:4443/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:10289 errors:0 dropped:0 overruns:0 frame:0
TX packets:10109 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:842459 (822.7 KiB) TX bytes:1603443 (1.5 MiB)
Interrupt:83 Base address:0x2080
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:184 errors:0 dropped:0 overruns:0 frame:0
TX packets:184 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:21457 (20.9 KiB) TX bytes:21457 (20.9 KiB)
lo:0 Link encap:Local Loopback
inet addr:172.16.100.1 Mask:255.255.255.255
UP LOOPBACK RUNNING MTU:16436 Metric:1
[hadoop@localhost ~]$ logout(退出)
[root@localhost ~]# ipvsadm -E -t 172.16.100.1:23 -s rr -p 3600(修改集群服务支持持久连接,-s指定调度算法,-p指定持久连接时间)
测试:通过Xshell软件telnet集群服务172.16.100.1:23;
[c:\~]$ telnet 172.16.100.1
Connecting to 172.16.100.1:23...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.
Red Hat Enterprise Linux Server release 5.8 (Tikanga)
Kernel 2.6.18-308.el5 on an i686
login: hadoop
Password:
Last login: Mon Mar 14 14:34:32 from 172.16.100.254
[hadoop@localhost ~]$ /sbin/ifconfig(显示网卡接口信息)
eth0 Link encap:Ethernet HWaddr 00:0C:29:D9:86:95
inet addr:172.16.100.8 Bcast:172.16.100.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fed9:8695/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:38557 errors:0 dropped:0 overruns:0 frame:0
TX packets:30902 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:3449748 (3.2 MiB) TX bytes:3765973 (3.5 MiB)
Interrupt:67 Base address:0x2000
eth1 Link encap:Ethernet HWaddr 00:0C:29:D9:86:9F
inet addr:192.168.10.2 Bcast:192.168.10.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fed9:869f/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:6726 errors:0 dropped:0 overruns:0 frame:0
TX packets:4296 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:588735 (574.9 KiB) TX bytes:434688 (424.5 KiB)
Interrupt:83 Base address:0x2080
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:244 errors:0 dropped:0 overruns:0 frame:0
TX packets:244 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:28703 (28.0 KiB) TX bytes:28703 (28.0 KiB)
lo:0 Link encap:Local Loopback
inet addr:172.16.100.1 Mask:255.255.255.255
UP LOOPBACK RUNNING MTU:16436 Metric:1
[hadoop@localhost ~]$ logout(退出)
[c:\~]$ telnet 172.16.100.1
Connecting to 172.16.100.1:23...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.
Red Hat Enterprise Linux Server release 5.8 (Tikanga)
Kernel 2.6.18-308.el5 on an i686
login: hadoop
Password:
Last login: Mon Mar 14 14:39:03 from 172.16.100.254
[hadoop@localhost ~]$ /sbin/ifconfig(查看网卡接口信息)
eth0 Link encap:Ethernet HWaddr 00:0C:29:D9:86:95
inet addr:172.16.100.8 Bcast:172.16.100.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fed9:8695/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:38682 errors:0 dropped:0 overruns:0 frame:0
TX packets:31012 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:3459602 (3.2 MiB) TX bytes:3778055 (3.6 MiB)
Interrupt:67 Base address:0x2000
eth1 Link encap:Ethernet HWaddr 00:0C:29:D9:86:9F
inet addr:192.168.10.2 Bcast:192.168.10.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fed9:869f/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:6728 errors:0 dropped:0 overruns:0 frame:0
TX packets:4298 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:588885 (575.0 KiB) TX bytes:434784 (424.5 KiB)
Interrupt:83 Base address:0x2080
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:248 errors:0 dropped:0 overruns:0 frame:0
TX packets:248 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:29051 (28.3 KiB) TX bytes:29051 (28.3 KiB)
lo:0 Link encap:Local Loopback
inet addr:172.16.100.1 Mask:255.255.255.255
UP LOOPBACK RUNNING MTU:16436 Metric:1
[hadoop@localhost ~]$ logout(退出)
提示:根据请求的客户端不同,我们集群服务定义两个,一个是web服务一个是telnet服务,这两种服务来自同一个客户端的请求她们可能定向的位置不一样,对于80服务的请求,第一次定义到172.16.100.7,一直访问都是172.16.100.7,但是对于23号端口的服务就不一定是172.16.100.7了,尽管在同一个集群内,但由于她们不是相同的集群服务,它只对同一个端口进行持久,向刚才用的机制是PPC,持久端口连接;
[root@localhost ~]# ps aux | grep bash(查看所有终端进程,只显示bash相关) root 24262 0.0 0.1 4988 1548 pts/2 Ss+ 14:08 0:00 -bash root 24289 0.0 0.1 4880 1404 pts/3 Ss+ 14:09 0:00 -bash root 24316 0.0 0.1 4988 1480 pts/4 Ss 14:09 0:00 -bash root 24984 0.0 0.1 4828 1196 pts/2 S 14:34 0:00 bash health_check.sh root 26511 0.0 0.0 4220 608 pts/4 R+ 15:14 0:00 grep bash [root@localhost ~]# kill 24984(杀死24984进程) [root@localhost ~]# ipvsadm -C(情况ipvs集群服务所有规则) [root@localhost ~]# ipvsadm -A -t 172.16.100.1:0 -s rr -p 600(添加集群服务172.16.100.1:0,-s指定调度算法,-p启用持久连接,持久连接时间600秒) [root@localhost ~]# ipvsadm -a -t 172.16.100.1:0 -r 172.16.100.7 -g -w 2(向集群服务172.16.100.1:0添加realserver,-g指定为DR模型,-w指定权重) [root@localhost ~]# ipvsadm -a -t 172.16.100.1:0 -r 172.16.100.8 -g -w 2(向集群服务172.16.100.1:0添加realserver,-g指定为DR模型,-w指定权重) 提示:把0端口定义为集群服务,意味着把所有端口请求都是集群服务;
测试:通过Windows系统IE浏览器访问http://172.16.100.1页面,对于web服务挑选的是RS2服务器;

测试:通过Xshell软件telnet连接172.16.100.1;
Type `help' to learn how to use Xshell prompt.
[c:\~]$ telnet 172.16.100.1
Connecting to 172.16.100.1:23...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.
Red Hat Enterprise Linux Server release 5.8 (Tikanga)
Kernel 2.6.18-308.el5 on an i686
login: hadoop
Password:
Last login: Mon Mar 14 14:40:04 from 172.16.100.254
[hadoop@localhost ~]$ /sbin/ifconfig(查看网卡接口信息)
eth0 Link encap:Ethernet HWaddr 00:0C:29:D9:86:95
inet addr:172.16.100.8 Bcast:172.16.100.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fed9:8695/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:39301 errors:0 dropped:0 overruns:0 frame:0
TX packets:31566 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:3519070 (3.3 MiB) TX bytes:3838207 (3.6 MiB)
Interrupt:67 Base address:0x2000
eth1 Link encap:Ethernet HWaddr 00:0C:29:D9:86:9F
inet addr:192.168.10.2 Bcast:192.168.10.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fed9:869f/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:6764 errors:0 dropped:0 overruns:0 frame:0
TX packets:4330 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:591525 (577.6 KiB) TX bytes:436320 (426.0 KiB)
Interrupt:83 Base address:0x2080
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:252 errors:0 dropped:0 overruns:0 frame:0
TX packets:252 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:29399 (28.7 KiB) TX bytes:29399 (28.7 KiB)
lo:0 Link encap:Local Loopback
inet addr:172.16.100.1 Mask:255.255.255.255
UP LOOPBACK RUNNING MTU:16436 Metric:1
提示:对于telnet服务挑选的也是RS2服务器;
测试:通过Xshell软件SHH集群服务172.16.100.1;
[c:\~]$ ssh 172.16.100.1
Connecting to 172.16.100.1:22...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.
Last login: Mon Mar 14 13:40:42 2016 from 192.168.10.254
[root@localhost ~]# ifconfig(查看网卡接口信息)
eth0 Link encap:Ethernet HWaddr 00:0C:29:D9:86:95
inet addr:172.16.100.8 Bcast:172.16.100.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fed9:8695/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:39365 errors:0 dropped:0 overruns:0 frame:0
TX packets:31624 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:3525495 (3.3 MiB) TX bytes:3846140 (3.6 MiB)
Interrupt:67 Base address:0x2000
eth1 Link encap:Ethernet HWaddr 00:0C:29:D9:86:9F
inet addr:192.168.10.2 Bcast:192.168.10.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fed9:869f/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:6770 errors:0 dropped:0 overruns:0 frame:0
TX packets:4336 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:591975 (578.1 KiB) TX bytes:436608 (426.3 KiB)
Interrupt:83 Base address:0x2080
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:256 errors:0 dropped:0 overruns:0 frame:0
TX packets:256 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:29747 (29.0 KiB) TX bytes:29747 (29.0 KiB)
lo:0 Link encap:Local Loopback
inet addr:172.16.100.1 Mask:255.255.255.255
UP LOOPBACK RUNNING MTU:16436 Metric:1
提示:对于SSH服务挑选的也是RS2服务器,只要使用了PCC,持久客户端连接,把所有的服务都定义为集群服务;
[root@localhost ~]# ipvsadm -L -n -c(-c显示当前持久连接模版) IPVS connection entries pro expire state source virtual destination TCP 14:04 ESTABLISHED 172.16.100.254:13236 172.16.100.1:23 172.16.100.8:23 TCP 14:39 ESTABLISHED 172.16.100.254:13359 172.16.100.1:22 172.16.100.8:22 TCP 06:39 NONE 172.16.100.254:0 172.16.100.1:0 172.16.100.8:0 TCP 38:12 NONE 172.16.100.254:0 172.16.100.1:23 172.16.100.8:23 提示:此前的请求都被定义到同一个realserver上去了,有些状态为NONE,这意味着,对于telnet这样的连接跟web服务不一样,web服务下载完一个web对象以后就立即断开了,长连 接过一会也会断开的,telnet连接上去以后,无论发不发命令这个连接一直在线,telnet是远程登录,跟ssh一样,只要登录以后它会一直在线,所以这是两种不同类型的服务,所以它们 的状态吗可能不完全一样; [root@localhost ~]# ipvsadm -C(清空集群服务规则) [root@localhost ~]# service ipvsadm save(保存ipvsadm规则) ipvsadm: Saving IPVS table to /etc/sysconfig/ipvsadm: [ OK ] [root@localhost ~]# service ipvsadm restart(重启ipvsadm服务) ipvsadm: Clearing the current IPVS table: [ OK ] ipvsadm: Unloading modules: [ OK ] ipvsadm: Clearing the current IPVS table: [ OK ] ipvsadm: Applying IPVS configuration: [ OK ] [root@localhost ~]# iptables -t mangle -A PREROUTING -d 172.16.100.1 -i eth0 -p tcp --dport 80 -j MARK --set-mark 8(向mangle表的PREROUTING 链添加规则,从eth0进入到达172.16.100.1的tcp协议80端口打标记为8,-A附加规则,-d目标地址,-i进入网卡,-p协议,--dport目标端口,-j动作,--set-mark标记) [root@localhost ~]# iptables -t mangle -A PREROUTING -d 172.16.100.1 -i eth0 -p tcp --dport 23 -j MARK --set-mark 8(向mangle表的PREROUTING 链添加规则,从eth0进入到达172.16.100.1的tcp协议23端口打标记为8,-A附加规则,-d目标地址,-i进入网卡,-p协议,--dport目标端口,-j动作,--set-mark标记) [root@localhost ~]# man ipvsadm(查看ipvsadm的man帮助) [root@localhost ~]# ipvsadm -A -f 8 -s rr(添加集群服务,-f指定防火墙标记,-s指定调度算法) [root@localhost ~]# ipvsadm -a -f 8 -r 172.16.100.7 -g -w 2(向集群服务添加realserver,-f指定防火墙标记,-g指定为DR模型,-w指定权重) [root@localhost ~]# ipvsadm -a -f 8 -r 172.16.100.8 -g -w 5(向集群服务添加realserver,-f指定防火墙标记,-g指定为DR模型,-w指定权重)
测试:通过Xshell软件通过SSH连接172.16.100.1,访问的是DR主机,所以它不会再影响其他服务;
[c:\~]$ ssh 172.16.100.1
Connecting to 172.16.100.1:22...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.
Last login: Mon Mar 14 14:09:04 2016 from 172.16.100.254
[root@localhost ~]# ifconfig(查看网卡接口信息)
eth0 Link encap:Ethernet HWaddr 00:0C:29:CC:FA:AE
inet addr:172.16.100.2 Bcast:172.16.100.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fecc:faae/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:167632 errors:0 dropped:0 overruns:0 frame:0
TX packets:158936 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:14834721 (14.1 MiB) TX bytes:20532526 (19.5 MiB)
Interrupt:67 Base address:0x2000
eth0:0 Link encap:Ethernet HWaddr 00:0C:29:CC:FA:AE
inet addr:172.16.100.1 Bcast:172.16.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
Interrupt:67 Base address:0x2000
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:48007 errors:0 dropped:0 overruns:0 frame:0
TX packets:48007 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:4090426 (3.9 MiB) TX bytes:4090426 (3.9 MiB)
[root@localhost ~]# logout(退出)
测试:通过Xshell软件telnet 172.16.100.1集群服务;
[c:\~]$ telnet 172.16.100.1
Connecting to 172.16.100.1:23...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.
Red Hat Enterprise Linux Server release 5.8 (Tikanga)
Kernel 2.6.18-308.el5 on an i686
login: hadoop
Password:
Last login: Mon Mar 14 14:55:55 from 172.16.100.254
[hadoop@localhost ~]$ /sbin/ifconfig(查看网卡接口信息)
eth0 Link encap:Ethernet HWaddr 00:0C:29:D9:86:95
inet addr:172.16.100.8 Bcast:172.16.100.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fed9:8695/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:39731 errors:0 dropped:0 overruns:0 frame:0
TX packets:31936 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:3550888 (3.3 MiB) TX bytes:3864899 (3.6 MiB)
Interrupt:67 Base address:0x2000
eth1 Link encap:Ethernet HWaddr 00:0C:29:D9:86:9F
inet addr:192.168.10.2 Bcast:192.168.10.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fed9:869f/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:6995 errors:0 dropped:0 overruns:0 frame:0
TX packets:4511 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:609653 (595.3 KiB) TX bytes:445002 (434.5 KiB)
Interrupt:83 Base address:0x2080
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:260 errors:0 dropped:0 overruns:0 frame:0
TX packets:260 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:30095 (29.3 KiB) TX bytes:30095 (29.3 KiB)
lo:0 Link encap:Local Loopback
inet addr:172.16.100.1 Mask:255.255.255.255
UP LOOPBACK RUNNING MTU:16436 Metric:1
[hadoop@localhost ~]$ logout(退出)
[c:\~]$ telnet 172.16.100.1
Connecting to 172.16.100.1:23...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.
Red Hat Enterprise Linux Server release 5.8 (Tikanga)
Kernel 2.6.18-308.el5 on an i686
login: hadoop
Password:
Last login: Mon Mar 14 14:36:01 from 172.16.100.254
[hadoop@localhost ~]$ /sbin/ifconfig(查看网卡接口信息)
eth0 Link encap:Ethernet HWaddr 00:0C:29:B8:44:39
inet addr:172.16.100.7 Bcast:172.16.100.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:feb8:4439/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:89363 errors:0 dropped:0 overruns:0 frame:0
TX packets:81244 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:7890097 (7.5 MiB) TX bytes:9950933 (9.4 MiB)
Interrupt:67 Base address:0x2000
eth1 Link encap:Ethernet HWaddr 00:0C:29:B8:44:43
inet addr:192.168.10.1 Bcast:192.168.10.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:feb8:4443/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:10567 errors:0 dropped:0 overruns:0 frame:0
TX packets:10331 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:864037 (843.7 KiB) TX bytes:1614099 (1.5 MiB)
Interrupt:83 Base address:0x2080
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:188 errors:0 dropped:0 overruns:0 frame:0
TX packets:188 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:21805 (21.2 KiB) TX bytes:21805 (21.2 KiB)
lo:0 Link encap:Local Loopback
inet addr:172.16.100.1 Mask:255.255.255.255
UP LOOPBACK RUNNING MTU:16436 Metric:1
[hadoop@localhost ~]$ logout(退出)
提示:这次telnet的RS主机是172.16.100.7,没有持久连接;
测试:通过Windows的IE浏览器访问http://172.16.100.1的页面,访问的是RS1主机web服务;

重新刷新页面,访问的是RS2主机的web服务;

提示:使用防火墙标记方式将两个服务一并定义为集群服务,但是由于没有使用持久连接,它们各自都遵循同一种算法,而且都是同一个集群服务当中的调度机制,所以只要两个集群服务使用同一种调度机制,完全可以把它们归类为防火墙标记连接;
[root@localhost ~]# ipvsadm -E -f 8 -s rr -p 600(修改集群服务为持久连接,-f防火墙标记,-s调度算法,-p持久连接超时时间)
测试:通过Windows的IE浏览器访问http://172.16.100.1的页面,多次刷新页面,一直访问的是RS1的web服务;

测试:通过Xshell软件telnet 172.16.100.1集群服务,访问的也是RS1主机;
[c:\~]$ telnet 172.16.100.1
Connecting to 172.16.100.1:23...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.
Red Hat Enterprise Linux Server release 5.8 (Tikanga)
Kernel 2.6.18-308.el5 on an i686
login: hadoop
Password:
Last login: Mon Mar 14 16:25:49 from 172.16.100.254
[hadoop@localhost ~]$ /sbin/ifconfig(查看网卡接口信息)
eth0 Link encap:Ethernet HWaddr 00:0C:29:B8:44:39
inet addr:172.16.100.7 Bcast:172.16.100.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:feb8:4439/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:89515 errors:0 dropped:0 overruns:0 frame:0
TX packets:81386 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:7906179 (7.5 MiB) TX bytes:9963152 (9.5 MiB)
Interrupt:67 Base address:0x2000
eth1 Link encap:Ethernet HWaddr 00:0C:29:B8:44:43
inet addr:192.168.10.1 Bcast:192.168.10.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:feb8:4443/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:10583 errors:0 dropped:0 overruns:0 frame:0
TX packets:10347 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:865237 (844.9 KiB) TX bytes:1614867 (1.5 MiB)
Interrupt:83 Base address:0x2080
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:192 errors:0 dropped:0 overruns:0 frame:0
TX packets:192 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:22153 (21.6 KiB) TX bytes:22153 (21.6 KiB)
lo:0 Link encap:Local Loopback
inet addr:172.16.100.1 Mask:255.255.255.255
UP LOOPBACK RUNNING MTU:16436 Metric:1
[hadoop@localhost ~]$ logout(退出)
[c:\~]$ telnet 172.16.100.1
Connecting to 172.16.100.1:23...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.
Red Hat Enterprise Linux Server release 5.8 (Tikanga)
Kernel 2.6.18-308.el5 on an i686
login: hadoop
Password:
Last login: Mon Mar 14 16:25:49 from 172.16.100.254
[hadoop@localhost ~]$ /sbin/ifconfig(查看网卡接口信息)
eth0 Link encap:Ethernet HWaddr 00:0C:29:B8:44:39
inet addr:172.16.100.7 Bcast:172.16.100.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:feb8:4439/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:89515 errors:0 dropped:0 overruns:0 frame:0
TX packets:81386 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:7906179 (7.5 MiB) TX bytes:9963152 (9.5 MiB)
Interrupt:67 Base address:0x2000
eth1 Link encap:Ethernet HWaddr 00:0C:29:B8:44:43
inet addr:192.168.10.1 Bcast:192.168.10.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:feb8:4443/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:10583 errors:0 dropped:0 overruns:0 frame:0
TX packets:10347 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:865237 (844.9 KiB) TX bytes:1614867 (1.5 MiB)
Interrupt:83 Base address:0x2080
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:192 errors:0 dropped:0 overruns:0 frame:0
TX packets:192 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:22153 (21.6 KiB) TX bytes:22153 (21.6 KiB)
lo:0 Link encap:Local Loopback
inet addr:172.16.100.1 Mask:255.255.255.255
UP LOOPBACK RUNNING MTU:16436 Metric:1
[hadoop@localhost ~]$ logout(退出)
RS健康状态检查脚本示例第二版:
#!/bin/bash
#
VIP=192.168.10.3
CPORT=80
FAIL_BACK=127.0.0.1
RS=("192.168.10.7" "192.168.10.8")
declare -a RSSTATUS
RW=("2" "1")
RPORT=80
TYPE=g
CHKLOOP=3
LOG=/var/log/ipvsmonitor.log
addrs() {
ipvsadm -a -t $VIP:$CPORT -r $1:$RPORT -$TYPE -w $2
[ $? -eq 0 ] && return 0 || return 1
}
delrs() {
ipvsadm -d -t $VIP:$CPORT -r $1:$RPORT
[ $? -eq 0 ] && return 0 || return 1
}
checkrs() {
local I=1
while [ $I -le $CHKLOOP ]; do
if curl --connect-timeout 1 http://$1 &> /dev/null; then
return 0
fi
let I++
done
return 1
}
initstatus() {
local I
local COUNT=0;
for I in ${RS[*]}; do
if ipvsadm -L -n | grep "$I:$RPORT" && > /dev/null ; then
RSSTATUS[$COUNT]=1
else
RSSTATUS[$COUNT]=0
fi
let COUNT++
done
}
initstatus
while :; do
let COUNT=0
for I in ${RS[*]}; do
if checkrs $I; then
if [ ${RSSTATUS[$COUNT]} -eq 0 ]; then
addrs $I ${RW[$COUNT]}
[ $? -eq 0 ] && RSSTATUS[$COUNT]=1 && echo "`date +'%F %H:%M:%S'`, $I is back." >> $LOG
fi
else
if [ ${RSSTATUS[$COUNT]} -eq 1 ]; then
delrs $I
[ $? -eq 0 ] && RSSTATUS[$COUNT]=0 && echo "`date +'%F %H:%M:%S'`, $I is gone." >> $LOG
fi
fi
let COUNT++
done
sleep 5
done
grep: 文本过滤器
grep 'pattern' input_file ...
sed: 流编辑器
sed 'COMMAND/PATTERN/'
awk: 报告生成器,根据输入的信息格式化以后,显示
格式化以后,显示
AWK a.ka. Aho, Kernighan and Weinberger
new awk: nawk
gawk, awk
# awk [options] 'script' file1, file2, ...(script报告格式化脚本,可以从多个文件读取文本信息,而后根据指定脚本,将其格式化为特定格式,而后显示值)
# awk [options] 'PATTERN { action }' file1, file2, ...(PATTERN模式,并不是对文件中的每一行都进行处理,处理那些能够被模式匹配到的行,行匹配到以后做出相应处理)
print, printf(可以自定义显示格式)
-F: 指定分隔符;
awk的输出:
一、print
print的使用格式:
print item1, item2, ...(item1那个字段)
要点:
1、各项目之间使用逗号隔开,而输出时则以空白字符分隔;
2、输出的item可以为字符串或数值、当前记录的字段(如$1)、变量或awk的表达式;数值会先转换为字符串,而后再输出;
3、print命令后面的item可以省略,此时其功能相当于print $0, 因此,如果想输出空白行,则需要使用print "";
例子:
# awk 'BEGIN { print "line one\nline two\nline three" }'
awk -F: '{ print $1, $3 }' /etc/passwd
二、awk变量
2.1 awk内置变量之记录变量:
FS: field separator,读取文件本时,所使用字段分隔符;
RS: Record separator,输入文本信息所使用的换行符;
OFS: Output Filed Separator: 输出字段分隔符;
ORS:Output Row Separator:输出行分隔符;
awk -F:(指定输入分隔符)
OFS="#"(输出分隔符)
FS=":"(输入分隔符)
2.2 awk内置变量之数据变量:
NR: The number of input records,awk命令所处理的记录数;如果有多个文件,这个数目会把处理的多个文件中行统一计数;
NF:Number of Field,当前记录的field个数,当前正在处理的行有多少字段;
FNR: 与NR不同的是,FNR用于记录正处理的行是当前这一文件中被总共处理的行数;
ARGV: 数组,保存命令行本身这个字符串,如awk '{print $0}' a.txt b.txt这个命令中,ARGV[0]保存awk,ARGV[1]保存a.txt;
ARGC: awk命令的参数的个数;
FILENAME: awk命令所处理的文件的名称;
ENVIRON:当前shell环境变量及其值的关联数组;
如:awk 'BEGIN{print ENVIRON["PATH"]}'
2.3 用户自定义变量
gawk允许用户自定义自己的变量以便在程序代码中使用,变量名命名规则与大多数编程语言相同,只能使用字母、数字和下划线,且不能以数字开头。gawk变量名称区分字符大小写。
2.3.1 在脚本中赋值变量
在gawk中给变量赋值使用赋值语句进行,例如:
awk 'BEGIN{var="variable testing";print var}'
2.3.2 在命令行中使用赋值变量
gawk命令也可以在“脚本”外为变量赋值,并在脚本中进行引用。例如,上述的例子还可以改写为:
awk -v var="variable testing" 'BEGIN{print var}'
三、printf
printf命令的使用格式:
printf format, item1, item2, ...(format指定格式,item1字段)
要点:
1、其与print命令的最大不同是,printf需要指定format;
2、format用于指定后面的每个item的输出格式;
3、printf语句不会自动打印换行符;\n
format格式的指示符都以%开头,后跟一个字符;如下:
%c: 显示字符的ASCII码;
%d, %i:十进制整数;
%e, %E:科学计数法显示数值;
%f: 显示浮点数;
%g, %G: 以科学计数法的格式或浮点数的格式显示数值;
%s: 显示字符串;
%u: 无符号整数;
%%: 显示%自身;
修饰符:
N: 显示宽度;
-: 左对齐;
+:显示数值符号;
例子:
# awk -F: '{printf "%-15s %i\n",$1,$3}' /etc/passwd
四、输出重定向
print items > output-file
print items >> output-file
print items | command
特殊文件描述符:
/dev/stdin:标准输入
/dev/sdtout: 标准输出
/dev/stderr: 错误输出
/dev/fd/N: 某特定文件描述符,如/dev/stdin就相当于/dev/fd/0;
例子:
# awk -F: '{printf "%-15s %i\n",$1,$3 > "/dev/stderr" }' /etc/passwd
六、awk的操作符:
6.1 算术操作符:
-x: 负值
+x: 转换为数值;
x^y: 次方
x**y: 次方
x*y: 乘法
x/y:除法
x+y: 加
x-y: 减
x%y:取余
6.2 字符串操作符:
只有一个,而且不用写出来,用于实现字符串连接;
6.3 赋值操作符:
=
+=
-=
*=
/=
%=
^=
**=
++
--
需要注意的是,如果某模式为=号,此时使用/=/可能会有语法错误,应以/[=]/替代;
6.4 布尔值
awk中,任何非0值或非空字符串都为真,反之就为假;
6.5 比较操作符:
x < y True if x is less than y. (小于)
x <= y True if x is less than or equal to y. (小于等于)
x > y True if x is greater than y. (大于)
x >= y True if x is greater than or equal to y. (大于等于)
x == y True if x is equal to y. (等于)
x != y True if x is not equal to y. (不等于)
x ~ y True if the string x matches the regexp denoted by y. (x字符串能够被y指定的模式匹配到就为真,否则就为假,y是模式,是正则表达式模式,x是字符串)
x !~ y True if the string x does not match the regexp denoted by y. (x字符串不能被y指定的模式匹配到就为真,否则就为假,)
subscript in array True if the array array has an element with the subscript subscript.(在指定的数组当中有对应元素下标就为真,否则为假;)
6.7 表达式间的逻辑关系符:
&& 与
|| 或
6.8 条件表达式:
selector?if-true-exp:if-false-exp(三目操作符,selector条件,判断真假,如果真取if-true-exp字符,否则取if-false-exp字符)
if selector; then
if-true-exp
else
if-false-exp
fi
a=3
b=4
a>b?a is max:b ia max
6.9 函数调用:
function_name (para1,para2)
七 awk的模式:
awk 'program' input-file1 input-file2 ...
其中的program为:
pattern { action }
pattern { action }
...
7.1 常见的模式类型:
1、Regexp: 正则表达式,格式为/regular expression/
2、expresssion: 表达式,其值非0或为非空字符时满足条件,如:$1 ~ /foo/ 或 $1 == "magedu",用运算符~(匹配)和!~(不匹配)。
3、Ranges: 指定的匹配范围,格式为pat1,pat2
4、BEGIN/END:特殊模式,仅在awk命令执行前运行一次或结束前运行一次
5、Empty(空模式):匹配任意输入行;
7.2 常见的Action
1、Expressions:(表达式)
2、Control statements(控制语句)
3、Compound statements(复合语句)
4、Input statements(输入语句)
5、Output statements(输出语句)
/正则表达式/:使用通配符的扩展集。
关系表达式:可以用下面运算符表中的关系运算符进行操作,可以是字符串或数字的比较,如$2>%1选择第二个字段比第一个字段长的行。
模式匹配表达式:
模式,模式:指定一个行的范围。该语法不能包括BEGIN和END模式。
BEGIN:让用户指定在第一条输入记录被处理之前所发生的动作,通常可在这里设置全局变量。
END:让用户在最后一条输入记录被读取之后发生的动作。
八 控制语句:
8.1 if-else
语法:if (condition) {then-body} else {[ else-body ]}
例子:
awk -F: '{if ($1=="root") print $1, "Admin"; else print $1, "Common User"}' /etc/passwd
awk -F: '{if ($1=="root") printf "%-15s: %s\n", $1,"Admin"; else printf "%-15s: %s\n", $1, "Common User"}' /etc/passwd
awk -F: -v sum=0 '{if ($3>=500) sum++}END{print sum}' /etc/passwd
8.2 while
语法: while (condition){statement1; statment2; ...}
awk -F: '{i=1;while (i<=3) {print $i;i++}}' /etc/passwd
awk -F: '{i=1;while (i<=NF) { if (length($i)>=4) {print $i}; i++ }}' /etc/passwd
8.3 do-while(c语言风格循环,和while区别,while先判断条件,条件满足才循环,而do-while不管条件满足不满足先上来执行一轮,执行一轮以后再判断)
语法: do {statement1, statement2, ...} while (condition)
awk -F: '{i=1;do {print $i;i++}while(i<=3)}' /etc/passwd
8.4 for
语法: for ( variable assignment; condition; iteration process) { statement1, statement2, ...}
awk -F: '{for(i=1;i<=3;i++) print $i}' /etc/passwd
awk -F: '{for(i=1;i<=NF;i++) { if (length($i)>=4) {print $i}}}' /etc/passwd
for循环还可以用来遍历数组元素:
语法: for (i in array) {statement1, statement2, ...}
awk -F: '$NF!~/^$/{BASH[$NF]++}END{for(A in BASH){printf "%15s:%i\n",A,BASH[A]}}' /etc/passwd
8.5 case
语法:switch (expression) { case VALUE or /REGEXP/: statement1, statement2,... default: statement1, ...}
8.6 break 和 continue
常用于循环或case语句中
8.7 next
提前结束对本行文本的处理,并接着处理下一行;例如,下面的命令将显示其ID号为奇数的用户:
# awk -F: '{if($3%2==0) next;print $1,$3}' /etc/passwd
九 awk中使用数组
9.1 数组(awk的数据下标从1开始,可以自定义下标)
array[index-expression]
index-expression可以使用任意字符串;需要注意的是,如果某数据组元素事先不存在,那么在引用其时,awk会自动创建此元素并初始化为空串;因此,要判断某数据组中是否存在某元素,需要使用index in array的方式。
要遍历数组中的每一个元素,需要使用如下的特殊结构:
for (var in array) { statement1, ... }
其中,var用于引用数组下标,而不是元素值;
例子:
netstat -ant | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
每出现一被/^tcp/模式匹配到的行,数组S[$NF]就加1,NF为当前匹配到的行的最后一个字段,此处用其值做为数组S的元素索引;
awk '{counts[$1]++}; END {for(url in counts) print counts[url], url}' /var/log/httpd/access_log
用法与上一个例子相同,用于统计某日志文件中IP地的访问量
9.2 删除数组变量
从关系数组中删除数组索引需要使用delete命令。使用格式为:
delete array[index]
十、awk的内置函数
split(string, array [, fieldsep [, seps ] ])
功能:将string表示的字符串以fieldsep为分隔符进行分隔,并将分隔后的结果保存至array为名的数组中;数组下标为从0开始的序列;
netstat -ant | awk '/:80\>/{split($5,clients,":");IP[clients[1]]++}END{for(i in IP){print IP[i],i}}' | sort -rn | head -50
length([string])
功能:返回string字符串中字符的个数;
substr(string, start [, length])
功能:取string字符串中的子串,从start开始,取length个;start从1开始计数;
system(command)
功能:执行系统command并将结果返回至awk命令
systime()
功能:取系统当前时间
tolower(s)
功能:将s中的所有字母转为小写
toupper(s)
功能:将s中的所有字母转为大写
十一、用户自定义函数
自定义函数使用function关键字。格式如下:
function F_NAME([variable])
{
statements
}
函数还可以使用return语句返回值,格式为“return value”。
awk处理机制,根据我们所定义的模式,一次从文件中读取一行文本,抽取出来以后,awk会相应的对其进行切片,将这每一行按照字符分隔符进行切割,默认可以使用空白字符当作分隔符,将它们逐个分开,而后每一个片段它们在awk内部可以使用一个变量来引用,这个变量完全类似于脚本的位置参数,$1...$n分别用于每一个切片,$0表示这一整行;
[root@localhost ~]# which awk(查看awk二进制程序路径)
/bin/awk
[root@localhost ~]# ls -l /bin/awk(查看awk文件详细信息)
lrwxrwxrwx 1 root root 4 Nov 22 2014 /bin/awk -> gawk
[root@localhost ~]# vim test.txt(编辑test.txt)
this is a test.
[root@localhost ~]# awk '{print $1}' test.txt(显示test.txt文件第一段内容)
this
[root@localhost ~]# awk '{print $0}' test.txt (显示test.txt文件整行内容)
this is a test.
[root@localhost ~]# awk '{print $4}' test.txt(显示test.txt文件第四段内容)
test.
[root@localhost ~]# awk '{print $1,$2}' test.txt(显示test.txt文件第一段和第二段内容)
this is
[root@localhost ~]# awk 'BEGIN{OFS="#"}{print $1,$2}' test.txt(显示test.txt第一段和第二段内容,输出的时候使用#井号作为分隔符)
this#is
[root@localhost ~]# awk 'BEGIN{OFS=":"}{print $1,$2,$3,$4}' test.txt(显示test.txt第一、第二、第三、第四段内容,输出时候使用:冒号作为分隔符)
this:is:a:test.
[root@localhost ~]# awk 'BEGIN{OFS=":"}{print $1,"hello",$2,$3,$4}' test.txt(显示test.txt文件第一段、hello、第二段、第三段、第四段内容,输出使用:
冒号分割)
this:hello:is:a:test.
[root@localhost ~]# awk '{print NF}' test.txt(显示test.txt文件当前处理的行有多少个字段)
4
[root@localhost ~]# awk '{print $NF}' test.txt(显示test.txt文件当前处理的行有多少字段,并且显示最后一个字段内容)
test.
[root@localhost ~]# awk '{print NR}' test.txt(显示当前处理test.txt文件处理了几行)
1
[root@localhost ~]# awk '{print NR}' test.txt health_check.sh(显示test.txt和health_check.sh文件总共处理几行)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
[root@localhost ~]# awk '{print FNR}' test.txt health_check.sh(显示test.txt和health_check.sh文件各自处理了几行)
1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
[root@localhost ~]# awk -v test="hello awk" 'BEGIN{print test}'(-v定义变量,显示test变量值)
hello awk
提示:在awk中打印变量值是不需要给变量加$符号的;
[root@localhost ~]# awk 'BEGIN{test="hello awk";print test}'(定义变量test,显示test变量)
hello awk
[root@localhost ~]# awk 'BEGIN{printf "%c","a"}'(显示a字符的ASCII码,printf不能自动换行)
a[root@localhost ~]#
[root@localhost ~]# awk 'BEGIN{printf "%c\n","a"}'(换行显示a字符的ASCII码)
a
[root@localhost ~]# awk '{printf "%c\n",$1}' test.txt(换行显示test.txt的第一段内容的ASCII码)
t
[root@localhost ~]# awk '{printf "%s\n",$1}' test.txt(换行显示test.txt的第一段内容的字符串类型)
this
[root@localhost ~]# awk '{printf "%10s\n",$1}' test.txt(换行显示test.txt的第一段内容10个字符串类型,默认右对齐)
this
[root@localhost ~]# awk '{printf "%-10s\n",$1}' test.txt(换行显示test.txt的第一段内容10个字符串类型,左对齐,后面有6个空白字符)
this
[root@localhost ~]# awk '{printf "%-10s,%-10s\n",$1,$3}' test.txt(换行显示test.txt第一段左对齐10个字符,显示第三段左对齐10个字符)
this ,a
[root@localhost ~]# awk '{printf "%-10s%-10s\n",$1,$3}' test.txt(换行显示test.txt第一段左对齐10个字符,显示第三段左对齐10个字符)
this a
[root@localhost ~]# awk -F: '{printf "%5d",$3}' /etc/passwd(显示passwd文件第三段右对齐5个字符,-F指定分隔符,)
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 99 28 69 77 38 81 70 32 47 51 74 29655
34 43 68 100 42 86 500 48[root@localhost ~]#
[root@localhost ~]# awk -F: '{printf "%5d\n",$3}' /etc/passwd(换行显示passwd文件第三段右对齐5个字符,-F指定分隔符)
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
99
28
69
77
38
81
70
32
47
51
74
29
65534
43
68
100
42
86
500
48
[root@localhost ~]# awk -F: '{printf "%-5d\n",$3}' /etc/passwd(换行显示passwd文件第三段左对齐5个字符,-F指定分隔符)
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
99
28
69
77
38
81
70
32
47
51
74
29
65534
43
68
100
42
86
500
48
[root@localhost ~]# awk -F: '/^r/{print $1}' /etc/passwd(显示passwd文件以r开头的第一段内容,-F指定分隔符)
root
rpc
rpcuser
[root@localhost ~]# awk -F: '$3>=500{print $1,$3}' /etc/passwd(显示passwd文件第一段和第三段并且第三段大于等于500,-F指定分隔符)
nfsnobody 65534
Smoke 500
[root@localhost ~]# awk -F: '$3+1>=500{print $1,$3}' /etc/passwd(显示passwd文件第一段和第三段并且第三段加1大于等于500,-F指定分割符)
nfsnobody 65534
Smoke 500
[root@localhost ~]# awk -F: '$7~"bash$"{print $1,$7}' /etc/passwd(显示passwd文件第一段和第七段并且第七段能够被bash匹配,-F指定分隔符)
root /bin/bash
Smoke /bin/bash
[root@localhost ~]# awk -F: '$7!~"bash$"{print $1,$7}' /etc/passwd(显示passwd文件第一段和第七段并且第七段不能被bash结尾匹配到,-F指定分隔符)
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
lp /sbin/nologin
sync /bin/sync
shutdown /sbin/shutdown
halt /sbin/halt
mail /sbin/nologin
news
uucp /sbin/nologin
operator /sbin/nologin
games /sbin/nologin
gopher /sbin/nologin
ftp /sbin/nologin
nobody /sbin/nologin
nscd /sbin/nologin
vcsa /sbin/nologin
pcap /sbin/nologin
ntp /sbin/nologin
dbus /sbin/nologin
avahi /sbin/nologin
rpc /sbin/nologin
mailnull /sbin/nologin
smmsp /sbin/nologin
sshd /sbin/nologin
rpcuser /sbin/nologin
nfsnobody /sbin/nologin
xfs /sbin/nologin
haldaemon /sbin/nologin
avahi-autoipd /sbin/nologin
gdm /sbin/nologin
sabayon /sbin/nologin
apache /sbin/nologin
[root@localhost ~]# awk -F: '/^r/,/^m/{print $1,$7}' /etc/passwd(显示passwd文件第一段和第七段,并且第一个以r开头的行和第一个以m开头的行,-F指定分隔符)
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
lp /sbin/nologin
sync /bin/sync
shutdown /sbin/shutdown
halt /sbin/halt
mail /sbin/nologin
rpc /sbin/nologin
mailnull /sbin/nologin
rpcuser /sbin/nologin
nfsnobody /sbin/nologin
xfs /sbin/nologin
haldaemon /sbin/nologin
avahi-autoipd /sbin/nologin
gdm /sbin/nologin
sabayon /sbin/nologin
Smoke /bin/bash
apache /sbin/nologin
[root@localhost ~]# awk -F: '$3==0,$7~"bash"{print $1,$3,$7}' /etc/passwd(显示/etc/passwd文件第一、第三、第七段,并且第一次能够被第三段等于0开始,第
七段能够被bash匹配的结束,-F指定分隔符)
root 0 /bin/bash
[root@localhost ~]# awk -F: '$3==0,$7~"nologin"{print $1,$3,$7}' /etc/passwd(显示/etc/passwd文件第一、第三、第七段,并且第一次能够被第三段等于0匹配开
始到第七段能够被nologin匹配结束,-F指定分隔符)
root 0 /bin/bash
bin 1 /sbin/nologin
[root@localhost ~]# cat /etc/passwd(查看/etc/passwd文件内容)
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
news:x:9:13:news:/etc/news:
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
gopher:x:13:30:gopher:/var/gopher:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
nscd:x:28:28:NSCD Daemon:/:/sbin/nologin
vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
pcap:x:77:77::/var/arpwatch:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
avahi:x:70:70:Avahi daemon:/:/sbin/nologin
rpc:x:32:32:Portmapper RPC user:/:/sbin/nologin
mailnull:x:47:47::/var/spool/mqueue:/sbin/nologin
smmsp:x:51:51::/var/spool/mqueue:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
xfs:x:43:43:X Font Server:/etc/X11/fs:/sbin/nologin
haldaemon:x:68:68:HAL daemon:/:/sbin/nologin
avahi-autoipd:x:100:101:avahi-autoipd:/var/lib/avahi-autoipd:/sbin/nologin
gdm:x:42:42::/var/gdm:/sbin/nologin
sabayon:x:86:86:Sabayon user:/home/sabayon:/sbin/nologin
Smoke:x:500:500:Smoke:/home/Smoke:/bin/bash
apache:x:48:48:Apache:/var/www:/sbin/nologin
[root@localhost ~]# awk -F: '$3==0,$7~"nologin"{print $1,$3,$7}' /etc/passwd(显示/etc/passwd文件第一、第三、第七段,并且第一次能够被第三段等于0匹配
开始到第七段能够被nologin匹配结束,-F指定分隔符)
root 0 /bin/bash
bin 1 /sbin/nologin
[root@localhost ~]# awk -F: '$3==0,$7~"nologin"{printf "%-10s%-10s%-20s\n",$1,$3,$7}' /etc/passwd(显示/etc/passwd文件第一段左对齐10个字符,显示
第三段左对齐10个字符,第七段左对齐20字符,并且第三段等于0开始到第七段为nologin结尾,-F指定分隔符)
root 0 /bin/bash
bin 1 /sbin/nologin
[root@localhost ~]# awk -F: 'BEGIN{print "Username ID Shell"}{printf "%-10s%-10s%-20s\n",$1,$3,$7}' /etc/passwd(在awk命令执行之前运行
一次显示Username ID Shell,显示passwd文件第一段左对齐10个字符,第三个字段左对齐10个字符,第七段字符左对齐120个字符,-F指定分隔符)
Username ID Shell
root 0 /bin/bash
bin 1 /sbin/nologin
daemon 2 /sbin/nologin
adm 3 /sbin/nologin
lp 4 /sbin/nologin
sync 5 /bin/sync
shutdown 6 /sbin/shutdown
halt 7 /sbin/halt
mail 8 /sbin/nologin
news 9
uucp 10 /sbin/nologin
operator 11 /sbin/nologin
games 12 /sbin/nologin
gopher 13 /sbin/nologin
ftp 14 /sbin/nologin
nobody 99 /sbin/nologin
nscd 28 /sbin/nologin
vcsa 69 /sbin/nologin
pcap 77 /sbin/nologin
ntp 38 /sbin/nologin
dbus 81 /sbin/nologin
avahi 70 /sbin/nologin
rpc 32 /sbin/nologin
mailnull 47 /sbin/nologin
smmsp 51 /sbin/nologin
sshd 74 /sbin/nologin
rpcuser 29 /sbin/nologin
nfsnobody 65534 /sbin/nologin
xfs 43 /sbin/nologin
haldaemon 68 /sbin/nologin
avahi-autoipd100 /sbin/nologin
gdm 42 /sbin/nologin
sabayon 86 /sbin/nologin
Smoke 500 /bin/bash
apache 48 /sbin/nologin
[root@localhost ~]# awk -F: 'BEGIN{print "Username ID Shell"}{printf "%-10s%-10s%-20s\n",$1,$3,$7}END{print "End of report."}' /etc
/passwd(在awk命令执行之前运行一次显示Username ID Shell,显示passwd文件第一段左对齐10个字符,第三段左对齐10个字符,在awk命令执行完打印End of report)
[root@localhost ~]# awk -F: '{printf "%-10s%-10s%-20s\n",$1,$3,$7}' /etc/passwd(显示passwd文件第一段左对齐10个字符,第三段左对齐10个字符,第七字段
左对齐20个字符,-F指定分隔符)
root 0 /bin/bash
bin 1 /sbin/nologin
daemon 2 /sbin/nologin
adm 3 /sbin/nologin
lp 4 /sbin/nologin
sync 5 /bin/sync
shutdown 6 /sbin/shutdown
halt 7 /sbin/halt
mail 8 /sbin/nologin
news 9
uucp 10 /sbin/nologin
operator 11 /sbin/nologin
games 12 /sbin/nologin
gopher 13 /sbin/nologin
ftp 14 /sbin/nologin
nobody 99 /sbin/nologin
nscd 28 /sbin/nologin
vcsa 69 /sbin/nologin
pcap 77 /sbin/nologin
ntp 38 /sbin/nologin
dbus 81 /sbin/nologin
avahi 70 /sbin/nologin
rpc 32 /sbin/nologin
mailnull 47 /sbin/nologin
smmsp 51 /sbin/nologin
sshd 74 /sbin/nologin
rpcuser 29 /sbin/nologin
nfsnobody 65534 /sbin/nologin
xfs 43 /sbin/nologin
haldaemon 68 /sbin/nologin
avahi-autoipd100 /sbin/nologin
gdm 42 /sbin/nologin
sabayon 86 /sbin/nologin
Smoke 500 /bin/bash
apache 48 /sbin/nologin
[root@localhost ~]# awk -F: '{if ($1=="root") print $1, "Admin"; else print $1, "Common User"}' /etc/passwd(判断第一段如果等于root就显示第一段
和Admin,否则显示第一段和Common User,-F指定分隔符)
root Admin
bin Common User
daemon Common User
adm Common User
lp Common User
sync Common User
shutdown Common User
halt Common User
mail Common User
news Common User
uucp Common User
operator Common User
games Common User
gopher Common User
ftp Common User
nobody Common User
nscd Common User
vcsa Common User
pcap Common User
ntp Common User
dbus Common User
avahi Common User
rpc Common User
mailnull Common User
smmsp Common User
sshd Common User
rpcuser Common User
nfsnobody Common User
xfs Common User
haldaemon Common User
avahi-autoipd Common User
gdm Common User
sabayon Common User
Smoke Common User
apache Common User
[root@localhost ~]# awk -F: '{if ($1=="root") printf "%-15s: %s\n", $1,"Admin"; else printf "%-15s: %s\n", $1, "Common User"}' /etc/passwd
(判断第一段是否等于root,如果等于就显示第一段左对齐15个字符:冒号Admin,否则就显示第一段左对齐15个字符:冒号COmmon User)
root : Admin
bin : Common User
daemon : Common User
adm : Common User
lp : Common User
sync : Common User
shutdown : Common User
halt : Common User
mail : Common User
news : Common User
uucp : Common User
operator : Common User
games : Common User
gopher : Common User
ftp : Common User
nobody : Common User
nscd : Common User
vcsa : Common User
pcap : Common User
ntp : Common User
dbus : Common User
avahi : Common User
rpc : Common User
mailnull : Common User
smmsp : Common User
sshd : Common User
rpcuser : Common User
nfsnobody : Common User
xfs : Common User
haldaemon : Common User
avahi-autoipd : Common User
gdm : Common User
sabayon : Common User
Smoke : Common User
apache : Common User
[root@localhost ~]# awk -F: -v sum=0 '{if ($3>=500) sum++}END{print sum}' /etc/passwd(声明变量sum=0,判断第三段大于等于500,sum自加1,awk命令执行
完成后显示sum值,-F指定分隔符,-v声明变量,uid大于等于500的用户有多少个)
2
[root@localhost ~]# cat /etc/passwd(查看passwd文件内容)
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
news:x:9:13:news:/etc/news:
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
gopher:x:13:30:gopher:/var/gopher:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
nscd:x:28:28:NSCD Daemon:/:/sbin/nologin
vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
pcap:x:77:77::/var/arpwatch:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
avahi:x:70:70:Avahi daemon:/:/sbin/nologin
rpc:x:32:32:Portmapper RPC user:/:/sbin/nologin
mailnull:x:47:47::/var/spool/mqueue:/sbin/nologin
smmsp:x:51:51::/var/spool/mqueue:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
xfs:x:43:43:X Font Server:/etc/X11/fs:/sbin/nologin
haldaemon:x:68:68:HAL daemon:/:/sbin/nologin
avahi-autoipd:x:100:101:avahi-autoipd:/var/lib/avahi-autoipd:/sbin/nologin
gdm:x:42:42::/var/gdm:/sbin/nologin
sabayon:x:86:86:Sabayon user:/home/sabayon:/sbin/nologin
Smoke:x:500:500:Smoke:/home/Smoke:/bin/bash
apache:x:48:48:Apache:/var/www:/sbin/nologin
[root@localhost ~]# awk -F: '{i=1;while (i<=NF) { if (length($i)>=4) {print $i}; i++ }}' /etc/passwd(i=1,while循环,i<=NF字段个数,判断字符长
度大于等于4,显示$i,每次循环i自加1,-F指定分隔符)
root
root
/root
/bin/bash
/bin
/sbin/nologin
daemon
daemon
/sbin
/sbin/nologin
/var/adm
/sbin/nologin
/var/spool/lpd
/sbin/nologin
sync
sync
/sbin
/bin/sync
shutdown
shutdown
/sbin
/sbin/shutdown
halt
halt
/sbin
/sbin/halt
mail
mail
/var/spool/mail
/sbin/nologin
news
news
/etc/news
uucp
uucp
/var/spool/uucp
/sbin/nologin
operator
operator
/root
/sbin/nologin
games
games
/usr/games
/sbin/nologin
gopher
gopher
/var/gopher
/sbin/nologin
FTP User
/var/ftp
/sbin/nologin
nobody
Nobody
/sbin/nologin
nscd
NSCD Daemon
/sbin/nologin
vcsa
virtual console memory owner
/dev
/sbin/nologin
pcap
/var/arpwatch
/sbin/nologin
/etc/ntp
/sbin/nologin
dbus
System message bus
/sbin/nologin
avahi
Avahi daemon
/sbin/nologin
Portmapper RPC user
/sbin/nologin
mailnull
/var/spool/mqueue
/sbin/nologin
smmsp
/var/spool/mqueue
/sbin/nologin
sshd
Privilege-separated SSH
/var/empty/sshd
/sbin/nologin
rpcuser
RPC Service User
/var/lib/nfs
/sbin/nologin
nfsnobody
65534
65534
Anonymous NFS User
/var/lib/nfs
/sbin/nologin
X Font Server
/etc/X11/fs
/sbin/nologin
haldaemon
HAL daemon
/sbin/nologin
avahi-autoipd
avahi-autoipd
/var/lib/avahi-autoipd
/sbin/nologin
/var/gdm
/sbin/nologin
sabayon
Sabayon user
/home/sabayon
/sbin/nologin
Smoke
Smoke
/home/Smoke
/bin/bash
apache
Apache
/var/www
/sbin/nologin
[root@localhost ~]# df -hP(显示磁盘使用情况,-h单位换算,-P使用POSIX格式显示)
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 20G 2.3G 17G 13% /
/dev/sda1 99M 12M 83M 13% /boot
tmpfs 506M 0 506M 0% /dev/shm
/dev/sr0 3.3G 3.3G 0 100% /media
[root@localhost ~]# awk -F: '{for(i=1;i<=NF;i++) { if (length($i)>=4) {print $i}}}' /etc/passwd(for循环,i=1,i小于等于字段个数,i自加1,判断字
段字符个数大于等于4,显示$i,-F指定分隔符)
root
root
/root
/bin/bash
/bin
/sbin/nologin
daemon
daemon
/sbin
/sbin/nologin
/var/adm
/sbin/nologin
/var/spool/lpd
/sbin/nologin
sync
sync
/sbin
/bin/sync
shutdown
shutdown
/sbin
/sbin/shutdown
halt
halt
/sbin
/sbin/halt
mail
mail
/var/spool/mail
/sbin/nologin
news
news
/etc/news
uucp
uucp
/var/spool/uucp
/sbin/nologin
operator
operator
/root
/sbin/nologin
games
games
/usr/games
/sbin/nologin
gopher
gopher
/var/gopher
/sbin/nologin
FTP User
/var/ftp
/sbin/nologin
nobody
Nobody
/sbin/nologin
nscd
NSCD Daemon
/sbin/nologin
vcsa
virtual console memory owner
/dev
/sbin/nologin
pcap
/var/arpwatch
/sbin/nologin
/etc/ntp
/sbin/nologin
dbus
System message bus
/sbin/nologin
avahi
Avahi daemon
/sbin/nologin
Portmapper RPC user
/sbin/nologin
mailnull
/var/spool/mqueue
/sbin/nologin
smmsp
/var/spool/mqueue
/sbin/nologin
sshd
Privilege-separated SSH
/var/empty/sshd
/sbin/nologin
rpcuser
RPC Service User
/var/lib/nfs
/sbin/nologin
nfsnobody
65534
65534
Anonymous NFS User
/var/lib/nfs
/sbin/nologin
X Font Server
/etc/X11/fs
/sbin/nologin
haldaemon
HAL daemon
/sbin/nologin
avahi-autoipd
avahi-autoipd
/var/lib/avahi-autoipd
/sbin/nologin
/var/gdm
/sbin/nologin
sabayon
Sabayon user
/home/sabayon
/sbin/nologin
Smoke
Smoke
/home/Smoke
/bin/bash
apache
Apache
/var/www
/sbin/nologin
[root@localhost ~]# awk -F: '{shell[$NF]++}END{for(A in shell) {print A,shell[A]}}' /etc/passwd(声明数组shell,$NF每行最后一个字段自加1,awk
语句结束后for循环,显示A和A的个数)
1
/bin/sync 1
/bin/bash 2
/sbin/nologin 29
/sbin/halt 1
/sbin/shutdown 1
[root@localhost ~]# netstat -tan(显示系统服务,-t代表tcp,-a显示所有连接套接字,-n以数字显示)
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 127.0.0.1:2208 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:852 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:6010 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:2207 0.0.0.0:* LISTEN
tcp 0 0 172.16.100.1:22 172.16.100.254:1071 ESTABLISHED
tcp 0 0 :::80 :::* LISTEN
tcp 0 0 :::22 :::* LISTEN
tcp 0 0 ::1:6010 :::* LISTEN
[root@localhost ~]# netstat -tan | awk '/^tcp/{STATE[$NF]++}END{for (S in STATE) {print S,STATE[S]}}'(显示系统服务,-t代表tcp,-a显示所有连
接套接字,-n以数字显示,将结果送给管道,行首以tcp开始,STATE数组,$NF每行最后一个字段,相同时自加1,END在awk语句结束后执行for循环,S为下标,STATE为数组,显示
S和相同值的下标的个数)
LISTEN 11
ESTABLISHED 1
[root@localhost ~]# cd /var/log/httpd/(切换到/var/log/httpd目录)
[root@localhost httpd]# tail access_log(查看access_log日志文件后10行)
172.16.100.254 - - [14/Mar/2016:16:32:06 +0800] "GET / HTTP/1.1" 304 - "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36"
172.16.100.254 - - [14/Mar/2016:16:32:06 +0800] "GET / HTTP/1.1" 304 - "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36"
172.16.100.254 - - [14/Mar/2016:16:32:06 +0800] "GET / HTTP/1.1" 304 - "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36"
172.16.100.254 - - [14/Mar/2016:16:32:07 +0800] "GET / HTTP/1.1" 304 - "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36"
172.16.100.254 - - [14/Mar/2016:16:32:07 +0800] "GET / HTTP/1.1" 304 - "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36"
172.16.100.254 - - [14/Mar/2016:16:32:07 +0800] "GET / HTTP/1.1" 304 - "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36"
172.16.100.254 - - [14/Mar/2016:16:32:07 +0800] "GET / HTTP/1.1" 304 - "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36"
172.16.100.254 - - [14/Mar/2016:16:32:07 +0800] "GET / HTTP/1.1" 304 - "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36"
172.16.100.254 - - [14/Mar/2016:16:32:07 +0800] "GET / HTTP/1.1" 304 - "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36"
172.16.100.254 - - [14/Mar/2016:16:32:08 +0800] "GET / HTTP/1.1" 304 - "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36"
[root@localhost httpd]# awk '{count[$1]++}END{for (ip in count) {printf "%-20s:%d\n",ip,count[ip]}}' access_log(显示每个ip地址访问多少次)
172.16.100.2 :925
127.0.0.1 :2
172.16.100.8 :15013
192.168.10.7 :1
::1 :4
192.168.10.9 :3
172.16.100.254 :62
浙公网安备 33010602011771号