一、什么是nginx
Nginx(engine x)是一个具有高性能的HTTP和反向代理的web服务器,同时也是一个POP3/SMTP/IMAP代理服务器。
C语言编写的。
1.2、常用功能模块
静态资源部署
Rewrite地址重写
反向代理
负载均衡
web缓存
1.3、Nginx的核心组成
nginx二进制可执行文件
nginx.conf配置文件
error.log 错误日志
access.log访问日志记录
二、配置文件nginx.conf
2.1、nginx.conf 配置文件中默认有三大块:全局块、events块、http块
http块中可以配置多个server块,每个server块又可以配置多个location块
2.2、全局块
(1)user指令
用于配置运行nginx服务器的worker进程的用户和用户组,默认值是nobody
403 forbidden  是因为nginx运行用户对访问目录没有访问权限
(2)work process指令
master_process:用来指定是否开启worker进程
语法:master_process on | off ,默认值是on
worker_processes:用于配置nginx生成工作进程的数量
语法:worker_processes 3 , 默认值是1
(3)daemon:设定nginx是否以守护进程的方式启动,默认是on
pid:用来配置nginx当前master进程进程的pid文件路径
默认为/usr/local/nginx/logs/nginx.pid
(4)error_log:用来配置nginx错误日志路径
语法:errorlog file [日志级别]
eg:
error_log logs/error.log error
位置:全局块、http块、server块、location
(5)include:用来引入其他配置文件,使nginx配置更加灵活
位置:任何位置都可以
2.3、events块
(1)accept_mutex:用来配置nginx网络连接序列化
(2)multi_accept:用来设置是否允许同时接受多个网络连接
(3)worker_connections:用来配置单个worker进程最大连接数,默认值512
(4)use:用来设置nginx服务器选择哪种事件驱动来处理网络消息
eg:
events {
	acept_mutex on;
	multi_accept on;
	worker_connections 1024;
	use epoll;
}
2.4、http块
(1)定义MIME-Type
在nginx的配置文件中,默认有两行配置
include mime.types;  # 引入mime.types文件中的内容
default_type application/octet-stream;
default_type:用来配置nginx响应前端请求默认的MIME类型
默认值text/plain ,
位置:http块、server块、location块
(2)keepalived_timeout:用来设置长链接的超时时间
(3)keepalived_requests:用来设置一个keep-alive连接使用的次数。
三、Nginx静态资源部署
html页面、css、js、图片、视频等资源
(1)静态资源的配置命令
listen指令:用来配置监听端口
语法:
listen ip[:port] [deafult_server]...;
listen port [default_server]...;
默认值:listen *:80 | *:8000
位置:server块
eg:
listen 127.0.0.1:8000;  # 监听指定的ip和端口
listen 127.0.0.1;   # 监听指定ip的所有端口
listen 8000;    # 监听指定端口上的连接
listen *:8000   # 监听指定端口上的连接
default_server 的属性是标识符,用来将将此虚拟主机设置成默认主机,如果没有匹配到对应的ip:port,则会默认执行的。
如果不指定,默认使用的是第一个server
server_name指令:用来设置虚拟主机的服务名称(即域名)
语法:
server_name name...; # name可以写多个值,中间用空格分割
默认值:server_name "";
位置:server块
关于server_name 的配置方式有三种,分别是:
精确匹配
eg:
server {
	listen 80;
	server_name localhost www.itcast.com;  # 
}
通配符匹配
正则表达式匹配
注意:listen指令和server_name指令是相辅相成的,listen指令用于配置ip和port,server_name 用于配置域名
如果使用了域名,则必须配置server_name
location指令:用来设置请求的url
语法:location [空 | = | ~ | ~* | ^~ | @] /uri/   # location后面可跟六种属性,默认是空
默认值是空
位置:server块
uri变量是带匹配的请求字符串,可以不包含正则表达式也可以包含正则表达式,nginx服务器在搜索匹配的location的时候
,是先使用不包含正则表达式进行匹配,找到一个匹配度最高的那一个,然后在通过正则表达式进行匹配,如果能匹配到直接访问,
来处理请求。匹配不到,就是用刚才匹配度最高的那个location来处理请求。
属性介绍:
不带符号,要求必须以指定模式开始
server {
	listen 80;
	srver_name localhost;
	location /abc { # 不带符号,则可以访问以/abc开头的地址,比如 http://localhost:80/abc  http://localhost:80/abc/del 等
		default_type text/plain;
		return 200 "access success";
	}
}
=:用于不包含正则表达式的uri前面,表示精确匹配,如果找到,立即停止搜索并立即处理此请求。
server {
	listen 80;
	srver_name localhost;
	location =/abc { # 不带符号,则只能访问/abc的地址,比如 http://localhost:80/abc  不能访问http://localhost:80/abc/  http://localhost:80/abc/del 等
		default_type text/plain;
		return 200 "access success";
	}
}
~:用于表示当前uri中包含了正则表达式,并且区分大小写
~*:用于表示当前uri中包含了正则表达式,并且不区分大小写
换句话说,如果uri包含了正则表达式,需要用上述两个符合来标识
^~:即表示只匹配普通字符(跟空格类似,但是它优先级比空格高)。使用前缀匹配,^表示“非”,
即不查询正则表达式。如果匹配成功,并且所匹配的字符串是最长的, 则不再匹配其他location。
@:用于定义一个 Location块,且该块不能被外部Client 所访问,只能被Nginx内部配置指令所访问,
比如try_files 或 error_page
匹配顺序:
	1、优先查找精确匹配,精确匹配 (=) 的 location 如果匹配请求 URI 的话,此 location 被马上使用,匹配过程结束。
	2、接下来进行字符串匹配(空格 和 ~^), 找到匹配最长的那个,如果发现匹配最长的那个是 ^~ 前缀, 那么也停止搜索并且马上使用,匹配过程结束。 否则继续往下走。
	3、如果字符串匹配没有,或者匹配的最长字符串不是 ^~ 前缀 (比如是空格匹配),那么就继续搜索正则表达式匹配, 这时候就根据在配置文件定义的顺序,取最上面的配置(正则匹配跟匹配长度没关系,只跟位置有关系,只取顺序最上面的匹配)
	4、如果第三步找到了,那么就用第三步的匹配,否则就用第二步的匹配 (字符匹配最长的空格匹配)
换成符号的优先级就是:[=] > [^~] > [~/~*] > [空格]
这边注意几个细节:
1、常规字符串匹配类型。是按前缀匹配(从根开始)。 而正则匹配是包含匹配,只要包含就可以匹配
2、~ 和 ~* 的优先级一样,取决于在配置文件中的位置,最上面的为主,跟匹配的字符串长度没关系,所以在写的时候,应该越精准的要放在越前面才对
3、空格匹配和 ^~ 都是字符串匹配,所以如果两个后面的匹配字符串一样,是会报错的,因为 nginx 会认为两者的匹配规则一致,所以会有冲突
4、^~, =, ~, ~* 这些修饰符和后面的 URI 字符串中间可以不使用空格隔开(大部分都是用空格隔开)。但是 @ 修饰符必须和 URI 字符串直接连接。
eg1:
location / {
  return 200 '404';
}
location ~ /hello {
  return 200 '1';
}
location ^~ /hello {
  return 200 '2';
}
location = /hello {
  return 200 '3';
}
location ~* /hello {
  return 200 '4';
}
[root@VM_156_200_centos ~]# curl 127.0.0.1/hello  #精确匹配,直接结束
3
[root@VM_156_200_centos ~]# curl 127.0.0.1/hello11 #字符串匹配,并且最大长度的匹配是 ~^,直接结束
2
[root@VM_156_200_centos ~]# curl 127.0.0.1/hello/22 #字符串匹配,并且最大长度的匹配是 ~^,直接结束
2
[root@VM_156_200_centos ~]# curl 127.0.0.1/11/hello/ #字符串不匹配(前缀匹配),正则匹配有两个,取最上面的那个
1
[root@VM_156_200_centos ~]# curl 127.0.0.1/11/Hello/ #字符串不匹配(前缀匹配),正则匹配有一个(大小写不敏感),取最上面的那个
4
[root@VM_156_200_centos ~]# curl 127.0.0.1/11/Hell #都不匹配,有设置通用匹配,取通用匹配
404
例子 2
location /images/test.png {
  return 200  '1';     
}        
location ^~ /images/ { 
  return 200  '2';      
}    
location ~ /images/ {        
  return 200  '3';   
} 
location ~ /images/test.png {        
  return 200  '4';   
}
[root@VM_156_200_centos ~]#  curl http://127.0.0.1/images/test.png 
3
[root@VM_156_200_centos ~]#  curl http://127.0.0.1/images/1 
2
第一个返回 3 是因为本例是 普通匹配和正则匹配都存在, 并且因为 ^~ 匹配不是最长的话,那么就取 正则匹配, 正则匹配满足条件的有两个, 取最上面那个, 所以是 3, (本例的字符串最长匹配是空格匹配)。(对于本例来说,如果去掉后面的两个正则匹配,那么返回的就是 1, 因为空格匹配的字符串是最长的)
第二个返回 2 是因为普通匹配和正则匹配都存在,但是这个^~ 匹配是最长的,所以就是 2。
root alias 指令:设置请求资源的真实路径
root:设置请求的根目录
语法:root path;
默认值:root html;
位置:http块、server块、location块
path为nginx服务器接收到的请求以后查找资源的根目录路径
alias:设置请求资源的真实路径
语法:alias path;
默认值:空
位置:location块
path为修改后的根路径
root 和 alias的区别是什么?看下面例子
location /i/ {
	root /data/w3;
}
请求 http://foofish.net/i/top.gif 这个地址时,那么在服务器里面对应的真正的资源是 /data/w3/i/top.gif文件
请求 http://foofish.net/i/j/top.gif 这个地址时,那么在服务器里面对应的真正的资源是 /data/w3/i/j/top.gif文件
而 alias 正如其名,alias指定的路径是location的别名,不管location的值怎么写,
资源的 真实路径都是 alias 指定的路径 ,比如:
location /i/ {
	alias /data/w3/;
}
同样请求 http://foofish.net/i/top.gif 时,在服务器查找的资源路径是: /data/w3/top.gif
请求 http://foofish.net/i/j/top.gif 这个地址时,那么在服务器里面对应的真正的资源是 /data/w3/top.gif文件
其他区别:
    1、alias 只能作用在location中,而root可以存在server、http和location中。
    2、alias 后面必须要用 "/" 结束,否则会找不到文件,而 root 则对 ”/” 可有可无。
index 指令:设置网站的默认首页页面
语法:index file ...;
默认值:index index.html;
位置:http块、server块、location块
index后面可以跟多个设置,如果访问的时候没有指定具体的访问的资源,则会一次进行查找,找到第一个为止。
error_page指令:设置网站的错误页面
语法:
error_page code ...[=[response]] uri;
默认值 "";
位置:http块、server块、location块
code是指后端返回的错误码
当出现错误后,如何来处理,有三种方式:
(1)可以指定具体跳转的地址
server {
	error_page 404 http://www.itcast.cn;
}
(2)可以指定重定向地址
server {
	error_page 404 500 503 /50x.html;
	location =/50x.html {
		root html;
	}
}
(3)使用location的@符号完成错误信息展示
server {
	error_page 404 @jump_to_error;
	location @jump_to_error {
		default_type text/plain;
		return 404 'not found page';
	}
}
@符号是自定义一个跳转的变量,然后下面用location 指定这个变量是跳转到哪个页面的。
(2)静态资源的配置优化
这里从三个属性进行优化配置:
sendfile on;         # 用来开启高效的文件传输模式,默认关闭
tcp_nopush on;		 # 该指令必须在sendfile打开的状态下才生效,主要是用来提升网络包的传输效率。
tcp_nodeplay on;     # 该指令必须在keep-alive 连接开启的情况下才生效,主要是用来提高网络包传输的实时性。
上述三个指定的位置可以在http块、server块、location块
(3)静态资源的压缩配置指令
(4)静态资源的缓存处理
浏览器缓存相关指令
(1)expires指令:该指令控制http应答中的"Expires"和"Cache-Control"
语法:expires [modified] time<br/>
	  expires epoch|max|off;
	  
(2)add_header指令:用来添加指定的响应头和响应值
(5)静态资源的访问控制,包括跨域问题和防盗链问题
1、什么情况下会出现跨域?
同源策略:浏览器的同源策略是一种约定,是浏览器最核心也是最基本的安全功能。
同源:协议、域名(ip)、端口都相同即为同源。
例如前后端分离项目如果部署在不同的服务器上,那ip不同,肯定会跨域,
如果部署在相同的服务器上的不同web服务器里,那端口号就会不同,也会跨域。
2、实例演示跨域问题
3、具体解决方案
四、rewrite功能配置
rewrite主要是实现URL的重写,要使用该功能,在编译安装nginx之前,要安装PCRE库。
nginx使用的是ngx_http_rewrite_module模块来解析和处理rewrite功能的相关配置。
rewrite的相关命令:
set指令
if指令
break指令
return指令
rewrite指令
rewrite_log指令
Rewrite的应用场景
1、域名跳转
2、域名镜像
3、独立域名
4、目录自动添加"/"
5、合并目录
6、防盗链的实现
五、nginx反向代理
nginx反向代理模块的指令是由ngx_http_proxy_module进行解析,该模块在安装nginx的时候已经自己加装到nginx中了,
接下来介绍下反向代理中常用指令:
(1)proxy_pass
该指令被用来设置被代理服务器地址,可以是主机名称、ip地址加端口号形式
语法:
proxy_pass URL;
默认值 "";
位置:location块
URL:为要设置的被代理服务器地址,包含传输协议(http://,https://),主机名称或ip地址加端口号
、URI等要素
eg:
proxy_pass http://wwww.baidu.com;
proxy_pass http://192.168.200.146:80/;
注意:在编写proxy_pass 的时候,例如proxy_pass http://192.168.200.146:80/;
 ,最后面的"/"要不要加?
 如果是location 后面跟的是 / ,加不加都一样,如下:
server {
	location / {
		proxy_pass http://192.168.200.146:80;
	}
}
如果是location 后面跟的除了 "/" 还有别的,则必须要加,如下:
server {
	location /server {
		proxy_pass http://192.168.200.146:80;
	}
}
访问的地址会是:http://192.168.200.146:80/server/index.html
server {
	location /server {
		proxy_pass http://192.168.200.146:80/;
	}
}
访问的地址会是:http://192.168.200.146:80/index.html
(2)proxy_set_header
该指令可以更改nginx服务器接收到的客户端请求头的信息,然后将新的请求头发送给代理服务器
语法:
proxy_set_hander field value;  # field 属性名, value属性值
默认值:
proxy_set_header Host $proxy_host<br/>
proxy_set_header Connection close;
位置:http块、server块、location块
需要注意的是,如果想要看到结果,必须在被代理的服务器删
来获取添加的头信息。
(3)proxy_redirect
该指令是用来重置头信息中的"Location"和"Refresh"的值
语法:
proxy_redirect redirect replacement;
proxy_redirect default;
proxy_redirect off;
默认值:proxy_redirect default;
位置:http块、server块、location块