nginx 常用优化配置项教程

本文目录

跨域配置

动静分离

反向代理-负载均衡

配置SLL证书

资源压缩

缓存机制

IP黑白名单

防盗链

大文件传输优化

跨域问题

产生原因

产生跨域问题的主要原因就在于 「同源策略」 ,为了保证用户信息安全,防止恶意网站窃取数据,同源策略是必须的,否则cookie可以共享。由于http无状态协议通常会借助cookie来实现有状态的信息记录,例如用户的身份/密码等,因此一旦cookie被共享,那么会导致用户的身份信息被盗取。

同源策略主要是指三点相同,协议+域名+端口 相同的两个请求,则可以被看做是同源的,但如果其中任意一点存在不同,则代表是两个不同源的请求,同源策略会限制了不同源之间的资源交互。

解决跨域问题

  • 方式一:直接在 nginx 配置文件的服务 server 模块中适当添加如下内容(然后重启生效)
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;  
    }  
}  
  • 方式二:后端代码中配置,以 golang 语言的 Gin 框架中间件包增加如下示例
package middleware
import (
	"github.com/gin-contrib/cors"
	"github.com/gin-gonic/gin"
)
func Cors() gin.HandlerFunc {
	config := cors.DefaultConfig()
	config.AllowAllOrigins = true
	return cors.New(config)
}
func CORS() gin.HandlerFunc {
	return func(c *gin.Context) {
		c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
		c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
		c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")
		c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT, DELETE")

		if c.Request.Method == "OPTIONS" {
			c.AbortWithStatus(204)
			return
		}

		c.Next()
	}
}

动静分离

动静分离应该是听的次数较多的性能优化方案,首先需要知道为啥要动静分离

我们部署 web 网站时都会将静态文件一起打包,跟随项目部署到服务某个目录,一般我们都会把这些文件放到项目根目录的 static 目录下,这些文件是大概率不会有太大变动的。当我们访问前端页面,刚开始加载的时候都会有大量请求加载各种静态资源文件,比如 html/js/css/image等等。

比如上图百度首页,就会有至少100+的请求静态资源,那么这些请求都会来到部署WEB服务的机器处理,那则代表着一个客户端请求百度首页,就会对后端服务器造成100+的并发请求,毫无疑问,这对于后端服务器的压力是尤为巨大的。

所以想办法在此之前就提前处理掉,因此有了「「动静分离」」 而且 至少能够让后端服务减少一半以上的并发量。

实现方式如下,需要在 Nginx 配置下添加一条 location 规则

location ~ .*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|txt|js|css){  
    root   /soft/nginx/static_resources;  #静态资源存放目录
    expires 7d;  
} 

该配置表示匹配以.html~.css为后缀的所有资源请求

  • ~代表匹配时区分大小写
  • .*代表任意字符都可以出现零次或多次,即资源名不限制
  • \.代表匹配后缀分隔符.
  • (html|...|css)代表匹配括号里所有静态资源类型

反向代理-负载均衡

为啥要用负载均衡

  • 单体结构无法承载日益增长的请求量
  • 当单体节点宕机后,整个系统会挂掉

因此引入负载均衡,它有以下优势

  • 「高可用:」 当某个节点宕机后可以迅速将流量转移至其他节点
  • 「高性能:」 多台服务器共同对外提供服务,为整个系统提供了更高规模的吞吐
  • 「拓展性:」 当业务再次出现增长或萎靡时,可再加入/减少节点,灵活伸缩

Nginx是目前负载均衡技术中的主流方案,是基于多路复用模型,主要就是【资源占用少、并发支持高】

原本客户端是直接请求目标服务器,由目标服务器直接完成请求处理工作,但加入Nginx后,所有的请求会先经过Nginx,再由其进行分发到具体的服务器处理,处理完成后再返回Nginx,最后由Nginx将最终的响应结果返回给客户端。

下面是一个负载均衡的配置示例

upstream nginx_server{  
   # 请求分发权重比为1:2   30s内检查心跳发送两次包,未回复就代表该机器宕机, 
   server 192.168.1.000:8001 weight=100 max_fails=2 fail_timeout=30s;   
   server 192.168.1.000:8002 weight=200 max_fails=2 fail_timeout=30s;  
}  
  
server {  
    listen 80;
    location / {  
        root   html;  
        index  index.html index.htm
        proxy_set_header Host $host;  
        proxy_set_header X-Real-IP $remote_addr;  
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  
        # 请求交给名为nginx_server的upstream上  
        proxy_pass http://nginx_server;  
    }  
}  

配置 SLL 证书

一般网站都会接入HTTPS,因此Nginx还需要监听443端口的请求,HTTPS为了确保通信安全,所以服务端需配置对应的数字证书,当项目使用Nginx部署时,那么证书在Nginx中也需要有相应的配置,

SSL证书配置步骤

  • 先去CA机构或从云控制台中申请对应的SSL证书,审核通过后下载Nginx版本的证书
  • 下载数字证书后,完整的文件总共有三个:.crt、.key、.pem
  • .crt:数字证书文件,.crt.pem的拓展文件,因此有些人下载后可能没有。
  • .key:服务器的私钥文件,及非对称加密的私钥,用于解密公钥传输的数据。
  • .pemBase64-encoded编码格式的源证书文本文件,可自行根需求修改拓展名。

最后添加 nginx 配置,如下所以,然后重启访问:https:localhost 查看是否生效

server {
	listen       80;
	# 添加监听 https 端口
	listen 443 ssl;
	server_name  localhost;	 
	# 根目录
	location / {
		# vue项目的打包后的dist
		root  /webapp/dist;
		index  index.html index.htm;
	}   

	# 填写证书文件的相对路径或绝对路径
	ssl_certificate /webapp/ng_https/xxx.crt;
	# 填写私钥文件的相对路径或绝对路径
	ssl_certificate_key /webapp//ng_https/xxx.key;
	ssl_session_timeout 5m;
	#请按照以下协议配置
	ssl_protocols TLSv1.2 TLSv1.3;
	#请按照以下套件配置,配置加密套件,写法遵循 openssl 标准。
	ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
	ssl_prefer_server_ciphers on;

	# 下面是强制 https 访问方式,按需打开
 	#rewrite ^(.*)$ https://$host$1   permanent;
}

资源压缩

在动静分离的基础之上,如果一个静态资源的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/cs5...
gzip_comp_level用于设置压缩级别,级别越高越耗时越高压缩效果越好
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-cach

如下是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;
}
  • 对于图片、视频类型的数据,会默认开启压缩机制,因此一般无需再次开启压缩
  • 对于.js文件而言,需要指定压缩类型为application/javascript,而并非text/javascript、application/x-javascript。

缓存机制

对于性能优化而言,缓存是一种能够大幅度提升性能的方案,因此几乎可以在各处都能看见缓存,如客户端缓存、代理缓存、服务器缓存等等,Nginx的缓存则属于代理缓存的一种,它包含以下优势

  • 减少向后端或文件服务器请求资源的带宽消耗
  • 降低了下游服务器的访问压力,提升系统整体吞吐
  • 缩短了响应时间,提升了加载速度,打开页面的速度更快

Nginx中,配置代理缓的配置项:(如下示例)

「proxy_cache_path」:代理缓存的路径

http {
   proxy_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size] [manager_files=number] [manager_sleep=time] [manager_threshold=time] [loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time];
}

参数含义

  • path:缓存的路径地址。
  • levels:缓存存储的层次结构,最多允许三层目录。
  • use_temp_path:是否使用临时目录。
  • keys_zone:指定一个共享内存空间来存储热点Key(1M可存储8000个Key)。
  • inactive:设置缓存多长时间未被访问后删除(默认是十分钟)。
  • max_size:允许缓存的最大存储空间,超出后会基于LRU算法移除缓存,Nginx会创建一个Cache manager的进程移除数据,也可以通过purge方式。
  • manager_files:manager进程每次移除缓存文件数量的上限。
  • manager_sleep:manager进程每次移除缓存文件的时间上限。
  • manager_threshold:manager进程每次移除缓存后的间隔时间。
  • loader_files:重启Nginx载入缓存时,每次加载的个数,默认100。
  • loader_sleep:每次载入时,允许的最大时间上限,默认200ms。
  • loader_threshold:一次载入后,停顿的时间间隔,默认50ms。
  • purger:是否开启purge方式移除数据。
  • purger_files:每次移除缓存文件时的数量。
  • purger_sleep:每次移除时,允许消耗的最大时间。
  • purger_threshold:每次移除完成后,停顿的间隔时间。

「proxy_cache」:开启或关闭代理缓存,开启时需要指定一个共享内存区域。

以上 是Nginx中的缓存配置项,下面来配置一下Nginx代理缓存

http{  
    # 设置缓存的目录,并且内存中缓存区名为hot_cache,大小为128m,  
    # 三天未被访问过的缓存自动清楚,磁盘中缓存的最大容量为2GB。  
    proxy_cache_path /log/nginx/cache levels=1:2 keys_zone=hot_cache:128m inactive=3d max_size=2g;  
      
    server{  
        location / {  
            # 使用名为nginx_cache的缓存空间  
            proxy_cache hot_cache;  
            # 对于200、206、304、301、302状态码的数据缓存1天  
            proxy_cache_valid 200 206 304 301 302 1d;  
            # 对于其他状态的数据缓存30分钟  
            proxy_cache_valid any 30m;  
            # 定义生成缓存键的规则(请求的url+参数作为key)  
            proxy_cache_key $host$uri$is_args$args;  
            # 资源至少被重复访问三次后再加入缓存  
            proxy_cache_min_uses 3;  
            # 出现重复请求时,只让一个去后端读数据,其他的从缓存中读取  
            proxy_cache_lock on;  
            # 上面的锁超时时间为3s,超过3s未获取数据,其他请求直接去后端  
            proxy_cache_lock_timeout 3s;  
            # 对于请求参数或cookie中声明了不缓存的数据,不再加入缓存  
            proxy_no_cache $cookie_nocache $arg_nocache $arg_comment;  
            # 在响应头中添加一个缓存是否命中的状态(便于调试)  
            add_header Cache-status $upstream_cache_status;  
        }  
    }  
}  

IP黑白名单

当我们需要指定、或者禁止某些 ip 访问服务时(黑白名单机制),可以通过 nginx 来限制访问,主要是通过allow、deny配置项来实现

  • 单个 ip 可以直接写在 location 里面
 server{
	location ^~ /my_api/ {
		deny 192.177.12.222; # 屏蔽192.177.12.222访问
		deny 127.0.0.0/8; # 屏蔽127.0.0.1到127.255.255.254网段中的所有IP访问
		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 时,需要新建 .conf 文件来引入

白名单文件 /webapp/white.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全部禁止访问  

黑名单文件 /webapp/black.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访问  

然后在 nginx 配置文件中引入

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

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

防盗链

含义:指外部网站引入当前网站的资源对外展示

比如 aaa.com 战点的图片资源,在bbb.com站点上面提供给其他人访问

Nginx的防盗链机制跟头部字段Referer有关,该字段描述了当前请求是从哪儿发出的,那么在Nginx中就可通过判断是否为本站的资源发起的请求,如果不是则不允许访问。

利用 Nginx配置项 中的valid_referers实现防盗链功能,示例配置如下

# 在 location 中开启防盗链机制  
location ~ .*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|txt|js|css){  
    # 最后面的值在上线前可配置为允许的域名地址  
    valid_referers blocked 111.111.111.111;  
    if ($invalid_referer) {  
        # 可以配置成返回一张禁止盗取的图片  
        # rewrite   ^/ http://xx.xx.com/NO.jpg;  
        # 也可直接返回403  
        return   403;  
    }  
    root   /soft/nginx/static_resources;  
    expires 7d;  
}  

大文件传输优化

web 开发中经常会遇到一些文件的上传下载,文件小的时候没啥问题,正常处理,但是当文件大传输时往往都会会出现一些Bug ,比如文件超出限制、文件传输过程中请求超时等,此时通过Nginx稍微做一些配置,相关配置项及含义如下

配置项释义
client max body_size设置请求体允许的最大体积
client header_timeout等待客户端发送一个请求头的超时时间
client_body_timeout设置读取请求体的超时时间
proxy_read timeout设置请求被后端服务器读取时,ginx等待的最长时间
proxy_send timeout设置后端向Nginx返回响应时的超时时间

根据自己的环境、硬件进行相应配置就OK

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值