写点什么

【得物技术】前端工程师要知道的 Nginx 知识

用户头像
得物技术
关注
发布于: 2021 年 04 月 02 日

平常我们在工作之中,遇到的许多问题其实都是与 Nginx 有关的问题,例如 跨域问题、请求过滤、配置 gzip、负载均衡、或者与静态资源服务器有关等等的问题。


虽然 nginx 一般都由运维配置,我们不会直接配置,但是了解它在我们线上程序中所起到的作用,并且能够知道如何排查问题,也是非常重要的。


那么 nginx 到底是什么呢?

一、什么是 Nginx

Nginx 是一款轻量级的 Web 服务器、反向代理服务器,由于它的内存占用少,启动极快,高并发能力强,在互联网项目中广泛应用。


上图大概描述了 Nginx 在整个浏览访问中起到的作用,有一点像入口网关。Nginx 其实就是一个高性能的反向代理服务器,那么什么是反向代理,什么是正向代理呢?

1. 正向代理



由于防火墙的原因,我们不能直接访问 www.google.com ,所以我们需要借助 vpn 来完成这次访问。通过这个例子,我们能发现,所谓的正向代理,代理的是客户端,客户端知道他访问的目标究竟是什么,但对于目标服务端来说,并不知道自己收到的是来自代理的访问还是来自真实客户端的访问。


官方解释如下:


是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。客户端才能使用正向代理。

2. 反向代理


从图中我们可以看出,我们从外网访问 www.baidu.com 的时候,会进行一个转发,代理到内网。因此反向代理其实代理的是服务器端,这一个过程对于客户端来说是透明的。


官方解释如下:


反向代理服务器位于用户与目标服务器之间,但是对于用户而言,反向代理服务器就相当于目标服务器,即用户直接访问反向代理服务器就可以获得目标服务器的资源。

二、Nginx 的基本配置

下图是 nginx 配置文件的基本结构:


其中:


  • main:nginx 的全局配置,对全局生效

  • events:配置影响 nginx 服务器或与用户的网络连接

  • http:可以嵌套多个 server,配置代理,缓存,日志定义等等功能,还能配置第三方模块的配置。

  • upstream:配置后端服务器的具体地址,与负载均衡息息相关

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

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

内置变量


三、跨域问题

1. 跨域的定义

浏览器出于安全考虑,有同源策略。也就是说,如果协议、域名或者端口有一个不同就是跨域。

2. Nginx 是怎么解决跨域

eg.• 前端 server 的域名:fast.dewu.com• 后端 server 的域名:app.dewu.com


如果没有代理,那么在 fast.dewu.com 对 app.dewu.com 发起请求一定会产生跨域问题。


如果使 Nginx 用代理将 serve_name 设置成 fast.dewu.com,然后设置相应的 location 拦截前端需要跨域的请求,最后将请求代理回 app.dewu.com。配置如下:


{     listen 80;     server_name fast.dewu.com;     location / {         proxy_pass app.dewu.com;         }     }
复制代码


将这样 fast.dewu.com 访问 nginx 的 fast.dewu.com 属于同源访问,而 nginx 对服务端转发的请求不会触发浏览器的同源策略。

四、请求过滤

1. 状态码过滤

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


50x 就是错误状态码的显示页面,后面是存放具体 html 的地址。

2. 根据 URL 名称过滤

location / {    rewrite  ^.*$ /index.html  redirect;}
复制代码


rewrite 的指令是这样的:


rewrite regex replacement [flag];
复制代码


这里使用了正则来匹配请求的 url,如果匹配成功,则使用 replacement 来更改 url。最后的 redirect 表示返回 302 临时重定向。


所以这里表示的是精准匹配 URL,不匹配的 URL 全部重定向到主页。

3. 请求类型过滤

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

五、配置 gzip

1. 什么是 gzip

gzip 是 GNUzip 的缩写,最早用于 UNIX 系统的文件压缩。HTTP 协议上的 gzip 编码是一种用来改进 web 应用程序性能的技术,web 服务器和客户端(浏览器)必须共同支持 gzip。目前主流的浏览器,Chrome,firefox,IE 等都支持该协议。常见的服务器如 Apache,Nginx,IIS 同样支持 gzip。


gzip 压缩比率在 3 到 10 倍左右,可以大大节省服务器的网络带宽。而在实际应用中,并不是对所有文件进行压缩,通常只是压缩静态文件。



2. 开启 gzip 的表现

请求头



响应头


3. nginx 配置

server{ gzip on; # 用于开启或 关闭gzip模块 gzip_buffers 32 4K; # 设置系统获取几个单位的缓存用于存储gzip的压缩结果数据流。 gzip_comp_level 6; # 压缩级别,1-10,数字越大压缩的越好,压缩级别越高压缩率越大,压缩时间越长。gzip_min_length 100; # 设置允许压缩的页面最小字节数,页面字节数从相应消息头的Content-length中进行获取。 gzip_types application/javascript text/css text/xml; gzip_disable "MSIE [1-6]\."; # IE6对Gzip不友好,对Gzip(可以通过该指令对一些特定的User-Agent不使用压缩功能) gzip_proxied on: # 用于设置启用或禁用从代理服务器上收到相应内容gzip压缩。 gzip_http_version 1.1; # 识别HTTP协议版本,其值可以是 1.1 或 1.0 gzip_proxied : off; # 用于设置启用或禁用从代理服务器上收到相应内容gzip压缩。gzip_vary on; # 用于在响应消息头中添加Vary:Accept-Encoding,使代理服务器根据请求头中的Accept-Encoding识别是否启用gzip压缩}
复制代码

六、负载均衡

1. 什么是负载均衡

负载均衡是高可用网络基础架构的关键组件,通常用于将工作负载分布到多个服务器来提高网站、应用、数据库或其他服务的性能和可靠性。


一个没有负载均衡的 web 架构类似下面这样:


在这里用户是直连到 web 服务器,如果这个服务器宕机了,那么用户自然也就没办法访问了。另外,如果同时有很多用户试图访问服务器,超过了其能处理的极限,就会出现加载速度缓慢或根本无法连接的情况。


而通过在后端引入一个负载均衡器和至少一个额外的 web 服务器,可以缓解这个故障。通常情况下,所有的后端服务器会保证提供相同的内容,以便用户无论哪个服务器响应,都能收到一致的内容。



2. nginx 如何实现负载均衡

Upstream 指定后端服务器地址列表


upstream balanceServer {    server 10.1.22.33:12345;    server 10.1.22.34:12345;    server 10.1.22.35:12345;}
复制代码


在 server 中拦截响应请求,并将请求转发到 Upstream 中配置的服务器列表。


server {       server_name fe.server.com;       listen 80;       location /api {           proxy_pass http://balanceServer;       }    }
复制代码

3. 负载均衡的策略

(1)轮询策略(默认)

将所有客户端请求轮询分配给服务端。这种策略是可以正常工作的,但是如果其中某一台服务器压力太大,出现延迟,会影响所有分配在这台服务器下的用户。代码如上。


(2) 最小连接数策略

将请求优先分配给压力较小的服务器,它可以平衡每个队列的长度,并避免向压力大的服务器添加更多的请求。


upstream balanceServer {   least_conn;   server 10.1.22.33:12345;   server 10.1.22.34:12345;   server 10.1.22.35:12345;   }
复制代码



(3) 权重策略

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


upstream balanceServer {    server 192.168.0.1 weight=2;    server 192.168.0.2 weight=8;}
复制代码

(4) 客户端 ip 绑定 ip_hash

来自同一个 ip 的请求永远只分配一台服务器,有效解决了动态网页存在的 session 共享问题。


upstream balanceServer {    ip_hash;    server 10.1.22.33:12345;    server 10.1.22.34:12345;    server 10.1.22.35:12345;}
复制代码

(5) 最快响应时间策略 fair(第三方)

会将请求优先分配给相应最快的服务器,这种方式需要依赖到第三方插件 nginx-upstream-fair


upstream balanceServer {    fair;    server 10.1.22.33:12345;    server 10.1.22.34:12345;    server 10.1.22.35:12345;}
复制代码

(6) url_hash(第三方)

按访问 url 的 hash 结果来分配请求,使每个 url 定向到同一个后端服务器,后端服务器为缓存时比较有效。


upstream balanceServer {   hash $request_uri;   server 192.168.244.1:8080;   server 192.168.244.2:8080;   server 192.168.244.3:8080;   server 192.168.244.4:8080;   }
复制代码

4. 健康检查

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


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


upstream balanceServer{   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://balanceServer;   } }
复制代码


涉及两个配置: fail_timeout : 设定服务器被认为不可用的时间段以及统计失败尝试次数的时间段,默认为 10s max_fails : 设定 Nginx 与服务器通信的尝试失败的次数,默认为:1 次。

七、静态资源服务器

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


匹配以 png|gif|jpg|jpeg 为结尾的请求,并将请求转发到本地路径,root 中指定的路径即 nginx 本地路径。同时也可以进行一些缓存的设置。

八、访问权限控制

可以配置 nginx 白名单,规定哪些 ip 可以访问服务器。


location / {        allow  192.168.0.1;  # 允许该ip访问        deny   all;  # 禁止所有    }
复制代码


文|衠灵


关注得物技术,携手走向技术的云端

发布于: 2021 年 04 月 02 日阅读数: 38
用户头像

得物技术

关注

得物APP技术部 2019.11.13 加入

关注微信公众号「得物技术」

评论

发布
暂无评论
【得物技术】前端工程师要知道的Nginx知识