关于前端需要关注的那些nginx配置和功能

Nginx简介:

先引用一段来自百度百科的介绍:

Nginx (engine x) 是一个高性能的HTTP反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文:Рамблер)开发的,第一个公开版本0.1.0发布于2004年10月4日。

其将源代码以类BSD许可证的形式发布,因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。2011年6月1日,nginx 1.0.4发布。

Nginx是一款轻量级Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力在同类型的网页服务器中表现较好

 这篇文章我们暂时只关注这个部分:

Nginx是一款轻量级Web 服务器/反向代理服务器。

 

 

Nginx配置:

先上一张图:

然后针对一些功能和配置展开来讲讲。

负载均衡(主要是后端人员配置)

当一个应用单位时间内访问量激增,服务器的带宽及性能受到影响,影响大到自身承受能力时,服务器就会宕机奔溃,为了防止这种现象发生,以及实现更好的用户体验,我们可以通过配置Nginx负载均衡的方式来分担服务器压力

当有一台服务器宕机时,负载均衡器就分配其他的服务器给用户,极大的增加的网站的稳定性 当用户访问web时候,首先访问到的是负载均衡器,再通过负载均衡器将请求转发给后台服务器

1.1 负载均衡的几种常用方式

  • 轮询(默认)

// nginx.config
upstream backserver {
    server 192.168.0.1;
    server 192.168.0.2;
}
  • 权重weight

指定不同ip的权重,权重与访问比成正相关,权重越高,访问越大,适用于不同性能的机器

// nginx.config
upstream backserver {
    server 192.168.0.1 weight=2;
    server 192.168.0.2 weight=8;
}
  • 响应时间来分配

公平竞争,谁相应快,谁处理,不过这种方式需要依赖到第三方插件nginx-upstream-fair,需要先安装

// nginx.config
upstream backserver {
    server 192.168.0.1;
    server 192.168.0.2;
    fair;
}

server {
    listen 80;
    server_name localhost;
    location / {
      proxy_pass  http://backserver;
    }
}

1.2 健康检查

Nginx 自带 ngx_http_upstream_module(健康检测模块)本质上服务器心跳的检查,通过定期轮询向集群里的服务器发送健康检查请求,来检查集群中是否有服务器处于异常状态

如果检测出其中某台服务器异常,那么在通过客户端请求nginx反向代理进来的都不会被发送到该服务器上(直至下次轮训健康检查正常)

基本例子如下👇

upstream backserver{
    server 192.168.0.1  max_fails=1 fail_timeout=40s;
    server 192.168.0.2  max_fails=1 fail_timeout=40s;
}

server {
    listen 80;
    server_name localhost;
    location / {
      proxy_pass http://backend;
    }
}

涉及两个配置:

  • fail_timeout : 设定服务器被认为不可用的时间段以及统计失败尝试次数的时间段,默认为10s

  • max_fails : 设定Nginx与服务器通信的尝试失败的次数,默认为:1次

反向代理,解决跨域问题  (前后端都需要了解)

反向代理指的是,当一个客户端发送的请求,想要访问服务器上的内容,但将被该请求先发送到一个代理服务器proxy,这个代理服务器(Nginx)将把请求代理到和自己属于同一个局域网下的内部服务器上,而用户通过客户端真正想获得的内容就存储在这些内部服务器上,此时Nginx代理服务器承担的角色就是一个中间人,起到分配和沟通的作用

2.1 为什么需要反向代理?

反向代理的优势主要有以下两点

  • 防火墙作用

当你的应用不想直接暴露给客户端(也就是客户端无法直接通过请求访问真正的服务器,只能通过Nginx),通过nginx过滤掉没有权限或者非法的请求,来保障内部服务器的安全

  • 负载均衡

也就上一章提到负载均衡,本质上负载均衡就是反向代理的一种应用场景,可以通过nginx将接收到的客户端请求"均匀地"分配到这个集群中所有的服务器上(具体看负载均衡方式),从而实现服务器压力的负载均衡

2.2 如何使用反向代理解决前端跨域问题

前端跨域问题由来:

跨域问题的由来是浏览器的同源策略
所谓同源是指,域名,协议,端口相同。浏览器执行javascript脚本时,会检查这个脚本属于那个页面,如果不是同源页面,就不会被执行。跨域情况如下:
这里写图片描述

由此可知,就算前后端部署在同一台服务器上,如果不是起在同一个应用服务器中,那么跨域问题还是存在,因为两个服务的端口不同。那么如何来解决这个问题呢?

常用的跨域解决方法

  1. 1.jsonp 需要目标服务器配合一个callback函数。

  2. 2.window.name+iframe 需要目标服务器响应window.name。

  3. 3.window.location.hash+iframe 同样需要目标服务器作处理。

  4. 4.html5的 postMessage+ifrme 这个也是需要目标服务器或者说是目标页面写一个postMessage,主要侧重于前端通讯。

  5. 5.CORS 需要服务器设置header :Access-Control-Allow-Origin。

  6. 6.nginx反向代理 这个方法一般很少有人提及,但是他可以不用目标服务器配合,不过需要你搭建一个中转nginx服务器,用于转发请求。

我们这里将的就是通过nginx反向代理的方式解决跨域问题。

在 Nginx 反向代理是,会通过 location 功能匹配指定的 URI,然后把接收到的符合匹配 URI的请求通过 proxy_pass 转移给之前定义好的 upstream 节点池。

先看一个简单的例子:

    upstream authorize_{
		ip_hash;
		server 127.0.0.1:81;
	 }
	upstream oauth_{
		ip_hash;
		server 127.0.0.1:88;
	 }
	server {
		listen 89; // nginx监听的端口,默认是80。可以手动修改,其实也就是到时候前端页面访问的端口
		server_name  localhost;

		#charset koi8-r;

		#access_log  logs/host.access.log  main;

		location / {
			root   /program/TyAuthorization/www/;
            index  index.html index.htm;
		}

		location /authorize{
			proxy_pass   http://authorize_/api/v1/authorize;
			proxy_redirect off;
			proxy_set_header Host $host;
			proxy_set_header X-Forwarded-For $remote_addr;
		}
		
		location /oauth{
			proxy_pass   http://oauth_/oauth;
			proxy_redirect off;
			proxy_set_header Host $host;
			proxy_set_header X-Forwarded-For $remote_addr;
		}
		
		location /files {
		  alias	/program/web/static/;
		  autoindex on;
		}

		error_page  404			  /404.html;

		error_page   500 502 503 504  /50x.html;
		location = /50x.html {
			root   html;
		}
	}

 

说明:nginx监听89端口,可以手动修改,其实也就是到时候前端页面访问的端口。所有到这个端口的请求都通过nginx来转发,默认会进到root目录下的静态页面 , 也就是 location / 这条协议路径。

但是当请求匹配到“/authorize_”或者“/oauth_”等协议路径时,则该请求会被转发到上面配置的upstream对应的server地址上,而匹配到“/files”时,则直接访问当前nginx服务器的本地路径:/program/web/static/, 这种情况一般用来预览或者下载文件。

PS: location 后面跟的协议路径是可以使用正则表达式的,如:

location ~* \.(png|gif|jpg|jpeg)$ {
    root    pragram/web/static/;  
    autoindex on;
    access_log  off;
    expires     10h;# 设置过期时间为 10 小时          
}

匹配以png|gif|jpg|jpeg为结尾的请求,并将请求转发到本地路径。

 

Gzip 配置开启 文件压缩

GZIP是规定的三种标准 HTTP 压缩格式之一。目前绝大多数的网站都在使用GZIP传输 HTMLCSSJavaScript 等资源文件。

对于文本文件,GZip 的效果非常明显,开启后传输所需流量大约会降至 1/4 ~ 1/3

并不是每个浏览器都支持gzip的,如何知道客户端是否支持gzip呢,请求头中的Accept-Encoding来标识对压缩的支持。

启用gzip同时需要客户端和服务端的支持,如果客户端支持gzip的解析,那么只要服务端能够返回gzip的文件就可以启用gzip了, 我们可以通过nginx的配置来让服务端支持gzip。下面的responecontent-encoding:gzip,指服务端开启了gzip的压缩方式。

在nginx配置中,把gzip 设置为on, 就表示开启了gzip

    gzip                    on;
    gzip_http_version       1.1;        
    gzip_comp_level         5;
    gzip_min_length         1000;
    gzip_types text/csv text/xml text/css text/plain text/javascript application/javascript application/x-javascript application/json application/xml;

 gzip

  • 开启或者关闭gzip模块

  • 默认值为off

  • 可配置为on / off

 gzip_http_version

  • 启用 GZip 所需的HTTP 最低版本

  • 默认值为HTTP/1.1

这里为什么默认版本不是1.0呢?

HTTP 运行在TCP 连接之上,自然也有着跟TCP 一样的三次握手、慢启动等特性。

启用持久连接情况下,服务器发出响应后让TCP连接继续打开着。同一对客户 / 服务器之间的后续请求和响应可以通过这个连接发送。

为了尽可能的提高 HTTP 性能,使用持久连接就显得尤为重要了。

HTTP/1.1默认支持TCP持久连接,HTTP/1.0 也可以通过显式指定 Connection: keep-alive来启用持久连接。

看一下对比:

不开启gzip:

在这里插入图片描述

开启gizp

在这里插入图片描述

开启之后,Content-Encoding: gzip; ETag: W/"~~~";
这里的ETag中的 W\ 就是区分是否是在线写入压缩的标识;

开启gzip298KB 可以减少到 104KB,效率还是不错的;

 

但是,对于很多前端项目来说,只是开启gzip是不够的。

继续来说说 gzip_static

 

在前端代码打包构建bundle的时候,一般都有根据一定的算法自动压缩代码成gz文件的webpack插件;

当我们不在 nginx 开启 gzip_static的时候,发现生产的gz文件并没有被运行,这个时候其实是无效的,它并没有加载前端打包之后的.gz文件。

而gzip_static是会自动执行gz文件的,这样的就避免了通过gzip自动压缩;

在这里插入图片描述

我们上面讲到通过gzip自动压缩是 104KB,而我们自己压缩的是90KB,所有如果运行了我们自己的gz文件,会更好。

所以,gzip static 也需要设置为 on

    gzip                    on;
    gzip static             on;
    gzip_http_version       1.1;        
    gzip_comp_level         5;
    gzip_min_length         1000;
    gzip_types text/csv text/xml text/css text/plain text/javascript application/javascript application/x-javascript application/json application/xml;

 在这里插入图片描述

 在这里插入图片描述

 

但是nginx上配置gzip static会遇到一些问题,具体可以参考我之前的文章:

https://blog.csdn.net/yorcentroll/article/details/102686680

 

请求过滤

根据状态码过滤

error_page 500 501 502 503 504 506 /50x.html;
    location = /50x.html {
        # 将跟路径改编为存放 html 的路径。
        root /root/static/html;
    }

根据 URL 名称过滤,精准匹配 URL,不匹配的 URL 全部重定向到主页。

location / {
    rewrite  ^.*$ /index.html  redirect;
}

根据请求类型过滤。

if ( $request_method !~ ^(GET|POST|HEAD)$ ) {
        return 403;
    }

 

适配PC与移动环境

当用户从移动端打开PC端baidu.com的场景时,将自动跳转指移动端m.baidu.com,本质上是Nginx可以通过内置变量$http_user_agent,获取到请求客户端的userAgent,从而知道当前用户当前终端是移动端还是PC,进而重定向到H5站还是PC站

server {
 location / {
        //移动、pc设备agent获取
        if ($http_user_agent ~* '(Android|webOS|iPhone)') {
            set $mobile_request '1';
        }
        if ($mobile_request = '1') {
            rewrite ^.+ http://m.baidu.com;
        }
    }
}

Nginx配置https

要开启 HTTPS 服务,在配置文件信息块(server),必须使用监听命令 listen 的 ssl 参数和定义服务器证书文件和私钥文件,如下所示:

server {
   #ssl参数
   listen              443 ssl; //监听443端口,因为443端口是https的默认端口。80为http的默认端口
   server_name         example.com;
   #证书文件
   ssl_certificate     example.com.crt;
   #私钥文件
   ssl_certificate_key example.com.key;
}
复制代码
  • ssl_certificate:证书的绝对路径

  • ssl_certificate_key: 密钥的绝对路径;

 

vue history路由配置修改:

如果路由模式为history模式,那么前端打包后的文件部署到nginx后需要加一个配置

location / {
		root   /program/TyAuthorization/www/;
        index  index.html index.htm;
		try_files $uri $uri/ /index.html;
	}

就是这个 try_files $uri $uri/ /index.html;  如果是hash模式,不需要配这行,history需要加上这行,否则多级路由的页面是访问不了的。

 

一些其他配置

    keepalive_timeout  65;
    #request的header中包含’_’时,不忽略。 比如如果header里面加了access_token这个字段,不加这个 on, 那就有问题,access_token识别不了。
    underscores_in_headers on; 

附上一份平时用到的配置:


#user  nobody;
worker_processes  4;

error_log  /usr/local/nginx/logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid /program/nginx/nginx.pid;

events {
	use epoll;
	worker_connections  4096;
}


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  /usr/local/nginx/logs/access.log  main;
	client_max_body_size 20M;
	sendfile on;
	#tcp_nopush on;

	#keepalive_timeout  0;
	keepalive_timeout  65;
	#request的header中包含’_’时,不忽略
	underscores_in_headers on; 

	gzip on;
	gzip_static on;
	gzip_proxied expired no-cache no-store private auth;
	gzip_disable "msie6"; #不使用gzip IE6
	gzip_min_length 1024; #gzip压缩最小文件大小,超出进行压缩(自行调节)
	gzip_buffers 4 16k; #buffer 不用修改
	gzip_comp_level 3; #压缩级别:1-10,数字越大压缩的越好,时间也越长
	gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png; # 压缩文件类型
	gzip_vary off; #跟Squid等缓存服务有关,on的话会在Header里增加 "Vary: Accept-Encoding"
	

	 
	upstream authorize_{
		ip_hash;
		server 127.0.0.1:81;
	}
	upstream oauth_{
		ip_hash;
		server 127.0.0.1:88;
	}
	server {
		listen 89;
		server_name  localhost;

		#charset koi8-r;

		#access_log  logs/host.access.log  main;

		location / {
			root   /program/web/www/;
            index  index.html index.htm;
			try_files $uri $uri/ /index.html;
		}

		location /authorize{
			proxy_pass   http://authorize_/api/v1/authorize;
			proxy_redirect off;
			proxy_set_header Host $host;
			proxy_set_header X-Forwarded-For $remote_addr;
		}
		
		#location /oauth{
		#	proxy_pass   http://oauth_/oauth;
		#	proxy_redirect off;
		#	proxy_set_header Host $host;
		#	proxy_set_header X-Forwarded-For $remote_addr;
		#}
		
		location /client{
			proxy_pass   http://authorize_/client;
			proxy_redirect off;
			proxy_set_header Host $host;
			proxy_set_header X-Forwarded-For $remote_addr;
		}
		
		location /files/ {
		  alias	/program/TyAuthorization/static/;
		  autoindex on;
		}

		error_page  404			  /404.html;

		error_page   500 502 503 504  /50x.html;
		location = /50x.html {
			root   html;
		}
	}
}

一些基本命令

nginx -t             检查配置文件是否有语法错误
nginx -s reload       热加载,重新加载配置文件
nginx -s stop         快速关闭
nginx -s quit         等待工作进程处理完成后关闭

参考文章:

https://mp.weixin.qq.com/s/wecUdGnuHdZOs3t7zc16jw
https://mp.weixin.qq.com/s/czV9m-jslpEUnvX39nduYw

 

如有问题或建议,请多多提出,如发现错误,烦请指正。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值