nginx
介绍
中文版文档
- http://tengine.taobao.org/nginx_docs/cn/docs/ #(淘宝根据nginx开发的tengine)
简介
- Nginx是俄罗斯人编写的十分轻量级的HTTP服务器,Nginx,发音为“engine X”
- 是一个高性能的HTTP和反向代理服务器
- 同时也是一个IMAP/POP3/SMTP代理服务器
优势
-
支持高并发连接
- 处理2-3万并发连接数,官方监测能支持5万并发
-
CPU与内存占用率非常低
- Nginx官方表示保持10,000个没有活动的连接,它只占2.5M内存,所以类似DOS这样的攻击对Nginx来说基本上是毫无用处的
-
稳定性高
- 宕机的概率非常小
-
节省宽带
- 支持GZIP压缩,可以对文件大小进行压缩,减少了客户端http的传输带宽,可以大幅度提高页面的加载速度
-
配置简单
- 丰富的功能集,模块扩展简单
-
内置健康检查
- 如果有一个服务器宕机,会做一个健康检查,再发送的请求就不会发送到宕机的服务器了。重新将请求提交到其他的节点上
-
可实现http服务器、虚拟主机、反向代理、负载均衡
-
接收用户请求是异步的
缺点
-
动态处理差
- nginx处理静态文件好,耗费内存少,但是处理动态页面则很鸡肋
版本类型
-
Mainline version
- Nginx目前主力在做的版本,可以说是开发版
-
Stable version
- 最新稳定版,生产环境上建议使用的版本
-
Legacy versions
- 老版本的稳定版
官方地址
-
下载
- http://nginx.org/en/download.html
-
配置指令
- http://nginx.org/en/docs/dirindex.html
-
配置变量
- http://nginx.org/en/docs/varindex.html
安装
编译
-
停止原有web服务器
-
创建账号
- useradd -M -s /sbin/nologin nginx
-
下载
- wget http://nginx.org/download/nginx-1.18.0.tar.gz
- tar xf nginx-1.18.0.tar.gz
-
环境准备
- yum -y install gcc gcc-c++ pcre-devel openssl-devel
-
预编译
-
cd nginx-1.18.0
-
./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module --with-http_ssl_module --sbin-path=/usr/sbin/
-
选项
-
–prefix=/usr/local/nginx
- 指定安装路径
-
–with-http_stub_status_module
- 启用service status页,默认不启用
-
–with-http_ssl_module
- 启用ssl模块,以支持https请求
-
–sbin-path=/usr/sbin/
- 指定二进制命令的路径
-
-
-
编译安装
- make && make install
-
使用
-
nginx
- 启动
-
选项
-
-?,-h
- 帮助
-
-v
- 查看版本号
-
-V
- 查看版本号及编译选项
-
-s signal
- 给主进程发送信号:stop,quit,reopen,reload
-
-t
- 测试配置是否正确
-
-c
- 指定配置文件,默认为安装目录下 conf/nginx.conf
-
-
-
测试主页是否可以访问
yum
-
epel源安装
- yum -y install nginx
-
主目录
- /etc/nginx
-
主配置文件
- /etc/nginx/nginx.conf
-
文档目录
- /usr/share/nginx/html
配置文件
位置
-
编译
- /usr/local/nginx/conf/nginx.conf
-
yum
- /etc/nginx/nginx.conf
格式
- 配置命令以分号结尾
模块
-
全局块
- 配置影响nginx全局的指令
- #user nobody; #nginx用户及组,名字一样可只写一个。开启并改为nginx
worker_processes 1; #nginx的worker进程数(cpu)。可设为“auto”自动检测
#error_log logs/error.log; #日志保存路径,可接告警级别,默认error
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid; #nginx进程pid存放路径
-
events块
-
配置影响nginx服务器或与用户的网络连接
-
events {
worker_connections 1024; #每个工作进程的最大连接数,根据需要调整大小
} -
上下文
- main(全局)
-
-
http块
- 可以嵌套多个server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置
- http {
include mime.types; #文件扩展名与文件类型映射表
default_type application/octet-stream;
#server_tokens off; #隐藏软件版本号(安全性)
#log_format main '$remote_addr - r e m o t e u s e r [ remote_user [ remoteuser[time_local] “$request” ’
'$status b o d y b y t e s s e n t " body_bytes_sent " bodybytessent"http_referer" ’
‘“ h t t p u s e r a g e n t " " http_user_agent" " httpuseragent""http_x_forwarded_for”’; #定义访问日志格式,使用main时开启
#access_log logs/access.log main; #定义访问日志文件
sendfile on; #开启高效文件传输模式
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65; #长连接超时时间
#gzip on;
server {
…
}-
上下文
- main
-
server块
-
配置虚拟主机的相关参数,一个http中可以有多个server
-
server {
listen 80; #监听套接字,默认IP本机地址,默认端口80
server_name localhost; #主机名称,可写域名
location 目录 {
…
}
} -
上下文
- http
-
-
location块
-
配置请求的路由,以及各种页面的处理情况
-
location / { #以/开头的uri,即所有uri都能匹配到
root html; #发布目录,默认为安装目录下的html目录
index index.html index.htm; #索引文件名称
autoindex on; #目录中无index时列出文件列表, 默认off
} -
上下文
- server,location
-
上下文
- 指令放置的环境,即可在哪些模块内配置。main即全局
自定义日志
模块
- ngx_http_log_module
配置
-
log_format cust ‘$remote_addr : $time_local : $http_user_agent’;
access_log logs/access.log cust; #cust:自定义的日志名称 -
上下文
-
log_format
- http
-
access_log
- http, server, location, if in location, limit_except
-
变量
-
$remote_addr
- 客户端ip
-
$remote_user
- 用户名(为基本用户认证提供的用户名, 通常没有)
-
$time_local
- 访问时间
-
$request
- 请求行
-
$status
- 状态码
-
$body_bytes_sent
- 返回给客户端的字节数,不含响应头
-
$http_referer
- 从哪个页面链接访问过来的
-
$http_user_agent
- 客户端浏览器
-
$http_x_forwarded_for
- 客户端ip
虚拟主机
基于域名
- server {
listen 80 [default]; #设为default则访问IP时默认
server_name www.qf2.com;
access_log www/qf2/logs/access.log main;
error_log www/qf2/logs/error.log;
location / {
root www/qf2/html;
index index.html index.htm;
}
}
基于IP
- server {
listen 1.1.1.22:80;
server_name localhost;
access_log www/qf2/logs/access.log main;
error_log www/qf2/logs/error.log;
location / {
root www/qf2/html;
index index.html index.htm;
}
}
基于端口
- server {
listen 8001;
server_name localhost;
access_log www/qf2/logs/access.log main;
error_log www/qf2/logs/error.log;
location / {
root www/qf2/html;
index index.html index.htm;
}
}
访问控制
用户认证
-
配置内容
- auth_basic “user&passwd”; #认证描述信息
auth_basic_user_file /usr/local/nginx/.passwd; #用户认证文件(绝对路径)
- auth_basic “user&passwd”; #认证描述信息
-
上下文
- http, server, location, limit_except
-
创建用户
-
yum -y install httpd-tools
-
htpasswd -c /usr/local/nginx/.passwd user1
- -c创建文件
-
htpasswd /usr/local/nginx/.passwd user2
-
访问控制
-
deny/allow
-
顺序从上往下匹配,匹配到即停止
-
配置
-
指令
- allow 192.168.10.0/24;
deny all;
- allow 192.168.10.0/24;
-
上下文
- http, server, location, limit_except
-
-
-
黑/白名单
-
使用geo模块定义一个访问控制的黑/白名单
-
配置
-
geo
-
定义
- #根据客户端IP给变量定义不同的值
geo $black_list {
default 0;
192.168.10.11 1;
127.0.0.1 1;
}
- #根据客户端IP给变量定义不同的值
-
上下文
- http
-
-
if
-
内容
- #变量值为真(非0)则执行
if ($black_list) {
return 403; #停止处理并返回指定状态码
}
- #变量值为真(非0)则执行
-
上下文
- server, location
-
-
-
-
限速
-
指令
-
limit_rate
- 限速, 1.17.0以上支持使用变量
-
map
- 根据一个变量的值来定义另一个变量的值
-
geo
- 根据IP定义变量的值
-
-
配置
-
geo
-
定义
- geo $limit {
default 2;
192.168.10.11 1;
127.0.0.1 0;
}
- geo $limit {
-
上下文
- http
-
-
map
-
定义
- map $limit $rate {
2 128k;
1 1m;
0 0; #0表示不限速
}
- map $limit $rate {
-
上下文
- http
-
-
limit_rate
-
指令
- autoindex on;
limit_rate $rate;
- autoindex on;
-
上下文
- http, server, location
http, server, location, if in location
- http, server, location
-
-
-
模块
-
ngx_http_access_module
- allow、deny
-
ngx_http_auth_basic_module
- auth_basic、auth_basic_user_file
状态访问统计
模块
- ngx_http_stub_status_module
server块配置
- location = /status {
stub_status on;
access_log off;
}
查看
- 浏览器:http://192.168.10.11/status
- Active connections: 557
server accepts handled requests
36 36 43
Reading: 3 Writing: 16 Waiting: 538
信息
-
Active connections
- 活跃连接数
-
server accepts handled requests
- nginx总共处理了36个连接, 成功创建36次握手 (相等表示没有失败的), 总共处理了43个请求
-
Reading
- nginx读取到客户端的Header信息数
-
Writing
- nginx返回给客户端的Header信息数
-
Waiting
- 开启keep-alive的情况下,这个值等于active - (reading + writing),意思就是Nginx说已经处理完正在等候下一次请求指令的驻留连接
添加模块
yum安装与编译安装的添加模块方法基本一致
步骤
-
查看版本及编译选项
-
nginx -V
- nginx -V 2>&1 |grep realip
-
-
下载相同版本的nginx的源码包
- wget http://nginx.org/download/nginx-xxxx
- tar xf nginx-xxxx;cd nginx-xxxx
-
将原来的nginx重要文件备份
- cp -rf /etc/nginx /etc/nginx.back
-
官方模块
-
查看nginx支持的模块
-
./configure --help
- disable代表已编译此模块
- enable代表未编译此模块
-
-
-
第三方模块
-
下载
- wget https://github.com/openresty/echo-nginx-module/archive/v0.61.tar.gz
-
解压
- mkdir /usr/local/nginx/modules
- tar xf v0.61.tar.gz -C /usr/local/nginx/modules
-
-
重新编译
-
./configure 原来的编译选项 新增的编译选项
-
新增的编译选项
-
官方
- ./configure --help左边部分,如:–with-http_realip_module
-
三方
- –add-module=第三方模块的绝对路径
- –add-module=/usr/local/nginx/modules/echo-nginx-module-0.61/
-
-
make
-
-
替换启动程序
- 编译成后会在objs目录下生成一个nginx启动文件
- mv /usr/sbin/nginx{,.bak};cp objs/nginx /usr/sbin/
-
重启nginx服务
第三方模块
(nginx-echo)
-
应用
- echo模块主要用于调试及排错。其他三方模块安装方式类似
-
文档
- https://github.com/openresty/echo-nginx-module
-
指令
-
echo
- 可输出字符或变量,自带换行符,支持转义字符
- location = /test {
echo “hello,qf!”;
echo “$remote_addr”;
}
-
echo_sleep
- 暂停,后面接数字,单位为秒
-
echo_before_body
echo_after_body- 页面前后输出
- location /echo {
echo_before_body “begin”;
proxy_pass http://192.168.10.42/echo;
echo_after_body “end”;
}
-
echo_duplicate
-
------ END ------
常用模块
-
ngx_http_core_module
-
ngx_http_access_module
- allow、deny
-
ngx_http_auth_basic_module
- auth_basic、auth_basic_user_file
-
ngx_http_stub_status_module
- stub_status
-
ngx_http_log_module
- log_format
-
ngx_http_gzip_module
- 压缩模块,有利于传输数据的大小减少,但是cpu使用会变高。因为要对传输的数据进行压缩
-
ngx_http_ssl_module
- 设置https连接的模块
-
ngx_http_rewrite_module
- rewrite、return、if
-
ngx_http_referer_module
- 可以基于这个模块做防盗链
-
ngx_http_headers_module
- 向由代理服务器响应给客户端的响应报文添加自定义首部,或修改指定首部的值
-
ngx_http_upstream_module
- 负载均衡
-
ngx_http_proxy_module
- 代理、缓存
location
语法
-
location [修饰符] uri {…}
- 用于匹配客户请求uri
-
uri
- 统一资源标志符,表示的是web上每一种可用的资源
- 如HTML文档、图像、视频片段、程序等都由一个URI进行标识的
修饰符
-
=
-
精确匹配,优先级最高
- location = /test {…}
-
-
^~
-
前缀匹配,优先级高于正则匹配
- location ^~ /test/ {…}
-
-
~
-
正则匹配,区分大小写
- location ~ .(jpg|png|gif)$ {…}
-
-
~*
- 正则匹配,不区分大小写
- 没有修饰符,优先级最低。也是前缀匹配
- 精确度高的优先
优先级顺序
- 精确匹配>前缀匹配>正则匹配>无修饰
注意
- 优先级的高低与location出现的顺序无关
- 尽量使用单一的location修饰符去完成任务
- 若uri为/,表示匹配所有.其他location未匹配到的均能匹配到
实验
-
配置
- server {
listen 80;
server_name www.qf.com;
location / {
root /www/a;
index index.html;
}
location = / {
root /www/b;
index index.html;
}
location ^~ /doc/ {
root /www/c;
index index.html;
}
location ~* .(jpe?g|png|gif$) {
root /www/d;
}
location /bbs/ {
root /www/e;
index index.html;
}
}
- server {
-
访问
-
http://www.qf.com
http://www.qf.com/-
/www/b/index.html
-
uri重写
- http://www.qf.com/index.html
- /www/a/index.html
-
-
-
http://www.qf.com/index.html
- /www/a/index.html
-
http://www.qf.com/cat.png
- /www/d/cat.png
-
http://www.qf.com/doc/index.html
- /www/c/doc/index.html
-
http://www.qf.com/doc/cat.png
- /www/c/doc/cat.png
-
http://www.qf.com/bbs/cat.png
- /www/d/bbs/cat.png
-
http://www.qf.com/bbs/index.html
- /www/e/bbs/index.html
-
alias
-
用法
- alias path
- 用于定义指定路径的替换路径
-
配置
- location /i/ {
alias /data/w3/images/;
}
- location /i/ {
-
访问
- “/i/top.gif” 将由 /data/w3/images/top.gif文件来响应
-
变量
- path的值可以包含变量,但不能使用$document_root和 $realpath_root这两个变量
-
正则
-
若使用正则,则正则表达式中需含有匹配组, 且path引用匹配组来组成一个完整的文件路径
-
如
-
配置
- location ~ ^/users/(.+.(?:gif|jpe?g|png))$ {
alias /data/w3/images/$1; #$1引用第1个匹配组(()中匹配内容)
}
- location ~ ^/users/(.+.(?:gif|jpe?g|png))$ {
-
访问
- “/users/top.gif” 由 /data/w3/images/top.gif文件响应
-
-
PCRE正则表达式
()分组匹配
-
(pattern)
- 匹配pattern并获取这一匹配
-
(?:pattern)
- 匹配pattern但不获取匹配结果
-
(?=pattern)
- 正向预查
-
(?!pattern)
- 负向预查
字符
-
\d
- [0-9]
-
\D
- [^0-9]
-
\s
- 任何空白字符
-
\S
- 任何非空白字符
-
\w
- 任何单词字符:字母、数字、下划线
-
\W
- 任何非单词字符
其他
-
\f
- 换页符
-
\n
- 换行符
-
\r
- 回车符
-
\t
- 制表符
-
\b
- 单词边界
-
\B
- 非单词边界
前期所学正则
正则测试工具
- https://tool.lu/regex/
rewrite
介绍
- Rewrite 是Nginx提供的一个重要基本功能,用于实现URL的重写
- 比如它可以让我们在改变网站结构后,仍使用原来的uri进行访问
- Nginx的Rewrite功能的实现依赖于PCRE库的支持
if指令
-
用法
-
if (condition) { … }
-
上下文
- server, location
-
如果condition为真,执行定义在大括号中的指令。if指令会从上一层配置中继承配置
-
-
condition
-
变量名
- 如果变量值为空或者是0,则条件为假
- 在1.0.1版本以前,任何以0开头的值都为假
-
使用“=”和“!=”运算符比较变量和字符串
-
使用“”和“*”匹配变量和正则表达式
- 正则表达式可以包含匹配组,使用变量$1…$9引用
- 正则表达式中包含字符“}”或者“;”,整个表达式需使用引号
-
文件
- “-f”和“!-f”,普通文件是否存在
- “-d”和“!-d”,目录是否存在
- “-e”和“!-e”,文件、目录或符号链接是否存在
- “-x”和“!-x”,是否为可执行文件
-
-
示例
-
if ( h o s t [ 0 − 9 ] host ~ [0-9] host [0−9]) {
return 403;
}- 禁止使用IP访问
-
if (KaTeX parse error: Expected '}', got 'EOF' at end of input: …{ rewrite ^(.*) /msie/$1 last;
} -
if ($slow) {
limit_rate 10k;
}
-
rewrite指令
-
介绍
- 通过正则表达式的使用改变URI
- 可以同时存在一个或者多个指令,按照顺序依次对URL进行匹配和处理
-
执行顺序
- 先执行server中的rewrite(如果有的话),得到新的URI, 只执行一次(无论修饰符是last还是break)
- 在location中匹配新的URI
- 执行location中的rewrite(如果有的话),根据修饰符决定是否再次location匹配
-
用法
-
指令
- rewrite regex replacement [flag];
-
上下文
- server, location, if
-
regex
- 用于匹配URI的正则表达式。使用"()"标记要截取的内容
- rewrite接受到的URI不包含URL中的HOST地址和参数
-
replacement
- 匹配成功后用于替换uri中被截取内容的字符串
- 如果是完整的url(http://或https://), 则直接将该url重写返回给客户端
- 如果接了新的请求参数,之前的参数会加到新参数后面。不想加则在末尾接"?"
-
flag
-
last
-
匹配后继续匹配改变后的uri
- 可能造成无限循环,超过10次停止并返回500错误
-
-
break
- 匹配后停止匹配
-
redirect
- 返回状态码为302的临时重定向
-
permanent
- 返回状态码为301的永久重定向
-
-
-
示例
- if (KaTeX parse error: Expected '}', got 'EOF' at end of input: …{ rewrite ^(.*) /msie/$1 break;
}
#如果UA包含"MSIE",rewrite请求到/msid/目录下 - if ($args ~ post=140) {
rewrite ^ http://example.com/ permanent;
}
#如果query string中包含"post=140",则永久重定向到example.com - server {
listen 80;
server_name my.domain.com;
rewrite ^ https://www.xxx.comKaTeX parse error: Expected 'EOF', got '#' at position 25: …ri? permanent; #̲或rewrite ^/(.*) https://www.xxx.com/$1 permanent;
}
将80端口永久重定向到https
- if (KaTeX parse error: Expected '}', got 'EOF' at end of input: …{ rewrite ^(.*) /msie/$1 break;
return指令
-
语法
-
return code [text];
- 204,400,402-406,408,410,411,413,416,500-504
-
return code URL;
- 301,302,303,307,308
-
return URL;
-
-
上下文
- server, location, if
-
示例
-
server {
listen 80;
server_name my.domain.com;
return 301 https:// s e r v e r n a m e server_name servernamerequest_uri;
}-
将80端口永久重定向到https
-
$server_name
- 接受请求的服务器的名称
-
$request_uri
- 完整的原始请求 URI(带参数)
-
-
缓存
介绍
- 缓存一般存的是静态资源
- 缓存可以提高客户端的访问速度,并能减轻服务器的压力
客户端缓存
-
介绍
- 通过设置expires指令,响应头中将会返回Expires和Cache-Control字段
- 当浏览器发现响应头存在缓存字段,再次请求相同资源时,会确认在客户端的资源是否过期
- 浏览器在不强制刷新的情况下可使用有效期内的缓存
-
expires
-
配置
- location ~ ..(html)$ {
expires 30m; #有效期30分钟
}
location ~ ..(js|css)?$ {
expires 1d; #有效期1天
}
- location ~ ..(html)$ {
-
上下文
- http, server, location, if in location
-
-
查看响应头
- curl -I 192.168.10.11
- Cache-Control: max-age=3600
服务器端缓存
-
介绍
- 主要设置在反向代理服务器上
- 当多个用户访问同一个资源时,缓存命中率及系统的性能将以指数的形式提升
-
配置
-
http块
- proxy_cache_path /usr/local/nginx/cache levels=1:2:2 keys_zone=test:20m max_size=1g;
-
location块
- proxy_cache test;
proxy_cache_valid 200 10m;
proxy_pass http://192.168.10.12;
- proxy_cache test;
-
-
指令
-
proxy_cache_path
-
用法
- proxy_cache_path path [levels=number] keys_zone=zone_name:zone_size [inactive=time] [max_size=size];
- 使用字段:http
- 指定缓存的路径和一些其他参数,缓存的数据存储在文件中,并且使用代理url的哈希值作为关键字与文件名
-
参数
-
levels
- 目录结构,可以使用任意的1位或2位数字作为目录结构
- 如 X, X:X或X:X:X ,最多三级。X为目录名字符数
-
keys_zone
- 指定所有活动的key和元数据存储的共享内存池区域
- 可以定义多个内存池,但必须是不重复的路径
-
inactive
- 指定缓存数据的失效时间,默认为10分钟
-
max_size
- 定义最大缓存大小,超出后则删除最少使用的数据
-
-
-
proxy_cache
- proxy_cache zone_name;
- 使用字段:http, server, location
- 设置一个缓存区域的名称,一个相同的区域可以在不同的地方使用
-
proxy_cache_valid
-
用法
- proxy_cache_valid reply_code [reply_code …] time;
- 使用字段:http, server, location
- 为不同的应答设置不同的缓存时间。any表示任何应答
- 如果只定义时间,只对代码为200, 301和302的应答进行缓存
-
示例
- proxy_cache_valid 200 302 10m;
- proxy_cache_valid 404 1m;
- proxy_cache_valid any 1m;
- proxy_cache_valid 5m;
-
-
负载均衡
代理(Proxy)
-
简介
- 是一种特殊的网络服务,允许一个网络终端通过这个服务与另一个网络终端进行非直接的连接
- 一些网关、路由器等网络设备具备网络代理功能
- 一般认为代理服务有助于保障网络终端的隐私或安全,防止攻击
-
类型
-
正向代理服务器
(标准代理服务器)-
目的
- 内网用户通过代理服务器能够访问外网的服务器
-
原理
- 内网用户将请求发给代理服务器,代理服务器向真正的web服务器发出请求,然后获取到网页内容在本地缓存并发给用户
-
缺点
- 需要用户对浏览器进行设置
-
-
透明代理服务器
- 目的和原理与正向代理一致,但一般布署在网关上,用户不需要再对浏览器进行设置
-
反向代理服务器
(反向加速服务器)-
目的
- 外网客户端通过代理服务器,能够访问内网服务器的资源
-
原理
- 外网客户端访问正常的域名或者IP,其实访问的是代理服务器,代理服务器帮助客户端请求页面,在代理服务器上缓存,然后再发送给客户端
-
-
反向代理
(7层)
-
配置反向代理
-
nginx反向代理功能由ngx_http_proxy_module模块提供
-
配置
- location / {
proxy_pass http://192.168.10.12;
} - 将所有的访问请求代理到后端服务器 http://192.168.10.12 上
- location / {
-
使用客户端访问代理服务器,将能获取后端真实服务器的内容
-
-
proxy_pass指令
-
特性
- 当proxy_pass指令后面不带URI时,将把所有的原始URI拼接到代理后的服务器上
- 当proxy_pass指令后面带URI时,将把该URI替换掉location匹配的URI
- 当使用正则匹配时,proxy_pass指令后面不应带URI
-
示例
- 访问URL:http://1.1.1.11/static/index.html
- location /static/ {
proxy_pass http://1.1.1.12; #代理到:http://1.1.1.12/static/index.html
proxy_pass http://1.1.1.12/; #代理到:http://1.1.1.12/index.html
proxy_pass http://1.1.1.12/abc; #代理到:http://1.1.1.12/abcindex.html
proxy_pass http://1.1.1.12/abc/; #代理到:http://1.1.1.12/abc/index.html
}
-
-
真实IP
-
背景
- 对于服务器而言,直接的客户端是代理服务器,所以默认日志记录的是代理的IP
- 所以客户端的真实IP需要通过代理服务器传递给后端服务器
- 可以在代理服务器上将客户端的IP封装到请求报文中发送给后端服务器
-
获取
-
单个代理
-
代理服务器
- location / {
proxy_pass http://webs;
proxy_set_header x-real-ip $remote_addr;
- location / {
-
-
-
将$remote_addr的值封装到请求报文头部的x-real-ip(自定义)字段中
}
- 后端服务器
- nginx
- 方式一
- 将log_format中$remote_addr改为$http_x_real_ip
- 方式二
- 安装real_ip模块(官方,yum自带):ngx_http_realip_module
- 修改配置
- location / {
root html;
index index.html index.htm;
set_real_ip_from 代理服务器IP;
real_ip_header x-real-ip;
}
- apache
- 将LogFormat中%h改为%{x-real-ip}i
- 多级代理
- 方式一
- 第一个代理
- proxy_set_header X-Forwarded-For $remote_addr;
- 后面的代理
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- 后端服务器
- set_real_ip_from 最后一个代理IP;
real_ip_header X-Forwarded-For; #指定从哪个字段获取
real_ip_recursive on; #递归解析,用字段中第一个IP
- 方式二
- 第一个代理
- proxy_set_header X-Real-IP $remote_addr;
- 后面的代理
- proxy_set_header X-Real-IP $http_x_real_ip;
- 后端服务器
- 将log_format中$remote_addr改为$http_x_real_ip
- IP变量
- $remote_addr
- 直接与服务器通信的客户端的IP地址
- $http_x_real_ip
- 从请求报文首部的X-Real-IP字段获取值
- $http_x_forwarded_for
- 从请求报文首部的X-Forwarded-For字段获取的值
- $realip_remote_addr
- 最后一个反向代理服务器的IP(realip模块提供)
- $proxy_add_x_forwarded_for
- proxy_set_header x-forwarded-for $proxy_add_x_forward_for
- $proxy_add_x_forward_for=$x_forwarded_for,$remote_addr
- $http_x_forwarded_for + $realip_remote_addr 记录了后端服务器前面所有节点的IP
负载均衡
-
该功能由ngx_http_upstream_module + ngx_http_proxy_module模块提供
-
服务器组的配置
-
upstream指令
-
语法: upstream name { … }
默认: —
语境: http -
示例
- upstream backend {
server 192.168.10.11 weight=5;
server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
server 192.168.10.12;
server 192.168.10.13 backup;
}
- upstream backend {
-
-
server指令
-
语法: server address [参数];
默认: —
语境: upstream -
address
- 后端服务器 ipaddress:port,默认端口可省略
-
参数
-
weight=N
- 定义权值,默认为1
-
max_conns=N
- 限制最大连接数,默认为0不限制
-
backup
- 备用服务器,当所有主服务器都宕机后才会起用
-
down
- 不起用的服务器
-
max_fails=N
- 判定服务器失效的连接失败次数
-
fail_timeout=Ns
- 心跳检测响应超时秒数,超时未响应则认为失败
-
-
-
-
配置负载均衡
- location / {
proxy_pass http://backend; #将请求代理到服务器组中,即负载均衡
}
- location / {
-
调度算法
-
官方
-
轮循
-
将所有的请求平均调度到后端所有的服务器上,不考虑服务器之间的差异及后端服务器的真实负载情况,是一种静态策略
-
示例
- upstream backend {
server 192.168.10.12;
server 192.168.10.13;
}
- upstream backend {
-
-
加权轮循
-
将后端服务器设置为不同的权值,权值高的服务器承担更多的负载,不考虑后端服务器的真实负载情况,是一种静态策略
-
示例
- upstream backend {
server 192.168.10.12 weight=1;
server 192.168.10.13 weight=2;
}
- upstream backend {
-
-
ip_hash
-
根据客户端ip的前三个字节的hash值进行调度,可实现把同一客户端的请求调度到同一台后端服务器上(session保持)
-
示例
- upstream backend {
ip_hash;
server 192.168.10.12;
server 192.168.10.13;
}
- upstream backend {
-
-
least_conn
-
将请求传递到活动连接数最少的服务器,同时考虑权重。如果有多个这样的服务器,则使用加权循环平衡方法轮流尝试它们
-
示例
- upstream backend {
least_conn;
server 192.168.10.12 weight=1;
server 192.168.10.13 weight=2;
}
- upstream backend {
-
-
hash key
- 根据自定义 key 的 hash 值进行调度。该 key 可以包含文本,变量,以及它们的组合
- 从组中添加或删除服务器可能会导致将大多数密钥重新映射到不同的服务器
-
random
-
语法
-
random [two [method]]
- 1.15.1
-
-
将请求传递到随机选择的服务器,同时考虑服务器的权重
-
可选two参数指示nginx随机选择两个服务器,然后使用指定的method. 默认least_conn
-
-
-
第三方
-
url_hash
-
模块
- ngx_http_upstream_hash_module
-
按访问URL的hash值进行调度,可实现同一个URL访问到同一台服务器。适用于后端服务器为缓存服务器
-
-
fair
-
模块
- ngx_http_upstream_fair_module
-
按后端服务器的响应时间来分配请求,响应时间短的优先分配
-
-
-
防盗链
介绍
-
盗链
- 服务器响应给客户端的资源,并非存储在自己服务器上,而是链接其他服务器的资源
-
Referer头域
- HTTP协议中的请求头的Referer头域,可以检测到访问目标资源的源地址
- 如果我们检测到Referer头域中的值并不是自己站点内的URL时就采取阻止措施,实现防盗链
- 但是任何HTTP协议头都会有可能被篡改,因此这种方法并不能完全的阻止盗链行为
配置
-
valid_referers
-
用法
- valid_referers none | blocked | server_names | string …;
- 用来获取Referer头域中的值,并根据该值的情况给$invalid_referer赋值
- 如果Referer中没有符合valid_referers指令配置的值,$invalid_referer置为1
-
参数
-
none
- HTTP头中不存在Referer头域(本机直接访问目标资源)
-
blocked
- 存在Referer头域,但里面的值有可能由于防火墙或者代理服务器的原因被删除或者伪装
- 这种情况下,该头域的值以"http://" 或者 “https://” 开头
-
server_names
- 设置一个或者多个域名, 检测Referer头域的值是不是这些域名中的某个。支持使用通配符*
-
-
-
实例
- location ~ .(jpe?g|png|gif) {
root html;
index index.html;
valid_referers none blocked 1.1.1.22 *.baidu.com;
if ($invalid_referer) {
return 403;
}
}
- location ~ .(jpe?g|png|gif) {
平滑升级
官方文档
- http://nginx.org/en/docs/control.html
主进程下信号
-
- HUP
- 挂起/reload,再次输入恢复启用
-
- INT
- 快速关闭,终止当前操作的请求。同 Ctrl + C
-
- QUIT
- 退出。同 Ctrl + \
-
- USR2
- 升级可执行文件
-
- TERM
- 快速关闭,请求彻底终止某项执行操作
-
- WINCH
- 正常关闭工作进程
目的
- 不中断服务的情况下,升级版本或者调整服务器模块
前提
- 服务以绝对路径启动才能实现
步骤
-
查看旧版编译选项
- nginx -V
-
编译新版
- ./configure
- make
-
替换命令
- mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak
- cp objs/nginx /usr/local/nginx/sbin/
-
启动新进程
- kill -USR2
cat /usr/local/nginx/logs/nginx.pid
- 主进程会将.pid重命名为.oldbin,执行新的可执行程序,依次启动新的主进程和新的工作进程
- kill -USR2
-
停止旧进程
-
kill -WINCH
cat /usr/local/nginx/logs/nginx.pid.oldbin
- 停止工作进程
-
kill -QUIT
cat /usr/local/nginx/logs/nginx.pid.oldbin
- 停止主进程
-
倒回
-
时间点
- 旧的主进程关闭前
-
步骤
-
发送HUP信号给旧的主进程
- 它将在不重载配置文件的情况下启动它的工作进程
-
发送QUIT信号给新的主进程
- 要求其从容关闭其工作进程
-
发送TERM信号给新的主进程
-
如果因为某些原因新的工作进程不能退出,向其发送 KILL 信号
-
新的主进程退出后,旧的主进程会由移除 .oldbin 前缀,恢复为它的 .pid 文件
-
状态码
2xx
-
表示⼀个HTTP请求成功
-
200
- 表示⼀个HTTP请求得到了正确的响应
3xx
-
主要表示HTTP请求URL重定向⾏为
-
301
- URL 永久性重定向。在Nginx中通过rewrite 指令结合 permanent 标记实现
- rewrite ^(.*)$ /index.html permanent;
-
302
- URL 临时重定向。在Nginx中通过rewrite 指令结合 redirect 标记实现
- rewrite ^(.*)$ /index.html redirect;
-
301 VS 302
- 对⽤户⽽⾔没有感官上的区别。都是访问A跳转到B,浏览器上的地址由A变成了B
- 主要区别在于搜索引擎,301时搜索引擎会将A地址相关信息带到B,并且废弃A地址,302无此行为
-
304
- 客户端缓存。通过Nginx 中的 expires 指令完成
- expires 1d;
- 第一次访问会返回200,在缓存有效期内下次访问则返回304
4xx
-
主要表示客户端错误。客户端发起的HTTP请求头不完整、客户度使⽤的⽤户名、密码错误等等
-
400
- 当WEB服务器遇到不完整的HTTP请求头时,会返回400状态码
- 请求头信息或者Cookie信息过⼤,通常是导致不完整的请求头的原因
- nginx中通过large_client_header_buffers配置最大值
-
401
- ⽤户名、密码等权限认证错误
-
403
- 没有权限访问。⽂件权限过⼩或者⼈为设置访问控制等
-
404
- 访问的⽂件不存在
-
499
- Nginx⾃⼰定义的⼀个状态码。在Nginx返回结果之前主动断开客户端连接时出现
5xx
-
主要表示服务端错误
-
500
-
500错误指的是服务器内部错误,也就是服务器遇到意外情况,而无法履行请求
-
常见原因
- web脚本错误,如php语法错误,lua语法错误等
- rewrite重写导致死循环,循环超过10次时停止并返回500错误
- 访问量大的时候,由于系统资源限制,而不能打开过多的文件
-
分析思路
- 查看nginx代理error log ,查看后端服务器error log
- 如果是too many open files,修改nginx的worker_rlimit_nofile参数,使用ulimit查看系统打开文件限制,修改/etc/security/limits.conf
- 如果是脚本的问题,则需要修复脚本错误,并优化代码
- 各种优化都做好,还是出现too many open files,那就要考虑做负载均衡,把流量分散到不同服务器上去了
-
-
502,504
-
使用nginx代理,而后端服务器发生故障
-
常见原因
- 访问量大,后端服务器进程不够用
- 后端进程执行时间长或者某种原因导致进程终止
-
502
- 网关错误,代理模式下后端服务器出现问题
-
504
- 请求超时,后端服务器的执⾏时间⼤于Nginx的读超时时间
-
-
503
- ervice Temporarily Unavailable错误
- 单个ip并发设置过小会导致503报错
动静分离
介绍
-
动
- 动态脚本请求
-
静
- 静态页面请求
-
分离
- 动态的请求和静态的请求在一台服务器分离出来, 由nginx-web-server处理静态页面请求, 由PHP处理动态请求(php脚本)
-
fastcgi
-
CGI
- 通用网关接口,web-server和动态的脚本语言之间进行通信的接口
-
fastCGI
- 高速通用网关接口
-
运行原理
- fastcgi在linux下是socket,需要通过应用程序wrapper调用CGI程序,这个wrapper绑定在socket上
- nginx将动态的HTTP请求交给socket,通过fastcgi接口,由wrapper接受请求,然后派生出一个线程,调用请求数据
- wrapper将得到的数据通过fastcgi接口通过 socket交给nginx
- nginx把数据交给客户端
-
LNMP架构
-
组成
- linux+nginx+mysql+php
-
实验
- 搭建个人博客
-
架构模式
-
allinone
- nginx、mysql、php部署在同一台服务器
-
全分离
- nginx、mysql、php分别部署在不同服务器
-
-
安装
-
nginx
-
mysql
-
php
- yum -y install libxml2-devel libpng-devel
- tar xf php-5.6.30.tar.gz
- cd php-5.6.30
- ./configure --prefix=/usr/local/php5 --with-gd --with-zlib --with-mysql=mysqlnd --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd --with-config-file-path=/usr/local/php5 --enable-mbstring --enable-fpm
- make && make install
- cd /usr/local/php5/etc/
- cp php-fpm.conf.default php-fpm.conf
-
-
配置
user nginx;
…
server {
listen 80;
server_name localhost;
location / {
root /www;
index index.html index.htm index.php;
}
location ~ .php$ {
root /www;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME
d
o
c
u
m
e
n
t
r
o
o
t
document_root
documentrootfastcgi_script_name;
include fastcgi_params;
}
}
- mkdir /www;chown nginx.nginx /www -R
- mysql
- >create database wordpress;
grant all on wordpress.* to wordpress@localhost identified by ‘Wordpress@123’;
- php
- # vim /usr/local/php5/etc/php-fpm.conf
user = nginx
group = nginx
pm.max_children = 20
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 10
- 全分离
- php
1.1.1.11
- 配置文件
- 在allinone的配置基础上修改listen为1.1.1.11:9000
- nfs
- mkdir /www
- echo "/www 1.1.1.22(rw,no_root_squash)" >> /etc/exports
- nginx
1.1.1.22
- 配置文件
- 在allinone的配置基础上修改fastcgi_pass为1.1.1.11:9000
- nfs
- mount 1.1.1.11:/www /www
- mysql
1.1.1.21
- >create database wordpress;
<?php phpinfo(); ?>grant all on wordpress.* to wordpress@1.1.1.11 identified by ‘Wordpress@123’;
- 在浏览器中访问nginx的ip, 如果能得到PHP的信息,说明测试通过
- 测试PHP连接数据库
- # vim /www/index.php
<?php mysql_connect('127.0.0.1','wordpress','Wordpress@123') or die('failed'); echo 'success' ; ?>
- 刷新页面, 如果输出success则测试通过
-
安装应用
- tar xf wordpress-4.5.3-zh_CN.tar.gz
- mv wordpress/* /www/;chown nginx.nginx /www -R
- 进WEB页面安装
curl
介绍
- 在命令行中利用URL进行数据或者文件传输
语法
-
curl [参数] url
- 默认直接访问url
参数
-
-H/–header
- 自定义http头部信息传递给服务器
- curl -H “Host:hhhh” 1.1.1.22
-
-I/–head
- 只显示文档信息(http头部)
- curl -I 192.168.10.11
-
-o/–output file
- 把输出写到该file中
- curl -o home.html http://blog.51yip.com
-
-O/–remote-name
- 下载,url需要具体到某个文件(可使用正则)
- curl -O http://nginx.org/download/nginx-1.20.2.tar.gz