nginx超级版
前言
nginx,功能很强大,除了单纯做负载还有很多其它的功能
- 静态文件服务:nginx可以快速、高效地提供静态文件的服务,例如HTML、CSS、JavaScript和图像等,通过将文件直接发送到客户端,大大提高了响应速度和服务器负载能力
- 反向代理:nginx作为反向代理服务器,可以将客户端的请求转发到后端的多个服务器,实现负载均衡,提高系统的处理能力和可靠性
- 虚拟主机支持:nginx可以支持多个域名(虚拟主机)的服务,通过配置不同的域名和目录路径,将客户端的请求分发到不同的网站或应用程序
- SSL/TLS支持:nginx可以配置和管理SSL/TLS协议,提供安全的HTTPS服务,保护客户端和服务器之间的数据传输的安全性
- 缓存加速:nginx可以作为反向代理服务器对请求的资源进行缓存,当客户端再次请求该资源时,可以直接返回缓存中的数据,提高访问速度和分享服务器负载
- 安全防护:nginx提供了一些安全特性,例如访问控制、IP黑名单、防止DDoS攻击等,保护服务器免受恶意请求和攻击
- nginx还具有很多更高级的功能和配置选项,包括gzip压缩、HTTP/2协议支持、缓存策略和负载均衡等
下面是介绍一下它的情况和其它功能,结合案例操作,需要就直接cv。参考文章:[文章1],[文章2],[文章3],[文章4]
正文
1. 全局块
- 该部分配置主要影响Nginx全局,通常包括下面几个部分:
- 配置运行Nginx服务器用户(组)
- worker process数
- Nginx进程PID存放路径
- 错误日志的存放路径
- 配置文件的引入
2. events块
- 该部分配置主要影响Nginx服务器与用户的网络连接,主要包括:
- 设置网络连接的序列化
- 是否允许同时接收多个网络连接
- 事件驱动模型的选择
- 最大连接数的配置
3. http块
- 定义MIMI-Type
- 自定义服务日志
- 允许sendfile方式传输文件
- 连接超时时间
- 单连接请求数上限
4. server块
- 配置网络监听
- 基于名称的虚拟主机配置
- 基于IP的虚拟主机配置
5. location块
- location配置
- 请求根目录配置
- 更改location的URI
- 网站默认首页配置
介绍
先来介绍一些基本概念,需要直接cv的看下面一小节:
Nginx 的进程模型:
内部结构:一个 Master 进程、多个 Worker 进程
- Master 进程:管理 Worker 进程。对外接口:接收外部的操作(信号);对内转发:根据外部的操作的不同,通过信号管理 Worker;监控:监控 Worker 进程的运行状态,Worker 进程异常终止后,自动重启 Worker 进程
- Worker 进程:所有 Worker 进程都是平等的。实际处理:网络请求,由 Worker 进程处理。Worker 进程数量:在 nginx.conf 中配置,一般设置为电脑核心数,充分利用 CPU 资源,同时,避免进程数量过多,避免进程竞争 CPU 资源,增加上下文切换的损耗
- 请求的完整过程:建立连接→读取请求→解析请求→处理请求→响应请求
- 请求的完整过程对应到底层就是:读写 Socket 事件
Nginx 为什么拥有高性能并且能够支撑高并发?
1. 采用Epoll 模型: 这是一种IO 多路复用模型,它允许单个进程同时监视多个文件描述符(例如网络套接字)以进行读取或写入操作,而无需阻塞其他的进程,EPoll 的优点是,使用了事件驱动的方式,只有在有事件发生时才会进行处理,从而避免了传统的轮询方式带来的性能浪费。nginx下是如何运行该模型的:
- 步骤一:创建 epoll 文件描述符:nginx 在启动时会初始化一个 epoll 实例,创建一个 epoll 文件描述符
- 步骤二:注册需要监视的事件:nginx 将要监听的套接字(例如客户端连接)添加到 epoll 实例中,以便在有事件发生时得到通知
- 步骤三:等待事件发生:nginx 通过调用 epoll_wait() 函数等待事件的发生。这将导致 nginx 进程阻塞,直到有事件发生为止
- 步骤四:处理发生的事件:一旦有事件发生,epoll_wait() 函数将返回发生事件的套接字的列表。nginx 将对这些套接字进行处理,例如接受客户端的连接或读取/写入数据
- 步骤五:重复以上步骤:nginx 在一个循环中不断重复以上步骤,以服务多个并发连接
2. 多进程/线程支持:Nginx使用多进程或多线程的方式处理请求,每个进程/线程都可以处理多个并发连接,从而提供更高的并发处理能力
3. 轻量级设计:Nginx的设计目标就是追求轻量级和高效率,它的核心代码非常精简,因此,本身条件就可以支持更大的请求处理
Nginx 最大连接数
连接数是根据具体参数配置决定,Nginx 是多进程模型,上文说到一个master管理多个worker,是worker去处理请求,而每个worker可以处理多个进程,所以答案显而易见:
Worker 的数量:worker_processes(默认值是自动根据系统的 CPU 核数来决定)
单个 Worker 进程的最大连接数:worker_connections(默认值是 512)
Nginx 的最大连接数:Worker 进程数量 x 单个 Worker 进程的最大连接数
上面是 Nginx 作为通用服务器时,最大的连接数
Nginx 作为反向代理服务器时,能够服务的最大连接数:(Worker 进程数量 x 单个 Worker 进程的最大连接数)/ 2
Nginx 反向代理时,会建立 Client 的连接和后端 Web Server 的连接,占用 2 个连接
常用命令
nginx -v #nginx 版本信息
nginx #启动 nginx
nginx -c /usr/local/nginx/conf/nginx.conf #指定配置文件启动
nginx -s stop #停止 nginx
nginx -s reload #重新加载配置文件
nginx -s reopen #重启 Nginx
nginx -t #检查 nginx 配置文件的语法是否正确
nginx -T #显示 nginx 所有工作进程的状态信息,就相当于把nginx.conf文件内容输出展示一遍
cv大法
nginx.conf
// 全局配置,该部分配置主要影响Nginx全局
#指定可以运行Nginx服务器的用户和用户组,如果user指令不配置或者配置为 user nobody nobody ,则默认所有用户都可以启动Nginx进程
user www www;
#上文讲到过的工作进程(worker)的数量,建议设置为CPU核心的个数,如果设置为auto,Nginx进程将自动检测
worker_processes auto;
# 错误日志的位置
error_log /www/xxx/nginx_error.log ;
#指定nginx进程的pid文件的路径。pid文件记录了nginx主进程的进程ID,它的作用是为系统管理工具提供一种方式来跟踪nginx进程的状态和管理
pid /www/xxx/xxx/nginx.pid;
#配置每个进程(worker)的连接数,默认512
worker_rlimit_nofile 51200;
// events块配置,主要影响Nginx服务器与用户的网络连接
events
{
#事件驱动模型的选择:model模型可选择项包括:select、poll、kqueue、epoll、rtsig等
use epoll;
#设置每个工作进程(worker)可以同时打开的最大连接数。默认值为512
worker_connections 51200;
#用于控制并发连接的处理,默认on。它允许服务器在接受新连接之前使用互斥锁来阻塞其他工作进程,可以这么理解:
#当一个新网络连接来到时,多个worker进程会被同时唤醒,但仅仅只有一个进程可以真正获得连接并处理之。如果每次唤醒的进程数目过多的话,其实是会影响一部分性能的。所以在这里,如果acceptmutex on,那么多个worker将是以串行方式来处理,其中有一个worker会被唤醒;反之若acceptmutex off,那么所有的worker都会被唤醒,不过只有一个worker能获取新连接,其它的worker会重新进入休眠状态
accept_mutex on;
#是否允许同时接收多个网络连接,该指令默认为off状态,意指每个worker_process 一次只能接收一个新到达的网络连接。若想让每个Nginx的worker process都有能力同时接收多个网络连接,则需要开启此配置
multi_accept on;
}
// http块,配置全局的HTTP属性
http
{
#该指令主要用于将其他的Nginx配置或者第三方模块的配置引用到当前的主配置文件中;mime.types是网络资源的媒体类型,也即前端请求的资源类型
include mime.types;
#设置代理缓存临时文件的存放路径
proxy_temp_path /www/server/nginx/proxy_temp_dir;
#以下是一些与后台服务器连接间的一些参数配置
client_body_buffer_size 512k;
proxy_connect_timeout 60;
proxy_read_timeout 60;
proxy_send_timeout 60;
proxy_buffer_size 32k;
proxy_buffers 4 64k;
proxy_busy_buffers_size 128k;
proxy_temp_file_write_size 128k;
proxy_next_upstream error timeout invalid_header http_500 http_503 http_404;
#是否开启/关闭访问日志的记录功能,on开始,off关闭
access_log on;
#可以详细记录与Nginx服务器的访问日志,这个配置可以写在http块中,server块中,location中,就能分别记录每个模块的访问情况。路径自定义
#在路径后还有很多参数可以配置,combined这个就是配置日志格式。combined:这是默认的日志格式,它包含了大量的信息,包括请求的IP地址、请求的时间、请求的方法和URL、返回的状态码、发送的字节数等,main:这是简化版的日志格式,它仅包含请求的IP地址、请求的时间、请求的方法和URL、返回的状态码,json:这是一种将日志以 JSON 格式记录的选项,它可以方便地进行日志分析和数据处理;
#还有一种是custom:这是一种自定义的日志格式,你可以根据自己的需求,选择需要记录的具体信息。你可以使用预定义的变量来组合成自定义格式,例如$remote_addr代表远程客户端IP地址,$http_user_agent代表客户端的用户代理字符串,等等
access_log /www/wwwlogs/log/access.log combined;
default_type application/octet-stream;
server_names_hash_bucket_size 512;
client_header_buffer_size 32k;
large_client_header_buffers 4 32k;
client_max_body_size 50m;
#控制是否启用操作系统的零拷贝机制的。零拷贝机制可以提高文件传输的效率和性能
#sendfile配置为on时,Nginx会使用操作系统提供的sendfile系统调用来直接从磁盘读取文件,并将文件内容直接发送到网络套接字,而不需要先将文件内容复制到用户空间缓冲区,再发送给客户端。这样可以避免不必要的内存操作,提高文件传输性能。当sendfile配置为off时,Nginx将会使用普通的read/write系统调用来完成文件传输,即将文件内容读取到用户空间缓冲区,再将缓冲区的内容发送给客户端。这种方式会增加数据拷贝的开销,但在某些情况下可能更可靠
sendfile on;
tcp_nopush on;
tcp_nodelay on;
#配置用于设置HTTP keep-alive连接的超时时间,60秒内没有活动时连接将被关闭
keepalive_timeout 60;
#用于定义在保持连接状态的情况下允许的最大请求数量。当一个用户在连接状态中的请求次数超过了这个配置值,将会关闭该连接,防止长时间持续的连接,以避免资源浪费和可能的安全问题。同时,它也可以用来限制来自单个客户端的请求次数,以保护服务器免受过多负载或恶意攻击
keepalive_requests 75;
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 256k;
fastcgi_intercept_errors on;
#配置Nginx服务器的gzip压缩功能的。gzip压缩可以减小传输的数据量,提高网站的加载速度,减少网络带宽的消耗
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.1;
gzip_comp_level 2;
gzip_types text/plain application/javascript application/x-javascript text/javascript text/css application/xml;
gzip_vary on;
gzip_proxied expired no-cache no-store private auth;
gzip_disable "MSIE [1-6]\.";
limit_conn_zone $binary_remote_addr zone=perip:10m;
limit_conn_zone $server_name zone=perserver:10m;
#用于控制服务器返回的响应头中的版本信息。默认情况下,Nginx会将服务器软件的版本信息包含在响应头中,以便客户端可以知道服务器的具体版本
server_tokens off;
//这个server块是宝塔自动配的,因为我是通过宝塔安装的这些中间件,可不用理会
server
{
listen 888;
server_name phpmyadmin;
index index.html index.htm index.php;
root /www/server/phpmyadmin;
#error_page 404 /404.html;
include enable-php.conf;
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;
}
location ~ .*\.(js|css)?$
{
expires 12h;
}
location ~ /\.
{
deny all;
}
access_log /www/wwwlogs/access.log;
}
#该指令主要用于将其他的Nginx配置或者第三方模块的配置引用到当前的主配置文件中,这里为了不混淆原本的配置,就把负载配置重新另起一份
include /www/server/panel/vhost/nginx/halo.conf;
#配置黑名单(方式二), 方式一在下面, http 块中配置一个map 指令块, 里面包含一个专门放ip的文件 ,就是创建一个名为 blacklist.conf 的文件,并将要阻止的IP地址添加到文件中。每个IP地址应位于单独的一行。示例内容如下:然后在server或location块中使用
#0.0.0.0;
#1.2.3.4;
#10.0.0.0/24;
map $remote_addr $is_blacklisted {
include /path/to/blacklist.conf;
}
}
halo.conf(普通版)
案列一(附黑名单功能):
访问路径: 192.x.x.x:9000/example1 或 192.x.x.x:9000/example2 分别会代理到 127.0.0.1:5000 和 127.0.0.1:8080
访问路径: 192.x.x.x:9000/example3 的时候,nginx将会将请求映射到/path/to/your/directory/路径上的文件, 其中的配置效果如下,当访问"/example3"路径时,nginx会将请求映射到"/path/to/your/directory/"目录。如果请求的是一个目录,nginx会生成目录列表。如果请求的是一个文件,nginx会尝试返回文件内容。如果文件是二进制文件(如bin、exe或dll),浏览器会将其下载,而不是在浏览器中展示
#Server块用于配置虚拟主机,可以在一个http块中包含多个server块。每个server块表示一个网站或虚拟主机
server {
listen 9000; #监听端口
server_name 192.x.x.x; #监听地址
#配置黑名单(方式一): 可以配置在server块,也可以配置location块, 粒度不同
deny 123.1.1.0; # 将123.1.1.0替换为你想要禁止的IP地址
deny 987.1.1.0; # 添加更多的deny语句来禁止其他IP地址
allow all; # 允许其他IP地址访问
#配置黑名单(方式二)
if ($is_blacklisted) {
return 403;
}
#根据在浏览器输入的路径不同,跳转到不同端口的服务中
# ~ : 表示uri包含正则表达式,且区分大小写。
# ~* : 表示uri包含正则表达式,且不区分大小写。
# = : 表示uri不含正则表达式,要求严格匹配。
location ~ /example1 / {
proxy_pass http://127.0.0.1:5000;
}
location ~ /example2/ {
proxy_pass http://127.0.0.1:8080;
}
location ~ /example3/ {
#alias是一种用于将请求映射到服务器文件系统中的特定路径的配置指令。它允许你在URL中使用不同的路径来访问服务器上的文件,可以配置相关参数来决定访问时的效果
alias /path/to/your/directory/;
autoindex on; # 启用目录列表功能
try_files $uri $uri/ =404; # 尝试访问文件或目录,如果不存在则返回404错误
add_header Content-Disposition inline; # 强制浏览器内联显示资源
types { # 设置资源类型
application/octet-stream bin exe dll; # 设置二进制文件为下载
}
}
}
案例二(附缓存功能):
访问路径192.x.x.x:9000 会被代理负载到127.0.0.1:8888 和 127.0.0.1:9999
#自定义缓存路径,levels=1:2定义了缓存目录的层级结构,keys_zone定义了缓存的名称和大小,max_size定义了缓存的最大大小,inactive定义了缓存多久没有被访问后就被认为是不活跃的,use_temp_path将其设为off可以提高性能,server块中配置缓存详情
proxy_cache_path /path/to/cache/directory levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;
#定义一个代理服务,用于分发HTTP请求到多个后端服务器
upstream halo {
#这里负载有多种策略,按需选择一个即可
#1,轮询(默认):按请求的时间顺序依次逐一分配,如果服务器down掉,能自动剔除
#2,权重 :需要配置weight ,weight 越高,被分配的客户端越多,默认为 1
#3,IP:按请求 ip 的 hash 值分配,每个访客固定访问一个后端服务器
ip_hash;
#4,fair:按后端服务器的响应时间来分配,响应时间短的优先分配到请求
fair;
server 127.0.0.1:8888 weight=10;
server 127.0.0.1:9999 weight=5;
}
upstream halo2 {
server 127.0.0.1:7777 ;
}
#Server块用于配置虚拟主机,可以在一个http块中包含多个server块。每个server块表示一个网站或虚拟主机
server {
listen 9000; #监听端口
server_name 192.x.x.x; #监听地址
location ~ /halo2 {
root html; # 指定服务器的根目录,即网站静态文件存放的位置,这里就是/html
index index.html ; # 并使用index.html设置默认页
proxy_pass http://halo2; # 请求转向 halo 定义的服务器列表 ,就是上面upstream的内容
}
location ~ \.(gif|jpg|png|htm|html|css|js)(.*) {
#如果没有缓存则转向请求
proxy_pass http://halo;
#关闭重定向行为,默认情况下,Nginx会自动修改响应头中的位置信息,以便将客户端重定向到新的位置
proxy_redirect off;
#proxy_cache指定了使用的缓存名称,proxy_cache_key定义了生成缓存键的规则,proxy_cache_valid定义了特定响应状态码的缓存有效期
proxy_cache_key $scheme$proxy_host$request_uri;
proxy_cache cache_one;
proxy_cache_valid 200 1h; #对不同的 HTTP 状态码设置不同的缓存时间
proxy_cache_valid 500 1d;
proxy_cache_valid any 1m;
#expires 是给一个资源设定一个过期时间,3天后过期
expires 3d;
}
}
halo.conf(HTTPS版)
#定义一个代理服务,用于分发HTTP请求到多个后端服务器
upstream halo {
server 127.0.0.1:8888;
server 127.0.0.1:9999;
}
#配置http转发到https,所以就以下面一个server块为参考
server {
listen 80; #指定虚拟主机监听的IP地址和端口号
server_name chenhuadadao.cn;
rewrite ^(.*)$ https://$host$1 permanent; # 将所有http请求通过rewrite重定向到https
}
server {
listen 443 ssl; #指定虚拟主机监听的IP地址和端口号
server_name chenhuadadao.cn; #定义虚拟主机的域名或IP地址
client_max_body_size 10m; # 上传文件大小的限制
# 将证书文件存放路径和证书的密钥文件名替换成自己存放路径与证书的密钥文件名。
ssl_certificate /www/halo/https/www.xxxx.cn_bundle.crt;
ssl_certificate_key /www/halo/https/www.xxxx.cn.key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
#块定义了与URI相关的处理方式。比如,可以在这里配置重定向或者代理
location / {
proxy_pass http://halo;
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
归纳
1. HTTP块:在Nginx配置文件中,http块是最外层的块,它用于配置全局的HTTP属性。主要包括:
- http:用于声明一个http块。
- include:可以使用include指令引入其他配置文件,方便管理。
- server:指定一个或多个server块的配置,表示监听一个IP地址和端口,处理HTTP请求。一个http块通常可以包含多个server块。
- server_name:指定服务器的域名或IP地址。
- upstream:定义一个代理服务,用于分发HTTP请求到多个后端服务器。
2. Server块:Server块用于配置虚拟主机,可以在一个http块中包含多个server块。每个server块表示一个网站或虚拟主机。主要包括:
- listen:指定虚拟主机监听的IP地址和端口号。
- server_name:定义虚拟主机的域名或IP地址。
- root:指定虚拟主机的根目录,即网站文件存放的位置。
- index:指定默认访问的文件,例如index.html。
- location:用于匹配URL,并指定处理请求的模块和规则。可以包含一个或多个location块。
- access_log:指定访问日志的保存路径和格式。
- error_log:指定错误日志的保存路径和格式。
3. Location块:Location块用于匹配URL,并指定处理请求的规则和模块。主要包括:
- location:用于指定匹配的URL路径。
- proxy_pass:配置反向代理,将请求转发到后端服务器进行处理。
- try_files:用于尝试查找指定文件,一般用于处理静态文件请求。
- rewrite:用于重写URL,可以修改请求的路径或参数。
- alias:用于指定一个别名路径,用于匹配指定URL的请求。