做为一名开发人员,你是否是常常碰到领导让你上服务器去修改 Nginx 配置,然而你会以“我是开发,这个我不会”为理由搪塞过去呢!今天就让咱们一块儿告别这种尴尬,向“真正”的程序员迈进!!!javascript
Nginx 是开源、高性能、高可靠的 Web 和反向代理服务器,并且支持热部署,几乎能够作到 7 * 24 小时不间断运行,即便运行几个月也不须要从新启动,还能在不间断服务的状况下对软件版本进行热更新。性能是 Nginx 最重要的考量,其占用内存少、并发能力强、能支持高达 5w 个并发链接数,最重要的是, Nginx 是免费的并能够商业化,配置使用也比较简单。css
Nginx 的最重要的几个使用场景:html
对于前端来讲 Node.js 并不陌生, Nginx 和 Node.js 的不少理念相似, HTTP 服务器、事件驱动、异步非阻塞等,且 Nginx 的大部分功能使用 Node.js 也能够实现,但 Nginx 和 Node.js 并不冲突,都有本身擅长的领域。Nginx 擅长于底层服务器端资源的处理(静态资源处理转发、反向代理,负载均衡等), Node.js 更擅长上层具体业务逻辑的处理,二者能够完美组合。前端
用一张图表示:java
本文演示的是 Linux centOS 7.x 的操做系统上安装 Nginx ,至于在其它操做系统上进行安装能够网上自行搜索,都很是简单的。node
yum install nginx -y
安装完成后,经过 rpm -ql nginx 命令查看 Nginx 的安装信息:webpack
# Nginx配置文件 /etc/nginx/nginx.conf # nginx 主配置文件 /etc/nginx/nginx.conf.default # 可执行程序文件 /usr/bin/nginx-upgrade /usr/sbin/nginx # nginx库文件 /usr/lib/systemd/system/nginx.service # 用于配置系统守护进程 /usr/lib64/nginx/modules # Nginx模块目录 # 帮助文档 /usr/share/doc/nginx-1.16.1 /usr/share/doc/nginx-1.16.1/CHANGES /usr/share/doc/nginx-1.16.1/README /usr/share/doc/nginx-1.16.1/README.dynamic /usr/share/doc/nginx-1.16.1/UPGRADE-NOTES-1.6-to-1.10 # 静态资源目录 /usr/share/nginx/html/404.html /usr/share/nginx/html/50x.html /usr/share/nginx/html/index.html # 存放Nginx日志文件 /var/log/nginx
主要关注的文件夹有两个:nginx
# 开机配置 systemctl enable nginx # 开机自动启动 systemctl disable nginx # 关闭开机自动启动 # 启动Nginx systemctl start nginx # 启动Nginx成功后,能够直接访问主机IP,此时会展现Nginx默认页面 # 中止Nginx systemctl stop nginx # 重启Nginx systemctl restart nginx # 从新加载Nginx systemctl reload nginx # 查看 Nginx 运行状态 systemctl status nginx # 查看Nginx进程 ps -ef | grep nginx # 杀死Nginx进程 kill -9 pid # 根据上面查看到的Nginx进程号,杀死Nginx进程,-9 表示强制结束进程
nginx -s reload # 向主进程发送信号,从新加载配置文件,热重启 nginx -s reopen # 重启 Nginxnginx -s stop # 快速关闭 nginx -s quit # 等待工做进程处理完成后关闭 nginx -T # 查看当前 Nginx 最终的配置 nginx -t # 检查配置是否有问题
Nginx 的典型配置示例:程序员
# main段配置信息 user nginx; # 运行用户,默认便是nginx,能够不进行设置 worker_processes auto; # Nginx 进程数,通常设置为和 CPU 核数同样 error_log /var/log/nginx/error.log warn; # Nginx 的错误日志存放目录 pid /var/run/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 /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段配置信息 server { listen 80; # 配置监听的端口 server_name localhost; # 配置的域名 # location段配置信息 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; # 同上 } }
用一张图清晰的展现它的层级结构:web
指定运行 Nginx 的 woker 子进程的属主和属组,其中组能够不指定。
user USERNAME [GROUP] user nginx lion; # 用户是nginx;组是lion
指定运行 Nginx master 主进程的 pid 文件存放路径。
pid /opt/nginx/logs/nginx.pid # master主进程的的pid存放在nginx.pid的文件
指定 worker 子进程能够打开的最大文件句柄数。
worker_rlimit_nofile 20480; # 能够理解成每一个worker子进程的最大链接数量。
指定 worker 子进程异常终止后的 core 文件,用于记录分析问题。
worker_rlimit_core 50M; # 存放大小限制working_directory /opt/nginx/tmp; # 存放目录
指定 Nginx 启动的 worker 子进程数量。
worker_processes 4; # 指定具体子进程数量 worker_processes auto; # 与当前cpu物理核心数一致
将每一个 worker 子进程与咱们的 cpu 物理核心绑定。
worker_cpu_affinity 0001 0010 0100 1000; # 4个物理核心,4个worker子进程
将每一个 worker 子进程与特定 CPU 物理核心绑定,优点在于,避免同一个 worker 子进程在不一样的 CPU 核心上切换,缓存失效,下降性能。但其并不能真正的避免进程切换。
指定 worker 子进程的 nice 值,以调整运行 Nginx 的优先级,一般设定为负值,以优先调用 Nginx 。
worker_priority -10; # 120-10=110,110就是最终的优先级
Linux 默认进程的优先级值是120,值越小越优先;nice 定范围为 -20 到 +19
[备注] 应用的默认优先级值是120加上 nice 值等于它最终的值,这个值越小,优先级越高。
指定 worker 子进程优雅退出时的超时时间。
worker_shutdown_timeout 5s;timer_resolution
worker 子进程内部使用的计时器精度,调整时间间隔越大,系统调用越少,有利于性能提高;反之,系统调用越多,性能降低。
在 Linux 系统中,用户须要获取计时器时须要向操做系统内核发送请求,有请求就必然会有开销,所以这个间隔越大开销就越小。
指定 Nginx 的运行方式,前台仍是后台,前台用于调试,后台用于生产。
daemon off; # 默认是on,后台运行模式
Nginx 使用何种事件驱动模型。
use method; # 不推荐配置它,让nginx本身选择method 可选值为:select、poll、kqueue、epoll、/dev/poll、eventport
worker 子进程可以处理的最大并发链接数。
worker_connections 1024 # 每一个子进程的最大链接数为1024
是否打开负载均衡互斥锁。
accept_mutex on # 默认是off关闭的,这里推荐打开
指定虚拟主机域名。
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\.*$ ; 匹配优先级:精确匹配 > 左侧通配符匹配 > 右侧通配符匹配 > 正则表达式匹配
一、配置本地 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 解析,若是使用阿里云上购买的域名,则须要在阿里云上设置好域名解析。
二、配置阿里云 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; } }
三、访问分析
当访问 www.nginx-test.com 时,均可以被匹配上,所以选择优先级最高的“彻底匹配”; 当访问 mail.nginx-test.com 时,会进行“左匹配”; 当访问 www.nginx-test.org 时,会进行“右匹配”; 当访问 doc.nginx-test.com 时,会进行“左匹配”; 当访问 www.nginx-test.cn 时,会进行“右匹配”; 当访问 fe.nginx-test.club 时,会进行“正则匹配”;
指定静态资源目录位置,它能够写在 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 则只取定义路径。
它也是指定静态资源目录位置,它只能写在 location 中。
location /image { alias /opt/nginx/static/image/; }
当用户访问 www.test.com/image/1.png 时,实际在服务器找的路径是 /opt/nginx/static/image/1.png
[注意] 使用 alias 末尾必定要添加 / ,而且它只能位于 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/ { ... }
中止处理请求,直接返回响应码或重定向到其余 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 ; # 返回重定向地址 }
根据指定正则表达式匹配规则,重写 URL 。
语法:rewrite 正则表达式 要替换的内容 [flag];上下文:server、location、if
示例:rewirte /images/(._.jpg)1; # $1是前面括号(._.jpg)的反向引用
flag 可选值的含义:
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 { } }
按照这个配置咱们来分析:
语法: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 命令。
用户请求以 / 结尾时,列出目录结构,能够用于快速搭建静态资源下载网站。
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/ 路径下的文件展现出来,以下图所示:
Nginx 提供给使用者的变量很是多,可是终究是一个完整的请求过程所产生数据, Nginx 将这些数据以变量的形式提供给使用者。
下面列举些项目中经常使用的变量:
remote_addr #客户端 IP 地址 remote_port #客户端端口 server_addr #服务端 IP 地址 server_port #服务端端口 server_protocol #服务端协议 binary_remote_addr #二进制格式的客户端 IP 地址 connection #TCP 链接的序号,递增 connection_request #TCP 链接当前的请求数量 uri #请求的URL,不包含参数 request_uri #请求的URL,包含参数 scheme #协议名, http 或 https request_method #请求方法 request_length #所有请求的长度,包含请求行、请求头、请求体 args #所有参数字符串 arg_参数名 #获取特定参数值 is_args #URL 中是否有参数,有的话返回 ? ,不然返回空 query_string #与 args 相同 host #请求信息中的 Host ,若是请求中没有 Host 行,则在请求头中找,最后使用 nginx 中设置的 server_name 。 http_user_agent #用户浏览器 http_referer #从哪些连接过来的请求 http_via #每通过一层代理服务器,都会添加相应的信息 http_cookie #获取用户 cookie request_time #处理请求已消耗的时间 https #是否开启了 https ,是则返回 on ,不然返回空 request_filename #磁盘文件系统待访问文件的完整路径 document_root #由 URI 和 root/alias 规则生成的文件夹路径 limit_rate #返回响应时的速度上限值
实例演示 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:808... 时,因为 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 的配置还有很是多,以上只是罗列了一些经常使用的配置,在实际项目中仍是要学会查阅文档。
代理是在服务器和客户端之间假设的一层服务器,代理将接收客户端的请求并将它转发给服务器,而后将服务端的响应转发给客户端。
无论是正向代理仍是反向代理,实现的都是上面的功能。
正向代理,意思是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),而后代理向原始服务器转交请求并将得到的内容返回给客户端。
正向代理是为咱们服务的,即为客户端服务的,客户端能够根据正向代理访问到它自己没法访问到的服务器资源。
正向代理对咱们是透明的,对服务端是非透明的,即服务端并不知道本身收到的是来自代理的访问仍是来自真实客户端的访问。
反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的链接请求,而后将请求转发给内部网络上的服务器,并将从服务器上获得的结果返回给internet上请求链接的客户端,此时代理服务器对外就表现为一个反向代理服务器。反向代理是为服务端服务的,反向代理能够帮助服务器接收来自客户端的请求,帮助服务器作请求转发,负载均衡等。
反向代理对服务端是透明的,对咱们是非透明的,即咱们并不知道本身访问的是代理服务器,而服务器知道反向代理在为他服务。
反向代理的优点:
那么“动静分离”是什么?负载均衡又是什么?
动静分离是指在 web 服务器架构中,将静态页面与动态页面或者静态内容接口和动态内容接口分开不一样系统访问的架构设计方法,进而提示整个服务的访问性和可维护性。
通常来讲,都须要将动态资源和静态资源分开,因为 Nginx 的高并发和静态资源缓存等特性,常常将静态资源部署在 Nginx 上。若是请求的是静态资源,直接到静态资源目录获取资源,若是是动态资源的请求,则利用反向代理的原理,把请求转发给对应后台应用去处理,从而实现动静分离。
使用先后端分离后,能够很大程度提高静态资源的访问速度,即便动态服务不可用,静态资源的访问也不会受到影响。
通常状况下,客户端发送多个请求到服务器,服务器处理请求,其中一部分可能要操做一些资源好比数据库、静态资源等,服务器处理完毕后,再将结果返回给客户端。
这种模式对于早期的系统来讲,功能要求不复杂,且并发请求相对较少的状况下还能胜任,成本也低。随着信息数量不断增加,访问量和数据量飞速增加,以及系统业务复杂度持续增长,这种作法已没法知足要求,并发量特别大时,服务器容易崩。
很明显这是因为服务器性能的瓶颈形成的问题,除了堆机器以外,最重要的作法就是负载均衡。
请求爆发式增加的状况下,单个机器性能再强劲也没法知足要求了,这个时候集群的概念产生了,单个服务器解决不了的问题,可使用多个服务器,而后将请求分发到各个服务器上,将负载分发到不一样的服务器,这就是负载均衡,核心是「分摊压力」。Nginx 实现负载均衡,通常来讲指的是将请求转发给服务器集群。
举个具体的例子,晚高峰乘坐地铁的时候,入站口常常会有地铁工做人员大喇叭“请走 B 口, B 口人少车空....”,这个工做人员的做用就是负载均衡。
在配置反向代理和负载均衡等等功能以前,有两个核心模块是咱们必需要掌握的,这两个模块应该说是 Nginx 应用配置中的核心,它们分别是:upstream 、proxy_pass 。
用于定义上游服务器(指的就是后台提供的应用服务器)的相关信息。
语法:upstream name { ...} 上下文:http
示例:
upstream back_end_server{ server 192.168.100.33:8081 }
在 upstream 内可以使用的指令:
定义上游服务器地址。
语法:server address [parameters]上下文:upstream
parameters 可选值:
限制每一个 worker 子进程与上游服务器空闲长链接的最大数量。
keepalive connections; 上下文:upstream
示例:[keepalive](http://mp.weixin.qq.com/s?__b...
485067&idx=1&sn=d5585b021802dfa47fb9cd8e01ddfb1d&chksm=e91b639
7de6cea81179917290cde1ff505291cee65f08d78f6a48fee90425db7e19b025fa683&scene=21#wechat_redirect) 16;
单个长链接能够处理的最多 HTTP 请求个数。
语法:keepalive_requests number; 默认值:keepalive_requests 100; 上下文:upstream
空闲长链接的最长保持时间。
语法:keepalive_timeout time; 默认值:keepalive_timeout 60s; 上下文:upstream
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;}
用于配置代理服务器。
语法: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 用法:
这两种用法的区别就是带 / 和不带 / ,在配置代理时它们的区别可大了:
不带 / 的用法:
location /bbs/{ proxy_pass http://127.0.0.1:8080;}
分析:
带 / 的用法:
location /bbs/{ proxy_pass http://127.0.0.1:8080/;}
分析:
这里为了演示更加接近实际,做者准备了两台云服务器,它们的公网 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
分析:
配置负载均衡主要是要使用 upstream 指令。
咱们把 121.42.11.34 服务器做为上游服务器,作以下配置( /etc/nginx/conf.d/balance.conf ):
server{ listen 8020; location / { return 200 'return 8020 \nserver{ 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'; } }
配置完成后:
把 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/hosts121.5.180.193 balance.lion.club
在客户端机器执行 curl http://balance.lion.club/bala... 命令:
不难看出,负载均衡的配置已经生效了,每次给咱们分发的上游服务器都不同。就是经过简单的轮询策略进行上游服务器分发。
接下来,咱们再来了解下 Nginx 的其它分发策略。
经过制定关键字做为 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 保持不变,就会一直分发给同一台服务器。
根据客户端的请求 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; } }
各个 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_nme balance.lion.club; location /balance/ { proxy_pass http://demo_server; } }
最后你会发现,负载均衡的配置其实一点都不复杂。
缓存能够很是有效的提高性能,所以不管是客户端(浏览器),仍是代理服务器( Nginx ),乃至上游服务器都多少会涉及到缓存。可见缓存在每一个环节都是很是重要的。下面让咱们来学习 Nginx 中如何设置缓存策略。
存储一些以前被访问过、并且可能将要被再次访问的资源,使用户能够直接从代理服务器得到,从而减小上游服务器的压力,加快整个访问速度。
语法:proxy_cache zone | off ; # zone 是共享内存的名称默认值:proxy_cache off;上下文:http、server、location
设置缓存文件的存放路径。
语法:proxy_cache_path path [level=levels] ...可选参数省略,下面会详细列举默认值:proxy_cache_path off上下文:http
参数含义:
设置缓存文件的 key 。
语法:proxy_cache_key 默认值:proxy_cache_key $scheme$proxy_host$request_uri; 上下文:http、server、location
配置什么状态码能够被缓存,以及缓存时长。
语法:proxy_cache_valid [code...] time; 上下文:http、server、location
配置
proxy_cache_valid 200 304 2m;; # 说明对于状态为200和304的缓存文件的缓存时间是2分钟
定义相应保存到缓存的条件,若是字符串参数的至少一个值不为空且不等于“ 0”,则将不保存该响应到缓存。
语法:proxy_no_cache string; 上下文:http、server、location 示例: proxy_no_cache $http_pragma $http_authorization;
定义条件,在该条件下将不会从缓存中获取响应。
语法:proxy_cache_bypass string; 上下文:http、server、location
示例:
proxy_cache_bypass $http_pragma $http_authorization;
它存储了缓存是否命中的信息,会设置在响应头信息中,在调试中很是有用。
MISS: 未命中缓存HIT: 命中缓存EXPIRED: 缓存过时STALE: 命中了陈旧缓存REVALIDDATED: Nginx验证陈旧缓存依然有效UPDATING: 内容陈旧,但正在更新BYPASS: X响应从原始服务器获取
咱们把 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; # 代理转发 } }
在学习如何配置 HTTPS 以前,咱们先来简单回顾下 HTTPS 的工做流程是怎么样的?它是如何进行加密保证安全的?
下载证书的压缩文件,里面有个 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 版的网站了。
先简单回顾下跨域到底是怎么回事。
同源策略限制了从同一个源加载的文档或脚本如何与来自另外一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。一般不容许不一样源间的读操做。
若是两个页面的协议,端口(若是有指定)和域名都相同,则两个页面具备相同的源。
下面给出了与 URL http://store.company.com/dir/... 的源进行对比的示例:
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 不一样源,主机不一样
不一样源会有以下限制:
例如:
如今咱们只须要启动一个 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 对服务端转发的请求不会触发浏览器的同源策略。
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; # 默认 off,nginx作为反向代理时启用,用于设置启用或禁用从代理服务器上收到相应内容 gzip 压缩; gzip_proxied any; # 用于在响应消息头中添加 Vary:Accept-Encoding,使代理服务器根据请求头中的 Accept-Encoding 识别是否启用 gzip 压缩; gzip_vary on; # gzip 压缩比,压缩级别是 1-9,1 压缩级别最低,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 的架构。
多进程结构 Nginx 的进程模型图:
多进程中的 Nginx 进程架构以下图所示,会有一个父进程( Master Process ),它会有不少子进程( Child Processes )。
reload 重载配置文件的流程:
Nginx 的内部结构是由核心部分和一系列的功能模块所组成。这样划分是为了使得每一个模块的功能相对简单,便于开发,同时也便于对系统进行功能扩展。Nginx 的模块是互相独立的,低耦合高内聚。
相信经过本文的学习,你应该会对 Nginx 有一个更加全面的认识。
都看到这里了,点在看、留言、转发朋友圈走一波吧!!
来源: https://juejin.cn/post/694260...