Nginx

1、Nginx概述

  • Nginx是lgor Sysoev为俄罗斯访问量第二的rambler.ru站点设计开发的。从2004年发布至今,凭借开源的力量,已经接近成熟与完善。

  • Nginx功能丰富,可作为HTTP服务器,也可作为反向代理服务器,邮件服务器。支持FastCGI、SSL、Virtual Host、URL Rewrite、Gzip等功能。并且支持很多第三方的模块扩展。

  • Nginx的稳定性、功能集、示例配置文件和低系统资源的消耗让他后来居上,在全球活跃的网站中有12.18%的使用比率,大约为2220万个网站。

  • 正向代理

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

    image-20240130142455324

  • 反向代理

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

    img

    正向代理的是客户端,反向代理服务端

  • 负载均衡

    单个服务器解决不了高并发问题,我们增加服务器的数量,然后将请求分发到各个服务器上,将原先请求集中到单个服务器上的情况改为将请求分发到多个服务器上,将负载分发到不同的服务器,也就是我们所说的负载均衡;

    img

  • 动静分离

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

    image-20240130144736337

2、安装Nginx

源码:https://trac.nginx.org/nginx/browser

官网:http://www.nginx.org/

先安装相关依赖,使用yum安装gcc zlib zlib-devel pcre-devel openssl openssl-devel这些依赖。

本次安装的是1.25.2版本的

image-20240130145235008

将压缩文件解压后,进入压缩目录执行./configure然后再执行make && make install

安装完成后即可看到/usr/local/nginx/目录

image-20240130145636157

使用systemctl start nginx即可启动

image-20240130150754185

使用浏览器可以访问,修改后的首页

image-20240130150824347

nginx的配置文件就在/usr/local/nginx/conf中

image-20240130150920111

使用vi nginx.conf默认配置文件

#user  nobody;
worker_processes  1;
#worker processes 值越大,可以支持的并发处理量也越多
#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;
}
#支持的最大连接数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;
    #    }
    #}
​
}

它有以下内容

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

    比如

    worker_processes  1;
    #worker processes 值越大,可以支持的并发处理量也越多

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

    比如

    events {
        worker_connections  1024;
    }
    #支持的最大连接数1024

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

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

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

3、Nginx配置实例1-反向代理

实现效果:

  • 打开浏览器输入地址www.123.com,跳转到linux中tomcat主页

步骤

1、先在linux中安装tomcat并启动

在tomcat官网中找到tar包,直接wget下载到软件包目录中会非常满,所以在本机上下载好的包传到linux中就好。

image-20240130153832711

本地下载好后上传并解压

解压后进入tomcat目录中的bin目录,运行./startup.sh即可启动

image-20240130155229249

在浏览器中访问linux虚拟机的8080端口可以进入首页

image-20240130155343937

对外开放端口一定要做

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

2、在本地windows中进行域名和IP关系对应配置

在C:\Windows\System32\drivers\etc\hosts中添加

image-20240130160522623

到linux中配置nginx.conf

image-20240130161228381

保存退出重启nginx即可

访问一下www.123.com

image-20240130161452683

4、Nginx反向代理实例-2

实现效果:

使用nginx反向代理,根据访问的路径跳转到不同端口的服务中nginx.监听端口为9001

准备两个tomcat,一个8080,一个8081

8080的就还使用原来启动过的那个就好,8081再创建一个目录,把软件包放进去再解压修改server.xml文件,改成8081端口

image-20240130163837782

修改之后启动8081的tomcat

image-20240130163926329

到浏览器访问一下试试

image-20240130163955436

可以正常访问

修改一下测试页面,在8080的webapps目录中新建edu目录然后在edu目录下创建一个测试页面,同理在8081的webapps目录中创建vod目录,然后创建测试页面

8080中操作

image-20240130164818555

image-20240130164808413

8081中操作

image-20240130164602939

image-20240130164535123

然后开始配置nginx.conf

 server {
         listen       9001;
         #    listen       somename:8080;
         server_name  192.168.111.27;
 
         location ~ /edu/ {
                  proxy_pass http://localhost:8080;#如果路径中包含edu就到8080
           }
         location ~ /vod/ {
                  proxy_pass http://localhost:8081;#如果路径中包含vod就到8081
           }
}
​

直接把防火墙关了防止访问不到其他端口

测试

image-20240130170524754

image-20240130170550852

location配置中的正则表达式说明:

image-20240130170644085

5、负载均衡

要实现效果

  • 在浏览器输入192.168.111.27/edu/a.html;

  • 负载均衡效果,输入地址后平均分摊到8080和8081上面;

  • 在两台tomcat里面的webapps目录中,都创建名称为edu的目录,在此目录中再创建测试页面;

配置nginx配置文件

image-20240202130541494

然后就可以测试了,直接IP地址加/edu/a.html

第一次是8080

image-20240202130756943

多刷新几次,又变成8081了。

image-20240202130832236

负载均衡的分配策略

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

  2. weight

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

    例如:

upstream myserver{
        server 192.168.111.27:8080 weight=5;
        server 192.168.111.27:8081 weight=10;
    }

3.ip_hash

每个请求按访问ip的 hash结果分配,这样每个访客固定访问一个后端服务器,可以解决 session的问题。比如,你访问地址192.168.111.27,第一次显示8080,那你再用这个IP就一直都是8080了。

例如:

upstream server_pool{
        ip_hash;
        server 192.168.111.27:8080;
        server 192.168.111.27:8081;
    }

4.fair(第三方)

按照后端服务器的响应时间来分配请求,响应时间段的优先级高。

示例:

upstream server_pool{
        server 192.168.111.27:8080;
        server 192.168.111.27:8081;
        fair;
    }

6、Nginx动静分离

Nginx动静分离简单来说就是把动态跟静态请求分开,不能理解成只是单纯的把动态页面和静态页面物理分离。严格意义上说应该是动态请求跟静态请求分开,可以理解成使用Nginx处理静态页面,Tomcat处理动态页面。

动静分离从目前实现角度来讲大致分为两种:

  • 一种是纯粹把静态文件独立成单独的域名,放在独立的服务器上,也是目前主流推崇的方案;

  • 另外一种方法就是动态跟静态文件混合在一起发布,通过nginx来分开。

在nginx配置文件中的体现就是,通过 location指定不同的后缀名实现不同的请求转发。通过 expires参数设置,可以使浏览器缓存过期时间,减少与服务器之前的请求和流量。具体Expires定义:是给一个资源设定一个过期时间,也就是说无需去服务端验证,直接通过浏览器自身确认是否过期即可,所以不会产生额外的流量。此种方法非常适合不经常变动的资源。(如果经常更新的文件,不建议使用Expires来缓存)。假如设置3d,表示在这3天之内访问这个URL,发送一个请求,比对服务器该文件最后更新时间没有变化,则不会从服务器抓取直接就在浏览器的缓存中,返回状态码304,如果有修改,则直接从服务器重新下载,返回状态码200。

测试案例:

创建一个data目录,进入后再分别创建www和image目录,:www中创建test.html,imgae中上传一个图片1.png。

nginx中配置文件修改

image-20240202155325025

测试:

输入192.168.111.28/image/就可以看到目录,因为我们加的有autoindex这个选项。

image-20240217115619808

点击1.png就可以看到图片

image-20240217115732792

输入192.168.111.28/www/test.html就可以看到测试页面

image-20240217115807167

7、Ngiinx的高可用配置

image-20240217121308755

高可用需求分析:

  • 需要两台nginx服务器;

  • 需要keepalived

  • 需要虚拟IP

keepalived

Keepalived是Linux下一个轻量级别的高可用解决方案,通过虚拟路由冗余协议来实现服务或者网络的高可用

起初是为LVS设计的,专门用来监控集群系统中各个服务节点的状态

如果某个服务器节点出现故障,Keepalived将检测到后自动将节点从集群系统中剔除

而在故障节点恢复正常后,Keepalived又可以自动将此节点重新加入集群中

这些工作自动完成,不需要人工干预,需要人工完成的只是修复出现故障的节点

特点:

1、部署简单,只需要配置一个配置文件即可;

2、加入了虚拟路由冗余协议,可以保证业务或网络不间断稳定运行;

7.1、高可用基础环境配置

原本演示的虚拟机还继续使用,安装keepalived后可以在/etc/keepalived下看到keepalived.conf配置文件。

image-20240217154511424

另一台nginx服务器我使用了华为云的云服务器,同样的也安装nginx相关依赖和keepalived

7.2、主从配置

修改/etc/keepalived/keepalived.conf配置文件,注意主master和从backup对应的修改。

global_defs {
    notification_email {
        acassen@firewall.loc
        failover@firewall.loc
        sysadmin@firewall.loc
    }
    notification_email_from Alexandre.Cassen@firewall.loc
    smtp_server 192.168.111.28
    smtp_connect_timeout 30
    router_id LVS_DEVEL 
}
​
vrrp_script chk_http_port {
    script "/usr/local/src/nginx_check.sh"
    interval 2 #(检测脚本执行的间隔)
    weight 2
}
​
vrrp_instance VI_1 {
    state MASTER  # 备份服务器上将 MASTER 改为 BACKUP
    interface ens36 //网卡名称
    virtual_router_id 51 # 主、备机的 virtual_router_id 必须相同
    priority 100  # 主、备机取不同的优先级,主机值较大,备份机值较小
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.111.50 // VRRP H 虚拟地址
    }
}
​

在 /usr/local/src 添加检测脚本nginx_check.sh

#!/bin/bash
A=`ps -C nginx – no-header |wc -l`
if [ $A -eq 0 ];then
    /usr/local/nginx/sbin/nginx
    sleep 2
    if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then
        killall keepalived
    fi
fi

在备份服务器中也做相同操作

主从各配置文件配置好了之后就重启nginx和keepalived服务进行测试,为了区分主从将主从的index.html进行修改。

image-20240217165314219

测试输入192.168.111.50这个虚拟IP时会显示主服务器的页面

image-20240217170014717

然后把主服务器停掉再次查看

image-20240217170607422

这次显示的就是BACKUP了

image-20240217170702675

8、Nginx的原理

在Nginx的工作机制中,采用的是主从架构。客户端发送请求给master,然后由master下发任务到worker实现。这种机制中,master和worker进程之间不是通过轮询方式,而是通过争抢机制来分配任务。每个worker都是独立的进程,如果其中一个worker出现问题,其他worker可以独立地继续进行争抢,实现请求过程,从而保证了服务的高可用性。

image-20240217172431538

通过nginx的进程也可以看到一个master和多个worker,master作为管理者下面有很多的worker

image-20240217181721109

各个worker是通过争抢的方式来获得连接

image-20240217181420986

一个master和多个worker的好处

  1. 可以使用nginx -s reload热部署;

  2. 每一个worker都是独立的,如果其中的一个worker出现问题,其它worker独立的继续进行争抢,实现请求过程,不会造成服务中断;

设置多少个worker才合适?

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

worker_processes  1;#设置worker数量
worker_connections 最大是1024

连接数worker_connection

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

  1. 一个问题:发送一个请求,占用worker的几个连接数?

    2个或者4个,worker获取到连接一个,如果是静态资源就返回资源给客户端这也是一个,如果访问的是动态资源还需要去访问tomcat,拿到资源后再返回又是两个。

  2. 普通的静态访问最大并发数是:worker_connections * worker_processes /2;

  3. 而如果是HTTP作为反向代理来说,最大并发数量应该是worker_connections* worker_processes/4;