CentOS7修改时区的正确姿势

CentOS7修改时区的正确姿势
今天在CentOS7上运行Java程序,发现程序生成的时间与当前时间匹配不上,还以为是数据停止更新了,后来发现没有正确使用修改时区的姿势,导致程序时区错误。
正确的修改CentOS7 时区的姿势:

ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
1
其他系统的修改文件可能是/var/etc/localtime.
———————
作者:yin138
来源:CSDN
原文:https://blog.csdn.net/yin138/article/details/52765089
版权声明:本文为博主原创文章,转载请附上博文链接!

LVS安装使用详解

LVS是Linux Virtual Server的简称,也就是Linux虚拟服务器, 是一个由章文嵩博士发起的自由软件项目,它的官方站点是www.linuxvirtualserver.org。

现在LVS已经是Linux标准内核的一部分,在Linux2.4内核以前,使用LVS时必须要重新编译内核以支持LVS功能模块,但是从Linux2.4内核以后,已经完全内置了LVS的各个功能模块,无需给内核打任何补丁,可以直接使用LVS提供的各种功能。

 

LVS主要用于服务器集群的负载均衡。其优点有:

复制代码
#工作在网络层,可以实现高性能,高可用的服务器集群技术。

#廉价,可把许多低性能的服务器组合在一起形成一个超级服务器。

#易用,配置非常简单,且有多种负载均衡的方法。

#稳定可靠,即使在集群的服务器中某台服务器无法正常工作,也不影响整体效果。

#可扩展性也非常好。
复制代码

 

安装配置

linux内核2.4版本以上的基本都支持LVS,要使用lvs,只需要再安装一个lvs的管理工具:ipvsadm

yum install ipvsadm

 

ipvsadm用法

其实LVS的本身跟iptables很相似,而且连命令的使用格式都很相似,其实LVS是根据iptables的框架开发的,那么LVS的本身分成了两个部分:

第一部分是工作在内核空间的一个IPVS的模块,其实LVS的功能都是IPVS模块实现的,

第二部分是工作在用户空间的一个用来定义集群服务的一个工具ipvsadm, 这个工具的主要作用是将管理员定义的集群服务列表传送给工作在内核空间中的IPVS模块,下面来简单的介绍下ipvsadm命令的用法

ipvsadm组件定义规则的格式:

 ipvsadm命令方法

 

LVS的10种调度算法

lvs调度算法(不区分大小写)可以分为两大类:

 lvs调度算法

 

 

 



LVS三种工作模式:NAT(地址转换)、DR(直接路由)、TUN(隧道)



 

LVS-NAT:地址转换

架构图:

 

 

 

工作方式:

NAT模型其实就是通过网络地址转换来实现负载均衡的。下面是它的流程:

复制代码
1.用户请求VIP(也可以说是CIP请求VIP)

2,Director Server 收到用户的请求后,发现源地址为CIP请求的目标地址为VIP,那么Director Server会认为用户请求的是一个集群服务,那么Director Server 会根据此前设定好的调度算法将用户请求负载给某台Real Server。
  假如说此时Director Server 根据调度的结果会将请求分摊到RealServer1上去,那么Director Server 会将用户的请求报文中的目标地址,从原来的VIP改为RealServer1的IP,然后再转发给RealServer1

3,此时RealServer1收到一个源地址为CIP目标地址为自己的请求,那么RealServer1处理好请求后会将一个源地址为自己目标地址为CIP的数据包通过Director Server 发出去,

4.当Driector Server收到一个源地址为RealServer1 的IP 目标地址为CIP的数据包,此时Driector Server 会将源地址修改为VIP,然后再将数据包发送给用户
复制代码

 

LVS-NAT的性能瓶颈:

在LVS/NAT的集群系统中,请求和响应的数据报文都需要通过负载调度器(Director),当真实服务器(RealServer)的数目在10台和20台之间时,负载调度器(Director)将成为整个集群系统的新瓶颈。

大多数Internet服务都有这样的特点:请求报文较短而响应报文往往包含大量的数据。如果能将请求和响应分开处理,即在负载调度器(Director)中只负责调度请求而响应直接(RealServer)返回给客户,将极大地提高整个集群系统的吞吐量。

 

部署

在RealServer上部署httpd服务并测试

 realserver部署

 

在Director上部署ipvs服务并测试
添加集群服务

 添加集群服务

 

测试访问http页面

 测试

 

更改LVS的调度算法并压力测试,查看结果

 lvs调度算法压力测试

 

永久保存LVS规则并恢复

 ipvsadm保存规则

模拟清空ipvsadm规则来恢复

 ipvsadm恢复规则

 

脚本

LVS-NAT服务控制脚本部署在Director上

 lvs-nat-director.sh

分享LVS-NAT一键安装脚本

 lvs-nat-install.sh

 

LVS-DR:直接路由

架构图:

 

 

工作方式:

上面说了NAT模型的实现方式,那么NAT模型有个缺陷,因为进出的每个数据包都要经过Director Server,当集群系统负载过大的时候Director Server将会成为整个集群系统的瓶颈,

那么DR模型就避免了这样的情况发生,DR模型在只有请求的时候才会经过Director Server, 回应的数据包由Real Server 直接响应用户不需要经过Director Server,其实三种模型中最常用的也就是DR模型了。

下面是它的工作流程:

复制代码
1, 首先用户用CIP请求VIP

2, 根据上图可以看到,不管是Director Server还是Real Server上都需要配置VIP,那么当用户请求到达我们的集群网络的前端路由器的时候,请求数据包的源地址为CIP目标地址为VIP,
   此时路由器会发广播问谁是VIP,那么我们集群中所有的节点都配置有VIP,此时谁先响应路由器那么路由器就会将用户请求发给谁,这样一来我们的集群系统是不是没有意义了,
   那我们可以在网关路由器上配置静态路由指定VIP就是Director Server,或者使用一种机制不让Real Server 接收来自网络中的ARP地址解析请求,这样一来用户的请求数据包都会经过Director Servrer

3,当Director Server收到用户的请求后根据此前设定好的调度算法结果来确定将请求负载到某台Real Server上去,假如说此时根据调度算法的结果,会将请求负载到RealServer 1上面去,
  此时Director Server 会将数据帧中的目标MAC地址修改为Real Server1的MAC地址,然后再将数据帧发送出去

4,当Real Server1 收到一个源地址为CIP目标地址为VIP的数据包时,Real Server1发现目标地址为VIP,而VIP是自己,于是接受数据包并给予处理,当Real Server1处理完请求后,
  会将一个源地址为VIP目标地址为CIP的数据包发出去,此时的响应请求就不会再经过Director Server了,而是直接响应给用户。
复制代码

 

编辑DR有三种方式(目的是让用户请求的数据都通过Director Server)

第一种方式:在路由器上明显说明vip对应的地址一定是Director上的MAC,只要绑定,以后再跟vip通信也不用再请求了,这个绑定是静态的,所以它也不会失效,也不会再次发起请求,但是有个前提,我们的路由设备必须有操作权限能够绑定MAC地址,万一这个路由器是运行商操作的,我们没法操作怎么办?第一种方式固然很简便,但未必可行。

 

第二种方式:在给别主机上(例如:红帽)它们引进的有一种程序arptables,它有点类似于iptables,它肯定是基于arp或基于MAC做访问控制的,很显然我们只需要在每一个real server上定义arptables规则,如果用户arp广播请求的目标地址是本机的vip则不予相应,或者说相应的报文不让出去,很显然网关(gateway)是接受不到的,也就是director相应的报文才能到达gateway,这个也行。第二种方式我们可以基于arptables。

 

第三种方式:在相对较新的版本中新增了两个内核参数(kernelparameter),第一个是arp_ignore定义接受到ARP请求时的相应级别;第二个是arp_announce定义将自己地址向外通告是的通告级别。【提示:很显然我们现在的系统一般在内核中都是支持这些参数的,我们用参数的方式进行调整更具有朴实性,它还不依赖于额外的条件,像arptables,也不依赖外在路由配置的设置,反而通常我们使用的是第三种配置】

arp_ignore:定义接受到ARP请求时的相应级别

复制代码
0:只要本地配置的有相应地址,就给予响应。

1:仅在请求的目标地址配置请求到达的接口上的时候,才给予响应(当别人的arp请求过来的时候,如果接收的设备上面没有这个ip,就不响应,默认是0,只要这台机器上面任何一个设备上面有这个ip,就响应arp请求,并发送MAC地址应答。)

2:只回答目标IP地址是来访网络接口本地地址的ARP查询请求,且来访IP必须在该网络接口的子网段内

3:不回应该网络界面的arp请求,而只对设置的唯一和连接地址做出回应

4-7:保留未使用

8:不回应所有(本地地址)的arp查询
复制代码

arp_announce:定义将自己地址向外通告是的通告级别;

0: 将本地任何接口上的任何地址向外通告

1:试图仅想目标网络通告与其网络匹配的地址

2:仅向与本地借口上地址匹配的网络进行通告

 

部署

在Real Server1 和Real Server2上做以下配置

复制代码
# 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 
#以上命令需填加到/etc/rc.local文件中让其开机自动生效 

# vim /etc/sysconfig/network-scripts/ifcfg-lo:0 内容如下 
DEVICE=lo:0  
IPADDR=172.16.100.100
NETMASK=255.255.255.255 
BROADCAST=172.16.100.100
ONBOOT=yes 
NAME=loopback  


# ifdown lo:0
# ifup lo:0 
# route add -host 172.16.100.100 dev lo:0
# echo "route add -host 172.16.100.100 dev lo:0" >> /etc/rc.local
复制代码

在Director Server上做以下配置

复制代码
# vim /etc/sysconfig/network-scripts/ifcfg-eth2:0 内容如下 
DEVICE=eth2:0 
IPADDR=172.16.100.100 
NETMASK=255.255.255.255 
BROADCAST=172.16.100.100 
ONBOOT=yes # ifdown eth2:0 

#命令
# ifup eth2:20 
# route add -host 172.16.100.100 dev eth2:0 
# echo "route add -host 172.16.100.100 dev eth2:0" >> /etc/rc.local 
# echo "1" > /proc/sys/net/ipv4/ip_forward 
# echo "echo "1" > /proc/sys/net/ipv4/ip_forward" >> /etc/rc.local 
# ipvsadm -A -t 172.16.100.100:80 -s wlc
# ipvsadm -a -t 172.16.100.100:80 -r 172.16.100.10 -g -w 2
# ipvsadm -a -t 172.16.100.100:80 -r 172.16.100.11 -g -w 1
复制代码

 

脚本

Director脚本

复制代码
#!/bin/bash
# 
# LVS script for VS/DR
# . /etc/rc.d/init.d/functions # VIP=172.16.100.100 
RIP1=172.16.100.10
RIP2=172.16.100.11
PORT=80 
 #
case "$1" in
start) 
  
  /sbin/ifconfig eth2:0 $VIP broadcast $VIP netmask 255.255.255.255 up
  /sbin/route add -host $VIP dev eth2: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
 # Reset iptables counters.
  /sbin/iptables -Z
 # Clear all ipvsadm rules/services.
  /sbin/ipvsadm -C
 # 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 1
  /sbin/ipvsadm -a -t $VIP:80 -r $RIP2 -g -w 2
  
  /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
 # Bring down the VIP interface
  /sbin/ifconfig eth2:0 down
  /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 ..."
  else
    echo "ipvs is running ..."
    ipvsadm -L -n
  fi
;; 
*) 
  echo "Usage: $0 {start|stop|status}"
;; esac

Director.sh
复制代码

RealServer脚本

复制代码
#!/bin/bash
# 
# Script to start LVS DR real server.
# description: LVS DR real server
# .  /etc/rc.d/init.d/functions
  
VIP=172.16.100.100
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
        /sbin/route add -host $VIP dev lo:0
  
;; 
stop) 
  
        # Stop LVS-DR real server loopback device(s).
        /sbin/ifconfig lo:0 down
        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`
        isrothere=`netstat -rn | grep "lo:0" | grep $VIP`
        if [ ! "$islothere" -o ! "isrothere" ];then
            # 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

RealServer.sh
复制代码

 

LVS-TUN:隧道

架构图:

 

工作方式:

TUN的工作机制跟DR一样,只不过在转发的时候,它需要重新包装IP报文。这里的real server(图中为RIP)离得都比较远。

用户请求以后,到director上的VIP上,它跟DR模型一样,每个realserver上既有RIP又有VIP,Director就挑选一个real server进行响应,但director和real server并不在同一个网络上,这时候就用到隧道了,Director进行转发的时候,一定要记得CIP和VIP不能动。

我们转发是这样的,让它的CIP和VIP不动,在它上面再加一个IP首部,再加的IP首部源地址是DIP,目标地址的RIP的IP地址。收到报文的RIP,拆掉报文以后发现了里面还有一个封装,它就知道了,这就是隧道。

 

其实数据转发原理和DR是一样的,不过这个我个人认为主要是位于不同位置(不同机房);LB是通过隧道进行了信息传输,虽然增加了负载,可是因为地理位置不同的优势,还是可以参考的一种方案;

优点:负载均衡器只负责将请求包分发给物理服务器,而物理服务器将应答包直接发给用户。所以,负载均衡器能处理很巨大的请求量,这种方式,一台负载均衡能为超过100台的物理服务器服务,负载均衡器不再是系统的瓶颈。
     使用VS-TUN方式,如果你的负载均衡器拥有100M的全双工网卡的话,就能使得整个Virtual Server能达到1G的吞吐量。

不足:但是,这种方式需要所有的服务器支持"IP Tunneling"(IP Encapsulation)协议;

 

LVS的健康状态检查

在LVS模型中,director不负责检查RS的健康状况,这就使得当有的RS出故障了,director还会将服务请求派发至此服务器,这种情况对用户、企业都是很不爽的,哪个用户倒霉说不定就遇到类似了。

为了让Director更人性化、可靠还要给director提供健康检查功能;如何实现?Director没有自带检查工具,只有手动编写脚本给director实现健康状态检查功能!

复制代码
#!/bin/bash
# VIP=172.16.100.100
CPORT=80 
FAIL_BACK=127.0.0.1
RS=("172.16.100.10" "172.16.100.11")
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
A++ 
Dir[0]=$A  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

check-lvs-health.sh
复制代码

LVS_DR模式构建配置

一、环境准备

lvs负载均衡器    系统:centos6.8 ip:192.168.2.203  vip:192.168.2.17

web服务器RS1   系统:centos6.8 ip:192.168.2.204

web服务器RS2   系统:centos6.8 ip:192.168.2.204

 

二、安装LVS软件

可以编译安装也可以yum安装,编译安装需要创建一个超链接:ln -s /usr/src/kernels/2.6.18-238.el5-i686 /usr/src/linux

这里选择yum方式安装

复制代码
[root@bogon ~]# yum -y install ipvsadm
已加载插件:fastestmirror
设置安装进程
Determining fastest mirrors
... ...
已安装:
  ipvsadm.x86_64 0:1.26-4.el6                                                                                          

作为依赖被安装:
  libnl.x86_64 0:1.1.4-2.el6                                                                                           

完毕!
复制代码

查看ipvs模块是否加载

[root@bogon ~]# lsmod | grep ip_vs
[root@bogon ~]#

因为此时系统还没有把ipvs模块加载进系统,需要我们执行ipvsadm命令才会加载进去或者modprobe ip_vs。

复制代码
[root@bogon ~]# ipvsadm
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
[root@bogon ~]# lsmod | grep ip_vs
ip_vs                 126897  0 
libcrc32c               1246  1 ip_vs
ipv6                  336282  270 ip_vs,ip6t_REJECT,nf_conntrack_ipv6,nf_defrag_ipv6
[root@bogon ~]#
复制代码

三、手动配置LVS负载均衡器

正常工作中是不会手动配置的,也不会使用脚本配置的。最终我们是通过配置文件生效的,结合keepalived来进行部署的。

[root@bogon ~]# ifconfig eth1:1 192.168.2.17 netmask 255.255.255.0
[root@bogon ~]# route add -host 192.168.2.17 dev eth1

ipvsadm命令参数:

复制代码
-A    
-A --add-service 添加一个带选项的虚拟服务。
Add  a virtual  service. A serviceaddress is uniquely defined by a triplet: IP address, portnumber,  and  protocol. Alternatively a virtualservice may be defined by a firewall-mark.
-t    指定虚拟服务器的IP地址和端口
-s    -s,--scheduler scheduling-method 调度算法
-p    会话保持按秒计算
-a    
-a在对应的VIP下添加RS节点
-g    指定此LVS的工作模式为-g   -g为DR模式
-l    
指定LVS的工作模式为-l  -l为tunnel模式
-m    指定LVS的工作模式为NAT模式
-w    指定RS节点的权重
-D    
删除虚拟服务
格式:ipvsadm-D -t|u|f service-address
Delete a virtual service, alongwith any associated real servers.
-C
-C, --clear  Clear the virtual server table清空lvs原有的配置。
-set    设置tcp  tcpfn udp  的连接超时时间(一般来说高并发的时候小一点点。
复制代码

ipvsadm添加lvs服务

复制代码
[root@bogon ~]# ipvsadm -C
[root@bogon ~]# ipvsadm -A -t 192.168.2.17:80 -s rr  #添加虚拟服务指定VIP
[root@bogon ~]# 
[root@bogon ~]# ipvsadm -a -t 192.168.2.17:80 -r 192.168.2.204:80 -g  #针对虚拟服务添加RS节点
[root@bogon ~]# ipvsadm -a -t 192.168.2.17:80 -r 192.168.2.205:80 -g
[root@bogon ~]# ipvsadm -L -n  #查看VIP和RS是否已经配置成功
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.2.17:80 rr
  -> 192.168.2.204:80             Route   1      0          0         
  -> 192.168.2.205:80             Route   1      0          0
复制代码

LB上删除虚拟服务

ipvsadm -D -t 192.168.2.17:80

四、RS节点服务器手动配置

添加lo端口的VIP&路由

[root@bogon ~]# ifconfig lo:0 192.168.2.17 netmask 255.255.255.255  (由于RS的VIP不是用来通讯,并且这里一定要设置24位掩码)
[root@bogon ~]# route add -host 192.168.2.17 dev lo

ARP抑制

[root@bogon ~]# echo "1" > /proc/sys/net/ipv4/conf/lo/arp_ignore 
[root@bogon ~]# echo "2" > /proc/sys/net/ipv4/conf/lo/arp_announce 
[root@bogon ~]# echo "1" > /proc/sys/net/ipv4/conf/all/arp_announce 
[root@bogon ~]# echo "2" > /proc/sys/net/ipv4/conf/all/arp_ignore

五、测试LVS是否生效

复制代码
[root@www ~]# curl http://192.168.2.204/test.txt
it is web1
[root@www ~]# curl http://192.168.2.205/test.txt
it is web2
[root@www ~]# curl http://192.168.2.17/test.txt
it is web2
[root@www ~]# curl http://192.168.2.17/test.txt
it is web1
[root@www ~]# curl http://192.168.2.17/test.txt
it is web2
[root@www ~]# curl http://192.168.2.17/test.txt
it is web1
[root@www ~]#
复制代码

 

至此我们的LVS DR模式负载均衡已经配置完成了。至于不同的调度算法啊-s  不同的工作模式-g(DR) -l(TUNNEL) -m(NAT)服务器端基本上没有什么差别。只是在客户端上有一定的差别。

NAT模式:

客户端同样需要配置VIP,进行ARP抑制,并且要服务器端开启内核转发功能,配置LB的DIP(内网IP地址)作为默认网关。

开启内核转发功能:vi /etc/sysctl  net.ipv4.ip_forword = 1

route add default gw  192.168.2.203

Tunnel模式:

客户端需要先开启Tunnel协议支持。

/sbin/modprobe ipip

/sbin/route add –host 192.168.2.17 devtun1

echo”1”>/proc/sys/net/ipv4/conf/tun1/arp-ignore

echo”2”>/proc/sys/net/ipv4/conf/tun1/arp_announce

echo”0” >/proc/sys/net/ipv4/conf/tun1/rp_filter

echo”1” >/proc/sys/net/ipv4/conf/tun1/forwarding

echo”1” >/proc/sys/net/ipv4/conf/all/arp_ignore

echo”2” >/proc/sys/net/ipv4/conf/all/ arp_announce

 

六、部署成功后的另一些问题

1)当我们的RS节点出现问题,LB如何知道。如果不知道是会把会话连接接续转发到RS上面。

2)如果LB出现故障,那么整个网络就出现故障。

针对上面的1问题,我们就需要一种RS节点健康检查机制。定时的去检测RS是否正常,如果出现不正常那么就把这个RS从VIP服务里面删除掉。如果恢复正常了,就再把RS添加进来。针对2问题,我们可以另外再架设一台LB服务器,作为备LB服务器。那么当主LB出现故障,备LB服务器就会启动接管主LB服务器的工作,接管它的资源(IP地址,在网络中的角色身份等)

而上面提到的这些我们就需要结合keepalived来完成。所以后续我们开始讲keepalived+lvs结合适用。完成RS节点健康检查和LVS的高可用性功能。

 

LVS负载均衡DR模式部署

LVS负载均衡DR模式部署

目录:

1. 拓扑图

2. 搭建环境

3. LVS服务器部署

4. 测试

 

1. 拓扑图

    LVS-DR模式采的IP地址全部为外网IP。
   本例中IP的设置全部采用临时设置IP的方式,重启后会失效。
   用户请求VIP,会由LVS服务器响应,分配至Real-Server服务器,真实服务器处理完后直接返回给用户,不再通过LVS服务器。

 

2. 搭建环境 (系统为 Centon 6.4 )

(1)、LVS-server  IP:192.168.36.101
(2)、Real-Server1 IP: 192.168.36.102 安装web服务器 准备测试站点内容
(3)、Real-Server2 IP: 192.168.36.103 安装web服务器 准备测试站点内容
测试机:xp/window7/8都可以,只要能ping通 192.168.36.*

3. LVS服务器部署

(1)、LVS-server配置
a. VIP设置:
[root@localhost ~]# ifconfig eth0:0 192.168.36.100 netmask 255.255.255.255
[root@localhost ~]# route add -host 192.168.36.100 dev eth0:0
b.安装Ipvsadm
[root@localhost ~]# yum -y install ipvsadm*
c.lvs配置:
[root@localhost ~]# ipvsadm -C
[root@localhost ~]# ipvsadm -At 192.168.36.100:80 -s rr
[root@localhost ~]# ipvsadm -at 192.168.36.100:80 -r 192.168.36.102:80 -g
[root@localhost ~]# ipvsadm -at 192.168.36.100:80 -r 192.168.36.103:80 -g
[root@localhost ~]# ipvsadm -L -n
(2)、Real-Server1配置
[root@localhost ~]# ifconfig lo:0 192.168.36.100 netmask 255.255.255.255
[root@localhost ~]# route add -host 192.168.36.100 dev lo:0
[root@localhost ~]# echo “1” > /proc/sys/net/ipv4/conf/lo/arp_ignore
[root@localhost ~]# echo “2” > /proc/sys/net/ipv4/conf/lo/arp_announce
[root@localhost ~]# echo “1” > /proc/sys/net/ipv4/conf/all/arp_ignore
[root@localhost ~]# echo “2” > /proc/sys/net/ipv4/conf/all/arp_announce
(3)、Real-Server2配置
同Real-Server1相同。

4.测试

现在通过测试机,直接访问 LVS VIP http://192.168.36.100 正常的话即可访问到准备的测试站点.
配置LVS采用的是轮循模式。第一次是访问Real-Server1,刷新后是访问Real-Server2,再刷新后访问Real-Server1

修改Exchange最大并发连接数

Exchange并发连接数默认都很小,入站并发数 和 出站并发数 默认都为20;对于一般企业而言,20个并发连接数足够用了,但是对于邮件较多的企业,可能同时接收/发送的邮件数量远远超过20,如果超过,Exchange就会返回错误信息,说是最大并发连接数已超过限制,如下:

421 4.3.2 The maximum number of concurrent connections has exceeded a limit, closing transmission channel

解决办法(以Exchange 2010为例):
通过Exchange的Shell命令和EMC管理控制台修改最大并发连接数。

修改入站最大并发连接数:

1、在服务器上运行Exchange Shell命令管理界面EMS
查看当前所有接收连接器的最大并发连接数:

[PS] C:\Windows\system32>get-receiveconnector * | ft Name,MaxInboundconnectionPersource

Name                                                        MaxInboundConnectionPerSource
----                                                        -----------------------------
Default EXCHANGE2010                                        20
Client EXCHANGE2010                                         20

2、修改默认接收连接器“Default EXCHANGE2010”的最大并发连接数为500:

[PS] C:\Windows\system32>Set-receiveconnector -identity "Default EXCHANGE2010" -MaxInboundconnectionPersource 500

3、再次查看默认接收连接器“Default EXCHANGE2010”的最大并发连接数

[PS] C:\Windows\system32>get-receiveconnector * | ft Name,MaxInboundconnectionPersource

Name                                                        MaxInboundConnectionPerSource
----                                                        -----------------------------
Default EXCHANGE2010                                        500
Client EXCHANGE2010                                         20

4
修改出站最大并发连接数:

1、打开Exchange管理控制台EMC,依次打开“服务器配置”–“集线器传输”,在右侧服务器上单击右键,点击“属性”
2
2、在“限制”–“连接限制”选项下,修改默认 最大并发出站连接数 即可
3

WINDOWS操作系统中可以允许最大的线程数

WINDOWS操作系统中可以允许最大的线程数

默认情况下,一个线程的栈要预留1M的内存空间
而一个进程中可用的内存空间只有2G,所以理论上一个进程中最多可以开2048个线程
但是内存当然不可能完全拿来作线程的栈,所以实际数目要比这个值要小。
你也可以通过连接时修改默认栈大小,将其改的比较小,这样就可以多开一些线程。
如将默认栈的大小改成512K,这样理论上最多就可以开4096个线程。

即使物理内存再大,一个进程中可以起的线程总要受到2GB这个内存空间的限制。
比方说你的机器装了64GB物理内存,但每个进程的内存空间还是4GB,其中用户态可用的还是2GB。

如果是同一台机器内的话,能起多少线程也是受内存限制的。每个线程对象都要站用非页面内存,而非页面内存也是有限的,当非页面内存被耗尽时,也就无法创建线程了。

如果物理内存非常大,同一台机器内可以跑的线程数目的限制值会越来越大。

在Windows下写个程序,一个进程Fork出2000个左右线程就会异常退出了,为什么?

这个问题的产生是因为windows32位系统,一个进程所能使用的最大虚拟内存为2G,而一个线程的默认线程栈StackSize为1024K(1M),这样当线程数量逼近2000时,2000*1024K=2G(大约),内存资源就相当于耗尽。

 

MSDN原文:

“The number of threads a process can create is limited by the available virtual memory. By default, every thread has one megabyte of stack space. Therefore, you can create at most 2,028 threads. If you reduce the default stack size, you can create more threads. However, your application will have better performance if you create one thread per processor and build queues of requests for which the application maintains the context information. A thread would process all requests in a queue before processing requests in the next queue.”

 

如何突破2000个限制?

可以通过修改CreateThread参数来缩小线程栈StackSize,例如

#define   MAX_THREADS   50000

DWORD   WINAPI   ThreadProc(   LPVOID   lpParam   ){
while(1){
Sleep(100000);
}
return   0;
}

int   main()   {
DWORD   dwThreadId[MAX_THREADS];
HANDLE   hThread[MAX_THREADS];

for(int   i   =   0;   i   <   MAX_THREADS;   ++i)
{
hThread[i]  = CreateThread(0,  64, ThreadProc, 0, STACK_SIZE_PARAM_IS_A_RESERVATION,   &dwThreadId[i]);

if(0   ==   hThread[i])
{
DWORD   e   =   GetLastError();
printf("%d\r\n",e);
break;
}
}
ThreadProc(0);
}

 

服务器端程序设计

如果你的服务器端程序设计成:来一个client连接请求则创建一个线程,那么就会存在2000个限制(在硬件内存和CPU个数一定的情况下)。建议如下:

The “one thread per client” model is well-known not to scale beyond a dozen clients or so. If you’re going to be handling more than that many clients simultaneously, you should move to a model where instead of dedicating a thread to a client, you instead allocate an object. (Someday I’ll muse on the duality between threads and objects.) Windows provides I/O completion ports and a thread pool to help you convert from a thread-based model to a work-item-based model.

1. Serve many clients with each thread, and use nonblocking I/O and level-triggeredreadiness notification
2. Serve many clients with each thread, and use nonblocking I/O and readiness changenotification
3. Serve many clients with each server thread, and use asynchronous I/O

 

Pushing the Limits of Windows: Processes and Threads


This is the fourth post in my Pushing the Limits of Windows series that explores the boundaries of fundamental resources in Windows. This time, I’m going to discuss the limits on the maximum number of threads and processes supported on Windows. I’ll briefly describe the difference between a thread and a process, survey thread limits and then investigate process limits. I cover thread limits first since every active process has at least one thread (a process that’s terminated, but is kept referenced by a handle owned by another process won’t have any), so the limit on processes is directly affected by the caps that limit threads.

Unlike some UNIX variants, most resources in Windows have no fixed upper bound compiled into the operating system, but rather derive their limits based on basic operating system resources that I’ve already covered. Process and threads, for example, require physical memory, virtual memory, and pool memory, so the number of processes or threads that can be created on a given Windows system is ultimately determined by one of these resources, depending on the way that the processes or threads are created and which constraint is hit first. I therefore recommend that you read the preceding posts if you haven’t, because I’ll be referring to reserved memory, committed memory, the system commit limit and other concepts I’ve covered. Here’s the index of the entire Pushing the Limits series. While they can stand on their own, they assume that you read them in order.

Pushing the Limits of Windows: Physical Memory

Pushing the Limits of Windows: Virtual Memory

Pushing the Limits of Windows: Paged and Nonpaged Pool

Pushing the Limits of Windows: Processes and Threads

Pushing the Limits of Windows: Handles

Pushing the Limits of Windows: USER and GDI Objects – Part 1

Pushing the Limits of Windows: USER and GDI Objects – Part 2

Processes and Threads

A Windows process is essentially container that hosts the execution of an executable image file. It is represented with a kernel process object and Windows uses the process object and its associated data structures to store and track information about the image’s execution. For example, a process has a virtual address space that holds the process’s private and shared data and into which the executable image and its associated DLLs are mapped. Windows records the process’s use of resources for accounting and query by diagnostic tools and it registers the process’s references to operating system objects in the process’s handle table. Processes operate with a security context, called a token, that identifies the user account, account groups, and privileges assigned to the process.

Finally, a process includes one or more threads that actually execute the code in the process (technically, processes don’t run, threads do) and that are represented with kernel thread objects. There are several reasons applications create threads in addition to their default initial thread: processes with a user interface typically create threads to execute work so that the main thread remains responsive to user input and windowing commands; applications that want to take advantage of multiple processors for scalability or that want to continue executing while threads are tied up waiting for synchronous I/O operations to complete also benefit from multiple threads.

Thread Limits

Besides basic information about a thread, including its CPU register state, scheduling priority, and resource usage accounting, every thread has a portion of the process address space assigned to it, called a stack, which the thread can use as scratch storage as it executes program code to pass function parameters, maintain local variables, and save function return addresses. So that the system’s virtual memory isn’t unnecessarily wasted, only part of the stack is initially allocated, or committed and the rest is simply reserved. Because stacks grow downward in memory, the system places guard pages beyond the committed part of the stack that trigger an automatic commitment of additional memory (called a stack expansion) when accessed. This figure shows how a stack’s committed region grows down and the guard page moves when the stack expands, with a 32-bit address space as an example (not drawn to scale):

image

The Portable Executable (PE) structures of the executable image specify the amount of address space reserved and initially committed for a thread’s stack. The linker defaults to a reserve of 1MB and commit of one page (4K), but developers can override these values either by changing the PE values when they link their program or for an individual thread in a call to CreateThread. You can use a tool like Dumpbinthat comes with Visual Studio to look at the settings for an executable. Here’s the Dumpbin output with the /headers option for the executable generated by a new Visual Studio project:

image

Converting the numbers from hexadecimal, you can see the stack reserve size is 1MB and the initial commit is 4K and using the new Sysinternals VMMap tool to attach to this process and view its address space, you can clearly see a thread stack’s initial committed page, a guard page, and the rest of the reserved stack memory:

image

Because each thread consumes part of a process’s address space, processes have a basic limit on the number of threads they can create that’s imposed by the size of their address space divided by the thread stack size.

32-bit Thread Limits

Even if the thread had no code or data and the entire address space could be used for stacks, a 32-bit process with the default 2GB address space could create at most 2,048 threads. Here’s the output of the Testlimit tool running on 32-bit Windows with the –t switch (create threads) confirming that limit:

image

Again, since part of the address space was already used by the code and initial heap, not all of the 2GB was available for thread stacks, thus the total threads created could not quite reach the theoretical limit of 2,048.

I linked the Testlimit executable with the large address space-aware option, meaning that if it’s presented with more than 2GB of address space (for example on 32-bit systems booted with the /3GB or /USERVA Boot.ini option or its equivalent BCD option on Vista and laterincreaseuserva), it will use it. 32-bit processes are given 4GB of address space when they run on 64-bit Windows, so how many threads can the 32-bit Testlimit create when run on 64-bit Windows? Based on what we’ve covered so far, the answer should be roughly 4096 (4GB divided by 1MB), but the number is actually significantly smaller. Here’s 32-bit Testlimit running on 64-bit Windows XP:

image

The reason for the discrepancy comes from the fact that when you run a 32-bit application on 64-bit Windows, it is actually a 64-bit process that executes 64-bit code on behalf of the 32-bit threads, and therefore there is a 64-bit thread stack and a 32-bit thread stack area reserved for each thread. The 64-bit stack has a reserve of 256K (except that on systems prior to Vista, the initial thread’s 64-bit stack is 1MB). Because every 32-bit thread begins its life in 64-bit mode and the stack space it uses when starting exceeds a page, you’ll typically see at least 16KB of the 64-bit stack committed. Here’s an example of a 32-bit thread’s 64-bit and 32-bit stacks (the one labeled “Wow64” is the 32-bit stack):

image

32-bit Testlimit was able to create 3,204 threads on 64-bit Windows, which given that each thread uses 1MB+256K of address space for stack (again, except the first on versions of Windows prior to Vista, which uses 1MB+1MB), is exactly what you’d expect. I got different results when I ran 32-bit Testlimit on 64-bit Windows 7, however:

image

The difference between the Windows XP result and the Windows 7 result is caused by the more random nature of address space layout introduced in Windows Vista, Address Space Load Randomization (ASLR), that leads to some fragmentation. Randomization of DLL loading, thread stack and heap placement, helps defend against malware code injection. As you can see from this VMMap output, there’s 357MB of address space still available, but the largest free block is only 128K in size, which is smaller than the 1MB required for a 32-bit stack:

image

As I mentioned, a developer can override the default stack reserve. One reason to do so is to avoid wasting address space when a thread’s stack usage will always be significantly less than the default 1MB. Testlimit sets the default stack reservation in its PE image to 64K and when you include the –n switch along with the –t switch, Testlimit creates threads with 64K stacks.  Here’s the output on a 32-bit Windows XP system with 256MB RAM (I did this experiment on a small system to highlight this particular limit):

image

Note the different error, which implies that address space isn’t the issue here. In fact, 64K stacks should allow for around 32,000 threads (2GB/64K = 32,768). What’s the limit that’s being hit in this case? A look at the likely candidates, including commit and pool, don’t give any clues, as they’re all below their limits:

image

It’s only a look at additional memory information in the kernel debugger that reveals the threshold that’s being hit, resident available memory, which has been exhausted:

image

Resident available memory is the physical memory that can be assigned to data or code that must be kept in RAM. Nonpaged pool and nonpaged drivers count against it, for example, as does memory that’s locked in RAM for device I/O operations. Every thread has both a user-mode stack, which is what I’ve been talking about, but they also have a kernel-mode stack that’s used when they run in kernel mode, for example while executing system calls. When a thread is active its kernel stack is locked in memory so that the thread can execute code in the kernel that can’t page fault.

A basic kernel stack is 12K on 32-bit Windows and 24K on 64-bit Windows. 14,225 threads require about 170MB of resident available memory, which corresponds to exactly how much is free on this system when Testlimit isn’t running:

image

Once the resident available memory limit is hit, many basic operations begin failing. For example, here’s the error I got when I double-clicked on the desktop’s Internet Explorer shortcut:

image

As expected, when run on 64-bit Windows with 256MB of RAM, Testlimit is only able to create 6,600 threads – roughly half what it created on 32-bit Windows with 256MB RAM – before running out of resident available memory:

image

The reason I said “basic” kernel stack earlier is that a thread that executes graphics or windowing functions gets a “large” stack when it executes the first call that’s 20K on 32-bit Windows and 48K on 64-bit Windows. Testlimit’s threads don’t call any such APIs, so they have basic kernel stacks.

64-bit Thread Limits

Like 32-bit threads, 64-bit threads also have a default of 1MB reserved for stack, but 64-bit processes have a much larger user-mode address space (8TB), so address space shouldn’t be an issue when it comes to creating large numbers of threads. Resident available memory is obviously still a potential limiter, though. The 64-bit version of Testlimit (Testlimit64.exe) was able to create around 6,600 threads with and without the –n switch on the 256MB 64-bit Windows XP system, the same number that the 32-bit version created, because it also hit the resident available memory limit. However, on a system with 2GB of RAM, Testlimit64 was able to create only 55,000 threads, far below the number it should have been able to if resident available memory was the limiter (2GB/24K = 89,000):

image

In this case, it’s the initial thread stack commit that causes the system to run out of virtual memory and the “paging file is too small” error. Once the commit level reached the size of RAM, the rate of thread creation slowed to a crawl because the system started thrashing, paging out stacks of threads created earlier to make room for the stacks of new threads, and the paging file had to expand. The results are the same when the –n switch is specified, because the threads have the same initial stack commitment.

Process Limits

The number of processes that Windows supports obviously must be less than the number of threads, since each process has one thread and a process itself causes additional resource usage. 32-bit Testlimit running on a 2GB 64-bit Windows XP system created about 8,400 processes:

image

A look in the kernel debugger shows that it hit the resident available memory limit:

image

If the only cost of a process with respect to resident available memory was the kernel-mode thread stack, Testlimit would have been able to create far more than 8,400 threads on a 2GB system. The amount of resident available memory on this system when Testlimit isn’t running is 1.9GB:

image

Dividing the amount of resident memory Testlimit used (1.9GB) by the number of processes it created (8,400) yields 230K of resident memory per process. Since a 64-bit kernel stack is 24K, that leaves about 206K unaccounted for. Where’s the rest of the cost coming from? When a process is created, Windows reserves enough physical memory to accommodate the process’s minimum working set size. This acts as a guarantee to the process that no matter what, there will enough physical memory available to hold enough data to satisfy its minimum working set. The default working set size happens to be 200KB, a fact that’s evident when you add the Minimum Working Set column toProcess Explorer’s display:

image

The remaining roughly 6K is resident available memory charged for additional non-pageable memory allocated to represent a process. A process on 32-bit Windows will use slightly less resident memory because its kernel-mode thread stack is smaller.

As they can for user-mode thread stacks, processes can override their default working set size with the SetProcessWorkingSetSize function. Testlimit supports a –n switch, that when combined with –p, causes child processes of the main Testlimit process to set their working set to the minimum possible, which is 80K. Because the child processes must run to shrink their working sets, Testlimit sleeps after it can’t create any more processes and then tries again to give its children a chance to execute. Testlimit executed with the –n switch on a Windows 7 system with 4GB of RAM hit a limit other than resident available memory: the system commit limit:

image

Here you can see the kernel debugger reporting not only that the system commit limit had been hit, but that there have been thousands of memory allocation failures, both virtual and paged pool allocations, following the exhaustion of the commit limit (the system commit limit was actually hit several times as the paging file was filled and then grown to raise the limit):

image

The baseline commitment before Testlimit ran was about 1.5GB, so the threads had consumed about 8GB of committed memory. Each process therefore consumed roughly 8GB/6,600, or 1.2MB. The output of the kernel debugger’s !vm command, which shows the private memory allocated by each active process, confirms that calculation:

image

The initial thread stack commitment, described earlier, has a negligible impact with the rest coming from the memory required for the process address space data structures, page table entries, the handle table, process and thread objects, and private data the process creates when it initializes.

How Many Threads and Processes are Enough?

So the answer to the questions, “how many threads does Windows support?” and “how many processes can you run concurrently on Windows?” depends. In addition to the nuances of the way that the threads specify their stack sizes and processes specify their minimum working sets, the two major factors that determine the answer on any particular system include the amount of physical memory and the system commit limit. In any case, applications that create enough threads or processes to get anywhere near these limits should rethink their design, as there are almost always alternate ways to accomplish the same goals with a reasonable number. For instance, the general goal for a scalable application is to keep the number of threads running equal to the number of CPUs (with NUMA changing this to consider CPUs per node) and one way to achieve that is to switch from using synchronous I/O to using asynchronous I/O and rely on I/O completion ports to help match the number of running threads to the number of CPUs.

 

Win 7, Server 2008 R2最大线程数限制

 

 

 

最近在做压力测试时发现Win 7 和 Server 2008 R2 系统内线程数设为1500则无法创建线程池,深入分析发现32位和64位程序存在很大性能差异。

 

最大线程数:

32bit:1450

64bit:100000

测试代码如下:

[cpp] view plain copy

  1. #include “stdafx.h”  
  2. #include <stdio.h>  
  3. #include <windows.h>  
  4. DWORD CALLBACK ThreadProc(void*)  
  5. {
  6.     Sleep(INFINITE);
  7.     return 0;  
  8. }
  9. int __cdecl main(int argc, const char* argv[])  
  10. {
  11.     int i;  
  12.     for (i = 0; i < 100000; i++)   
  13.     {
  14.         DWORD id;  
  15.         HANDLE h = CreateThread(NULL,4096, ThreadProc, NULL, STACK_SIZE_PARAM_IS_A_RESERVATION, &id);  
  16.         if (!h)  
  17.             break;  
  18.         CloseHandle(h);
  19.         printf(“%d\n”, i);  
  20.     }
  21.     // default 1413 [3/18/2012 WangJinhui]  
  22.     printf(“Created %d threads\n”, i); return 0;  
  23. }

IIS 之 连接数、并发连接数、最大并发工作线程数、队列长度、最大工作进程数

IIS 之 连接数、并发连接数、最大并发工作线程数、队列长度、最大工作进程数

一、IIS连接数

一般购买过虚拟主机的朋友都熟悉购买时,会限制IIS连接数,顾名思义即为IIS服务器可以同时容纳客户请求的最高连接数,准确的说应该叫“IIS限制连接数”。

  客户请求的连接内容包括:

[1] 网站html请求,html中的图片资源,html中的脚本资源,其他需要连接下载的资源等等,任何一个资源的请求即一次连接(虽然有的资源请求连接响应很快)

[2] 如果网页采用框架(框架内部嵌套网页请求),那么一个框架即一次连接

[3] 如果网页弹出窗口(窗口内部嵌套网页请求),那么一个窗口一个连接

很多人对连接数的概念认识都很模糊,现介绍如下:
[1] 浏览者访问站点,必需与站点通过TCP协议,建立连接。这个连接在从服务器上读取信息时存在,读取结束时,一般即自动关闭。所以,当一个页面已经完全地显示在客户端的显示器上时,使用的连接也许已经关闭了。
[2] 每个浏览者,访问某站点时,可能会占用1-3多个连接,这是由计算机自动处理的,这样做的目的是为了加快速度。所以,对于连接数为30的基础型主机而言,有时只能十几个人访问。
[3] 虽然服务器中可以规定每个站点的最大连接数,但同时也存在服务器的总计最大连接数。所以,即使规定用户站点的最大连接数为不限,当服务器达到了最大连接数时,仍不能访问站点。而服务器的最大连接数一般在1000—2000。
注意:
[1] 这就是为什么服务商敢于开出不限连接数的主机,本质上不是无限连接数的。
[2] 西部数码提供的主机,允许连接数均较高,一般可以满足用户需求。

在IIS(6.2版及以上版本)中  “点击网站”->“右击切换到功能视图”->“点击界面右侧的 ‘限制…’ 链接”->“编辑网站限制”

限制连接数(N)即为虚拟主机供应公开的IIS连接数标准,如果购买的IIS连接数为50,那么我们不得不考虑网站的内容框架和访问量。

如果网站图片够多,弹窗窗口随意(可能连时间选择框、简单条件筛选框也用弹出新窗口),加上不得已的打开新页面浏览内容,那么仅仅能容忍10个人同时操作也很正常,我不会把这个操作描述为很多网站说的“10同时在线”,这很容易让人误解,在用户的一次请求(表面上可能是刷新一次网页,实际上内部请求不止一次,事实上很少只有一次)都完成得到服务器响应完毕之后,连接全部会被释放,当然在你看到展示的页面之前,内部嵌套如果有请求图片等连接请求,连接会早早的被释放。

事实上,很多企业门户网站访问量低的惊人,IIS连接数为50也是绰绰有余了。

二、IIS最大并发连接数

“管理网站” → “高级设置…” → “限制” → “最大并发连接数”

其实,普通用户常说的“IIS连接数”就是这边的“最大并发连接数”,如果PC端有IIS的朋友,可以测试上述“限制连接数”和“最大并发连接数”的设置,是相互影响的。“最大并发连接数”默认为:4294967295,这是一个很惊人的数字,难道这代表着网站能具有并发执行连接数为4294967295的能力?

  这边做两个假设:

1、很多虚拟主机供应商所说的无并发连接数限制真的成立吗?

2、每个连接的处理,IIS都会开启一个线程去处理,假设这个处理方式成立,那么4294967295个并发连接请求来了是否IIS会立即启动4294967295个线程去处理?

  对于假设1:很显然不成立,最大并发连接数的设置绝对有上限;

  对于假设2:这是很多朋友的误区,假设4294967295并发连接同时来了,IIS不会立即启动4294967295个线程去处理,因为这不现实,对于处理连接,IIS是有“最大并发工作线程数”限制的。从一些资料上查阅到,该数字跟操作系统相关,win7系统的IIS的值是10(或者其他不确定),VS2012自带的IIS Express的值是80。对于windows服务器版本的系统的具体值不清楚,即4294967295个并发连接来了后,(这边以win7下的10为例),iis第一时间只能启动10个工作线程去处理,那么其他4294967285必须排队,排队对用户的体验来说就是网页正在加载,但是什么都不显示,然后此时购买了据虚拟主机供应商所说的无并发连接数限制的客户就要开始狂暴了,为何购买了所谓的“无限并发连接数”,还是会一直在加载的情况,这就是IIS处理能力有限的问题。

当然服务器没有直接返回“HTTP Error 503. The service is unavailable.”应该也算是一些你花更多钱的安慰吧,因为你只购买了IIS连接数为50的话,那么第50+1个连接请求操作得到的就直接是“HTTP Error 503. The service is unavailable.”了。另外,如果web服务器的硬件设备够牛,那么IIS的工作线程也会处理的更快,那么响应的用户等待的时间也会更短(前提是IIS连接数够大,否则就直接503了)。

总的来说,最大并发连接数,影响了排队的数量,很多时候需要我们评估自己的网站的最大并发连接数,然后来进行设置最佳数量。

三、IIS最大并发工作线程数

在上面有所涉及,简单的说就是 IIS 在并发连接请求过来时的处理机制,它会更智能的以某个数量级为单位来分批处理,让没有处理连接请求排队等待,用户浏览器中对于排队等待的响应就是“正在加载”,这比页面直接显示“HTTP Error 503. The service is unavailable.”更加能让人接受。但是切勿怒点刷新按钮,因为点的越多,请求在排队队列中越靠后。

当然很多朋友会说,为什么我有时候第一次刷不出来,重新多刷一次内容就出来了,

  可能是:

1、页面脚本哪个地方下载或者处理出了问题,导致页面显示异常或者直接不显示

2、你重新刷新的那个秒级别的操作,web服务器更快速的已经处理好了其他队列的请求或者他人放弃了对web服务器连接请求的操作

3、路由或者宽带网络运营商问题(不稳定)

4、浏览器或者本身电脑问题

暂不知道“IIS最大并发工作线程数”有无地方可以设置。

四、队列长度

最大并发连接数,影响了排队的数量,那么进一步影响排队数量的设置就是队列长度。

假设最大连接数设置为100,1000个并发连接请求过来了,首先900直接返回给客户“HTTP Error 503. The service is unavailable.”

然后IIS先启动(假设最大并发工作线程数为10)10个线程处理请求,其他90个进入排队状态,如果此时如下操作:

“应用程序池” → 找到网站的所属应用程序池 → 右键“高级设置…” → “常规” → “列队长度”,设置为20

那么实际情况只会有20个进入排队状态了,70(队列中的20-90)个请求也会立刻返回“HTTP Error 503. The service is unavailable”,IIS 默认队列长度设置是1000,范围在10-65535 之间。

五、最大工作进程数

  IIS 6.0 及以后允许将应用程序池配置成一个Web园(Web Garden)。每个应用程序池的单一工作进程,能够大约承受30-50个左右的并发。

“应用程序池” → 找到网站的所属应用程序池 → 右键“高级设置…” → “进程模型” → “最大工作进程数”,默认值为1。

  

如果这个值大于 1,那么当有连接请求时会启动多个新的工作进程实例,可启动的最多进程数为所指定的最大工作进程数,后续更多的请求将以循环的方式发送至工作进程,这样每个工作进程都能承担负载一些连接请求,当然是以消耗cpu等硬件做代价,这是值得的,如果web服务器cpu使用率很低但是又需要更高效的处理并发连接请求,应当这样做。

如果网站中用到了依赖进程的Session和Cache等对象,则不能保存在服务器内存中,存储方式选用StateServer或者SQLServer会更好,另外多个工作进程切换时会有上下文复制,这也是资源消耗更多地方。

1、 最大工作进程数值的设置依据

在确定每个应用程序池的最大工作进程数时,最主要参考的数据包括网站的最大并发用户数以及WEB服务器的可用内存数。最大并发用户数需要通过一段时间的观察,记录下在系统忙时的最大并发用户数,按照每工作进程能承载30个并发的原则来确定应用程序池的最大工作进程数。同时要注意,每个工作进程大约会占用200M左右的系统内存,在设置最大工作进程数的时候,要主要最大工作进程数与200M的乘积不要超过系统最大可用内存数。一般情况下,建议按照每次增加5个工作进程数的方式对最大工作进程数进行调整,调整完后对网站观察一段时间,如依然无法满足要求,再继续增加5个工作进程数。

2、 session共享问题

如果网站没有用到session机制,则不会引发此问题。如果用到了session机制进行传值和保存数据,则需要考虑在应用程序池多个工作进程间进行session共享,防止出现session丢失的问题。此问题的解决措施见 Asp.Net 之 Session共享设置。

2.1 Asp.Net的Session共享设置

Asp.Net提供了以下几种Session保存机制,如表 1所示:Session保存方式

方式名称 存储方式 性能
Off 设置为不使用Session功能
InProc 设置为将Session存储在进程内,就是ASP中的存储方式,这是默认值 最高
StateServer 设置为将Session存储在独立的状态服务中。通常是aspnet_state.exe进程 性能损失10-15%
SQLServer 设置将Session存储在SQL Server中。 性能损失10-20%
Custom 自定制的存储方案 由实现方式确定

在Asp.Net程序的web.config配置文件中对Session的保存方式进行设置。如果不显示指定Session的保存方式,默认使用InProc的方式保存,即Session由提供服务的工作进程保存。

为了提高IIS对高并发的支持,可以增加应用程序池的工作进程数,IIS会根据内置的调度算法,将用户的请求在多个工作进程间动态分配,如果搭建了服务器集群和负载均衡,则用户请求会在多台机器的多个工作进程间进行动态分配。在上述情况下,如果Session的保存方式依然为InProc,则用户请求在多个工作进程间切换时可能出现Session丢失的情况,导致请求失败或出错。

为解决上述为,需要将Session的保存方式设置为共享,即表 1中的“StateServer”、“SQLServer”或“Custom”方式。这几种方法中,“SQLServer”方式需要安装独立的SQLServer数据库,“Custom”方式需要自行实现相应的Session存储与检索过程,部署起来相对复杂,相对上述两种方式,“StateServer”方式在功能性和可实施性上最好,因此下文重点介绍此种Session共享机制。

2.2 “ StateServer ”设置步骤:

[1] 确定StateServer服务器。如果只有一台WEB服务器,可指定当前服务器为StateServer服务器。如果存在多台服务器集群,可指定集群中的一台符合较轻的服务器作为StateServer服务器。

[2] 修改注册表,允许远程访问StateServer服务。可直接导入如下脚本。

端口默认为42424,可根据需要进行修改,下文均以42424为例。

[3] 打开【管理工具】-【服务】,找到“Asp.Net State Service”,点击右键,选择【属性】,如图 4所示:

[4]在弹出的【属性】窗口中,将【启动方式】改为“自动”,然后点击【启动】按纽启动服务,如图 5所示:

[5] 打开待修改网站主目录下的web.config配置文件,搜索找到“<sessionstate>”配置节点,如果不存在配置节点,则在“<system.web>”节点下新建“<sessionstate>”配置节点,并将节点属性修改为:
<sessionState mode=”StateServer” stateConnectionString=”tcpip=127.0.0.1:42424″ />
其中“tcpip=*”后的主机IP地址和端口可根据实际情况修改。修改完后保存配置文件即可。

注意:

[1] Session中保存的自定义对象必须显示标记为可序列化“[serializable]”。如果未显示标记为可序列化,则在访问页面时会报错。

[2] StateServer服务器必须为Windows Server操作系统,如Windows Server 2003或Windows Server 2008。

3、 合理的资源回收机制

大多数应用系统都存在工作时间使用量高、非工作时间使用量低的情况,针对这种现象,在系统非忙时应合理的释放操作系统资源,因此,应合理设置应用程序池的【限制超时】和【回收时间间隔】属性。

六、总结

当很多请求同时到来的时候,IIS会根据【最大并发连接数】来判断是否有多余的请求,多余的请求直接返回503,然后再根据【队列长度】来判断是否有多余的请求排不了队,排不了队的也直接返回503。所以,如何设置【最大并发连接数】和【队列长度】,实际上是有公式可以计算的:

  最大并发连接数 = 队列长度 + IIS最大并发工作线程数

IIS的默认值对我们网站并发处理能力的影响:

IIS默认的” 最大并发连接数 “为4294967295(42亿多),而” 队列长度 “默认值为1000。对于windows server版本的IIS,最大并发工作线程数可能几百(猜测,可能没有限制),按照这个默认值,那么IIS同时处理的请求数也就1000多。1000多这个数字才是IIS真正的并发处理能力,而这个能力跟我们的代码没有关系。

哪些指标是评判我们网站的处理能力的呢?最重要的指标可能莫过于” 每秒处理请求数 “(在性能分析器里面可以查看),这个数字也叫吞吐率。如果每个请求处理速度非常快,那么那么网站吞吐率就大,吞吐率大那么支持的同时在线人数就大。如果要做秒杀,那就看你的秒杀相关的URL支持多大的吞吐率吧。

CPU的计算能力是如何影响网站的处理能力的呢?还是那么多请求,如果CPU很强大,能够缩减每个请求的处理时间,那必然会提高吞吐率。还有很多的请求,如果花在网络传输或者到数据库的传输时间比较多,这部分等待时间CPU是闲置的,如果能够提高CPU的利用率,也可能提高网站的处理能力,最充分的利用服务器的资源。如果不想改代码而想提高CPU利用率,可以在IIS的应用程序池中设置最大工作进程数(默认值为1),可以设置为10如果当前CPU利用率只有百分之几的话,调整这个数值需要特别注意每一个工作进程是独立的应用程序,全局静态变量不共享。

提示“缺少所需的CD/DVD驱动器设备驱动程序”

缺少所需的cd/dvd驱动器设备驱动程序怎么办?这个问题经常会出现在新买的笔记本经常会遇到的报错问题。

今天笔者为大家带来解决方法,希望能帮大家解决问题。

提示“缺少所需的CD/DVD驱动器设备驱动程序”

工具/原料

  • 电脑

方法一:BIOS中关闭USB3.0

  1. 1

    以下为参考:在BIOS中-Config-USB-USB3.0 Mode 将默认的Auto选项更改为Disabled后再按F10保存即可。关闭后再尝试安装即可。

    提示“缺少所需的CD/DVD驱动器设备驱动程序”
    提示“缺少所需的CD/DVD驱动器设备驱动程序”
    END

方法二:为Win7 U盘安装盘加入Usb3.0支持

  1. 从Intel官网下载Windows7 USB3.0 Creator 实用程序

    提示“缺少所需的CD/DVD驱动器设备驱动程序”
  2. 使用Windows 7 USB DVD Download Tool或者软碟通(UltraISO)制作Win7原版安装盘。(不要使用ghost镜像制作,否则后续会有报错)

     

  3. 解压缩之前下载的软件,在解压缩路径下右键以管理员方式运行Installer_Creator.exe

    提示“缺少所需的CD/DVD驱动器设备驱动程序”
  4. 在弹出的提示框中点击右侧的选择按钮,选中U盘所在分区。

    提示“缺少所需的CD/DVD驱动器设备驱动程序”
  5. 点击Create Image开始往U盘中添加程序,等待程序安装的安装,时间可能会比较长,要十来二十分钟。

    提示“缺少所需的CD/DVD驱动器设备驱动程序”
    提示“缺少所需的CD/DVD驱动器设备驱动程序”
  6. 在出现Upadte finished,后创建结束,现在就可以使用这个U盘在USB 3.0接口上安装系统了。

    提示“缺少所需的CD/DVD驱动器设备驱动程序”
  7. 7

    使用安装完补丁的U盘安装完系统USB3.0驱动会自动安装上。

    通过上面的两个方法就能解决在安装Win7原版时出现缺少所需的CD/DVD驱动器设备驱动程序的问题了~

Win7 USB3.0 Creator V3官方版 (win7镜像添加usb3.0驱动)

https://www.jb51.net/softs/562140.html

Intel官方出品的Win7 USB3.0镜像创建工具,能够给Win7系统添加USB3.0驱动,是Win7镜像添加3.0驱动的官方实用工具。很多用户在找带usb 3.0驱动的Win7镜像,用这个工具就能轻松制作。

Win7 USB3.0 Creator

Win7 USB3.0 Creator使用教程

使用时需要将安装镜像解压出来,再使用Win7 USB3.0 Creator去找里面的文件,软件会自动完成添加驱动的步骤。

一、使用Windows 7 USB DVD Download Tool或者软碟通(UltraISO)制作Win7原版安装盘。(不要使用ghost镜像制作,否则后续会有报错

二、解压缩之前下载的软件,在解压缩路径下右键以管理员方式运行Installer_Creator.exe;

win7镜像添加3.0驱动

三、在弹出界面中点击右侧的选择按钮,选中U盘所在分区;

Win7 USB3.0 Creator

四、点击Create Image开始往U盘中添加程序,过程会比较长,Intel官方数据是15分钟,实测超过20分钟;

win7镜像添加3.0驱动

六、在出现Upadte finished!后创建结束,现在就可以使用这个U盘在USB 3.0接口上安装系统了。

当然这个应该也是支持2008的,如果这个不能实现,大家可以试试主板厂商出的工具。