Nginx介绍
定义:一个非常 轻量级的HTTP服务器, 是一个高性能的HTTP和反向代理服务器!
特性:
高性能,稳定性,丰富的功能,简单的配置和低资源消耗。
原理
Nginx有一个主线程和几个工作线程。
主线程是加载和验证配置文件、维护工作线程。
工作线程处理实际的请求,Nginx 采用基于事件的模型和依赖操作系统的机制在工作线程之间高效地分发请求。工作线程的数量可配置,也可自动调整为服务器CPU的数量。
Nginx及其模块的工作方式由配置文件确定!
Nginx实质
Nginx配置的核心是定义要处理的URL以及如何响应这些URL请求,定义一系列的虚拟服务器(Virutal Servers) 控制来自特定域名或者IP的请求处理!!
换句话说:
Nginx 配置为 Web 服务器就是定义处理哪些 URLS 和如何处理这些URLS 对应的请求。具体来说,就是定义一些虚拟服务器(Virtual Servers),控制具有特定 IP 和域名的请求。
虚拟服务器
1)虚拟服务器定义一系列的location控制处理特定的URI集合。
2) 每一个location定义了对映射到自己的请求的处理场景,可以返回一个文件或代理此请求。
Nginx模块
Nginx 由不同的模块组成,这些模块由配置文件中指定的指令控制。
简单指令和块指令
简单指令一个简单指令包含指令名称和指令参数,以空格分隔,以分号结尾。
块指令:块指令与简单指令类似,但是由大括号({和})包围。 如果块指令大括号中包含其他指令,则称该指令为上下文(如: events, http, server 和 location)
指令一般有以下这些:
listen: 配置块使用 listen 命令监听本机 IP 和端口号
server_name: 用于区分,当多个server的IP和端口号一样时, Niginx通过请求头中的Host区分!!!!
location: 定义了对映射到自己的请求的处理场景。
当Nginx选定了一个server(虚拟服务器)之后,就会根据URIs去选择合适的location来决定代理请求或返回文件。
location支持前缀或正则。
location必须是在一个server里面。
作用一 处理静态内容
http块中创建server块指令,再设置location块指令:
server{
location/{
root /data/www;
}
location /images/ {
root /data;
}
}
上面的location块指定/前缀与请求中的URI对比。 匹配的请求将会被添加到root指令中指定的路径,这就是本地文件系统的路径!!
比如上面:
http://localhost/
匹配
/data/www/
Nginx采用最长前缀匹配原则
也就是说,如果URI匹配多个location,Nginx采用最长前缀匹配原则。
即上面的
location /images/ {
}
location / {
}
URI如果是/image/这样的请求,优先匹配/image/ location。 / location不会被使用
配置代理服务器
server{
location / {
proxy_pass http://localhost:8080/;
}
location ~\.(git|jpg|png){
root /data/images;
}
}
这个服务器将会过滤以gif jpg png结尾的请求,并映射到/data/image目录。并将其他请求发给上面配置的代理服务器。
原理
Nginx选择一个location块处理请求,它首先检查指定location块的前缀,记住具有最长前缀的location块,然后检查正则表达式。 如果匹配,Nginx就选择这个location块~
listen指令
listen指令监听本机IP和端口号, 支持IPv4 IPv6
server {
listen 127.0.0.1:8080; // IPv4地址,8080端口
# listen [2001:3CA1:10F:1A:121B:0:0:10]:80; //IPv6地址,80端口
# listen [::]:80; // 听本机的所有IPv4与IPv6地址,80端口
# The rest of server configuration
}
proxy_pass指令
参数为:协议+主机名+端口号。
server_name
这个非常重要,server_name的参数是:
1.完整主机名
2. 含有通通配符 如*.xxx.com
3. 正则,~开头
通配符只能在开头或结尾。
server_name的匹配规则:
- 完整主机名,如 api.lufficc.com
- 最长的,且以开头的通配名,如.luffic.com
- 最长的且以结尾的通配名,如:api.
- 第一个匹配的正则表达式
server {
listen 80;
server_name api.lufficc.com *.lufficc.com;
...
}
如果 Host 头部不匹配任何一个 server_name ,Nginx 将请求路由到默认虚拟服务器。默认虚拟服务器是指:nginx.conf 文件中第一个 server 或者 显式用 default_server 声明
server {
listen 80 default_server;
...
}
使用变量
你可以使用变量来使 Nginx 在不同的请求下采用不同的处理方式。变量是在运行时计算的,用作指令的参数。 变量由 $ 开头的符号表示。 变量基于 Nginx 的状态定义信息,例如当前处理的请求的属性。
使用预定义的变量
有很多预定义变量,例如核心的 HTTP 变量,你也可以使用 set,map 和 geo 指令定义自定义变量。 大多数变量在运行时计算,并包含与特定请求相关的信息。 例如, remoteaddr包含客户端IP地址, uri 保存当前URI值。
例如:
server{
...
return 301 https://lufficc.com$request_uri;
...
}
返回特定状态码
return CODE URL/Response Text
可选的第二个参数可以是重定向的URL 或在响应正文中返回的文本
location /wrong/url {
return 404;
}
处理错误
error_page 命令可以配置特定错误码的错误页面,或者重定向到其他的页面。下面的示例将在 404 错误发生时返回 /404.html 页面。
error_page 404 /404.html;
也可以让Nginx自动替换错误的请求,301通知浏览器页面已永久移除,需自动替换为返回的新地址。
location /old/path.html {
error_page 404 =301 http:/example.com/new/path.html;
}
重写URIs
rewrite指令可以多次修改请求的URI。
可以把URI
rewrite用法
第一个参数是URI需要匹配的正则,
第二个是要替换的URI。
第三个指示是否继续可以重写或返回重定向代码(301或302)
location /user/ {
rewrite ^/user/(.*)$ /show?user=$1 break;
}
一般是在server和location上下文中使用。 Nginx按照它们发生的顺序一个一个执行。
当处理完一组rewrite指令之后,它根据新的URI选择location。 如果所选location仍然包含rewrite执行,他们还是会被执行,然后又根据新的URI搜索新的location。。
server {
...
rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 last;
rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra last;
return 403;
...
}
诸如 /download/some/media/file 的 URI 被改为 /download/some/mp3/file.mp3
last标志:后续指令被跳过。 但是继续以更改后的URI指令处理请求。 应用location中的任何rewrite指令(这意味着URI又可能改变)
break标志: 停止当前上下文中,rewrite指令的处理,取消搜索与新URI匹配的location。不会执行新location中的rewrite指令
配置反向代理实际例子
http {
# CORS
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers X-Requested-With;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
server{
server_name api.linzhida.cc;
location / {
proxy_pass http://api.linzhida.cc:3000;
}
}
server{
server_name spw.linzhida.cc;
location / {
proxy_pass http://spw.linzhida.cc:8090;
}
}
server{
listen 80;
server_name www.linzhida.cc;
location / {
proxy_redirect off;
proxy_pass http://www.linzhida.cc:8090;
}
# location ~ \.(html|js|css|png|gif|jpg)$ {
# root /usr/local/tomcat8/webapps/balight/file/*;
# }
}
}
定义了三个虚拟服务器,Nginx会根据请求的URI选择其中一个。 后台设置了三个服务器,一个Nginx服务器用于转发请求,包括一个Node服务器和一个Tomcat服务器。
监听80请求,转发
http://www.linzhida.cc:8090
监听api.linzhida.cc请求
http://api.linzhida.cc:3000
监听spw.linzhida.cc请求 转发到 http://spw.linzhida.cc:8090
tomcat服务器配置了3个connector
127.0.0.1:8005
:8005
:8090
重点 server_name VS location
server_name 决定了请求进来的域名是什么,也就是根据你的host来匹配到各个虚拟服务器上。(一般一个server就有一个server_name)
而location是决定了域名后面的部分,也就是”/”后面的部分的匹配规则!
也就是URL中的path部分!
如 http://wxw.linzhida.cc/aka.html
server_name决定的是前面 wxw.linzhida.cc这一部分!
然后location则是决定aka.html这一部分!