Nginx 常用配置、操作详解

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

学习每个技术都要有目标比如说要源码精通gRPC实现原理要熟练应用Prometheus、Gin以及NginxNginx个人定位目标是不需要深入了解技术原理、更不要阅读源码只需要在自己使用的时候能通过本文章快速检索就够了。

在看到https://juejin.cn/post/6942607113118023710 的技术文章后知道这是一篇可以让自己达成目标的文章大家可参考

1. Nginx代理概念

Nginx我们的主要作用是用其来做反向代理什么是正向代理什么是反向代理下面两张图足可以说明参考《Nginx高性能Web服务器详解》。
正向代理局域网内部机器借助代理服务器访问局域网外的网站可增强局域网内部网络安全性使得网外的威胁因素不容易影响到网内。
反向代理局域网像Internet提供资源让Internet用户可以访问局域网内部资源代理服务器将请求代理访问到局域网内部的服务。
在这里插入图片描述
在这里插入图片描述

2. Nginx下载安装

  1. 下载wget http://nginx.org/download/nginx-1.23.1.tar.gz
  2. 解压tar xzvf nginx-1.23.1.tar.gz
  3. 编译./configure --prefix=/usr/local/nginx && make && make install

经过上面一系列操作nginx目录出现在/usr/local/nginx其中二进制目录在 /usr/local/nginx/sbin配置文件目录/usr/local/nginx/conf

3. Nginx常用命令

nginx -s reload # 向主进程发送信号重新加载配置文件热重启
nginx -s reopen # 重启 Nginx
nginx -s stop # 快速关闭
nginx -s quit # 等待工作进程处理完成后关闭
nginx -T # 查看当前 Nginx 最终的配置
nginx -t # 检查配置是否有问题

4. Nginx 核心配置

# main段配置信息
user  nginx;                        # 运行用户默认即是nginx可以不进行设置
worker_processes  auto;             # Nginx 进程数一般设置为和 CPU 核数一样
error_log  logs/error.log warn;   # Nginx 的错误日志存放目录
pid        logs/nginx.pid;      # Nginx 服务启动时的 pid 存放位置

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

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

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

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

    # include /etc/nginx/conf.d/*.conf;   # 加载子配置项
    
    # server段配置信息
    server {
    	listen       80;       # 配置监听的端口
    	server_name  localhost;    # 配置的域名
      
    	# location段配置信息
    	location / {
    		root   /usr/local/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;   # 同上
    }
}
  • main 全局配置对全局生效
  • events 配置影响 Nginx 服务器与用户的网络连接
  • http 配置代理缓存日志定义等绝大多数功能和第三方模块的配置
  • server 配置虚拟主机的相关参数一个 http 块中可以有多个 server 块
  • location 用于配置匹配的 uri
  • upstream 配置后端服务器具体地址负载均衡配置不可或缺的部分

用一张图清晰的展示它的层级结构:
在这里插入图片描述

5. 配置文件 main 段核心参数

5.1 user

指定运行 Nginx 的 woker 子进程的属主和属组其中组可以不指定。

user USERNAME [GROUP]
user nginx lion; # 用户是nginx;组是lion

5.2 pid

指定运行 Nginx master 主进程的 pid 文件存放路径。

pid /opt/nginx/logs/nginx.pid # master主进程的的pid存放在nginx.pid的文件

5.3 worker_rlimit_nofile_number

指定 worker 子进程可以打开的最大文件句柄数。

worker_rlimit_nofile 20480; # 可以理解成每个worker子进程的最大连接数量。

5.4 worker_rlimit_core

指定 worker 子进程异常终止后的 core 文件用于记录分析问题。

worker_rlimit_core 50M; # 存放大小限制
working_directory /opt/nginx/tmp; # 存放目录

5.5 worker_processes_number

指定 Nginx 启动的 worker 子进程数量。

worker_processes 4; # 指定具体子进程数量
worker_processes auto; # 与当前cpu物理核心数一致

5.6 worker_cpu_affinity

将每个 worker 子进程与我们的 cpu 物理核心绑定。

worker_cpu_affinity 0001 0010 0100 1000; # 4个物理核心4个worker子进程

在这里插入图片描述
将每个 worker 子进程与特定 CPU 物理核心绑定优势在于避免同一个 worker 子进程在不同的 CPU 核心上切换缓存失效降低性能。但其并不能真正的避免进程切换。

5.7 worker_priority

指定 worker 子进程的 nice 值以调整运行 Nginx 的优先级通常设定为负值以优先调用 Nginx 。
Linux 默认进程的优先级值是120值越小越优先 nice 定范围为 -20 到 +19 。
[备注] 应用的默认优先级值是120加上 nice 值等于它最终的值这个值越小优先级越高。

worker_priority -10; # 120-10=110110就是最终的优先级

5.8 worker_shutdown_timeout

指定 worker 子进程优雅退出时的超时时间。

worker_shutdown_timeout 5s;

5.9 timer_resolution

worker 子进程内部使用的计时器精度调整时间间隔越大系统调用越少有利于性能提升反之系统调用越多性能下降。
在 Linux 系统中用户需要获取计时器时需要向操作系统内核发送请求有请求就必然会有开销因此这个间隔越大开销就越小。

timer_resolution 100ms;

5.10 daemon

指定 Nginx 的运行方式前台还是后台前台用于调试后台用于生产。

daemon off; # 默认是on后台运行模式

6. 配置文件 events 段核心参数

6.1 use

Nginx 使用何种事件驱动模型。

use method; # 不推荐配置它让nginx自己选择
method 可选值为select、poll、kqueue、epoll、/dev/poll、eventport

6.2 worker_connections

worker 子进程能够处理的最大并发连接数。

worker_connections 1024 # 每个子进程的最大连接数为1024

6.3 accept_mutex

是否打开负载均衡互斥锁。

accept_mutex on # 默认是off关闭的这里推荐打开

7. server

7.1 server_name

指定虚拟主机域名。

server_name name1 name2 name3

# 示例
server_name www.nginx.com;

域名匹配的四种写法

精确匹配 server_name www.nginx.com ;
左侧通配 server_name *.nginx.com ;
右侧统配 server_name  www.nginx.* ;
正则匹配 server_name ~^www\.nginx\.*$ ;
匹配优先级精确匹配 > 左侧通配符匹配 > 右侧通配符匹配 > 正则表达式匹配

server_name 配置实例
1、配置本地 DNS 解析 vim /etc/hosts macOS 系统

# 添加如下内容其中 121.42.11.34 是阿里云服务器IP地址
121.42.11.34 www.nginx-test.com
121.42.11.34 mail.nginx-test.com
121.42.11.34 www.nginx-test.org
121.42.11.34 doc.nginx-test.com
121.42.11.34 www.nginx-test.cn
121.42.11.34 fe.nginx-test.club

[注意] 这里使用的是虚拟域名进行测试因此需要配置本地 DNS 解析如果使用阿里云上购买的域名则需要在阿里云上设置好域名解析

2、配置阿里云 Nginx vim /etc/nginx/nginx.conf

# 这里只列举了http端中的sever端配置

# 左匹配
server {
	listen	80;
	server_name	*.nginx-test.com;
	root	/usr/share/nginx/html/nginx-test/left-match/;
	location / {
		index index.html;
	}
}

# 正则匹配
server {
	listen	80;
	server_name	~^.*\.nginx-test\..*$;
	root	/usr/share/nginx/html/nginx-test/reg-match/;
	location / {
		index index.html;
	}
}

# 右匹配
server {
	listen	80;
	server_name	www.nginx-test.*;
	root	/usr/share/nginx/html/nginx-test/right-match/;
	location / {
		index index.html;
	}
}

# 完全匹配
server {
	listen	80;
	server_name	www.nginx-test.com;
	root	/usr/share/nginx/html/nginx-test/all-match/;
	location / {
		index index.html;
	}
}

3、访问分析
当访问 www.nginx-test.com 时都可以被匹配上因此选择优先级最高的“完全匹配”
当访问 mail.nginx-test.com 时会进行“左匹配”
当访问 www.nginx-test.org 时会进行“右匹配”
当访问 doc.nginx-test.com 时会进行“左匹配”
当访问 www.nginx-test.cn 时会进行“右匹配”
当访问 fe.nginx-test.club 时会进行“正则匹配”

7.2 root

指定静态资源目录位置它可以写在 http 、 server 、 location 等配置中。

root path

例如
location /image {
	root /opt/nginx/static;
}

当用户访问 www.test.com/image/1.png 时实际在服务器找的路径是 /opt/nginx/static/image/1.png

[注意] root 会将定义路径与 URI 叠加 alias 则只取定义路径。

7.3 alias

它也是指定静态资源目录位置它只能写在 location 中。

location /image {
	alias /opt/nginx/static/image/;
}

当用户访问 www.test.com/image/1.png 时实际在服务器找的路径是 /opt/nginx/static/image/1.png

[注意] 使用 alias 末尾一定要添加 / 并且它只能位于 location 中。

7.4 location

配置路径。

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

匹配规则

  • = 精确匹配
  • ~ 正则匹配区分大小写
  • ~* 正则匹配不区分大小写
  • ^~ 匹配到即停止搜索

匹配优先级 = > ^~ > ~ > ~* > 不带任何字符。
实例

server {
  listen	80;
  server_name	www.nginx-test.com;
  
  # 只有当访问 www.nginx-test.com/match_all/ 时才会匹配到/usr/share/nginx/html/match_all/index.html
  location = /match_all/ {
      root	/usr/share/nginx/html
      index index.html
  }
  
  # 当访问 www.nginx-test.com/1.jpg 等路径时会去 /usr/share/nginx/images/1.jpg 找对应的资源
  location ~ \.(jpeg|jpg|png|svg)$ {
  	root /usr/share/nginx/images;
  }
  
  # 当访问 www.nginx-test.com/bbs/ 时会匹配上 /usr/share/nginx/html/bbs/index.html
  location ^~ /bbs/ {
  	root /usr/share/nginx/html;
    index index.html index.htm;
  }
}

location 中的反斜线

location /test {
	...
}

location /test/ {
	...
}

不带 / 当访问 www.nginx-test.com/test 时 Nginx 先找是否有 test 目录如果有则找 test 目录下的 index.html 如果没有 test 目录 nginx 则会找是否有 test 文件。
带 / 当访问 www.nginx-test.com/test 时 Nginx 先找是否有 test 目录如果有则找 test 目录下的 index.html 如果没有它也不会去找是否存在 test 文件。

7.5 return

停止处理请求直接返回响应码或重定向到其他 URL 执行 return 指令后 location 中后续指令将不会被执行。

return code [text];
return code URL;
return URL;

例如
location / {
	return 404; # 直接返回状态码
}

location / {
	return 404 "pages not found"; # 返回状态码 + 一段文本
}

location / {
	return 302 /bbs ; # 返回状态码 + 重定向地址
}

location / {
	return https://www.baidu.com ; # 返回重定向地址
}

7.6 rewrite

根据指定正则表达式匹配规则重写 URL 。

语法rewrite 正则表达式 要替换的内容 [flag];

上下文server、location、if

示例rewirte /images/(.*\.jpg)$ /pic/$1; # $1是前面括号(.*\.jpg)的反向引用

flag 可选值的含义

  • last 重写后的 URL 发起新请求再次进入 server 段重试 location 的中的匹配
  • break 直接使用重写后的 URL 不再匹配其它 location 中语句
  • redirect 返回302临时重定向
  • permanent 返回301永久重定向
server{
  listen 80;
  server_name fe.lion.club; # 要在本地hosts文件进行配置
  root html;
  location /search {
  	rewrite ^/(.*) https://www.baidu.com redirect;
  }
  
  location /images {
  	rewrite /images/(.*) /pics/$1;
  }
  
  location /pics {
  	rewrite /pics/(.*) /photos/$1;
  }
  
  location /photos {
  
  }
}

按照这个配置我们来分析

  • 当访问 fe.lion.club/search 时会自动帮我们重定向到 https://www.baidu.com。
  • 当访问 fe.lion.club/images/1.jpg 时第一步重写 URL 为 fe.lion.club/pics/1.jpg 找到 pics 的 location 继续重写 URL 为 fe.lion.club/photos/1.jpg 找到 /photos 的 location 后去 html/photos 目录下寻找 1.jpg 静态资源。

7.7 if

语法if (condition) {...}

上下文server、location

示例
if($http_user_agent ~ Chrome){
  rewrite /(.*)/browser/$1 break;
}

condition 判断条件

  • $variable 仅为变量时值为空或以0开头字符串都会被当做 false 处理
  • = 或 != 相等或不等
  • ~ 正则匹配
  • ! ~ 非正则匹配
  • ~* 正则匹配不区分大小写
  • -f 或 ! -f 检测文件存在或不存在
  • -d 或 ! -d 检测目录存在或不存在
  • -e 或 ! -e 检测文件、目录、符号链接等存在或不存在
  • -x 或 ! -x 检测文件可以执行或不可执行

实例

server {
  listen 8080;
  server_name localhost;
  root html;
  
  location / {
  	if ( $uri = "/images/" ){
    	rewrite (.*) /pics/ break;
    }
  }
}

当访问 localhost:8080/images/ 时会进入 if 判断里面执行 rewrite 命令。

7.8 autoindex

用户请求以 / 结尾时列出目录结构可以用于快速搭建静态资源下载网站。
autoindex.conf 配置信息

server {
  listen 80;
  server_name fe.lion-test.club;
  
  location /download/ {
    root /opt/source;
    
    autoindex on; # 打开 autoindex可选参数有 on | off
    autoindex_exact_size on; # 修改为off以KB、MB、GB显示文件大小默认为on以bytes显示出⽂件的确切⼤⼩
    autoindex_format html; # 以html的方式进行格式化可选参数有 html | json | xml
    autoindex_localtime off; # 显示的⽂件时间为⽂件的服务器时间。默认为off显示的⽂件时间为GMT时间
  }
}

当访问 fe.lion.com/download/ 时会把服务器 /opt/source/download/ 路径下的文件展示出来如下图所示

在这里插入图片描述

7.9 变量

Nginx 提供给使用者的变量非常多但是终究是一个完整的请求过程所产生数据 Nginx 将这些数据以变量的形式提供给使用者。
在这里插入图片描述
在这里插入图片描述
实例演示 var.conf

server{
	listen 8081;
	server_name var.lion-test.club;
	root /usr/share/nginx/html;
	location / {
		return 200 "
remote_addr: $remote_addr
remote_port: $remote_port
server_addr: $server_addr
server_port: $server_port
server_protocol: $server_protocol
binary_remote_addr: $binary_remote_addr
connection: $connection
uri: $uri
request_uri: $request_uri
scheme: $scheme
request_method: $request_method
request_length: $request_length
args: $args
arg_pid: $arg_pid
is_args: $is_args
query_string: $query_string
host: $host
http_user_agent: $http_user_agent
http_referer: $http_referer
http_via: $http_via
request_time: $request_time
https: $https
request_filename: $request_filename
document_root: $document_root
";
	}
}

当我们访问 http://var.lion-test.club:8081/test?pid=121414&cid=sadasd 时由于 Nginx 中写了 return 方法因此 chrome 浏览器会默认为我们下载一个文件下面展示的就是下载的文件内容

remote_addr: 27.16.220.84
remote_port: 56838
server_addr: 172.17.0.2
server_port: 8081
server_protocol: HTTP/1.1
binary_remote_addr: 茉
connection: 126
uri: /test/
request_uri: /test/?pid=121414&cid=sadasd
scheme: http
request_method: GET
request_length: 518
args: pid=121414&cid=sadasd
arg_pid: 121414
is_args: ?
query_string: pid=121414&cid=sadasd
host: var.lion-test.club
http_user_agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36
http_referer: 
http_via: 
request_time: 0.000
https: 
request_filename: /usr/share/nginx/html/test/
document_root: /usr/share/nginx/html

Nginx 的配置还有非常多以上只是罗列了一些常用的配置在实际项目中还是要学会查阅文档。

8. Nginx 应用核心概念

8.1 正向代理

上面已经阐述

8.2 反向代理

上面已经阐述

8.3 动静分离

动静分离是指在 web 服务器架构中将静态页面与动态页面或者静态内容接口和动态内容接口分开不同系统访问的架构设计方法进而提示整个服务的访问性和可维护性。
在这里插入图片描述

一般来说都需要将动态资源和静态资源分开由于 Nginx 的高并发和静态资源缓存等特性经常将静态资源部署在 Nginx上。如果请求的是静态资源直接到静态资源目录获取资源如果是动态资源的请求则利用反向代理的原理把请求转发给对应后台应用去处理从而实现动静分离。

使用前后端分离后可以很大程度提升静态资源的访问速度即使动态服务不可用静态资源的访问也不会受到影响。

8.4 负载均衡

一般情况下客户端发送多个请求到服务器服务器处理请求其中一部分可能要操作一些资源比如数据库、静态资源等服务器处理完毕后再将结果返回给客户端。

这种模式对于早期的系统来说功能要求不复杂且并发请求相对较少的情况下还能胜任成本也低。随着信息数量不断增长访问量和数据量飞速增长以及系统业务复杂度持续增加这种做法已无法满足要求并发量特别大时服务器容易崩。

很明显这是由于服务器性能的瓶颈造成的问题除了堆机器之外最重要的做法就是负载均衡。

请求爆发式增长的情况下单个机器性能再强劲也无法满足要求了这个时候集群的概念产生了单个服务器解决不了的问题可以使用多个服务器然后将请求分发到各个服务器上将负载分发到不同的服务器这就是负载均衡核心是「分摊压力」。 Nginx 实现负载均衡一般来说指的是将请求转发给服务器集群。

举个具体的例子晚高峰乘坐地铁的时候入站口经常会有地铁工作人员大喇叭“请走 B 口 B 口人少车空…”这个工作人员的作用就是负载均衡。
在这里插入图片描述
Nginx 实现负载均衡的策略

  • 轮询策略默认情况下采用的策略将所有客户端请求轮询分配给服务端。这种策略是可以正常工作的但是如果其中某一台服务器压力太大出现延迟会影响所有分配在这台服务器下的用户。
  • 最小连接数策略将请求优先分配给压力较小的服务器它可以平衡每个队列的长度并避免向压力大的服务器添加更多的请求。
  • 最快响应时间策略优先分配给响应时间最短的服务器。
  • 客户端 ip 绑定策略来自同一个 ip 的请求永远只分配一台服务器有效解决了动态网页存在的 session 共享问题。

9. Nginx 实战配置

在配置反向代理和负载均衡等等功能之前有两个核心模块是我们必须要掌握的这两个模块应该说是 Nginx 应用配置中的核心它们分别是 upstream 、proxy_pass 。

9.1 upstream

用于定义上游服务器指的就是后台提供的应用服务器的相关信息。
在这里插入图片描述

语法upstream name {
	...
}

上下文http

示例
upstream back_end_server{
  server 192.168.100.33:8081
}

在 upstream 内可使用的指令

  • server 定义上游服务器地址
  • zone 定义共享内存用于跨 worker 子进程
  • keepalive 对上游服务启用长连接
  • keepalive_requests 一个长连接最多请求 HTTP 的个数
  • keepalive_timeout 空闲情形下一个长连接的超时时长
  • hash 哈希负载均衡算法
  • ip_hash 依据 IP 进行哈希计算的负载均衡算法
  • least_conn 最少连接数负载均衡算法
  • least_time 最短响应时间负载均衡算法
  • random 随机负载均衡算法
9.1.1 server

定义上游服务器地址。

语法server address [parameters]

上下文upstream

parameters 可选值

  • weight=number 权重值默认为1
  • max_conns=number 上游服务器的最大并发连接数
  • fail_timeout=time 服务器不可用的判定时间
  • max_fails=numer 服务器不可用的检查次数
  • backup 备份服务器仅当其他服务器都不可用时才会启用
  • down 标记服务器长期不可用离线维护
9.1.2 keepalive

限制每个 worker 子进程与上游服务器空闲长连接的最大数量。

keepalive connections;

上下文upstream

示例keepalive 16;
9.1.3 keepalive_requests

单个长连接可以处理的最多 HTTP 请求个数。

语法keepalive_requests number;

默认值keepalive_requests 100;

上下文upstream
9.1.4 keepalive_timeout

空闲长连接的最长保持时间。

语法keepalive_timeout time;

默认值keepalive_timeout 60s;

上下文upstream
9.1.5 配置实例
upstream back_end{
	server 127.0.0.1:8081 weight=3 max_conns=1000 fail_timeout=10s max_fails=2;
  keepalive 32;
  keepalive_requests 50;
  keepalive_timeout 30s;
}

9.2 proxy_pass

用于配置代理服务器。

语法proxy_pass URL;

上下文location、if、limit_except

示例
proxy_pass http://127.0.0.1:8081
proxy_pass http://127.0.0.1:8081/proxy

URL 参数原则

  • URL 必须以 http 或 https 开头
  • URL 中可以携带变量
  • URL 中是否带 URI 会直接影响发往上游请求的 URL

接下来让我们来看看两种常见的 URL 用法

  • proxy_pass http://192.168.100.33:8081
  • proxy_pass http://192.168.100.33:8081/

这两种用法的区别就是带 / 和不带 / 在配置代理时它们的区别可大了

  • 不带 / 意味着 Nginx 不会修改用户 URL 而是直接透传给上游的应用服务器
  • 带 / 意味着 Nginx 会修改用户 URL 修改方法是将 location 后的 URL 从用户 URL 中删除

不带 / 的用法

location /bbs/{
  proxy_pass http://127.0.0.1:8080;
}

分析

  • 用户请求 URL /bbs/abc/test.html
  • 请求到达 Nginx 的 URL /bbs/abc/test.html
  • 请求到达上游应用服务器的 URL /bbs/abc/test.html

带 / 的用法

location /bbs/{
  proxy_pass http://127.0.0.1:8080/;
}

分析

  • 用户请求 URL /bbs/abc/test.html
  • 请求到达 Nginx 的 URL /bbs/abc/test.html
  • 请求到达上游应用服务器的 URL /abc/test.html

并没有拼接上 /bbs 这点和 root 与 alias 之间的区别是保持一致的。

9.3 配置反向代理

这里为了演示更加接近实际作者准备了两台云服务器它们的公网 IP 分别是 121.42.11.34 与 121.5.180.193 。

我们把 121.42.11.34 服务器作为上游服务器做如下配置

# /etc/nginx/conf.d/proxy.conf
server{
  listen 8080;
  server_name localhost;
  
  location /proxy/ {
    root /usr/share/nginx/html/proxy;
    index index.html;
  }
}

# /usr/share/nginx/html/proxy/index.html
<h1> 121.42.11.34 proxy html </h1>

配置完成后重启 Nginx 服务器 nginx -s reload 。

把 121.5.180.193 服务器作为代理服务器做如下配置

# /etc/nginx/conf.d/proxy.conf
upstream back_end {
  server 121.42.11.34:8080 weight=2 max_conns=1000 fail_timeout=10s max_fails=3;
  keepalive 32;
  keepalive_requests 80;
  keepalive_timeout 20s;
}

server {
  listen 80;
  server_name proxy.lion.club;
  location /proxy {
  	proxy_pass http://back_end/proxy;
  }
}

本地机器要访问 proxy.lion.club 域名因此需要配置本地 hosts 通过命令vim /etc/hosts 进入配置文件添加如下内容

121.5.180.193 proxy.lion.club

在这里插入图片描述
分析

  • 当访问 proxy.lion.club/proxy 时通过 upstream 的配置找到 121.42.11.34:8080
  • 因此访问地址变为 http://121.42.11.34:8080/proxy
  • 连接到 121.42.11.34 服务器找到 8080 端口提供的 server
  • 通过 server 找到 /usr/share/nginx/html/proxy/index.html 资源最终展示出来。

9.4 配置负载均衡

配置负载均衡主要是要使用 upstream 指令。

我们把 121.42.11.34 服务器作为上游服务器做如下配置 /etc/nginx/conf.d/balance.conf

server{
  listen 8020;
  location / {
  	return 200 'return 8020 \n';
  }
}

server{
  listen 8030;
  location / {
  	return 200 'return 8030 \n';
  }
}

server{
  listen 8040;
  location / {
  	return 200 'return 8040 \n';
  }
}

配置完成后

  • nginx -t 检测配置是否正确
  • nginx -s reload 重启 Nginx 服务器
  • 执行 ss -nlt 命令查看端口是否被占用从而判断 Nginx 服务是否正确启动。

把 121.5.180.193 服务器作为代理服务器做如下配置 /etc/nginx/conf.d/balance.conf

upstream demo_server {
  server 121.42.11.34:8020;
  server 121.42.11.34:8030;
  server 121.42.11.34:8040;
}

server {
  listen 80;
  server_name balance.lion.club;
  
  location /balance/ {
  	proxy_pass http://demo_server;
  }
}

配置完成后重启 Nginx 服务器。并且在需要访问的客户端配置好 ip 和域名的映射关系。

# /etc/hosts

121.5.180.193 balance.lion.club

在客户端机器执行 curl http://balance.lion.club/balance/ 命令
在这里插入图片描述
不难看出负载均衡的配置已经生效了每次给我们分发的上游服务器都不一样。就是通过简单的轮询策略进行上游服务器分发。

接下来我们再来了解下 Nginx 的其它分发策略。

9.4.1 hash 算法

通过制定关键字作为 hash key 基于 hash 算法映射到特定的上游服务器中。关键字可以包含有变量、字符串。

upstream demo_server {
  hash $request_uri;
  server 121.42.11.34:8020;
  server 121.42.11.34:8030;
  server 121.42.11.34:8040;
}

server {
  listen 80;
  server_name balance.lion.club;
  
  location /balance/ {
  	proxy_pass http://demo_server;
  }
}

hash $request_uri 表示使用 request_uri 变量作为 hash 的 key 值只要访问的 URI 保持不变就会一直分发给同一台服务器。

9.4.2 ip_hash

根据客户端的请求 ip 进行判断只要 ip 地址不变就永远分配到同一台主机。它可以有效解决后台服务器 session 保持的问题。

upstream demo_server {
  ip_hash;
  server 121.42.11.34:8020;
  server 121.42.11.34:8030;
  server 121.42.11.34:8040;
}

server {
  listen 80;
  server_name balance.lion.club;
  
  location /balance/ {
  	proxy_pass http://demo_server;
  }
}
9.4.3 最少连接数算法

各个 worker 子进程通过读取共享内存的数据来获取后端服务器的信息。来挑选一台当前已建立连接数最少的服务器进行分配请求。

语法least_conn;

上下文upstream;

示例

upstream demo_server {
  zone test 10M; # zone可以设置共享内存空间的名字和大小
  least_conn;
  server 121.42.11.34:8020;
  server 121.42.11.34:8030;
  server 121.42.11.34:8040;
}

server {
  listen 80;
  server_name balance.lion.club;
  
  location /balance/ {
  	proxy_pass http://demo_server;
  }
}

最后你会发现负载均衡的配置其实一点都不复杂。

9.5 配置缓存

缓存可以非常有效的提升性能因此不论是客户端浏览器还是代理服务器 Nginx 乃至上游服务器都多少会涉及到缓存。可见缓存在每个环节都是非常重要的。下面让我们来学习 Nginx 中如何设置缓存策略。

9.5.1 proxy_cache

存储一些之前被访问过、而且可能将要被再次访问的资源使用户可以直接从代理服务器获得从而减少上游服务器的压力加快整个访问速度。

语法proxy_cache zone | off ; # zone 是共享内存的名称

默认值proxy_cache off;

上下文http、server、location
9.5.2 proxy_cache_path

设置缓存文件的存放路径。

语法proxy_cache_path path [level=levels] ...可选参数省略下面会详细列举

默认值proxy_cache_path off

上下文http

参数含义

  • path 缓存文件的存放路径
  • level path 的目录层级
  • keys_zone 设置共享内存
  • inactive 在指定时间内没有被访问缓存会被清理默认10分钟
9.5.3 proxy_cache_key

设置缓存文件的 key 。

语法proxy_cache_key

默认值proxy_cache_key $scheme$proxy_host$request_uri;

上下文http、server、location
9.5.4 proxy_cache_valid

配置什么状态码可以被缓存以及缓存时长。

语法proxy_cache_valid [code...] time;

上下文http、server、location

配置示例proxy_cache_valid 200 304 2m;; # 说明对于状态为200和304的缓存文件的缓存时间是2分钟
9.5.5 proxy_no_cache

定义相应保存到缓存的条件如果字符串参数的至少一个值不为空且不等于“ 0”则将不保存该响应到缓存。

语法proxy_no_cache string;

上下文http、server、location

示例proxy_no_cache $http_pragma    $http_authorization;
9.5.6 proxy_cache_bypass

定义条件在该条件下将不会从缓存中获取响应。

语法proxy_cache_bypass string;

上下文http、server、location

示例proxy_cache_bypass $http_pragma    $http_authorization;
9.5.7 upstream_cache_status

它存储了缓存是否命中的信息会设置在响应头信息中在调试中非常有用。

MISS: 未命中缓存
HIT 命中缓存
EXPIRED: 缓存过期
STALE: 命中了陈旧缓存
REVALIDDATED: Nginx验证陈旧缓存依然有效
UPDATING: 内容陈旧但正在更新
BYPASS: X响应从原始服务器获取
9.5.8 配置实例

我们把 121.42.11.34 服务器作为上游服务器做如下配置 /etc/nginx/conf.d/cache.conf

server {
  listen 1010;
  root /usr/share/nginx/html/1010;
  location / {
  	index index.html;
  }
}

server {
  listen 1020;
  root /usr/share/nginx/html/1020;
  location / {
  	index index.html;
  }
}

把 121.5.180.193 服务器作为代理服务器做如下配置 /etc/nginx/conf.d/cache.conf

proxy_cache_path /etc/nginx/cache_temp levels=2:2 keys_zone=cache_zone:30m max_size=2g inactive=60m use_temp_path=off;

upstream cache_server{
  server 121.42.11.34:1010;
  server 121.42.11.34:1020;
}

server {
  listen 80;
  server_name cache.lion.club;
  location / {
    proxy_cache cache_zone; # 设置缓存内存上面配置中已经定义好的
    proxy_cache_valid 200 5m; # 缓存状态为200的请求缓存时长为5分钟
    proxy_cache_key $request_uri; # 缓存文件的key为请求的URI
    add_header Nginx-Cache-Status $upstream_cache_status # 把缓存状态设置为头部信息响应给客户端
    proxy_pass http://cache_server; # 代理转发
  }
}

缓存就是这样配置我们可以在 /etc/nginx/cache_temp 路径下找到相应的缓存文件。

对于一些实时性要求非常高的页面或数据来说就不应该去设置缓存下面来看看如何配置不缓存的内容。

server {
  listen 80;
  server_name cache.lion.club;
  # URI 中后缀为 .txt 或 .text 的设置变量值为 "no cache"
  if ($request_uri ~ \.(txt|text)$) {
  	set $cache_name "no cache"
  }
  
  location / {
    proxy_no_cache $cache_name; # 判断该变量是否有值如果有值则不进行缓存如果没有值则进行缓存
    proxy_cache cache_zone; # 设置缓存内存
    proxy_cache_valid 200 5m; # 缓存状态为200的请求缓存时长为5分钟
    proxy_cache_key $request_uri; # 缓存文件的key为请求的URI
    add_header Nginx-Cache-Status $upstream_cache_status # 把缓存状态设置为头部信息响应给客户端
    proxy_pass http://cache_server; # 代理转发
  }
}

9.6 HTTPS

在学习如何配置 HTTPS 之前我们先来简单回顾下 HTTPS 的工作流程是怎么样的它是如何进行加密保证安全的

9.6.1 HTTPS 工作流程
  1. 客户端浏览器访问 https://www.baidu.com 百度网站
  2. 百度服务器返回 HTTPS 使用的 CA 证书
  3. 浏览器验证 CA 证书是否为合法证书
  4. 验证通过证书合法生成一串随机数并使用公钥证书中提供的进行加密
  5. 发送公钥加密后的随机数给百度服务器
  6. 百度服务器拿到密文通过私钥进行解密获取到随机数公钥加密私钥解密反之也可以
  7. 百度服务器把要发送给浏览器的内容使用随机数进行加密后传输给浏览器
  8. 此时浏览器可以使用随机数进行解密获取到服务器的真实传输内容

这就是 HTTPS 的基本运作原理使用对称加密和非对称机密配合使用保证传输内容的安全性。

9.6.2 配置证书

下载证书的压缩文件里面有个 Nginx 文件夹把 xxx.crt 和 xxx.key 文件拷贝到服务器目录再进行如下配置

server {
  listen 443 ssl http2 default_server;   # SSL 访问端口号为 443
  server_name lion.club;         # 填写绑定证书的域名(我这里是随便写的)
  ssl_certificate /etc/nginx/https/lion.club_bundle.crt;   # 证书地址
  ssl_certificate_key /etc/nginx/https/lion.club.key;      # 私钥地址
  ssl_session_timeout 10m;
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # 支持ssl协议版本默认为后三个主流版本是[TLSv1.2]
 
  location / {
    root         /usr/share/nginx/html;
    index        index.html index.htm;
  }
}

如此配置后就能正常访问 HTTPS 版的网站了。

9.7 配置跨域 CORS

9.7.1 跨域的定义

同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。通常不允许不同源间的读操作。

9.7.2 同源的定义

如果两个页面的协议端口如果有指定和域名都相同则两个页面具有相同的源。

下面给出了与 URL http://store.company.com/dir/page.html 的源进行对比的示例:

http://store.company.com/dir2/other.html 同源
https://store.company.com/secure.html 不同源协议不同
http://store.company.com:81/dir/etc.html 不同源端口不同
http://news.company.com/dir/other.html 不同源主机不同

不同源会有如下限制

  • Web 数据层面同源策略限制了不同源的站点读取当前站点的 Cookie 、 IndexDB 、 LocalStorage 等数据。
  • DOM 层面同源策略限制了来自不同源的 JavaScript 脚本对当前 DOM 对象读和写的操作。
  • 网络层面同源策略限制了通过 XMLHttpRequest 等方式将站点的数据发送给不同源的站点。
9.7.3 Nginx 解决跨域的原理

例如

  • 前端 server 的域名为 fe.server.com
  • 后端服务的域名为 dev.server.com

现在我在 fe.server.com 对 dev.server.com 发起请求一定会出现跨域。
现在我们只需要启动一个 Nginx 服务器将 server_name 设置为 fe.server.com 然后设置相应的 location 以拦截前端需要跨域的请求最后将请求代理回 dev.server.com 。如下面的配置

server {
	listen   		 80;
	server_name  fe.server.com;
	location / {
		proxy_pass dev.server.com;
	}
}

这样可以完美绕过浏览器的同源策略 fe.server.com 访问 Nginx 的 fe.server.com 属于同源访问而 Nginx 对服务端转发的请求不会触发浏览器的同源策略。

9.8 配置开启 gzip 压缩

GZIP 是规定的三种标准 HTTP 压缩格式之一。目前绝大多数的网站都在使用 GZIP 传输 HTML 、CSS 、 JavaScript 等资源文件。
对于文本文件 GZiP 的效果非常明显开启后传输所需流量大约会降至 1/4~1/3 。
并不是每个浏览器都支持 gzip 的如何知道客户端是否支持 gzip 呢请求头中的 Accept-Encoding 来标识对压缩的支持。
在这里插入图片描述
启用 gzip 同时需要客户端和服务端的支持如果客户端支持 gzip 的解析那么只要服务端能够返回 gzip 的文件就可以启用 gzip 了,我们可以通过 Nginx 的配置来让服务端支持 gzip 。下面的 respone 中 content-encoding:gzip 指服务端开启了 gzip 的压缩方式。

在这里插入图片描述
在 /etc/nginx/conf.d/ 文件夹中新建配置文件 gzip.conf

# # 默认off是否开启gzip
gzip on; 
# 要采用 gzip 压缩的 MIME 文件类型其中 text/html 被系统强制启用
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

# ---- 以上两个参数开启就可以支持Gzip压缩了 ---- #

# 默认 off该模块启用后Nginx 首先检查是否存在请求静态文件的 gz 结尾的文件如果有则直接返回该 .gz 文件内容
gzip_static on;

# 默认 offnginx做为反向代理时启用用于设置启用或禁用从代理服务器上收到相应内容 gzip 压缩
gzip_proxied any;

# 用于在响应消息头中添加 VaryAccept-Encoding使代理服务器根据请求头中的 Accept-Encoding 识别是否启用 gzip 压缩
gzip_vary on;

# gzip 压缩比压缩级别是 1-91 压缩级别最低9 最高级别越高压缩率越大压缩时间越长建议 4-6
gzip_comp_level 6;

# 获取多少内存用于缓存压缩结果16 8k 表示以 8k*16 为单位获得
gzip_buffers 16 8k;

# 允许压缩的页面最小字节数页面字节数从header头中的 Content-Length 中进行获取。默认值是 0不管页面多大都压缩。建议设置成大于 1k 的字节数小于 1k 可能会越压越大
# gzip_min_length 1k;

# 默认 1.1启用 gzip 所需的 HTTP 最低版本
gzip_http_version 1.1;

其实也可以通过前端构建工具例如 webpack 、rollup 等在打生产包时就做好 Gzip 压缩然后放到 Nginx 服务器中这样可以减少服务器的开销加快访问速度。
关于 Nginx 的实际应用就学习到这里相信通过掌握了 Nginx 核心配置以及实战配置之后再遇到什么需求我们也能轻松应对。接下来让我们再深入一点学习下 Nginx 的架构。

原连接还有一些原理的介绍这里忽略原理介绍。

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: nginx