Nginx 是一款高性能的开源 Web 服务器软件,也可以用作反向代理服务器、负载均衡器和 HTTP 缓存服务器。由 Igor Sysoev 于 2002 年创建,2004年公开,并且在开源社区得到广泛的支持和贡献。
Nginx 的设计目标是解决 C10K(Concurrency 10,000) 问题,即同时处理成千上万个并发连接的能力。相比传统的Web服务器,如 Apache,Nginx 使用了异步非阻塞的事件驱动架构,更高效地处理大量的并发请求,提供更快的响应速度和更低的资源消耗。
以下是 Nginx 的一些主要特点:
总之,Nginx 是一个高性能、可靠稳定的 Web 服务器软件,适用于处理大量并发连接和高流量的场景。无论是作为一个独立的 Web 服务器,还是配合其他服务一起工作,Nginx 都是一个非常强大和有价值的工具。
下载地址:https://nginx.org/en/download.html
先下载源码
curl -O http://nginx.org/download/nginx-1.24.0.tar.gz
解压
tar -zxvf nginx-1.24.0.tar.gz
在编译之前,需要确保系统中已安装了一些必要的依赖项,如gcc编译器、PCRE库(用于支持正则表达式)、zlib库(用于支持HTTP压缩)和OpenSSL库(用于支持SSL加密)。可以通过包管理器来安装这些依赖项,例如在Centos上可以使用yum命令:
yum install -y gcc-c++
yum install -y gcc automake autoconf libtool make
yum install -y pcre pcre-devel
yum install -y zlib zlib-devel
yum install -y openssl openssl-devel
配置configure
./configure --prefix=/usr/local/nginx --with-pcre --with-zlib --with-openssl
编译make安装
make && make install
先下载好第三方源码,解压,重新配置nginx,编译
./configure --prefix=/usr/local/nginx --add-module=/path/to/module
一个 Nginx 配置文件的结构就像 nginx.conf
显示的那样,配置文件的语法规则如下:
;
分号结尾,指令与参数间以空格符号分隔{}
大括号将多条指令组织在一起include
语句允许组合多个配置文件以提升可维护性#
符号添加注释,提高可读性$
符号使用变量所有指令文档查询:https://nginx.org/en/docs/dirindex.html
官方文档:https://nginx.org/en/docs/http/ngx_http_core_module.html#location
location 后面可以跟下面几种符号,再跟前缀字符串或正则表达式
=
精确匹配路径,后面跟不含正则表达式的 uri ,如果匹配成功,不再进行后续的查找~
正则匹配路径,后面跟正则,区分大小写~*
正则匹配路径,后面跟正则,不区分大小写^~
前缀匹配 uri,后面跟前缀字符串,这是默认匹配项location 配置优先级文档:https://docs.nginx.com/nginx/admin-guide/web-server/web-server/#location_priority
=
定义了 URI 和前缀字符串的精确匹配。如果找到了精确的匹配项,则搜索将停止^~
放在最长匹配前缀字符串的前面,则不检查正则表达式示例
server {
listen 8081;
server_name localhost;
location /i/ {
root html;
}
location /i/js {
root html/js;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
访问http://localhost:8081/i/js/js.html
, 前缀匹配最长的,对应 windows 文件夹路径 html\js\i\js\js.html
配置文件包含以下几块:
全局块
配置影响nginx全局的指令。一般有运行nginx服务器的用户组,nginx进程pid存放路径,日志存放路径,配置文件引入,允许生成worker process数等。
指令名 | 语法 | 默认值 | 说明 |
---|---|---|---|
daemon | daemon on | off; | daemon on; | 是否成为一个守护进程 |
debug_points | debug_points abort | stop; | 用于debug, 当检测到内部错误时,核心文件的创建中止(abort )或停止进程(stop) | |
env | env variable[=value]; | env TZ; | 环境变量 |
error_log | error_log file [level]; | error_log logs/error.log error; | 配置日志 |
lock_file | lock_file file | lock_file logs/nginx.lock; | 锁文件位置 |
master_process | master_process on | off; | master_process on; | 确定是否已启动工作进程。本指令适用于nginx开发人员 |
pcre_jit | pcre_jit on | off; | pcre_jit off; | 1.1.12新增,启用或禁用对配置解析时已知的正则表达式使用“即时编译” |
pid | pid file; | pid logs/nginx.pid; | pid 文件位置 |
ssl_engine | ssl_engine device; | 定义硬件SSL加速器的名称 | |
thread_pool | thread_pool name threads=number [max_queue=number]; | thread_pool default threads=32 max_queue=65536; | 1.7.11新增,定义线程池的名称和参数,用于多线程读取和发送文件,而不阻塞工作进程。 |
timer_resolution | timer_resolution interval; | 降低工作进程中的计时器频率,从而减少每天进行系统调用的次数。 | |
user | user user [group]; | user nobody nobody; | 定义工作进程使用的用户和组。 |
worker_cpu_affinity | worker_cpu_affinity cpumask …; worker_cpu_affinity auto [cpumask]; |
将工作进程绑定到cpu中,1.9.10新增auto,可自动绑定。指令只在FreeBSD和 Linux可用 | |
worker_priority | worker_priority number; | worker_priority 0; | 定义工作进程的调度优先级,负数意味着更高的优先级。允许的范围通常从-20到20 |
worker_processes | worker_processes number | auto; | worker_processes 1; | 定义工作进程的数量,auto从1.3.8和 1.2.5开始支持 |
worker_rlimit_core | worker_rlimit_core size; | 更改工作进程的核心文件(RLIMIT_CORE)的限制。用于增加限制,而不重新启动主进程。 | |
worker_rlimit_nofile | worker_rlimit_nofile number; | 更改对工作进程的最大打开文件数量(RLIMIT_NOFILE)的限制。用于增加限制,而不重新启动主进程。 | |
worker_shutdown_timeout | worker_shutdown_timeout time; | 1.11.11新增,为工作进程的正常关闭配置了一个超时时间。当时间到期时,nginx将尝试关闭当前打开的所有连接,以方便关闭, | |
working_directory | working_directory directory; | 定义工作进程的当前工作目录。它主要用于写入核心文件时,在这种情况下,工作进程应该具有对指定目录的写权限 |
events块
配置影响nginx服务器或与用户的网络连接。有是否允许同时接受多个网路连接,选取哪种事件驱动模型处理连接请求,,每个进程的最大连接数,开启多个网络连接序列化等
常用指令
指令名 | 语法 | 默认值 | 说明 |
---|---|---|---|
multi_accept | multi_accept on | off; | multi_accept off; | 如果为off,则一个工作进程将一次接受一个新的连接。否则一次接受所有新的连接。 |
use | use method; | 指定要使用的连接处理方法。通常不需要显式地指定它,因为nginx将默认使用最有效的方法。 | |
worker_aio_requests | worker_aio_requests number; | worker_aio_requests 32; | 当使用aio和epoll 时,为单个工作进程设置未完成的异步I/O操作的最大数量。 |
worker_connections | worker_connections number; | worker_connections 512; | 设置工作进程可以打开的最大同时连接数。不能超过当前对最大打开文件数量的限制. |
http块
可以嵌套多个server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置。如文件引入,mime-type定义,日志自定义,是否使用sendfile传输文件,连接超时时间,单连接请求数等。
文档:https://nginx.org/en/docs/http/ngx_http_core_module.html
常用指令
指令名 | 文档地址 | 默认值 | 说明 |
---|---|---|---|
default_type | defulat_type | default_type text/plain; | 默认相应类型 |
error_page | error_page | 定义将为指定的错误显示的URI。uri值可以包含一些变量。 | |
include | include | 在配置中包含另一个文件,或与指定的掩码相匹配的文件 |
server块
配置虚拟主机的相关参数,一个http中可以有多个server。
常用指令
指令名 | 文档地址 | 默认值 | 说明 |
---|---|---|---|
listen | listen | listen *:80 | *:8000; | 监听端口 |
location | location | 设置uri匹配 | |
server_name | server_name | server_name “”; | 设置虚拟服务器的名称 |
location块
配置请求的路由,以及各种页面的处理情况。
文档:https://nginx.org/en/docs/http/ngx_http_core_module.html#location
常用指令
指令名 | 语法 | 默认值 | 说明 |
---|---|---|---|
alias | alias path; | ||
error_page | error_page code … [=[response]] uri; | ||
proxy_pass | proxy_pass URL; | 设置代理服务器的协议和地址,以及位置应该映射到的可选URI | |
root | root path; | root html; | |
try_files | try_files file … uri; try_files file … =code; |
检查按指定顺序排列的文件是否存在,并使用第一个找到的文件进行请求处理 |
官方文档:https://nginx.org/en/docs/http/ngx_http_core_module.html#variables
下面是一些常用的全局变量:
全局变量名 | 功能 |
---|---|
$args |
请求中的参数 |
$body_bytes_sent |
客户端发送的字节数 |
$content_length |
请求头中的 Content-length 字段 |
$host |
请求头中的 Host ,如果请求中没有 Host 行,则等于设置的服务器名,不包含端口 |
$http_cookie |
客户端cookie信息 |
$http_referer |
对应请求头的referer |
$http_user_agent |
客户端agent信息 |
$http_x_forwarded_for |
请求头的x-forwarded-for |
$request |
请求的URL与HTTP协议(如GET /index HTTP/1.0 ) |
$request_method |
客户端请求类型(如 GET 、POST ) |
$remote_addr |
客户端的 IP 地址 |
$remote_user |
客户端用户的名称 |
$remote_port |
客户端的端口 |
$server_protocol |
请求使用的协议(如 HTTP/1.0 、HTTP/1.1 ) |
$server_addr |
服务器地址 |
$server_name |
服务器名称 |
$server_port |
服务器的端口号 |
$scheme |
HTTP 方法(如http, https) |
$status |
HTTP响应代码(如 200, 404) |
$uri |
请求 uri |
默认配置
# 可以使用的 worker 进程数
worker_processes 1;
# 全局错误日志定义类型,[ debug | info | notice | warn | error | crit ]
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
events {
# 单个进程最大连接数(最大连接数=连接数*进程数)
worker_connections 1024;
# 事件模型,use [ kqueue | rtsig | epoll | /dev/poll | select | poll ]
# Linux 2.6以上版本内核中的高性能网络I/O模型,linux建议epoll,如果跑在FreeBSD上面,就用kqueue模型。
# use epoll;
}
http {
include mime.types;
# 默认文件类型, 未指定默认 text/plain; 当文件类型未定义时使用这种方式
default_type application/octet-stream;
# 零拷贝,开启文件高效传输模式
sendfile on;
# 连接超时时间
keepalive_timeout 65;
# 编码
# charset utf-8;
server {
# 监听端口
listen 80;
# 主机域名
server_name localhost;
# 配置请求的路由,以及各种页面的处理情况。
location / {
# 网站根目录
root html;
# 默认首页文件
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
官方文档:https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/
关于正向代理与反向代理
两者区别就是正向代理,客户端是知道的,而反向代理,客户端是感知不到的
server {
listen 80;
location /api2/ {
proxy_pass http://localhost:8080/;
}
location /api3/ {
proxy_pass http://localhost:8081/;
}
location / {
proxy_pass http://localhost:8082/;
}
}
当访问http://localhost/api2/index.html时,反向代理访问 http://localhost:8080/index.html,注意8080后面的/,如果不加,那就访问http://localhost:8080/api2/index.html
开启压缩能够将传输的数据的大小减少一半甚至更多,减少带宽消耗
官方文档:http://nginx.org/en/docs/http/ngx_http_gzip_module.html
http{
# 开启压缩
gzip on;
# 除 text/html 外,还可以指定被压缩的文件类型
gzip_types text/plain application/javascript text/css application/xml text/javascript image/jpeg image/gif image/png;
# 设置压缩级别,越高资源消耗越大,但压缩效果越好,范围从1到9,默认为1
gzip_comp_level 5;
# 在头部中添加Vary: Accept-Encoding(建议开启)
gzip_vary on;
# 处理压缩请求的缓冲区数量和大小,默认值 32 4k|16 8k;具体取决于平台
gzip_buffers 16 8k;
# 对于不支持压缩功能的客户端请求不开启压缩机制
gzip_disable "MSIE [1-6]\."; # 低版本的IE浏览器不支持压缩
# 设置压缩响应所支持的HTTP最低版本,默认1.1
gzip_http_version 1.1;
# 设置触发压缩的最小阈值,默认20, 长度从Content-Length获取
gzip_min_length 2k;
# 关闭对后端服务器的响应结果进行压缩
gzip_proxied off;
}
官方文档:https://docs.nginx.com/nginx/admin-guide/load-balancer/http-load-balancer/
负载均衡类型:
upstream backend{
# least_conn;
# ip_hash;
# hash $request_uri consistent;
# random two least_time=last_byte;
server localhost:8080 weight=3 max_fails=2 fail_timeout=30s;
server localhost:8081 weight=1 max_fails=2 fail_timeout=30s;
server localhost:8082 backup;
}
server {
listen 80;
location / {
proxy_pass http://backend;
}
}
需要生成ssl证书
server {
listen 443 ssl;
server_name localhost;
ssl_certificate /usr/local/nginx/ssl/demo.crt;
ssl_certificate_key /usr/local/nginx/ssl/demo.key;
location / {
root html;
index index.html index.htm;
}
}
可以通过rewrite url实现页面跳转,参数隐藏等功能
文档:http://nginx.org/en/docs/http/ngx_http_rewrite_module.html
参数隐藏
location / {
# 将类似 1.html 替换为 index?page=1
rewrite ^/([0-9]+).html$ /index?page=$1 break;
proxy_pass http://localhost:8081;
}
旧域名跳转到新域名
server {
listen 80;
server_name www.a.com;
location = / {
if ($host = "www.a.com") {
rewrite ^/(.*)$ http://www.b.com/$1 permanent;
}
}
}
valid_referers 相关文档:http://nginx.org/en/docs/http/ngx_http_referer_module.html
location ~* \.(gif|jpg|jpeg|png|bmp|swf)$ {
valid_referers none blocked server_names ~\.google\. ~\.baidu\. *.qq.com;
if ($invalid_referer){
return 403;
}
}
以下是两种方案:
反向代理
proxy_cookie_domain文档:http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cookie_domain
location ^~/apis/ {
rewrite ^/apis/(.*)$ /$1 break;
proxy_pass a.demo.com;
# 两个域名之间cookie的传递与回写
proxy_cookie_domain a.demo.com b.demo.com;
}
Header头添加
server {
listen 80;
server_name localhost;
add_header 'Access-Control-Allow-Origin' $http_origin; # 全局变量获得当前请求origin,带cookie的请求不支持*
add_header 'Access-Control-Allow-Credentials' 'true'; # 为 true 可带上 cookie
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; # 允许请求方法
add_header 'Access-Control-Allow-Headers' $http_access_control_request_headers; # 允许请求的 header,可以为 *
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000; # OPTIONS 请求的有效期,在有效期内不用发出另一条预检请求
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204; # 200 也可以
}
location / {
root html;
index index.html;
}
}
文档:http://nginx.org/en/docs/http/ngx_http_autoindex_module.html
server {
listen 80;
server_name localhost;
charset utf-8;
location /download {
alias html/static; # 静态资源目录
autoindex on; # 开启静态资源列目录
autoindex_exact_size off; # on(默认)显示文件的确切大小,单位是byte;off显示文件大概大小,单位KB、MB、GB
autoindex_localtime off; # off(默认)时显示的文件时间为GMT时间;on显示的文件时间为服务器时间
}
}
通过user agent 控制访问不同网页
server {
listen 80;
server_name localhost;
location / {
root html/pc;
if ($http_user_agent ~* '(Android|webOS|iPhone|iPod|BlackBerry)') {
root html/mobile;
}
index index.html;
}
}
控制访问:https://docs.nginx.com/nginx/admin-guide/security-controls/controlling-access-proxied-tcp/
指令是从上到下依次执行的:如果指令序列中的第一个指令拒绝了所有,那么所有下一步允许的指令都没有效果
location / {
# 允许访问
allow 192.168.0.2;
# 禁止访问
deny all;
}
expires文档:http://nginx.org/en/docs/http/ngx_http_headers_module.html#expires
location ~ .*\.(css|js|jpg|png|gif|swf|woff|woff2|eot|svg|ttf|otf|mp3|m4a|aac|txt)$ {
expires 10d;
}