目录 | 功能 |
---|---|
bin | 存放启动和关闭 Tomcat 的脚本文件,比较常用的是 catalina.sh 、startup.sh 、shutdown.sh 三个文件 |
conf | 存放 Tomcat 服务器的各种配置文件,比较常用的是 server.xml 、context.xml 、tomcat-users.xml 、web.xml 四个文件。 |
lib | 存放Tomcat日志 |
temp | 存放Tomcat运行时产生的文件 |
webapps | 存放项目资源的目录 |
work | Tomcat工作目录,一般清除Tomcat缓存的时候会使用到 |
Nginx是一款非常优秀的HTTP服务器软件。Nginx支持高达50000个并发连接数的响应,拥有强大的静态资源处理能力,运行稳定,内存、CPU等系统资源消耗非常低。
目前很多大型网站都应用Nginx服务器作为后端网站程序的反向代理及负载均衡器,提升整个站点的负载并发能力。
首先我们需要明确,我们作为用户是从客户端去访问服务端,因此从客户端-→服务端可以简单的认为是正向。换句话说正向代理时,我们往往明确的知道我们需要访问哪个服务端,比如我想访问google,但是由于某种原因,我无法直接访问它,因此我需要一个能访问呢google的代理服务器去帮我完成这个通信,通过一系列代理服务器的配置,当我输入google的网站时,代理服务器接收请求并转交给目标服务端即google,最终返回内容给我客户端。至此完成了一个简单的正向代理,通过上文我们可以发现,服务端仅仅只与代理服务器产生了通信,因此服务端并不知道该请求来自于哪个客户端,它知道是从代理服务器而来,因此正向代理的最大特点即:其屏蔽或者隐藏了真实客户端的信息,即保护了客户端。
弄清了正向代理,其实反向代理也很清晰了,不就是一个逆向思维嘛,即保护了服务端。反向代理往往应用于分布式环境下,例如我们的淘宝,为了解决高流星带来的服务器压力,单台服务器往往不能够解决问题,此时则需要搭建一个集群环境,并且其也拥有一个反向代理服务器,当大量的客户端请求淘宝时,往往请求并不会直接到服务端,而是先到代理服务器,由代理服务器进行反向代理,采用负载均衡9策略将请求分法给各台服务器,保证资源的充分利用。这就是反向代理最大的用处,我们是否也能发现,从某种意义上来说,反向代理屏蔽或者隐藏了服务器的信息,相对于单一服务端,采用了反向代理之后我们只知道访问了淘宝,却不知道访问了其具体的哪台服务器。
客户端向反向代理发送请求,接着反向代理根据某种负载机制请求至目标服务器(这些服务器都运行着相同的应用),并把获取的内容返回给客户端,其中代理请求可能根据配置被发往不同的服务器。
配置后端服务器池,以提供响应数据。
upstream 服务池名{}
配置将访问请求发送给后端服务器池的服务器处理。
proxy_pass http://服务池名
4层代理
使用NAT (Network Address Translation)技术,即网络地址转换。即请求进来的时候,nginx只修改数据包里面的目标IP、源IP、端口,然后就直接把数据包发给目标服务器(即nginx不知道请求的具体内容),目标服务器处理完成后,发给nginx,nginx数据包再做一次类似的修改,就返回给请求的客户端了。
7层代理
nginx读取并解析Http请求内容,然后将具体内容(请求行、请求头、空行、请求数据)转发到相应的服务器,转发的过程是:建立和目标机器的连接,然后转发请求,收到响应数据再转发给请求客户端。
每个请求按时间顺序逐一分配到不同的后端服务器,如果超过了最大失败次数后(max_fails,默认1),在失效时间内(fail_timeout,默认10秒),该节点失效权重变为0,超过失效时间后,则恢复正常,或者全部节点都为down后,那么将所有节点都恢复为有效继续探测,一般来说rr可以根据权重来进行均匀分配。
优先将客户端请求调度到当前连接最少的服务器。
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题,但是ip_hash会造成负载不均,有的服务请求接受多,有的服务请求接受少,所以不建议采用ip_hash模式,session 共享问题可用后端服务的 session 共享代替 nginx 的 ip_hash(使用后端服务器自身通过相关机制保持session同步)。
按后端服务器的响应时间来分配请求,响应时间短的优先分配。
基于用户请求的uri做hash。和ip_hash算法类似,是对每个请求按url的hash结果分配,使每个URL定向到同一个后端服务器,但是也会造成分配不均的问题,这种模式后端服务器为缓存时比较好。
客户端发送请求想要访问服务器端,首先会经过一个代理服务器(即包含Nginx服务的服务器),如果发送的请求中既有静态资源也有动态资源,其中的静态资源会有Nginx提供服务进行返回响应给客户端,动态资源则会由Nginx转发给后端(即包含Tomcat服务的服务器),然后由后端在进行返回响应给代理服务器,再由代理服务器返回响应给客户端。其本质就是是location规则的匹配。
吞吐量可以理解成带宽流量,以每个请求0.5KB大小,并发每秒25万,0.5/1024MB*250000=122MB*8bit=977Mbps
。
以10分钟有5000万用户平均每人访问2次为例,并发量为每秒(5000w*2)/(60*10)=16.7万
,再double下,就说每秒25万并发量。
Nginx 服务器:192.168.145.15:80
Tomcat服务器1:192.168.145.30:80
Tomcat服务器2:192.168.145.45:8080 192.168.2.200:8081
前提虚拟机需要配置本地yum源以及挂载镜像
环境配置
###关闭firewalld
[root@localhost ~]# systemctl stop firewalld.service
###关闭防火墙开机自启
[root@localhost ~]# systemctl disable firewalld.service
Removed symlink /etc/systemd/system/multi-user.target.wants/firewalld.service.
Removed symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.
关闭selinux
[root@localhost ~]# setenforce 0
编译安装nginx
[root@localhost ~]# yum -y install pcre-devel zlib-devel openssl-devel gcc gcc-c++ make
[root@localhost ~]# useradd -M -s /sbin/nologin nginx
[root@localhost ~]# cd /opt/
[root@localhost opt]# ls
nginx-1.24.0.tar.gz rh
[root@localhost opt]# tar xf nginx-1.24.0.tar.gz
[root@localhost opt]# ls
nginx-1.24.0 nginx-1.24.0.tar.gz rh
[root@localhost opt]# cd nginx-1.24.0/
[root@localhost nginx-1.24.0]# ./configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-file-aio \ #启用文件修改支持
--with-http_stub_status_module \ #启用状态统计
--with-http_gzip_static_module \ #启用 gzip静态压缩
--with-http_flv_module \ #启用 flv模块,提供对 flv 视频的伪流支持
--with-http_ssl_module #启用 SSL模块,提供SSL加密功能
--with-stream #启用 stream模块,提供4层调度
###编译安装
[root@localhost nginx-1.24.0]# make -j2 && make install
./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-file-aio --with-http_stub_status_module --with-http_gzip_static_module --with-http_flv_module --with-stream
添加nginx服务
###把nginx服务的可执行程序文件放入路径环境变量的目录中便于系统识别
[root@localhost ~]# ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/
###修改nginx服务的配置文件
[root@localhost nginx-1.24.0]# vim /lib/systemd/system/nginx.service
[Unit] #服务的说明
Description=nginx #描述服务
After=network.target #依赖,当依赖的服务启动之后再启动自定义的服务
[Service] #服务运行参数的设置
Type=forking #是后台运行的形式,使用此启动类型应同时指定
PIDFile=/usr/local/nginx/logs/nginx.pid #PID文件位置以便systemd能够跟踪服务的主进程
ExecStart=/usr/local/nginx/sbin/nginx #服务的具体运行命令
ExecReload=/bin/kill -s HUP $MAINPID #重启命令
ExecStop=/bin/kill -s QUIT $MAINPID #停止命令
PrivateTmp=true #给服务分配独立的临时空间
[Install] #服务安装的相关设置
WantedBy=multi-user.target #可设置为多用户
###给予文件权限
[root@localhost ~]# chmod 754 /lib/systemd/system/nginx.service
###启动nginx服务
[root@localhost ~]# systemctl start nginx.service
###开机自启nginx服务
[root@localhost ~]# systemctl enable nginx.service
Created symlink from /etc/systemd/system/multi-user.target.wants/nginx.service to /usr/lib/systemd/system/nginx.service.
[Unit]
Description=nginx
After=network.target
[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStart=/usr/local/nginx/sbin/nginx
ExecrReload=/bin/kill -s HUP $MAINPID
ExecrStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
测试访问ip地址
环境设置
###关闭firewalld
[root@localhost ~]# systemctl stop firewalld.service
###关闭防火墙开机自启
[root@localhost ~]# systemctl disable firewalld.service
Removed symlink /etc/systemd/system/multi-user.target.wants/firewalld.service.
Removed symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.
关闭selinux
[root@localhost ~]# setenforce 0
安装jdk
[root@localhost opt]# cd /opt
###查询指定软件包的文件列表
[root@localhost opt]# rpm -qpl jdk-8u201-linux-x64.rpm
###安装jdk
[root@localhost opt]# rpm -ivh jdk-8u201-linux-x64.rpm
###查看jdk版本号
[root@localhost opt]# java -version
openjdk version "1.8.0_262"
OpenJDK Runtime Environment (build 1.8.0_262-b10)
OpenJDK 64-Bit Server VM (build 25.262-b10, mixed mode)
设置JDK环境变量
[root@localhost opt]# vim /etc/profile.d/java.sh
export JAVA_HOME=/usr/java/jdk1.8.0_201-amd64
export JRE_HOME=$JAVA_HOME/jre
export CLASSPATH=.:$JAVA_HOME/lib:$JRE_HOME/lib
export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH
###刷新配置文件
[root@localhost opt]# source /etc/profile.d/java.sh
[root@localhost opt]# java -version
java version "1.8.0_201"
Java(TM) SE Runtime Environment (build 1.8.0_201-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.201-b09, mixed mode)
安装tomcat
[root@localhost opt]# tar xf apache-tomcat-9.0.16.tar.gz
[root@localhost opt]# mv apache-tomcat-9.0.16 /usr/local/tomcat
tomcat设置位服务
###编写tomcat服务文件
[root@localhost system]# vim /usr/lib/systemd/system/tomcat.service
[Unit]
Description=tomcat server
Wants=network-online.target
After=network.target
[Service]
Type=forking
Environment="JAVA_HOME=/usr/java/jdk1.8.0_201-amd64"
Environment="PATH=$JAVA_HOME/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin"
Environment="CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar"
ExecStart=/usr/local/tomcat/bin/startup.sh
ExecStop=/usr/local/tomcat/bin/shutdown.sh
Restart=on-failure
[Install]
WantedBy=multi-user.target
###重新加载服务
[root@localhost system]# systemctl daemon-reload
[root@localhost system]# systemctl start tomcat
浏览器访问验证
安装jdk
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# systemctl disable firewalld
[root@localhost ~]# setenforce 0
[root@localhost ~]# cd /opt/
[root@localhost opt]# ls
apache-tomcat-9.0.16.tar.gz jdk-8u91-linux-x64.tar.gz rh
###解压
[root@localhost opt]# tar xf jdk-8u91-linux-x64.tar.gz
[root@localhost opt]# mv jdk1.8.0_91/ /usr/local/
[root@localhost opt]# cd
[root@localhost ~]# vim /etc/profile
export JAVA_HOME=/usr/local/jdk1.8.0_91
export JRE_HOME=$JAVA_HOME/jre
export CATALINA=.:$JAVA_HOME/lib:$JRE_HOME/lib
export PATH=%JAVA_HOME/bin:$JRE_HOME/bin:$PATH
###加载文件
[root@localhost ~]# source /etc/profile
[root@localhost ~]# java -version
java version "1.8.0_91"
Java(TM) SE Runtime Environment (build 1.8.0_91-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.91-b14, mixed mode)
安装 tomcat
[root@localhost opt]# tar zxvf apache-tomcat-9.0.16.tar.gz
###创建目录
[root@localhost opt]# mkdir /usr/local/tomcat
###移动tomcat到/usl/local/tomcat/改名为tomcat1
[root@localhost opt]# mv apache-tomcat-9.0.16 /usr/local/tomcat/tomcat1
###复制 tomcat1 改名为 tomcat2
[root@localhost opt]# cd /usr/local/tomcat/
[root@localhost tomcat]# ls
tomcat1
[root@localhost tomcat]# cp -a tomcat1/ tomcat2/
[root@localhost tomcat]# ls
tomcat1 tomcat2
配置tomcat环境变量
[root@localhost ~]# vim /etc/profile.d/tomcat.sh
#tomcat1
export CATALINA_HOME1=/usr/local/tomcat/tomcat1
export CATALINA_BASE1=/usr/local/tomcat/tomcat1
export TOMCAT_HOME1=/usr/local/tomcat/tomcat1
#tomcat2
export CATALINA_HOME2=/usr/local/tomcat/tomcat2
export CATALINA_BASE2=/usr/local/tomcat/tomcat2
export TOMCAT_HOME2=/usr/local/tomcat/tomcat2
[root@localhost ~]# source /etc/profile.d/tomcat.sh
修改 tomcat2 中的 server.xml 文件,要求各 tomcat 实例配置不能有重复的端口号
[root@localhost ~]# vim /usr/local/tomcat/tomcat2/conf/server.xml
###22行,修改Server prot,默认为8005 -> 修改为8006
###69行,修改Connector port,HTTP/1.1 默认为8080 -> 修改为8081
修改为8010
修改各 tomcat 实例中的 startup.sh 和 shutdown.sh 文件
[root@localhost ~]#
[root@localhost ~]# vim /usr/local/tomcat/tomcat1/bin/startup.sh
# -----------------------------------------------------------------------------
# Start Script for the CATALINA Server
# -----------------------------------------------------------------------------
##添加以下内容
export CATALINA_BASE=$CATALINA_BASE1
export CATALINA_HOME=$CATALINA_HOME1
export TOMCAT_HOME=$TOMCAT_HOME1
[root@localhost ~]# vim /usr/local/tomcat/tomcat1/bin/shutdown.sh
# -----------------------------------------------------------------------------
# Stop script for the CATALINA Server
# -----------------------------------------------------------------------------
export CATALINA_BASE=$CATALINA_BASE1
export CATALINA_HOME=$CATALINA_HOME1
export TOMCAT_HOME=$TOMCAT_HOME1
[root@localhost ~]# vim /usr/local/tomcat/tomcat2/bin/startup.sh
# -----------------------------------------------------------------------------
# Start Script for the CATALINA Server
# -----------------------------------------------------------------------------
export CATALINA_BASE=$CATALINA_BASE2
export CATALINA_HOME=$CATALINA_HOME2
export TOMCAT_HOME=$TOMCAT_HOME2
[root@localhost ~]# vim /usr/local/tomcat/tomcat1/bin/shutdown.sh
# -----------------------------------------------------------------------------
# Stop script for the CATALINA Server
# -----------------------------------------------------------------------------
export CATALINA_BASE=$CATALINA_BASE2
export CATALINA_HOME=$CATALINA_HOME2
export TOMCAT_HOME=$TOMCAT_HOME2
启动各 tomcat 中的 /bin/startup.sh
[root@localhost ~]# /usr/local/tomcat/tomcat1/bin/startup.sh
Using CATALINA_BASE: /usr/local/tomcat/tomcat1
Using CATALINA_HOME: /usr/local/tomcat/tomcat1
Using CATALINA_TMPDIR: /usr/local/tomcat/tomcat1/temp
Using JRE_HOME: /usr
Using CLASSPATH: /usr/local/tomcat/tomcat1/bin/bootstrap.jar:/usr/local/tomcat/tomcat1/bin/tomcat-juli.jar
Tomcat started.
[root@localhost ~]# /usr/local/tomcat/tomcat2/bin/startup.sh
Using CATALINA_BASE: /usr/local/tomcat/tomcat2
Using CATALINA_HOME: /usr/local/tomcat/tomcat2
Using CATALINA_TMPDIR: /usr/local/tomcat/tomcat2/temp
Using JRE_HOME: /usr
Using CLASSPATH: /usr/local/tomcat/tomcat2/bin/bootstrap.jar:/usr/local/tomcat/tomcat2/bin/tomcat-juli.jar
Tomcat started
[root@localhost ~]# netstat -lntp | grep java
tcp6 0 0 :::8080 :::* LISTEN 12737/java
tcp6 0 0 :::8081 :::* LISTEN 12802/java
tcp6 0 0 127.0.0.1:8005 :::* LISTEN 12737/java
tcp6 0 0 127.0.0.1:8006 :::* LISTEN 12802/java
tcp6 0 0 :::8009 :::* LISTEN 12737/java
tcp6 0 0 :::8010 :::* LISTEN 12802/java
浏览器测试
[root@localhost ~]# mkdir /usr/local/tomcat/webapps/test
[root@localhost ~]# vim /usr/local/tomcat/webapps/test/index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
JSP test1 page
动态页面1
[root@localhost ~]# cd /usr/local/tomcat/conf/
###备份
[root@localhost conf]# cp /usr/local/tomcat/conf/server.xml /usr/local/tomcat/conf/server.xml.bak
[root@localhost ~]# vim /usr/local/tomcat/conf/server.xml
#由于主机名 name 配置都为 localhost,需要删除前面的 HOST 配置
[root@localhost conf]# systemctl restart tomcat
配置测试文件
[root@localhost ~]# mkdir /usr/local/tomcat/tomcat1/webapps/test /usr/local/tomcat/tomcat2/webapps/test
[root@localhost ~]# vim /usr/local/tomcat/tomcat1/webapps/test/index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
JSP test2 page
动态页面2
##备份
[root@localhost ~]# cp /usr/local/tomcat/tomcat1/conf/server.xml /usr/local/tomcat/tomcat1/conf/server.xml.bak
[root@localhost ~]# vim /usr/local/tomcat/tomcat1/conf/server.xml
###删除前面的 HOST 配置
配置测试文件
[root@localhost ~]# vim /usr/local/tomcat/tomcat2/webapps/test/index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
JSP test3 page
动态页面3
###备份
[root@localhost ~]# cp /usr/local/tomcat/tomcat2/conf/server.xml /usr/local/tomcat/tomcat2/conf/server.xml.bak
[root@localhost ~]#vim /usr/local/tomcat/tomcat2/conf/server.xml
###删除前面的 HOST 配置
重新启动服务
[root@localhost ~]# /usr/local/tomcat/tomcat1/bin/shutdown.sh
[root@localhost ~]# /usr/local/tomcat/tomcat1/bin/startup.sh
[root@localhost ~]# /usr/local/tomcat/tomcat2/bin/shutdown.sh
[root@localhost ~]# /usr/local/tomcat/tomcat2/bin/startup.sh
#准备静态页面和静态图片
[root@localhost ~]# echo '这是静态页面
' > /usr/local/nginx/html/index.html
[root@localhost ~]# mkdir /usr/local/nginx/html/img
[root@localhost ~]# cp /root/game.jpg /usr/local/nginx/html/img
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
......
http {
......
#gzip on;
#配置负载均衡的服务器列表,weight参数表示权重,权重越高,被分配到的概率越大
upstream tomcat_server {
server 192.168.145.30:8080 weight=1;
server 192.168.145.45:8080 weight=1;
server 192.168.145.45:8081 weight=1;
}
server {
listen 80;
server_name www.accp.com;
charset utf-8;
#access_log logs/host.access.log main;
#配置Nginx处理动态页面请求,将 .jsp文件请求转发到Tomcat 服务器处理
location ~ .*\.jsp$ {
proxy_pass http://tomcat_server;
#设置后端的Web服务器可以获取远程客户端的真实IP
##设定后端的Web服务器接收到的请求访问的主机名(域名或IP、端口),默认HOST的值为proxy_pass指令设置的主机名。如果反向代理服务器不重写该请求头的话,那么后端真实服务器在处理时会认为所有的请求都来自反向代理服务器,如果后端有防攻击策略的话,那么机器就被封掉了。
proxy_set_header HOST $host;
##把$remote_addr赋值给X-Real-IP,来获取源IP
proxy_set_header X-Real-IP $remote_addr;
##在nginx 作为代理服务器时,设置的IP列表,会把经过的机器ip,代理机器ip都记录下来
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
#配置Nginx处理静态图片请求
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|css)$ {
root /usr/local/nginx/html/img;
expires 10d;
}
location / {
root html;
index index.html index.htm;
}
......
}
......
}
重启服务
[root@localhost ~]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@localhost ~]# systemctl restart nginx.service
测试静态页面效果
浏览器访问 http://192.168.145.15/
浏览器访问 http://192.168.145.15/game.jpg
测试负载均衡效果,不断刷新浏览器测试
浏览器访问 http://192.168.145.15/index.jsp
同192.168.145.15 配置
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
stream {
upstream appserver {
server 192.168.145.30:8080 weight=1;
server 192.168.145.45:8080 weight=1;
server 192.168.145.45:8081 weight=1;
}
server {
listen 8080;
proxy_pass appserver;
}
}
http {
......
server {
listen 80;
server_name localhost;
charset utf-8;
...
}
...
}
测试静态页面效果
浏览器访问 http://192.168.145.60/
测试负载均衡效果,不断刷新浏览器测试
浏览器访问 http://192.168.145.60:8080
基于端口访问,但是会有60s左右的缓存时间才会实现跳转到别的tomcat服务器
四层反向代理:基于IP+PORT实现的代理转发
七层反向代理:基于http、https、mail等七层协议转发
(1)在 http{}
配置段里设置 upstream
定义后端应用服务器池的名称和节点参数配置
upstream backend { ###backend是服务器池名称
server IP:PROT weight=1 ###weight设置权重
...
}
(2)在server{}
配置段里用 location{}
匹配用户的访问路径,使用 proxy_pass
基于协议进行转发
location ~ .*\.jsp$ { ###正则表达式,匹配 .jsp 结尾的文件
proxy_pass http://backend;
}
(1)编译安装时需要 --with-stream
添加四层反向代理模块;
./configure --with-stream
(2)和 http{}
配置段同层级别,一般在 http{}
配置段上面添加是 stream{}
配置段,在 stream{}
配置段中定义服务器池、监听端口和转发等配置
stream{
upstream backend {
server IP:PROT weight=1
...
}
server {
listen PROT;
server_name localhost;
location / {
proxy_passhttp://backend;
}
}
}