前言
Nginx是一款非常优秀的HTTP服务器软件
支持高达50000个并发连接数的响应
拥有强大的静态资源处理能力
运行稳定
内存、CPU等系统资源消耗非常低
目前很多大型网站都应用Nginx服务器作为后端网站程序的反向代理及负载均衡器,提升整个站点的负载并发能力
一。Nginx反向代理概念
Nginx实现负载均衡是通过反向代理实现
反向代理(Reverse Proxy)方式是指以代理服务器来接受Internet上的连接请求,然后将请求转发给内部网络上的服务器;并将从服务器上得到的结果返回给Internet上请求连接的客户端,此时代理服务器对外就表现为一个服务器。
1.1)Nginx反向代理为什么可以优化服务器的性能?
因为Nginx可以在request读取完整请求前,buffer住(缓冲),然后一起发给服务器。因为有时候会出现卡顿现象,会断断续续传递,比如网慢的时候,request请求就会一点一点发给服务器,Nginx可以发给服务器一个完整的http请求。同样,Nginx也可以把response先buffer住,也是提升服务器性能。
通常的代理服务器,只用于代理内部网络对Internet的连接请求,客户机必须指定代理服务器,并将本来要直接发送到Web服务器上的http请求发送到代理服务器中。当一个代理服务器能够代理外部网络上的主机,访问内部网络时,这种代理服务的方式称为反向代理服务。
1.2)Nginx配置反向代理的主要参数
*upstream 服务池名{}
配置后端服务器池,以提供响应数据
*proxy_pass http://服务池名
配置将访问请求转发给后端服务器池的服务器处理
1.3)Nginx四层反向代理和七层反向代理
四层反向代理:是基于IP+PORT(TCP/UDP端口)转发
七层反向代理:基于http,https,mail代理转发
二。Nginx动静分离实现原理
服务端接收来自客户端的请求中,既有静态资源也有动态资源,静态资源由Nginx提供服务,动态资源Nginx转发至后端
Nginx静态处理优势
Nginx处理静态页面的效率远高于Tomcat的处理能力
若Tomcat的请求量为1000次,则Nginx的请求量为6000次
Tomcat每秒的吞吐量为0.6M,Nginx的每秒吞吐量为3.6M
Nginx处理静态资源的能力是Tomcat处理的6倍
三。Nginx负载均衡模式
rr负载均衡模式
每个请求按时间顺序逐一分配到不同的后端服务器,如果超过了最大失败次数后(max_fails,默认1),在失效时间内(fail_timeout,默认10秒),该节点失效权重变为0,超过失效时间后,则恢复正常,或者全部节点都为down后, 那么将所有节点都恢复为有效继续探测,一般来说rr可以根据权重来进行均匀分配。
least_conn最少连接
优先将客 户端请求调度到当前连接最少的服务器。
ip_hash负载均衡模式
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器, 可以解决session(会话状态)的问题,但是ip_hash会造成负载不均,有的服务请求接受多,有的服务请求接受少,所以不建议采用ip_hash模式,session共享问题可用后端服务的session共享代替nginx的ip_hash。ip_hash无法作用于四层反向代理,配置需要将其他模式删除例如weight删掉然后直接在加上
注释:
Session又称为会话状态,是Web系统中最常用的状态,用于维护和当前浏览器实例相关的一些信息。我们控制用户去权限中经常用到Session来存储用户状态
session其实分为客户端Session和服务器端Session。
当用户首次与Web服务器建立连接的时候,服务器会给用户分发一个 SessionID作为标识。SessionID是一个由24个字符组成的随机字符串。用户每次提交页面,浏览器都会把这个SessionID包含在 HTTP头中提交给Web服务器,这样Web服务器就能区分当前请求页面的是哪一个客户端。这个SessionID就是保存在客户端的,属于客户端Session。
其实客户端Session默认是以cookie的形式来存储的,所以当用户禁用了cookie的话,服务器端就得不到SessionID。这时我们可以使用url的方式来存储客户端Session。也就是将SessionID直接写在了url中,当然这种方法不常用。
Session共享:指在一个浏览器对应多个Web服务时,服务端的Session数据需要共享。例如单点登录、Web服务器集群等场景都需要用到、多子服务。
fair(第三方)负载均衡模式
按后端服务器的响应时间来分配请求,响应时间短的优先分配。
url_hash(第三方)负载均衡模式
和ip hash算法类似,是对每个请求按url的hash结果分配,使每个URL定向到同一个后端服务器, 但是也会造成分配不均的问题, 这种模式后端服务器为缓存时比较好。
四。Nginx+Tomcat负载均衡、动静分离配置实验
设备:
Nginx服务器∶192.168.150.10:80
Tomcat服务器1∶192.168.150.15:8080
Tomcat服务器2(双实例)∶192.168.150.20:8080 192.168.150.20:8081
1.部署Nginx负载均衡器
systemctl stop firewalld
setenforce 0
yum -y install pcre-devel zlib-devel openssl-devel gcc gcc-c++ make #安装依赖环境
useradd -M -s /sbin/nologin nginx #建立执行用户
cd /opt
tar zxvf nginx-1.12.0.tar.gz -C /opt/ #解压软件包
cd nginx-1.12.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层调度
-------------------------------------------------------------------------------
./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
make -j 2 && make install
ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/
#加入系统启动管理
vim /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
chmod 754 /lib/systemd/system/nginx.service
systemctl start nginx.service
systemctl enable nginx.service
2.部署2台Tomcat应用服务器,一台单实例,一台配置双实例
systemctl stop firewalld
setenforce 0
tar zxvf jdk-8u91-linux-x64.tar.gz -C /usr/local/
vim /etc/profile
export JAVA_HOME=/usr/local/jdk1.8.0_91
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH
source /etc/profile
tar zxvf apache-tomcat-8.5.16.tar.gz
mv /opt/apache-tomcat-8.5.16/ /usr/local/tomcat
/usr/local/tomcat/bin/startup.sh
netstat -ntap | grep 8080
3.动静分离配置
(1)Tomcat服务器1
#定义首页文件内容
mkdir /usr/local/tomcat/webapps/test
vim /usr/local/tomcat/webapps/test/index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
<head><title>JSP test1 page</title></head> #指定为test1页面
<body>
<% out.println("这里是tomcat服务器1");%>
</body>
</html>
vim /usr/local/tomcat/conf/server.xml #进入tomcat主配置文件修改连接规则
#由于主机名name配置都为localhost,需要删除前面的HOST配置
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware=" false">
<Context docBase="/usr/local/tomcat/webapps/test" path="" reloadable="true" />
</Host>
#重启服务
/usr/local/tomcat/bin/shutdown.sh
/usr/local/tomcat/bin/startup.sh
(2)Tomcat服务器2实例1
mkdir /usr/local/tomcat/tomcat1/webapps/test /usr/local/tomcat/tomcat2/webapps/test
vim /usr/local/tomcat/tomcat1/webapps/test/index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
<head><title>JSP test2 page</title></head> #指定为test2页面
<body>
<% out.println("这里是tomcat服务器2的实例1");%>
</body>
</html>
vim /usr/local/tomcat/tomcat1/conf/server.xml
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware=" false">
<Context docBase="/usr/local/tomcat/tomcat1/webapps/test" path="" reloadable="true" />
</Host>
#重启一下服务
/usr/local/tomcat/tomcat1/bin/shutdown.sh
/usr/local/tomcat/tomcat1/bin/startup.sh
(3)Tomcat服务器2实例2
vim /usr/local/tomcat/tomcat2/webapps/test/index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
<head><title>JSP test3 page</title></head> #指定为test3页面
<body>
<% out.println("这里是tomcat服务器2的实例2");%>
</body>
</html>
vim /usr/local/tomcat/tomcat1/conf/server.xml #前面监听端口需要改成与实例1不一样的,按照Tomcat多实例部署配置方法
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">
<Context docBase="/usr/local/tomcat/tomcat2/webapps/test" path="" reloadable="true" />
</Host>
#重启一下服务
/usr/local/tomcat/tomcat2/bin/shutdown.sh
/usr/local/tomcat/tomcat2/bin/startup.sh
(4)Nginx server设置
#准备静态页面和静态图片
echo '<html><body><h1>这是静态页面!!</h1></body></html>' > /usr/local/nginx/html/index.html
vim /usr/local/nginx/conf/nginx.conf
http {
#gzip on;
#配置负载均衡的服务器列表,weight参数表示权重,权重越高,被分配到的概率越大可以在wegight后面配置max_fails(最大失败次数)、fail_timeout(失效时间)
upstream tomcat_server {
server 192.168.150.15:8080 weight=1;
server 192.168.150.20:8080 weight=1;
server 192.168.150.20:8081 weight=1;
}
server {
listen 80;
server_name www. kgc. com;
charset utf-8;
#access_log logs/host.access.log main;
#配置Nginx处理动态页面请求,不区分大小写将.jsp结尾文件请求转发到Tomcat服务器处理
location ~ .*\.jsp$ {
proxy_pass http://tomcat_server;
####设定后端的Web服务器接收到的请求访问的主机名(域名或IP、端口),默认HOST的值为proxy pass指令设置的主机名。如果反向代理服务器不重写该请求头的话,那么后端真实服务器在处理时会认为所有的请求都来在反向代理服务器,如果后端有防攻击策略的话,那么反向代理就无法连接后端服务器
#设置后端的web服务器可以获取远程客户端的真实IP
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|swf)$ {
root /usr/local/nginx/html/img;
expires 10d; #有效时间10天
}
location / {
root html;
index index.html index.htm;
}
。。。。。。。。。。。。。。。。。
systemctl restart nginx.service
4.访问验证
http://192.168.150.10/index.jgp
http://192.168.150.10/index.jsp
五。Nginx四层代理设置
1.与七层配置区别地方
./configure
........
--with-stream #需要安装该模块
vim /usr/local/nginx/conf/nginx.conf #nginx服务器中主配置文件配置
和http同等级:所以一般只在http上面一段设置
stream {
upstream tomcat_server {
server 192.168.150.15:8080 weight=1;
server 192.168.150.20:8080 weight=1;
server 192.168.150.20:8081 weight=1;
}
server {
listen 800;
proxy_pass tomcat_server;
}
}
http {
....................................................
2.访问验证
基于端口访问,但是会有60s左右的缓存时间才会实现跳转到别的tomcat服务器