一文搞定Nginx

Posted 活跃的咸鱼

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一文搞定Nginx相关的知识,希望对你有一定的参考价值。

nginx 简介

Nginx (“engine x”) 是一个高性能的 HTTP 和反向代理服务器,特点是占有内存少,并发能力强,事实上 nginx 的并发能力确实在同类型的网页服务器中表现较好.

Nginx 作为 web 服务器

Nginx 可以作为静态页面的 web 服务器,同时还支持 CGI 协议的动态语言,比如 perl、php等。但是不支持 java。Java 程序只能通过与 tomcat 配合完成。Nginx 专为性能优化而开发,性能是其最重要的考量,实现上非常注重效率 ,能经受高负载的考验,有报告表明能支持高达 50,000 个并发连接数。

Nginx常用功能

1.HTTP代理

代理又分为正向代理和反向代理

正向代理:如果把局域网外的 Internet 想象成一个巨大的资源库,则局域网中的客户端要访问 Internet,则需要通过代理服务器来访问,这种代理服务就称为正向代理。

如果我们需要访问国外的网站我们并不能直接访问,我们可以通过vpn或者中间有一个代理服务器帮我们访问,这就是正向代理。

在这里插入图片描述

反向代理:其实客户端对代理是无感知的,因为客户端不需要任何配置就可以访问,我们只需要将请求发送到反向代理服务器,由反向代理服务器去选择目标服务器获取数据后,在返回给客户端,此时反向代理服务器和目标服务器对外就是一个服务器,暴露的是代理服务器地址,隐藏了真实服务器 IP 地址。

在这里插入图片描述

2.负载均衡

传统的访问模式:客户端发送多个请求到服务器,服务器处理请求,有一些可能要与数据库进行交互,服务器处理完毕后,再将结果返回给客户端。 这种架构模式对于早期的系统相对单一,并发请求相对较少的情况下是比较适合的,成本也低。但是随着信息数量的不断增长,访问量和数据量的飞速增长,以及系统业务的复杂度增加,这种架构会造成服务器相应客户端的请求日益缓慢,并发量特别大的时候,还容易造成服务器直接崩溃。很明显这是由于服务器性能的瓶颈造成的问题,那么如何解决这种情况呢?

1.我们首先想到的可能是升级服务器的配置,比如提高 CPU 执行频率,加大内存等提高机器的物理性能来解决此问题,但是我们知道摩尔定律的日益失效,硬件的性能提升已经不能满足日益提升的需求了。最明显的一个例子,天猫双十一当天,某个热销商品的瞬时访问量是极其庞大的,那么类似上面的系统架构,将机器都增加到现有的顶级物理配置,都是不能够满足需求的。那么怎么办呢?

2.上面的分析我们去掉了增加服务器物理配置来解决问题的办法,也就是说纵向解决问题的办法行不通了,那么横向增加服务器的数量呢?这时候集群的概念产生了,单个服务器解决不了,我们增加服务器的数量,然后将请求分发到各个服务器上,将原先请求集中到单个服务器上的情况改为将请求分发到多个服务器上,将负载分发到不同的服务器,也就是我们所说的负载均衡
在这里插入图片描述

3.动静分离

为了加快网站的解析速度,可以把动态页面和静态页面由不同的服务器来解析,加快解析速度。降低原来单个服务器的压力。

这里的动静是指动态请求和静态请求

在这里插入图片描述

nginx 安装

第一步:下载nginx压缩包

在这里可以去 nginx官网 下载
也可以直接使用wget命令下载,指令如下所示(请根据自己的需求进行下载):

wget -c https://nginx.org/download/nginx-1.18.1.tar.gz

这里推荐去官网下载压缩包然后上传到Linux系统上面。

第二步:配置nginx安装所需的环境

1.安装gcc nginx 需要先将官网下载的源码进行编译,编译依赖 gcc 环境。安装指令如下:

yum install gcc-c++

2.安装PCRE pcre-devel
Nginx的Rewrite模块和HTTP核心模块会使用到PCRE正则表达式语法。这里需要安装两个安装包pcre和pcre-devel。第一个安装包提供编译版本的库,而第二个提供开发阶段的头文件和编译项目的源代码。安装指令如下:

yum install -y pcre pcre-devel

3.安装zlib

zlib库提供了开发人员的压缩算法,在Nginx的各种模块中需要使用gzip压缩。安装指令如下:

yum install -y zlib zlib-devel

4.安装Open SSL

nginx不仅支持 http协议,还支持 https(即在 ssl 协议上传输 http),如果使用了 https,需要安装 OpenSSL 库。安装指令如下:

yum install -y openssl openssl-devel

第三步:解压nginx压缩包并安装

将压缩包进行解压,解压指令如下:

tar -zxvf nginx-1.18.1.tar.gz

解压之后,进入解压文件,即cd nginx-1.18.1。
然后进行配置,推荐使用默认配置,直接./configure就好了。

第四步:编译安装nginx

首先在当前目录(/usr/local/nginx-1.18.1)进行编译。输入make即可

make

然后回车,如果编译出错,请检查是否前面的4个安装都没有问题。
编译成功之后,就可以安装了,输入以下指令:

make install

正常情况下安装以上步骤便可以安装成功啦

第五步:启动nginx

进入/usr/local/nginx/sbin目录,输入./nginx即可启动nginx

./nginx

在这里插入图片描述

nginx 常用的命令和配置文件

常用命令

1.启动命令

cd /usr/local/nginx/sbin

./nginx 

2.关闭nginx

./nginx -s quit  或者 ./nginx -s stop

3.重启nginx

./nginx -s reload

4.查看nginx进程

ps aux|grep nginx

设置nginx开机启动,只需在rc.local增加启动代码即可。

vim /etc/rc.local

#然后在底部增加
/usr/local/nginx/sbin/nginx

配置文件

配置文件的位置默认在

/usr/local/nginx/conf/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 {
    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;

    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        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;
    #    }
    #}

}

nginx 文件结构

...              #全局块

events {         #events块
   ...
}

http      #http块
{
    ...   #http全局块
    server        #server块
    { 
        ...       #server全局块
        location [PATTERN]   #location块
        {
            ...
        }
        location [PATTERN] 
        {
            ...
        }
    }
    server
    {
      ...
    }
    ...     #http全局块
}

1、全局块:配置影响nginx全局的指令。一般有运行nginx服务器的用户组,nginx进程pid存放路径,日志存放路径,配置文件引入,允许生成worker process数等。

2、events块:配置影响nginx服务器或与用户的网络连接。有每个进程的最大连接数,选取哪种事件驱动模型处理连接请求,是否允许同时接受多个网路连接,开启多个网络连接序列化等。

3、http块:可以嵌套多个server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置。如文件引入,mime-type定义,日志自定义,是否使用sendfile传输文件,连接超时时间,单连接请求数等。

4、server块:配置虚拟主机的相关参数,一个http中可以有多个server。

5、location块:配置请求的路由,以及各种页面的处理情况。

下面是nginx的基本配置,

########### 每个指令必须有分号结束。#################

#配置用户或者组,默认为nobody 
#user administrator administrators;nobody。
#允许生成的进程数,默认为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'; #自定义格式
    access_log log/access.log myFormat;  #combined为日志格式的默认值
     #允许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;   #监听地址   
        #请求的url过滤,正则匹配,~为区分大小写,~*为不区分大小写。    
        location  ~*^.+$ {       
           #root path;  #根目录
           #index vv.txt;  #设置默认页
           #请求转向mysvr 定义的服务器列表  
           proxy_pass  http://mysvr; 
           #拒绝的ip
           deny 127.0.0.1; 
           #允许的ip      
           allow 172.18.5.54;       
        } 
    }
}

上面是nginx的基本配置,需要注意的有以下几点:

1、几个常见配置项:

  1. remote_addr 与 http_x_forwarded_for 用以记录客户端的ip地址;
  2. remote_user :用来记录客户端用户名称;
  3. time_local : 用来记录访问时间与时区;
  4. request : 用来记录请求的url与http协议;
  5. status : 用来记录请求状态;成功是200;
  6. body_bytes_s ent :记录发送给客户端文件主体内容大小;
  7. http_referer :用来记录从那个页面链接访问过来的;
  8. http_user_agent :记录客户端浏览器的相关信息;

2、惊群现象:一个网路连接到来,多个睡眠的进程被同时叫醒,但只有一个进程能获得链接,这样会影响系统性能。

3、每个指令必须有分号结束。

Nginx 反向代理与负载均衡详解

Nginx 代理服务的配置说明

1、设置 404 页面导向地址

error_page 404 https://www.runnob.com; #错误页
 #如果被代理服务器返回的状态码为400或者大于400,
 #设置的error_page配置起作用。默认为off。
proxy_intercept_errors on;   

2、如果我们的代理只允许接受get,post请求方法的一种

proxy_method get;    #支持客户端的请求方法。post/get;

3、设置支持的http协议版本

proxy_http_version 1.0 ; #Nginx服务器提供代理服务的http协议版本1.0,1.1,默认设置为1.0版本

4、如果你的nginx服务器给2台web服务器做代理,负载均衡算法采用轮询,那么当你的一台机器web程序iis关闭,也就是说web不能访问,那么nginx服务器分发请求还是会给这台不能访问的web服务器,如果这里的响应连接时间过长,就会导致客户端的页面一直在等待响应,对用户来说体验就打打折扣,这里我们怎么避免这样的情况发生呢。这里我配张图来说明下问题。
在这里插入图片描述
如果负载均衡中其中web2发生这样的情况,nginx首先会去web1请求,但是nginx在配置不当的情况下会继续分发请求道web2,然后等待web2响应,直到我们的响应时间超时,才会把请求重新分发给web1,这里的响应时间如果过长,用户等待的时间就会越长。

下面的配置是解决方案之一。

 #nginx服务器与被代理的服务器建立连接的超时时间,默认60秒
 proxy_connect_timeout 1;  
 #nginx服务器想被代理服务器组发出read请求后,等待响应的超时间,默认为60秒。
 proxy_read_timeout 1;
#nginx服务器想被代理服务器组发出write请求后,等待响应的超时间,默认为60秒。
proxy_send_timeout 1; 
#客户端断网时,nginx服务器是否终端对被代理服务器的请求。默认为off。
proxy_ignore_client_abort on;  

5、如果使用upstream指令配置啦一组服务器作为被代理服务器,服务器中的访问算法遵循配置的负载均衡规则,同时可以使用该指令配置在发生哪些异常情况时,将请求顺次交由下一组服务器处理。

 #反向代理upstream中设置的服务器组,出现故障时,被代理服务器返回的状态值。
proxy_next_upstream timeout; 

状态值可以是:

error|timeout|invalid_header|http_500|http_502|http_503|http_504|http_404|off

error: 建立连接或向被代理的服务器发送请求或读取响应信息时服务器生错误。
timeout: 建立连接,想被代理服务器发送请求或读取响应信息时服务器生超时。
invalid_header: 被代理服务器返回的响应头异常。
off: 无法将请求分发给被代理的服务器。
http_400,…: 被代理服务器返回的状态码为400,500,502,等。

6、如果你想通过http获取客户的真是ip而不是获取代理服务器的ip地址,那么要做如下的设置。

1.只要用户在浏览器中访问的域名绑定了 VIP VIP 下面有RS;则就用$host;host是访问URL中的域名和端口 www.taobao.com:80

proxy_set_header Host $host; 

2.把源IP 【$remote_addr,建立HTTP连接header里面的信息】赋值给X-Real-IP;这样在代码中 $X-Real-IP来获取 源IP

proxy_set_header X-Real-IP $remote_addr;  

3.在nginx 作为代理服务器时,设置的IP列表,会把经过的机器ip,代理机器ip都记录下来,用 【,】隔开;代码中用 echo $x-forwarded-for |awk -F, ‘{print $1}’ 来作为源IP

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

7、下面是一个关于代理配置的配置文件部分,仅供参考。

include       mime.types;   #文件扩展名与文件类型映射表
default_type  application/octet-stream; #默认文件类型,默认为text/plain
#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'; #自定义格式
access_log log/access.log myFormat;  #combined为日志格式的默认值
sendfile on;   #允许sendfile方式传输文件,默认为off,可以在http块,server块,location块。
sendfile_max_chunk 100k;  #每个进程每次调用传输数量不能大于设定的值,默认为0,即不设上限。
keepalive_timeout 65;  #连接超时时间,默认为75s,可以在http,server,location块。
proxy_connect_timeout 1;   #nginx服务器与被代理的服务器建立连接的超时时间,默认60秒
proxy_read_timeout 1; #nginx服务器想被代理服务器组发出read请求后,等待响应的超时间,默认为60秒。
proxy_send_timeout 1; #nginx服务器想被代理服务器组发出write请求后,等待响应的超时间,默认为60秒。
proxy_http_version 1.0 ; #Nginx服务器提供代理服务的http协议版本1.0,1.1,默认设置为1.0版本。
#proxy_method get;    #支持客户端的请求方法。post/get;
proxy_ignore_client_abort on;  #客户端断网时,nginx服务器是否终端对被代理服务器的请求。默认为off。
proxy_ignore_headers "Expires" "Set-Cookie";  #Nginx服务器不处理设置的http相应投中的头域,这里空格隔开可以设置多个。
proxy_intercept_errors on;    #如果被代理服务器返回的状态码为400或者大于400,设置的error_page配置起作用。默认为off。
proxy_headers_hash_max_size 1024; #存放http报文头的哈希表容量上限,默认为512个字符。
proxy_headers_hash_bucket_size 128; #nginx服务器申请存放http报文头的哈希表容量大小。默认为64个字符。
proxy_next_upstream timeout;  #反向代理upstream中设置的服务器组,出现故障时,被代理服务器返回的状态值。error|timeout|invalid_header|http_500|http_502|http_503|http_504|http_404|off
#proxy_ssl_session_reuse on; 默认为on,如果我们在错误日志中发现“SSL3_GET_FINSHED:digest check failed”的情况时,可以将该指令设置为off。

Nginx 负载均衡详解

在文章前面我们已经说过Nginx 配置的详解,当中nginx有很多负载均衡算法。下面我们来具体看看,首先给大家说下upstream这个配置的,这个配置是写一组被代理的服务器地址,然后配置负载均衡的算法。这里的被代理服务器地址有2中写法。

upstream mysvr { 
    server 192.168.10.121:3333;
    server 192.168.10.122:3333;
}
server {
    ....
    location  ~*^.+$ {         
        proxy_pass  http://mysvr;  #请求转向mysvr 定义的服务器列表         
    }
}

然后,就来点实战的东西。

1、热备:如果你有2台服务器,当一台服务器发生事故时,才启用第二台服务器给提供服务。服务器处理请求的顺序:AAAAAA突然A挂啦,BBBBBBBBBBBBBB…

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

2、轮询:nginx默认就是轮询其权重都默认为1,服务器处理请求的顺序:ABABABABAB…

upstream mysvr { 
    server 127.0.0.1:7878;
    server 192.168.10.121:3333;       
}

3、加权轮询:跟据配置的权重的大小而分发给不同服务器不同数量的请求。如果不设置,则默认为1。下面服务器的请求顺序为:ABBABBABBABBABB…

upstream mysvr { 
    server 127.0.0.1:7878 weight=1;
    server 192.168.10.121:3333 weight=2;
}

4、ip_hash:nginx会让相同的客户端ip请求相同的服务器。

upstream mysvr { 
    server 127.0.0.1:7878; 
    server 192.168.10.121:3333;
    ip_hash;
}

关于nginx负载均衡配置的几个状态参数讲解。

down,表示当前的server暂时不参与负载均衡。

backup,预留的备份机器。当其他所有的非backup机器出现故障或者忙的时候,才会请求backup机器,因此这台机器的压力最轻。

max_fails,允许请求失败的次数,默认为1。当超过最大次数时,返回proxy_next_upstream 模块定义的错误。

fail_timeout,在经历了max_fails次失败后,暂停服务的时间。max_fails可以和fail_timeout一起使用。

upstream mysvr { 
    server 127.0.0.1:7878 weight=2 max_fails=2 fail_timeout=2;
    server 192.168.10.121:3333 weight=1 max_fails=2 fail_timeout=1;    
}

nginx 配置实例-反向代理

案例一

1、实现效果

打开浏览器,在浏览器地址栏输入地址 www.123.com,跳转到 liunx 系统 tomcat 主页面中
在这里插入图片描述

2、准备工作

1)在 liunx 系统安装 tomcat,使用默认端口 8080,tomcat 安装文件放到 liunx 系统中,解压
在这里插入图片描述
进入 tomcat 的 bin 目录中,./startup.sh 启动 tomcat 服务器
在这里插入图片描述
2)对外开放端口
如果防火墙打开了的需要对外开放端口命令如下

  firewall-cmd --add-port=8080/tcp --permanent
  firewall-cmd –reload

查看已经开放的端口号

firewall-cmd --list-all

3)在 windows 系统中通过浏览器访问 tomcat 服务器
在这里插入图片描述
3、访问过程的分析
在这里插入图片描述
4、具体配置
第一步 在 windows 系统的 host 文件进行域名和 ip 对应关系的配置
在这里插入图片描述
在这里插入图片描述

第二步 在 nginx 进行请求转发的配置(反向代理配置)

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

在HTTP下把server_name改成IP地址,然后加上proxy_pass http://127.0.0.1:8080;
在这里插入图片描述
5、最终测试
在这里插入图片描述
案列二

1、实现效果:使用 nginx 反向代理,根据访问的路径跳转到不同端口的服务中nginx 监听端口为 9001,
访问 http://127.0.0.1:9001/edu/ 直接跳转到 127.0.0.1:8081
访问 http://127.0.0.1:9001/vod/ 直接跳转到 127.0.0.1:8082

2、准备工作
(1)准备两个 tomcat 服务器,一个 8080 端口,一个 8081 端口
我们把刚刚解压的tomcat复制一份

 cp -r  apache-tomcat-9.0.48 tomcat8081

然后进入到配置文件下把有关的端口号都修改一下然后启动
在这里插入图片描述
在这里插入图片描述
现在两个tomcat已经启动完成
在这里插入图片描述
(2)创建文件夹和测试页面

我们分别在两个tomcat下的webapps下面创建一个文件夹并放入一个html文件
在这里插入图片描述
在这里插入图片描述
访问两个页面
在这里插入图片描述

3、具体配置
(1)找到 nginx 配置文件,进行反向代理配,在配置文件的http下配置如下
在这里插入图片描述
location 指令说明
该指令用于匹配 URL。
语法如下:
在这里插入图片描述
1、= :用于不含正则表达式的 uri 前,要求请求字符串与 uri 严格匹配,如果匹配
成功,就停止继续向下搜索并立即处理该请求。
2、~:用于表示 uri 包含正则表达式,并且区分大小写。
3、~ * :用于表示 uri 包含正则表达式,并且不区分大小写。
4、^~:用于不含正则表达式的 uri 前,要求 Nginx 服务器找到标识 uri 和请求字符串匹配度最高的 location 后,立即使用此 location 处理请求,而不再使用 location 块中的正则 uri 和请求字符串做匹配。

注意:如果 uri 包含正则表达式,则必须要有 ~ 或者 ~* 标识。

4、最终测试结果
在这里插入图片描述
在这里插入图片描述

nginx 配置实例-负载均衡

1、实现效果

(1)浏览器地址栏输入地址 http://192.168.17.129/edu/a.html,负载均衡效果,平均 8080到 8081 端口中

2、准备工作

(1)准备两台 tomcat 服务器,一台 8080,一台 8081(我们上面已经准备好了)
(2)在两台 tomcat 里面 webapps 目录中,创建名称是 edu 文件夹,在 edu 文件夹中创建页面 a.html,用于测试,我们只需要在8080端口的Tomcat的webapps下面创建一个edu文件夹和a.html文件既可。
在这里插入图片描述

3、在 nginx 的配置文件中进行负载均衡的配置
在http下面加入

 #gzip  on;
    upstream myserver {
    server 192.168.1.108:8080;
    server 192.168.1.108:8081;
    }

server中修改为如下

 server {
        listen       80;
        server_name  192.168.1.108;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            proxy_pass  http://myserver;
            root   html;
            index  index.html index.htm;
        }

4、测试结果如下

负载均衡配置完成,请求会平均分配到8080和8081中去
在这里插入图片描述
在这里插入图片描述
Nginx 提供了几种分配方式(策略):

1、轮询(默认)
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器 down 掉,能自动剔除。

2、weight
weight 代表权,重默认为 1,权重越高被分配的客户端越多
指定轮询几率,weight 和访问比率成正比,用于后端服务器性能不均的情况。 例如:

upstream server_pool{ 
server 192.168.5.21 weight=10; 
server 192.168.5.22 weight=10; 
}

3、ip_hash
每个请求按访问 ip 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决 session 的问题。 例如:

upstream server_pool{ 
ip_hash; 
server 192.168.5.21:80; 
server 192.168.5.22:80; 
}

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

upstream server_pool{ 
server 192.168.5.21:80; 
server 192.168.5.22:80; 
fair; 
}

nginx 配置实例-动静分离

Nginx 动静分离简单来说就是把动态跟静态请求分开,不能理解成只是单纯的把动态页面和静态页面物理分离。严格意义上说应该是动态请求跟静态请求分开,可以理解成使用 Nginx 处理静态页面,Tomcat 处理动态页面。动静分离从目前实现角度来讲大致分为两种,一种是纯粹把静态文件独立成单独的域名,放在独立的服务器上,也是目前主流推崇的方案;另外一种方法就是动态跟静态文件混合在一起发布,通过 nginx 来分开。通过 location 指定不同的后缀名实现不同的请求转发。

通过 expires 参数设置,可以使浏览器缓存过期时间,减少与服务器之前的请求和流量。具体 Expires 定义:是给一个资源设定一个过期时间,也就是说无需去服务端验证,直接通过浏览器自身确认是否过期即可,所以不会产生额外的流量。此种方法非常适合不经常变动的资源。(如果经常更新的文件,不建议使用 Expires 来缓存),我这里设置 3d,表示在这 3 天之内访问这个 URL,发送一个请求,比对服务器该文件最后更新时间没有变化,则不会从服务器抓取,返回状态码304,如果有修改,则直接从服务器重新下载,返回状态码 200。
在这里插入图片描述
1、动静分离准备工作
在root目录下创建一个文件夹放静态资源放一张图片和一个html文件
在这里插入图片描述
2、具体配置

server {
        listen       80;
        server_name  192.168.1.108;
        
        #charset koi8-r;
           
        #access_log  logs/host.access.log  main;
       location /www/  {
            root   /data/;
            index  index.html index.htm;
        }
       location /image/  {
            root   /data/ ;
            autoindex on;
        }       
}

3、测试结果
在这里插入图片描述

nginx 原理与优化参数配置

一 .nginx的工作原理
在这里插入图片描述
nginx启动后会有两个进程一个为worker一个为master。
在这里插入图片描述
master将任务分配给worker,由worker完成具体的任务。
在这里插入图片描述
1.在nginx启动后,会有一个master进程和多个worker进程,master进程主要用来管理worker进程,包括:接受信号,将信号分发给worker进程,监听worker进程工作状态,当worker进程退出时(非正常),启动新的worker进程。基本的网络事件会交给worker进程处理。多个worker进程之间是对等的,他们同等竞争来自客户端的请求,各进程互相之间是独立的 。一个请求,只可能在一个worker进程中处理,一个worker进程,不可能处理其它进程的请求。 worker进程的个数是可以设置的,一般我们会设置与机器cpu核数一致,这里面的原因与nginx的进程模型以及事件处理模型是分不开的 。

2.当master接收到重新加载的信号会怎么处理(./nginx -s reload)?,master会重新加载配置文件,然后启动新的进程,使用的新的worker进程来接受请求,并告诉老的worker进程他们可以退休了,老的worker进程将不会接受新的,老的worker进程处理完手中正在处理的请求就会退出。

3.worker进程是如何处理用户的请求呢?首先master会根据配置文件生成一个监听相应端口的socket,然后再faster出多个worker进程,这样每个worker就可以接受从socket过来的消息(其实这个时候应该是每一个worker都有一个socket,只是这些socket监听的地址是一样的)。当一个连接过来的时候,每一个worker都能接收到通知,但是只有一个worker能和这个连接建立关系,其他的worker都会连接失败,这就是所谓的惊群现在,为了解决这个问题,nginx提供一个共享锁accept_mutex,有了这个共享锁后,就会只有一个worker去接收这个连接。当一个worker进程在accept这个连接之后,就开始读取请求,解析请求,处理请求,产生数据后,再返回给客户端,最后才断开连接,这样一个完整的请求就是这样的了。

nginx的事件驱动机制

为什么几个worker进程(每一个worker进程里面其实只有一个主线程)能同时接收上万的请求呢?这是因为nginx事件处理机制是异步非阻塞的。nginx将一个请求划分为多个阶段来异步处理模块,每个阶段只是处理请求的一部分,如果请求的这一部分发生阻塞,nginx不会等待,它会处理其他的请求的某一部分。传统web服务器的每个事件消费者独占一个进程(线程)资源,这种情况对于用户规模较小的情况来说,用户响应速度快,但是当并发规模达到数十万上百万的时候,由于线程(进程)数目过多,会频繁的切换,而且当线程阻塞的时候会进行睡眠,也会造成资源的浪费,这样服务器就会产生瓶颈.

nginx服务器采用的事件驱动机制不同,他不会为每个消费事件创建一个进程或线程,这样就不会产生由于进程间频繁切换占用cpu而产生的瓶颈,而且nginx不会让事件阻塞,即采用无阻塞事件驱动模型,这样就不会因为事件阻塞使进程睡眠而造成的资源浪费.

nginx将一个请求划分成多个阶段异步处理,每个阶段仅仅完成一个请求中的一部分,当本阶段任务完成后进入下一阶段.等待事件发生不是阻塞的等待,等待事件发生时候内。

事件发生源产生事件->事件收集器来收集分发事件(选择自己感兴趣的)->消费事件.

epoll库

epoll库是Nginx服务器支持的高性能事件驱动库之一。它是公认的最好的事件驱动模型。和poll库及select库有很大的区别。
poll和select都是创建一个待处理事件列表,然后把这个列表发给内核,返回的时候,再去轮询检查这个列表。以判断这个事件是否发生。在描述符太多的情况下,就会明显效率低下了。
epoll是这么做的,它把事件描述符列表的管理交给内核复制。一旦有某个事件发生,内核将发生事件的事件描述符交给Nginx的进程,而不是将整个事件描述符列表交给进程,让进程去轮询具体是哪个描述符。epoll()避免了轮询整个事件描述符列表。所以显得更高效。

epoll库的基本步骤:

首先:epoll库通过相关调用通知内核创建一个有N个描述符的事件列表。然后给这个事件列表设置自己关心的事件。并把它添加到内核中。在具体的代码中还可以实现对相关调用的事件描述符列表进行修改和删除。之后,一旦设置完成就一直等待内核通知事件发生了,某一事件发生后,内核就将发生事件的描述符给epoll库,epoll库去处理事件。

二、一个 master 和多个 woker 的好处

(1)可以使用 nginx –s reload 热部署,利用 nginx 进行热部署操作

(2)每个 woker 是独立的进程,如果有其中的一个 woker 出现问题,其他 woker 独立的,继续进行争抢,实现请求过程,不会造成服务中断。

(3)首先,对于每个 worker 进程来说,独立的进程,不需要加锁,所以省掉了锁带来的开销,同时在编程以及问题查找时,也会方便很多。其次,采用独立的进程,可以让互相之间不会影响,一个进程退出后,其它进程还在工作,服务不会中断,master 进程则很快启动新的worker 进程。当然,worker 进程的异常退出,肯定是程序有 bug 了,异常退出,会导致当前 worker 上的所有请求失败,不过不会影响到所有请求,所以降低了风险。

三、设置多少个 woker 合适

Nginx 同 redis 类似都采用了 io 多路复用机制,每个 worker 都是一个独立的进程,但每个进程里只有一个主线程,通过异步非阻塞的方式来处理请求, 即使是千上万个请求也不在话下。每个 worker 的线程可以把一个 cpu 的性能发挥到极致。所以 worker 数和服务器的 cpu数相等是最为适宜的。设少了会浪费 cpu,设多了会造成 cpu 频繁切换上下文带来的损耗。

四、连接数 worker_connection

第一个:发送请求,占用了 woker 的几个连接数?
答案:2 或者 4 个

原因是当我们访问静态资源时向nginx发出请求,nginx可以直接将静态资源返回给客户端,所以需要来回两个连接。
在这里插入图片描述

如果我们访问的是动态资源时因为nginx不支持java所以我们nginx要去访问java的服务器Tomcat这样来回就是四个请求。
在这里插入图片描述

第二个:nginx 有一个 master,有四个 woker,每个 woker 支持最大的连接数 1024,支持的最大并发数是多少?

这个值是表示每个 worker 进程所能建立连接的最大值,所以,一个 nginx 能建立的最大连接数,应该是 worker_connections * worker_processes。当然,这里说的是最大连接数,对于HTTP 请 求 本 地 资 源 来 说 , 能 够 支 持 的 最 大 并 发 数 量 是 worker_connections * worker_processes,如果是支持 http1.1 的浏览器每次访问要占两个连接,所以普通的静态访问最大并发数是: worker_connections * worker_processes /2,而如果是 HTTP 作 为反向代理来说,最大并发数量应该是 worker_connections * worker_processes/4。因为作为反向代理服务器,每个并发会建

以上是关于一文搞定Nginx的主要内容,如果未能解决你的问题,请参考以下文章

一文搞定前端 Jenkins 自动化部署

从应用到原理一文搞定Nginx的使用与配置

POI 导出 Excel:字体颜色行列自适应锁住合并单元格一文搞定……

干货 | 一文搞定 pytest 自动化测试框架

干货 | 一文搞定 uiautomator2 自动化测试工具使用

Java分享客栈一文搞定京东零售开源的AsyncTool,彻底解决异步编排问题。