简介
Nginx是一款轻量级的Web(HTTP)服务器,采用事件驱动的异步非阻塞处理方式框架,常用于服务端的反向代理和负载均衡,内存占用少,启动极快,高并发能力强,c语言开发的。
- 正向代理
位于客户端和原始服务器之间,客户端向代理服务器发送请求,然后代理服务器将请求转发给原始服务器,并将原始服务器的响应返回给客户端。对于原始服务器来说,请求似乎来自于代理服务器,而不是真实的客户端。
常见于局域网内部,用于代表客户端访问互联网。可以用于访问受限制的内容、提高访问速度(缓存)以及隐藏客户端的真实IP地址等
- 反向代理
位于原始服务器和客户端之间,客户端向代理服务器发送请求,然后代理服务器根据负载均衡、缓存、安全过滤等策略将请求转发给一个或多个后端服务器,并将后端服务器的响应返回给客户端。对应客户端来说,响应似乎来自于代理服务器,而不是真实的后端服务器。
常见于服务器端,用于提供负载均衡、安全过滤、SSL终结、缓存、静态内容服务等。通过反向代理可以隐藏后端服务器的真实IP地址和架构,提供更好的安全性和性能。
web服务器
负责处理和响应用户请求,一般成为http服务器,如Apache、Nginx
应用服务器
存放和运行系统程序的服务器,负责处理程序中的业务逻辑,如Tomcat等(现在大多数应用服务器也包含了web服务器的功能)
安装
- Ubuntu
sudo apt update
sudo apt install nginx
# 查看当前可用的版本
sudo apt-cache show nginx
# 指定版本
sudo apt install nginx=1.18.0-6ubuntu14.4
# 验证
nginx -v
curl http://127.0.0.1
# 查看服务状态
systemctl status nginx
# 停止服务、启动服务、重启服务
sudo systemctl stop nginx
sudo systemctl start nginx
sudo systemctl restart nginx
sudo pkill -9 nginx
# 卸载、删除目录、删除依赖项
sudo apt purge nginx
sudo rm -rf /var/log/nginx /var/www/html /etc/nginx
sudo apt autoremove
Master-Worker模式
- Master进程作用
读取并验证配置文件nginx.conf,管理worker进程。
- Worker进程作用
每个Worker进程维护一个线程,处理连接和请求。Worker进程个数由配置文件决定,与CPU核心数相关。
- Nginx热部署原理
修改配置文件nginx.conf后,重新生成新的worker进程,以新的配置进行处理请求,新请求都交给新的worker进程,老worker进程处理完以前的请求后被kill掉。
- Nginx高并发下的高效处理
Nginx采用LInux的epoll模型,基于事件驱动机制,可以监控多个事件是否准备完毕,如果完毕则放入epoll队列,这个过程异步。worker只需从epoll队列循环处理。
- Nginx实现高可用
Keepalived+Nginx实现高可用。Keepalived是一个高可用解决方案,防止服务器单点发生故障,和Nginx配合来使用。
- 请求先通过Keepalived(虚拟IP)再去Nginx
- Keepalived可以监控Nginx生命状态(通过脚本检查Nginx进程状态,进行权重变化,实现故障切换)
nginx文件存放目录
路径 | 描述 |
---|---|
/var/log/nginx/error.log | Nginx运行日志的目录 |
/var/www/html | web项目目录,默认根目录 |
/usr/sbin/nginx | 服务文件 |
/etc/nginx/nginx.conf | 配置文件目录 |
默认配置文件介绍
- server{}是包含在http{}内部,每个server{}是一个主机站点
- 当一个localhost:8080请求Nginx服务器时,请求匹配到下面server{}块中执行
- location可以进行正则匹配
# 当Nginx接到请求后,会匹配配置中的service模块
# 匹配方法是将请求携带的host和port跟配置中的server_name和listen相匹配
server {
listen 8080;
server_name localhost;
location / {
root html; # Nginx默认值(静态资源)
index index.html index.htm; # 从根目录下找index.html,没有则找index.htm
}
}
应用
动静分离
- Nginx服务器将收到的请求分为动态请求和静态请求。(提高速度)
- 静态请求直接从Nginx服务器设置的根目录路径获取资源,动态请求则转发给后台。
server {
listen 8080;
server_name localhost;
location / {
root html; # Nginx默认值
index index.html index.htm; # 从根目录下找index.html,没有则找index.htm
}
# 静态化配置,所有静态请求都转发给nginx处理,存放目录为my-project
location ~ .*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|js|css)$ {
root /usr/local/var/www/my-project;
}
# 动态请求匹配到path为'node'的就转发到8002端口处理
location /node/ {
proxy_pass http://localhost:8002; # 充当服务代理
}
}
反向代理【proxy_pass】
请求的IP地址是Nginx地址而非真实的request地址
- 保障应用服务器的安全,增加一层代理,屏蔽危险攻击
- 实现负载均衡
- 实现跨域(最简单的跨域)
server {
listen 8080;
server_name localhost;
location / {
root html; # Nginx默认值
index index.html index.htm;
}
proxy_pass http://localhost:8000; # 反向代理配置,请求转发到8000端口
}
- 应用场景:CDN(内容分发网络)
负载均衡【upstream】
nginx将接收到的请求,根据设置好的权重,分配到服务器集群。除此还有检查服务异常状态,异常则不会将请求分发到该服务器上。
注意:用户状态保存问题(Session回话信息不能保存到服务器上)
- 分摊服务器集群压力
- 保证客户端访问稳定性
# 负载均衡:设置domain
upstream domain{
server localhost:8000 weight=1; # 轮询权重默认为1
server localhost:8001 weight=2; # 设置轮询权重为2
}
server {
listen 8080;
server_name localhost;
location / {
# root html;
#
proxy_pass http://domain; # 负载均衡配置,请求会分配到8000和8001端口
proxy_set_header Host $host:$server_port;
}
}
Nginx进行IP访问控制
实际应用
# 全局快
user xxx; # 配置用户或者组 指定Nginx进程运行用户,一般指定非root用户,提高安全性。
worker_processes auto; # 指定Nginx worker进程数为自动根据CPU核来确定
pid /run/nginx.pid; # 指定Nginx主进程PID文件路径,用于记录主进程的进程ID
include /etc/nginx/modules-enabled/*.conf; # 包含其他配置文件,加载额外的模块配置文件
# error_log log/error.log debug; # 指定日志路径,级别。
# events块
events { # Nginx事件模块的配置,包括worker进程与客户端连接处理相关参数
# accept_mutex on; # 设置网路连接序列化,防止惊群现象(一个网路连接到来,多个睡眠的进程被同时叫醒,只有一个进程能获得链接,会影响系统性能),默认为on
# use epoll; # 事件驱动模型,select|poll|kqueue等
worker_connections 768; # 每个worker进程可以同时处理的最大连接数
# multi_accept on; # 允许每个worker进程同时接受多个新连接,提高连接接受效率
}
# HTTP块 可以嵌套多个server
http { # HTTP服务的相关配置(请求处理、反向代理、负载均衡、缓存、日志等)
# HTTP全局块
include mime.types; # 文件扩展名与文件类型映射表
default_type application/octet-stream; # 默认文件类型,默认为test/plain
# access_log off; # 取消服务日志
log_format myFormat '$remote_addr-$remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for'; #自定义格式
access_log log/access.log myFormat; # combined为日志格式的默认值
sendfile on; # 允许sendfile方式传输文件,默认为off,可以在http块,server块,location块
sendfile_max_chunk 100k; # 每个进程每次调用传输数量不能大于设定的值,默认为0,即不设上限
keepalive_timeout 65; # 连接超时时间,默认为75s,可以在http,server,location块
tcp_nopush on; # on:发送相应尽可能发送完整数据包,而非分成小块,提高传输效率和性能
tcp_nodelay on; # on:禁用Nagle算法,减少延迟,增加网络流量
types_hash_max_size 2048; # 使用这个哈希表查找文件的MIME类型,增大该值,提高查找性能
# server_tokens off; # 是否在响应头中包含版本信息
# server_names_hash_bucket_size 64; # 使用这个哈希表存储服务器名称和配置信息
# server_name_in_redirect off; # 控制重定向响应头中是否包含服务器名称
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # 指定Nginx支持的SS/TLS协议版本
ssl_prefer_server_ciphers on; # 控制是否优先使用服务器端的加密套件
gzip on;
# gzip_vary on; # 设置是否在响应头中包含Vary:Accept-Encodeing 缓存分片
# gzip_proxied any; # 控制哪些响应将被压缩
# gzip_comp_level 6; # 设置gzip压缩级别,级别越高,压缩率越高,CPU资源消耗越高
# gzip_buffers 16 8k; # 设置gzip压缩缓存区大小
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+ress text/javascript;
upstream mysvr {
server 172.0.0.1:7878 max_fails=2 fail_timeout=20s; # max_fails允许请求失败次数,超过最大次数返回proxy_next_upstream定义的错误。经历了max_fails失败,暂停服务的时间。
server 192.168.1.1:3333 backup; # 热备:7878挂了使用3333
ip_hash; # 让相同客户端ip请求相同服务器
}
error_page 404 https://www.baidu.com; # 错误页
# server块
server {
# server全局块
keepalive_requests 120; # 单连接请求上限次数
listen 4545; # 监听端口
server_name 127.0.0.1; # 监听地址
#location块
location ~*^.+${ # 请求url过滤,正则匹配,~区分大小写,~*不区分大小写
# root path; # 根目录
# index vv.txt; # 设置默认页
proxy_pass http://mysvr; # 请求转向mysvr 定义的服务器列表
deny 127.0.0.1; # 拒绝的ip
allow 172.18.5.54; # 允许的ip
proxy_connect_timeout 1; # nginx服务器预被代理的服务器建立连接的超时时间,默认60秒
proxy_read_timeout 1; # nginx服务器向被代理服务器组发出read请求,等待响应超时时间,默认60秒
proxy_send_timeout 1; # nginx服务器向被代理服务器组发出write请求,等待响应超时时间,默认60秒
proxy_ignore_client_abort on; # 客户端取消请求时,nginx服务器是否继续对被代理服务器的请求,默认off
proxy_intercept_errors on; # 被代理服务器返回状态码为400或者大于400,设置的exxor_page起作用,默认off
proxy_next_upstream timeout; # 设置反向代理服务器组出现故障,被代理服务器返回的状态(可选:error|http_500等)
client_body_buffer_size 4096m; # 设置解释客户端请求体的缓冲区大小。用来接收比如POST请求体数据
client_max_body_size 4096m; # 限制客户端请求体的最大大小。超过返回413 Request Entity Too Large
proxy_max_temp_file_size 4096m; # 设置响应暂存的临时文件大小
}
# HTTP全局块
}