Nginx的基本使用
1. 介绍
Nginx主要用于分发网络流量,涉及到的最常用的三个功能分别是反向代理、负载均衡和动静分离
1.1 反向代理
1. 正向代理: 用户端配置代理服务,用户通过代理服务器访问目标网站,服务端不知道用户端的实际地址,代理服务端通常部署SS、SSR、Trojan等协议的流量转发服务,客户端则安装对应的软件进行使用
2. 反向代理: 服务端配置代理服务,服务端通过代理服务器为用户返回结果,用户端不知道服务端的实际地址,Nginx支持在 传输层(TCP/UDP)和应用层(HTTP) 的代理
我的理解是,两者的原理相同,都是通过代理服务器对流量进行转发,关键是代理服务器归谁管控。如果归请求方管控,请求方就可以隐藏自己的真实地址,即正向代理;反之则为反向代理
1.2 负载均衡
负载均衡(Load Balance)将负载(工作任务、访问请求)进行平衡、分摊到多个操作单元(服务器、组件)上进行执行, 是解决高性能、高可用(单点故障)、扩展性(水平伸缩)的终极解决方案
1.2.1 常见负载均衡算法
1. 轮询
每个请求按时间顺序逐一分配到不同的后端服务器, 此外还可以为服务器添加权重来增加其访问量
# 轮询
upstream web {
server x.x.x.x:8080;
server x.x.x.x:8080;
}
# 加权(默认1)
upstream web {
server x.x.x.x:8080 weight=2;
server x.x.x.x:8080;
}
2. IP Hash
按访问IP的hash结果分配,同一个IP客户端固定访问一个后端服务器。可以保证来自同一ip的请求被打到固定的机器上,可以解决session问题
upstream web {
ip_hash;
server x.x.x.x:8080;
server x.x.x.x:8080;
}
3. URL Hash
按访问url的hash结果分配,使每个url定向到同一个后端服务器
upstream web {
hash $request_uri;
server x.x.x.x:8080;
server x.x.x.x:8080;
}
4. Fair
根据后端服务器的响应时间(页面加载时间)来分配请求,响应时间短的优先分配。Nginx本身是不支持 fair的,如果需要使用这种调度算法,必须下载Nginx的upstream_fair
模块
upstream web {
fair;
server x.x.x.x:8080;
server x.x.x.x:8080;
}
1.2.2 Upstream块的其他配置
upstream块支持以下配置, 均是放在server xxx:port
后来使用:
- down:表示当前的server暂时不参与负载均衡
- backup:热备,当其他所有的非backup机器出现故障或者忙的时候,才会请求backup机器
- max_fails:允许请求失败的次数,默认为1。当超过最大次数时,返回proxy_next_upstream 模块定义的错误
- fail_timeout:在经历了max_fails次失败后,暂停服务的时间单位秒
1.3 动静分离
- 静态资源:不依赖于用户的请求动态生成,服务器直接将文件内容发送给客户端,通常由Web服务器(如Nginx、Apache)直接提供
- 动态资源:服务器端根据用户请求或其他数据生成的内容
动静分离就是将静态资源放在静态服务器,动态资源放在动态服务器,让专业的服务器做专业的事(比如Tomcat就不擅长解析静态资源),加快网站解析速度
2. 安装
这里给出docker-compose的内容,直接使用docker.io的镜像并将配置文件映射进去即可
services:
nginx:
container_name: nginx
image: 'nginx:latest'
restart: always
environment:
- TZ=Asia/Shanghai
network_mode: host
volumes:
- /etc/localtime:/etc/localtime:ro
- ./data/nginx/etc/nginx.conf:/etc/nginx/nginx.conf
3. 使用
Nginx的配置文件包括全局块、events块、http块
- 全局块:影响Nginx服务器运行的配置
- events块:影响Nginx服务器与用户连接的配置
- http块:反向代理、负载均衡等配置,又分为http和stream块
- http块:处理http和https流量,具备http功能,但不支持非http流量
- stream块:处理通用TCP和UDP流量
下面通过一个例子看一下
# example: nginx.conf
# 全局块
user nginx; # 运行用户
worker_processes auto; # worker 进程数
worker_cpu_affinity auto; # 设置 worker 进程与 CPU 核心的关联性
worker_rlimit_nopaper 102400; # 每个 worker 进程可以打开的最大文件描述符数量
error_log /var/log/nginx/error.log notice; # 错误日志路径和 level
pid /var/run/nginx.pid; # 指定存储 Nginx 进程 ID 的文件路径
# events块
events {
use epoll; # 事件驱动
worker_connections 102400; # 每个 worker 进程可以同时处理的最大连接数
}
# http块
http {
# MIME
include /etc/nginx/mime.types;
default_type application/octet-stream;
# 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 /var/log/nginx/access.log main;
# 响应中不出现Nginx版本信息
server_tokens off;
# 启用 sendpaper 机制,用于提高文件传输性能
sendpaper on;
# 全局超时设置
proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
send_timeout 600;
keepalive_timeout 600;
# 启动gzip压缩
gzip on;
gzip_min_length 0;
gzip_buffers 4 16k;
gzip_comp_level 1;
gzip_types text/plain application/javascript text/css
application/xml text/javascript application/x-httpd-php
image/jpeg image/gif image/png;
gzip_vary on;
# 导入其他配置
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/conf.d/*/*.conf;
}
stream {
# Log
log_format proxy '$remote_addr [$time_local] '
'$protocol $status $bytes_sent $bytes_received '
'$session_time "$upstream_addr" '
'"$upstream_bytes_sent" "$upstream_bytes_received" "$upstream_connect_time"';
access_log /var/log/nginx/tcp-access.log proxy;
# 关闭日志缓存
open_log_paper_cache off;
# 导入其他配置
include /etc/nginx/conf.d/*.stream;
include /etc/nginx/conf.d/*/*.stream;
}