前言
公司项目使用Nginx完成反向代理以及静态资源服务器,所以对Nginx相关的知识学习整理一下
Nginx简介
Nginx由俄罗斯工程师伊戈尔·赛索耶夫使用C语言编写创造(致敬🚀️ )并开源,是一款具有高性能、高可靠性的 Web 和反向代理服务器,占用内存少、并发能力强、支持热部署,支持高达 5w 个并发连接数。
Nginx优势
- 高并发、高性能;Nginx采用了多进程和I/O多路复用(epoll)的底层实现,从而拥有优秀的并发能力及性能
- 高可靠性;Nginx采用的多进程模式运行,其中有一个master主进程和N个worker进程,每个worker进程之间相互独立提供服务,master主进程可以在某一个worker进程出错时,快速去拉起新的worker进程提供服务
- 配置简单,扩展性强;模块化架构使得它的扩展性非常好,这些模块的使用可以通过配置文件的配置来添加
- 热部署、平滑升级;Nginx可以在不停止的情况下,对Nginx进行文件升级、更新配置和更换日志文件等功能
- 开源,社区繁荣;免费且好用,大家都喜欢😄
Nginx使用场景
- 作为静态资源服务器
- 作为反向代理服务器,并提供负载均衡和容错
- 邮件代理服务
- 虚拟主机、过滤器功能等等
Nginx基础命令
我们可以通过Nginx安装目录sbin下的可执行文件来对nginx进行控制,使用 nginx -h
查看可使用参数(因为我这里使用docker方式启动的所以前面使用了docker exec -it 容器命,不必在意)
nginx -h #显示帮助信息
nginx -V #打印版本号信息和配置信息并退出
nginx -T #测试nginx的配置文件语法是否正确并列出用到的配置文件信息然后退出
nginx -q #在配置测试期间禁止显示非错误消息
nginx -s stop #立刻停止nginx服务
nginx -s quit #等待所有请求处理完毕后,停止nginx服务
nginx -s reopen #重新打开日志文件
nginx -s reload #重新加载nginx配置文件,以热部署的方式重启
nginx -p "prefix" #指定Nginx的prefix路径,(默认为: /usr/local/nginx/)
nginx -c "filename" #指定Nginx的配置文件路径,(默认为: conf/nginx.conf)
nginx -g "directives" #补充Nginx配置文件,向Nginx服务指定启动时应用全局的配置
Nginx核心配置
配置文件概览
Nginx的核心配置文件默认路径 /usr/local/nginx/conf/nginx.conf
(如果是以docker容器的方式启动那么就不一样了哈,应该是在 /etc/nginx/nginx.conf
),作为开发人员主要关注点就是其相关的使用及配置参数,直接贴一份比较详细的配置文件吧,当然看nginx的默认配置文件也可以的
# 全局配置信息
user nginx; # 运行用户,默认即是nginx,可以不进行设置
worker_processes auto; # Nginx 进程数,一般设置为和 CPU 核数一样
error_log /var/log/nginx/error.log warn; # Nginx 的错误日志存放目录
pid /var/run/nginx.pid; # Nginx 服务启动时的 pid 存放位置
# events段配置信息
events {
use epoll; # 使用epoll的I/O模型(如果你不知道Nginx该使用哪种轮询方法,会自动选择一个最适合你操作系统的)
worker_connections 1024; # 每个进程允许最大并发数
}
# http段配置信息
# 配置使用最频繁的部分,代理、缓存、日志定义等绝大多数功能和第三方模块的配置都在这里设置
http {
# 设置日志模式
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访问日志存放位置
sendfile on; # 开启高效传输模式
tcp_nopush on; # 减少网络报文段的数量
tcp_nodelay on;
keepalive_timeout 65; # 保持连接的时间,也叫超时时间,单位秒
types_hash_max_size 2048;
include /etc/nginx/mime.types; # 文件扩展名与类型映射表
default_type application/octet-stream; # 默认文件类型
include /etc/nginx/conf.d/*.conf; # 加载子配置项
# server段配置信息
server {
listen 80; # 配置监听的端口
server_name localhost; # 配置的域名
# location段配置信息
location / {
root /usr/share/nginx/html; # 网站根目录
index index.html index.htm; # 默认首页文件
deny 172.168.22.11; # 禁止访问的ip地址,可以为all
allow 172.168.33.44;# 允许访问的ip地址,可以为all
}
error_page 500 502 503 504 /50x.html; # 默认50x对应的访问页面
error_page 400 404 error.html; # 同上
}
}
总的来说,Nginx配置文件分三个大块:
- 全局块:主要设置Nginx服务器整体运行的配置指令,全局生效
- events块:主要设置,Nginx服务器与用户的网络连接,这块配置Nginx服务器性能有影响较大
- http块:主要设置代理、缓存、日志记录、第三方模块配置等,也是我们关注最多的块
接下来会对各个模块的主要配置参数进行说明
全局块
user
语法 user username [group]
用于配置运行Nginx服务器的worker进程的用户和用户组,这样对于系统的权限访问控制的更加精细,也更加安全。具体使用方式,这里不多做说明,读者可自行查阅
work process
用于配置Nginx生成工作进程的数量,这个是Nginx服务器实现并发处理服务的关键所在。理论上来说workder process的值越大,可以支持的并发处理量也越多,但事实上这个值的设定是需要受到来自服务器自身的限制,建议将该值和服务器CPU的内核数保存一致,可以通过 设置 worker_processes auto
让Nginx根据当前服务器配置自动选择合适的大小
pid
用来配置Nginx当前master进程的进程号ID存储的文件路径,默认路径 /usr/local/nginx/logs/nginx.pid
daenon
设定Nginx是否以守护进程的方式启动, 默认为 on 后台进程形式
,不会随着控制台关闭而关闭
events块
accept_mutex
用来设置Nginx网络连接序列化,默认值 accept_mutex on
,由于nginx后台以多进程方式运行时,一个请求唤醒多个进程,最终只能有一个进程可以获取连接,这样会造成资源的浪费,影响性能。将accept_mutex 设置为on,会对多个Nginx进程接收连接进行序列号,一个个来唤醒接收,就防止了多个进程对连接的争抢
worker_connections
worker 子进程能够处理的最大并发连接数,最大值为1024
multi_accept
用来设置是否允许同时接收多个网络连接,默认值 multi_accept off
默认值时nginx一个工作进程只能同时接受一个新的连接,当一个链接。否则,一个工作进程可以同时接受所有的新连接
use
用来设置Nginx服务器选择哪种事件驱动来处理网络消息,不配置时Nginx根据操作系统决定,
可选值为:select、poll、kqueue、epoll、/dev/poll、eventport
http块
http块中我们主要关注server段的配置,其他部分这里不具体介绍,直接开始反向代理的配置,实操能直观的体会server块的功能
反向代理配置
配置一(实现代理)
实现效果:通过配置nginx实现请求转发tomcat
步骤一:创建一个tomcat,修改默认index页面方便后续做区分
# 1.使用docker创建tomcta
docker run -d --name my-tomcat -p 8080:8080 -v /root/tomcat/data:/usr/local/tomcat/webapps/ROOT tomcat
# 2.修改默认页面
echo "hello tomcat 8080" >> /root/tomcat/data/index.html
步骤二:创建一个nginx,修改默认配置文件nginx.conf 中的server块
# 1.使用docker创建nginx,因为我这里宿主机80端口已经被占用所以使用的是81
docker run -d --name nginx-demo -p 81:80 -v /root/nginx/nginx.conf:/etc/nginx/nginx.conf -v /root/nginx/log:/var/log/nginx/ --restart=always nginx
# 2.修改nginx.conf配置文件内容,将默认server段信息替换成如下
# Nginx server块配置
server {
listen 80; # 配置监听的端口
root /usr/share/nginx/html; # 网站根目录
index index.html; # 默认首页文件
location / {
# ps: ip是docker的网关地址,centos系统可以通过ifconfig命令查看,端口号是tomcat容器运行时映射的
# 主机端口号,不要搞混了,虽然确实有点混👀️
proxy_pass http://172.17.0.1:8080;
}
error_page 500 502 503 504 /50x.html;
error_page 400 404 /50x.html;
}
步骤三:直接访问你的服务器ip+81端口号,效果如下,证明代理成功
配置二(实现根据路径名进行转发)
步骤一:创建另一个tomcat,内容跟第一个做区分
# 1.使用docker创建tomcta,第一个占用8080,所以第二个使用8081
docker run -d --name my-tomcat1 -p 8081:8080 -v /root/tomcat1/data:/usr/local/tomcat/webapps/ROOT tomcat
# 2.修改默认页面
echo "hello tomcat 8081" >> /root/tomcat1/data/index.html
步骤二:修改nginx配置文件server段内容为
# 1.使用docker创建nginx,因为我这里宿主机80端口已经被占用所以使用的是81
docker run -d --name nginx-demo -p 81:80 -v /root/nginx/nginx.conf:/etc/nginx/nginx.conf -v /root/nginx/log:/var/log/nginx/ --restart=always nginx
# 2.修改nginx.conf配置文件内容,将默认server段信息替换成如下
# Nginx server块配置
server {
listen 80; # 配置监听的端口
root /usr/share/nginx/html; # 网站根目录
index index.html; # 默认首页文件
location /tomcat {
# ps: ip是docker的网关地址,centos系统可以通过ifconfig命令查看,端口号是tomcat容器运行时映射的
# 主机端口号,不要搞混了,虽然确实有点混👀️
proxy_pass http://172.17.0.1:8080;
}
location /tomcat1 {
# ps: ip是docker的网关地址,centos系统可以通过ifconfig命令查看,端口号是tomcat容器运行时映射的
# 主机端口号,不要搞混了,虽然确实有点混👀️
proxy_pass http://172.17.0.1:8081;
}
error_page 500 502 503 504 /50x.html;
error_page 400 404 /50x.html;
}
步骤三:分别访问两个不同路径,最终实现根据路径匹配转发
访问 ip:81/tomcat
访问ip:81/tomcat1
配置三(负载均衡)
步骤一:修改nginx配置文件,添加upstream,将代理地址替换为upstream
# 添加upstream
upstream tomcatServer {
server 172.17.0.1:8080;
server 172.17.0.1:8081;
}
# server段配置信息
server {
listen 80; # 配置监听的端口
root /usr/share/nginx/html; # 网站根目录
index index.html; # 默认首页文件
location /tomcat{
# 将代理地址替换成前面配置的upstream
proxy_pass http://tomcatServer/;
}
步骤二:重启nginx,多次访问 ip:81/tomcat,通过响应的页面可以知道我们的请求被轮询转发到两个tomcat
Nginx负载均衡的策略
轮询
Nginx默认的策略,通过前面测试可以看出,请求被Nginx逐次转发给上游服务器
hash 算法
通过指定关键字作为 hash key ,基于 hash 算法映射到特定的上游服务器中。关键字可以包含有变量、字符串
upstream tomcatServer {
hash $request_uri;
server 172.17.0.1:8080;
server 172.17.0.1:8081;
}
hash $request_uri 表示使用 request_uri 变量作为 hash 的 key 值,只要访问的 URI 保持不变,就会一直分发给同一台服务器
ip_hash
根据客户端的请求 ip 进行判断,只要 ip 地址不变就永远分配到同一台主机。它可以有效解决后台服务器 session 保持的问题
upstream tomcatServer {
ip_hash;
server 172.17.0.1:8080;
server 172.17.0.1:8081;
}
权重
根据设置的weight权重值进行转发,默认值为1,权重越大,被转发的概率越高
upstream tomcatServer {
server 172.17.0.1:8080 weight=10; # 这个Nginx会被转发更多的请求
server 172.17.0.1:8081 weight=2;
}
fair
按照服务器的响应时间来分配请求,响应时间短的优先分配,充分利用服务器资源
upstream tomcatServer {
server 172.17.0.1:8080;
server 172.17.0.1:8081;
fair;
}
server 段配置参数
listen
配置监听的端口,默认80端口
listen 80;
server_name
配置的域名
server_name www.nginx.site;
location
配置路径,我们的请求会匹配对应的的location路径,然后被代理到不同上游服务器
location /tomcat {
}
proxy_pass
配置代理服务器,匹配对应的location块后,请求会被转发到 proxy_pass 配置的对应上有服务器
location /tomcat {
proxy_pass http://127.0.0.1/;
}
upstream
用于定义上游服务器的相关信息,在proxy_pass中使用定义的upstream,就可以实现多服务器的负载均衡
upstream tomcatServer {
server 172.17.0.1:8080;
server 172.17.0.1:8081;
}
总结
本篇对Nginx的基础学习做了整理,包括常用的命令使用,配置文件参数介绍,以及使用nginx进行反向代理的实操测试。这里没有涉及到的知识还有很多,需要更多的学习🚀️