Apache和Nginx负载均衡集群及测试分析

时间:2021-12-10 10:09:37

一、应用场景介绍

本文主要是介绍Apache和Tomcat在Linux环境下的安装讲解以及AJP协议动静分离负载均衡的实现,以及与Nginx负载性能比较。联网安装较为简单,故此处只说脱机的Linux环境下是如何安装的。因为大多数时候,公司的生产环境是在内网环境下,无外网,服务器处于脱机状态。

二、 Apache与Tomcat简介

传统的Java Web项目是通过tomcat来运行和发布的。但在实际的企业应用环境中,采用单一的tomcat来维持项目的运行是不现实的。tomcat 处理能力低,效率低,承受并发小(1000左右)。当用户请求较少时,单一的tomcat能够快速响应用户请求,但如果访问量一大,tomcat处理能力跟不上,无法及时响应请求,就会造成用户等待;如果访问量过大,超出tomcat的承受能力,还可能导致tomcat超载故障。

apache 是一个 web 服务器环境程序,可以作为web 服务器使用。Apache对并发请求的处理能力较tomcat强,对静态页面(如asp,php,cgi,jsp等)的处理上比tomcat更为迅速,但apache不支持动态网页(需借助tomcat)。

因此实际应用中可以搭建apache+tomcat负载均衡集群,一个apache 作为 Web 服务器,为网站的静态页面请求提供服务;并使用tomcat 服务器作为一个 Servlet/JSP 插件,用于处理网站的动态页面。当用户通过浏览器发出请求时,客户请求首先会发送到 apache,如果请求是静态文本则由 apache 解析,并把结果返回给客户端;如果是动态的请求,如 jsp,apache 会把解析工作交给 tomcat,由 tomcat 进行解析(这首先要两者现实整合),tomcat 解析完成后,结果仍是通过 apache 返回给客户端。这样就可以达到分工合作,实现负载均衡,提高系统的性能!

三、安装环境及工具

系统:CentOS7

  工具:XShell5及Xftp5 (Xshell和Xftp的使用请查看《离线Nginx配置》此处不再累述)

安装包:httpd-2.4.28.tar.gz(Apache)  apache-tomcat-8.5.23.tar.gz

软件下载

1. Apache HTTP Server

地址:http://httpd.apache.org/download.cgi#apache24

2. APR 和 APR-Util

地址:http://apr.apache.org/download.cgi

3. PCRE

地址:https://sourceforge.net/projects/pcre/files/pcre/

基本依赖包的准备(此处其他Linux基本依赖包如gcc安装不再累述,可查看《离线Nginx配置》)

apr-1.6.2.tar.gz

apr-util-1.6.0.tar.bz2

pcre-8.30.tar.gz

tomcat-connectors-1.2.42-src.tar.gz

jdk-8u144-linux-x64.rpm

四、安装依赖包

1、JDK的卸载与安装

因为CentOS自带有open jdk,需要将其删除,再重新安装oracle jdk。使用命令# rpm -qa | grep gcj或者# rpm -qa | grep jdk查看jdk的具体信息,通过# java -version和里面的jdk版本比较,用

rpm -e --nodeps java-1.7.0-openjdk-headless-1.7.0.75-2.5.4.2.el7_0.x86_64

rpm -e --nodeps java-1.7.0-openjdk-1.7.0.75-2.5.4.2.el7_0.x86_64

命令卸载相应的jdk;

Apache和Nginx负载均衡集群及测试分析

然后使用Xftp将我们从oracle下载的jdk版本,放入/usr/local/src/下,使用#cd /usr/local/src/命令进入对应的目录,使用安装命令#rpm -ivh jdk-8u144-linux-x64.rpm进行安装,安装完成后使用命令#java –version查看是否安装成功。

Apache和Nginx负载均衡集群及测试分析

2、httpd的卸载与安装

2.1卸载自带的httpd

因为有的系统是自带httpd(apache)的,我们需要先卸载掉系统自带的

  1. 查看是否有httpd进程正在运行

# ps -ef|grep httpd

Apache和Nginx负载均衡集群及测试分析

查看linux系统服务中有没有httpd 命令# chkconfig –list

Apache和Nginx负载均衡集群及测试分析

2.有processor或者有service,就执行如下步骤,没有的话可以跳过此步

关闭httpd服务自启动,令# chkconfig httpd off

停止httpd服务 ,# service httpd stop

停止后查看进程processor,如果依然有httpd,手动kill掉

命令# ps -ef|grep httpd

命令# kill -9 pid(pid为上一步查询到的进程id,逐个都删除)

查看是否存在rpm安装的httpd文件

命令#rpm -qa|grep httpd

根据名字删除包

命令#rpm -e httpd-tools-2.4...

2.2安装APR、APR-Util、PCRE、Apache

1、先创建对应的4个目录

[root@localhost src]# mkdir /usr/local/apache

[root@localhost src]# mkdir /usr/local/apr

[root@localhost src]# mkdir /usr/local/apr-util

[root@localhost src]# mkdir /usr/local/pcre

[root@localhost src]# tar -zxvf apr-1.6.2.tar.gz

[root@localhost src]# tar -jvxf apr-util-1.6.0.tar.bz2

[root@localhost src]# tar -zvxf pcre-8.30.tar.gz

[root@localhost src]# tar -zvxf httpd-2.4.28.tar.gz

[root@localhost src]# cd apr-1.6.2

[root@localhost apr-1.6.2]# ./configure --prefix=/usr/local/apr

[root@localhost apr-1.6.2]# make

[root@localhost apr-1.6.2]# make install

[root@localhost apr-1.6.2]# cd ../apr-util-1.6.0

[root@localhost apr-util-1.6.0]# ./configure --prefix=/usr/local/apr-util

--with-apr=/usr/local/apr/bin/apr-1-config

[root@localhost apr-util-1.6.0]# make

[root@localhost apr-util-1.6.0]# make install

[root@localhost apr-util-1.6.0]# cd ../pcre-8.30

[root@localhost pcre-8.30]# ./configure --prefix=/usr/local/pcre

--with-apr=/usr/local/apr/bin/apr-1-config

[root@localhost pcre-8.30]# make

[root@localhost pcre-8.30]# make install

[root@localhost pcre-8.30]# cd ../httpd-2.4.28

此步骤需安装OpenSSL,之前在Nginx的安装配置中已安装,此处不再累述。

[root@localhost httpd-2.4.28]#

./configure --prefix=/usr/local/apache --with-pcre=/usr/local/pcre --with-apr=/usr/local/apr

--with-apr-util=/usr/local/apr-util --enable-so --enable-rewirte --enable-ssl

--with-ssl=/usr/local/openssl--with-ssl=/usr/local/openssl

[root@localhost httpd-2.4.28]# make

[root@localhost httpd-2.4.28]# make install

vim修改httpd.conf文件的监听端口以及查找ServerName,打开注释,将ServerName值改为对应的IP地址。

Apache和Nginx负载均衡集群及测试分析

2.3启动Apache

到此可以启动Apache,进入到安装目录 # cd /usr/local/apache/bin ,下面三个命令分别是对应的启动、停止和重启命令。启动成功后浏览器中输入IP:端口即可看到对应的 It works!

[root@localhost bin]# ./apachectl start

[root@localhost bin]# ./apachectl stop

[root@localhost bin]# ./apachectl restart

3、Tomcat安装

3.1、解压安装

由于要在本地开启两个tomcat服务器实例以模拟负载均衡+群集的效果,因此我们需要将之前解压出来的tomcat复制成两份。使用Xftp将压缩包放入/usr/local/src中,进入目录进行解压。

#tar -zxvf apache-tomcat-8.5.23.tar.gz

我们可以使用Xftp在/usr/local下新建对应的这两个文件夹然后再复制过去,也可以使用命令将解压的文件直接拷贝过去。

# cp -r apache-tomcat-8.5.23 ../tomcat8109 ../tomcat8209

3.2启动与关闭

使用下面2个命令可以启动或关闭对应的Tomcat服务

# /usr/local/tomcat8080/bin/startup.sh

# /usr/local/tomcat8080/bin/shutdown.sh

4、JK连接器安装

mod_jk是连接apache和tomcat集群的中间件。因此我们需要安装mod_jk。

使用Xftp将tomcat-connectors-1.2.42-src.tar.gz放入服务器的/usr/local/src目录中,并进行解压。

# tar -zxvf tomcat-connectors-1.2.42-src.tar.gz

进入刚刚解压出来的tomcat-connector目录,再进入native目录。对jk进行编译和安装。

命令# ./configure --with-apxs=/usr/local/apache/bin/apxs

这里需要注意的是配置脚本要添加一个apxs完整路径作为参数。apxs是一个为Apache HTTP服务器编译和安装扩展模块的工具,用于编译一个或多个源程序或目标代码文件为动态共享对象,使之可以用由mod_so提供的LoadModule指令在运行时加载到Apache服务器中。

配置完成后执行编译操作 #make 。编译完成后使用ls命令来列出native目录下的所有目录和文件。注意有apache-1.3和apache-2.0两个目录。由于在配置编译的时候指定了apxs工具的位置。配置脚本会根据apxs的反馈结果自动识别目标apache服务器为2.x版本,因此本次编译生成的mod_jk.so模块会放在apache-2.0目录中,apache-1.3目录中是没有mod_jk.so的,这一点请注意。

我们现在将编译好的mod_jk.so拷贝到apache服务器的modules目录中,这个目录是专门用来存放扩展模块的:

# cp ./mod_jk.so  /usr/local/apache/modules/

到此我们的安装过程就结束了。

五、配置相关文件

1、Apache配置

1.1httpd.conf配置

我们可以使用Xftp进行到Apache的安装目录中,对conf文件夹中的httpd.conf使用notepad++打开,这里不推荐使用linux的vim进行编辑,因为文件行数较多且很多东西直接复制就好。

在有很多LoadModule语句的地方,末尾追加一行

LoadModule jk_module modules/mod_jk.so

然后在写有<IfModule XXXX>的区域追加一行如下配置

<IfModule jk_module>

JkWorkersFile conf/workers.properties

JkMountFile conf/uriworkermap.properties

JkLogFile logs/mod_jk.log

JkLogLevel warn

</IfModule>

<IfModule worker.c>

StartServers            5

ServerLimit            20

ThreadLimit           200

MaxClients           4000

MinSpareThreads        25

MaxSpareThreads       250

ThreadsPerChild       200

MaxRequestsPerChild  1000

</IfModule>

LoadModule表示当apache服务启动时要加载模块 jk_module为模块的别名,后面跟的modules/mod_jk.so就是相对于apache服务器所在目录(/usr/local/apache2/)的模块文件名。

<IfModule jk_module>区域表示当apache服务器加载jk_module(在LoadModule指令中指定的模块别名)模块时所做的配置。

其中:

JkWorkersFile 指定负载均衡服务器的配置文件,文件名为相对于apache服务器所在目录的conf/workers.properties文件

JkMountFile 指定那些请求交由负载均衡服务器来处理,那些由apache服务器来处理,配置文件为相对于apache服务器所在目录的conf/uriworkermap.properties文件

JkLogFile 指定JK连接器的日志输出文件,文件为相对于apache服务器所在目录的logs/mod_jk.log文件

JkLogLevel 指定JK连接器输出日志的级别,级别为warn以上的日志将被输出到日志文件中,可选的值级别由低到高分别为:TRACE DEBUG INFO WARN ERROR FATAL

<IfModule worker.c>区域表示当apache服务器以worker模式工作时使用的配置。

指令说明:

StartServers:设置服务器启动时建立的子进程数量。因为子进程数量动态的取决于负载的轻重,所有一般没有必要调整这个参数。

ServerLimit:服务器允许配置的进程数上限。只有在你需要将MaxClients和ThreadsPerChild设置成需要超过默认值16个子进程的时候才需要使用这个指令。不要将该指令的值设置的比MaxClients 和ThreadsPerChild需要的子进程数量高。修改此指令的值必须完全停止服务后再启动才能生效,以restart方式重启动将不会生效。

ThreadLimit:设置每个子进程可配置的线程数ThreadsPerChild上限,该指令的值应当和ThreadsPerChild可能达到的最大值保持一致。修改此指令的值必须完全停止服务后再启动才能生效,以restart方式重启动将不会生效。

MaxClients:用于伺服客户端请求的最大接入请求数量(最大线程数)。任何超过MaxClients限制的请求都将进入等候队列。默认值是"400",16 (ServerLimit)乘以25(ThreadsPerChild)的结果。因此要增加MaxClients的时候,你必须同时增加 ServerLimit的值。笔者建议将初始值设为(以Mb为单位的最大物理内存/2),然后根据负载情况进行动态调整。比如一台4G内存的机器,那么初始值就是4000/2=2000。

MinSpareThreads:最小空闲线程数,默认值是"75"。这个MPM将基于整个服务器监视空闲线程数。如果服务器中总的空闲线程数太少,子进程将产生新的空闲线程。

MaxSpareThreads:设置最大空闲线程数。默认值是"250"。这个MPM将基于整个服务器监视空闲线程数。如果服务器中总的空闲线程数太多,子进程将杀死多余的空闲线程。MaxSpareThreads的取值范围是有限制的。Apache将按照如下限制自动修正你设置的值:worker要求其大于等于 MinSpareThreads加上ThreadsPerChild的和。

ThreadsPerChild:每个子进程建立的线程数。默认值是25。子进程在启动时建立这些线程后就不再建立新的线程了。每个子进程所拥有的所有线程的总数要足够大,以便可以处理可能的请求高峰。

MaxRequestsPerChild:设置每个子进程在其生存期内允许伺服的最大请求数量。到达MaxRequestsPerChild的限制后,子进程将会结束。如果MaxRequestsPerChild为"0",子进程将永远不会结束。将MaxRequestsPerChild设置成非零值有两个好处:可以防止(偶然的)内存泄漏无限进行而耗尽内存;

给进程一个有限寿命,从而有助于当服务器负载减轻的时候减少活动进程的数量。

如果设置为非零值,我建议设为10000-30000之间的一个值。

公式:

ThreadLimit >= ThreadsPerChild

MaxClients <= ServerLimit * ThreadsPerChild,并且MaxClients必须是ThreadsPerChild的倍数

MaxSpareThreads >= MinSpareThreads+ThreadsPerChild

1.2 workers.properties和uriworkermap.properties

在Apache的conf目录下新建两个文件,这里我们可以使用Xftp进行新建,较为方便。

以下为workers.properties  文件内容:

#

# workers.properties

#

# list the workers by name

worker.list=loadBalanceServers, jk_watcher

# localhost server 1

# ------------------------

worker.s1.port=8109

worker.s1.host=localhost

worker.s1.route=s1

worker.s1.type=ajp13

worker.s1.lbfactor=10

worker.s1.cachesize=5

worker.s1.connection_pool_size=800

worker.s1.connection_pool_minsize=25

worker.s1.connection_pool_timeout=600

# localhost server 2

# ------------------------

worker.s2.port=8209

worker.s2.host=localhost

worker.s2.route=s2

worker.s2.type=ajp13

worker.s2.lbfactor=10

worker.s2.cachesize=5

worker.s2.connection_pool_size=800

worker.s2.connection_pool_minsize=25

worker.s2.connection_pool_timeout=600

worker.loadBalanceServers.type=lb

worker.loadBalanceServers.balanced_workers=s1,s2

worker.loadBalanceServers.sticky_session=false

worker.jk_watcher.type=status

# worker.jk_watcher.read_only=True

worker.jk_watcher.mount=/admin/jk

worker.retries=3

worker.list 首先配置了两个worker,一个用于负载均衡,一个用于监视负载均衡状态。别名分别为loadBalanceServers和jk_watcher

然后分别配置位于本机的两个负载均衡服务器

worker.s1.port:第一台负载均衡服务器AJP协议连接器的连接端口,这里配置为8109

worker.s1.host:第一台负载均衡服务器的主机名、域名或者IP地址,这里配置为本机localhost

worker.s1.type:JK模块实现负载均衡采用的是AJP协议1.3版本,因此第一台负载均衡服务器的类型配置为ajp13

worker.s1.lbfactor:第一台负载均衡服务器在整个负载均衡系统中所占的权重,这里配置为10,权重越大,越有可能处理更多的请求,建议给性能好的机器配置更高的权重。

worker.s1.cachesize:apache服务器是多线程的,tomcat能够利用这一优势来维持一定数量的连接作为缓存。根据用户的多少来配置一个合适缓存连接数量有助于提高性能。这里配置为5。

s1是第一台负载均衡服务器的别名,这个别名要牢记,因为在接下来的配置中还会用到。

s2作为第二台负载均衡服务器,配置与s1大致相同。区别是AJP协议连接器的连接端口与s1的不同,这是因为要在同一台物理机上部署两个tomcat服务器的缘故。如果是两台物理机,则可以配置相同的端口,那么host属性就应该不一样了。两个tomcat服务器的权重都是10,则两个tomcat服务器将会有相同的处理请求的机会。

worker.loadBalanceServers.type:设置名称为“loadBalanceServers”的worker类型,这里配置为lb,也就是Load Balance负载均衡

worker.loadBalanceServers.balanced_workers:设置名称为“loadBalanceServers”的worker拥有哪些负责负载均衡的服务器实例,这里配置为s1和s2

worker.loadBalanceServers.sticky_session:设置负载均衡是否采用粘性会话。如果该属性设置为true,假设一个请求被s1处理了,下次来源于同一个客户端的请求也将被s1处理。直到s1已经达到最大连接数,JK才会将会话切换到其他服务器上。但是如果恰巧一直负责处理该会话的服务器down掉了,则会话将会丢失,明显的故障现象就是关于session的操作会出现莫名其妙的错误(例如你所运行的应用中用户可能已经登录了,但突然在一次访问后莫名其妙地提示没有登录)。这里配置为false,不启用粘性会话,让服务器都有机会处理请求,提高了系统的稳定性。

worker.jk_watcher.type:设置名称为“jk_watcher”的worker类型,这里配置为status,用于监视各个负载均衡服务器实例的运行状态

# worker.jk_watcher.read_only:设置名称为“jk_watcher”的worker是否为只读。上面已经将这个worker设置为了监控worker,如果设置为只读,就不能对负载均衡服务器参数进行配置了,这里先将这条配置注释掉,默认值为false,表示可以配置参数。

worker.jk_watcher.mount:设置名称为“jk_watcher”的worker(负载均衡服务器实例监视器)的挂载路径,这里配置为/admin/jk。这样就可以通过http://127.0.0.1/admin/jk来访问监视工具了,可以很方便地看到各个负载均衡服务器的工作情况。

worker.retries:这是worker全局的重试次数。在apache服务器启动后,会最多尝试若干次去连接这些负载均衡服务器,若连接不上就认为是down掉了,这里配置为3。

下面给出uriworkermap.properties配置,其作用是告诉apache服务器哪些请求由负载均衡服务器处理:

#

# uriworkermap.properties

#

#define all requests will be submitted to load balance servers

#if the condition is satisfied, the filter will validate the next statement until it's not.

#notice the order of the following statements

/*=loadBalanceServers

/jkstatus=jk_watcher

!/*.js  =loadBalanceServers

!/*.css  =loadBalanceServers

!/*.scss =loadBalanceServers

!/*.otf  =loadBalanceServers

!/*.htm  =loadBalanceServers

!/*.html =loadBalanceServers

!/*.gif  =loadBalanceServers

!/*.jpg  =loadBalanceServers

!/*.jpeg =loadBalanceServers

!/*.png  =loadBalanceServers

!/*.bmp  =loadBalanceServers

!/*.swf  =loadBalanceServers

!/*.ioc  =loadBalanceServers

!/*.iocn  =loadBalanceServers

!/*.rar  =loadBalanceServers

!/*.zip  =loadBalanceServers

!/*.txt  =loadBalanceServers

!/*.flv  =loadBalanceServers

!/*.mid  =loadBalanceServers

!/*.doc  =loadBalanceServers

!/*.ppt  =loadBalanceServers

!/*.pdf  =loadBalanceServers

!/*.xls  =loadBalanceServers

!/*.mp3  =loadBalanceServers

!/*.wma  =loadBalanceServers

!/*.eot  =loadBalanceServers

!/*.svg  =loadBalanceServers

!/*.ttf  =loadBalanceServers

!/*.woff =loadBalanceServers

!/*.map  =loadBalanceServers

!/*.woff2=loadBalanceServers

!/*.ogg  =loadBalanceServers

在配置文件中,以“!”开头的条件表示“不要”,“=”表示交给。

因此条件“/*=loadBalanceServers”表示将任何请求交给负载均衡服务器。

条件“!/*.jpg=loadBalanceServers”表示不要将.jpg结尾的请求交给负载均衡服务器

apache服务器接收到一个请求后会按照配置文件中的约束条件一个一个地检查,然后按照最后满足的匹配条件来决定由哪个worker来处理请求。

2、Tomcat配置

因为是在同一台服务器上部署,因此端口号不能冲突,这里给出一个tomcat 的server.xml配置信息。

<?xml version='1.0' encoding='utf-8'?>

<!--指定tomcat服务器的Telnet登录端口 并设置关闭服务器指令为"SHUTDOWN" 此处需注意服务器安全 -->

<Server port="8005" shutdown="SHUTDOWN">

<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />

<!-- Prevent memory leaks due to use of particular java/javax APIs-->

<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />

<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />

<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

<GlobalNamingResources>

<Resource name="UserDatabase" auth="Container"

type="org.apache.catalina.UserDatabase" description="User database that can be updated and saved"

factory="org.apache.catalina.users.MemoryUserDatabaseFactory"

pathname="conf/tomcat-users.xml" />

</GlobalNamingResources>

<Service name="Catalina">

<!-- HTTP服务端口 若在同一台机器上运行两个Tomcat实例 需要修改这个端口 具体数值无要求 不重复即可 -->

<Connector port="8081" protocol="HTTP/1.1"

connectionTimeout="20000" redirectPort="8443" />

<!-- 此处的端口要与workers.properties文件中s1负载均衡服务器一致 -->

<Connector port="8109" protocol="AJP/1.3" redirectPort="8443" maxThreads="1000" URIEncoding="UTF-8" />

<!-- jvmRoute属性用来负载均衡的转发对象 值一定要与在workers.properties文件中指定的另外一台一样 -->

<!-- 本实验中有两个tomcat服务器实例,因此s1服务器指向的转发对象为s2,s2服务器的这个地方要设置为s1 -->

<!-- 如果有三个tomcat服务器实例做负载均衡,需要设置为s1->s2, s2->s3, s3->s1 -->

<Engine name="Catalina" defaultHost="localhost" jvmRoute="s2">

<Realm className="org.apache.catalina.realm.UserDatabaseRealm"

resourceName="UserDatabase" />

<Host name="localhost" appBase="webapps" unpackWARs="true"

autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">

<!-- 开始配置集群 -->

<!-- 如果仅配置负载均衡,只需要将Cluster标签注释掉 -->

<!-- 如果使用群集,应用的web.xml要加上distributable标签 -->

<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"

channelSendOptions="8">

<Manager className="org.apache.catalina.ha.session.DeltaManager"

expireSessionsOnShutdown="false"

notifyListenersOnReplication="true"/>

<Channel className="org.apache.catalina.tribes.group.GroupChannel">

<Membership className="org.apache.catalina.tribes.membership.McastService"

address="228.0.0.4"

port="45564"

frequency="500"

dropTime="3000"/>

<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"

address="auto"

port="4000"

autoBind="100"

selectorTimeout="5000"

maxThreads="6"/>

<Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">

<Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>

</Sender>

<Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>

<Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatchInterceptor"/>

</Channel>

<Valve className="org.apache.catalina.ha.tcp.ReplicationValve"

filter=""/>

<Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>

<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>

</Cluster>

<!-- 结束配置群集 -->

</Host>

</Engine>

</Service>

</Server>

到此我们就配置完成了,可以对其进行测试了。

六、测试比较

1、Window和Linux的比较

目前我们使用的是在window下面的Apache与Tomcat部署的动静分离负载均衡的服务。这里我们对window下使用Apache、Linux下使用Nginx、Linux下使用Apache进行测试。对于window下的AJP动静分离负载均衡和Linux下Nginx等配置不再累述,只进行相关测

我们使用jmeter进行相关测试,启用5个jmeter线程,每个线程进行2000次请求,每次请求相隔1s,执行对应的测试。

window下的Apache和Tomcat集群请求结果

Apache和Nginx负载均衡集群及测试分析

Linux下Apache和Tomcat动静分离后的集群请求结果

Apache和Nginx负载均衡集群及测试分析

Linux下Nginx和Tomcat动静分离后的集群请求结果

Apache和Nginx负载均衡集群及测试分析

从3个图中我们可以很明显的看到,window服务器下无论是从服务器的吞吐量还是请求响应的时间来看都远远的低于Linux系统,而在Linux系统下Apache和Nginx的性能则相差不大。

2、Nginx和Apache的比较

因为在请求较少的情况下二者差别不大,因此我们加大并发量,来测试Linux中高并发的情况下Apache与Nginx的性能。采用500个线程并发,同时在间隔1s的时间内循环请求100次。这样的并发下我们就可以发现Nginx与Apache的差异了。

Nginx高并发下的请求结果

Apache和Nginx负载均衡集群及测试分析

Apache高并发下的请求结果

Apache和Nginx负载均衡集群及测试分析

从图中我们可以看到,Apache在高并发的情况下响应时间比Nginx短,而且吞吐量较大,但是请求错误率却高达25%,这是无法忍受的。而Nginx相对而言的话,在高并发下响应时间没有Apache快,但是请求失败的情况只有0.01%,几乎可以忽略不计。

3、结论

从上面的测试我们可以得出结论,Apache在处理动态请求时效率比Nginx要好,但是对于高并发的情况,Nginx则比起Apache来说,性能要好。从现在的实际情况来考虑的话,在Linux下使用Nginx是一个更好的选择。