nginx 反向代理,nginx 负载均衡【nginx】(一)

1 具体内容

中文官网:
http://www.nginx.cn/doc/
https://www.nginx.cn/
英文官网:
http://nginx.org/en/

1.1 nginx简介

Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3/SMAP)代理服务器 。其特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。

Nginx以事件驱动的方式编写,所以有非常好的性能,同时也是一个非常高效的反向代理、负载平衡服务器。在性能上,Nginx占用很少的系统资源,能支持更多的并发连接,达到更高的访问效率;在功能上,Nginx是优秀的代理服务器和负载均衡服务器;在安装配置上,Nginx安装简单、配置灵活。

1.2 正向代理和反向代理

1.2.1正向代理
正向代理类似一个跳板机,代理访问外部资源。
在这里插入图片描述

 作用:
  (1)访问原来无法访问的资源
  (2) 可以做缓存,加速访问资源   
  (3)对客户端访问授权,上网进行认证
  (4)代理可以记录用户访问记录(上网行为管理),对外隐藏用户信息

1.2.2反向代理
反向代理的感觉是,客户端是无感知代理的存在的,反向代理对外都是透明的,访问者者并不知道自己访问的是一个代理。因为客户端不需要任何配置就可以访问。反向代理(Reverse Proxy)实际运行方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个服务器。

在这里插入图片描述

作用:
1,保证内网的安全,可以使用反向代理提供WAF(web application firewall)功能,阻止web攻击
2,负载均衡,通过反向代理服务器来优化网站的负载

1.3 web服务器搭建

1.3.1单机版nginx规划

在这里插入图片描述

2个服务器(反向代理服务器和web服务器)

web服务器:qy142-webserver1      192.168.xxx.11
反向代理服务器:  qy142-nginx1  192.168.xxx.21

1.3.2web后台服务器搭建:

克隆电脑(克隆后的所有操作都在虚拟机里面完成,重启后再使用ssh工具去连接)
centos7:

 1,修改网卡配置文件,修改ipaddr   
   vim /etc/sysconfig/network-scripts/ifcfg-ens33  
            修改第15行
 2,修改主机名称
   vim /etc/hostname   //改名
3,重启系统:reboot
4,使用xshell连接

centos6:

1,修改了三个地方,删除了uuid 和 hwaddr  修改了ipaddr
    vim /etc/sysconfig/network-scripts/ifcfg-eth0
2,修改主机名称
   vim /etc/sysconfig/network
 
3,删除mac地址和网卡对应文件
   rm -rf /etc/udev/rules.d/70-persistent-net.rules
4,修改主机和ip地址对应文件
   vim /etc/hosts
   192.168.52.20 nginx1

查看防火墙状态: service  firewalld status
关闭防火墙: service firewalld stop;
开机自动关闭: systemctl disable firewalld
验证是否装有jdk,是否配置有JAVA_HOME:
   java -version
   echo  $JAVA_HOME

配置 tomcat 启动运行web项目

  复制apache-tomcat-9.0.52.tar.gz到虚拟机下  /root/software
 解压:
  tar -xzvf /root/software/apache-tomcat-9.0.52.tar.gz -C /usr/
进入目录:  
  cd /usr/apache-tomcat-9.0.52/
启动tomcat:
     ./bin/startup.sh   
另外链接一个窗口:
   cd /usr/apache-tomcat-9.0.52/
   查看日志:
        tail -F logs/catalina.out  
     为了更方便的启动和关闭tomcat配置环境变量:
    在tomcat目录下执行pwd:
	/usr/apache-tomcat-9.0.52
      vim /etc/profile
             export TOMCAT_HOME=/usr/apache-tomcat-9.0.52
	          export JAVA_HOME=/usr/java/jdk1.8.0_151
export TOMCAT_HOME=/usr/apache-tomcat-9.0.52
export ClASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$PATH:$JAVA_HOME/bin:$TOMCAT_HOME/bin
    echo $TOMCAT_HOME
    让配置生效:
	   source /etc/profile
  显示结果:
      echo $TOMCAT_HOME   
  在任意目录下都可以启动关闭tomcat
          startup.sh
          shutdown.sh

查看tomcat是否在运行:

ps -ef|grep tomcat|grep -v grep

查看端口号是否被占用:
netstat -ano|grep 8080
测试(确保里面防火墙关闭的):

http://192.168.170.31:8080/

准备web后台项目,并打war包,上传war包到:

/usr/apache-tomcat-9.0.52/webapps/

再次测试:
http://192.168.170.31:8080/ssm_restful_demo_20211210/deptRest/queryById?deptNo=70
http://192.168.170.31:8080/ssm_restful_demo_20211210/deptRest/queryAll?pageNo=1&pageSize=10

1.4 部署安装nginx

1.4.1,克隆服务器nginx1

      修改IP地址
   vim /etc/sysconfig/network-scripts/ifcfg-ens33  
      修改主机名称
 vim /etc/hostname   //改名
      修改子安全系统
            vim /etc/sysconfig/selinux     

1.4.2,安装前的准备
1)确保进行了安装了linux常用必备支持库。
(windows vs编译写好的c和c++,在linux下用g++和gcc编译c)
检查是否安装了g++、gcc。
rpm -qa | grep gcc之后需要出现3个包如下图所示。如果没有出现。需要安装g++、gcc。
检查是否安装gcc-c++
rpm -qa|grep gcc --有的已经安装但版本低,检查时仍然出错
如果有就不需要安装

     yum install -y gcc-c++

2)准备和安装 pcre-8.38.tar.gz。
该文件为正则表达式库。让nginx支持rewrite需要安装这个库(rewrite :和apache等web服务软件一样,rewrite的组要功能是实现RUL地址的重定向。Nginx的rewrite功能需要PCRE软件的支持,即通过perl兼容正则表达式语句进行规则匹配的。)。

    ( PCRE(Perl Compatible Regular Expressions)是一个Perl库,包括 perl 兼容的正则表达式库。 nginx通过ngx_http_rewrite_module模块支持url重写)
      pcre:  http://www.pcre.org/
    pcre安装:
解压pcre-8.12.tar.gz
   tar -xzvf /root/software/pcre-8.44.tar.gz -C /usr  解压
   进入解压后的目录
      cd /usr/pcre-8.44/ 
     配置
      ./configure(./configure是用来检测你的安装平台的目标特征的。比如它会检测你是不是有CC或GCC,并不是需要CC或GCC)
    编译
     make(是用来编译的,它从Makefile中读取指令,然后编译。)
    安装
    make install(用来安装的,它也从Makefile中读取指令,安装到指定的位置。)
    检查是否安装
	 pcre-config --version

3)安装gzip模块需要 zlib 库

    yum install -y zlib-devel

1.4.3,nginx安装

   tar -xzvf /root/software/nginx-1.18.0.tar.gz -C /usr/
  进入目录
  cd /usr/nginx-1.18.0/
   配置
   ./configure
    编译
    #make
    安装
     #  make install
    查看是否安装成功
     ls /usr/local/nginx/   
   进入安装目录
     cd /usr/local/nginx/
    启动:(进入上面红圈安装的目录,在sbin中,有nginx的启动文件)
    ./sbin/nginx 
       (如果报错 error while loading shared libraries: libpcre.so.1: cannot open shared object file: No such file or directory,用如下方法查看缺少)
      ldd $(which /usr/local/nginx/sbin/nginx)
      ldd是list, dynamic, dependencies的缩写, 意思是, 列出动态库依赖关系。

通过列表可以看出,在/lib64下缺少libpcre.so.1我们到这里面去建立软连接
ln -s libpcre.so.0.0.1 libpcre.so.1
测试:(在浏览器访问当前nginx服务器)
http://192.168.170.21/
分析为什么可以访问地址:
vim conf/nginx.conf http->server->(listen 80 location root index)
修改监听端口号:
:36 listen 8088
重启服务:
/usr/local/nginx/sbin/nginx -s reload
再次访问:
http://192.168.170.21:8088/
1.4.4,反向代理配置

让我们可以通过nginx访问webserver1上的tomcat
 vim  /usr/local/nginx/conf/nginx.conf
 在43  3yy->p
 在46下面加入(注意要自己IP):
 location /qy141/ {
    proxy_pass http://192.168.170.31:8080/; 
}
然后再回去启动nginx
     查看nginx进程是否启动: 
      ps -ef|grep nginx |grep -v grep
     存在进程,重启nginx : 
         /usr/local/nginx/sbin/nginx -s reload
    不存在进程,直接启动nginx:
        /usr/local/nginx/sbin/nginx
       测试:
 http://192.168.170.21:8088/    
http://192.168.170.21:8088/qy141/ssm_restful_demo_20211210/deptRest/queryById?deptNo=70
http://192.168.170.21:8088/qy141//ssm_restful_demo_20211210/deptRest/queryAll?pageNo=1&pageSize=10

1.5 配置文件详解:

1.5.1结构:
全局设置
全局设置包含Events和HTTP
HTTP包含upstream和多个Server
Server又包含多个location
1.5.2 重要配置解释:

	main(全局设置,设置的指令将影响其他所有设置)
	server(主机设置,用于指定主机和端口)
	upstream(负载均衡服务器设置,设置一系列的后端服务器)
	location(URL匹配特定位置的设置,用于匹配网页位置)。
	     详细配置:
	          全局配置 :
	user是个主模块指令,指定Nginx Worker进程运行用户以及用户组,默认由nonody账号运行。
	worker_processes是个主模块指令,指定了Nginx要开启的进程数。每个Nginx进程平均耗费10M~12M内存 ,支持5W并发。建议指定和CPU的数量一致即可。

error_log是个主模块指令,用来定义全局错误日志文件。日志输出级别有debug、info、notice、warn、error、 crit可供选择,其中,debug输出日志最为最详细,而crit输出日志最少。
pid是个主模块指令,用来指定进程pid的存储文件位置。
worker_rlimit_nofile用于绑定worker进程和CPU, Linux内核2.4以上可用
   events:
        事件指令是设定Nginx的工作模式及连接数上限
HTTP 服务器配置:
include是个主模块指令,实现对配置文件所包含的文件的设定,可以减少主配置文件的复杂度。类似于Apache中的include方法。
default_type属于HTTP核心模块指令,这里设定默认类型为二进制流,也就是当文件类型未定义时使用这种方式	
log_format是Nginx的HttpLog模块指令,用于指定Nginx日志的输出格式。main为此日志输出格式的名称,可以在下面的access_log指令中引用。
 client_max_body_size用来设置允许客户端请求的最大的单个文件字节数;
 client_header_buffer_size用于指定来自客户端请求头的headerbuffer大小。对于大多数请求,1K的缓冲区大小已经足够,如果自定义了消息头或有更大的Cookie,可以增加缓冲区大小。这里设置为32K;
 large_client_header_buffers用来指定客户端请求中较大的消息头的缓存最大数量和大小, “4”为个数,“128K”为大小,最大缓存量为4个128K;
 sendfile 参数用于开启高效文件传输模式。将tcp_nopush和tcp_nodelay两个指令设置为on用于防止网络阻塞;
 keepalive_timeout 设置客户端连接保持活动的超时时间。在超过这个时间之后,服务器会关闭该连接;
 client_header_timeout设置客户端请求头读取超时时间。如果超过这个时间,客户端还没有发送任何数据,Nginx将返回“Request time out(408)”错误;
 client_body_timeout设置客户端请求主体读取超时时间。如果超过这个时间,客户端还没有发送任何数据,Nginx将返回“Request time out(408)”错误,默认值是60;
 send_timeout指定响应客户端的超时时间。这个超时仅限于两个连接活动之间的时间,如果超过这个时间,客户端没有任何活动,Nginx将会关闭连接。
在安装目录的conf下nginx.conf配置(加入红字部分)

server虚拟主机配置:

server标志定义虚拟主机开始
     listen 用于指定虚拟主机的服务端口
     server_name 用来指定IP地址或者域名,多个域名之间用空格分开
     index 用于设定访问的默认首页地址
     root指令用于指定虚拟主机的网页根目录,这个目录可以是相对路径,也可以是绝对路径。
     Charset用于 设置网页的默认编码格式。
      access_log用来指定此虚拟主机的访问日志存放路径
      main用于指定访问日志的输出格式。
 location URL匹配配置
    URL地址匹配是进行Nginx配置中最灵活的部分。 location支持正则表达式匹配,也支持条件判断匹配,用户可以通过location指令实现Nginx对动、静态网页进行过滤处理。
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ {
    root  /root/baidu;
    expires 30d;
}

通过location指令来对网页URL进行分析处理,所有扩展名以.gif、.jpg、.jpeg、.png、.bmp、.swf结尾的静态文件都交给nginx处理,而expires用来指定静态文件的过期时间,这里是30天。

这段设置是将upload和html下的所有文件都交给nginx来处理,当然,upload和html目录包含在/root/baidu/test目录中。

 location ~ ^/(upload|html)/ {
  root /root/baidu/test;
  expires 30d;
}

location是对此虚拟主机下动态网页的过滤处理,也就是将所有以.jsp为后缀的文件都交给本机的8080端口处理。

location ~ .*.jsp$ {
 index index.html;
 proxy_pass http://localhost:8080;
}
 upstream myapp{ #定义负载均衡设备的Ip及设备状态
      ip_hash;
      server  192.168.23.30:8080;  down;
      server  192.168.23.31:8080;  weight=2;
      server  192.168.23.32:8080; 
      server  192.168.23.33:8080;  backup;
}

完整配置:

#user  nobody;
worker_processes  1;
 
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;
 
#pid        logs/nginx.pid;
 
 
events {
    worker_connections  1024;
}
 
 
http {
    include       mime.types;
    default_type  application/octet-stream;
 
    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';
 
    #access_log  logs/access.log  main;
 
    sendfile        on;
    #tcp_nopush     on;
 
    #keepalive_timeout  0;
    keepalive_timeout  65;
 
    #gzip  on;
upstream my_server {                                                         
 server 192.168.23.112:8080;                                                  
    keepalive 2000;
}
    server {
        listen       80;
        server_name  localhost;
 
        #charset koi8-r;
 
        #access_log  logs/host.access.log  main;
 
        location / {
            root   html;
            index  index.html index.htm;
        }
  location /my/ {
        proxy_pass http://my_server/;
    }
        #error_page  404              /404.html;
 
        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
 
        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}
 
        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}
 
        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }
 
 
    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;
 
    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}
 
 
    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;
 
    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;
 
    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;
 
    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;
 
    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}
 
}

1.6 负载均衡:

1.6.1 概念:
为了保证服务的高可用,服务单元往往都是集群化部署的,当服务消费者消费服务时,负载均衡组件(nginx)获取服务提供者所有实例的注册信息,并通过一定的负载均衡策略(可以自己配置)选择一个服务提供者实例,向该实例进行服务消费,这样就实现了负载均衡。
3.6.2 集群规划:
在这里插入图片描述

具体实现:

  再克隆一台web服务器名字为webserver2:
  1,修改网卡配置文件,修改ipaddr   
   vim /etc/sysconfig/network-scripts/ifcfg-ens33  
 2,修改主机名称
   vim /etc/hostname   //改名
3,重启系统:reboot
4,使用xshell连接

在webserver1进行配置:

  cp -r /usr/apache-tomcat-9.0.52/  /usr/tomcat1
  cp -r /usr/apache-tomcat-9.0.52/  /usr/tomcat2
  cp -r /usr/apache-tomcat-9.0.52/  /usr/tomcat3
  vim /usr/tomcat1/conf/server.xml 
           :22     8001
           :69    8081
 vim /usr/tomcat1/webapps/ssm_restful_demo_20211210/index.jsp
         :3     111111111111111111111111111
 
vim /usr/tomcat2/conf/server.xml 
           :22     8002
           :69    8082
 vim /usr/tomcat2/webapps/ssm_restful_demo_20211210/index.jsp
         :3    222222222222222222222222

vim /usr/tomcat3/conf/server.xml 
               :22     8003
               :69    8083
     vim /usr/tomcat3/webapps/ssm_restful_demo_20211210/index.jsp
             :3    33333333333333333333333333

启动测试:
/usr/tomcat1/bin/startup.sh
/usr/tomcat2/bin/startup.sh
/usr/tomcat3/bin/startup.sh
http://192.168.170.31:8081/ssm_restful_demo_20211210/
http://192.168.170.31:8082/ssm_restful_demo_20211210/
http://192.168.170.31:8083/ssm_restful_demo_20211210/
在webserver2进行配置:

      cp -r /usr/apache-tomcat-9.0.52/  /usr/tomcat4
      cp -r /usr/apache-tomcat-9.0.52/  /usr/tomcat5
      cp -r /usr/apache-tomcat-9.0.52/  /usr/tomcat6
     vim /usr/tomcat4/conf/server.xml 
               :22     8004
               :69    8084
     vim /usr/tomcat4/webapps/ssm_restful_demo_20211210/index.jsp
             :3     444444444444444444
     
    vim /usr/tomcat5/conf/server.xml 
               :22     8005
               :69    8085
     vim /usr/tomcat5/webapps/ssm_restful_demo_20211210/index.jsp
             :3    5555555555555555555555
    
vim /usr/tomcat6/conf/server.xml 
               :22     8006
               :69    8086
     vim /usr/tomcat6/webapps/ssm_restful_demo_20211210/index.jsp
             :3    66666666666666666666666

启动测试:
/usr/tomcat4/bin/startup.sh
/usr/tomcat5/bin/startup.sh
/usr/tomcat6/bin/startup.sh
http://192.168.170.31:8084/ssm_restful_demo_20211210/
http://192.168.170.31:8085/ssm_restful_demo_20211210/
http://192.168.170.31:8086/ssm_restful_demo_20211210/

1.6.3 负载均衡配置:
upstream是Nginx的HTTP Upstream模块,这个模块通过一个简单的调度算法来实现客户端IP到后端服务器的负载均衡。
Nginx的负载均衡模块目前支持5种调度算法,下面进行分别介绍,其中后两项属于第三方的调度方法。
轮询round robin(默认):每个请求按时间顺序逐一分配到不同的后端服务器,如果后端某台服务器宕机,故障系统被自动剔除,使用户访问不受影响;

vim /usr/local/nginx/conf/nginx.conf

server 中配置:

location /qy141lb/ {
proxy_pass http://loadbalanceserver/;
}
在http{}里面和server配置并列位置

  upstream loadbalanceserver {
		      server  192.168.170.31:8081;
		      server  192.168.170.31:8082;
		      server  192.168.170.31:8083;
		      server  192.168.170.32:8084;
		      server  192.168.170.32:8085;
		      server  192.168.170.32:8086;
		    }

myservers不可以使用my_servers
重启nginx服务:
/usr/local/nginx/sbin/nginx -s reload
测试:
http://192.168.170.21:8088/qy141lb/ssm_restful_demo_20211210/
测试后台服务器宕机:
/usr/tomcat5/bin/shutdown.sh
/usr/tomcat1/bin/shutdown.sh
weight:指定轮询权值,Weight值越大,分配到的访问机率越高,主要用于后端每个服务器性能不均的情况下,weight:默认值为1,最大255;

 upstream  myservers {
         server 192.168.170.11:8081 weight=10;
         server 192.168.170.11:8082;
         server 192.168.170.11:8083 weight=20;
         server 192.168.170.12:8084;
         server 192.168.170.12:8085;
         server 192.168.170.12:8086;
    }

ip_hash:每个请求按访问IP的hash结果分配,这样来自同一个IP的访客固定访问一个后端服务器,有效解决了动态网页存在的session共享问题;

  String ip =   request.getRemoteAddr(); // 192.168.31.11  192.168.31.12   192.168.31.13....
    long   600001=ip_hash_method(ip) ; // 192.168.1.12
    long   600002=ip_hash_method(ip) ;//192.168.1.13
     600002%6=2
     600001%6=1
      ......
     余数一定是  0-5     根据余数把请求分配到服务器上
upstream  myservers {
         ip_hash;
         server 192.168.170.11:8081 weight=10;
         server 192.168.170.11:8082;
         server 192.168.170.11:8083 weight=20;
         server 192.168.170.12:8084;
         server 192.168.170.12:8085;
         server 192.168.170.12:8086;
    }

fair(公平):比上面两个更加智能的负载均衡算法。此种算法可以依据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间来分配请求,响应时间短的优先分配。Nginx本身是不支持fair的,如果需要使用这种调度算法,必须下载Nginx的upstream_fair模块;

url_hash:按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,可以进一步提高后端缓存服务器的效率。Nginx本身是不支持url_hash的,如果需要使用这种调度算法,必须安装Nginx 的hash软件包。

request.getRequestURI   ///myapp/nginx_demo_20200721/order?a=1&b=2&c=3 
request.getParameterNames();  // a=1&b=2&c=3   [a,b,c]   所有参数名称   循环
request.getParameter("a")//  1   2   3 获取每个参数的值
request.getRequestUrl    获取IP地址 
http://192.168.23.251/myapp/nginx_demo_20200721/order      缓存到8081

long 600066 =   url_hash_method("http://192.168.23.251/myapp/nginx_demo_20200721/orderList");   10M
600066%6=0;    缓存到服务器tomcat1   10M
....                    缓存到服务器tomcat2   10M     60M
                           缓存到服务器tomcat3   10M
....
 http://192.168.23.251/myapp/nginx_demo_20200721/emp     缓存到8083

在HTTP Upstream模块中,可以通过server指令指定后端服务器的IP地址和端口,同时还可以设定每个后端服务器在负载均衡调度中的状态。常用的状态有:

   down:表示当前的server暂时不参与负载均衡;
   backup:预留的备份机器。当其他所有的非backup机器出现故障或者忙的时候,才会请求backup机器,因此这台机器的压力最轻;
    max_fails:允许请求失败的次数,默认为1。当超过最大次数时,返回proxy_next_upstream 模块定义的错误;
   fail_timeout:在经历了max_fails次失败后,暂停服务的时间,默认10秒。max_fails可以和fail_timeout一起使用。
        
   server 192.168.170.21:8081 max_fails=1 fail_timeout=30s;
   server 192.168.170.21:8082;

启动反向代理服务器和web服务器,测试配置结果