中间件--nginx
NGINX
I/O模型
同步,异步
- 同步:synchronous,被调用者并不提供事件的处理结果相关的通知消息,需要调用者主动询问事 情是否处理完成
- 异步:asynchronous,被调用者通过状态、通知或回调机制主动通知调用者被调用者的运行状态
阻塞,非阻塞
- 阻塞:blocking,指IO操作需要彻底完成后才返回到用户空间,调用结果返回之前,调用者被挂起,干不了别的事情。
- 非阻塞:nonblocking,指IO操作被调用后立即返回给用户一个状态值,而无需等到IO操作彻底完成,在最终的调用结果返回之前,调用者不会被挂起,可以去做别的事情。
NGINX安装和信号
nginx时多进程模型,由一个master管理多个worker
- master进程:接收外部请求,通过信号管理worker进程,读取配置,监控worker,不中断服务,开启日志,读取文件描述符
- worker进程:worker进程平等,处理网络请求,I/O调用,缓存发送数据,与后端服务器通信,接收master进程信号
nginx安装
-
yum安装:
yum -y install nginx 通过yum直接安装,也可以使用官方源安装最新版本
-
编译安装:
1.安装依赖 yum -y install gcc pcre-devel openssl-devel zlib-devel 2.创建用户 useradd -s /sbin/nologin nginx 3.准备文件 wget http://nginx.org/download/nginx-1.18.0.tar.gz tar xf nginx-1.18.0.tar.gz 4.编译,编译时可以指定功能模块 cd nginx-1.18.0/ ./configure --prefix=/apps/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module make && make install chown -R nginx.nginx /apps/nginx 5.准备service文件 vim /usr/lib/systemd/system/nginx.service [Unit] Description=nginx - high performance web server Documentation=http://nginx.org/en/docs/ After=network-online.target remote-fs.target nss-lookup.target Wants=network-online.target [Service] Type=forking PIDFile=/apps/nginx/run/nginx.pid ExecStart=/apps/nginx/sbin/nginx -c /apps/nginx/conf/nginx.conf ExecReload=/bin/kill -s HUP $MAINPID ExecStop=/bin/kill -s TERM $MAINPID [Install] WantedBy=multi-user.target systemctl daemon-reload 6.建议 创建软连接 ln -s /apps/nginx/sbin/nginx /usr/sbin 或者 echo "/apps/nginx/sbin/nginx:$PATH" > /etc/profile.d/nginx.sh . /etc/profile.d/nginx.sh 将PID文件单独存放 mkdir /apps/nginx/run vim /apps/nginx/conf/nginx.conf pid /apps/nginx/run/nginx.pid;
#!/bin/bash version=nginx-1.18.0 download=/usr/local/src install=/apps rpm -q gcc wget pcre-devel openssl-devel zlib-devel make > /dev/null || yum -y install wget make gcc pcre-devel openssl-devel zlib-devel id nginx >/dev/null || useradd -s /sbin/nologin nginx [ -d ${install} ] || mkdir /apps [ -d ${install}/nginx/run ] || mkdir ${install}/nginx/run [ -e ${version}.tar.gz ] || wget -q -P cd ${download} http://nginx.org/download/${version}.tar.gz && echo "download nginx" cd ${download} tar -xvf ${version}.tar.gz >/dev/null && echo "archive nginx package" cd ${version} ./configure --prefix=${install}/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module > /dev/null && echo "configure finish" (make && make install) > /dev/null && echo "nginx make finish" chown -R nginx.nginx ${install}/nginx cat > /usr/lib/systemd/system/nginx.service <<EOF [Unit] Description=nginx - high performance web server Documentation=http://nginx.org/en/docs/ After=network-online.target remote-fs.target nss-lookup.target Wants=network-online.target [Service] Type=forking PIDFile=${install}/nginx/run/nginx.pid ExecStart=${install}/nginx/sbin/nginx -c ${install}/nginx/conf/nginx.conf ExecReload=/bin/kill -s HUP $MAINPID ExecStop=/bin/kill -s TERM $MAINPID [Install] WantedBy=multi-user.target EOF systemctl daemon-reload [ -e /usr/sbin/nginx ] || ln -s ${install}/nginx/sbin/nginx /usr/sbin grep -E "${install}/nginx/run/nginx.pid" ${install}/nginx/conf/nginx.conf > /dev/null || sed -ri "s#.*pid.*#pid /apps/nginx/run/nginx.pid;#" ${install}/nginx/conf/nginx.conf nginx -v
命令和信号
nginx 命令支持向其发送信号,实现不同功能
-
NGINX命令格式:
nginx [-?hvVtTq] [-s signal] [-c filename] [-p prefix] [-g directives] 帮助: -? -h 使用指定的配置文件: -c 指定配置指令:-g 指定运行目录:-p 测试配置文件是否有语法错误:-t -T 打印nginx的版本信息、编译信息等:-v -V 发送信号: -s 示例: nginx -s reload 信号: 立刻停止服务:stop,相当于信号SIGTERM,SIGINT 优雅的停止服务:quit,相当于信号SIGQUIT 平滑重启,重新加载配置文件: reload,相当于信号SIGHUP 重新开始记录日志文件:reopen,相当于信号SIGUSR1,在切割日志时用途较大 平滑升级可执行程序:发送信号SIGUSR2,在升级版本时使用 优雅的停止工作进程:发送信号SIGWINCH,在升级版本时使用
quit实现优雅关闭
关闭监听句柄
关闭空闲连接
在循环中等待全部连接关闭
退出nginx所有进程
reload实现配置重载
向master进程发送HUP信号(reload命令)
master进程校验配置语法是否正确
master进程打开新的监听端口
master进程用新配置启动新的worker子进程reload实现平滑升级和回退
1.将旧Nginx二进制文件换成新Nginx程序文件(注意先备份)
2.向master进程发送USR2信号
3.master进程修改pid文件名加上后缀.oldbin,成为nginx.pid.oldbin
4.master进程用新Nginx文件启动新master进程成为旧master的子进程,系统中将有新旧两个Nginx
5.主进程共同提供Web服务,当前新的请求仍然由旧Nginx的worker进程进行处理,将新生成的master进程的PID存放至新生成的pid文件nginx.pid
6.向旧的Nginx服务进程发送WINCH信号,使旧的Nginx worker进程平滑停止
7.向旧master进程发送QUIT信号,关闭老master,并删除Nginx.pid.oldbin文件
8.如果发现升级有问题,可以回滚∶向老master发送HUP,向新master发送QUIT1.解压编译新版本文件:注意:编译选项需要与原版本相同 nginx -V可查看原版本编译选项 tar -xvf tar xnf nginx-1.22.0.tar.gz ./configure --prefix=/apps/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module make 注:只需执行make 2.备份原版本二进制文件 mv /apps/nginx/sbin/nginx /apps/nginx/sbin/nginx.old 3.将新编译文件拷贝到/nginx/sbin下 cp objs/nginx /apps/nginx/sbin/nginx 4.向当前master进程发送USR2信号 kill -USR2 `cat /apps/nginx/run/nginx.pid` [root@centos7 sbin]# ps -auxf |grep nginx root 7584 0.0 0.0 112808 968 pts/0 S+ 10:53 0:00 \_ grep --color=auto nginx root 7576 0.0 0.0 46204 1352 ? Ss 10:52 0:00 nginx: master process /apps/nginx/sbin/nginx -c /apps/ngin/conf/nginx.conf nginx 7577 0.0 0.1 46652 1916 ? S 10:52 0:00 \_ nginx: worker process root 7580 0.0 0.1 46196 3352 ? S 10:52 0:00 \_ nginx: master process /apps/nginx/sbin/nginx -c /apps/nginx/conf/nginx.conf nginx 7581 0.0 0.1 46640 1908 ? S 10:52 0:00 \_ nginx: worker process 此时新老版本同时存在,老版本监听80端口,生成pid.oldbin文件 5.向nginx.pid.pldbin发送WINCH信号,新进程监听80端口,老版本工作进程结束,只保留master进程 kill -WINCH `cat /apps/nginx/run/nginx.pid.oldbin` [root@centos7 sbin]# ps -auxf |grep nginx root 7620 0.0 0.0 112808 968 pts/0 S+ 11:03 0:00 \_ grep --color=auto nginx root 7576 0.0 0.0 46204 1352 ? Ss 10:52 0:00 nginx: master process /apps/nginx/sbin/nginx -c /apps/ngin/conf/nginx.conf root 7580 0.0 0.1 46196 3352 ? S 10:52 0:00 \_ nginx: master process /apps/nginx/sbin/nginx -c /apps/nginx/conf/nginx.conf nginx 7581 0.0 0.1 46640 2152 ? S 10:52 0:00 \_ nginx: worker process 6.此时如果未出现问题,向老版本发送QUIT信号,原版本master进程退出 kill -QUIT `cat /apps/nginx/run/nginx.pid.oldbin` [root@centos7 ~]# ps -auxf |grep nginx root 7632 0.0 0.0 112808 968 pts/0 S+ 11:12 0:00 \_ grep --color=auto nginx root 7580 0.0 0.1 46196 3352 ? S 10:52 0:00 nginx: master process /apps/nginx/sbin/nginx -c /apps/ngin/conf/nginx.conf nginx 7581 0.0 0.1 46640 2152 ? S 10:52 0:00 \_ nginx: worker process 7.如果出现问题进行回退,向nginx.pid.oldbin发送HUP信号,从新拉起worker进程,并向当前master进程发送QUIT信号 kill -HUP `cat /apps/nginx/run/nginx.pid.oldbin` [root@centos7 sbin]# ps -auxf |grep nginx root 7625 0.0 0.0 112808 968 pts/0 S+ 11:10 0:00 \_ grep --color=auto nginx root 7576 0.0 0.0 46204 1352 ? Ss 10:52 0:00 nginx: master process /apps/nginx/sbin/nginx -c /apps/ngin/conf/nginx.conf root 7580 0.0 0.1 46196 3352 ? S 10:52 0:00 \_ nginx: master process /apps/nginx/sbin/nginx -c /apps/nginx/conf/nginx.conf nginx 7581 0.0 0.1 46640 2152 ? S 10:52 0:00 | \_ nginx: worker process nginx 7623 0.0 0.1 46652 1912 ? S 11:10 0:00 \_ nginx: worker process kill -QUIT `cat /apps/nginx/run/nginx.pid`
NGINX配置
- 主配置文件:nginx.conf
- 子配置文件: include conf.d/*.conf
- fastcgi, uwsgi,scgi 等协议相关的配置文件
- mime.types:支持的mime类型,MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型,MIME消息能包含文本、图像、音频、视频以及其他应用程序专用的数据,是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。
nginx 配置文件格式说明
配置文件由指令与指令块构成
每条指令以;分号结尾,指令与值之间以空格符号分隔
可以将多条指令放在同一行,用分号分隔即可,但可读性差,不推荐
指令块以{ }大括号将多条指令组织在一起,且可以嵌套指令块
include语句允许组合多个配置文件以提升可维护性
使用#符号添加注释,提高可读性
使用$符号使用变量
部分指令的参数支持正则表达式
main block:主配置段,即全局配置段,对http,mail都有效
#事件驱动相关的配置
event {
...
}
#http/https 协议相关配置段
http {
...
}
#默认配置文件不包括下面两个块
#mail 协议相关配置段
mail {
...
}
#stream 服务器相关配置段
stream {
...
}
全局配置块
user nginx; #启动Nginx工作进程的用户
worker_processes [number | auto]; #启动Nginx工作进程的数量,一般设为和CPU核心数相同
worker_cpu_affinity 00000001 00000010 00000100 00001000; nginx工作进程绑定cpu核心,阻止进程飘逸,降低资源损耗,建议优化项
error_log /apps/nginx/logs/error.log error; #错误日志,#错误日志记录配置,语法:error_log file [debug | info | notice | warn | error | crit | alert | emerg]
#pid文件保存路径
pid /apps/nginx/logs/nginx.pid;
worker_priority 0; #工作进程优先级,-20~20(19)
worker_rlimit_nofile 65536; #所有worker进程能打开的文件数量上限,包括:Nginx的所有连接(例如与代理服务器的连接等),而不仅仅是与客户端的连接,另一个考虑因素是实际的并发连接数不能超过系统级别的最大打开文件数的限制.最好与ulimit -n 或者limits.conf的值保持一致,建议优化项
修改最大打开文件数
[root@centos7 conf]# vim /etc/security/limits.conf
* soft nofile 1000000
* hard nofile 1000000
* - nproc 100000
daemon off; #前台运行Nginx服务用于测试、docker等环境。
master_process off|on; #是否开启Nginx的master-worker工作模式,仅用于开发调试场景,默认为on
events {
worker_connections 65536; #设置单个工作进程的最大并发连接数
use epoll; #使用epoll事件驱动,Nginx支持众多的事件驱动,比如:select、poll、epoll,只能设置在events模块中设置。
accept_mutex on; #on为同一时刻一个请求轮流由work进程处理,而防止被同时唤醒所有worker,避免多个睡眠进程被唤醒的设置,默认为off,新请求会唤醒所有worker进程,此过程也称为"惊群",因此nginx刚安装完以后要进行适当的优化。建议设置为on
multi_accept on; #ON时Nginx服务器的每个工作进程可以同时接受多个新的网络连接,此指令默认为off,即默认为一个工作进程只能一次接受一个新的网络连接,打开后几个同时接受多个。建议设置为on
}
http配置块
http 协议相关的配置结构
http {
include mime.types; #导入支持的文件类型,是相对于/apps/nginx/conf的目录
default_type application/octet-stream; #除mime.types中文件类型外,设置其它文件默认类型,访问其它类型时会提示下载不匹配的类型文件
#日志配置部分
#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 logs/access.log main;
#自定义优化参数
sendfile on;
#tcp_nopush on; #在开启了sendfile的情况下,合并请求后统一发送给客户端。
#tcp_nodelay off; #在开启了keepalived模式下的连接是否启用TCP_NODELAY选项,当为off时,延迟0.2s发送,默认On时,不延迟发送,立即发送用户响应报文。
#keepalive_timeout 0;
keepalive_timeout 65 65; #设置会话保持时间,第二个值为响应首部:keep_Alived:timeout=65,可以和第一个值不同
#gzip on; #开启文件压缩
server {
listen 80; #设置监听地址和端口
server_name localhost; #设置server name,可以以空格隔开写多个并支持正则表达式,如:*.magedu.com www.magedu.* ~^www\d+\.magedu\.com$ default_server
#charset koi8-r; #设置编码格式,默认是俄语格式,建议改为utf-8
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html; #定义错误页面
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ { #以http的方式转发php请求到指定web服务器
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ { #以fastcgi的方式转发php请求到php处理
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht { #拒绝web形式访问指定文件,如很多的网站都是通过.htaccess文件来改变自己的重定向等功能。
# deny all;
#}
location ~ /passwd.html {
deny all;
}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server { #自定义虚拟server
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm; #指定默认网页文件,此指令由ngx_http_index_module模块提供
# }
#}
# HTTPS server
#
#server { #https服务器配置
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
#建议将server块单独放到子配置中,include /apps/nginx/conf/conf.d/*.conf;
修改报文头server首部,隐藏nginx版本信息
#是否在响应报文中的Content-Type显示指定的字符集,默认off不显示
charset charset | off;
#示例
charset utf-8;
#是否在响应报文的Server首部显示nginx版本
server_tokens on | off | build | string;
如果server_tokens on,修改 src/core/nginx.h
[root@centos7 conf]# vim /usr/local/src/nginx-1.18.0/src/core/nginx.h
#define NGINX_VERSION "1.18.0"
#define NGINX_VER "nginx/" NGINX_VERSION
如果server_tokens off,修改 src/http/ngx_http_header_filter_module.c
static char ngx_http_server_string[] = "Server: nginx" CRLF;
static u_char ngx_http_server_string[] = "Server: nginx" CRLF;
把其中的nginx改为自己想要的文字即可,如:wanginx
注意:修改源码需重新编译
server_tokens off;
root@ubuntu:~# curl www.magedu.org/pc -I
HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Mon, 25 Jul 2022 08:22:17 GMT
Content-Type: text/html
Content-Length: 162
Location: http://www.magedu.org/pc/
Connection: keep-alive
常用核心配置
server{
listen 80;
server_name www.magedu.org;
root /data/html/pc;
location / {
index index.html;
}
location /pc {
root /data/html;
alias /data/html/pc;
}
}
root:指定web的家目录,在定义location的时候,文件的绝对路径等于 root+location
alias:定义路径别名,会把访问的路径重新定义到其指定的路径,文档映射的另一种机制;仅能用于location上下文,此指令使用较少
#alias将访问时的url直接替换为alias后的url
#alias 两个pc后的/需同时存在或不存在
location匹配规则和优先级
#语法规则:
location [ = | ~ | ~* | ^~ ] uri { ... }
= #用于标准uri前,需要请求字串与uri精确匹配,大小敏感,如果匹配成功就停止向下匹配并立即处理请
求
^~ #用于标准uri前,表示包含正则表达式,并且匹配以指定的正则表达式开头,对URI的最左边部分做匹配
检查,不区分字符大小写
~ #用于标准uri前,表示包含正则表达式,并且区分大小写
~* #用于标准uri前,表示包含正则表达式,并且不区分大写
不带符号 #匹配起始于此uri的所有的uri
\ #用于标准uri前,表示包含正则表达式并且转义字符。可以将 . * ?等转义为普通符号
#匹配优先级从高到低:
=, ^~, ~/~*, 不带符号
生产中:
#直接匹配网站根会加速Nginx访问处理
location = /index.html {
......;
}
location / {
......;
}
#静态资源配置方法1
location ^~ /static/ {
......;
}
#静态资源配置方法2,应用较多
location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
......;
}
#多应用配置
location ~* /app1 {
......;
}
location ~* /app2 {
......;
}
访问控制
访问控制基于模块ngx_http_access_module实现,可以通过匹配客户端源IP地址进行限制
注意: 如果能在防火墙设备控制,最好就不要在nginx上配置,可以更好的节约资源
allow 10.0.0.100;
deny all;
#deny 10.0.0.100;
#allow all;
#权限控制从小到大
账户访问
由 ngx_http_auth_basic_module 模块提供此功能
server{
listen 80;
server_name www.magedu.org;
location /pc {
root /data/html/;
auth_basic "login";
auth_basic_user_file /apps/nginx/conf/conf.d/.passwd;
}
}
htpasswd -cb /apps/nginx/conf/conf.d/.passwd mage 123456
htpasswd -b /apps/nginx/conf/conf.d/.passwd laowang 123456
#创建文件时-c选项,后不再使用,htpasswd由httpd-tools提供
自定义错误页面
server{
listen 80;
server_name www.magedu.org;
error_page 400 401 402 403 404 /erroe.html;
location = /error.html {
root /data/html/error;
}
location /pc {
root /data/html/;
}
}
将404转换为301 并跳转到主页
server{
listen 80;
server_name www.magedu.org;
error_page 404 =301 /index.html;
location =/index.html {
root /data/html/pc;
}
}
自定义错误日志
error_log /apps/nginx/logs/error.log; #定义错误日志
文件检测
try_files $uri $uri.html $uri/index.html default.html[=401];
当前面页面都不存在是跳转到default页面,可自定义状态码
长连接
keepalive_timeout timeout [header_timeout]; #设定保持连接超时时长,0表示禁止长连接,默认为75s,通常配置在http字段作为站点全局配置
keepalive_requests number; #在一次长连接上所允许请求的资源的最大数量,默认为100次,建议适当调大,比如:50
下载服务器
ngx_http_autoindex_module 模块处理以斜杠字符 "/" 结尾的请求,并生成目录列表,可以做为下载服务配置使用
autoindex on | off;#自动文件索引功能,默为off
autoindex_exact_size on | off; #计算文件确切大小(单位bytes),off 显示大概大小(单位K、M),默认on
autoindex_localtime on | off ; #显示本机时间而非GMT(格林威治)时间,默认off
autoindex_format html | xml | json | jsonp; #显示索引的页面文件风格,默认html
limit_rate rate; #限制响应客户端传输速率(除GET和HEAD以外的所有方法),单位B/s,即bytes/second,默认值0,表示无限制,此指令由ngx_http_core_module提供
set $limit_rate 4k; #也可以通变量限速,单位B/s,Rate limit can also be set in the $limit_rate variable, however, since version 1.17.0, this method is not recommended:
server{
listen 80;
server_name www.magedu.org;
location /download {
root /data/html;
autoindex on;
autoindex_exact_size on;
autoindex_localtime on;
limit_rate 1024k;
}
}
上传服务器
client_max_body_size 1m; #设置允许客户端上传单个文件的最大值,默认值为1m,上传文件超过此值会出413错误
client_body_buffer_size size; #用于接收每个客户端请求报文的body部分的缓冲区大小;默认16k;超出此大小时,其将被暂存到磁盘上的由下面client_body_temp_path指令所定义的位置
client_body_temp_path path [level1 [level2 [level3]]];
#设定存储客户端请求报文的body部分的临时存储路径及子目录结构和数量,目录名为16进制的数字,使用hash之后的值从后往前截取1位、2位、2位作为目录名
#上传时,Nginx会自动创建path目录
1级目录占1位16进制,即2^4=16个目录 0-f
2级目录占2位16进制,即2^8=256个目录 00-ff
3级目录占2位16进制,即2^8=256个目录 00-ff
aio on | off #是否启用asynchronous file I/O(AIO)功能,需要编译开启 --with-file-aio
directio size | off; #操作完全和aio相反,aio是读取文件而directio是写文件到磁盘,启用直接I/O,默认为关闭,当文件大于等于给定大小时,例如:directio 4m,同步(直接)写磁盘,而非写缓存。
open_file_cache off; #是否缓存打开过的文件信息
open_file_cache max=N [inactive=time];
max=N:#可缓存的缓存项上限数量;达到上限后会使用LRU(Least recently used,最近最少使用)算法实现管理
inactive=time:#缓存项的非活动时长,在此处指定的时长内未被命中的或命中的次数少于open_file_cache_min_uses指令所指定的次数的缓存项即为非活动项,将被删除
open_file_cache_valid time; #缓存项有效性的检查验证频率,默认值为60s
open_file_cache_errors on | off; #是否缓存查找时发生错误的文件一类的信息,默认值为off
open_file_cache_min_uses number; #open_file_cache指令的inactive参数指定的时长内,至少被命中此处指定的次数方可被归类为活动项,默认值为1
例:
open_file_cache max=10000 inactive=60s; #最大缓存10000个文件,非活动数据超时时长60s
open_file_cache_valid 60s; #每间隔60s检查一下缓存数据有效性
open_file_cache_min_uses 5; #60秒内至少被命中访问5次才被标记为活动数据
open_file_cache_errors on; #缓存错误信息
高级配置
状态页
基于nginx 模块 ngx_http_stub_status_module 实现,在编译安装nginx的时候需要添加编译参数 --with-http_stub_status_module,否则配置完成之后监测会是提示语法错误,建议限制访问
location /status {
stub_status;
}
root@ubuntu:~# curl http://www.magedu.org/status
Active connections: 3
server accepts handled requests
67 67 98
Reading: 0 Writing: 1 Waiting: 2
Active connections: #当前处于活动状态的客户端连接数,包括连接等待空闲连接数=reading+writing+waiting
accepts:#统计总值,Nginx自启动后已经接受的客户端请求的总数。
handled:#统计总值,Nginx自启动后已经处理完成的客户端请求总数,通常等于accepts,除非有因worker_connections限制等被拒绝的连接
requests:#统计总值,Nginx自启动后客户端发来的总的请求数。
Reading:#当前状态,正在读取客户端请求报文首部的连接的连接数,数值越大,说明排队现象严重,性能不足
Writing:#当前状态,正在向客户端发送响应报文过程中的连接数,数值越大,说明访问量很大
Waiting:#当前状态,正在等待客户端发出请求的空闲连接数,开启 keep-alive的情况下,这个值等于active – (reading+writing)
第三方模块
编译时--add-module=/usr/local/src/module #指定模块源代码路径
变量
nginx的变量可以在配置文件中引用,作为功能判断或者日志等场景使用,变量可以分为内置变量和自定义变量,内置变量是由nginx模块自带,通过变量可以获取到众多的与客户端访问相关的值。
1.常用内置变量
$remote_addr;
#存放了客户端的地址,注意是客户端的公网IP
$proxy_add_x_forwarded_for
#此变量表示将客户端IP追加请求报文中X-Forwarded-For首部字段,多个IP之间用逗号分隔,如果请求中没有X-Forwarded-For,就使用$remote_addrthe “X-Forwarded-For” client request header field with the $remote_addr variable appended to it, separated by a comma. If the “X-Forwarded-For” field is not present in the client request header, the $proxy_add_x_forwarded_for variable is equal to the $remote_addr variable.
$args;
#变量中存放了URL中的参数,例如:http://www.magedu.org/main/index.do?
id=20190221&partner=search
#返回结果为: id=20190221&partner=search
$document_root;
#保存了针对当前资源的请求的系统根目录,例如:/apps/nginx/html
$document_uri;
#保存了当前请求中不包含参数的URI,注意是不包含请求的指令,比如:http://www.magedu.org/main/index.do?id=20190221&partner=search会被定义为/main/index.do
#返回结果为:/main/index.do
$host;
#存放了请求的host名称
limit_rate 10240;
echo $limit_rate;
#如果nginx服务器使用limit_rate配置了显示网络速率,则会显示,如果没有设置, 则显示0
$remote_port;
#客户端请求Nginx服务器时随机打开的端口,这是每个客户端自己的端口
$remote_user;
#已经经过Auth Basic Module验证的用户名
$request_body_file;
#做反向代理时发给后端服务器的本地资源的名称
$request_method;
#请求资源的方式,GET/PUT/DELETE等
$request_filename;
#当前请求的资源文件的磁盘路径,由root或alias指令与URI请求生成的文件绝对路径,如:/apps/nginx/html/main/index.html
$request_uri;
#包含请求参数的原始URI,不包含主机名,相当于:$document_uri?$args,例如:/main/index.do?id=20190221&partner=search
$scheme;
#请求的协议,例如:http,https,ftp等
$server_protocol;
#保存了客户端请求资源使用的协议的版本,例如:HTTP/1.0,HTTP/1.1,HTTP/2.0等
$server_addr;
#保存了服务器的IP地址
$server_name;
#请求的服务器的主机名
$server_port;
#请求的服务器的端口号
$http_<name>
#name为任意请求报文首部字段,表示记录请求报文的首部字段arbitrary request header field; the last part of a variable name is the field name converted to lower case with dashes replaced by underscores #用下划线代替横线#示例: echo $http_User_Agent;
$http_user_agent;
#客户端浏览器的详细信息
$http_cookie;
#客户端的cookie信息
$cookie_<name>
#name为任意请求报文首部字部cookie的key名
2.自定义变量
假如需要自定义变量名称和值,使用指令set $variable value; #value可以为内置变量
自定义访问日志
log_format name context;#name为日志格式起个名字,后续直接引用。context日志定义内容
例:
log_format access_json '{"@timestamp":"$time_iso8601",'
'"host":"$server_addr",'
'"clientip":"$remote_addr",'
'"size":$body_bytes_sent,'
'"responsetime":$request_time,' #总的处理时间
'"upstreamtime":"$upstream_response_time",'
'"upstreamhost":"$upstream_addr",' #后端应用服务器处理时间
'"http_host":"$host",'
'"uri":"$uri",'
'"xff":"$http_x_forwarded_for",'
'"referer":"$http_referer",'
'"tcp_xff":"$proxy_protocol_addr",'
'"http_user_agent":"$http_user_agent",'
'"status":"$status"}';
access_log /apps/nginx/logs/access_json.log access_json;
#建议使用json格式方便日志收集
[root@centos7 ~]# tail -f /apps/nginx/logs/access_pc.log
{"@timestamp":"2022-07-25T16:46:17+08:00","host":"10.0.0.17","clientip":"10.0.0.1","size":100,"responsetime":0.000,"upstreamtime":"-","upstreamhost":"-","http_host":"www.magedu.org","uri":"/status","xff":"-","referer":"-","tcp_xff":"-","http_user_agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36 Edg/103.0.1264.71","status":"200"}
压缩
Nginx对文件的压缩功能是依赖于模块 ngx_http_gzip_module
#启用或禁用gzip压缩,默认关闭
gzip on | off;
#压缩比由低到高从1到9,默认为1
gzip_comp_level [1-9];
#禁用IE6 gzip功能
gzip_disable "MSIE [1-6]\.";
#gzip压缩的最小文件,小于设置值的文件将不会压缩
gzip_min_length 1k;
#启用压缩功能时,协议的最小版本,默认HTTP/1.1
gzip_http_version 1.0 | 1.1;
#指定Nginx服务需要向服务器申请的缓存空间的个数和大小,平台不同,默认:32 4k或者16 8k;
gzip_buffers number size;
#指明仅对哪些类型的资源执行压缩操作;默认为gzip_types text/html,不用显示指定,否则出错
gzip_types mime-type ...;
#如果启用压缩,是否在响应报文首部插入“Vary: Accept-Encoding”,一般建议打开
gzip_vary on | off;
gzip on;
gzip_comp_level 5;
gzip_min_length 1k; gzip_buffers 32 16k;
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/gif image/png;
gzip_vary on;
实现https
nginx 的https 功能基于模块ngx_http_ssl_module实现,因此如果是编译安装的nginx要使用参数 ngx_http_ssl_module开启ssl功能,但是作为nginx的核心功能,yum安装的nginx默认就是开启的,编 译安装的nginx需要指定编译参数--with-http_ssl_module开启
配置相关:
ssl on | off;
listen 443 ssl;
#为指定的虚拟主机配置是否启用ssl功能,此功能在1.15.0废弃,使用listen [ssl]替代
ssl_certificate /path/to/file;
#指向包含当前虚拟主机和CA的两个证书信息的文件,一般是crt文件
ssl_certificate_key /path/to/file;
#当前虚拟主机使用的私钥文件,一般是key文件
ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2];
#支持ssl协议版本,早期为ssl现在是TLS,默认为后三个
ssl_session_cache off | none | [builtin[:size]] [shared:name:size];
#配置ssl缓存
off: #关闭缓存
none: #通知客户端支持ssl session cache,但实际不支持
builtin[:size]:#使用OpenSSL内建缓存,为每worker进程私有
[shared:name:size]:#在各worker之间使用一个共享的缓存,需要定义一个缓存名称和缓存空间大小,一兆可以存储4000个会话信息,多个虚拟主机可以使用相同的缓存名称
ssl_session_timeout time;
#客户端连接可以复用ssl session cache中缓存的有效时长,默认5m
[root@centos7 conf.d]# vim https.conf
server{
listen 443 ssl;
server_name www.magedu.net;
ssl_certificate /apps/nginx/certs/nginx.crt;
ssl_certificate_key /apps/nginx/certs/nginx.key;
location / {
root /data/html/https;
}
}
root@ubuntu:~# curl https://www.magedu.net -k
https page
[root@centos7 conf.d]# vim https_2.conf
server{
listen 443 ssl;
server_name mobile.magedu.net;
ssl_certificate /apps/nginx/certs/mobile.crt;
ssl_certificate_key /apps/nginx/certs/mobile.key;
location / {
root /data/html/mobile;
}
}
root@ubuntu:~# curl https://mobile.magedu.net -k
https mobile page
#使用openssl命令创建crt时需合并 web.crt ca.crt > web.pem[crt]
解决favicon.ico告警问题
favicon.ico文件是网页显示图标,在请求网页时会加载文件,当文件不存在时会出错误。
解决办法
#方法一:服务器不记录访问日志:
location = /favicon.ico {
log_not_found off;
access_log off;
}
#方法二:将图标保存到指定目录访问:
#location ~ ^/favicon\.ico$ {
location = /favicon.ico {
root /data/nginx/html/pc/images;
expires 365d; #设置文件过期时间
}
openssl升级
升级openssl解决安全漏洞
升级openssl可在编译nginx时使用--with-openssl=path,指定openssl源码位置将新版本openssl编译到nginx。类似的,使用--with-module=path新增模块
[root@centos7 nginx-1.18.0]# nginx -V
nginx version: nginx/1.18.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)
built with OpenSSL 1.1.1k 25 Mar 2021
TLS SNI support enabled
configure arguments: --prefix=/apps/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module --with-openssl=/usr/local/src/openssl-1.1.1k
Nginx Rewrite
Nginx服务器利用 ngx_http_rewrite_module 模块解析和处理rewrite请求,此功能依靠 PCRE(perl compatible regular expression),因此编译之前要安装PCRE库,rewrite用于实现URL的重写。
ngx_http_rewrite_module 模块指令
1.if:
用于条件匹配判断,并根据条件判断结果选择不同的Nginx配置,可以配置在server或location块中进行配置,Nginx的if语法仅能使用if做单次判断,不支持使用if else或者if elif这样的多重判断,用法如下:
if (条件匹配) {
action
}
使用正则表达式对变量进行匹配,匹配成功时if指令认为条件为true,否则认为false,变量与表达式之间使用以下符号链接:
= #比较变量和字符串是否相等,相等时if指令认为该条件为true,反之为false
!= #比较变量和字符串是否不相等,不相等时if指令认为条件为true,反之为false
~ #区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假
!~ #区分大小写字符,判断是否匹配,不满足匹配条件为真,满足匹配条件为假
~* #不区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假
!~* #不区分大小字符,判断是否匹配,满足匹配条件为假,不满足匹配条件为真
-f 和 !-f #判断请求的文件是否存在和是否不存在
-d 和 !-d #判断请求的目录是否存在和是否不存在
-x 和 !-x #判断文件是否可执行和是否不可执行
-e 和 !-e #判断请求的文件或目录是否存在和是否不存在(包括文件,目录,软链接)
#注意:
#如果$变量的值为空字符串或0,则if指令认为该条件为false,其他条件为true。
#nginx 1.0.1之前$变量的值如果以0开头的任意字符串会返回false
server{
listen 80;
server_name a.magedu.org;
include mime.types;
location / {
root /data/html/a;
if ($scheme = http ){
return 666;
}
}
}
root@ubuntu:~# curl -I http://a.magedu.org
HTTP/1.1 666
Server: nginx/1.18.0
Date: Fri, 29 Jul 2022 17:04:52 GMT
Content-Length: 0
Connection: keep-alive
2.set
指定key并给其定义一个变量,变量可以调用Nginx内置变量赋值给key,另外set定义格式为set $key value,value可以是text, variables和两者的组合。
location /pc {
root /data/nginx/html/pc;
index index.html;
default_type text/html;
set $port $server_port; #将server_port变量赋值给port
}
3.break
用于中断当前相同作用域(location)中的其他Nginx配置,与该指令处于同一作用域的Nginx配置中,位于它前面的配置生效,位于后面的 ngx_http_rewrite_module 模块中指令就不再执行,Nginx服务器在根据配置处理请求的过程中遇到该指令的时候,回到上一层作用域继续向下读取配置,该指令可以在server块和locationif块中使用
注意: 如果break指令在location块中后续指令还会继续执行,只是不执行 ngx_http_rewrite_module 模块的指令,其它指令还会执行
location /main {
root /data/nginx/html/pc;
index index.html;
default_type text/html;
set $name magedu;
echo $name;
break; #location块中break后面指令还会执行
set $my_port $server_port;
echo $my_port;
}
4.return
return用于完成对请求的处理,并直接向客户端返回响应状态码,比如:可以指定重定向URL(对于特殊重定向状态码,301/302等) 或者是指定提示文本内容(对于特殊状态码403/500等),处于此指令后的所有配置都将不被执行,return可以在server、if 和 location块进行配置
return code; #返回给客户端指定的HTTP状态码
return code [text]; #返回给客户端的状态码及响应报文的实体内容,可以调用变量,其中text如果有空格,需要用单或双引号
return code URL; #返回给客户端的URL地址
server {
listen 80;
server_name www.magedu.org;
return 301 https://$server_name$request_uri;
5.rewrite_log
设置是否开启记录ngx_http_rewrite_module 模块日志记录到 error_log日志文件当中,可以配置在http、server、location 或 if 中
location /main {
index index.html;
default_type text/html;
set $name magedu;
echo $name;
rewrite_log on;
break;
set $my_port $server_port;
echo $my_port;
}
rewrite 指令
通过正则表达式的匹配来改变URI,可以同时存在一个或多个指令,按照顺序依次对URI进行匹配, rewrite主要是针对用户请求的URL或者是URI做具体处理
rewrite可以配置在 server、location、if
语法格式 :rewrite regex replacement [flag];
rewrite将用户请求的URI基于regex所描述的模式进行检查,匹配到时将其替换为表达式指定的新的URI
注意:如果在同一级配置块中存在多个rewrite规则,那么会自下而下逐个检查;被某条件规则替换完成后,会重新一轮的替换检查,隐含有循环机制,但不超过10次;如果超过,提示500响应码,[flag]所表示的标志位用于控制此循环机制
如果替换后的URL是以http://或https://开头,则替换结果会直接以重定向返回给客户端, 即永久重定向301
利用nginx的rewrite的指令,可以实现url的重新跳转,rewrtie有四种不同的flag,分别是redirect(临时重定向302)、permanent(永久重定向301)、break和last。其中前两种是跳转型的flag,后两种是代理型
跳转型指由客户端浏览器重新对新地址进行请求
代理型是在WEB服务器内部实现跳转
redirect;
#临时重定向,重写完成后以临时重定向方式直接返回重写后生成的新URL给客户端,由客户端重新发起请求;
使用相对路径,或者http://或https://开头,状态码:302
permanent;
#重写完成后以永久重定向方式直接返回重写后生成的新URL给客户端,由客户端重新发起请求,状态码:301
break;
#重写完成后,停止对当前URL在当前location中后续的其它重写操作,而后直接跳转至重写规则配置块之后
的其它配置;结束循环,建议在location中使用
#适用于一个URL一次重写
last;
#重写完成后,停止对当前URI在当前location中后续的其它重写操作,而后对新的URL启动新一轮重写检查,
不建议在location中使用
#适用于一个URL多次重写,要注意避免出现超过十次以及URL重写后返回错误的给用户
rewrite实现临时重定向和永久重定向
域名临时重定向,告诉浏览器域名不是固定重定向到当前目标域名,后期可能随时会更改,因此浏览器不会缓存当前域名的解析记录,而浏览器会缓存永久重定向的DNS解析记录,这也是临时重定向与永久重定向最大的本质区别。
1.临时重定向
server{
listen 80;
server_name a.magedu.org;
include mime.types;
rewrite / http://b.magedu.org redirect;
#location / {
# root /data/html/a;
# }
}
root@ubuntu:~# curl -LI a.magedu.org
HTTP/1.1 302 Moved Temporarily
Server: nginx/1.18.0
Date: Fri, 29 Jul 2022 14:26:49 GMT
Content-Type: text/html
Content-Length: 145
Connection: keep-alive
Location: http://b.magedu.org
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Fri, 29 Jul 2022 14:26:49 GMT
Content-Type: text/html
Content-Length: 14
Last-Modified: Fri, 29 Jul 2022 14:08:50 GMT
Connection: keep-alive
ETag: "62e3e9f2-e"
Accept-Ranges: bytes
2.永久重定向
server{
listen 80;
server_name a.magedu.org;
include mime.types;
rewrite / http://b.magedu.org permanent;
#rewrite / http://b.magedu.org redirect;
#location / {
# root /data/html/a;
# }
}
root@ubuntu:~# curl -LI a.magedu.org
HTTP/1.1 301 Moved Permanently
Server: nginx/1.18.0
Date: Fri, 29 Jul 2022 14:28:52 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
Location: http://b.magedu.org
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Fri, 29 Jul 2022 14:28:52 GMT
Content-Type: text/html
Content-Length: 14
Last-Modified: Fri, 29 Jul 2022 14:08:50 GMT
Connection: keep-alive
ETag: "62e3e9f2-e"
Accept-Ranges: bytes
3.break
break适合单次重写,例如在url改变时许访问原来资源,
server {
listen 80;
server_name web.magedu.org;
location /a {
root /data/html;
index index.html;
rewrite /a /b break;
}
location /b {
root /data/html;
index index.html;
}
}
root@ubuntu:~# curl -L web.magedu.org/a
/data/html/b/
root@ubuntu:~# curl -L web.magedu.org/b
/data/html/b/
4.last
last 适用于要不改变客户端访问方式但是需做多次目的URL重写的场景,使用场景不是很多。
server{
listen 80;
server_name a.magedu.org;
include mime.types;
root /data/html;
location /test {
rewrite /test /a last;
rewrite /a /b last;
}
location /a {
root /data/html;
rewrite /a /b last;
}
location /b {
root /data/html;
}
}
root@ubuntu:~# curl -L a.magedu.org/test
/data/html/b/
实现全站https
server{
listen 443 ssl;
listen 80;
server_name www.magedu.net;
ssl_certificate /apps/nginx/certs/nginx.crt;
ssl_certificate_key /apps/nginx/certs/nginx.key;
location / {
root /data/html/https;
if ($scheme = http){ #不做判断会死循环
rewrite / https://$host redirect;
}
}
}
root@ubuntu:~# curl -LIk http://www.magedu.net
HTTP/1.1 302 Moved Temporarily
Server: nginx/1.18.0
Date: Fri, 29 Jul 2022 17:13:42 GMT
Content-Type: text/html
Content-Length: 145
Connection: keep-alive
Location: https://www.magedu.net
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Fri, 29 Jul 2022 17:13:42 GMT
Content-Type: text/html
Content-Length: 11
Last-Modified: Mon, 25 Jul 2022 09:24:02 GMT
Connection: keep-alive
ETag: "62de6132-b"
Accept-Ranges: bytes
root@ubuntu:~# curl -LIk https://www.magedu.net
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Fri, 29 Jul 2022 17:13:55 GMT
Content-Type: text/html
Content-Length: 11
Last-Modified: Mon, 25 Jul 2022 09:24:02 GMT
Connection: keep-alive
ETag: "62de6132-b"
Accept-Ranges: bytes
防盗链
防盗链基于客户端携带的referer实现,referer是记录打开一个页面之前记录是从哪个页面跳转过来的标 记信息,根据referer是否可信限制盗链
正常的referer信息:
none:#请求报文首部没有referer首部,比如用户直接在浏览器输入域名访问web网站,就没有referer信息。
blocked:#请求报文有referer首部,但无有效值,比如为空。
server_names:#referer首部中包含本主机名及即nginx 监听的server_name。
arbitrary_string:#自定义指定字符串,但可使用*作通配符。示例: *.magedu.org www.magedu.*
regular expression:#被指定的正则表达式模式匹配到的字符串,要使用~开头,例如:~.*\.baidu\.com
实现防盗链:
location /images {
root /data/nginx/html/pc;
index index.html;
valid_referers none blocked server_names
*.example.com example.* www.example.org/galleries/
~\.google\.; #定义可信referer
if ($invalid_referer) {
return 403;# 对不可信referer返回403
}
反向代理
反向代理:reverse proxy,指的是代理外网用户的请求到内部的指定的服务器,并将数据返回给用户的 一种方式
nginx使用不同的模块实现不同的功能
常用模块
ngx_http_proxy_module: #将客户端的请求以http协议转发至指定服务器进行处理
ngx_http_upstream_module #用于定义为proxy_pass,fastcgi_pass,uwsgi_pass等指令引用的后端服务器分组
ngx_stream_proxy_module:#将客户端的请求以tcp协议转发至指定服务器处理
ngx_http_fastcgi_module:#将客户端对php的请求以fastcgi协议转发至指定服务器助理
ngx_http_uwsgi_module: #将客户端对Python的请求以uwsgi协议转发至指定服务器处理
http反向代理
常用参数配置
ngx_http_proxy_module模块:
转发请求至另一台主机
proxy_pass URL;
注意:proxy_pass后面路径不带uri时,会将location的uri传递(附加)给后端主机
server {
...
server_name HOSTNAME;
location /uri/ {
proxy_pass http://host[:port]; ##注意:最后没有/,如果有/就会直接访问此uri下的文件,而不是location目录下的文件
}
...
}
上面示例:http://HOSTNAME/uri --> http://host/uri ,功能类似 root
如果上面示例中有 /,即:http://host[:port]/ 此方式较少使用
意味着:http://HOSTNAME/uri --> http://host/ 即置换,功能类似 alias
#如果location定义其uri时使用了正则表达式模式(包括~,~*,但不包括^~),则proxy_pass之后必须不能使用uri; 用户请求时传递的uri将直接附加至后端服务器之后
proxy_hide_header field;
#用于nginx作为反向代理的时候,在返回给客户端http响应时,隐藏后端服务器相应头部的信息,可以设置在http,server或location块,
#示例: 隐藏后端服务器ETag首部字段
location /web {
index index.html;
proxy_pass http://10.0.0.18:8080/;
proxy_hide_header ETag;
}
proxy_pass_header field;
#默认nginx在响应报文中不传递后端服务器的首部字段Date, Server, X-Pad, X-Accel等参数,如果要传递的话则要使用 proxy_pass_header field声明将后端服务器返回的值传递给客户端
#field 首部字段大小不敏感
#示例:透传后端服务器的Server和Date首部,同时不再显示前端服务器的Server字段
proxy_pass_header Server;
proxy_pass_header Date;
proxy_pass_request_body on | off;
#是否向后端服务器发送HTTP实体部分,可以设置在http,server或location块,默认即为开启
proxy_pass_request_headers on | off;
#是否将客户端的请求头部转发给后端服务器,可以设置在http,server或location块,默认即为开启
proxy_set_header;
#可更改或添加客户端的请求头部信息内容并转发至后端服务器,比如在后端服务器想要获取客户端的真实IP的时候,就要更改每一个报文的头部
#示例:
#proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; #添加客户端IP和反向代理服务器IP到请求报文头部
$proxy_add_x_forwarded_for
the “X-Forwarded-For” client request header field with the $remote_addr variable appended to it, separated by a comma. If the “X-Forwarded-For” field is not present in the client request header, the $proxy_add_x_forwarded_for variable is equal to the $remote_addr variable.
proxy_set_header X-Real-IP $remote_addr; #只添加客户端IP到请求报文头部,转发至后端服务器
#添加HOST到报文头部,如果客户端为NAT上网那么其值为客户端的共用的公网IP地址,常用于在日之中记录客户端的真实IP地址。
#在后端httpd服务器修改配置,添加日志记录X-Forwarded-For字段
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" \"%{X-Real-IP}i\"" combined
proxy_connect_timeout time;
#配置nginx服务器与后端服务器尝试建立连接的超时时间,默认为60秒,用法如下:
proxy_connect_timeout 6s;
#60s为自定义nginx与后端服务器建立连接的超时时间,超时会返回客户端504响应码
proxy_read_timeout time;
#配置nginx服务器向后端服务器或服务器组发起read请求后,等待的超时时间,默认60s
proxy_send_timeout time;
#配置nginx项后端服务器或服务器组发起write请求后,等待的超时 时间,默认60s
proxy_http_version 1.0;
#用于设置nginx提供代理服务的HTTP协议的版本,默认http 1.0
proxy_ignore_client_abort off;
#当客户端网络中断请求时,nginx服务器中断其对后端服务器的请求。即如果此项设置为on开启,则服务器会忽略客户端中断并一直等着代理服务执行返回,如果设置为off,则客户端中断后Nginx也会中断客户端请求并立即记录499日志,默认为off。
proxy_headers_hash_bucket_size 128;
#当配置了 proxy_hide_header和proxy_set_header的时候,用于设置nginx保存HTTP报文头的hash表的上限
proxy_headers_hash_max_size 512;
#设置proxy_headers_hash_bucket_size的最大可用空间
server_namse_hash_bucket_size 512;
#server_name hash表申请空间大小
server_names_hash_max_size 512;
#设置服务器名称hash表的上限大小
反向代理缓存功能常用配置
proxy_cache zone_name | off; 默认off
#指明调用的缓存,或关闭缓存机制;Context:http, server, location
#zone_name 表示缓存的名称.需要由proxy_cache_path事先定义
proxy_cache_key string;
#缓存中用于“键”的内容,默认值:proxy_cache_key $scheme$proxy_host$request_uri;
proxy_cache_valid [code ...] time;
#定义对特定响应码的响应内容的缓存时长,定义在http{...}中
示例:
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
proxy_cache_path;
#定义可用于proxy功能的缓存;Context:http
proxy_cache_path path [levels=levels] [use_temp_path=on|off]
keys_zone=zone_name:size [inactive=time] [max_size=size] [manager_files=number]
[manager_sleep=time] [manager_threshold=time] [loader_files=number]
[loader_sleep=time] [loader_threshold=time] [purger=on|off]
[purger_files=number] [purger_sleep=time] [purger_threshold=time];
#示例:在http配置定义缓存信息
proxy_cache_path /var/cache/nginx/proxy_cache #定义缓存保存路径,proxy_cache会自动创建
levels=1:2:2 #定义缓存目录结构层次,1:2:2可以生成2^4x2^8x2^8=2^20=1048576个目录
keys_zone=proxycache:20m #指内存中缓存的大小,主要用于存放key和metadata(如:使用次数)
inactive=120s #缓存有效时间
max_size=1g; #最大磁盘占用空间,磁盘存入文件内容的缓存空间最大值
#调用缓存功能,需要定义在相应的配置段,如server{...};或者location等
proxy_cache proxycache;
proxy_cache_key $request_uri; #对指定的数据进行MD5的运算做为缓存的key
proxy_cache_valid 200 302 301 10m; #指定的状态码返回的数据缓存多长时间
proxy_cache_valid any 1m; #除指定的状态码返回的数据以外的缓存多长时间,必须设置,否则不会缓存
proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | off ; #默认是off
#在被代理的后端服务器出现哪种情况下,可直接使用过期的缓存响应客户端
#示例
proxy_cache_use_stale error http_502 http_503;
proxy_cache_methods GET | HEAD | POST ...;
#对哪些客户端请求方法对应的响应进行缓存,GET和HEAD方法总是被缓存
添加响应报文头部信息
nginx基于模块ngx_http_headers_module可以实现对后端服务器响应给客户端的报文中添加指定的响 应首部字段
Context: http, server, location, if in location
#添加响应报文的自定义首部:
add_header name value [always];
#示例:
add_header X-Via $server_addr; #当前nginx主机的IP
add_header X-Cache $upstream_cache_status; #是否缓存命中
add_header X-Accel $server_name; #客户访问的FQDN
反向代理:upstream
Nginx 可以基于ngx_http_upstream_module模块 提供服务器分组转发、权重分配、状态监测、调度算法等高级功能
upstream backend {
server backend1.example.com weight=5;
server backend2.example.com:8080;
server unix:/tmp/backend3;
server backup1.example.com:8080 backup;
server backup2.example.com:8080 backup;
}
#upstream定义在http模块中
server {
location / {
proxy_pass http://backend;
}
}
server address [parameters];
#配置一个后端web服务器,配置在upstream内,至少要有一个server服务器配置。
#server支持的parameters如下:
weight=number #设置权重,默认为1,实现类似于LVS中的WRR,WLC等
max_conns=number #给当前server设置最大活动链接数,默认为0表示没有限制
max_fails=number #对后端服务器连续监测失败多少次就标记为不可用,默认为1次,当客户端访问时,才会利用TCP触发对探测后端服务器健康性检查,而非周期性的探测
fail_timeout=time #对后端服务器的单次监测超时时间,默认为10秒
backup #设置为备份服务器,当所有服务器不可用时将重新启用次服务器
down #标记为down状态
resolve #当server定义的是主机名的时候,当A记录发生变化会自动应用新IP而不用重启Nginx
hash KEY [consistent];
#基于指定请求报文中首部字段或者URI等key做hash计算,使用consistent参数,将使用ketama一致性hash算法,适用于后端是Cache服务器(如varnish)时使用,consistent定义使用一致性hash运算,一致性hash基于取模运算
hash $request_uri consistent; #基于用户请求的uri做hash
hash $cookie_sessionid #基于cookie中的sessionid这个key进行hash调度,实现会话绑定
ip_hash;
#源地址hash调度方法,基于的客户端的remote_addr(源地址IPv4的前24位或整个IPv6地址)做hash计算,以实现会话保持
least_conn;
#最少连接调度算法,优先将客户端请求调度到当前连接最少的后端服务器,相当于LVS中的WLC
一致性hash
0-2^32构成一个圆环,0和2^32重合。对服务器进行hash(如服务器编号,ip等)等到输出值映射到圆环上,对请求进行hash,将输出值映射到圆环,顺时针遇到的第一个服务器就是请求分配的服务器。
案例:实现反向代理单台web服务器
web服务器:10.0.0.27
代理服务器:10.0.0.17
客户端:10.0.0.100
#全站代理
web服务器设置:
1.安装httpd
[root@centos7 ~]# yum -y install httpd
2.准备页面,启动服务
[root@centos7 ~]# hostname -I > /var/www/html/index.html
[root@centos7 ~]# systemctl start httpd.service
代理服务器设置:
[root@centos7 conf.d]# vim proxy.conf
server {
listen 80;
server_name www.magedu.org;
location / {
proxy_pass http://10.0.0.27:80;
}
}
测试:
root@ubuntu:~# curl www.magedu.org
10.0.0.27
#基于uri代理
server {
listen 80;
server_name www.magedu.org;
location /static {
proxy_pass http://10.0.0.27:80;
}
}
root@ubuntu:~# curl -L www.magedu.org/static
/var/www/html/static
#基于uri可实现动静分离
server {
listen 80;
server_name www.magedu.org;
location /statics {
root /data/html;
index index.html;
}
location /static {
proxy_pass http://10.0.0.27:80;
}
}
root@ubuntu:~# curl -L www.magedu.org/statics
/data/html/statics
root@ubuntu:~# curl -L www.magedu.org/static
/var/www/html/static
反向代理缓存功能
缓存功能默认关闭状态,需要先动配置才能启用
proxy_cache zone_name | off; 默认off
#指明调用的缓存,或关闭缓存机制;Context:http, server, location
#zone_name 表示缓存的名称.需要由proxy_cache_path事先定义
proxy_cache_key string;
#缓存中用于“键”的内容,默认值:proxy_cache_key $scheme$proxy_host$request_uri;
proxy_cache_valid [code ...] time;
#定义对特定响应码的响应内容的缓存时长,定义在http{...}中
示例:
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
proxy_cache_path;
#定义可用于proxy功能的缓存;Context:http
proxy_cache_path path [levels=levels] [use_temp_path=on|off]
keys_zone=zone_name:size [inactive=time] [max_size=size] [manager_files=number]
[manager_sleep=time] [manager_threshold=time] [loader_files=number]
[loader_sleep=time] [loader_threshold=time] [purger=on|off]
[purger_files=number] [purger_sleep=time] [purger_threshold=time];
proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 |
http_502 | http_503 | http_504 | http_403 | http_404 | off ; #默认是off
#在被代理的后端服务器出现哪种情况下,可直接使用过期的缓存响应客户端
#示例
proxy_cache_use_stale error http_502 http_503;
案例:反向代理实现缓存
http {
...
proxy_cache_path /apps/nginx/proxy_cache levels=1:1:1 keys_zone=proxy_cache:20m inactive=120s max_size=1g; #定义缓存,目录结构,内存中缓存大小,有效时间,最大占用磁盘空间。
...
}
[root@centos7 conf.d]# vim proxy.conf
server {
listen 80;
server_name www.magedu.org;
location / {
#proxy_cache proxycache;
#proxy_cache_key $request_uri;
#proxy_cache_valid 200 302 301 10m;
#proxy_cache_valid any 1m;
proxy_pass http://10.0.0.27:80;
}
}
[root@centos7 ~]# ab -n1000 -c100 http://www.magedu.org/index.html
Concurrency Level: 100
Time taken for tests: 0.489 seconds
Complete requests: 1000
Failed requests: 0
Write errors: 0
Total transferred: 29190000 bytes
HTML transferred: 28934000 bytes
Requests per second: 2043.76 [#/sec] (mean)
Time per request: 48.929 [ms] (mean)
Time per request: 0.489 [ms] (mean, across all concurrent requests)
Transfer rate: 58259.04 [Kbytes/sec] received
[root@centos7 conf.d]# vim proxy.conf
server {
listen 80;
server_name www.magedu.org;
location / {
proxy_cache proxycache;
proxy_cache_key $request_uri;
proxy_cache_valid 200 302 301 10m;
proxy_cache_valid any 1m;
proxy_pass http://10.0.0.27:80;
}
}
[root@centos7 ~]# ab -n1000 -c100 http://www.magedu.org/index.html
Concurrency Level: 100
Time taken for tests: 0.306 seconds
Complete requests: 1000
Failed requests: 0
Write errors: 0
Total transferred: 29190000 bytes
HTML transferred: 28934000 bytes
Requests per second: 3265.06 [#/sec] (mean)
Time per request: 30.627 [ms] (mean)
Time per request: 0.306 [ms] (mean, across all concurrent requests)
Transfer rate: 93073.37 [Kbytes/sec] received
添加响应报文的头部信息
nginx基于模块ngx_http_headers_module可以实现对后端服务器响应给客户端的报文中添加指定的响 应首部字段
[root@centos7 conf.d]# vim proxy.conf
server {
listen 80;
server_name www.magedu.org;
location / {
proxy_pass http://10.0.0.27:80;
add_header X-Via $server_addr;
add_header X-Cache $upstream_cache_status;
add_header X-Accel $server_name;
proxy_cache proxycache;
proxy_cache_key $request_uri;
proxy_cache_valid 200 302 301 10m;
proxy_cache_valid any 1m;
}
}
[root@centos7 ~]# curl www.magedu.org -I
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Sat, 30 Jul 2022 03:55:55 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 28934
Connection: keep-alive
Last-Modified: Sat, 30 Jul 2022 03:43:41 GMT
ETag: "7106-5e4fd92a42bdb"
X-Via: 10.0.0.17
X-Cache: MISS
X-Accel: www.magedu.org
Accept-Ranges: bytes
[root@centos7 ~]# curl www.magedu.org -I
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Sat, 30 Jul 2022 03:55:58 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 28934
Connection: keep-alive
Last-Modified: Sat, 30 Jul 2022 03:43:41 GMT
ETag: "7106-5e4fd92a42bdb"
X-Via: 10.0.0.17
X-Cache: HIT
X-Accel: www.magedu.org
Accept-Ranges: bytes
多台服务器代理
1.轮询:
[root@centos7 conf.d]# vim ../nginx.conf
http {
upstream web {
server 10.0.0.27:80 weight=1 fail_timeout=5s max_fails=3;
server 10.0.0.37:80 weight=1 fail_timeout=5s max_fails=3;
}
}
[root@centos7 conf.d]# cat proxy.conf
server {
listen 80;
server_name www.magedu.org;
location / {
proxy_pass http://web;
}
}
[root@centos7 ~]# curl www.magedu.org
10.0.0.27
[root@centos7 ~]# curl www.magedu.org
10.0.0.37
2.ip_hash
[root@centos7 conf.d]# vim ../nginx.conf
http {
upstream web {
ip_hash;
server 10.0.0.27:80 weight=1 fail_timeout=5s max_fails=3;
server 10.0.0.37:80 weight=1 fail_timeout=5s max_fails=3;
}
}
[root@centos7 ~]# curl www.magedu.org
10.0.0.37
[root@centos7 ~]# curl www.magedu.org
10.0.0.37
3.least_conn
[root@centos7 conf.d]# vim ../nginx.conf
http {
upstream web {
least_conn;
server 10.0.0.27:80 weight=1 fail_timeout=5s max_fails=3;
server 10.0.0.37:80 weight=1 fail_timeout=5s max_fails=3;
}
}
[root@centos7 ~]# curl www.magedu.org
10.0.0.27
[root@centos7 ~]# curl www.magedu.org
10.0.0.37
3.基于cookie会话绑定
[root@centos7 conf.d]# vim ../nginx.conf
http {
upstream web {
hash $cookie_sessionid; #session信息不变,转发到同一服务器
server 10.0.0.27:80 weight=1 fail_timeout=5s max_fails=3;
server 10.0.0.37:80 weight=1 fail_timeout=5s max_fails=3;
}
}
4.一致性hash
[root@centos7 conf.d]# vim ../nginx.conf
http {
upstream web {
hash $request_uri consistent;
server 10.0.0.27:80 weight=1 fail_timeout=5s max_fails=3;
server 10.0.0.37:80 weight=1 fail_timeout=5s max_fails=3;
}
}
[root@centos7 ~]# curl www.magedu.org
10.0.0.27
[root@centos7 ~]# curl www.magedu.org
10.0.0.27
实现ip透传
#proxy_set_header X-Real-IP $remote_addr; #只添加客户端IP到请求报文头部,转发至后端服务器
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; #添加客户端IP和反向代理服务器IP到请求报文头部
#修改代理配置
[root@centos7 conf.d]# cat proxy.conf
server {
listen 80;
server_name www.magedu.org;
location / {
proxy_pass http://web;
#proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
[root@centos7 conf.d]# nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@centos7 conf.d]# nginx -s reload
#修改web服务器日志格式
[root@centos7 html]# vim /etc/httpd/conf/httpd.conf
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" \"%{X-Forwarded-For}i\"" combined
[root@centos7 html]# systemctl restart httpd.service
测试:
[root@centos7 ~]# tail -f /var/log/httpd/access_log
10.0.0.17 - - [30/Jul/2022:12:21:09 +0800] "HEAD / HTTP/1.0" 200 - "-" "curl/7.29.0" "10.0.0.57"
Nginx 四层负载均衡
基于ngx_stream_proxy_module模块实现tcp 负载,基于模块ngx_stream_upstream_module实现后端服务器分组转发、权重分配、状态监测、 调度算法等高级功能。
stream { #定义stream相关的服务;Context:main
upstream backend { #定义后端服务器
hash $remote_addr consistent; #定义调度算法
server backend1.example.com:12345 weight=5; #定义具体server
server 127.0.0.1:12345 max_fails=3 fail_timeout=30s;
server unix:/tmp/backend3;
}
upstream dns { #定义后端服务器
server 10.0.0.1:53535; #定义具体server
server dns.example.com:53;
}
server { #定义server
listen 12345; #监听IP:PORT
proxy_connect_timeout 1s; #连接超时时间
proxy_timeout 3s; #转发超时时间
proxy_pass backend; #转发到具体服务器组
}
server {
listen 127.0.0.1:53 udp reuseport;
proxy_timeout 20s;
proxy_pass dns;
}
server {
listen [::1]:12345;
proxy_pass unix:/tmp/stream.socket;
}
}
1.实现reids负载均衡
[root@centos7 proxy]# cat redis.conf
stream {
upstream redis_server {
server 10.0.0.100:6379 weight=1 fail_timeout=10s max_fails=3;
server 10.0.0.110:6379 weight=1 fail_timeout=10s max_fails=3;
}
server {
listen 6379;
proxy_connect_timeout 3s;
proxy_timeout 3s;
proxy_pass redis_server;
}
}
测试:在10.0.0.100服务器插入reids 100,10.0.0.110为空
127.0.0.1:6379> set redis 100
OK
127.0.0.1:6379> get redis
"100"
[root@localhost ~]# redis-cli -h 10.0.0.17 -p 6379 get redis
(nil)
[root@localhost ~]# redis-cli -h 10.0.0.17 -p 6379 get redis
"100"
2.实现mysql负载均衡
[root@centos7 proxy]# cat mysql.conf
stream {
upstream mysql_server {
server 10.0.0.100:3306 weight=1 fail_timeout=3s max_fails=3;
server 10.0.0.110:3306 weight=1 fail_timeout=3s max_fails=3;
}
server {
listen 3306;
proxy_timeout 5s;
proxy_connect_timeout 5s;
proxy_pass mysql_server;
}
}
测试:
[root@localhost ~]# mysql -utest -h10.0.0.17 -P3306 -e 'show variables like "hostname"'
+---------------+------------------+
| Variable_name | Value |
+---------------+------------------+
| hostname | node1.magedu.org |
+---------------+------------------+
[root@localhost ~]# mysql -utest -h10.0.0.17 -P3306 -e 'show variables like "hostname"'
+---------------+------------------+
| Variable_name | Value |
+---------------+------------------+
| hostname | node2.magedu.org |
+---------------+------------------+
实现lamp搭建wordpress
Nginx基于模块ngx_http_fastcgi_module实现通过fastcgi协议将指定的客户端请求转发至php-fpm处 理,其配置指令如下:
fastcgi_pass address:port;
#转发请求到后端服务器,address为后端的fastcgi server的地址,可用位置:location, if in
location
fastcgi_index name;
#fastcgi默认的主页资源,示例:fastcgi_index index.php;
fastcgi_param parameter value [if_not_empty];
#设置传递给FastCGI服务器的参数值,可以是文本,变量或组合,可用于将Nginx的内置变量赋值给自定义key
fastcgi_param REMOTE_ADDR $remote_addr; #客户端源IP
fastcgi_param REMOTE_PORT $remote_port; #客户端源端口
fastcgi_param SERVER_ADDR $server_addr; #请求的服务器IP地址
fastcgi_param SERVER_PORT $server_port; #请求的服务器端口
fastcgi_param SERVER_NAME $server_name; #请求的server name
Nginx默认配置示例:
location ~ \.php$ {
root /scripts;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; #默认脚本路径
#fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params; #此文件默认系统已提供,存放的相对路径为prefix/conf
}
1.准备nginx
server {
listen 80;
server_name www.magedu.org;
location / {
root /data/php/wordpress;
index index.php index.html;
}
location ~ \.php$ {
root /data/php/wordpress;
fastcgi_pass 10.0.0.27:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
2.准备php-fpm,跟nginx在同一台机器,listen = 127.0.0.1:9000
rpm -q gcc make libxml2-devel bzip2-devel libmcrypt-devel sqlite-devel oniguruma-devel >/dev/null || yum -y install gcc make libxml2-devel bzip2-devel libmcrypt-devel sqlite-devel oniguruma-devel
tar -xvf php-8.0.20.tar.gz
cd php-8.0.20
./configure --prefix=/apps/php --enable-mysqlnd --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd --with-openssl --with-zlib --with-config-file-path=/etc --with-config-file-scan-dir=/etc/php.d --enable-mbstring --enable-xml --enable-sockets --enable-fpm --enable-maintainer-zts --disable-fileinfo
make && make install
echo PATH=/apps/php/bin:/apps/httpd/bin:$PATH >> /etc/profile.d/httpd.sh && source /etc/profile.d/httpd.sh
cp php.ini-production /etc/php.ini
cp sapi/fpm/php-fpm.service /usr/lib/systemd/system/
cd /apps/php/etc
cp php-fpm.conf.default php-fpm.conf
cd php-fpm.d/
cp www.conf.default www.conf
grep -e "^user = apache" -e "^group = apache" /app/php/etc/php-fpm.d/www.conf || sed -ri -e "s/user = apache/user = nginx/" -e "s/group = apache/group = nginx/" /app/php/etc/php-fpm.d/www.conf
mkdir /etc/php.d/
cat > /etc/php.d/opcache.ini <<EOF
[opcache]
zend_extension=opcache.so
opcache.enable=1
EOF
systemctl daemon-reload
systemctl enable --now php-fpm.service
systemctl status php-fpm.service
3.准备mysql,此处使用yum安装
mysql> create database wordpress;
mysql> create user wordpress@'10.0.0.%' identified by '123456';
mysql> grant all on wordpress.* to wordpress@'10.0.0.%';
root@node1:~# curl 10.0.0.27 -I
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Sun, 31 Jul 2022 10:26:06 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/8.0.20
Link: <http://10.0.0.27/index.php?rest_route=/>; rel="https://api.w.org/"
归纳总结:
-
对常用I/O模型进行比较说明
阻塞型 I/O 模型:程序向内核发送I/O请求后一直等待内核响应,如果内核处理请求的IO操作不能立即返回,则进程将一直等待并不再接受新的请求,并由进程轮训查看I/O是否完成,完成后进程将I/O结果返回给Client,在IO没有返回期间进程不能接受其他客户的请求,而且是有进程自己去查看I/O是否完成。 优点:程序简单,在阻塞等待数据期间进程/线程挂起,基本不会占用 CPU 资源 缺点:每个连接需要独立的进程/线程单独处理,当并发请求量大时为了维护程序,内存、线程切换开销较大,apache 的preforck使用的是这种模式。 非阻塞型 I/O 模型:程序向内核发送请I/O求后一直等待内核响应,如果内核处理请求的IO操作不能立即返回IO结果,进程将不再等待,而且继续处理其他请求,但是仍然需要进程隔一段时间就要查看内核I/O是否完成。 优点:较阻塞型IO效率更好 缺点:频繁询问IO状态,更加消耗CPU 多路复用 I/O 型:程序注册一组socket,并调用select/poll/epoll函数监控这些socket,当发生io操作时select/poll/epoll函数进行监控内核数据读取,当读内核取完成后返回完成信号,程序读取数据 优点:可以基于一个阻塞对象,同时在多个描述符上等待就绪,而不是使用多个线程(每个文件描述符一个线程),这样可以大大节省系统资源 缺点:当连接数较少时效率相比多线程+阻塞 I/O 模型效率较低,可能延迟更大,因为单个连接处理需要 2 次系统调用,占用时间会有增加 信号驱动式 I/O 模型:程序进程向内核发送IO调用后,不用等待内核响应,可以继续接受其他请求,内核收到进程请求后进行的IO如果不能立即返回,就由内核等待结果,直到IO完成后内核再通知进程 优点:于等待数据报到达期间进程不被阻塞。用户主程序可以继续执行,只要等待来自信号处理函数的通知。 缺点:信号 I/O 在大量 IO 操作时可能会因为信号队列溢出导致没法通知 异步 I/O 模型:程序进程向内核发送IO调用后,不用等待内核响应,可以继续接受其他请求,内核调用的IO如果不能立即返回,内核会继续处理其他事物,直到IO完成后将结果通知给内核,内核在将IO完成的结果返回给进程,期间进程可以接受新的请求,内核也可以处理新的事物,因此相互不影响,可以实现较大的同时并实现较高的IO复用,因此异步非阻塞使用最多的一种通信方式。 优点:异步 I/O 能够充分利用 DMA 特性,让 I/O 操作与计算重叠 缺点:要实现真正的异步 I/O,操作系统需要做大量的工作。
-
nginx中的模块分类及常见核心模块有哪些
核心模块:是 Nginx 服务器正常运行必不可少的模块,提供错误日志记录 、配置文件解析 、事件驱动机制 、进程管理等核心功能 标准HTTP模块:提供 HTTP 协议解析相关的功能,比如: 端口配置 、 网页编码设置 、 HTTP响应头设置 等等 可选HTTP模块:主要用于扩展标准的 HTTP 功能,让 Nginx 能处理一些特殊的服务,比如: Flash 多媒体传输 、解析 GeoIP 请求、 网络传输压缩 、 安全协议 SSL 支持等 邮件服务模块:主要用于支持 Nginx 的 邮件服务 ,包括对 POP3 协议、 IMAP 协议和 SMTP协议的支持 Stream服务模块: 实现反向代理功能,包括TCP协议代理 第三方模块:是为了扩展 Nginx 服务器应用,完成开发者自定义功能,比如: Json 支持、 Lua 支持等
-
描述nginx中worker_processes、worker_cpu_affinity、worker_rlimit_nofile、worker_connections配置项的含义
worker_processes:启动Nginx工作进程的数量,一般设为和CPU核心数相同 worker_cpu_affinity:CPU亲缘性,将工作进程与CPU绑定,减少进程切换的消耗 worker_rlimit_nofile:工作进程打开文件上限,建议与limits.conf一致 worker_connections:设置单个工作进程的最大并发连接数
-
编译安装nginx,实现多域名 https
编译安装脚本 #!/bin/bash version=nginx-1.18.0 download=/usr/local/src install=/apps rpm -q gcc wget pcre-devel openssl-devel zlib-devel make > /dev/null || yum -y -q install wget make gcc pcre-devel openssl-devel zlib-devel id nginx >/dev/null || useradd -s /sbin/nologin nginx [ -d ${install} ] || mkdir ${install} [ -e ${download}/${version}.tar.gz ] && echo "${download}/${version}.tar.gz is exist" || wget -q -P ${download} http://nginx.org/download/${version}.tar.gz && echo "downloaded nginx" cd ${download} tar -xvf ${version}.tar.gz >/dev/null && echo "archive nginx package" cd ${version} ./configure --prefix=${install}/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module > /dev/null && echo "configure finish" (make && make install) > /dev/null && echo "nginx make finish" chown -R nginx.nginx ${install}/nginx [ -d ${install}/nginx/run ] || mkdir ${install}/nginx/run cat > /usr/lib/systemd/system/nginx.service <<EOF [Unit] Description=nginx - high performance web server Documentation=http://nginx.org/en/docs/ After=network-online.target remote-fs.target nss-lookup.target Wants=network-online.target [Service] Type=forking PIDFile=${install}/nginx/run/nginx.pid ExecStart=${install}/nginx/sbin/nginx -c ${install}/nginx/conf/nginx.conf ExecReload=/bin/kill -s HUP $MAINPID ExecStop=/bin/kill -s TERM $MAINPID [Install] WantedBy=multi-user.target EOF systemctl daemon-reload [ -L /usr/sbin/nginx ] || (ln -s ${install}/nginx/sbin/nginx /usr/sbin;echo "link created") grep -E "${install}/nginx/run/nginx.pid" ${install}/nginx/conf/nginx.conf > /dev/null || sed -ri "s#.*pid.*#pid /apps/nginx/run/nginx.pid;#" ${install}/nginx/conf/nginx.conf [root@centos7 ~]# nginx -v nginx version: nginx/1.18.0 2.准备crt文件,centos7可以在/etc/pki/tls/certs下执行make [root@centos7 certs]# ls apps.crt apps.key web.crt web.key 3.准备配置文件 [root@centos7 conf.d]# cat web1.conf web2.conf server { listen 80; listen 443 ssl; server_name pc.magedu.org; ssl_certificate /apps/nginx/certs/apps.crt; ssl_certificate_key /apps/nginx/certs/apps.key; location / { root /data/html; index index.html; } } server { listen 80; listen 443 ssl; server_name web.magedu.org; ssl_certificate /apps/nginx/certs/web.crt; ssl_certificate_key /apps/nginx/certs/web.key; location / { root /data/html; index index.html; } } 测试: root@node1:~/nginx-1.18.0# curl -ki https://pc.magedu.org HTTP/1.1 200 OK Server: nginx/1.18.0 Date: Sun, 31 Jul 2022 14:49:58 GMT Content-Type: text/html Content-Length: 11 Last-Modified: Sun, 31 Jul 2022 14:39:32 GMT Connection: keep-alive ETag: "62e69424-b" Accept-Ranges: bytes https page root@node1:~/nginx-1.18.0# curl -ki https://web.magedu.org HTTP/1.1 200 OK Server: nginx/1.18.0 Date: Sun, 31 Jul 2022 14:50:05 GMT Content-Type: text/html Content-Length: 11 Last-Modified: Sun, 31 Jul 2022 14:39:32 GMT Connection: keep-alive ETag: "62e69424-b" Accept-Ranges: bytes https page
-
nginx负载均衡中常见的算法及原理有哪些?
server backend1.example.com weight=5; weight=N:加权轮询算法 hash KEY [consistent];哈希算法 hash $request_uri consistent; #基于用户请求的uri做hash,参数consistent:一致性哈希 hash $cookie_sessionid #基于cookie中的sessionid这个key进行hash调度,实现会话绑定 ip_hash:ip地址哈希 least_conn;最少连接算法
-
使用rewrite规则实现将所有到a域名的访问rewrite到b域名
[root@centos7 conf.d]# cat web1.conf web2.conf server { listen 80; server_name a.magedu.org; location / { root /data/html/a; index index.html; rewrite / http://b.magedu.org permanent; #permanent 永久重定向,会将重定向信息缓存到磁盘中 } } server { listen 80; server_name b.magedu.org; location / { root /data/html/b; index index.html; } }
-
实现反向代理客户端IP透传
第一个代理服务器 [root@centos7 conf.d]# cat proxy.conf server { listen 80; location / { proxy_pass http://10.0.0.27:80; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } 第二个代理服务器 [root@centos7 conf.d]# cat proxy.conf server { listen 80; location / { proxy_pass http://10.0.0.37:80; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } httpd服务器 [root@centos7 ~]# vim /etc/httpd/conf/httpd.conf LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" \"%{X-Forwarded-For}i\"" combined #修改日志格式增加X-Forwarded-For [root@centos7 ~]# tail -f /var/log/httpd/access_log 10.0.0.27 - - [31/Jul/2022:23:48:03 +0800] "GET / HTTP/1.0" 200 11 "-" "curl/7.81.0" "10.0.0.100, 10.0.0.17" 10.0.0.27 - - [31/Jul/2022:23:48:54 +0800] "GET / HTTP/1.0" 200 11 "-" "curl/7.81.0" "10.0.0.100, 10.0.0.17"
-
利用LNMP实现wordpress站点搭建"
#!/bin/bash yum -y install libaio numactl-libs wget make gcc pcre-devel openssl-devel zlib-devel libxml2-devel bzip2-devel libmcrypt-devel sqlite-devel oniguruma-devel unzip dir=`pwd` install_nginx () { version=nginx-1.18.0 download=/usr/local/src/ install=/apps id nginx >/dev/null || useradd -s /sbin/nologin nginx [ -d ${install} ] || mkdir /apps [ -e ${version}.tar.gz ] || wget -P ${download} http://nginx.org/download/${version}.tar.gz && echo "download nginx" cd ${download} tar -xvf ${download}${version}.tar.gz -C ${download} >/dev/null && echo "archive nginx package" cd ${download}${version} ./configure --prefix=${install}/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module > /dev/null && echo "configure finish" (make -j 4 && make install) > /dev/null && echo "nginx make finish" [ -d ${install}/nginx/run ] || mkdir ${install}/nginx/run chown -R nginx.nginx ${install}/nginx cat > /usr/lib/systemd/system/nginx.service <<EOF [Unit] Description=nginx - high performance web server Documentation=http://nginx.org/en/docs/ After=network-online.target remote-fs.target nss-lookup.target Wants=network-online.target [Service] Type=forking PIDFile=${install}/nginx/run/nginx.pid ExecStart=${install}/nginx/sbin/nginx -c ${install}/nginx/conf/nginx.conf ExecReload=/bin/kill -s HUP $MAINPID ExecStop=/bin/kill -s TERM $MAINPID [Install] WantedBy=multi-user.target EOF systemctl daemon-reload [ -e /usr/sbin/nginx ] || ln -s ${install}/nginx/sbin/nginx /usr/sbin grep -E "${install}/nginx/run/nginx.pid" ${install}/nginx/conf/nginx.conf > /dev/null || sed -ri "s#.*pid.*#pid /apps/nginx/run/nginx.pid;#" ${install}/nginx/conf/nginx.conf } install_php(){ version=php-8.0.20 src=/usr/local/src/ path=/apps/php/ [ -d ${src}${version} ] || tar -xvf ${version}.tar.gz -C ${src} cd ${src}${version} ./configure --prefix=${path} --enable-mysqlnd --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd --with-openssl --with-zlib --with-config-file-path=/etc --with-config-file-scan-dir=/etc/php.d --enable-mbstring --enable-xml --enable-sockets --enable-fpm --enable-maintainer-zts --disable-fileinfo make -j 4 && make install ln -s /apps/php/bin/php /usr/sbin [ -f /etc/profile.d/php.sh ] || echo PATH=${path}bin:$PATH >> /etc/profile.d/php.sh source /etc/profile.d/php.sh cp ${src}${version}/php.ini-production /etc/php.ini cp ${src}${version}/sapi/fpm/php-fpm.service /usr/lib/systemd/system/ cd ${path}etc cp php-fpm.conf.default php-fpm.conf cd php-fpm.d/ cp www.conf.default www.conf grep -e "^user = nginx" ${path}etc/php-fpm.d/www.conf || sed -ri -e "s/user = .*/user = nginx/" -e "s/group = .*/group = nginx/" ${path}etc/php-fpm.d/www.conf mkdir /etc/php.d/ cat > /etc/php.d/opcache.ini <<EOF [opcache] zend_extension=opcache.so opcache.enable=1 EOF systemctl daemon-reload } install_mysql(){ [ -d /usr/local/mysql-5.7.33-linux-glibc2.12-x86_64 ] || tar -xvf mysql-5.7.33-linux-glibc2.12-x86_64.tar.gz -C /usr/local/ [ -d /usr/local/mysql ] || ln -s /usr/local/mysql-5.7.33-linux-glibc2.12-x86_64 /usr/local/mysql id mysql || useradd -r -s /sbin/nologin mysql chown -R root:root /usr/local/mysql ln -s /usr/local/mysql/bin /usr/sbin echo "PATH=/usr/local/mysql/bin:$PATH" >/etc/profile.d/mysql.sh source /etc/profile.d/mysql.sh cp /etc/my.cnf{,.bak} cat > /etc/my.cnf <<EOF [mysqld] server-id=1 log-bin datadir=/data/mysql socket=/data/mysql/mysql.sock log-error=/data/mysql/mysql.log pid-file=/data/mysql/mysql.pid [client] socket=/data/mysql/mysql.sock EOF mysqld --initialize --user=mysql --datadir=/data/mysql if [ -d /etc/init.d/mysqld ] then chkconfig --add mysqld service mysqld start else cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld chkconfig --add mysqld service mysqld start fi PASSWD=`awk '/password/{print $NF}' /data/mysql/mysql.log` mysqladmin -uroot -p"${PASSWD}" password magedu mysql -uroot -pmagedu -e "create database wordpress" mysql -uroot -pmagedu -e "create user wordpress@'10.0.0.%' identified by '123456'" mysql -uroot -pmagedu -e "grant all on wordpress.* to wordpress@'10.0.0.%'" } web(){ [ -d /data/php/ ] || mkdir /data/php/ tar -xvf wordpress-6.0.1-zh_CN.tar.gz -C /data/php/ > /dev/null chown -R nginx:nginx /data/php/wordpress cat /root/nginx.conf > /apps/nginx/conf/nginx.conf [ -d /apps/nginx/conf/conf.d/ ] || mkdir /apps/nginx/conf/conf.d/ cat > /apps/nginx/conf/conf.d/web.conf <<EOF server { listen 80; server_name www.magedu.org; location / { root /data/php/wordpress; index index.php index.html; } location ~ \.php$ { root /data/php/wordpress; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name; include fastcgi_params; } } EOF systemctl restart php-fpm.service ss -ntlp | grep nginx || nginx nginx -s reload } source /etc/profile.d/mysql.sh source /etc/profile.d/php.sh cd ${dir} install_nginx cd ${dir} install_php cd ${dir} install_mysql cd ${dir} web [root@centos7 data]# curl 10.0.0.27 -I HTTP/1.1 200 OK Server: nginx/1.18.0 Date: Sun, 31 Jul 2022 19:40:12 GMT Content-Type: text/html; charset=UTF-8 Connection: keep-alive X-Powered-By: PHP/8.0.20 Link: <http://10.0.0.27/index.php?rest_route=/>; rel="https://api.w.org/"
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
· AI 智能体引爆开源社区「GitHub 热点速览」