Nginx学习笔记

本文涉及的产品
传统型负载均衡 CLB,每月750个小时 15LCU
.cn 域名,1个 12个月
网络型负载均衡 NLB,每月750个小时 15LCU
简介: 自学笔记

一、Nginx基本概念

1、什么是nginx

Nginx ("engine x") 是一个高性能的 HTTP 和反向代理服务器,特点是占有内存少,并发能力强。

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

二、正向代理与反向代理

2.1 、概念

正向代理是一个位于客户端和目标服务器之间的代理服务器(中间服务器)。为了从原始服务器取得内容,客户端向代理服务器发送一个请求,并且指定目标服务器,之后代理向目标服务器转交并且将获得的内容返回给客户端。正向代理的情况下客户端必须要进行一些特别的设置才能使用。

反向代理正好相反。对于客户端来说,反向代理就好像目标服务器。并且客户端不需要进行任何设置。客户端向反向代理发送请求,接着反向代理判断请求走向何处,并将请求转交给客户端,使得这些内容就好似他自己一样,一次客户端并不会感知到反向代理后面的服务,也因此不需要客户端做任何设置,只需要把反向代理服务器当成真正的服务器就好了。

2.2 、区别

image-20230111171228155

正向代理中,proxy和client同属一个LAN,对server透明; 反向代理中,proxy和server同属一个LAN,对client透明。 实际上proxy在两种代理中做的事都是代为收发请求和响应,不过从结构上来看正好左右互换了下,所以把前者那种代理方式叫做正向代理,后者叫做反向代理。

image-20230111171240108

正向代理:客户端 <一> 代理 一>服务端

正向代理简单地打个租房的比方:

A(客户端)想租C(服务端)的房子,但是A(客户端)并不认识C(服务端)租不到。
B(代理)认识C(服务端)能租这个房子所以你找了B(代理)帮忙租到了这个房子。

这个过程中C(服务端)不认识A(客户端)只认识B(代理)
C(服务端)并不知道A(客户端)租了房子,只知道房子租给了B(代理)。

反向代理:客户端 一>代理 <一> 服务端

反向代理也用一个租房的例子:

A(客户端)想租一个房子,B(代理)就把这个房子租给了他。
这时候实际上C(服务端)才是房东。
B(代理)是中介把这个房子租给了A(客户端)。

这个过程中A(客户端)并不知道这个房子到底谁才是房东
他都有可能认为这个房子就是B(代理)的

由上的例子和图,我们可以知道正向代理和反向代理的区别在于代理的对象不一样,正向代理的代理对象是客户端,反向代理的代理对象是服务端。

3. 负载均衡

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

image-20230111171247788

4. 动静分离

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

image-20230111171255130

二、Nginx的安装

1.1 、安装Nginx

# 安装编译工具及库文件
yum -y install gcc pcre pcre-devel zlib zlib-devel openssl openssl-devel

一次安装如果有问题,可以试一下分开安装(上面命令执行成功了就就无需执行以下命令了)

yum install gcc-c++

yum install -y pcre pcre-devel

yum install -y zlib zlib-devel

yum install -y openssl openssl-devel

安装的插件的作用

  • 1、gcc 可以编译 C,C++,Ada,Object C和Java等语言(安装 nginx 需要先将官网下载的源码进行编译,编译依赖 gcc 环境)

  • 2、pcre pcre-devel pcre是一个perl库,包括perl兼容的正则表达式库,nginx的http模块使用pcre来解析正则表达式,所以需要安装pcre库

  • 3、zlib zlib-devel zlib库提供了很多种压缩和解压缩方式nginx使用zlib对http包的内容进行gzip,所以需要安装

  • 4、openssl openssl-devel OpenSSL 是一个强大的安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理功能及 SSL 协议,并提供丰富的应用程序供测试或其它目的使用。

  • 5、nginx 不仅支持 http 协议,还支持 https(即在ssl协议上传输http),所以需要在 Centos 安装 OpenSSL 库

方法一、 直接下载.tar.gz安装包
https://nginx.org/en/download.htm

方法二、使用wget命令下载(推荐)。确保系统已经安装了wget,如果没有安装,执行 yum install wget 安装。

(注意:本示例使用方法二)

tar xvf nginx-1.21.6.tar.gz

cd nginx-1.21.6
  • 配置(带有https模块)
./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module
  • 编译和安装
编译:make
  • 安装:
make install
  • 查看安装路径
whereis nginx

1.2 、测试安装是否成功

安装成功后,/usr/local/nginx目录下会多一个sbin的启动目录

image-20230111171103828

1.3、启动

进入/usr/loacl/nginx/sbin目录下输入命令

./nginx

启动后访问服务器对应端口号即可显示,因为Nginx默认访问端口是80端口

image-20230111172303785

三、Nginx的常用命令和配置文件

常用命令

以下命令nginx已经通过apt安装好了,有nginx命令。

使用Nginx命令的前提是必须在Nginx的usr/local/nginx/sbin目录下才能使用

查看版本

[root@xujicheng sbin]# ./nginx -v
nginx version: nginx/1.13.7

如果你想同时看到更详细的配置项,使用 -V

[root@xujicheng sbin]# ./nginx -V
nginx version: nginx/1.13.7
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) 
built with OpenSSL 1.0.2k-fips  26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module

启动 Nginx 服务

./nginx

查看 Nginx 服务状态

这条是看运行时的服务状态信息的。

[root@xujicheng sbin]# ps -ef | grep nginx
root     10500     1  0 17:16 ?        00:00:00 nginx: master process ./nginx
nobody   10501 10500  0 17:16 ?        00:00:00 nginx: worker process
root     11754  5025  0 17:30 pts/0    00:00:00 grep --color=auto nginx

重写加载 Nginx 服务

重载是重新加载 配置文件,看命令:

./nginx -s reload

停止 Nginx 服务

不管你是什么原因想停了它,都可以用:

./nginx -s stop

强行停止Nginx服务

killall nginx

四、配置文件

nginx 安装目录下,其默认的配置文件都放在这个目录的 conf 目录下,而主配置文件 nginx.conf 也在其中,后续对 nginx 的使用基本上都是对此配置文件进行相应的修改,配置文件的位置通常在\usr\loacl\nginx\conf目录下

image-20230111174425282

下面查看Nginx.conf的命令组成

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

}

第一部分:全局块

从配置文件开始到 events 块之间的内容,主要会设置一些影响 nginx 服务器整体运行的配置指令,主要包括配置运行 Nginx 服务器的用户(组)、允许生成的 worker process 数,进程 PID 存放路径、日志存放路径和类型以及配置文件的引入等。

比如上面第一行配置的:

image-20230111175053907

这是 Nginx 服务器并发处理服务的关键配置,worker_processes 值越大,可以支持的并发处理量也越多,但是会受到硬件、软件等设备的制约

第二部分:events 块

events 块涉及的指令主要影响 Nginx 服务器与用户的网络连接,常用的设置包括是否开启对多 work process 下的网络连接进行序列化,是否允许同时接收多个网络连接,选取哪种事件驱动模型来处理连接请求,每个 word process 可以同时支持的最大连接数等。

image-20230111175307760

上述例子就表示每个 work process 支持的最大连接数为 1024. 这部分的配置对 Nginx 的性能影响较大,在实际中应该灵活配置。

第三部分:http 块

这算是 Nginx 服务器配置中最频繁的部分,代理、缓存和日志定义等绝大多数功能和第三方模块的配置都在这里。

需要注意的是:http 块也可以包括 http 全局块server

1. http全局块

http 全局块配置的指令包括文件引入、MIME-TYPE 定义、日志自定义、连接超时时间、单链接请求数上限等。

upstream(上游服务器设置,主要为反向代理、负载均衡相关配置,upstream 的指令用于设置一系列的后端服务器,设置反向代理及后端服务器的负载均衡

2. server块

这块和虚拟主机有密切关系,虚拟主机从用户角度看,和一台独立的硬件主机是完全一样的,该技术的产生是为了节省互联网服务器硬件成本。

每个 http 块可以包括多个 server 块,而每个 server 块就相当于一个虚拟主机。

而每个 server 块也分为全局 server 块,以及可以同时包含多个 locaton 块。

1.全局 server 块

最常见的配置是本虚拟机主机的监听配置和本虚拟主机的名称或 IP 配置。

2. location块

一个 server 块可以配置多个 location 块。

这块的主要作用是基于 Nginx 服务器接收到的请求字符串(例如 server_name/uri-string),对虚拟主机名称(也可以是 IP 别名)之外的字符串(例如 前面的 /uri-string)进行匹配,对特定的请求进行处理。地址定向、数据缓存和应答控制等功能,还有许多第三方模块的配置也在这里进行。

nginx.conf 详细的配置文件介绍

#定义Nginx运行的用户和用户组
user www www; 

#nginx进程数,通常设置成和cpu的数量相等
worker_processes 4; 

#全局错误日志定义类型,[debug | info | notice | warn | error | crit]
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;


#进程pid文件
#pid        logs/nginx.pid;


#指定进程可以打开的最大描述符:数目
#工作模式与连接数上限
##这个指令是指当一个nginx进程打开的最多文件描述符数目,理论值应该是最多打开文件数(ulimit -n)与nginx进程数相除,但是nginx分配请求并不是那么均匀,所以最好与ulimit -n 的值保持一致。
#这是因为nginx调度时分配请求到进程并不是那么的均衡,所以假如填写10240,总并发量达到3-4万时就有进程可能超过10240了,这时会返回502错误。
worker_rlimit_nofile 65535;


events {
    #参考事件模型,use [ kqueue | rtsig | epoll | /dev/poll | select | poll ]; epoll模型
    #是Linux 2.6以上版本内核中的高性能网络I/O模型,linux建议epoll,如果跑在FreeBSD上面,就用kqueue模型。
    #补充说明:
    #与apache相类,nginx针对不同的操作系统,有不同的事件模型
    #A)标准事件模型
    #Select、poll属于标准事件模型,如果当前系统不存在更有效的方法,nginx会选择select或poll
    #B)高效事件模型
    #Kqueue:使用于FreeBSD 4.1+, OpenBSD 2.9+, NetBSD 2.0 和 MacOS X.使用双处理器的MacOS X系统使用kqueue可能会造成内核崩溃。
    #Epoll:使用于Linux内核2.6版本及以后的系统。
    #/dev/poll:使用于Solaris 7 11/99+,HP/UX 11.22+ (eventport),IRIX 6.5.15+ 和 Tru64 UNIX 5.1A+。
    #Eventport:使用于Solaris 10。 为了防止出现内核崩溃的问题, 有必要安装安全补丁。
    use epoll


    #单个进程最大连接数(最大连接数=连接数+进程数)
    #根据硬件调整,和前面工作进程配合起来用,尽量大,但是别把cup跑到100%就行。
    worker_connections  1024;

    #keepalive 超时时间
    keepalive_timeout 60;

    #客户端请求头部的缓冲区大小。这个可以根据你的系统分页大小来设置,一般一个请求头的大小不会超过1k,不过由于一般系统分页都要大于1k,所以这里设置为分页大小。
    #分页大小可以用命令getconf PAGESIZE 取得。
    #[root@web001 ~]# getconf PAGESIZE
    #但也有client_header_buffer_size超过4k的情况,但是client_header_buffer_size该值必须设置为“系统分页大小”的整倍数。
    client_header_buffer_size 4k;

    #这个将为打开文件指定缓存,默认是没有启用的,max指定缓存数量,建议和打开文件数一致,inactive是指经过多长时间文件没被请求后删除缓存。
    open_file_cache max=65535 inactive=60s;


    #这个是指多长时间检查一次缓存的有效信息。
    #语法:open_file_cache_valid time 默认值:open_file_cache_valid 60 使用字段:http, server, location 这个指令指定了何时需要检查open_file_cache中缓存项目的有效信息.
    open_file_cache_valid 80s;


    #open_file_cache指令中的inactive参数时间内文件的最少使用次数,如果超过这个数字,文件描述符一直是在缓存中打开的,如上例,如果有一个文件在inactive时间内一次没被使用,它将被移除。
    #语法:open_file_cache_min_uses number 默认值:open_file_cache_min_uses 1 使用字段:http, server, location  这个指令指定了在open_file_cache指令无效的参数中一定的时间范围内可以使用的最小文件数,如果使用更大的值,文件描述符在cache中总是打开状态.
    open_file_cache_min_uses 1;

    #语法:open_file_cache_errors on | off 默认值:open_file_cache_errors off 使用字段:http, server, location 这个指令指定是否在搜索一个文件是记录cache错误.
    open_file_cache_errors on;
}


#设定http服务器,利用它的反向代理功能提供负载均衡支持
http{
    #文件扩展名与文件类型映射表
    include mime.types;

    #默认文件类型
    default_type application/octet-stream;

    #默认编码
    charset utf-8;

    #服务器名字的hash表大小
    #保存服务器名字的hash表是由指令server_names_hash_max_size 和server_names_hash_bucket_size所控制的。参数hash bucket size总是等于hash表的大小,并且是一路处理器缓存大小的倍数。在减少了在内存中的存取次数后,使在处理器中加速查找hash表键值成为可能。如果hash bucket size等于一路处理器缓存的大小,那么在查找键的时候,最坏的情况下在内存中查找的次数为2。第一次是确定存储单元的地址,第二次是在存储单元中查找键 值。因此,如果Nginx给出需要增大hash max size 或 hash bucket size的提示,那么首要的是增大前一个参数的大小.
    server_names_hash_bucket_size 128;

    #客户端请求头部的缓冲区大小。这个可以根据你的系统分页大小来设置,一般一个请求的头部大小不会超过1k,不过由于一般系统分页都要大于1k,所以这里设置为分页大小。分页大小可以用命令getconf PAGESIZE取得。
    client_header_buffer_size 32k;

    #客户请求头缓冲大小。nginx默认会用client_header_buffer_size这个buffer来读取header值,如果header过大,它会使用large_client_header_buffers来读取。
    large_client_header_buffers 4 64k;

    #设定通过nginx上传文件的大小
    client_max_body_size 8m;

    #开启高效文件传输模式,sendfile指令指定nginx是否调用sendfile函数来输出文件,对于普通应用设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络I/O处理速度,降低系统的负载。注意:如果图片显示不正常把这个改成off。
    #sendfile指令指定 nginx 是否调用sendfile 函数(zero copy 方式)来输出文件,对于普通应用,必须设为on。如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络IO处理速度,降低系统uptime。
    sendfile on;

     #开启目录列表访问,合适下载服务器,默认关闭。
    autoindex on;

      #此选项允许或禁止使用socke的TCP_CORK的选项,此选项仅在使用sendfile的时候使用
    tcp_nopush on;

    tcp_nodelay on;

    #长连接超时时间,单位是秒
    keepalive_timeout 120;

    #FastCGI相关参数是为了改善网站的性能:减少资源占用,提高访问速度。下面参数看字面意思都能理解。
    fastcgi_connect_timeout 300;
    fastcgi_send_timeout 300;
    fastcgi_read_timeout 300;
    fastcgi_buffer_size 64k;
    fastcgi_buffers 4 64k;
    fastcgi_busy_buffers_size 128k;
    fastcgi_temp_file_write_size 128k;

    #gzip模块设置
    gzip on; #开启gzip压缩输出
    gzip_min_length 1k;    #最小压缩文件大小
    gzip_buffers 4 16k;    #压缩缓冲区
    gzip_http_version 1.0; #压缩版本(默认1.1,前端如果是squid2.5请使用1.0)
    gzip_comp_level 2;     #压缩等级
    gzip_types text/plain application/x-javascript text/css application/xml;    #压缩类型,默认就已经包含textml,所以下面就不用再写了,写上去也不会有问题,但是会有一个warn。
    gzip_vary on;

    #开启限制IP连接数的时候需要使用
    #limit_zone crawler $binary_remote_addr 10m;


    #负载均衡配置
    upstream piao.jd.com {

        #upstream的负载均衡,weight是权重,可以根据机器配置定义权重。weigth参数表示权值,权值越高被分配到的几率越大。
        server 192.168.80.121:80 weight=3;
        server 192.168.80.122:80 weight=2;
        server 192.168.80.123:80 weight=3;

        #nginx的upstream目前支持4种方式的分配
        #1、轮询(默认)
        #每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。
        #2、weight
        #指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。
        #例如:
        #upstream bakend {
        #    server 192.168.0.14 weight=10;
        #    server 192.168.0.15 weight=10;
        #}
        #2、ip_hash
        #每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
        #例如:
        #upstream bakend {
        #    ip_hash;
        #    server 192.168.0.14:88;
        #    server 192.168.0.15:80;
        #}
        #3、fair(第三方)
        #按后端服务器的响应时间来分配请求,响应时间短的优先分配。
        #upstream backend {
        #    server server1;
        #    server server2;
        #    fair;
        #}
        #4、url_hash(第三方)
        #按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。
        #例:在upstream中加入hash语句,server语句中不能写入weight等其他的参数,hash_method是使用的hash算法
        #upstream backend {
        #    server squid1:3128;
        #    server squid2:3128;
        #    hash $request_uri;
        #    hash_method crc32;
        #}

        #tips:
        #upstream bakend{#定义负载均衡设备的Ip及设备状态}{
        #    ip_hash;
        #    server 127.0.0.1:9090 down;
        #    server 127.0.0.1:8080 weight=2;
        #    server 127.0.0.1:6060;
        #    server 127.0.0.1:7070 backup;
        #}
        #在需要使用负载均衡的server中增加 proxy_pass http://bakend/;

        #每个设备的状态设置为:
        #1.down表示单前的server暂时不参与负载
        #2.weight为weight越大,负载的权重就越大。
        #3.max_fails:允许请求失败的次数默认为1.当超过最大次数时,返回proxy_next_upstream模块定义的错误
        #4.fail_timeout:max_fails次失败后,暂停的时间。
        #5.backup: 其它所有的非backup机器down或者忙的时候,请求backup机器。所以这台机器压力会最轻。

        #nginx支持同时设置多组的负载均衡,用来给不用的server来使用。
        #client_body_in_file_only设置为On 可以讲client post过来的数据记录到文件中用来做debug
        #client_body_temp_path设置记录文件的目录 可以设置最多3层目录
        #location对URL进行匹配.可以进行重定向或者进行新的代理 负载均衡
    }


    #虚拟主机的配置
    server {
        #监听端口
        listen 80;

        #域名可以有多个,用空格隔开
        server_name www.jd.com jd.com;
        #默认入口文件名称
        index index.html index.htm index.php;
        root /data/www/jd;

        #对******进行负载均衡
        location ~ .*.(php|php5)?$
        {
            fastcgi_pass 127.0.0.1:9000;
            fastcgi_index index.php;
            include fastcgi.conf;
        }

        #图片缓存时间设置
        location ~ .*.(gif|jpg|jpeg|png|bmp|swf)$
        {
            expires 10d;
        }

        #JS和CSS缓存时间设置
        location ~ .*.(js|css)?$
        {
            expires 1h;
        }

        #日志格式设定
        #$remote_addr与$http_x_forwarded_for用以记录客户端的ip地址;
        #$remote_user:用来记录客户端用户名称;
        #$time_local: 用来记录访问时间与时区;
        #$request: 用来记录请求的url与http协议;
        #$status: 用来记录请求状态;成功是200,
        #$body_bytes_sent :记录发送给客户端文件主体内容大小;
        #$http_referer:用来记录从那个页面链接访问过来的;
        #$http_user_agent:记录客户浏览器的相关信息;
        #通常web服务器放在反向代理的后面,这样就不能获取到客户的IP地址了,通过$remote_add拿到的IP地址是反向代理服务器的iP地址。反向代理服务器在转发请求的http头信息中,可以增加x_forwarded_for信息,用以记录原有客户端的IP地址和原来客户端的请求的服务器地址。
        log_format access '$remote_addr - $remote_user [$time_local] "$request" '
        '$status $body_bytes_sent "$http_referer" '
        '"$http_user_agent" $http_x_forwarded_for';

        #定义本虚拟主机的访问日志
        access_log  /usr/local/nginx/logs/host.access.log  main;
        access_log  /usr/local/nginx/logs/host.access.404.log  log404;

        #对 "/connect-controller" 启用反向代理
        location /connect-controller {
            proxy_pass http://127.0.0.1:88; #请注意此处端口号不能与虚拟主机监听的端口号一样(也就是server监听的端口)
            proxy_redirect off;
            proxy_set_header X-Real-IP $remote_addr;

            #后端的Web服务器可以通过X-Forwarded-For获取用户真实IP
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

            #以下是一些反向代理的配置,可选。
            proxy_set_header Host $host;

            #允许客户端请求的最大单文件字节数
            client_max_body_size 10m;

            #缓冲区代理缓冲用户端请求的最大字节数,
            #如果把它设置为比较大的数值,例如256k,那么,无论使用firefox还是IE浏览器,来提交任意小于256k的图片,都很正常。如果注释该指令,使用默认的client_body_buffer_size设置,也就是操作系统页面大小的两倍,8k或者16k,问题就出现了。
            #无论使用firefox4.0还是IE8.0,提交一个比较大,200k左右的图片,都返回500 Internal Server Error错误
            client_body_buffer_size 128k;

            #表示使nginx阻止HTTP应答代码为400或者更高的应答。
            proxy_intercept_errors on;

            #后端服务器连接的超时时间_发起握手等候响应超时时间
            #nginx跟后端服务器连接超时时间(代理连接超时)
            proxy_connect_timeout 90;

            #后端服务器数据回传时间(代理发送超时)
            #后端服务器数据回传时间_就是在规定时间之内后端服务器必须传完所有的数据
            proxy_send_timeout 90;

            #连接成功后,后端服务器响应时间(代理接收超时)
            #连接成功后_等候后端服务器响应时间_其实已经进入后端的排队之中等候处理(也可以说是后端服务器处理请求的时间)
            proxy_read_timeout 90;

            #设置代理服务器(nginx)保存用户头信息的缓冲区大小
            #设置从被代理服务器读取的第一部分应答的缓冲区大小,通常情况下这部分应答中包含一个小的应答头,默认情况下这个值的大小为指令proxy_buffers中指定的一个缓冲区的大小,不过可以将其设置为更小
            proxy_buffer_size 4k;

            #proxy_buffers缓冲区,网页平均在32k以下的设置
            #设置用于读取应答(来自被代理服务器)的缓冲区数目和大小,默认情况也为分页大小,根据操作系统的不同可能是4k或者8k
            proxy_buffers 4 32k;

            #高负荷下缓冲大小(proxy_buffers*2)
            proxy_busy_buffers_size 64k;

            #设置在写入proxy_temp_path时数据的大小,预防一个工作进程在传递文件时阻塞太长
            #设定缓存文件夹大小,大于这个值,将从upstream服务器传
            proxy_temp_file_write_size 64k;
        }

        #本地动静分离反向代理配置
        #所有jsp的页面均交由tomcat或resin处理
        location ~ .(jsp|jspx|do)?$ {
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass http://127.0.0.1:8080;
        }
    }
}

总结

Nginx 配置文件主要分成四部分:main(全局设置)、server(主机设置)、upstream(上游服务器设置,主要为反向代理、负载均衡相关配置)和 location(URL匹配特定位置后的设置)。

main 部分设置的指令影响其他所有部分的设置;

server 部分的指令主要用于制定虚拟主机域名、IP 和端口号;

upstream 的指令用于设置一系列的后端服务器,设置反向代理及后端服务器的负载均衡;

location 部分用于匹配网页位置(比如,根目录“/”,“/images”,等等)。

他们之间的关系:server 继承 main,location 继承 server;upstream 既不会继承指令也不会被继承。

四、Nginx配置实例-反向代理

1、反向代理实例一

实现效果:使用 nginx 反向代理,访问 www.123.com 直接跳转到 127.0.0.1:8080

准备工作:安装Tomcat,使用默认端口8080

首先下载Tomcat的压缩包,这里分享一个镜像地址下载巨快 https://mirrors.cnnic.cn/apache/tomcat/

选择对应版本后进入其bin目录下载对应操作系统的压缩包

image-20230111180948429

Windows就选.exe结尾的,Linux就选tar.gz结尾的

image-20230111181041585

下载完毕后可以使用第三方连接工具将其上传到服务器对应的目录,然后解压

tar xvf apache-tomcat-9.0.70.tar.gz

进入到/usr/local/apache-tomcat-9.0.70/bin目录启动Tomcat

[root@xujicheng bin]# ./startup.sh  # 启动Tomcat
Using CATALINA_BASE:   /usr/local/apache-tomcat-9.0.70
Using CATALINA_HOME:   /usr/local/apache-tomcat-9.0.70
Using CATALINA_TMPDIR: /usr/local/apache-tomcat-9.0.70/temp
Using JRE_HOME:        /usr/local/src/Java/jdk1.8.0_351
Using CLASSPATH:       /usr/local/apache-tomcat-9.0.70/bin/bootstrap.jar:/usr/local/apache-tomcat-9.0.70/bin/tomcat-juli.jar
Using CATALINA_OPTS:   
Tomcat started.
[root@xujicheng bin]# netstat -anp|grep 8080  # 查看进程
tcp6       0      0 :::8080                 :::*                    LISTEN      15627/java

若是查看进程有端口启动服务器却无法访问就是防火墙的问题

firewall-cmd --permanent --zone=public --add-port=8080/tcp # 开放8080端口到防火墙
firewall-cmd --reload  # 让修改的配置生效

修改完毕后访问http://39.101.65.192:8080/

image-20230111182545479

实现过程

实现过程分析如下:

image-20230111183147612

1、需要达到的效果

启动一个 tomcat,浏览器地址栏输入 www.123.com,出现如下界面

image-20230111183803851

配置完成之后,我们便可以通过 www.123.com:8080 访问到第一步出现的 Tomcat 初始界面。那么如何只需要输入 www.123.com 便可以跳转到 Tomcat 初始界面呢?便用到 nginx 的反向代理。

2、修改host文件

在本地的host文件中加入映射,即Windows访问的端口号和映射的域名做一个对应

image-20230111183705990

3. 在 nginx.conf 配置文件中增加如下配置

    server {
        listen       80;
        server_name  www.123.com; 

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
            proxy_pass http://39.101.65.192:8080;  # 即表示如果我们访问的是39.101.65.192端口,它就会转发到整地址
        }

如上配置,我们监听 80 端口,不加端口号时默认为 80 端口,故访问该域名时会跳转到 127.0.0.1:8080 路径上。

测试:

进入/usr/loacl/nginx/sbin目录下输入命令

# 启动nginx
./nginx

在浏览器端输入 www.123.com 结果如下:

image-20230111225910455

2. 反向代理实例二

实现效果:使用 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

实现过程

1、准备两个 tomcat,一个 8001 端口,一个 8002 端口,并准备好测试的页面

重复以上步骤,部署两个tomcat并启动,修改另一个tomcat的配置文件的端口号为8081

firewall-cmd --permanent --zone=public --add-port=8081/tcp # 开放8081端口到防火墙
firewall-cmd --reload  # 让修改的配置生效

image-20230111232638236

image-20230111232647393

tomcat/webapps下创建一个目录etc并在底下创建一个html测试页面(两个tomcat都要)

image-20230111235752230

image-20230112000543031

需要注意的点:

1、两个tomcat需要更改其中一个tomcat的端口号

2、在webapps目录下创建了对应的静态资源之后需要重启两个tomcat,否则会报404

2、修改 nginx 的配置文件

在 http 块中添加 server{}块

server{
    listen    9001;   #  表示监听的端口
    server_name  192.168.1.5;  # 表示server的名字这里定义端口号

    location ~ /edu/ {   # 正则表达式的一种写法,表示路径匹配到/edu时就执行代码块里的操作
        proxy_pass  http://127.0.0.1:8080;   # 表示转发到http://127.0.0.1:8080这个地址
    }

    location ~ /vdu/ {
        proxy_pass  http://127.0.0.1:8081;  # 表示转发到http://127.0.0.1:8081这个地址
    }
}

更改配置完毕后一定一定一定要开放对应的端口号到防火墙,虽然我们可以关闭防火墙一劳永逸,但是我们要养成习惯,毕竟关闭就少了安全性

firewall-cmd --permanent --zone=public --add-port=9001/tcp # 开放8080端口到防火墙
firewall-cmd --reload  # 让修改的配置生效

location 指令说明 该指令用于匹配 URL。

语法如下:

1、= :用于不含正则表达式的 uri 前,要求请求字符串与 uri 严格匹配,如果匹配成功,就停止继续向下搜索并立即处理该请求。

2、~:用于表示 uri 包含正则表达式,并且区分大小写。

3、~*:用于表示 uri 包含正则表达式,并且不区分大小写。

4、^~:用于不含正则表达式的 uri 前,要求 Nginx 服务器找到标识 uri 和请求字符串匹配度最高的 location 后,立即使用此 location 处理请求,而不再使用 location 块中的正则 uri 和请求字符串做匹配。

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

测试效果如图:通过

image-20230112003045634

image-20230112003112555

五、Nginx配置实例-负载均衡

1、需要实现的效果

浏览器地址栏中输入http://192.168.1.5:9001/edu/a.html,能够实现负载均衡效果,即将请求平均分到8080和8081中

2、准备工作

需要准备两台tomcat服务器,一台部署在8080,一台部署在8081

在两台tomcat里面webapps 目录中,创建名为edu的文件夹,并在文件夹内创建一样的页面,用于测试

3、 在 nginx.conf 中进行配置

在 nginx.conf 中进行配置,需要配置在http代码块中

注意!!!!!!!!是修改安装后目录下的配置文件,不是解压包解压出来的配置文件

upstream myserver{   # 负载均衡的配置
    server 39.101.65.192:8080;  # 服务器的端口+ IP
    server 39.101.65.192:8081;  # 另一台服务器的端口 + IP
}

server{
    listen    80    # 监听的端口号是80
    server_name  39.101.65.192   # 服务名称
}

    location / {    # 以下是路径匹配规则
        proxy_pass  http://myserver;   # 此处写的是本次需要被负载均衡的服务名称
    }

配置完毕以上的配置后就实现了默认的负载均衡,即输入http://39.101.65.192/edu/a.html进行访问

页面会在两个服务器(8080和8081)中轮询转换,以达到默认的负载均衡的效果,也就是轮询负载均衡的效果

如图:第一次请求:

image-20230112115722603

第二次请求:

image-20230112115731239

随着互联网信息的爆炸性增长,负载均衡(load balance)已经不再是一个很陌生的话题,顾名思义,负载均衡即是将负载分摊到不同的服务单元,既保证服务的可用性,又保证响应足够快,给用户很好的体验。快速增长的访问量和数据流量催生了各式各样的负载均衡产品,很多专业的负载均衡硬件提供了很好的功能,但却价格不菲,这使得负载均衡软件大受欢迎, nginx 就是其中的一个,在 linux 下有 Nginx、LVS、Haproxy 等等服务可以提供负载均衡服务

4、 Nginx 提供了几种分配方式(策略):

1、轮询(默认)

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

2、weight

weight 代表权,重默认为 1,权重越高被分配的客户端越多

指定轮询几率,weight 和访问比率成正比,用于后端服务器性能不均的情况。 例如:

upstream myserver{   # 负载均衡的配置
    server 39.101.65.192:8080 weight=7;  # 服务器的端口+ IP
    server 39.101.65.192:8081 weight=3;  # 另一台服务器的端口 + IP
}    # 上述配置所示,8081的权重比8080的权重要高,那么对应的访问率也会比8080高,测试部分省略

3、ip_hash

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

upstream myserver{   # 负载均衡的配置
    ip_hash;   # 这个配置的即表示客户端第一次访问的服务器,如:第一次访问的是8080,那么之后访问都是8080
    server 39.101.65.192:8080;  # 服务器的端口+ IP
    server 39.101.65.192:8081;  # 另一台服务器的端口 + IP
}

4、fair(第三方)

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

注意这个配置是第三方的插件,需要加入对应模块依赖重新编译到Nginx安装目录,以下文章是参考,此处省略

https://blog.csdn.net/Leon_Jinhai_Sun/article/details/121153174

upstream myserver{   # 负载均衡的配置
    server 39.101.65.192:8080;  # 服务器的端口+ IP
    server 39.101.65.192:8081;  # 另一台服务器的端口 + IP
    fair; # 根据服务器响应的时间来分配,响应短的服务器优先分配
}

六、Nginx配置实例-动静分离

1、 什么是动静分离

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

image-20230112135624542

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

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

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

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

2.、准备工作

在 liunx 系统中准备静态资源,用于进行访问,即创建目录,一个用于存放html页面一个用于存放image文件并在里面放测试文件

image-20230112141731584

3. 具体配置

nginx 配置文件中进行配置

server {
        listen       80;
        server_name  39.101.65.192;   # 服务名称

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location /www/ {  # 精确的匹配路径的写法,表示定位到目录www
            root    /data/;   # 设置需要映射的文件的家目录。root 设置的目录是根目录,locatoin里所指定名称的目录,必须在root设定下的目录有相同名字的目录。
            index    index.html  inde.htm;  # 固定写法,表示显示到首页
        }

        location /image/ {
            root    /data/;  # 同上
            autoindex on;   # 默认为 off,不允许列出整个目录的。on 表示 列出整个目录
        }

4. 最终测试

因为配置文件 autoindex on

http://39.101.65.192/image/

image-20230112150648453

浏览器中输入地址

http://39.101.65.192/image/1.jpg

image-20230112150720085

在浏览器地址栏输入地址

http://39.101.65.192/www/a.html

image-20230112151112557

七、Nginx搭建高可用集群

1、Nginx 高可用集群(主从模式)

什么是高可用?

正常的Nginx执行过程中,我们通常会通过Nginx转发到不同的Tomcat服务器中,大概的执行过程如下:

但问题随之而来:

  • 以上的模式仅限于系统量级不大的情况下,但随着系统量级和用户量的增大,服务器势必扛不住高流量的压力,从而导致Nginx宕机,无法实现通过Nginx转发的效果,那么这个时候我们为了避免Nginx的宕机,推出高可用的集群架构,图解如下:

image-20230112155548349

对上图的解释如下:

  • 由于单台服务器已经无法满足系统流量大的需求,即一台Nginx宕机后我们为了让服务正常访问,推出了一种架构模式就是主从模式,如图,架构中有两台Nginx,一台是主,一台是从,通过keepaliver绑定两台Nginx并对外暴露一个虚拟IP供外部访问,当主Nginx服务器宕机时,keepalived就会检测并自动切换到另一台Nginx服务器上,以实现高可用的效果

2、配置高可用的准备工作

1、需要两台服务器

  • 我这里准备了两台虚拟机,别问为什么不用docker,docker只能配着玩玩,安全性是不如宿主机的
  • IP分别是 192.168.1.5(虚拟机IP) 和 192.168.6.152

2、需要在两台服务器上都安装好 Nginx (安装好了这步就跳过)

3、需要在两台服务器上都安装好keepaliver

3、 在两台服务器上安装keepalived

1、使用yum命令安装

yum install keepalived -y

2、安装完成之后,在etc里面生成keepalived,有文件keepalived.conf

4. 完成高可用配置(主从配置)

1、修改/etc/keepalived/keepalived.conf配置文件

global_defs {   # 表示全局定义

notification_email {

acassen@firewall.loc

failover@firewall.loc

sysadmin@firewall.loc

}

notification_email_from Alexandre.Cassen@firewall.loc

smtp_server 192.168.17.129

smtp_connect_timeout 30

router_id LVS_DEVEL   # 表示唯一的IP

}

vrrp_script chk_http_port {   # 检测脚本的作用用于检测服务是否存活
script "/usr/local/src/nginx_check.sh"

interval 2    #(检测脚本执行的间隔)

weight 2   # 权重的参数

}

vrrp_instance VI_1 {   # 虚拟IP的配置,此配置是主配置机的网卡配置

state BACKUP    # 备份服务器上将 MASTER 改为 BACKUP

interface eth0    //网卡

virtual_router_id 51    # 主、备机的 virtual_router_id 必须相同

priority 100    # 主、备机取不同的优先级,主机值较大,备份机值较小

advert_int 1

authentication {

auth_type PASS


auth_pass 1111

}

virtual_ipaddress {

192.168.17.50 // VRRP H 虚拟地址

}

}

2、在/usr/local/src添加检测脚本

#!/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

3、把两台服务器上nginx和keepalived启动

启动nginx

systemctl start nginx

启动keepalived

systemctl start keepalived.service

5. 最终测试

1、在浏览器地址栏输入虚拟地址ip 192.168.17.50

需要注意的是设置虚拟IP的网段地址必须一致,即必须在同一网段下

image-20230112173949519

2、把主服务器(192.168.17.129) nginx和keepalived停止,在输入192.168.17.50

image-20230112174245885

八、Nginx原理及优化参数配置

1、master和worker

image-20230112175135024

2、worker如何进行工作

image-20230112175258704

3、一个master和多个woker有好处

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

  1. 可以使用nginx –s reload热部署,利用nginx进行热部署操作
  2. 每个woker是独立的进程,如果有其中的一个woker出现问题,其他woker独立的,继续进行争抢,实现请求过程,不会造成服务中断

4、设置多少个worker合适

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

设置worker 数量: worker_processes 4 work 绑定 cpu(4 work 绑定 4cpu)。

5、连接数worker_connection

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

第一个:发送请求,占用了woker 的几个连接数?

答案:2或者4个

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

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

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

相关文章
|
6月前
|
tengine Rust 负载均衡
反向代理学习笔记(一) Nginx与反向代理绪论
反向代理学习笔记(一) Nginx与反向代理绪论
|
6月前
|
Kubernetes 应用服务中间件 nginx
nginx-ingress学习笔记
nginx-ingress学习笔记
135 0
|
前端开发 应用服务中间件 nginx
前端学习笔记202305学习笔记第二十三天-nginx项目部署500情况
前端学习笔记202305学习笔记第二十三天-nginx项目部署500情况
61 0
|
负载均衡 前端开发 应用服务中间件
Nginx学习笔记
Nginx学习笔记
|
JavaScript 前端开发 应用服务中间件
前端学习笔记202305学习笔记第二十三天-vue打包nginx部署
前端学习笔记202305学习笔记第二十三天-vue打包nginx部署
82 0
|
缓存 算法 前端开发
网站流量日志埋点收集—后端脚本(nginx+lua)|学习笔记
快速学习网站流量日志埋点收集—后端脚本(nginx+lua)
581 0
网站流量日志埋点收集—后端脚本(nginx+lua)|学习笔记
|
负载均衡 Java 应用服务中间件
案例开发-搭建 fastDSF 加 Nginx 文件服务器| 学习笔记
快速学习案例开发-搭建 fastDSF 加 Nginx 文件服务器。
案例开发-搭建 fastDSF 加 Nginx 文件服务器| 学习笔记
|
SQL JSON 监控
课时3: Nginx 日志分析 | 学习笔记
快速学习课时3: Nginx 日志分析,介绍了课时3: Nginx 日志分析系统机制, 以及在实际应用过程中如何使用。
课时3: Nginx 日志分析 | 学习笔记
|
存储 JSON 监控
Nginx 日志分析(三)| 学习笔记
快速学习 Nginx 日志分析。
Nginx 日志分析(三)| 学习笔记
|
SQL 监控 应用服务中间件
Nginx 日志分析(二)| 学习笔记
快速学习 Nginx 日志分析。
Nginx 日志分析(二)| 学习笔记