在日常工作中,Nginx 的重要性当然不言而喻。
经常用,但并不意味着精通,还会有很多不清楚的方式和技巧,那么本文就简单汇总下,帮助自己理解。
Nginx(发音为“Engine X”)是一款轻量级和高性能的 Web 服务器、反向代理服务器、电子邮件(IMAP/POP3/SMTP)代理服务器,是带有 BSD-like 协议的开源产品。
另外,关于 BSD-like 协议,它为开发者和企业提供了极大的灵活性,在确保尊重原作者工作的同时,允许代码的自由流通和使用,无论是在开源社区还是商业应用中。
其特点包括:
Nginx 是基于 C 语言开发的,拥有高性能的基本保证。
正向代理主要是为了客户端服务,而反向代理则是为了服务器端的服务优化和安全考虑,都可以明显提高数据传输的效率。它们的特点如下:
正向代理(Forward Proxy):
由于防火墙的原因,我们并不能直接访问谷歌,那么我们可以借助 VPN 来实现,这就是一个简单的正向代理的例子。这里你能够发现,正向代理“代理”的是客户端,而且客户端是知道目标的,而目标是不知道客户端是通过 VPN 访问的。
反向代理(Reverse Proxy):
当我们在外网访问百度的时候,其实会进行一个转发,代理到内网去,这就是所谓的反向代理,即反向代理“代理”的是服务器端,而且这一个过程对于客户端而言是无感的。
正向代理和反向代理的关系示意图如下:
无论是正向代理还是反向代理,都适用 Cache(缓存)技术。比如反向代理服务器,可以缓存一些从服务端取到的实时性要求不太高的数据,当客户端访问已缓存的数据且没有过期,就会 Cache 命中,不用再重复去服务端去获取,减少响应等待时间。
详情可参考:https://zhuanlan.zhihu.com/p/68560128
负载均衡(Load Balance),意思是将负载(工作任务,访问请求)进行平衡、分摊到多个操作单元(服务器,组件)上进行执行。是达到高性能,解决单点故障(高可用),增加扩展性(水平伸缩)的终极解决方案。
举个事例,在早高峰乘地铁时候,紧挨小区的地铁口人特别多,一般会有限流,还会有个地铁工作人员用大喇叭在喊“着急的人员请走B口,B口人少车空”。那么,地铁工作人员就是负责负载均衡的。
为了提升网站的各方面能力,我们一般会把多台机器组成一个集群对外提供服务。然而,一般网站对外提供的访问入口都是一个。比如 www.taobao.com,当用户在浏览器输入 www.taobao.com 的时候如何将用户的请求分发到集群中不同的机器上呢?这就是负载均衡在做的事情。
如下图中的代理,就可以是 nginx 服务器,接收到请求后,分配给服务集群:
根据负载均衡技术实现在 OSI 七层模型(7应用层、6表示层、5会话层、4传输层、3网络层、2数据链路层、1物理层)的不同层次,可以给负载均衡分类。常见的实现方式中,主要可以在应用层、传输层、网络层和数据传输层做文章。所以,工作在应用层的负载均衡,我们通常称之为七层负载均衡;工作在传输层的我们称之为四层负载均衡。
大致可以分为以下几种,其中最常用的是四层和七层负载均衡:
负载均衡服务器对外依然提供一个 VIP(虚 IP),集群中不同的机器采用相同 IP 地址,但是机器的 MAC 地址不一样。当负载均衡服务器接受到请求之后,通过改写报文的目标 MAC 地址的方式将请求转发到目标机器实现负载均衡。
和二层负载均衡类似,负载均衡服务器对外依然提供一个 VIP(虚 IP),但是集群中不同的机器采用不同的 IP 地址。当负载均衡服务器接受到请求之后,根据不同的负载均衡算法,通过 IP 将请求转发至不同的真实服务器。
四层负载均衡工作在 OSI 模型的传输层,由于在传输层,只有 TCP/UDP 协议,这两种协议中除了包含源 IP、目标 IP 以外,还包含源端口号及目的端口号。四层负载均衡服务器在接受到客户端请求后,以后通过修改数据包的地址信息(IP+端口号)将流量转发到应用服务器。
七层负载均衡工作在 OSI 模型的应用层,应用层协议较多,常用 http、radius、dns 等。七层负载就可以基于这些协议来负载。这些应用层协议中会包含很多有意义的内容。比如同一个 Web 服务器的负载均衡,除了根据 IP 加端口进行负载外,还可根据七层的 URL、浏览器类别、语言来决定是否要进行负载均衡。
Nginx:主要用来做七层负载均衡。Nginx 是一个网页服务器,它能反向代理 HTTP, HTTPS, SMTP, POP3, IMAP 的协议链接,以及一个负载均衡器和一 个HTTP 缓存。
详细可参考:https://www.cnblogs.com/fanBlog/p/10936190.html
官网下载页:nginx: download
可下载稳定版:
另外 Mainline version 主线版本为最新版本的,Legacy version 历史版本,可按需下载。
安装包中的目录与对应功能:
Nginx 默认监听当前服务器的 80 端口,如下图:(配置文件路径示例:C:\nginx-1.24.0\conf\nginx.conf)
因此可先看下 80 端口有没有被占用。方法是打开 cmd 窗口,用命令(...>netstat -ano)来查看当前端口使用情况,最后一列为 PID。使用命令(...>taskkill /f /t /pid PID编号)结束对应的进程。如果占用 80 端口的是一个关键进程关不掉,那么就是惹不起得躲,将 Nginx 配置文件中的 80 端口改掉。
可以通过双击 nginx.exe,也可以通过命令的方式,如下在 Nginx 的主目录地址栏输入 cmd,并回车:
打开命令行窗口,路径是在当前文件夹,如下图,然后输入命令:nginx 或者 start nginx 开启服务:
然后在地址栏输入:http://localhost:80,查看服务是否启动成功。
需要另开一个命令窗口通过命令(...>nginx -s stop)进行关闭。
参考:https://blog.csdn.net/weixin_44251179/article/details/129700793
// 进入 opt 目录,暂存安装包
cd /opt
// 下载 nginx 包,示例下载版本为 1.24.0 可根据实际修改
wget http://nginx.org/download/nginx-1.24.0.tar.gz
// 创建目录,用于存放 nginx 文件
mkdir /usr/local/nginxtest
// 解压安装包内容
// -zxvf:解压详细配置,略
// -C:解压到指定目录,后边跟的是目标目录
tar -zxvf nginx-1.24.0.tar.gz -C /usr/local/nginxtest
// 进入解压后文件存放的文件夹
cd /usr/local/nginxtest/nginx-1.24.0
// 配置 nginx 编辑环境
./configure
// 编译并安装
make && make install
编译安装完成后,在 /usr/local/ 目录下会自动生成一个 nginx 目录,代表安装成功。
// 进入 sbin 目录
cd /usr/local/nginx/sbin/
// 启动 Nginx 服务
./nginx
浏览器输入服务 IP,默认 80 端口:
在执行命令./configure
来配置 nginx 编辑环境时,如下异常提示:
[root@localhost nginx-1.24.0]# ./configure
checking for OS
+ Linux 3.10.0-1160.83.1.el7.x86_64 x86_64
checking for C compiler ... not found
./configure: error: C compiler cc is not found
如何解决:
yum -y install gcc
gcc 的全称是 GNU Compiler Collection,它是一个能够编译多种语言的编译器。最开始 gcc 是作为 C 语言的编译器(GNU C Compiler),现在除了 C 语言,还支持 C++、java、Pascal 等语言,gcc 还支持多种硬件平台。
在执行命令./configure
来配置 nginx 编辑环境时,如下异常提示:
./configure: error: the HTTP rewrite module requires the PCRE library.
You can either disable the module by using --without-http_rewrite_module
option, or install the PCRE library into the system, or build the PCRE library
statically from the source with nginx by using --with-pcre=<path> option.
PCRE 库(Perl Compatible Regular Expressions Library)是一个正则表达式库,提供了与 Perl 语言兼容的正则表达式功能。它被广泛用于各种编程语言和软件中,用于处理字符串匹配、搜索、替换等操作。
如何解决:
yum -y install openssl openssl-devel
openssl 命令是强大的安全套接字层密码库。OpenSSL 是一种开源命令行工具,通常用于生成私钥,创建 CSR,安装 SSL / TLS 证书以及标识证书信息等等。通过使用 OpenSSL,用户可以保护自己的数据不受未授权访问,并确保通信的安全性。
参考:https://www.cnblogs.com/orangebooks/p/12058830.html https://blog.csdn.net/memory6364/article/details/87258101
// windows
nginx -t // 小写 t:检查配置文件并显示文件路径;大写 T:还额外显示全部配置项和支持的文件类型
.\nginx -t
nginx -c filename // 设置配置文件(默认是:/nginx/conf/nginx.conf)
// Linux
./nginx -t
./nginx -c filename // 设置配置文件(默认是:/nginx/conf/nginx.conf)
// Windows
nginx // 命令行运行(当前窗口关掉,不影响运行)
.\nginx // 命令行运行(当前窗口关掉,不影响运行)
start nginx // 后台运行
// Linux
./nginx // 后台运行
// windows
nginx -s quit // 等待任务完成后停止
.\nginx -s quit
nginx -s stop // 强制停止
.\nginx -s stop
// linux
./nginx -s quit // 等待任务完成后停止
./nginx -s stop // 强制停止
// windows
nginx -s reload
.\nginx -s reload
// linux
./nginx -s reload
// 小写 v:仅显示版本;大写 V:除了版本信息还显示配置信息
// windows
nginx -v
.\nginx -v
// linux
./nginx -v
// windows
tasklist /fi "imagename eq nginx.exe" // 查看进程,包含 PID // fi:Filter 过滤器/筛选器
tskill PID数值 // 关闭指定进程
taskkill /im nginx.exe /f // 根据映像名称关闭同名的全部进程 // im:映像名称 f:强制 t:一起结束进程树
taskkill /f /t /fi "imagename eq nginx.exe" // 根据映像名称关闭同名的全部进程
// linux
pgrep nginx // 根据进程名查询 PID
ps -ef | grep nginx // 根据进程名查询详细信息 // e:全部进程 f:显示完整格式
kill PID数值 // 关闭指定 PID 的进程,以及子进程
pkill nginx // 根据进程名关闭
killall nginx // 关闭根据进程名得到的全部匹配项
当 nginx 日志文件内容较多时,一般需要按天切割文件,每天的日志放在一个文件中,并用日期命名,方便日后查找。但是简单的把文件移动并重新命名是无法及时生效的,因为在 linux 下的文件句柄,文件在被打开的情况下 mv 移走文件,操作这个文件的进程还是有这个文件的信息,原进程还是读写原来的文件。因此简单的 mv 无法生效也就无法完成我们想要的文件分割。
此时就需要根据以下步骤:先移走文件并重命名;再利用 nginx 的 reopen 功能,完成新日志文件的生成。
// windows
ren access.log access_20240410.log // 进入 logs 文件夹 ren 重命名日志文件
nginx -s reopen // 返回 nginx 目录后,重新生成新的日志文件
.\nginx -s reopen
// linux
mv /usr/local/nginx/logs/access.log /usr/local/nginx/logs/access20240410.log // 通过绝对路径重命名
./nginx -s reopen // 重新生成新的日志文件
cd .. // 进入 logs 文件夹查看日志文件
cd logs
ls // 结果:access20240410.log access.log error.log nginx.pid
Nginx 的主配置文件是 nginx.conf,这个配置文件一共由三部分组成,分别为全局块、events 块和 http 块。
在 http 块中,又包含 http 全局块、多个 server 块。每个 server 块中,可以包含 server 全局块和多个 location 块。在同一配置块中嵌套的配置块,各个之间不存在次序关系。
配置文件支持大量可配置的指令,绝大多数指令不是特定属于某一个块的。同一个指令放在不同层级的块中,其作用域也不同。
一般情况下,高一级块中的指令可以作用于自身所在的块和此块包含的所有低层级块。如果某个指令在两个不同层级的块中同时出现,则采用“就近原则”,即以较低层级块中的配置为准。比如,某指令同时出现在 http 全局块中和 server 块中,并且配置不同,则应该以 server 块中的配置为准。
全局块是默认配置文件从开始到events块之间的一部分内容,主要设置一些影响Nginx服务器整体运行的配置指令,因此,这些指令的作用域是Nginx服务器全局。
通常包括配置运行 Nginx 服务器的用户(组)、允许生成的 worker process 数、Nginx 进程 PID 存放路径、日志的存放路径和类型以及配置文件引入等。
# 指定可以运行 nginx 服务的用户和用户组
# user [user] [group]
# 将user指令注释掉,或者配置成 nobody 的话所有用户都可以运行
# user nobody nobody;
# user 指令在 Windows 上不生效,如果指定具体用户和用户组会报警告
# nginx: [warn] "user" is not supported, ignored in D:\software\nginx-1.18.0/conf/nginx.conf:2
user root;
# 指定并发工作的进程数,可以配置具体数字,也可使用自动模式
# worker_processes number | auto;
# 如下配置:指定 4 个工作进程,此时会生成一个 master 进程和 4 个工作进程,总共五个
# 因此,可以配置工作进程数为本机 CPU 核心数 n -1
worker_processes 4;
# 指定包含 nginx 主进程的 PID 数值的文件路径
# 用途:进程管理、监控与诊断、方便进行自动化脚本控制
pid logs/nginx.pid;
# 指定错误日志的路径和日志级别
# error_log [path] [debug | info | notice | warn | error | crit | alert | emerg]
# 其中debug级别的日志需要编译时使用--with-debug开启debug开关
error_log logs/error.log info;
# 此指令可以在(全局块 < http 块 < server 块 < location 块)中配置,下面简单介绍下区别:
# 首先就是,配置在越低级的块中优先级越高;
# 各个级别的配置块中设置的日志指令,将应用于各自所有下级;
# server 块的配置,目的是不同的服务器配置不同的日志文件或日志级别;
# location 块是最具体的配置级别,它可为特定的 URI 路径或模式设置专门的日志指令。
events 块涉及的指令主要影响 Nginx 服务器与用户的网络连接。
常用到的设置包括:
# 当某一时刻只有一个网络连接到来时,【多个睡眠进程】会被同时唤醒,但只有【一个进程】可获得连接
# 如果【每次唤醒的进程数目太多】,会影响一部分系统性能
# 开启的时候,将会对多个 Nginx 进程接收连接进行序列化,【防止多个进程对连接的争抢】
# 有两个枚举值,默认是开启状态,因此可以不进行专门配置
# accept_mutex on | off;
accept_mutex on;
# multi_accept 配置,决定了当有多个工作进程监听同一个端口时,这些进程如何处理到来的新请求,语法:
# multi_accept on | off;
# off 时:当有新连接到来时,【所有等待的工作进程都会被唤醒】来接受连接,这样可以【提高处理效率】,尤其是在高并发的场景下
# on 时:当有新连接到来时,【只有一个工作进程数会被唤醒】,其他仍处于休眠状态 ,目的是【控制资源的使用】,避免在高并发情况下系统资源的过度消耗
# 如果在支持 kqueue 高效多路复用机制的操作系统(FreeBSD、macOS 等)上运行 Nginx,那么这条指令会被忽略
# 【默认是 off 状态】
multi_accept off;
# 指定使用哪种网络 IO 模型,影响到 Nginx 处理并发连接的能力,语法:
# use method
# 其中 method 可选择的内容有:
# 【Windows 默认 select】【Linux 默认 epoll】【FreeBSD 默认 kqueue】
# select:这是最基本的网络 IO 模型,适用于低并发场景,它在处理大量连接时可能会变得效率低下
# poll:相比 select,poll 能够处理更多的文件描述符,但在某些系统上性能提升有限
# kqueue:这是 FreeBSD 系统特有的高效网络 IO 模型,适用于高并发环境
# epoll:这是Linux 系统下的高效网络 IO 模型,同样适合处理大量并发连。
# rtsig:这是一种实时信号驱动的网络 IO 模型,它可以在不使用线程的情况下处理事件
# dev/poll:这是 Solaris 操作系统特有的网络 IO 模型,类似于 poll
# eventport:这是 NetBSD 和 GNU/Hurd 系统上的事件端口模型,用于处理网络事件
# /dev/poll:这是 macOS 系统上的网络 IO 模型,类似于 poll
use epoll
# 设置允许每一个 worker process 同时开启的最大连接数
# 当每个工作进程接受的连接数超过这个值时将不再接收连接,当所有的工作进程都接收满时,连接进入 logback,logback 满后连接被拒绝
worker_connections 1024;
# 注意:worker_connections * worker_process <= 系统的最大打开文件数
# worker_connections <= 单个进程支持打开的最大文件数
# 下文继续详解...
关于全局和单进程最大打开文件数:
# 【全局限制】
# Linux 下执行:cat /proc/sys/fs/file-nr
# 打印出结果:960 0 3228075
# 第三个数字 3228075 就是当前系统的全局最大打开文件数(Max Open Files)
# 也可以自行修改这个数值,用 root 权限修改 /etc/sysctl.conf 文件
# fs.file-max = 3228075
# net.ipv4.ip_conntrack_max = 3228075
# net.ipv4.netfilter.ip_conntrack_max = 3228075
# 【进程限制】
# Linux 下执行:ulimit -n
# 打印出结果:655350
# 临时修改(需 root 用户):ulimit -n 3228075
# 永久修改:
# 打开文件 /etc/security/limits.conf,加入如下行:
# work hard nofile 3228075
# work soft nofile 3228075
# 详情参考:https://cloud.tencent.com/developer/article/1114773
http 块是 Nginx 服务器配置中的重要部分,代理、缓存和日志定义等绝大多数的功能和第三方模块的配置都可以放在这个模块中。
http 块中可以包含自己的全局块,其中配置的指令包括文件引入、MIME-Type 定义、日志自定义、是否使用 sendfile 传输文件、连接超时时间、单连接请求数上限等。
# include 指令,用于包含其他的配置文件,提高配置可读性,避免单个配置文件过大,但必须符合配置规范
# 下面的指令将 mime.types 包含进来,mime.types 和 nginx.conf 同级目录,不同级的话需要指定具体路径
include mime.types;
# 浏览器可以显示的内容有 HTML、XML、GIF 及 Flash 等种类繁多的文本、媒体等资源,浏览器为区分这些资源,需要使用MIME Type
# 换言之,MIME Type 是网络资源的媒体类型。Nginx 服务器作为 Web 服务器,必须能够识别前端请求的资源类型
# default_type 指令默认类型,如果不加此指令【默认值为 text/plain】
# 当 Web 程序无法识别对应文件 MIME 类型时,Nginx 会使用 default_type 指定的类型来告诉浏览器如何处理这个文件
# application/octet-stream,这是一种通用的二进制流数据类型,通常用于未知或未指定类型的文件,浏览器不会直接打开未知文件,而是提示下载
# 这样可以确保在没有明确指定 MIME 类型的情况下,用户不会被误导直接在浏览器中打开可能是执行代码的文件,更加安全
# 此指令还可以在 http 块、server 块或者 location 块中进行配置
default_type application/octet-stream;
# log_format 指令,用于定义日志格式,变量意义见后文表格
# main 为定义的格式名称,这样 access_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 指令
# 在全局块中,我们介绍过 errer_log 指令,其用于配置 Nginx 进程运行时的日志存放和级别
# 此处所指的日志与常规的不同,它是指记录 Nginx 服务器【提供服务过程应答前端请求的日志】
# buffer=size:设置内存缓存区的大小,不实时写入日志文件,可以减少磁盘 I/O 操作的次数
# access_log path [format [buffer=size]]
# 如果你要关闭 access_log,你可以使用下面的命令:access_log off;
# 此指令可以在 http 块、server 块或者 location 块中进行设置
access_log logs/access.log main;
# sendfile 指令用于配置,是否使用 sendfile()系统调用来高效的传输文件数据,【特别适合于提供静态内容的场景】,语法:
# sendfile on | off;
# 【默认值是 off】但在大多数提供静态内容的 Nginx 服务器上,建议将其设置为 on 以利用其带来的性能优势
# sendfile()系统调用模式,允许内核直接将文件数据从磁盘传输到网络 socket,而非先将数据读取到用户空间缓冲区,再写入到 socket 的内核缓冲区
# 这样可以减少数据在用户空间和内核空间之间的拷贝次数,从而显著提高静态文件传输的效率
# 此指令可以在 http 块、server 块或者 location 块中进行配置
sendfile on;
# sendfile_max_chunk 指令用于限制每个 sendfile()调用传输数据的最大块大小,语法:
# sendfile_max_chunk size;
# 此指令的最优值取决于具体的系统环境和网络条件
# 在高速网络环境中,较大的块大小可能更有利于提高传输效率;而在低速网络或高延迟的环境中,较小的块大小可能更合适
# 此外,还需要考虑到服务器的硬件资源,如 CPU 和内存的限制
# size 值如果大于 0,Nginx 进程的每个 worker process 每次调用 sendfile()传输的数据量最大不能超过这个值
# 如果设置为0,则无限制【默认值为 0】
# 此指令可以在 http 块、server 块或 location 块中配置
sendfile_max_chunk 128k;
# 配置连接超时时间,与用户建立会话连接后,Nginx 服务器可以保持这些连接打开一段时间,语法:
# keepalive_timeout timeout [header_timeout]
# timeout:服务器端对连接的保持时间【默认值为 75s】针对的是整个 TCP 连接的生命周期
# header_timeout:为可选项,是 timeout 的一个子集,在应答报文头部的 Keep-Alive 域设置超时时间,仅控制发送响应头之后的保持时间
# 此指令可以在 http 块、server 块或 location 块中配置
# 下面配置的含义是,在服务器端保持连接的时间设置为 120s,发给用户端的应答报文头部中 Keep-Alive 域的超时时间设置为 100s
keepalive_timeout 120s 100s;
# keepalive_requests 指令配置【单连接请求数上限】达到上限后自动关闭
# 【默认值为100】这意味着在默认配置下,Nginx 会在处理了100个请求后关闭长连接
# 此指令可以在 http 块、server 块或 location 块中配置
keepalive_requests 100;
# error_page 指令用于定义在出现特定错误时 Nginx 应该如何响应
# 当发生错误时,如请求的资源不存在(404错误)或服务器内部错误(500错误),Nginx 可以使用 error_page 指令来定制错误响应
# error_page <HTTP_Error> <value1> <value2>;
# <HTTP_Error>:表示要处理的 HTTP 错误状态码,如 404、500 等
# <value1>:表示当出现 <HTTP_Error> 错误时,Nginx 返回的错误页面的 uri
# <value2>:可选参数,表示是否允许重新定义该错误页面。默认为“=”,即允许重新定义。如果设置为“=@”,则表示不允许重新定义
error_page 404 /404.html;
# http 块中的 error_page 允许你指定一个特定的页面作为错误响应,而 location快中的 return 则只能返回标准的错误响应代码和消息
log_fomat 变量值定义:
参数名 | 参数意义 |
$remote_addr | 客户端 IP |
$remote_user | 远程客户端用户名,一般为:‘-’ |
$time_local | 时间和时区 |
$request | 请求的 url 以及 method |
$status | 响应状态码 |
$body_bytes_send | 响应客户端内容字节数 |
$http_referer | 记录用户从哪个链接跳转过来的 |
$http_user_agent | 用户所使用的代理,一般来时都是浏览器 |
$http_x_forwarded_for | 通过代理服务器来记录客户端的 IP |
server 块和“虚拟主机”的概念有密切联系。
虚拟主机,又称虚拟服务器、主机空间或是网页空间,该技术是为了节省互联网服务器硬件成本而出现。这里的“主机”或“空间”是由实体的服务器延伸而来,硬件系统可以基于服务器群,或者单个服务器等。虚拟主机技术主要应用于 HTTP、FTP 及 EMAIL 等多项服务,将一台服务器的某项或者全部服务内容逻辑划分为多个服务单位,对外表现为多个服务器,从而充分利用服务器硬件资源。从用户角度来看,一台虚拟主机和一台独立的硬件主机是完全一样的。
在使用 Nginx 服务器提供 Web 服务时,利用虚拟主机的技术,就可以在同一台服务器上只运行一组 Nginx 进程,来对应运行多个网站。
每一个 http 块都可以包含多个 server 块,而每个 server 块就相当于一台虚拟主机,它内部可有多台主机联合提供服务,一起对外提供一组逻辑上关系密切的服务(或网站)。
和 http 块相同,server 块也可以包含自己的全局块,同时可以包含多个 location 块。在 server 全局块中,最常见的两个配置项是本虚拟主机的监听配置和本虚拟主机的名称或 IP 配置。
server 块中最重要的指令就是 listen 指令,这个指令有三种配置语法。这个指令默认的配置值是:listen *:80 | *:8000;只能在server块种配置这个指令。
# 【三种格式】
# 第一种
# listen address[:port] [default_server] [ssl] [http2 | spdy] [proxy_protocol] [setfib=number] [fastopen=number] [backlog=number] [rcvbuf=size] [sndbuf=size] [accept_filter=filter] [deferred] [bind] [ipv6only=on|off] [reuseport] [so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt]];
# 第二种
# listen port [default_server] [ssl] [http2 | spdy] [proxy_protocol] [setfib=number] [fastopen=number] [backlog=number] [rcvbuf=size] [sndbuf=size] [accept_filter=filter] [deferred] [bind] [ipv6only=on|off] [reuseport] [so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt]];
# 第三种(可以不用重点关注)
# listen unix:path [default_server] [ssl] [http2 | spdy] [proxy_protocol] [backlog=number] [rcvbuf=size] [sndbuf=size] [accept_filter=filter] [deferred] [bind] [so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt]];
部分参数说明:
listen 指令的格式看起来比较复杂,但在实际应用中并不会进行太复杂的配置。
如下几个简单的配置,可以单独制定 IP,单独指定端口或者同时指定 IP 和端口:
# 只监听来自 127.0.0.1 这个 IP,请求 8000 端口的请求
listen 127.0.0.1:8000;
listen localhost:8000;
# 只监听来自 127.0.0.1 这个 IP,请求 80 端口的请求(不指定端口,默认 80)
listen 127.0.0.1;
# 监听来自所有 IP,请求 8000 端口的请求
listen 8000;
listen *:8000;
用于指定虚拟主机的域名,它决定了请求将被路由到哪个服务器块处理。语法是:
# 【基本使用】
# 配置一个或多个具体的域名,以空格分隔,表示 Nginx 可接受指向这些域名的请求
# server_name name1 name2 ...;
server_name example.com www.example.com;
# 【通配符匹配】
# 使用通配符 * 只能用来匹配域名的【开头或结尾】部分,如下配置会匹配所有以 .example.com 结尾的域名
server_name *.example.com;
# 【正则表达式匹配】
# 支持使用正则表达式进行更复杂的匹配,如下配置可以捕获并使用正则表达式中的部分内容
server_name ~^www\.(?<domain>.+\.com)$;
# 对于字符串 "www.example.com",它将匹配成功,并提取出 "example" 作为 "domain" 的值
关于优先级和匹配顺序:
当有多个 server_name 配置时,Nginx 会根据配置文件中的顺序以及域名匹配的优先级来决定使用哪个 server_name。
匹配顺序:准确匹配 > 通配符在开头匹配成功 > 通配符在结尾时匹配server_name成功 > 正则表达式匹配成功。
在以上四种匹配方式中,如果 server_name 被处于同一优先级的匹配方式多次匹配成功,则首次匹配成功的虚拟主机处理请求。
若未配置 server_name:
就默认为空字符串 "",这意味着它不会匹配任何基于域名的请求。
如果没有其他 server 块匹配请求,那么请求将被这个默认 server 块处理。
HTTPS 配置:
当配置 HTTPS 时,通常需要为 server_name 指定相应的 SSL 证书。
例如:listen 443 ssl; server_name abc.com;
表示监听 443 端口(HTTPS)并为 abc.com 提供 SSL 加密。
重定向配置:
有时需要将 HTTP 请求重定向到 HTTPS,可以通过 rewrite 指令实现,例如:rewrite ^(.*) https://$server_name$1 permanent;
表示将所有 HTTP 请求永久重定向到 HTTPS。
怎样使用基于 IP 地址的虚拟主机配置?比如访问 192.168.1.31 由虚拟主机一处理,访问 192.168.1.32 由虚拟主机二处理。
这时要先在网卡绑定别名,比如说网卡之前绑定的 IP 是 192.168.1.30,现在将 192.168.1.31 和 192.168.1.32 这两个 IP 都绑定到这个网卡上,那么请求这个两个 IP 的请求才会到达这台物理主机,然后再通过 Nginx 路由转发到指定的虚拟主机。
绑定别名后进行以下配置即可:
http {
server {
listen: 80;
server_name: 192.168.1.31;
...
}
server {
listen: 80;
server_name: 192.168.1.32;
...
}
}
用于匹配不同的 uri 请求,并对这些请求执行特定的操作。地址定向、数据缓存和应答控制等功能都是在这部分实现。许多第三方模块的配置也是在 location 块中提供功能。
在 Nginx 的官方文档中定义的 location 的语法结构为:
location [ = | ~ | ~* | ^~ ] uri { ... }
其中,uri 变量是待匹配的请求字符串,可以是不含正则表达的字符串,如 /myserver.php 等;也可以是包含有正则表达的字符串,如 .php$(表示以.php结尾的URL)等。
方括号里的部分,是可选项,用来改变请求字符串与 uri 的匹配方式。在不添加此选项时,Nginx 服务器首先在 server 块的多个 location 块中搜索是否有【 uri 】和请求字符串匹配,如果有多个可以匹配,就记录匹配度最高的一个。然后,服务器再用 location 块中的【正则 uri 】和请求字符串匹配,当第一个正则 uri 匹配成功,结束搜索,并使用这个 location 块处理此请求;如果正则匹配全部失败,就使用刚才记录的匹配度最高的 location 块处理此请求。
下边看下可选项的具体意义:
注意:如果 uri 包含正则表达式,就必须要使用“~”或者“~*”标识
另外,经过 URL 编码的 uri 也是可以匹配成功的。比如空格被编码为“%20”,问号被编码为“%3f”等。选项“~”自动对 uri 中的这些符号将会进行编码处理。比如,如果 location 块收到的 uri 为“/html/%20/data”,则当 Nginx 服务器搜索到配置为“~ /html/ /data”的 location 时,可以匹配成功。
用于设置请求寻找资源的跟目录。当浏览器请求某个资源时,Nginx 会根据 root 指令指定的路径和 location 匹配的路径组合成完整的文件路径,以此来查找并返回对应的静态资源。
此指令可以在 http 块、server 块或者 location 块中配置。
由于使用 Nginx 服务器多数情况下要配置多个 location 块对不同的请求分别做出处理,因此该指令通常在 location 块中进行设置。
root path;
root 指令通常与 location 指令配合使用。例如,配置如下 location:
如果 location 块指定为 location /flv/ { root /data/web; },那么当请求的 URL 为 /flv/example.txt 时,Nginx 会在 /data/web/flv/example.txt 的位置查找文件。
location /flv/ {
root /data/web;
}
那么当请求的 URL 为 /flv/example.txt
时,Nginx 会在 /data/web/flv/example.txt
的位置查找文件。
与 root 指令类似,但 alias 不会将 location 的值添加到文件路径的末尾,而是直接使用 alias 指定的路径作为文件路径。
定义请求 uri 指向的默认文件名。如果请求的是一个目录,Nginx 会尝试寻找此目录下的 index 文件中的文件并将其作为响应返回。
根据条件返回指定的HTTP状态码。例如,如果请求的资源不存在,可以返回404状态码。
http 块中的 error_page 允许你指定一个特定的页面作为错误响应,而 location快中的 return 则只能返回标准的错误响应代码和消息。
######Nginx配置文件nginx.conf中文详解#####
#定义Nginx运行的用户和用户组
user www www;
#nginx进程数,建议设置为等于CPU总核心数。
worker_processes 8;
#全局错误日志定义类型,[ debug | info | notice | warn | error | crit ]
error_log /usr/local/nginx/logs/error.log info;
#进程pid文件
pid /usr/local/nginx/logs/nginx.pid;
#指定进程可以打开的最大描述符:数目
#工作模式与连接数上限
#这个指令是指当一个nginx进程打开的最多文件描述符数目,理论值应该是最多打开文件数(ulimit -n)与nginx进程数相除,但是nginx分配请求并不是那么均匀,所以最好与ulimit -n 的值保持一致。
#现在在linux 2.6内核下开启文件打开数为65535,worker_rlimit_nofile就相应应该填写65535。
#这是因为nginx调度时分配请求到进程并不是那么的均衡,所以假如填写10240,总并发量达到3-4万时就有进程可能超过10240了,这时会返回502错误。
worker_rlimit_nofile 65535;
events
{
# 参考事件模型,use [ kqueue | rtsig | epoll | /dev/poll | select | poll ]; epoll模型
# 是Linux 2.6以上版本内核中的高性能网络I/O模型,linux建议epoll,如果跑在FreeBSD上面,就用kqueue模型。
# 补充说明:
# 与apache相类,nginx针对不同的操作系统,有不同的事件模型
# A)标准事件模型
# Select、poll属于标准事件模型,如果当前系统不存在更有效的方法,nginx会选择select或poll
# B)高效事件模型
# Kqueue:使用于FreeBSD 4.1+, OpenBSD 2.9+, NetBSD 2.0 和 MacOS X.使用双处理器的MacOS X系统使用kqueue可能会造成内核崩溃。
# Epoll:使用于Linux内核2.6版本及以后的系统。
# /dev/poll:使用于Solaris 7 11/99+,HP/UX 11.22+ (eventport),IRIX 6.5.15+ 和 Tru64 UNIX 5.1A+。
# Eventport:使用于Solaris 10。 为了防止出现内核崩溃的问题, 有必要安装安全补丁。
use epoll;
# 单个进程最大连接数(最大连接数=连接数*进程数)
# 根据硬件调整,和前面工作进程配合起来用,尽量大,但是别把cpu跑到100%就行。每个进程允许的最多连接数,理论上每台nginx服务器的最大连接数为。
worker_connections 65535;
# keepalive超时时间。
keepalive_timeout 60;
# 客户端请求头部的缓冲区大小。这个可以根据你的系统分页大小来设置,一般一个请求头的大小不会超过1k,不过由于一般系统分页都要大于1k,所以这里设置为分页大小。
# 分页大小可以用命令getconf PAGESIZE 取得。
# [root@web001 ~]# getconf PAGESIZE
# 4096
# 但也有client_header_buffer_size超过4k的情况,但是client_header_buffer_size该值必须设置为“系统分页大小”的整倍数。
client_header_buffer_size 4k;
# 这个将为打开文件指定缓存,默认是没有启用的,max指定缓存数量,建议和打开文件数一致,inactive是指经过多长时间文件没被请求后删除缓存。
open_file_cache max=65535 inactive=60s;
# 这个是指多长时间检查一次缓存的有效信息。
# 语法:open_file_cache_valid time 默认值:open_file_cache_valid 60 使用字段:http, server, location 这个指令指定了何时需要检查open_file_cache中缓存项目的有效信息.
open_file_cache_valid 80s;
# open_file_cache指令中的inactive参数时间内文件的最少使用次数,如果超过这个数字,文件描述符一直是在缓存中打开的,如上例,如果有一个文件在inactive时间内一次没被使用,它将被移除。
# 语法:open_file_cache_min_uses number 默认值:open_file_cache_min_uses 1 使用字段:http, server, location 这个指令指定了在open_file_cache指令无效的参数中一定的时间范围内可以使用的最小文件数,如果使用更大的值,文件描述符在cache中总是打开状态.
open_file_cache_min_uses 1;
# 语法:open_file_cache_errors on | off 默认值:open_file_cache_errors off 使用字段:http, server, location 这个指令指定是否在搜索一个文件时记录cache错误.
open_file_cache_errors on;
}
#设定http服务器,利用它的反向代理功能提供负载均衡支持
http
{
# 文件扩展名与文件类型映射表
include mime.types;
# 默认文件类型
default_type application/octet-stream;
# 默认编码
# charset utf-8;
# 服务器名字的hash表大小
# 保存服务器名字的hash表是由指令server_names_hash_max_size 和server_names_hash_bucket_size所控制的。参数hash bucket size总是等于hash表的大小,并且是一路处理器缓存大小的倍数。在减少了在内存中的存取次数后,使在处理器中加速查找hash表键值成为可能。如果hash bucket size等于一路处理器缓存的大小,那么在查找键的时候,最坏的情况下在内存中查找的次数为2。第一次是确定存储单元的地址,第二次是在存储单元中查找键 值。因此,如果Nginx给出需要增大hash max size 或 hash bucket size的提示,那么首要的是增大前一个参数的大小.
server_names_hash_bucket_size 128;
# 客户端请求头部的缓冲区大小。这个可以根据你的系统分页大小来设置,一般一个请求的头部大小不会超过1k,不过由于一般系统分页都要大于1k,所以这里设置为分页大小。分页大小可以用命令getconf PAGESIZE取得。
client_header_buffer_size 32k;
# 客户请求头缓冲大小。nginx默认会用client_header_buffer_size这个buffer来读取header值,如果header过大,它会使用large_client_header_buffers来读取。
large_client_header_buffers 4 64k;
# 设定通过nginx上传文件的大小
client_max_body_size 8m;
# 开启高效文件传输模式,sendfile指令指定nginx是否调用sendfile函数来输出文件,对于普通应用设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络I/O处理速度,降低系统的负载。注意:如果图片显示不正常把这个改成off。
# sendfile指令指定 nginx 是否调用sendfile 函数(zero copy 方式)来输出文件,对于普通应用,必须设为on。如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络IO处理速度,降低系统uptime。
sendfile on;
# 开启目录列表访问,合适下载服务器,默认关闭。
autoindex on;
# 此选项允许或禁止使用socke的TCP_CORK的选项,此选项仅在使用sendfile的时候使用
tcp_nopush on;
tcp_nodelay on;
# 长连接超时时间,单位是秒
keepalive_timeout 120;
# FastCGI相关参数是为了改善网站的性能:减少资源占用,提高访问速度。下面参数看字面意思都能理解。
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;
# gzip模块设置
gzip on; # 开启gzip压缩输出
gzip_min_length 1k; # 最小压缩文件大小
gzip_buffers 4 16k; # 压缩缓冲区
gzip_http_version 1.0; # 压缩版本(默认1.1,前端如果是squid2.5请使用1.0)
gzip_comp_level 2; # 压缩等级
gzip_types text/plain application/x-javascript text/css application/xml; # 压缩类型,默认就已经包含textml,所以下面就不用再写了,写上去也不会有问题,但是会有一个warn。
gzip_vary on;
# 开启限制IP连接数的时候需要使用
# limit_zone crawler $binary_remote_addr 10m;
# 负载均衡配置
upstream jh.w3cschool.cn {
# upstream的负载均衡,weight是权重,可以根据机器配置定义权重。weigth参数表示权值,权值越高被分配到的几率越大。
server 192.168.80.121:80 weight=3;
server 192.168.80.122:80 weight=2;
server 192.168.80.123:80 weight=3;
# nginx的upstream目前支持4种方式的分配
# 1、轮询(默认)
# 每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。
# 2、weight
# 指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。
# 例如:
# upstream bakend {
# server 192.168.0.14 weight=10;
# server 192.168.0.15 weight=10;
# }
# 2、ip_hash
# 每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
# 例如:
# upstream bakend {
# ip_hash;
# server 192.168.0.14:88;
# server 192.168.0.15:80;
# }
# 3、fair(第三方)
# 按后端服务器的响应时间来分配请求,响应时间短的优先分配。
# upstream backend {
# server server1;
# server server2;
# fair;
# }
# 4、url_hash(第三方)
# 按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。
# 例:在upstream中加入hash语句,server语句中不能写入weight等其他的参数,hash_method是使用的hash算法
# upstream backend {
# server squid1:3128;
# server squid2:3128;
# hash $request_uri;
# hash_method crc32;
# }
# tips:
# upstream bakend{#定义负载均衡设备的Ip及设备状态}{
# ip_hash;
# server 127.0.0.1:9090 down;
# server 127.0.0.1:8080 weight=2;
# server 127.0.0.1:6060;
# server 127.0.0.1:7070 backup;
# }
# 在需要使用负载均衡的server中增加 proxy_pass http://bakend/;
# 每个设备的状态设置为:
# 1.down表示单前的server暂时不参与负载
# 2.weight为weight越大,负载的权重就越大。
# 3.max_fails:允许请求失败的次数默认为1.当超过最大次数时,返回proxy_next_upstream模块定义的错误
# 4.fail_timeout:max_fails次失败后,暂停的时间。
# 5.backup: 其它所有的非backup机器down或者忙的时候,请求backup机器。所以这台机器压力会最轻。
# nginx支持同时设置多组的负载均衡,用来给不用的server来使用。
# client_body_in_file_only设置为On 可以讲client post过来的数据记录到文件中用来做debug
# client_body_temp_path设置记录文件的目录 可以设置最多3层目录
# location对URL进行匹配.可以进行重定向或者进行新的代理 负载均衡
}
# 虚拟主机的配置
server
{
# 监听端口
listen 80;
# 域名可以有多个,用空格隔开
server_name www.w3cschool.cn w3cschool.cn;
index index.html index.htm index.php;
root /data/www/w3cschool;
# 对******进行负载均衡
location ~ .*.(php|php5)?$
{
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi.conf;
}
# 图片缓存时间设置
location ~ .*.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 10d;
}
# JS和CSS缓存时间设置
location ~ .*.(js|css)?$
{
expires 1h;
}
# 日志格式设定
# $remote_addr与$http_x_forwarded_for用以记录客户端的ip地址;
# $remote_user:用来记录客户端用户名称;
# $time_local: 用来记录访问时间与时区;
# $request: 用来记录请求的url与http协议;
# $status: 用来记录请求状态;成功是200,
# $body_bytes_sent :记录发送给客户端文件主体内容大小;
# $http_referer:用来记录从那个页面链接访问过来的;
# $http_user_agent:记录客户浏览器的相关信息;
# 通常web服务器放在反向代理的后面,这样就不能获取到客户的IP地址了,通过$remote_add拿到的IP地址是反向代理服务器的iP地址。反向代理服务器在转发请求的http头信息中,可以增加x_forwarded_for信息,用以记录原有客户端的IP地址和原来客户端的请求的服务器地址。
log_format access '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" $http_x_forwarded_for';
# 定义本虚拟主机的访问日志
access_log /usr/local/nginx/logs/host.access.log main;
access_log /usr/local/nginx/logs/host.access.404.log log404;
# 对 "/" 启用反向代理
location / {
proxy_pass http://127.0.0.1:88;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
# 后端的Web服务器可以通过X-Forwarded-For获取用户真实IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 以下是一些反向代理的配置,可选。
proxy_set_header Host $host;
# 允许客户端请求的最大单文件字节数
client_max_body_size 10m;
# 缓冲区代理缓冲用户端请求的最大字节数,
# 如果把它设置为比较大的数值,例如256k,那么,无论使用firefox还是IE浏览器,来提交任意小于256k的图片,都很正常。如果注释该指令,使用默认的client_body_buffer_size设置,也就是操作系统页面大小的两倍,8k或者16k,问题就出现了。
# 无论使用firefox4.0还是IE8.0,提交一个比较大,200k左右的图片,都返回500 Internal Server Error错误
client_body_buffer_size 128k;
# 表示使nginx阻止HTTP应答代码为400或者更高的应答。
proxy_intercept_errors on;
# 后端服务器连接的超时时间_发起握手等候响应超时时间
# nginx跟后端服务器连接超时时间(代理连接超时)
proxy_connect_timeout 90;
# 后端服务器数据回传时间(代理发送超时)
# 后端服务器数据回传时间_就是在规定时间之内后端服务器必须传完所有的数据
proxy_send_timeout 90;
# 连接成功后,后端服务器响应时间(代理接收超时)
# 连接成功后_等候后端服务器响应时间_其实已经进入后端的排队之中等候处理(也可以说是后端服务器处理请求的时间)
proxy_read_timeout 90;
# 设置代理服务器(nginx)保存用户头信息的缓冲区大小
# 设置从被代理服务器读取的第一部分应答的缓冲区大小,通常情况下这部分应答中包含一个小的应答头,默认情况下这个值的大小为指令proxy_buffers中指定的一个缓冲区的大小,不过可以将其设置为更小
proxy_buffer_size 4k;
# proxy_buffers缓冲区,网页平均在32k以下的设置
# 设置用于读取应答(来自被代理服务器)的缓冲区数目和大小,默认情况也为分页大小,根据操作系统的不同可能是4k或者8k
proxy_buffers 4 32k;
# 高负荷下缓冲大小(proxy_buffers*2)
proxy_busy_buffers_size 64k;
# 设置在写入proxy_temp_path时数据的大小,预防一个工作进程在传递文件时阻塞太长
# 设定缓存文件夹大小,大于这个值,将从upstream服务器传
proxy_temp_file_write_size 64k;
}
# 设定查看Nginx状态的地址
location /NginxStatus {
stub_status on;
access_log on;
auth_basic "NginxStatus";
auth_basic_user_file confpasswd;
# htpasswd文件的内容可以用apache提供的htpasswd工具来产生。
}
# 本地动静分离反向代理配置
# 所有jsp的页面均交由tomcat或resin处理
location ~ .(jsp|jspx|do)?$ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:8080;
}
# 所有静态文件由nginx直接读取不经过tomcat或resin
location ~ .*.(htm|html|gif|jpg|jpeg|png|bmp|swf|ioc|rar|zip|txt|flv|mid|doc|ppt|
pdf|xls|mp3|wma)$
{
expires 15d;
}
location ~ .*.(js|css)?$
{
expires 1h;
}
}
}
######Nginx配置文件nginx.conf中文详解#####
配置详解参考:https://www.cnblogs.com/54chensongxia/p/12938929.html
大佬文章推荐:https://zhuanlan.zhihu.com/p/34943332 https://www.cnblogs.com/48xz/p/15781821.html https://zhuanlan.zhihu.com/p/364588916 https://kb.cnblogs.com/page/661047/