Nginx应用场景

  |   0 评论   |   0 浏览

Nginx应用场景

Nginx配置文件说明

Nginx 的配置文件位置

1、文件位置

安装目录\conf\nginx.conf
安装目录\nginx.conf

2、两个文件是一样的

3、使用 /usr/local/nginx/sbin/nginx 启动 Nginx ,默认用的是 安装目录 \nginx.conf 配置文件

4、作用:完成对 Nginx 的各种配置,包括端口,并发数,重写规则等

1.反向代理

img

配置说明:当浏览器对nginx所在服务器发起请求时,比如:192.168.79.111/XXX 请求会被转发到linux本机安装的tomcat端口为8080,当然如果nginx和tomcat不在同一个服务器proxy_pass更改为对应的IP和端口即可。

这样做的好处在于只需对外暴露nginx所在的服务器ip,而不必暴露tomcat所在服务器ip。

server {
        listen       80;
        # Nginx所在得服务器得ip
        server_name  192.168.79.111;


        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            # 当浏览器请求192.168.79.111/XXX就会转发到127.0.0.1:8080/XXX
            proxy_pass http://127.0.0.1:8080;
            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;
        }
}

2.负载均衡

负载均衡就是将负载分摊到不同的服务单元,既保证服务的可用性,又保证响应足够快

linux 下有 Nginx、LVS、Haproxy 等等服务可以提供负载均衡服务, Nginx 提供了几种分
配方式(策略):

1、轮询(默认)

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

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

upstream llpservers{
	server 192.168.79.111:8080 weight=1;
	server 192.168.79.111:8081 weight=2;
}

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

upstream llpservers{
	ip_hash;
	server 192.168.79.111:8081;
	server 192.168.79.111:8080;
}

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

upstream llpservers{
server 192.168.79.111:8080;
server 192.168.79.111:8081;
fair;
}

image-20221022225626831

#1.配置要进行负载均衡的服务器ip和端口 llpservers由可以根据实际情况命名
    #2.注意upstream上游服务器配置在http全局块中
    upstream llpservers {
        server 192.168.79.111:8080;
        server 192.168.79.111:8081;
    }
	
	#配置nginx要监听的端口和ip
    server {
        listen       80;
        server_name  192.168.79.111;


        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
           # proxy_pass http://127.0.0.1:8080;
           #1.指定要对那一组服务器进行负载均衡
           #2.llpservers在前面进行了配置
             proxy_pass http://llpservers;
            index  index.html index.htm;
        }

ps:小技巧执行在nginx安装目录执行./sbin/nginx -t可以检查配置那里有问题

img

3.动静分离

什么时动静分离?

img

  1. Nginx 动静分离简单来说就是把动态跟静态请求分开,可以理解成使用 Nginx 处理静态
    页面/资源,Tomcat 处理动态页面/资源。
  2. 动静分离可以减轻 Tomcat 压力,静态请求由 Nginx 处理,提供系统整体性能.
  3. 不管是前后端分离项目还是传统项目,动静分离在nginx中都是配置动态应用和静态应用的Localtion匹配规则
location / {
            root /usr/local/nginx/html/dist;
            index  index.html index.htm;
        }

规则说明:已nginx服务器ip为192.168.109.130为例,/usr/local/nginx/html/dist目录存放的是一个前端项目,当浏览器请求192.168.109.130/XX资源时,会到 /usr/local/nginx/html/dist目录下去查找资源

192.168.109.130/1.jpg ----> 192.168.109.130//usr/local/nginx/html/dist/1.jpg

3.Nginx资源压缩

建立在动静分离的基础之上,如果一个静态资源的Size越小,那么自然传输速度会更快,同时也会更节省带宽,因此我们在部署项目时,也可以通过Nginx对于静态资源实现压缩传输,一方面可以节省带宽资源,第二方面也可以加快响应速度并提升系统整体吞吐。

Nginx也提供了三个支持资源压缩的模块ngx_http_gzip_module、ngx_http_gzip_static_module、ngx_http_gunzip_module,其中ngx_http_gzip_module属于内置模块,代表着可以直接使用该模块下的一些压缩指令,后续的资源压缩操作都基于该模块,先来看看压缩配置的一些参数/指令:

参数项释义参数值
gzip开启或关闭压缩机制on/off;
gzip_types根据文件类型选择性开启压缩机制image/png、text/css...
gzip_comp_level用于设置压缩级别,级别越高越耗时1~9(越高压缩效果越好)
gzip_vary设置是否携带Vary:Accept-Encoding头域的响应头部on/off;
gzip_buffers设置处理压缩请求的缓冲区数量和大小数量 大小,如16 8k;
gzip_disable针对不同客户端的请求来设置是否开启压缩.*Chrome.*;
gzip_http_version指定压缩响应所需要的最低HTTP请求版本1.1;
gzip_min_length设置触发压缩的文件最低大小512k;
gzip_proxied对于后端服务器的响应结果是否开启压缩off、expired、no-cache...

了解了Nginx中的基本压缩配置后,接下来可以在Nginx中简单配置一下:

http{
    # 开启压缩机制
    gzip on;
    # 指定会被压缩的文件类型(也可自己配置其他类型)
    gzip_types text/plain application/javascript text/css application/xml text/javascript image/jpeg image/gif image/png;
    # 设置压缩级别,越高资源消耗越大,但压缩效果越好
    gzip_comp_level 5;
    # 在头部中添加Vary: Accept-Encoding(建议开启)
    gzip_vary on;
    # 处理压缩请求的缓冲区数量和大小
    gzip_buffers 16 8k;
    # 对于不支持压缩功能的客户端请求不开启压缩机制
    gzip_disable "MSIE [1-6]\."; # 低版本的IE浏览器不支持压缩
    # 设置压缩响应所支持的HTTP最低版本
    gzip_http_version 1.1;
    # 设置触发压缩的最小阈值
    gzip_min_length 2k;
    # 关闭对后端服务器的响应结果进行压缩
    gzip_proxied off;
}

在上述的压缩配置中,最后一个gzip_proxied选项,可以根据系统的实际情况决定,总共存在多种选项:

  • off:关闭Nginx对后台服务器的响应结果进行压缩。
  • expired:如果响应头中包含Expires信息,则开启压缩。
  • no-cache:如果响应头中包含Cache-Control:no-cache信息,则开启压缩。
  • no-store:如果响应头中包含Cache-Control:no-store信息,则开启压缩。
  • private:如果响应头中包含Cache-Control:private信息,则开启压缩。
  • no_last_modified:如果响应头中不包含Last-Modified信息,则开启压缩。
  • no_etag:如果响应头中不包含ETag信息,则开启压缩。
  • auth:如果响应头中包含Authorization信息,则开启压缩。
  • any:无条件对后端的响应结果开启压缩机制。

OK~,简单修改好了Nginx的压缩配置后,我们来做个测试 ,下面是我做了上传得静态文件,以app.7733e065.js文件为例没用压缩之前是241kb

image-20230113093433546

配置压缩,重启nginx之后再次访问,可以看到app.7733e065.js只有79kb,效果还是很明显得.

配置压缩并不会影响图片清晰度,但是会比较耗费性能占用带宽.

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Jan5OT8b-1674027324348)(http://cdn.llinp.cn/imgs/202301130943242.png)]

4.Nginx设置ip黑白名单

有时候往往有些需求,可能某些接口只能开放给对应的合作商,或者购买/接入API的合作伙伴,那么此时就需要实现类似于IP白名单的功能。而有时候有些恶意攻击者或爬虫程序,被识别后需要禁止其再次访问网站,因此也需要实现IP黑名单。那么这些功能无需交由后端实现,可直接在Nginx中处理。

Nginx做黑白名单机制,主要是通过allow、deny配置项来实现:

allow xxx.xxx.xxx.xxx; # 允许指定的IP访问,可以用于实现白名单。
deny xxx.xxx.xxx.xxx; # 禁止指定的IP访问,可以用于实现黑名单。

要同时屏蔽/开放多个IP访问时,如果所有IP全部写在nginx.conf文件中显然是不合适的,这种方式比较冗余,那么可以新建两个文件BlocksIP.conf、WhiteIP.conf

# --------黑名单:BlocksIP.conf---------
deny 192.177.12.222; # 屏蔽192.177.12.222访问
deny 192.177.44.201; # 屏蔽192.177.44.201访问
deny 127.0.0.0/8; # 屏蔽127.0.0.1到127.255.255.254网段中的所有IP访问

# --------白名单:WhiteIP.conf---------
allow 192.177.12.222; # 允许192.177.12.222访问
allow 192.177.44.201; # 允许192.177.44.201访问
allow 127.45.0.0/16; # 允许127.45.0.1到127.45.255.254网段中的所有IP访问
deny all; # 除开上述IP外,其他IP全部禁止访问

分别将要禁止/开放的IP添加到对应的文件后,可以再将这两个文件在nginx.conf中导入:

nginx有两个配置文件,安装目录\conf\nginx.conf、安装目录\nginx.conf,nginx以哪一个配置文件启动就配置在哪一个文件中,这里以安装目录\nginx.conf为例,引入BlocksIP.conf和WhiteIPs.conf的配置和安装目录\nginx.conf在同一个目录即可,也可以指定绝对路径

http{
    # 屏蔽该文件中的所有IP
    include include BlocksIP.conf; 
 server{
    location xxx {
        # 某一系列接口只开放给白名单中的IP
        include WhiteIPs.conf; 
    }
 }
}

重启nginx

/usr/local/nginx/sbin/nginx -s reload

对于文件具体在哪儿导入,这个也并非随意的,如果要整站屏蔽/开放就在http中导入,如果只需要一个域名下屏蔽/开放就在sever中导入,如果只需要针对于某一系列接口屏蔽/开放IP,那么就在location中导入。

也可以通过ngx_http_geo_module、ngx_http_geo_module第三方库去实现(这种方式可以按地区、国家进行屏蔽,并且提供了IP库)。

5.Nginx解决跨域问题

跨域问题在之前的单体架构开发中,其实是比较少见的问题,除非是需要接入第三方SDK时,才需要处理此问题。但随着现在前后端分离、分布式架构的流行,跨域问题也成为了每个Java开发必须要懂得解决的一个问题。

跨域问题产生的原因

产生跨域问题的主要原因就在于**「同源策略」** ,为了保证用户信息安全,防止恶意网站窃取数据,同源策略是必须的,否则cookie可以共享。由于http无状态协议通常会借助cookie来实现有状态的信息记录,例如用户的身份/密码等,因此一旦cookie被共享,那么会导致用户的身份信息被盗取。 同源策略主要是指三点相同,「协议+域名+端口」 相同的两个请求,则可以被看做是同源的,但如果其中任意一点存在不同,则代表是两个不同源的请求,同源策略会限制了不同源之间的资源交互。

Nginx解决跨域问题

弄明白了跨域问题的产生原因,接下来看看Nginx中又该如何解决跨域呢?其实比较简单,在nginx.conf中稍微添加一点配置即可:

location / {
    # 允许跨域的请求,可以自定义变量$http_origin,*表示所有
    add_header 'Access-Control-Allow-Origin' *;
    # 允许携带cookie请求
    add_header 'Access-Control-Allow-Credentials' 'true';
    # 允许跨域请求的方法:GET,POST,OPTIONS,PUT
    add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT';
    # 允许请求时携带的头部信息,*表示所有
    add_header 'Access-Control-Allow-Headers' *;
    # 允许发送按段获取资源的请求
    add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
    # 一定要有!!!否则Post请求无法进行跨域!
    # 在发送Post跨域请求前,会以Options方式发送预检请求,服务器接受时才会正式请求
    if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Type' 'text/plain; charset=utf-8';
        add_header 'Content-Length' 0;
        # 对于Options方式的请求返回204,表示接受跨域请求
        return 204;
    }
 }

nginx.conf文件加上如上配置后,跨域请求即可生效了。

但如果后端是采用分布式架构开发的,有时候RPC调用也需要解决跨域问题(不同服务之间),不然也同样会出现无法跨域请求的异常,因此可以在你的后端项目中,通过继承HandlerInterceptorAdapter类、实现WebMvcConfigurer接口、添加@CrossOrgin注解的方式实现接口之间的跨域配置。

6.Nginx防盗链

首先了解一下何谓盗链:「盗链即是指外部网站引入当前网站的资源对外展示」 ,来举个简单的例子理解:

好比壁纸网站X站、Y站,X站是一点点去购买版权、签约作者的方式,从而积累了海量的壁纸素材,但Y站由于资金等各方面的原因,就直接通过<img src="X站/xxx.jpg" />这种方式照搬了X站的所有壁纸资源,继而提供给用户下载。

Nginx的防盗链机制实现,跟一个头部字段:Referer有关,该字段主要描述了当前请求是从哪儿发出的,那么在Nginx中就可获取该值,然后判断是否为本站的资源引用请求,如果不是则不允许访问。Nginx中存在一个配置项为valid_referers,正好可以满足前面的需求,语法如下:

  • valid_referers none | blocked | server_names | string ...;
    • none:表示接受没有Referer字段的HTTP请求访问。
    • blocked:表示允许http://https//以外的请求访问。
    • server_names:资源的白名单,这里可以指定允许访问的域名。
    • string:可自定义字符串,支配通配符、正则表达式写法。

简单了解语法后,接下来的实现如下:

# 在动静分离的location中开启防盗链机制
location ~ .*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|txt|js|css){
    # 最后面的值在上线前可配置为允许的域名地址或ip
    valid_referers blocked 192.168.12.129;
    if ($invalid_referer) {
        # 可以配置成返回一张禁止盗取的图片
        # rewrite   ^/ http://xx.xx.com/NO.jpg;
        # 也可直接返回403
        return   403;
    }
    
    root    /soft/nginx/static_resources;
    #当nginx设置了expires后,例如设置为:expires 10d;  
    #那么,所在的location或if的内容,用户在10天内请求的时候,
    #都只会访问浏览器中的缓存,而不会去请求nginx。
    #ps:需要注意的是,这种缓存方式只能在用户不对浏览器强制刷新的情况下生效
    #expires 30s;   #缓存30秒
	#expires 30m;   #缓存30分钟   
	#expires 2h;    #缓存2小时
	#expires 30d;   #缓存30天
    expires 7d;
}

ps:防盗链机制也无法解决爬虫伪造referers信息的这种方式抓取数据。

7.Nginx大文件传输配置

在某些业务场景中需要传输一些大文件,但大文件传输时往往都会会出现一些Bug,比如文件超出限制、文件传输过程中请求超时等,那么此时就可以在Nginx稍微做一些配置,先来了解一些关于大文件传输时可能会用的配置项:

配置项释义
client_max_body_size设置请求体允许的最大体积
client_header_timeout等待客户端发送一个请求头的超时时间
client_body_timeout设置读取请求体的超时时间
proxy_read_timeout设置请求被后端服务器读取时,Nginx等待的最长时间
proxy_send_timeout设置后端向Nginx返回响应时的超时时间

配置在nginx配置文件最外层

client_max_body_size     50m;  # 限制请求体的大小,若超过所设定的大小,返回413错误,默认1m
client_header_timeout    1m;  # 读取请求头的超时时间,若超过所设定的大小,返回408错误
client_body_timeout      1m; # 读取请求实体的超时时间,若超过所设定的大小,返回413错误
proxy_connect_timeout     60s; # http请求没法当即被容器(tomcat, netty等)处理,被放在nginx的待处理池中等待被处理。此参数为等待的最长时间,默认为60秒,官方推荐最长不要超过75秒
proxy_read_timeout      1m;  # http请求被容器(tomcat, netty等)处理后,nginx会等待处理结果,也就是容器返回的response。此参数即为服务器响应时间,默认60秒
proxy_send_timeout      1m; # http请求被服务器处理完后,把数据传返回给Nginx的用时,默认60秒

8.Nginx配置SLL证书

随着越来越多的网站接入HTTPS,因此Nginx中仅配置HTTP还不够,往往还需要监听443端口的请求,HTTPS为了确保通信安全,所以服务端需配置对应的数字证书,当项目使用Nginx作为网关时,那么证书在Nginx中也需要配置,接下来简单聊一下关于SSL证书配置过程:

  • ①先去CA机构或从云控制台中申请对应的SSL证书,审核通过后下载Nginx版本的证书。
  • ②下载数字证书后,完整的文件总共有三个:.crt、.key、.pem
    • .crt:数字证书文件,.crt.pem的拓展文件,因此有些人下载后可能没有。
    • .key:服务器的私钥文件,及非对称加密的私钥,用于解密公钥传输的数据。
    • .pemBase64-encoded编码格式的源证书文本文件,可自行根需求修改拓展名。
  • ③在Nginx目录下新建certificate目录,并将下载好的证书/私钥等文件上传至该目录。
  • ④最后修改一下nginx.conf文件即可,如下:
# ---------HTTP请求转HTTPS-------------
server {
    # 监听HTTP默认的80端口
    listen 80;
    # 如果80端口出现访问该域名的请求
    server_name www.xxx.com;
    # 将请求改写为HTTPS(这里写你配置了HTTPS的域名)
    rewrite ^(.*)$ https://www.xxx.com;
}

# ----------HTTPS配置-----------
server {
    # 监听HTTPS默认的443端口
    listen 443;
    # 配置自己项目的域名
    server_name www.xxx.com;
    # 打开SSL加密传输
    ssl on;
    # 输入域名后,首页文件所在的目录
    root html;
    # 配置首页的文件名
    index index.html index.htm index.jsp index.ftl;
    # 配置自己下载的数字证书
    ssl_certificate  certificate/xxx.pem;
    # 配置自己下载的服务器私钥
    ssl_certificate_key certificate/xxx.key;
    # 停止通信时,加密会话的有效期,在该时间段内不需要重新交换密钥
    ssl_session_timeout 5m;
    # TLS握手时,服务器采用的密码套件
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    # 服务器支持的TLS版本
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    # 开启由服务器决定采用的密码套件
    ssl_prefer_server_ciphers on;

 		#如果是静态文件,直接指向目录,如果是动态应用,用proxy_pass转发一下
        location / {
                root /usr/local/service/ROOT;
                index index.html;
        }
        #动态应用
        location / {
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header Host $http_host;
            proxy_pass http://ip:port;
        }
}

标题:Nginx应用场景
作者:llp
地址:https://llinp.cn/articles/2023/03/13/1678715842963.html