1 Nginx 安装

1.1 安装

  1. 下载 Nginx 包,然后解压
  2. 配置安装路径
    不配置默认安装在 /usr/local/nginx ./configure
    也可以指定安装目录,加上参数 --prefix=/usr/local/nginx
  3. 编译:make
  4. 安装:make install

1.2 Nginx 目录介绍

安装完成后,进入安装目录:cd /usr/local/nginx/

nginx 主要的目录就下面四个,其他 temp 目录都是启动以后产生的

在这里插入图片描述

  • conf : 配置文件目录,主配置文件 nginx.conf 就在里面。
    在这里插入图片描述

  • html: 存放 nginx 自带的两个静态的 html 页面

    • 50x.html:访问失败后的失败页面
    • index.html:成功访问的默认首页
  • logs : 记录入门的文件,当 nginx 服务器启动后,这里面会有 access.log error.lognginx.pid 三个文件出现。

  • sbin : 是存放执行程序文件 nginx 。nginx 是用来控制 Nginx 的启动和停止等相关的命令。

1.3 Nginx 常用命令

进入安装好的目录 /usr/local/nginx/sbin

./nginx # 启动
./nginx -s stop # 快速停止
./nginx -s quit # 优雅关闭,在退出前完成已经接受的连接请求
./nginx -s reload # 重新加载配置

启动 Nginx 后,查看是否启动成功

在这里插入图片描述

可以看到 nginx 已启动成功,且是多进程的,master 进程负责协调 worker 进程,worker 进程是实际负责处理请求的

Nginx 基础.png

1.4 进入到一台服务器后如何寻找 Nginx 的安装位置

whereis nginx

Nginx 基础-2.png

ps -ef|grep nginx

Nginx 基础-3.png

2 ⭐️ Nginx 核心概念

2.1 ⭐️ 最小配置文件

nginx.conf 去掉注释后的最小配置文件

worker_processes  1; # 启动的worker进程数,建议与CPU核心数保持一致,(双核4线程,可以设置为4)
 
events {
    worker_connections  1024; # 单个工作进程(worker)可以允许同时建立外部连接的数量
}
 
http {
    include       mime.types; # 引入mime.types配置,mime.types是服务器返回给浏览器的类型,告诉浏览器以哪种格式展示
    default_type  application/octet-stream; # 默认的返回类型
 
    sendfile        on; # 开启零拷贝
	keepalive_timeout  65;  # 用来设置长连接的超时时间
 
#虚拟主机 vhost
    server {
        listen       80; # 监听的端口号
        server_name  localhost; # 域名、主机名
		# url:http://ayguigu.com/order/queryOne
		# uri:域名之后的东西
		# location匹配的就是uri,一个主机下可以配置多个location且互不影响
        location / {
            root   html; # 匹配到该location后从哪个目录来找网页。html是相对路径,相对于nginx的主目录,相当于/usr/local/nginx/html
            index  index.html index.htm;  # 如果没有默认页,访问到这个目录下如果有这两个文件就展示出来
        }
       # 当访问url出现500 502 503 504错误时,重定向到/50x.html,即是http://ayguigu.com/50x.html
        error_page   500 502 503 504  /50x.html;
        location = /50x.html { # 当访问/50x.html时,就到相对路径html下找,即是html下的50x.html
            root   html;
        }
    }
}

2.2 ⭐️ 虚拟主机

虚拟主机,就是把一台物理服务器划分成多个虚拟的服务器,这样我们的一台物理服务器就可以当做多个服务器来使用,从而可以配置多个网站。Nginx 提供虚拟主机的功能,就是为了让我们不需要安装多个 Nginx,就可以运行多个域名不同的网站。

Nginx 下,一个 server 标签就是一个虚拟主机。nginx 的虚拟主机就是通过 nginx.conf 中 server 节点指定的,想要设置多个虚拟主机,配置多个 server 节点即可。

如果一个公司有多个二级域名,没有必要为每个二级域名都提供一台 Nginx 服务器,就可以使用虚拟主机技术,在一台 Nginx 服务器上,模拟多个虚拟服务器。

配置虚拟主机方式
1)基于端口的虚拟主机
使用端口来区分。浏览器使用同一个域名 + 端口或同一个 ip 地址 + 端口访问;

2)基于域名的虚拟主机
使用域名来区分。端口可以相同,但是域名+端口不能相同。

实操:
修改本地的 hosts 文件,文件位置:C:\Windows\System32\drivers\etc\hosts 将云服务器 ip 和 nginxtest.com 域名、nginxstudy.com 域名绑定。进入 home 目录下,分别创建 hello 和 world 文件夹,在其下分别创建 index.html。

2.2.1 端口区分:

server {
	listen       80;
	server_name  nginxtest.com;
 
	location / {
		root   /home/hello;
		index  index.html index.htm;
	}
}
server {
	listen       81;
	server_name  nginxtest.com;
 
	location / {
		root   /home/world;
		index  index.html index.htm;
	}
}

./nginx -s reload 重新加载 nginx 配置

浏览器访问 http://nginxtest.com/ ,显示 /home/hello/index.html 中的内容。不带端口的默认就是 80 端口。
浏览器访问 http://nginxtest.com:81/ ,显示 /home/world/index.html 中的内容。

2.2.2 域名区分:

server {
	listen       80;
	server_name  nginxtest.com;
 
	location / {
		root   /home/hello;
		index  index.html index.htm;
	}
}
server {
	listen       80;
	server_name  nginxstudy.com;
 
	location / {
		root   /home/world;
		index  index.html index.htm;
	}
}

./nginx -s reload 重新加载 nginx 配置

浏览器访问 http://nginxtest.com/,显示 /home/hello/index.html 中的内容。
浏览器访问 http://nginxstudy.com/ ,显示 /home/world/index.html 中的内容。

2.3 ⭐️ 域名解析

2.3.1 域名解析过程

域名解析过程,略。

广域网负载均衡(GSLB)
广域网负载均衡:大厂自己研发的 DNS 服务器。最终实现:一个域名对应多个 ip,网站在全国各地部署,用户就近访问。

授权 DNS 服务器
授权 DNS 服务器:是一级一级授权的,根是由国际组织(注册局)去管理的,由它去管控所有的一级域名服务器的申请,将一级域名的管理授权给了全球各地的注册商,中国授权给了万网。注册商将下面的二级、三级、四级域名的解析授权给各个企业,这样企业就可以自建 DNS 域名服务器了,然后加入到全球的网络。
注册局–>注册商–>企业自建 DNS 服务器层层授权,所以叫授权 DNS 服务器

DNS 劫持
本地 DNS 大多数为运营商 DNS 服务器,处在整个 DNS 解析的交互的中心,这里容易发生劫持。如你访问 www.qq.com ,却返回了其他访问的 ip 地址。

httpDNS
游览器会向你部署 httpDNS 服务器发送 HTTP 请求(直接访问 httpDNS 的 IP),HTTP 服务器返回域名解析结果,然后浏览器缓存起来。相当于绕过了本地 DNS,直接去请求 httpDNS,所以就不存在 DNS 劫持了。
httpDNS 适合 app、或 CS 架构的服务,通过预埋 ip 地址,直接将域名解析发到 httpDNS 所在服务器。

Short URL
短网址,Short URL、短 URL,是指短网址服务器为某个链接生成的中间链接。短链接并不是绝对的就比原链接短。短网址可以减少字节数,同时还可以隐藏真实网站地址。短网址机制根本上是通过“短网址服务器+302 重定向实现”。本质就只是将短网址还原为原网址,可以将短网址与原网址建立一个映射。所以点击短网址必须是去访问短域名服务器而不是原 URL 的服务器。

泛域名解析
域名泛解析最大的用途是可以让主域名支持无限的子域名扩展。
泛域名解析:*.域名 解析到同一 IP。
域名解析:子域名.域名 解析到同一 IP。

2.3.2 server_name 匹配规则

server_name 匹配分先后顺序,写在前面的匹配上就不会继续往下匹配了。

完整匹配 —— 我们可以在同一 servername 中匹配多个域名

server_name vod.mmban.com www1.mmban.com;

通配符匹配

server_name *.mmban.com

通配符结束匹配

server_name vod.*;

正则匹配

server_name ~^[0-9]+\.mmban\.com$;

2.4 ⭐️ 反向代理

2.4.1 区分正向代理与反向代理

在这里插入图片描述 在这里插入图片描述
正向代理 —— 用户和外网不能互通,通过代理服务器将用户请求发送给外网

在这里插入图片描述

反向代理

用户和 nginx 是互通的,用户和应用服务器是不互通的,用户发送请求到 nginx,nginx 作为代理将请求发送给应用服务器(如 tomcat 等),tomcat 接受 nginx 的请求处理好后将结果发送给 nginx,nginx 将结果发送给用户。
如下图,是隧道式代理(瓶颈在于 nginx 代理服务器,即使应用服务器的带宽很大,但是如果代理服务器的带宽很小,那么请求都会阻塞到代理服务器)

在这里插入图片描述

反向代理和正向代理的区别是代理服务器的提供方不同,对于反向代理,nginx 是由服务提供方提供的,对于正向代理,代理服务器是由用户自己提供的。

2.4.2 如何解决隧道式代理的问题呢?

DR 模型

用户发送请求到代理服务器,代理服务器正常将请求发送给应用服务器,在应用服务器处理完请求后直接将结果发送给用户,不经过代理服务器。LVS 负载均衡器既可以使用 DR 模型,也可以使用隧道式代理模型。

2.4.3 反向代理实际配置

proxy_pass http://baidu.com ;

配置了 proxy_pass 以后,就可以注释掉 roothtml,然后访问 nginxtest.com,就会被反向代理到 http://www.baidu.com/

server {
        listen       80;
        server_name  nginxtest.com;
        location / {
             proxy_pass http://www.baidu.com/;
    #        root   /home/hello;
     #       index  index.html index.htm;
        }
    }

如果 nginx 作为反向代理使用,那么必须要搞明白的就是 proxy_pass 的规则,这关系到请求能否打到正确的接口。
proxy_pass 规则:

  • 如果 proxy_pass 后面没有路径,那么转发时带上 uri
  • 如果 proxy_pass 后面有路径,那么转发时使用该路径替换匹配到的 uri

2.5 ⭐️ 负载均衡

2.5.1 基本概念

如果一个服务由多台服务器提供,需要把负载分配到不同的服务器处理,需要负载均衡。负载均衡配置一般都需要同时配置反向代理,通过反向代理跳转到负载均衡。

upstream tomcat2 {
	server 192.168.25.148:8081;
	server 192.168.25.148:8082;
}

默认方式 —— 轮询。

可以根据服务器的实际情况调整服务器权重。权重越高分配的请求越多,权重越低,请求越少。默认是都是 1。

负载均衡策略

  • 轮询:默认情况下使用轮询方式,逐一转发,这种方式适用于无状态请求。
  • weight(权重):指定轮询几率,weight 和访问比率成正比,用于后端服务器性能不均的情况。
    upstream httpd
      {
    	server 127.0.0.1:8050 weight=10 down;
    	server 127.0.0.1:8060 weight=1;
    	server 127.0.0.1:8060 weight=1 backup;
    }
    # down:表示当前的 server 暂时不参与负载
    # weight:默认为 1.weight 越大,负载的权重就越大。
    # backup: 其它所有的非 backup 机器 down 或者忙的时候,请求 backup 机器。
    
  • ip_hash:根据客户端的 ip 地址转发同一台服务器,可以保持会话。但是如果是动态 ip,其实也不能保持会话。
  • least_conn:最少连接访问(可能造成流量倾斜)
  • url_hash:根据用户访问的 url 定向转发请求(第三方插件)
  • fair:根据后端服务器响应时间转发请求(可能造成流量倾斜)(第三方插件)

2.5.2 负载均衡的配置

因为只有一台服务器,所以使用虚拟主机来做负载均衡,采用端口区分的方式。

1)轮询

upstream httpProxy {
	server 10.0.4.23:81;
	server 10.0.4.23:82;
}
server {
	listen       80;
	server_name  nginxtest.com;
	location / {
		 proxy_pass http://httpProxy;
		# root   /home/hello;
		# index  index.html index.htm;
	}
 
	error_page 500 502 503 504  /50x.html;
	location = /50x.html {
		root   html;
	}
 
}
server {
	listen       81;
	server_name  nginxstudy.com;
	location / {
		 proxy_pass http://www.qq.com/;
		 root   /home/world;
		 index  index.html index.htm;
	}
 
	error_page 500 502 503 504  /50x.html;
	location = /50x.html {
		root   html;
	}
 
}
server {
	listen       82;
	server_name  nginxlearn.com;
	location / {
		 proxy_pass http://www.baidu.com/;
		 root   /home/leihou;
		 index  index.html index.htm;
	}
 
	error_page 500 502 503 504  /50x.html;
	location = /50x.html {
		root   html;
	}
 
}

测试:在浏览器输入 nginxtest.com,被反向代理到 http://httpProxy ,因为 upstreamhttpProxy 做了负载均衡,所以会被代理到 10.0.4.238182 端口。而 8182 端口又被 server 监听了,所以会反向代理到 http://www.qq.com/http://www.baidu.com/ ,最终结果就是浏览器轮询访问 qq 和百度,反向代理负载均衡虚拟主机配置成功!!!

注释掉 81 和 82 中的反向代理 proxy_pass 配置,在浏览器访问 nginxtest.com,地址栏不变,会轮询访问 /home/world/home/leihou 下面的 index.html

2)权重

upstream httpProxy {
	server 10.0.4.23:81  weight=5;
	server 10.0.4.23:82  weight=1;
  }

81 和 82 以近似 5 比 1 的比例访问。

2.6 ⭐️ 动静分离

动静分离:严格意义是将动态请求和静态请求分离。

一种是将静态文件拆分出来,放置在独立域名下的服务器(主流方案)。另一种是混合在一起,使用 nginx 区分。通过 location 指定不同的后缀名实现不同的请求转发。

配置反向代理

location / {
	proxy_pass http://10.0.4.23:8080;
	root html;
	index index.html index.htm;
}

增加每一个 location

location /css {
	root /usr/local/nginx/static;
	index index.html index.htm;
}
location /images {
	root /usr/local/nginx/static;
	index index.html index.htm;
}
location /js {
	root /usr/local/nginx/static;
	index index.html index.htm;
}

使用一个 location

location = /uri 精确匹配
location ^~ /uri 前缀匹配,在正则匹配之前
location ~ pattern 正则匹配,区分大小写
location ~* pattern 正则匹配,不区分大小写
location /uri 前缀匹配,在正则匹配之后
location / 通用匹配,未匹配到其它 location 的请求会匹配到它

location 匹配顺序

多个正则 location 直接按书写顺序匹配,成功后就不会继续往后面匹配
普通(非正则)location 会一直往下,直到找到匹配度最高的(最大前缀匹配)
当普通 location 与正则 location 同时存在,如果正则匹配成功,则不会再执行普通匹配
所有类型 location 存在时,“=”匹配 > “^~”匹配 > 正则匹配 > 普通(最大前缀匹配)

location ~*/(css|img|js)
{
	root /usr/local/nginx/static;
	index index.html index.htm;
}

location 配置实例

upstream webserver_v1 {
	server 10.1.75.62;
 
}
upstream webserver_v2 {
	server 10.1.75.63;
}
 
location / {
   proxy_ignore_client_abort on;
   proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
   proxy_set_header    X-Real-IP $remote_addr;
   proxy_set_header    Host $http_host;	# 把请求的主机域名传到后端
   proxy_set_header X-Http-scheme $scheme;
 
 	set $group webserver_v1 ; # 默认为生产环境
   if ($http_cookie ~* "environment=gray") {
		set $group webserver_v2; # 有Cookie去灰度环境
   }
   proxy_pass http://$group;
   proxy_connect_timeout 300s;
   proxy_read_timeout 3000s;
   proxy_send_timeout 3000s;
   break;
}

alias 与 root

location /css
{
	alias /usr/local/nginx/static/css;
	index index.html index.htm;
}

root 用来设置根目录,而 alias 在接受请求的时候在路径上不会加上 location。

1)alias 指定的目录是准确的,即 location 匹配访问的 path 目录下的文件直接是在 alias 目录下查找的;
2)root 指定的目录是 location 匹配访问的 path 目录的上一级目录,这个 path 目录一定要是真实存在 root 指定目录下的;
3)使用 alias 标签的目录块中不能使用 rewrite 的 break(具体原因不明);另外,alias 指定的目录后面必须要加上”/“符号!!
4)alias 虚拟目录配置中,location 匹配的 path 目录如果后面不带”/“,那么访问的 url 地址中这个 path 目录后面加不加”/“不影响访问,访问时它会自动加上”/“;但是如果 location 匹配的 path 目录后面加上”/“,那么访问的 url 地址中这个 path 目录必须要加上”/“,访问时它不会自动加上”/“。如果不加上”/“,访问就会失败!
5)root 目录配置中,location 匹配的 path 目录后面带不带”/“,都不会影响访问。

动静分离实操

将静态文件存放到 nginx 服务器上,目录为/home/static,分别上传 1.jpg 和 2.jpg
在 server 监听 80 端口下配置如下内容。

location /images {
	# alias /home/static;
	root /home/static;
	index index.html index.htm;
}

alias 就是直接访问 static 下面的内容,root 就是访问/static/images 下的内容

测试:
浏览器访问: http://nginxtest.com/images/1.jpg ,其实访问的是 /home/static/images 下的 1.jpg,图片正常显示。

2.7 ⭐️ UrlRewrite

rewrite 语法格式及参数语法:

rewrite 是实现 URL 重写的关键指令,根据 regex (正则表达式)部分内容,重定向到 replacement,结尾是 flag 标记。

rewrite <regex> <replacement> [flag];
关键字   正则   替代内容   flag标记


关键字:其中关键字 error_log 不能改变
正则:perl 兼容正则表达式语句进行规则匹配
替代内容:将正则匹配的内容替换成 replacement
flag 标记:rewrite 支持的 flag 标记

rewrite 参数的标签段位置: server,location,if

flag 标记说明:

  • last 本条规则匹配完成后,继续向下匹配新的 location URI 规则
  • break # 本条规则匹配完成即终止,不再匹配后面的任何规则
  • redirect # 返回 302 临时重定向,浏览器地址会显示跳转后的 URL 地址
  • permanent # 返回 301 永久重定向,浏览器地址栏会显示跳转后的 URL 地址

redirect 和 permanent 对用户来说,感觉是一样的。

实例 1

rewrite ^/([0-9]+).html$ /index.jsp?pageNum=$1 break;

网关配置

upstream httpds
{
	server 192.168.44.102 weight=8 down;
	server 192.168.44.103:8080 weight=2;
	server 192.168.44.104:8080 weight=1 backup;
}
location /  {
	rewrite ^/([0-9]+).html$ /index.jsp?pageNum=$1 redirect;
	proxy_pass http://httpds ;
}

实例 2

rewrite ^/(.*) http://www.baidu.com/$1 permanent;
  • rewrite 是固定关键字,表示开始进行 rewrite 匹配规则。
  • regex 是 ^/(.*),这是一个正则表达式,匹配完整的域名和后面的路径地址。
  • replacement 是 http://www.baidu.com/$1 ,其中 $1 是取 regex 部分 () 里面的内容,如果匹配成功后跳转到的 URL
  • flag 是 permanent,代表永久重定向的含义,即跳转到 http://www.baidu.com/$1

Nginx 直接返回假的响应

location /test/study/queryIso2List{
	default_type application/json;
	return 200 '{"streamNo": "123456789","code": "00000000","msg": "success","data": {    "iso2List": [ "CN", "JP"]}}';
}

2.8 防盗链配置

valid_referers none | blocked | server_names | strings …;

  • none,检测 Referer 头域不存在的情况。
  • blocked,检测 Referer 头域的值被防火墙或者代理服务器删除或伪装的情况。这种情况该头域的值不以“http://” 或 “https://” 开头。
  • server_names ,设置一个或多个 URL ,检测 Referer 头域的值是否是这些 URL 中的某一个。

在需要防盗链的 location 中配置

valid_referers 192.168.44.101;   # 允许的 ip
if ($invalid_referer)            # 如果不被允许
{
	return 403;
}                  # 返回错误码 403

使用 curl 测试 -I 参数则只显示 http response 的头信息。

curl -I http://10.0.4.23/images/1.jpg

带引用 -e 带引用

curl -e http://baidu.com -I http://10.0.4.23/images/1.jpg

实操配置

返回错误码:

valid_referers 10.0.4.23;
if ($invalid_referer) {
	return 403;
}

返回错误页面:
error_page 不能少,否则匹配不上。在 html 下 cp 50x.html 401.html,修改内容

valid_referers 10.0.4.23;
if ($invalid_referer){
	return 401;
}
 
error_page   401  /401.html;
location = /401.html {
	root   html;
}

返回图片:
首先确保 rewrite 后地址可以正常访问

valid_referers 10.0.4.23;
if ($invalid_referer) {
	rewrite ^/ http://nginxtest.com/image/1.gif break;
}