NGINX

Nginx学习

1、Nginx 使用场景

静态资源服务,通过本地文件系统提供服务;
反向代理服务,延伸出包括缓存、负载均衡等;
API 服务,OpenResty

2、概念

2.1、简单请求和非简单请求
1、简单请求

同时满足下面两个条件
1)请求方法是 HEAD、GET、POST 三种之一;
2)HTTP 头信息不超过右边着几个字段:Accept、Accept-Language、Content-Language、Last-Event-ID
Content-Type 只限于三个值 application/x-www-form-urlencoded、multipart/form-data、text/plain;

2、非简单请求

不同时满足上述两个条件的

3、浏览器处理简单请求和非简单请求的方式

1)简单请求
对于简单请求,浏览器会在头信息中增加 Origin 字段后直接发出,Origin 字段用来说明,本次请求来自的哪个源(协议+域名+端口)。
如果服务器发现 Origin 指定的源不在许可范围内,服务器会返回一个正常的 HTTP 回应,浏览器取到回应之后发现回应的头信息中没有包含 Access-Control-Allow-Origin 字段,就抛出一个错误给 XHR 的 error 事件;
如果服务器发现 Origin 指定的域名在许可范围内,服务器返回的响应会多出几个 Access-Control- 开头的头信息字段。
2)非简单请求
非简单请求是那种对服务器有特殊要求的请求,比如请求方法是 PUT 或 DELETE,或 Content-Type 值为 application/json。浏览器会在正式通信之前,发送一次 HTTP 预检 OPTIONS 请求,先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些 HTTP 请求方法和头信息字段。只有得到肯定答复,浏览器才会发出正式的 XHR 请求,否则报错。

2.2跨域
1、跨域概念

在浏览器上当前访问的网站向另一个网站发送请求获取数据的过程

2、跨域作用

跨域:浏览器的同源策略决定的,是一个重要的浏览器安全策略,用于限制一个 origin 的文档或者它加载的脚本与另一个源的资源进行交互,它能够帮助阻隔恶意文档,减少可能被攻击的媒介,可以使用 CORS 配置解除这个限制。

同源定义:
如果两个 URL 的 protocol、port (en-US) (如果有指定的话)和 host 都相同的话,则这两个 URL 是同源。这个方案也被称为“协议/主机/端口元组”,或者直接是 “元组”。(“元组” 是指一组项目构成的整体,双重/三重/四重/五重/等的通用形式)。

例子:
在这里插入图片描述

2.3、正向代理和反向代理

一般给客户端做代理的都是正向代理,给服务器做代理的就是反向代理。
在这里插入图片描述
在这里插入图片描述

2.4、负载均衡

负载均衡,核心是「分摊压力」。Nginx 实现负载均衡,一般来说指的是将请求转发给服务器集群。

2.5、动静分离

由于 Nginx 的高并发和静态资源缓存等特性,经常将静态资源部署在 Nginx 上。如果请求的是静态资源,直接到静态资源目录获取资源,如果是动态资源的请求,则利用反向代理的原理,把请求转发给对应后台应用去处理,从而实现动静分离。
使用前后端分离后,可以很大程度提升静态资源的访问速度,即使动态服务不可用,静态资源的访问也不会受到影响。

3、nginx配置

3.1通用配置:nginx.conf
user  nginx;                        # 运行用户,默认即是nginx,可以不进行设置
worker_processes  1;                # Nginx 进程数,一般设置为和 CPU 核数一样
error_log  /var/log/nginx/error.log warn;   # Nginx 的错误日志存放目录
pid        /var/run/nginx.pid;      # Nginx 服务启动时的 pid 存放位置

events {
    use epoll;     # 使用epoll的I/O模型(如果你不知道Nginx该使用哪种轮询方法,会自动选择一个最适合你操作系统的)
    worker_connections 1024;   # 每个进程允许最大并发数
}

http {   # 配置使用最频繁的部分,代理、缓存、日志定义等绝大多数功能和第三方模块的配置都在这里设置
    # 设置日志模式
    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  /var/log/nginx/access.log  main;   # Nginx访问日志存放位置

    sendfile            on;   # 开启高效传输模式
    tcp_nopush          on;   # 减少网络报文段的数量
    tcp_nodelay         on;
    keepalive_timeout   65;   # 保持连接的时间,也叫超时时间,单位秒
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;      # 文件扩展名与类型映射表
    default_type        application/octet-stream;   # 默认文件类型

    include /etc/nginx/conf.d/*.conf;   # 加载子配置项
    
    server {
        listen       80;       # 配置监听的端口
        server_name  localhost;    # 配置的域名
        
        location / {
            root   /usr/share/nginx/html;  # 网站根目录
            index  index.html index.htm;   # 默认首页文件
            deny 172.168.22.11;   # 禁止访问的ip地址,可以为all
            allow 172.168.33.44; # 允许访问的ip地址,可以为all
        }
        
        error_page 500 502 503 504 /50x.html;  # 默认50x对应的访问页面
        error_page 400 404 error.html;   # 同上
    }
}

server 块可以包含多个 location 块,location 指令用于匹配 uri,语法:

location [ = | ~ | ~* | ^~] uri {
    ...
}

= 精确匹配路径,用于不含正则表达式的 uri 前,如果匹配成功,不再进行后续的查找;
^~ 用于不含正则表达式的 uri前,表示如果该符号后面的字符是最佳匹配,采用该规则,不再进行后续的查找;
~ 表示用该符号后面的正则去匹配路径,区分大小写;
~* 表示用该符号后面的正则去匹配路径,不区分大小写。跟 ~ 优先级都比较低,如有多个location的正则能匹配的话,则使用正则表达式最长的那个;
如果 uri 包含正则表达式,则必须要有 ~ 或 ~* 标志。

3.2 配置反向代理

在这里插入图片描述
改完保存退出,nginx -s reload 重新加载

比如监听 9001 端口,然后把访问不同路径的请求进行反向代理:

把访问 http://127.0.0.1:9001/edu 的请求转发到 http://127.0.0.1:8080
把访问 http://127.0.0.1:9001/vod 的请求转发到 http://127.0.0.1:8081

打开主配置文件,然后在 http 模块下增加一个 server 块:

server {
  listen 9001;
  server_name *.sherlocked93.club;

  location ~ /edu/ {
    proxy_pass http://127.0.0.1:8080;
  }
  
  location ~ /vod/ {
    proxy_pass http://127.0.0.1:8081;
  }
}

反向代理其他的指令:

proxy_set_header:在将客户端请求发送给后端服务器之前,更改来自客户端的请求头信息。
proxy_connect_timeout:配置Nginx与后端代理服务器尝试建立连接的超时时间。
proxy_read_timeout:配置Nginx向后端服务器组发出read请求后,等待相应的超时时间。
proxy_send_timeout:配置Nginx向后端服务器组发出write请求后,等待相应的超时时间。
proxy_redirect:用于修改后端服务器返回的响应头中的Location和Refresh。

3.3、配置负载均衡
upstream demo_name{
   server ip:port; # ip1
   server ip:port; # ip2
   server ip:port; #ip3
}
3.4、例子

在这里插入图片描述

4、模块

1、proxy_set_header

1.1、 h t t p h o s t 与 http_host与 httphosthost区别
1、在使用Nginx做反向代理的时候,proxy_set_header功能可以设置反向代理后的http header中的host,
那么常用的几个设置中$proxy_host, h o s t , host, host,http_host又都表示什么意思呢?
Nginx的官网文档中说下面这两条是做反代时默认的,所以$proxy_host 自然是 proxy_pass后面跟着的host了

proxy_set_header Host       $proxy_host;
proxy_set_header Connection close;

如果客户端发过来的请求的header中有’HOST’这个字段时,
h t t p h o s t 和 http_host和 httphosthost都是原始的’HOST’字段
比如请求的时候HOST的值是www.csdn.net 那么反代后还是www.csdn.ne

1.1.1、 不设置 proxy_set_header Host 时
浏览器直接访问 nginx,获取到的 Host 是 proxy_pass 后面的值,即 $proxy_host 的值,参考
http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_set_header

server {
    listen 8090;
    server_name _;
    location / {
        proxy_pass http://172.31.5.0:5000;
    }
}

在这里插入图片描述
1.1.2、 设置 proxy_set_header Host $host 时
浏览器直接访问 nginx,获取到的 Host 是 $host 的值,没有端口信息

server {
    listen 8090;
    server_name _;
    location / {
        proxy_set_header Host $host;
        proxy_pass http://172.31.5.0:5000;
    }
}

在这里插入图片描述
1.1.3、2.3 设置 proxy_set_header Host h o s t : host: host:proxy_port 时
浏览器直接访问 nginx,获取到的 Host 是 h o s t : host: host:proxy_port 的值

server {
    listen 8090;
    server_name _;
    location / {
        proxy_set_header Host $host:$proxy_port;
        proxy_pass http://172.31.5.0:5000;
    }
}

在这里插入图片描述
1.1.4、2.4 设置 proxy_set_header Host $http_host 时
浏览器直接访问 nginx,获取到的 Host 包含浏览器请求的 IP 和端口

server {
    listen 8090;
    server_name _;
    location / {
        proxy_set_header Host $http_host;
        proxy_pass http://172.31.5.0:5000;
    }
}

在这里插入图片描述
1.1.5、2.5 设置 proxy_set_header Host $host 时
浏览器直接访问 nginx,获取到的 Host 是 $host 的值,没有端口信息。此时代码中如果有重定向路由,那么重定向时就会丢失端口信息,导致 404

server {
    listen 8090;
    server_name _;
    location / {
        proxy_set_header Host $host;
        proxy_pass http://172.31.5.0:5000;
    }
}

在这里插入图片描述
1.1.6、X-Real-IP
下面我们看一下有多级代理存在时如何获取客户端真实IP.

首先要明确在header里面的 X-Real-IP只是一个变量,后面的设置会覆盖前面的设置(跟X-Forwarded-For的追加特性区别明显),所以我们一般只在第一个代理设置proxy_set_header X-Real-IP r e m o t e a d d r ; 就好了,然后再应用端直接引用 remote_addr;就好了,然后再应用端直接引用 remoteaddr;就好了,然后再应用端直接引用http_x_real_ip就行.
https://blog.csdn.net/xiaoxiao_yingzi/article/details/92835704

2、服务器使用nginx反向代理后,后端服务器获取访客的真实ip的失败

1、配置反向代理端的nginx服务器

在server后面增加如下这三个参数用于记录IP:

  proxy_set_header Host $host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

在这里插入图片描述
2、在后端服务器配置如下
在后端服务器的nginx_http处配置如下:
配置log_format信息, 后续的日志后面也需要加上main这个参数

log_format  main '$remote_addr $remote_user [$time_local] "$request" '           
                  '$status $body_bytes_sent "$http_referer" '                   
                  '$http_user_agent $http_x_forwarded_for $request_time $upstream_response_time $upstream_addr $upstream_status'; 

在这里插入图片描述
以上即可记录访客的真实ip地址
在这里插入图片描述
2.2、其他配置参数


`参数                      说明                                         示例`

`$remote_addr             客户端地址                                    211.28.65.253`

`$remote_user             客户端用户名称                                --`

`$time_local              访问时间和时区                                18``/Jul/2012``:17:00:01 +0800`

`$request                 请求的URI和HTTP协议                           ``"GET /article-10000.html HTTP/1.1"`

`$http_host               请求地址,即浏览器中你输入的地址(IP或域名)     www.wang.com 192.168.100.100`

`$status                  HTTP请求状态                                  200`

`$upstream_status         upstream状态                                  200`

`$body_bytes_sent         发送给客户端文件内容大小                        1547`

`$http_referer            url跳转来源                                   https:``//www``.baidu.com/`

`$http_user_agent         用户终端浏览器等信息                           "Mozilla``/4``.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident``/4``.0; SV1; GTB7.0; .NET4.0C;`

`$ssl_protocol            SSL协议版本                                   TLSv1`

`$ssl_cipher              交换数据中的算法                               RC4-SHA`

`$upstream_addr           后台upstream的地址,即真正提供服务的主机地址     10.10.10.100:80`

`$request_time            整个请求的总时间                               0.205`

`$upstream_response_time  请求过程中,upstream响应时间                    0.002`

3、获取多有请求头
  ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
 HttpServletRequest request = getRequest();
//获取所有请求头名称
        Enumeration<String> headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String name = headerNames.nextElement();
            //根据名称获取请求头的值
            String value = request.getHeader(name);
            System.out.println(name+"---"+value);
        }

4、nginx.conf配置
性能优化-开启高效文件传输模式sendfile on;
sendfile on; #特殊的数据传输功能

tcp_nopush on;

参数sendfile on 用于开启文件高效传输模式,同时将tcp_nopush on 和tcp_nodelay on 两个指令设置为on,可防止网络及磁盘I/O阻塞,提升Nginx工作效率

(1) 设置参数 sendfile on
参数语法 sendfile on | off;

放置位置 http,server,location,if in location

(2) 设置参数 tcp_nopush on 说明:当有数据时,先别着急发送, 确保数据包已经装满数据, 避免了网络拥塞
参数语法 tcp_nopush on | off;

放置位置 http,server,location
(3) 设置参数 tcp_nodelay on 说明:有时要抓紧发货, 确保数据尽快发送, 提高可数据传输效率
参数语法 tcp_nodelay on | off;

放置位置 http,server,location
sendfile on配合使用(2)(3) 但(2)(3)只能选其一特别注意

在主配置文件nginx.conf中配置


worker_processes  2;
worker_cpu_affinity 0101 1010;
error_log logs/error.log;
 
#配置Nginx worker进程最大打开文件数
worker_rlimit_nofile 65535;
 
user www www;
events {
    #单个进程允许的客户端最大连接数
    worker_connections  20480;
    #使用epoll模型
    use epoll;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    #sendfile        on;
    keepalive_timeout  65;
    #访问日志配置
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
 
 
    #虚拟主机
    include /application/nginx/conf/extra/www.conf;
    include /application/nginx/conf/extra/blog.conf;
    include /application/nginx/conf/extra/bbs.conf;
    include /application/nginx/conf/extra/edu.conf;
    include /application/nginx/conf/extra/phpmyadmin.conf;
    include /application/nginx/conf/extra/status.conf;
 
    #nginx优化----------------------
    #隐藏版本号
    server_tokens on;
 
    #优化服务器域名的散列表大小 
    server_names_hash_bucket_size 64;
    server_names_hash_max_size 2048;
 
    #开启高效文件传输模式
    sendfile on;
    #减少网络报文段数量
    #tcp_nopush on;
    #提高I/O性能
    tcp_nodelay on;
}

常用nginx常用命令

1、在nginx部署目录:/home/admin/soft/nginx/sbin/下
2、查看 nginx 版本号

./nginx -v
启动 nginx
./nginx
查看是否启动成功:ps -ef|grep nginx
在这里插入图片描述
3、停止 nginx
./nginx -s stop
4、重新加载 nginxv
./nginx -s reload
5、查看版本号
nginx -v
6、检查配置文件是否有误
nginx –t

3、nginx 日志配置不生效的问题

log_format 有个默认的日志格式:

log_format  combined  '$remote_addr - $remote_user  [$time_local]  '
                       ' "$request"  $status  $body_bytes_sent  '
                       ' "$http_referer"  "$http_user_agent" ';

nginx 默认调用 combined 格式来记录日志,即默认调用:(默认记录在access.log文件中)

access_log  logs/access.log  combined;

nginx允许自定义日志格式,例如:

log_format  main  '$remote_addr - $remote_user [$time_local] "$http_host" "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" $http_x_forwarded_for $request_time';

以上是自定义了日志格式:main(main名称可以自定义)
要想使其生效,就必须用access_log指定调用:

access_log  logs/xx.log  main;

否则,nginx仍然会去调用combined格式来记录日志。
注意,http段也必须明确指定调用main格式才会生效,否则还是会调用默认的combined格式。

4、打印自定义header

1、nginx.conf

  log_format  accesslog  '$http_x_forwarded_for`$remote_addr`$proxy_add_x_forwarded_for`[$time_local]`"$request"`'
                      '$status`$body_bytes_sent`"$http_referer"`'
                      '"$http_user_agent"`"$request_time"`'
                      '$request_id`$upstream_response_time`$upstream_addr`$upstream_connect_time`$upstream_status';

2、在自定义的conf/web.conf 中配置nginx 的server

server{
listen 80;
server_name _;
access_log /home/admin/logs/nginx/web_access.log accesslog;

location ~*~/login/{
rewrite ^/login/(.*) /$1 break;
proxy_pass http://xx.xx.xx.xx;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

注:
header必须用减号“-”分隔单词,nginx里面会转换为对应的下划线“_”连接的小写单词。
1、nginx是支持读取非nginx标准的用户自定义header的,但是需要在http或者server下开启header的下划线支持:
underscores_in_headers on;
2、比如我们自定义header为X-Real-IP,通过第二个nginx获取该header时需要这样:
$http_x_real_ip; (一律采用小写,而且前面多了个http_,减号转成下划线)

学习参考:

  1. https://juejin.cn/post/6844904144235413512
  2. 浏览器的同源策略:https://developer.mozilla.org/zh-CN/docs/Web/Security/Same-origin_policy

模块参考:
3) https://blog.csdn.net/u011897301/article/details/72486278
4) https://www.cnblogs.com/faberbeta/p/nginx008.html
5) http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_set_header
6) https://blog.csdn.net/diyiday/article/details/80827437
7) https://juejin.cn/post/7003639916139642893
8) https://blog.csdn.net/weixin_34209851/article/details/91681937
9) https://blog.csdn.net/xiaoxiao_yingzi/article/details/92835704
配置参考:

  1. https://www.cnblogs.com/hjqjk/p/6337447.html
  2. http://nginx.org/en/docs/http/ngx_http_core_module.html#underscores_in_headers

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值