Nginx是一个高性能的HTTP和反向代理服务器,及电子邮件代理服务器。

功能

  • 反向代理
  • 负载均衡
  • 动静分离

常用命令

启动命令: ./sbin/nginx -c conf/nginx.conf

停止命令:./sbin/nginx -s stop

  1. `./sbin/nginx -s quit`

重载配置:./sbin/nginx -s reload(平滑重启)

进程模型

image-20200213223116000.png

Nginx启动时分为单进程模式和多进程模式,在多进程模式下,有一个master进程多个worker进程,其中,master进程负责信号处理以及worker进程的管理;worker进程负责处理具体的请求。Master与Worker中间使用epoll多路复用来确保非阻塞。

基于此,Nginx得以无缝重启,在重启时,master并不会重启,只是更换了Worker进程(Worker是单线程的)。

Nginx处理Http请求的过程

Nginx使用Reactor模式。主进程循环等待操作系统发出准备事件的信号,这样数据就可以从套接字读取,在该实例中读取到缓冲区并进行处理。单个线程可以提供数万个并发连接。

Reactor

Reactor模式是事件驱动的一种实现方式,处理多个客户端并发的向服务端请求服务的场景。

image-20200214002028329.png

这是最简单的单Reactor单线程模型。Reactor线程是个多面手,负责多路分离套接字,Accept新连接,并分派请求到Handler处理器中。

正反向代理

  • 正向代理
    正向代理就是平时说的代理(比如Shadowsocks就是正向代理),是指Nginx代理服务器受客户端委托代理客户端,转发请求,并将从服务端获得的响应返回给客户端。
  • 反向代理
    反向代理是指Nginx代理服务器受服务端的委托代理服务端,作为集群的web节点,反向代理一般和负载均衡配合使用。反向代理服务器可以隐藏源服务器的存在和特征,比较安全。

负载均衡

负载均衡的实现必须依赖于反向代理,Nginx的负载均衡策略有两种:内置策略和扩展策略。

内置策略:

  • 轮询:将请求依次轮询发给每个服务器。
  • 最少连接:将请求发送给持有最少活动链接的服务器。(least_conn)
  • IP哈希:通过哈希函数决定请求发送给哪个服务器。(ip_hash)
  • 权重:服务器的权重越高,处理请求的概率越大。

配置文件结构

  • 全局块
    一般配置影响Nginx全局的指令。一般配置用户组,日志存放路径,pid存放路径等。
  • events块
    配置Nginx服务器与用户的网络连接。
    1. events {
    2. worker_connections 1024;
    3. }
  • http块
    可以嵌套多个server块,配置代理服务器,日志等。
    • server块
      可以嵌套多个location块,配置代理服务器的相关参数。 ```shell upstream aaa{

      反向代理

      server 127.0.0.1:8080 weight=1; server 127.0.0.1:8081 weight=1; }

server{ listen 80;

  1. ...
  2. location / {
  3. proxy_pass http://aaa;
  4. ...
  5. }

}

  1. - location块<br />配置请求路由和处理请求的页面或服务器。
  2. <a name="4290207f"></a>
  3. ### location规则
  4. | 标识符 | 描述 |
  5. | --- | --- |
  6. | = | **精确匹配:**用于标准uri前,要求请求字符串和uri严格匹配。如果匹配成功就停止匹配,立即执行该location里面的请求。 |
  7. | ~ | **正则匹配:**用于正则uri前,表示uri里面包含正则,并且区分大小写。 |
  8. | ~* | **正则匹配:**用于正则uri前,表示uri里面包含正则,不区分大小写。 |
  9. | ^~ | **非正则匹配:**用于标准uri前,Nginx服务器匹配到前缀最多的uri后就结束,该模式匹配成功后,不会使用正则匹配。 |
  10. | | **普通匹配(最长字符匹配):**与location顺序无关,是按照匹配的长短来取匹配结果。若完全匹配,就停止匹配。 |
  11. <a name="4bf4d0ac"></a>
  12. #### =匹配
  13. ```shell
  14. location = /news/ {
  15. echo "test1";
  16. }
  17. [root...] curl x.x.x.x/news/
  18. test1

~匹配

  1. location ~ \.(html) {
  2. echo 'test2';
  3. }
  4. location ~ \.(htmL) {
  5. echo 'test3';
  6. }
  7. [root...] curl x.x.x.x/index.html
  8. test2
  9. [root...] curl x.x.x.x/index.htmL
  10. test3

^~匹配

  1. location ^~ /index/ {
  2. echo 'test5';
  3. }
  4. [root...] curl x.x.x.x/index/heihei
  5. test5

普通匹配

  1. location / {
  2. echo 'test6';
  3. }
  4. [root...] curl x.x.x.x
  5. test6

Rewrite的使用

基本语法:if(condition){...}

标记符号 说明
last 终止在本location块中处理接收到的URI,并将此处重写的URI作为新的URI使用其他location进行处理。(只是终止当前location的处理)
break 将此处重写的URI作为一个新的URI在当前location中继续执行,并不会将新的URI转向其他location。
redirect 将重写后的URI返回个客户端,状态码是302,表明临时重定向,主要用在replacement字符串不以“http://”,“ https://”或“ $scheme” 开头;
permanent 将重写的URI返回客户端,状态码为301,指明是永久重定向;

例子:

  1. server {
  2. listen 80;
  3. server_name abc.com;
  4. rewrite ^/(.*) http://www.abc.com/$1 permanent; # 跳转到www.abc.com网址上
  5. }

动静分离与Expires(缓存)

动静分离是让动态网站里的动态网页根据一定规则把不变的资源和经常变的资源区分开来,动静资源做好了拆分以后,我们就可以根据静态资源的特点将其做缓存操作,这就是网站静态化处理的核心思路。

以下代码同时配置了静态资源的访问与缓存策略:

image-20200214003013275.png

跨域配置

跨域的概念:

浏览器从一个域名的网页去请求另一个域名的资源时,域名、端口、协议任一不同,都是跨域。

参考配置代码:

  1. location /xxx-web {
  2. add_header 'Access-Control-Allow-Origin' $http_origin;
  3. add_header 'Access-Control-Allow-Credentials' 'true';
  4. add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
  5. add_header 'Access-Control-Allow-Headers' 'DNT,web-token,app-token,Authorization,Accept,Origin,Keep-Alive,User-Agent,X-Mx-ReqToken,X-Data-Type,X-Auth-Token,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
  6. add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
  7. if ($request_method = 'OPTIONS') {
  8. add_header 'Access-Control-Max-Age' 1728000;
  9. add_header 'Content-Type' 'text/plain; charset=utf-8';
  10. add_header 'Content-Length' 0;
  11. return 204;
  12. }
  13. root html;
  14. index index.html index.htm;
  15. proxy_pass http://127.0.0.1:8080;
  16. proxy_set_header Host $host;
  17. proxy_set_header X-Real-IP $remote_addr;
  18. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  19. proxy_set_header X-Forwarded-Proto $scheme;
  20. proxy_connect_timeout 5;
  21. }
  1. Access-Control-Allow-Origin,这里使用变量 $http_origin取得当前来源域。
  2. Access-Control-Allow-Credentials,为 true 的时候指请求时可带上Cookie,自己按情况配置。
  3. Access-Control-Allow-Methods,OPTIONS一定要有的,另外一般也就GET和POST,如果你有其它的也可加进去;
  4. Access-Control-Allow-Headers,这个要注意,里面一定要包含自定义的http头字段(就是说前端请求接口时,如果在http头里加了自定义的字段,这里配置一定要写上相应的字段)。
  5. Access-Control-Expose-Headers,可不设置,看网上大致意思是默认只能获返回头的6个基本字段,要获取其它额外的,先在这设置才能获取它;
  6. 语句“ if ($request_method = ‘OPTIONS’) { ”,因为浏览器判断是否允许跨域时会先往后端发一个 options 请求,然后根据返回的结果判断是否允许跨域请求,所以这里单独判断这个请求,然后直接返回。

gzip压缩策略

浏览器请求url,同时声明当前浏览器可以支持压缩类型(gzip、deflate等),服务端会把内容根据浏览器所支持的压缩策略去进行压缩并返回给浏览器,浏览器拿到数据以后进行解码。

image-20200214003031201.png

image-20200214003048549.png

Nginx默认只对text/html进行压缩 ,如果要对html之外的内容进行压缩传输,需要我们进行手动配置。