Nginx反向代理及负载均衡

nginx和gateway的区别

  • 相同点
    ○ 它们都可以用于反向代理和负载均衡
  • 不同点
    • 设计目的:
      ■ nginx主要设计目的是作为web服务器和反向代理服务器使用
      ■ gateway的主要设计目的是用于构建和管理微服务的API网关
    • 功能不同
      ■ Nginx提供了HTTP/HTTPS等协议的支持,包括静态资源的请求、动态网页的处理、反向代理、负载均衡、HTTP缓存等功能
      ■ Gateway提供了路由、负载均衡、API转换、认证授权等管理微服务的功能
    • 使用场景
      ■ Nginx的使用场景主要集中在Web服务器、API服务器、CDN等领域
      ■ Gateway的使用场景主要集中在微服务架构、云原生应用等领域
    • 配置方式
      ■ Nginx的配置文件主要基于纯文本格式,配置灵活但有一定门槛
      ■ Gateway则更多地采用了视觉化的配置方式,简化了配置过程

两张图体会为何要用nginx

最开始项目上线时并发量小,用户使用的少,所以在低并发的情况下,一个jar包启动应用就够了,然后内部tomcat返回内容给用户。
Nginx反向代理及负载均衡_第1张图片
但是慢慢的,平台用户量越来越大,并发量也随之增高,一台服务器已经满足不了我们的需求了
Nginx反向代理及负载均衡_第2张图片
于是我们横向扩展,又增加了服务器。这个时候几个项目启动在不同的服务器上,用户要访问,就需要增加一个代理服务器了,通过代理服务器来帮我们转发和处理请求。
Nginx反向代理及负载均衡_第3张图片
我们希望这个代理服务器可以帮助我们接收用户的请求,然后将用户的请求按照规则帮我们转发到不同的服务器节点之上。这个过程用户是无感知的,用户并不知道是哪个服务器返回的结果,我们还希望他可以按照服务器的性能提供不同的权重选择。保证最佳体验!所以我们使用了Nginx。

nginx作用

  • 代理功能

    • 正向代理
      正向代理是指代理服务器代表客户端请求目标服务器获取资源,隐藏客户端真实IP地址,使目标服务器无法获取请求的客户端身份,正向代理情况下,代理服务器充当了目标服务器接受请求的中间人。
      Nginx反向代理及负载均衡_第4张图片

    正向代理的请求的流转过程:

    1. 客户端向代理服务器发起请求,请求中包含了需要访问的目标服务器的地址和端口号,但是不包含客户端的真实IP地址。
    2. 代理服务器接收到请求后,代表客户端向目标服务器发起请求。这一步中,代理服务器的IP地址会被目标服务器记录为请求的IP地址,而请求中并不包含客户端的真实IP地址。
    3. 目标服务器将响应返回给代理服务器,响应中包含了客户端需要的资源或者其他信息。
    4. 代理服务器接收到响应后,将响应返回给客户端。客户端并不知道响应是从代理服务器发出的。
    • 反向代理
      反向代理是指代理服务器代表目标服务器接受客户端的请求,隐藏服务器的真实IP地址,使客户端无法直接得知访问的目标服务器身份。在反向代理的情况下,代理服务器充当了目标服务器接受请求的中间人。
      Nginx反向代理及负载均衡_第5张图片
      反向代理的请求流转过程:
  1. 客户端向反向代理服务器发起请求,请求中包含了需要访问的资源的地址和端口号,以及一些HTTP头信息,如HOST,Cookie等等。
  2. 反向代理服务器收到请求信息后,将请求转发到后端服务器群组中的一台或多台目标服务器上。
  3. 后端服务器接收到请求后,处理请求并产生响应,返回给反向代理服务器。
  4. 反向代理服务器接收到后端服务器的响应后,对响应头信息和内容进行处理,然后将响应返回给客户端。

整个过程中,外部流量的访问请求由反向代理服务器接收后端的服务器业务逻辑都被隐藏反向代理服务器后面,从而保证了服务器的安全性。在请求发送到后端服务器时,反向代理服务器会根据一定的负载均衡策略,将请求分配到不同的后端服务器上,从而达到了负载均衡目的。

负载均衡策略

nginx提供2种负载均衡策略:

  • 内置策略
    • 加权轮询
    • IP hash
  • 扩展策略
    • 扩展策略相当于自定义,天马行空,只有你想不到的没有他做不到的

动静分离

在软件开发中,有些请求时需要后台处理的,有些请求是不需要经过后台处理的,例如css、html、jpg、js等,这些不需要经过后台处理的文件称为静态文件。动静资源做好拆分后,我们就可以根据静态资源的特点将其做缓存操作,提高资源响应速度。
Nginx反向代理及负载均衡_第6张图片

nginx安装

  • windows环境
  1. 下载
    http://nginx.org/en/download.html 下载稳定版本。
    以nginx/Windows-1.16.1为例,直接下载 nginx-1.16.1.zip。
    下载后解压,解压后如下:
    Nginx反向代理及负载均衡_第7张图片

  2. 启动nginx
    有很多种方法启动nginx
    (1)直接双击nginx.exe,双击后一个黑色的弹窗一闪而过
    (2)打开cmd命令窗口,切换到nginx解压目录下,输入命令 nginx.exe ,回车即可

  3. 检查nginx是否成功启动
    直接在浏览器地址栏输入网址 http://localhost:80 回车,出现以下页面说明启动成功!
    Nginx反向代理及负载均衡_第8张图片
    nginx的配置文件是conf目录下的nginx.conf,默认配置的nginx监听的端口为80,如果80端口被占用可以修改为未被占用的端口即可。

  4. 关闭nginx
    如果使用cmd命令窗口启动nginx, 关闭cmd窗口是不能结束nginx进程的,可使用两种方法关闭nginx
    (1)输入nginx命令 nginx -s stop(快速停止nginx) 或 nginx -s quit(完整有序的停止nginx)
    (2)使用taskkill taskkill /f /t /im nginx.exe
    taskkill是用来终止进程的,
    /f是强制终止 .
    /t终止指定的进程和任何由此启动的子进程。
    /im示指定的进程名称 .

  • Linux环境
  1. 安装gcc
    安装 nginx 需要先将官网下载的源码进行编译,编译依赖 gcc 环境,如果没有 gcc 环境,则需要安装:
yum install gcc-c++
  1. PCRE pcre-devel 安装
    PCRE(Perl Compatible Regular Expressions) 是一个Perl库,包括 perl 兼容的正则表达式库。nginx 的 http 模块使用 pcre 来解析正则表达式,所以需要在 linux 上安装 pcre 库,pcre-devel 是使用 pcre 开发的一个二次开发库。nginx也需要此库。命令:
yum install -y pcre pcre-devel
  1. zlib安装
    zlib 库提供了很多种压缩和解压缩的方式, nginx 使用 zlib 对 http 包的内容进行 gzip ,所以需要在 Centos 上安装 zlib 库。
yum install -y zlib zlib-devel
  1. OpenSSL安装
    OpenSSL 是一个强大的安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理功能及 SSL 协议,并提供丰富的应用程序供测试或其它目的使用。
    nginx 不仅支持 http 协议,还支持 https(即在ssl协议上传输http),所以需要在 Centos 安装 OpenSSL 库。
yum install -y openssl openssl-devel
  1. 下载安装包
    手动下载.tar.gz安装包,地址:https://nginx.org/en/download.html
    Nginx反向代理及负载均衡_第9张图片
    下载完毕上传到服务器上 /root

  2. 解压

tar -zxvf nginx-1.18.0.tar.gz
cd nginx-1.18.0

Nginx反向代理及负载均衡_第10张图片

  1. 配置
    使用默认配置,在nginx根目录下执行
./configure
make
make install

如果报错,需要在第一个命令中加入 ./configure --prefix=/usr/local/nginx
查找安装路径: whereis nginx
在这里插入图片描述
如何启动

[root@localhost nginx-1.20.2]# cd /usr/local/nginx/
[root@localhost nginx]# ls
conf  html  logs  sbin
[root@localhost nginx]# cd sbin/
[root@localhost sbin]# ls
nginx  nginx.old
[root@localhost sbin]# ./nginx

nginx常用命令

cd /usr/local/nginx/sbin/
./nginx  启动
./nginx -s stop  停止
./nginx -s quit  安全退出
./nginx -s reload  重新加载配置文件
ps aux|grep nginx  查看nginx进程

启动成功访问 服务器ip:80
Nginx反向代理及负载均衡_第11张图片
如果连接不上,检查阿里云安全组是否开放端口,或者服务器防火墙是否开放端口!
相关命令:

# 开启
service firewalld start
# 重启
service firewalld restart
# 关闭
service firewalld stop
# 查看防火墙规则
firewall-cmd --list-all
# 查询端口是否开放
firewall-cmd --query-port=8080/tcp
# 开放80端口
firewall-cmd --permanent --add-port=80/tcp
# 移除端口
firewall-cmd --permanent --remove-port=8080/tcp
#重启防火墙(修改配置后要重启防火墙)
firewall-cmd --reload
# 参数解释
1、firwall-cmd:是Linux提供的操作firewall的一个工具;
2--permanent:表示设置为持久;
3--add-port:标识添加的端口;

nginx配置详解

默认的nginx配置文件nginx.conf内容如下:

##### 全局块
#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块
events {
    worker_connections  1024;
}

##### http块
http {
    ###### 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;

    ##### server块
    server {
        ##### server的全局块
        listen       80;
        server_name  localhost;
        #charset koi8-r;
        #access_log  logs/host.access.log  main;

        ##### location块
        location / {
            root   html;
            index  index.html index.htm;
        }

        #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. 全局块:
    配置影响nginx全局的指令。一般有运行nginx服务器的用户组,nginx进程pid存放路径,日志存放路径,配置文件引入,允许生成worker process数等
  2. events块:配置影响nginx服务器或与用户的网络连接。每个进程的最大连接数,选取哪种时间驱动模型处理连接请求,是否允许同时接受多个网络连接,开启多个网络连接序列化等
  3. http块:可以嵌套多个server块,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置。如文件引入,mime-type定义,日志自定义,是否使用sendfile传输文件,连接超时时间,但链接请求数等
  4. server块:配置虚拟主机的相关参数,一个http中可以有多个server块
  5. location块:配置请求的路由,及各种页面的处理情况
    示例
########### 每个指令必须有分号结束。#################
#配置用户或者组,默认为nobody nobody。
#user administrator administrators;
#允许生成的进程数,默认为1
#worker_processes 2;  
#指定nginx进程运行文件存放地址
#pid /nginx/pid/nginx.pid;   
#制定日志路径,级别。这个设置可以放入全局块,http块,server块
#日志级别依次为:debug|info|notice|warn|error|crit|alert|emerg
error_log log/error.log debug;  
events {
     #设置网路连接序列化,防止惊群现象发生,默认为on
    accept_mutex on;  
    #设置一个进程是否同时接受多个网络连接,默认为off
    multi_accept on;  
    #事件驱动模型,select|poll|kqueue|epoll|resig|/dev/poll|eventport
    #use epoll;      
    #最大连接数,默认为512
    worker_connections  1024;   
}
http {
    #文件扩展名与文件类型映射表
    include       mime.types;   
    #指定默认文件类型,默认为text/plain
    default_type  application/octet-stream;
    #取消服务日志  
    #access_log off;   
    #下面是日志的自定义格式
    log_format myFormat '$remote_addr–$remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for';
    #combined为日志格式的默认值
    access_log log/access.log myFormat;  
    #允许sendfile方式传输文件,默认为off,可以在http块,server块,location块。
    sendfile on;   
    #每个进程每次调用传输数量不能大于设定的值,默认为0,即不设上限。
    sendfile_max_chunk 100k;  
    #连接超时时间,默认为75s,可以在http,server,location块。
    keepalive_timeout 65;  

    upstream mysvr {   
      server 127.0.0.1:7878;
      server 192.168.10.121:3333 backup;  #热备
    }
     #指定错误页
    error_page 404 https://www.baidu.com;
    server {
        #单连接请求上限次数。
        keepalive_requests 120; 
        listen       4545;   #监听端口
        server_name  127.0.0.1;   #监听地址       
        location  ~*^.+$ {   #请求的url过滤,正则匹配,~为区分大小写,~*为不区分大小写。
           #root path;  #根目录
           #index vv.txt;  #设置默认页
           proxy_pass  http://mysvr;  #请求转向mysvr 定义的服务器列表
           deny 127.0.0.1;  #拒绝的ip
           allow 172.18.5.54; #允许的ip           
        } 
    }
}

配置nginx需要注意以下几点:
1、几个常见配置项
● $remote_addr 与 $http_x_forwarded_for 用以记录客户端的ip地址;
● $remote_user :用来记录客户端用户名称;
● $time_local : 用来记录访问时间与时区;
● $request : 用来记录请求的url与http协议;
● $status : 用来记录请求状态;成功是200;
● $body_bytes_s ent :记录发送给客户端文件主体内容大小;
● $http_referer :用来记录从那个页面链接访问过来的;
● $http_user_agent :记录客户端浏览器的相关信息;
2、惊群现象:
一个网络连接的到来,多个睡眠进程同时被叫醒,但只有一个进程能获得链接,这样会影响系统性能
3、每个指令必须有分号作为结束

以下是一个更多转发的server块的示例:

server {
        listen       80;
        listen       [::]:80;
        server_name  _;
        root         /usr/share/nginx/html;
        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;
        error_page 404 /404.html;
        location = /404.html {
        }
        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        }
       location ^~ /iotsaas/ {
                  rewrite  ^/iotsaas/(.*)$ /$1 break;
                  proxy_pass http://localhost:8097;
                  client_max_body_size    100m;
           }
           location ^~ /iotpaas/ {
                  rewrite  ^/iotpaas/(.*)$ /$1 break;
                  proxy_pass http://localhost:8086;
           }
       location ^~ /hwnfctest/ {
                  rewrite  ^/hwnfctest/(.*)$ /$1 break;
                  proxy_pass http://localhost:32018;
           }
       location ^~ /urumqi_apartment/ {
                  rewrite  ^/urumqi_apartment/(.*)$ /$1 break;
                  proxy_pass http://localhost:20010;
           }
    }

下面是几种负载均衡的配置示例
轮询模式

upstream中如果按以下这样配置则是默认的轮询效果

upstream mysvr { 
 server 127.0.0.1:7878;
 server 192.168.10.121:3333 backup; #热备
 }

权重模式
如果要使用权重模式,那么是这样配置

upstream webservers{
 server 192.168.9.134:8081 weight=8;
 server 192.168.9.134:8082 weight=2;
 }

ip_hash
每个请求按访问IP的hash结果进行分配,这样每个访客就可以固定访问一个后端服务,一定程度上可以解决session共享问题;

upstream tomcats {
 ip_hash;
 server 192.168.93.129:8080;
 server 192.168.93.130:8080;
 server 192.168.93.131:8080;
}

在ip_hash中如果要停掉某一台服务器,不能直接删除,应该使用down

upstream tomcats {
 ip_hash;
 server 192.168.93.129:8080;
 server 192.168.93.130:8080 down;
 server 192.168.93.131:8080;
}

fair(第三方)
按后端服务器的响应时间来分配请求,响应时间短的将会被优先分配

upstream webservers{
 server 192.168.9.134:8081;
 server 192.168.9.134:8082;
 fair;
}

url_hash
按访问URL的hash结果分配。这样相同的url会被分配到同一个节点,主要为了提高缓存命中率。比如,为了提高访问性能,服务端有大量数据或者资源文件需要被缓存。使用这种策略,可以节省缓存空间,提高缓存命中率

upstream webservers{
 hash &request_uri;
 server 192.168.9.134:8081;
 server 192.168.9.134:8082;
}

least_conn
按节点连接数分配,把请求优先分配给连接数少的节点。该策略主要为了解决,各个节点请求处理时间长短不一造成某些节点超负荷的情况。

upstream webservers{
 least_conn;
 server 192.168.9.134:8081;
 server 192.168.9.134:8082;
}

你可能感兴趣的:(nginx,负载均衡,java)