Nginx是什么
Nginx(engine x)是一款的Web服务器、反向代理服务器,能够实现前端Web应用的部署、请求反向代理及负载均衡处理等功能。
特点
- 轻量,占用内存少
- 高可靠
- 高并发、高性能
- 可扩展性好
- 支持热部署
- BSD许可证(开源、可修改再发布)
反向代理(Reverse Proxy)
- 客户端请求某个网络资源。
- 这个请求会发送到反向代理服务器。
- 反向代理服务器根据某种策略选择一个后端服务处理这个请求,并将处理结果返回给客户端。
正向代理(Forward Proxy)
- 用户首先连接到正向代理服务器。
- 正向代理服务器再根据用户的请求内容和配置的代理地址请求相应服务器上的资源。
- 服务器的资源返回给正向代理服务器,然后再返回给用户。
在正向代理中,用户知道他们正在使用代理,并且知道代理到哪里;而在反向代理中,用户将请求的服务器理解为一个整体,并不能知道后边的请求是怎样流转的。
工作过程
- 启动:Nginx启动后会生成一个主进程(
master process
)和多个工作进程(worker process
)。主进程并不处理网络请求,主要负责监控和管理工作进程。而工作进程则是实际处理网络请求的地方。 - 接受连接:主进程在指定的端口上监听传入的连接请求。当有新的连接请求到达时,主进程接受连接并将其分配给一个可用的子进程。
- 读取请求:接下来,Nginx会读取并解析这个HTTP请求。包括URI、参数、头部信息等等。
- 请求处理:根据配置文件中设置的规则(例如 server 块)将请求路由到相应的处理逻辑。比如静态文件直接返回,动态内容则可能需要转发给后端服务器处理。
- 输出响应:最后,将处理结果返回给客户端。如果此前有启用缓存,并且当前响应可以被缓存,则还会保存一份在本地。
- 关闭连接:完成响应之后关闭当前连接或者保持长链接等待下次使用。
- 日志记录:根据规则记录请求和响应的详细日志,以便于故障排除和分析。
版本介绍
Nginx
:2004年发布第一个版本v0.1.0,目前已更新至v1.25.2。Tengine
:由阿里推出,在Nginx基础上添加了很多功能和特性,并且已经在淘宝,天猫等各大应用得到应用,相对较稳定。但是并不能跟着Nginx官方版本同步升级。openresty
:支持lua脚本嵌入,可操作性更高。
绿色为Nginx共有模块,橙色为Tengine模块,紫色为OpenResty模块
安装&使用
-
MAC使用Homebrew安装
-
安装Homebrew(如已安装,请跳过)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" brew -v # 查看Homebrew版本 brew update # 更新Homebrew
-
安装nginx
brew install nginx
-
查看版本&启动nginx
nginx -v #查看版本 nginx #启动nginx
-
nginx脚本及配置文件地址
配置文件目录
/opt/homebrew/etc/nginx
脚本位置/opt/homebrew/bin/nginx
-
启动后在浏览器输入
http://localhost:8080
,看到如下画面,说明安装启动成功
-
-
Linux使用编译方式安装
-
环境安装
- 安装gcc环境(编译环境)
yum -y install gcc gcc-c++ autoconf automake make
- 安装pcre(nginx重写功能)
yum -y install pcre pcre-devel
- 安装zlib(nginx 使用 zlib 对 http 包内容进行 gzip 压缩)
yum -y install zlib zlib-devel make libtool
- 安装openssl(用于nginx使用https)
yum -y install openssl openssl-devel
- 安装gcc环境(编译环境)
-
nginx下载&编译
- 从官网下载nginx,建议下载最新的stable版本
wget https://nginx.org/download/nginx-1.24.0.tar.gz
- 解压
tar -zxvf nginx-1.24.0.tar.gz
- 编译
cd nginx-1.24.0 # 编译目录 ./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --user=nginx --group=nginx make #编译 make install #安装
参数说明:
–prefix=/usr/local/nginx
#编译安装目录
–user=nginx
#所属用户nginx
–group=nginx
#所属组nginx
–with-http_stub_status_module
#该模块提供nginx的基本状态信息
–with-http_ssl_module
#支持HTTPS
- 从官网下载nginx,建议下载最新的stable版本
-
nginx脚本及配置文件位置
跟编译目录阶段配置的-prefix有关
配置文件目录/usr/local/nginx/conf
脚本位置/usr/local/nginx/sbin/nginx
-
启动nginx
/usr/local/nginx/sbin/nginx
启动后在浏览器输入
http://localhost:8080
,看到欢迎页面,说明安装启动成功
-
-
Nginx常用命令
nginx # 启动nginx nginx -t # 检测nginx配置是否有误 nginx -s reload # 重载nginx nginx -s quit # 从容停止 nginx -s stop # 强制停止 nginx -v # 查看版本 nginx -V # 查看nginx详细信息,包括安装位置,已安装的模块
配置介绍
nginx 总配置文件地址:/opt/homebrew/etc/nginx/nginx.conf
(MAC)、/usr/loca/nginx/conf/nginx.conf
(Linux),配置介绍如下:
#daemon on; # 启用或禁用守护进程模式。
#user nobody; # worker进程运行的用户和组,如果没有提供则使用nginx的master进程的用户和用户组。
worker_processes 1; # 定义worker进程数量一般和cpu核数一致,默认为1。
# 制定日志路径,级别。这个设置可以放入全局块,http块,server块,级别枚举:debug|info|notice|warn|error|crit|alert|emerg
#error_log logs/error.log error;
#pid logs/nginx.pid; # 存放nginx守护进程的pid文件路径。
events {
#accept_mutex on; #设置网路连接序列化,防止惊群现象发生,默认为on (惊群现象:一个网路连接到来,多个睡眠的进程被同时叫醒,但只有一个进程能获得链接,这样会影响系统性能。)
#multi_accept on; #设置一个进程是否同时接受多个网络连接,默认为off
worker_connections 1024; # 定义一个worker进程能够同时连接的数量,默认为512.
}
http {
include mime.types; #文件扩展名与文件类型映射表
default_type application/octet-stream; #默认文件类型,默认为text/plain
# 定义log格式
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; # 使用定义好的log_format
sendfile on; #允许sendfile方式传输文件,默认为off,可以在http块,server块,location块使用
#tcp_nopush on; #该指令必须在sendfile打开的状态下才会生效,主要是用来提升网络包的传输'效率'
keepalive_timeout 65; #连接超时时间,默认为75s,可以在http,server,location块使用
#gzip on; #是否开启gzip压缩
server {
listen 8080; #监听的端口
server_name localhost; #监听的域名/ip,有多个server监听同一端口时可以通过server_name控制匹配到哪里,如果都没有匹配,则自动匹配端口的第一个
#charset koi8-r; #字符集设置
#access_log logs/host.access.log main; #为该server设置log
#前端资源路径
location / {
root html; #静态文件路径,一般是前端的dist目录
index index.html index.htm; #index文件匹配
try_files $uri $uri/ =404; #定尝试查找静态文件的顺序。可以使用 try_files 指令来指定查找静态文件的顺序,如果找不到则返回指定的错误码。一般用于history模式
add_header Cache-Control "public, max-age=604800"; #通过add_header添加header,比如进行缓存控制
expires 7d; #缓存过期时间
etag on; #使用etag协商缓存
gzip on; #开启gizp压缩
gzip_types text/plain text/css application/javascript; #使用gzip的文件类型
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# 接口反向代理
location ~^ /api {
proxy_pass http://127.0.0.1;
}
}
#负载均衡
upstream mysvr {
server 127.0.0.1:7878;
server 192.168.10.121:3333 backup; #热备
}
server {
keepalive_requests 120; #单连接请求上限次数。
listen 4545; #监听端口
server_name 127.0.0.1; #监听地址
location ^~ /vue {
alias /Users/chenjialin/Desktop/WorkSpace/test/vue-test/dist/; # 前端静态资源路径
index index.html index.htm;
}
location ~^ /api { #请求的url过滤,正则匹配,~为区分大小写,~*为不区分大小写。
#root path; #根目录
#index vv.txt; #设置默认页
proxy_pass http://mysvr; #请求转向mysvr 定义的服务器列表
deny 127.0.0.1; #拒绝的ip
allow 172.18.5.54; #允许的ip
}
}
# HTTPS server
server {
listen 443 ssl;
server_name localhost;
ssl_certificate cert.pem; # 证书位置
ssl_certificate_key cert.key; # 证书key位置
ssl_protocols TLSv1.2; # SSL 协议版本
ssl_session_timeout 5m;
location / {
root html;
index index.html index.htm;
}
}
# 80端口重定向到443
server {
listen 80;
server_name www.xxx.com;#填写绑定证书的域名
rewrite ^ https://$http_host$request_uri? permanent; # 将http转到https
}
# 引入外部文件
include servers/*;
}
内置变量
- $remote_addr 与 $http_x_forwarded_for 用以记录客户端的ip地址;
- $remote_user :用来记录客户端用户名称;
- $time_local : 用来记录访问时间(服务器的时间);
- $request : 用来记录请求的url与http协议;
- $status : 用来记录请求状态;成功是200;
- $request_body : 客户端请求的body;
- $bytes_sent :记录发送给客户端的字节数;
- $body_bytes_sent :记录发送给客户端body的字节数;
- $content_type :请求头字段;
- $http_referer :用来记录从那个页面链接访问过来的;
- $http_user_agent :记录客户端浏览器的相关信息;
- $pid : 工作进程pid;
匹配规则
模式 | 含义 |
---|---|
location = /uri | = 表示精确匹配,只有完全匹配上才能生效 |
location ^~ /uri | ^~ 开头对URL路径进行前缀匹配,并且在正则之前 |
location ~ pattern | 开头表示区分大小写的正则匹配 |
location ~* pattern | 开头表示不区分大小写的正则匹配 |
location /uri | 不带任何修饰符,也表示前缀匹配,但是在正则匹配之后 |
location / | 通用匹配,任何未匹配到其它location的请求都会匹配到,相当于switch中的default |
匹配优先级:
- 精确匹配 =
- 前缀匹配 ^~,或者不加任何修饰符
- 按文件中顺序的正则匹配
- / 通用匹配
- 当有匹配成功时候,停止匹配,按当前匹配规则处理请求
注意:前缀匹配,如果有包含关系时,按最大匹配原则进行匹配。比如在前缀匹配:
location /a
与location /a/b
,如有请求http://localhost/a/b/file
将最终匹配到location /a/b
扩展
一、root还是alias?
root和alias是nginx中配置资源路径的两种写法,但在使用时要注意他们的区别:
- root与alias主要区别在于nginx如何解释location后面的uri,这会使两者分别以不同的方式将请求映射到服务器文件上。
root的处理结果是:root路径+location路径
alias的处理结果是:使用alias路径替换location路径# root, 如果一个请求的URI是/a/a.html时,web服务器将会返回服务器上的/www/root/html/a/a.html的文件。 location ^~ /a/ { root /www/root/html/; } # alias 如果一个请求的URI是/b/b.html时,web服务器将会返回服务器上的/www/root/html/b.html的文件。注意这里是直接访问html中的文件,因为alias会把location后面配置的路径丢弃掉,把当前匹配到的目录指向到指定的目录。 location ^~ /b/ { alias /www/root/html/; }
- root配置段:http、server、location、if,而alias只能在location中;
- 使用alias时,结尾一定要带 ‘/’,否则会找不到文件,而root后可有可无。
二、负载均衡调度策略及状态控制
- 轮循
upstream balanceUp { server 127.0.0.1:3003; server 127.0.0.1:3004; server 127.0.0.1:3005; }
- 加权
upstream balanceUp2 { server 127.0.0.1:3003 weight=1; server 127.0.0.1:3004 weight=2; server 127.0.0.1:3005 weight=3; }
- IP分配:可通过
ip_hash
关键字进行配置,按照访问IP的hash结果分配,会导致来自同一IP的请求访问固定的一个后台服务器upstream balanceUp3 { server 127.0.0.1:3003; server 127.0.0.1:3004; server 127.0.0.1:3005; ip_hash; }
- URL分配: 通过url_hash关键字进行配置,按照访问URL的hash结果分配资源
- 最少连接数:通过least_conn关键字配置,哪个服务器链接数少就会给分配谁
状态控制
状态 | 概述 |
---|---|
down | 当前的server暂不参与负载均衡 |
backup | 预留的备份服务器,当其他服务器都挂掉的时候,启用 |
max_fails | 允许请求失败的次数 ,如果请求失败次数超过限制,则进过fail_timeout 时间后从虚拟服务池中kill掉该服务器 |
fail_timeout | 经过max_fails失败后,服务暂停时间,max_fails设置后,必须设置fail_timeout 值 |
max_conns | 限制最大的连接数,用于服务器硬件配置不同的情况下 |
upstream balanceUp4 {
server 127.0.0.1:3003 down;
server 127.0.0.1:3004 backup;
server 127.0.0.1:3005 max_fails=1 fail_timeout=10s;
}
三、proxy_set_header和add_header的区别
# 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'
# 告诉服务端用户真实请求的IP
proxy_set_header Host $host;
proxy_set_header X-real-ip $remote_addr; # 存放用户的真实ip
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 每经过一个反向代理,就会把反向代理IP存放在X-Forwarded-For里