青蛙学Linux—Nginx+Tomcat实现动静分离以及负载均衡
Tomcat也是一个Web服务器,用于运行JSP页面和Servlet。虽然Tomcat也可以处理静态网页,但是其性能与并发能力远远比不上Nginx,而且Tomcat在高并发环境下处理动态请求的性能也不高,所以通过Nginx与Tomcat的整合来适应高并发的环境。
Nginx可以通过以下两种方式来实现与Tomcat的整合:
- 将静态页面请求交由Nginx处理,动态页面的请求交由Tomcat处理
- 将所有的请求都交由后端的Tomcat进行处理,Nginx利用自身的负载均衡功能实现多台Tomcat服务器的负载均衡
1、安装Tomcat
1.1、构建JAVA环境
Tomcat的运行需要JAVA环境的支持,所以我们在安装Tomcat之前必须先构建一个JAVA环境。JAVA环境需要安装JDK,JDK可以在https://www.oracle.com/technetwork/java/javase/downloads/index.html下载。
这里我们使用的是JDK 8u191(1.8.0_191)的版本,JDK的安装非常简单,Oracle提供给我们的是二进制可执行程序,在上面提供的网址中下载相应版本的tar.gz包之后,直接解压到相应的路径即可使用。
安装好JDK后,我们必须配置环境变量以便Tomcat进行调用,这里把JDK安装到/usr/local/jdk目录下,然后在/etc/profile中配置以下的环境变量:
export JAVA_HOME=/usr/local/jdk export PATH=$PATH:$JAVA_HOME/bin export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
测试:
[root@localhost ~]# java -version java version "1.8.0_191" Java(TM) SE Runtime Environment (build 1.8.0_191-b12) Java HotSpot(TM) 64-Bit Server VM (build 25.191-b12, mixed mode)
1.2、安装Tomcat
Tomcat的官网为http://tomcat.apache.org。
这里选择Tomcat 8.5.37的版本进行安装。与JDK一样,Tomcat在官网上同样提供给我们的是二进制可执行程序的tar.gz包,我们只要下载后解压到指定的目录即可。这里我们将Tomcat安装到/usr/local/tomcat目录下。
1.3、Tomcat的目录结构
Tomcat的可执行脚本位于安装目录下的bin目录中,重点关注以下三个脚本文件:
startup.sh # 启动Tomcat shutdown.sh # 关闭Tomcat catalina.sh # 配置Tomcat运行时需要的一些环境变量
Tomcat的配置文件位于安装目录下的conf目录中,重点关注以下配置文件:
server.xml # Tomcat的主配置文件 logging.properties # 配置Tomcat的日志输出格式
Tomcat的日志文件位于安装目录下的logs目录中。
Tomcat自带的默认站点位于安装目录下的webapps目录下,该目录有以下几个子目录:
docs # Tomcat文档 examples # 部署实例 host-manager # 通过Web管理Tomcat manager # 通过Web管理Tomcat ROOT # 自带网站的根目录
1.4、Tomcat的简单配置
Tomcat的主配置文件server.xml位于安装目录下的conf目录中,我们通过该文件进行简单的配置(端口号和虚拟主机的配置):
端口配置
# 通过HTTP协议访问Tomcat的端口,默认为8080 <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
虚拟主机配置
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"> <!-- SingleSignOn valve, share authentication between web applications Documentation at: /docs/config/valve.html --> <!-- <Valve className="org.apache.catalina.authenticator.SingleSignOn" /> --> <!-- Access log processes all example. Documentation at: /docs/config/valve.html Note: The pattern used is equivalent to using pattern="common" 日志配置,配置日志的文件名、扩展名和保存位置 --> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> </Host>
其中:
- name:定义虚拟主机的域名,也可以使用IP地址
- debug:定义日志输出级别
- appBase:定义存放Web应用的根目录,可以是绝对路径或相对于$CATALINA_HOME(Tomcat安装目录)的目录
- unpackWARs:定义Tomcat是否将WAR文件解压后运行,true为自动解压后运行
- autoDeploy:定义Tomcat是否自动发布appBase目录下的所有Web应用(包括新加入的Web应用),true为自动发布
也可以在<Host></Host>中定义以下内容,实现一个虚拟主机下的不同Web应用:
<Context path="" docBase="" debug=""/>
其中:
- path:定义Web应用的URL入口,比如path=“jsp”,则请求的URL应该为http://xxx/jsp
- docBase:定义Web应用的路径,可以使用绝对路径也可以使用相对路径,也可以为WAR文件的路径
1.5、启动Tomcat
进入Tomcat安装目录下的bin目录,运行:
[root@localhost bin]# ./startup.sh Using CATALINA_BASE: /usr/local/tomcat Using CATALINA_HOME: /usr/local/tomcat Using CATALINA_TMPDIR: /usr/local/tomcat/temp Using JRE_HOME: /usr/local/jdk Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar Tomcat started.
当前安装Tomcat的主机IP地址为192.168.0.110,访问http://192.168.0.110:8080:
Tomcat的欢迎页面。看到这个页面就说明Tomcat启动成功。
在Tomcat的Web根目录下,还放置了一个名为info.jsp的探针文件,我们访问http://192.168.0.110:8080/info.jsp:
2、Nginx+Tomcat实现动静分离
Nginx通过反向代理的方式将相应的请求转发给Tomcat以实现动静分离。这里通过一个实例来展示Nginx+Tomcat如何实现动静分离。
实验环境:
仅使用一台主机进行实验,主机IP为192.168.0.110,安装Nginx和Tomcat,Tomcat的端口为8080。通过配置Nginx将访问JSP文件的请求交由Tomcat处理。
Nginx配置部分(仅展示配置文件中server和location配置的相关部分):
server { listen 80; server_name localhost 192.168.0.110; location / { root html; index index.html index.htm; } location ~ \.jsp$ { proxy_pass http://127.0.0.1:8080; } }
我们首先来访问http://192.168.0.110:
然后访问http://192.168.0.110/info.jsp:
JSP文件也访问成功。服务器名称与域名均显示127.0.0.1是因为在Nginx反向代理时没有配置将真实IP发送给后端。
如何验证JSP文件真的是由Tomcat处理的呢,我们可以访问一个不存在的JSP文件,看看它的错误信息:
404错误,由Tomcat给出,同样,访问一个不存在的html,看看错误信息:
html文件的404由Nginx给出,这就说明了我们的配置已经实现了动静分离。
3、Nginx实现Tomcat的负载均衡
Nginx实现Tomcat的负载均衡同样是通过upstream定义一组主机,然后通过反向代理将请求转到该组主机上。以下通过一个实例来展示如何通过Nginx来实现Tomcat的负载均衡。
实验环境:
- 主机A:IP地址为192.168.0.110,安装Nginx 1.14.2,无Tomcat环境
- 主机B:IP地址为192.168.0.88,安装Tomcat 8.5.37,无Nginx环境
- 主机C:IP地址为192.168.0.106,安装Tomcat 8.5.37,无Nginx环境
- 主机D:IP地址为192.168.0.61,安装Tomcat 8.5.37,无Nginx环境
其中,主机A为前端服务器,通过Nginx提供负载均衡调度功能,主机BCD为后端服务器组,运行Tomcat提供Web服务,Tomcat端口均为8080。在BCD三台主机的Tomcat默认站点目录下均有一个名为info.jsp的探针文件。站点通过IP进行访问,没有进行域名解析。
我们首先来访问下BCD三台主机,看看它们的Tomcat是否正常提供服务:
http://192.168.0.88:8080/info.jsp
http://192.168.0.106:8080/info.jsp
http://192.168.0.61:8080/info.jsp
在主机A上配置整个站点的请求均转发到后端Tomcat服务器组,配置如下(仅展示Nginx配置文件中http、server和location部分的相关配置;这里为了展现负载均衡的效果,使用的是轮询算法,其实动态页面应该使用ip_hash算法,以解决session共享的问题):
http{ upstream tomcat_server{ server 192.168.0.88:8080 max_fails=3 fail_timeout=20s; server 192.168.0.106:8080 max_fails=3 fail_timeout=20s; server 192.168.0.61:8080 max_fails=3 fail_timeout=20s; } server { listen 80; server_name localhost 192.168.0.110; location / { proxy_pass http://tomcat_server; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
访问http://192.168.0.110/info.jsp:
Nginx成功为Tomcat提供了负载均衡功能。