Nginx 介绍
Nginx 简介与特性
-
Nginx 全称:engine X
-
国内流行的 Nginx 分支:
淘宝:Tengine---支持模块化动态装卸载
Registry---陌陌在使用 -
Nginx 使用时调用以下库:
libevent:高性能的网络库
Nginx 架构
Nginx 是 Master/Worker 架构
-
Master:主控进程;实现装载配置、平滑升级、管理 worker 进程
-
Worker:通过模块以流水线式方式完成各项功能处理
-
通过 epoll 机制实现单个 worker 进程并发响应多个客户请求
-
磁盘 IO:基于内核直接构建响应报文
AIO:异步 IO
mmap etc:内存映射 -
网络 IO:第一节段实现异步 IO(非阻塞),第二阶段还是阻塞
Nginx 的特性
1、模块化设计、较好的扩展性
2、高可靠
Nginx的组成:
一个主控进程:master(主进程负责生成多个子进程worker)
主控进程负责分析解析配置文件并启动子进程
主要完成以下工作:读取并验证配置,绑定或创建套接字,以及启动终结维护子进程的个数,无需重启重载配置文件,平滑升级
多个子进程:worker
负责响应用户请求
3、低内存消耗
一个线程响应多个请求
4、热部署
不停机更新配置文件、日志文件滚动、升级程序版本
5、支持事件驱动机制、支持异步AIO、支持内存映射机制(mmap)
Nginx 的基本功能
1、静态资源web服务器,能够缓存打开的文件描述符
2、http、smtp、pop3支持这三种协议的反向代理服务器
反向代理服务器:建立在80端口上,但是不提供内容,代理进程解析判断客户端是否可以访问后端web服务器,如果可以访问,代理服务器将用户请求改为封装为另一个样子提交给web服务器;如果不允许则拒绝
3、缓存加速(在反向代理时实现)、负载均衡
4、支持FastCGI(fpm,LNMP);uWSGI协议(Pyhton)等
5、支持模块化(非DSO机制)、过滤器zip、SSI及图像的大小调整
6、支持SSL,从而实现https服务
Nginx 扩展功能
基于名称和 IP 的虚拟主机
支持 keepalived
支持平滑升级
定制访问日志、支持使用日志缓存区提供日志存储性能
支持路径别名
支持 url rewrite
支持基于 IP 及用户的访问控制
支持速度限制,支持并发数限制
Nginx 基本架构特性
一个 master 进程生成一个或多个 worker 进程
支持事件驱动:Linux 调用 epoll(边缘触发)、bs 调用 kqueue、server 调用/dev/poll
复用器:select,poll,rt signal
支持 sendfile,sedfile64
支持 AIO
支持 mmap
Nginx 工作模式
非阻塞、事件驱动、由一个 master 进程生成多个 worker 进程,每个 worker 响应 n 个请求
Nginx 模块类型
1、核心模块
2、标准的http协议模块
3、可选的http协议模块
4、邮件模块
5、第三发模块(编译Nginx时指定模块在何处,手动指定模块文件)
Nginx 安装方法
Nginx 没有收录到系统,但是收录到 epel 源中了
-
方式 1、yum 安装
-
方式 2、源码安装:编译安装
编译安装:
[root@localhost ~]# yum groupinstall "Development Tools" "Server Platform Development"
[root@localhost ~]# yum install pcre-devel openssl-devel zlib-devel
[root@localhost ~]# useradd -r nginx //-r指定为系统用户
[root@localhost ~]# ./configure --prefix=/usr/local/nginx --conf-path=/usr/local/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_dav_module --with-http_stub_status_module --with-threads --with-file-aio
[root@localhost ~]# make && make install
- 方式 3、制作好的程序包:rpm 包
Nginx 配置文件结构
- main block:主配置段,也即全局配置段;主要配置 Nginx 进程的特性
events { >>>事件驱动相关的配置
...
worker_connections 1024;
}
http { >>>http/https协议的相关的配置段;web在此段配置
...
}
stream { >>>四层反向代理配置段
...
}
- http 协议相关的配置结构
http {
... >>>各server段中要使用到的公共配置
server { >>>单个server段,即为一个虚拟主机
listen 80; >>>监听的地址和端口,可监听端口\地址\主机名
server_name 域名;
root 代码存放路径;
location / URL { >>>定义对某一个URL的访问特性
index index.php index.html index.htm;
}
}
}
Nginx 配置文件以及模块使用
主配值段的指令
- 正常运行的必备配置:
1、user USERNAME [GROUPNAME] >>>指定运行worker进程的用户和组
2、pid /path/to/pid_file >>>指定Nginx守护进程的pid文件
3、worker_rlimit_nofile >>>指定一个worker进程所能打开的最大文件句柄数(文件数量)
- 性能优化相关的配置:放在主配置段下
worker_processes 数字;
所能够打开worker进程的个数;通常少于cpu物理核心数
worker_cpu_affinity auto [cpumask];
优点:能够提升cpu的缓存命中率
cpumask:cpu掩码(每一颗CPU用8位二进制表示)
0000 0000
0000 0001 第一颗CPU
0000 0010 第二颗CPU
0000 0100 第三颗CPU
注意:1在哪个位就代表第几颗cpu 0011表示第一颗和第二颗
context switch:会产生cpu不必要的消耗
timer_resolution;
计时器解析度:降低此值,可减少gettimeofday()系统调用的次数
worker_priority number;
指明worker进程的nice值设定worker进程优先级,优先调度使用CPU;
nice值范围:-20到19 默认值为0对应120
-20对应100
19对应139
worker_rlimit_nofile number;
单个worker进程可以打开的文件数量上限;一个文件打开就需要维持1个套接字文件;注意:该值的设置必须大于等于worker_processes和worker_connections的乘级
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
worker_connections 值;
设定单个worker进程所能够处理的最大并发连接数量worker_connections 乘以 worker_processes
- 用户用于调试、定位问题:
deamon {on | off}
是否以守护进程方式运行Nginx
master_process {on | off}
是否以master/worker模型来运行nginx;默认为on;调试时设置为off;适用于二次开发
error_log_file [level]
指明日志文件,并指明level
事件相关的配置:放在events段
accept_mutex {off | on};
master调用用户请求至各worker进程时使用的负载均衡锁;
on表示能让多个worker轮流地、序列化地去响应新请求;【起点公平】
off表示每个新请求的到达都会通知所有worker进程,谁抢到谁处理【结果公平】
lock_file file;
accept_mutex用到的锁文件路径
use [epoll | rtsig | select | poll]
指明使用的事件模型;建议让Nginx自行选择
worker_connections 值;
设定单个worker进程所能够处理的最大并发连接数量worker_connections 乘以
worker_processes
- 核心模块 ngx_http_core_module
http{ }:由 ngx_http_core_module 模块所引入,像 httpd 一样静态 web 服务器
配置框架:
http {
upstream { >>>负载均衡;反向代理
}
server {
location URL {
root "本地文件系统路径"
} //类似于httpd中的<Location>,用于定义URL与本地文件系统的映射关系,一个server中可以有多个location
location URL {
if ... { >>>条件判断功能
....
}
}
} //每个server段类似于httpd中的虚拟主机<VirtualHost>;
}
#注意:与http相关的指令仅能够放置于httpd、server、location、upstream、if上下文,但有些指令仅应用于这5种上下文中的某些种
一个http段中可以有多个server段,每个server段中可以有多个location段
2个server不能使用同一个套接字
#注意:在http段下可以引用外部的配置文件,操作如下
配置参数:
1、定义一个虚拟主机: //在http段下添加一个server段
server {
listem 端口号;
server_name 网站名称;
root web网页存放路径;
location / {
index index.html index.htm;
}
}
2、listen:指定监听的地址和端口
设置IP的地址和端口,或服务器将在其上接受请求的unix域套接字的路径。地址和端口都可以指定,或者只能指定地址或端口。例如,地址也可以是主机名
listen 网址[:端口号];或者listen 端口号;
示例:
listen 127.0.0.1:8000;
listen 127.0.0.1;
listen 8000;
listen *:8000;
listen localhost:8000;
3、server_name 主机名称 ...;
指明虚拟主机的主机名称;后可跟多个由空白字符分隔的字符串
支持通配符*匹配任意长度的任意字符,例如: server_name *.baidu.com www.baidu.*
支持~起始的字符做正则表达式模式匹配,例如: server_name ~^www\d+\.baidu\.com$
\d+:相当于数字0-9或[0-9]; +号表示至少匹配一个字符
\. :匹配点本身的,点表示匹配任意单个字符
$:表示以此符号前的字符结尾的
匹配机制优先级:
(1)字符串精确匹配
(2)左侧*号通配符匹配
(3)右侧*号通配符匹配
(4)正则表达式匹配
4、tcp_nodelay {on | off}; //添加在http段中
仅对保持连接的http有效
5、tcp_nopush {on | off};
只有当sendfile为on时有用(上图中的sendfile)
作用:
在Linux和FreeBSD 4上,在一个数据包中发送响应头和文件的开头*;
以完整数据包发送文件
6、keepalive_timeout 65;
保持连接的超时时间
7、keepalive_requests number;
在保持连接的超时时间内(keepalive_timeout)可以访问多少个资源;如果超过该设置的值,即便没有超过保持连接设置的超时时间也会断开连接
8、types_hash_max_size 值;
设定保存类型的哈希表的最大值;默认值为1024
types_hash_max_size影响散列表的冲突率。
types_hash_max_size越大,就会消耗更多的内存,但散列key的冲突率会降低,检索速度就更快。
types_hash_max_size越小,消耗的内存就越小,但散列key的冲突率可能上升。
- 定义路径的相关配置
1、root 网站路径;
默认值: root html;
设置web资源路径映射,用于指明用户请求的url所对应的本地文件系统上的文档所在目录路径
可定义的段: http段, server段, location段, if in location
2、location [ = | ~ | ~* | ^~ ] uri { ... }
location @name { ... }
根据请求的uri做请求响应的访问限制
=:对URI做精确匹配;
例如:www.baidu.com/ www.baidu.com/index.html
location = / { >>>那么上面的2地址则会匹配到第一个
...
}
~:对URI做正则表达式模式匹配,区分字符大小写
~*:对URI做正则表达式模式匹配,不区分字符大小写
^~:对URI的左半部分做匹配检查,不区分字符大小写
不带符号:默认只有 / 匹配起始于此URI的所有URI
匹配优先级:
=, ^~, ~与~*, 不带符号
可定义的上下文范围: server段, location段
- 定义客户端请求的相关配置
以下参数可以定义的上下文段为: http, server, location
keepalive_timeout 75;
设定保持连接的超时时间;0表示禁止长连接,默认值为75s
keepalive_disable none | browser ...;
对哪种浏览器禁用长连接
keepalive_requests 数值;
在长连接超时时间内所允许请求资源的最大数量,默认值为100
send_timeout time;
向客户端发送响应报文的超时时长,此处是指两次写操作之间的间隔时长
client_body_buffer_size size;
用于接收客户端请求报文的body部分的缓存区大小;默认为16k;超出此大小时,其将被暂存到磁盘上的由client_body_temp_path指令指定的位置;
只有允许客户端上传大文件时就需要进行调整该值;如果是一个电商平台只是简单的交易操作和登入操作,那么此值默认即可
client_body_temp_path path [一级 [二级 [三级]]];
设定用与存储客户端请求报文的body部分的临时存储路径以及子目录结构和数量
加速文件查找
对URI进行hash计算
示例:对地址做md5sum校验
[dqz@localhost ~]$ echo www.baidu.com | md5sum
ed6322bc931d5aba9cc72b63f0f03a82 -
16进制的数字:
示例:client_body_temp_path /var/tmp/client_body 2 1 1
1:表示用一位16进制的数字表示一级子目录;0-f 256个一级目录
2:表示用2位16进制的数字表示二级子目录;00-ff 256x16=4096 二级目录
2:表示用2位16进制的数字表示三级子目录;00-ff 256x16x16=65536三级
- 对客户端进行限制的配置
limit_rate rate;
限制响应客户端的传输速率,单位为bytes/second,默认值0表示无限制;
可以定义的上下文段为:http, server, location, if in location
limit_except method ... { ... }
限制对指定的请求方法之外,使用其他方法的客户端
示例
limit_except GET {
allow 192.168.1.0/32;
deny all;
}
可以定义的上下文段为:location
- 文件操作优化的配置
以下参数可以定义的上下文段为:http, server, location
aio on | off | threads[=pool];
是否开启aio功能;极大优化系统访问时被阻塞在IO
directio size | off;
在Linux主机启动O_DIRECT标记,此处意味文件大于等于给定的大小时使用,例如dlrectio 4m;
open_file_cache off;
open_filecache max=N [inactive=time];
nginx可以缓存以下三种信息:
(1)文件的描述符、文件大小和最近一次的修改时间
(2)打开的目录结构
(3)没有找到或者没有权限访问的文件相关信息
max=N:可缓存的缓存项上限;达到上限后会使用LRU算法实现缓存管理
inactive=time:缓存项的非活动时长,在此处指定的时长内未被命中或命中的次数少于open_file_cache_min_uses命令指定的次数的缓存项即为非活动项
open_file_cache_valid time;
缓存项有效性的检查频率;默认为60s
open_file_cache_min_uses number;
在open_file_cache指令的inactive参数指定的时长内,至少应该被命中多少次方可被归类为活动项
open_file_cache_error on | off;
是否缓存查找时发生错误的文件等一类信息
访问控制模块
(1)基于 IP 访问限制 ngx_http_access_module
location / {
deny 192.168.1.1;
allow 192.168.1.0/24;
allow 10.1.1.0/16;
allow 2001:0db8::/32;
deny all;
}
按顺序检查规则,直到找到第一个匹配项。在此示例中,仅允许IPv4网络访问 10.1.1.0/16并且192.168.1.0/24 不包括地址192.168.1.1,以及IPv6网络2001:0db8::/32。如果有很多规则, 最好使用 ngx_http_geo_module模块变量。
可定义的上文段位:http,server,location,limit_except
允许访问指定的网络或地址。如果unix:指定了特殊值(1.5.1),则允许访问所有UNIX域套接字
句法: allow address | CIDR | unix: | all;
拒绝访问指定的网络或地址。如果unix:指定了特殊值(1.5.1),则拒绝所有UNIX域套接字的访问
句法:deny address | CIDR | unix: | all;
(2)基于用户的访问控制 ngx_http_auth_basic_module
示例:
location / {
auth_basic "提示信息"; //弹出提示信息
auth_basic_user_file 密码文件路径; //账号密码文件
}
账号密码文件创建:
使用命令htpasswd;该命令由httpd-tools提供
语法:htpasswd [-cmdpsD] 密码文件名 用户名
[root@localhost ~]# yum -y install httpd-tools
[root@localhost ~]# htpasswd -c -m /usr/local/nginx/ngxpasswd dqz
New password: //设置密码
Re-type new password: //再次确认密码
Adding password for user dqz
参数详解:
-c:创建密码文件
-m:使用md5加密(默认)
#nginx配置文件更改
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
[root@localhost ~]# nginx -t
[root@localhost ~]# nginx -s reload
[root@localhost ~]# mkdir /web/vhost1/admin/
[root@localhost ~]# vim /web/vhost1/admin/index.html
浏览器进行访问测试:
输入账号密码
状态页模块 ngx_http_stub_status_module
用于输出 nginx 的基本状态信息
进行源码编译安装时需要带上该模块,如下所示
]# ./configure --prefix=/usr/local/nginx --with-http_stub_status_module
配置示例:
location = /basic_status {
stub_status;
}
浏览器访问:
Active connections: 活动状态的连接数
accepts:已经接受的客户端请求的总数
handled:已经处理完成的客户端请求的总数
requests:客户端发来的总的请求数;
Reading:处于读取客户端请求报文首部的连接的连接数
Writing:处于向客户端发送响应报文过程中的连接数;
Waiting:处于等待客户端发出请求的空闲连接数;
#通过awk取指定值
[root@localhost ~]# curl --silent 192.168.66.51/ngxstatus | awk '/^Active/{print $3}'
日志管理模块 ngx_http_log_module
定义日志格式
log_format name string..
access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];
访问日志文件路径,格式及相关的缓冲的配置;
buffer=size
flush=time
access_log off; //关闭
可配置的段: http, server, location, if in location, limit_except
open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time];
open_log_file_cache off;
缓存各日志文件相关的元数据信息;
max:缓存的最大文件描述符数量;
min_uses:在inactive指定的时长内访问大于等于此值方可被当作活动项;
inactive:非活动时长;
valid:验正缓存中各缓存项是否为活动项的时间间隔;
压缩传输模块 ngx_http_gzip_module
gzip on | off;
开启/关闭
默认值为off
可配置的段: http, server, location, if in location
gzip_comp_level level;
压缩节点
默认值1;范围1-9
可配置的段:http, server, location
gzip_disable regex ...;
禁止压缩功能
可配置的段: http, server, location
gzip_buffers number size;
支持实现压缩功能时为其配置的缓冲区数量及每个缓存区的大小;
默认值:gzip_buffers 32 4k|16 8k;
可配置的段:http, server, location
gzip_proxied off | expired | no-cache | no-store | private | no_last_modified | no_etag | auth | any ...;
nginx作为代理服务器接收到从被代理服务器发送的响应报文后,在何种条件下启用压缩功能的;
off:对代理的请求不启用
no-cache, no-store,private:表示从被代理服务器收到的响应报文首部的Cache-Control的值为此三者中任何一个,则启用压缩功能;
gzip_types mime-type ...;
压缩过滤器,仅对此处设定的MIME类型的内容启用压缩功能;
默认值: gzip_types text/html;
可配置的段: http, server, location
#示例:
gzip on;
gzip_comp_level 6;
gzip_min_length 64;
gzip_proxied any;
gzip_types text/xml text/css application/javascript;
Nginx 作为 https 服务器
ngx_http_ssl_module
默认情况下不构建此模块,应使用--with-http_ssl_module 配置参数启用它
ssl on | off;
定义ssl引擎,开启
ssl_certificate file;
当前虚拟主机使用PEM格式的证书文件;
ssl_certificate_key file;
当前虚拟主机上与其证书匹配的私钥文件;
ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2];
支持ssl协议版本,默认为后三个;
ssl_session_cache off | none | [builtin[:size]] [shared:name:size];
builtin[:size]:使用OpenSSL内建的缓存,此缓存为每worker进程私有;
[shared:name:size]:在各worker之间使用一个共享的缓存;
ssl_session_timeout time;
客户端一侧的连接可以复用ssl session cache中缓存 的ssl参数的有效时长;
#配置示例:
server {
listen 443 ssl;
server_name www.geekdqz.com;
root /vhosts/ssl/htdocs;
ssl on;
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;
ssl_session_cache shared:sslcache:20m;
}
#操作步骤:
1、先建立一个CA服务器【node1服务器做CA服务器】
[root@localhost ~]# cd /etc/pki/CA/
[root@localhost CA]# ls
certs crl newcerts private
#创建私钥
[root@localhost CA]# (umask 077;openssl genrsa -out private/cakey.pem 2048)
[root@localhost CA]# ll private/
#建立自签证书
[root@localhost CA]# openssl req -new -x509 -key private/cakey.pem -out cacert.pem -days 365
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN //国家
State or Province Name (full name) []:shenzhen //省份
Locality Name (eg, city) [Default City]:shenzhen //城市
Organization Name (eg, company) [Default Company Ltd]:geekdqz //公司
Organizational Unit Name (eg, section) []:devops //部门
Common Name (eg, your name or your server's hostname) []:web.geekdqz.com //服务器主机名
Email Address []:
[root@localhost CA]# touch index.txt
[root@localhost CA]# echo 01 > serial
2、nginx服务器创建私钥
[root@nginx-web ~]# mkdir /etc/nginx/ssl
[root@nginx-web ~]# cd /etc/nginx/ssl/
[root@nginx-web ssl]# (umask 077;openssl genrsa -out nginx.key 2048)
#制作CA请求文件
[root@nginx-web ssl]# openssl req -new -key nginx.key -out nginx.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:shengzhen
Locality Name (eg, city) [Default City]:shengzhen
Organization Name (eg, company) [Default Company Ltd]:geekdqz
Organizational Unit Name (eg, section) []:devops
Common Name (eg, your name or your server's hostname) []:www.geekdqz.com //注意需要跟CA服务器的域名一样,不然无法访问
Email Address []:dqzboy@163.com
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
#拷贝证书请求文件至CA服务器
[root@nginx-web ssl]# scp nginx.csr root@192.168.66.50:/etc/pki/CA/
3、CA服务器进行签署
[root@localhost CA]# openssl ca -in nginx.csr -out /etc/pki/CA/certs/nginx.crt -days 365
Certificate is to be certified until May 11 07:19:27 2020 GMT (365 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
#拷贝签署的CSR文件到nginx服务器
[root@localhost CA]# scp certs/nginx.crt root@192.168.66.51:/etc/nginx/ssl
[root@nginx-web ]# vim /etc/nginx/nginx.conf
listen 443 ssl;
server_name www.geekdqz.com;
ssl on;
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;
ssl_protocols sslv3 tlsv1 tlsv1.1 tlsv1.2;
ssl_session_cache shared:SSL:10m;
[root@nginx-web ]# nginx -t
[root@nginx-web ]# nginx -s reload
#浏览器访问:
https://www.geekdqz.com
域名重定向模块 ngx_http_rewrite_module
将源网站重定向至新的网站域名
可定义的段:server,location,if
语法格式:
rewrite 匹配规则 重定向的位置; //匹配规则正则支持正则,重定向不支持正则的写法
配置示例:
server {
listen 80;
server_name www.geekdqz.com;
rewrite /(.*)\.png$ /$1.jpg; //所有匹配到.png结尾的都重定向至.jpg(重定向的域名或文件必须存在不然返回404); $1表示前面(.*)所匹配到的内容改为 .jpg结尾的
#charset koi8-r;
#access_log logs/host.access.log main;
root /web/vhost1;
location / {
index index.html index.htm;
}
location ~* \.(jpg|png)$ {
allow all;
}
浏览器访问测试:
四个 rewrite 标志位
rewrite 匹配规则 重定向至 last;
多个规则会以上向下进行匹配;当用户请求URI后,如果该配置段中有多个rewrite,第一次URI匹配到某一条rewrite那么重写为新的URI,如果重写后的URI可以被该段中其他rewrite匹配到那么重新再次匹配所有的rewrite
nginx内部有一个机制,如果URI连续改了10次还在写,那么Nginx则返回内部错误,避免发生死循环
-
rewrite 匹配规则 重定向至 break;
多个 rewrite 中匹配到某一条规则后就直接执行下面的操作 -
rewrite 匹配规则 重定向至 redirect;
redirect 为临时重定向,给客户端发送 302 状态码,然后告诉客户端新的 URI 再次进行访问=
- rewrite 匹配规则 重定向至 permanent;
永久重定向
Nginx 反向代理
ngx_http_proxy_module模块:
server {
listen 端口;
location / {
proxy_pass http://192.168.x.x:80;
}
}
面向服务:实现反代
1、http
2、FastCGI
3、memcache
4、每个协议都有专用的协议客户端
Nginx的优势在于反向代理
httpd既能做正向也能做反向
代理模块 ngx_http_proxy_module
1、proxy_pass uri;
设置代理服务器的协议和地址,以及应将位置映射到其上的可选URI。作为协议,可以指定http或https。地址可以指定为域名或IP地址,以及一个可选端口。
可定义的段: location, if in location, limit_except
示例:
location / {
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
注意1: 如果proxy_pass后面的路径没有带URI的话,访问时就会将location的URI传递给后端服务器
server {
listen 80;
server_name HOSTNAME;
location /uri/ {
proxy_pass http://hos[:port];
}
}
访问http://HOSTNAME/uri --> http://host/uri
#示例:192.168.66.50为nginx反向代理服务器;192.168.66.51为httpd服务器;
#修改配置文件location添加URI
#后端httpd服务器添加此处指定的URI路径[web]
[root@nginx-web conf]# cd /var/www/html //注意此处为httpd默认网页存储路径
[root@nginx-web html]# mkdir web
[root@nginx-web html]# cd web/
[root@nginx-web web]# vim index.html
[root@nginx-web web]# cat index.html
this is http server
浏览器进行访问:http://www.ilinux.com/web
注意2: proxy_pass后面的路径是一个uri时,其会将location的uri替换为proxy_pass的uri;
server {
...
server_name HOSTNAME;
location /uri/ {
proxy_pass http://host/new_uri/;
}
...
}
http://HOSTNAME/uri/ --> http://host/new_uri/
#示例:修改反代服务器Nginx配置文件
#浏览器进行访问:http://www.ilinux.com/web
注意3:如果location定义其uri时使用了正则表达式的模式,或在if语句或limt_execept中使用proxy_pass指令,则proxy_pass之后必须不能使用uri; 用户请求时传递的uri将直接附加代理到的服务的之后;
server {
...
server_name HOSTNAME;
location ~|~* /uri/ {
proxy_pass http://host;
}
...
}
访问http://HOSTNAME/uri/ --> http://host/uri/;
2、proxy_set_header field value;
设定发往后端主机的请求报文的请求首部的值;
客户端向服务端发送的请求报文
可设定的段: http, server, location
#示例:
修改代理服务器Nginx的配置文件
[root@nginx-proxy ~]# vim /usr/local/nginx/conf.d/web.conf
添加proxy_set_header模块,定义首部记录格式名称
X-Real-IP: 为自定义的首部定义名称
$remote_addr: 此为nginx内建变量,该变量记录的为客户端地址
[root@nginx-proxy ~]# nginx -t
[root@nginx-proxy ~]# nginx -s reload
#修改后端服务器httpd配置文件
[root@httpd-web ~]# vim /etc/httpd/conf/httpd.conf
将默认的LogFormat记录格式注释掉,然后复制一行将默认首部记录格式 %h 改为代理服务器nginx配置文件中(上图)所定义的X-Real-IP的名称
[root@httpd-web ~]# httpd -t //检查配置文件
[root@httpd-web ~]# systemctl restart httpd
#查看后端服务器httpd的访问日志
记录的是真正访问的服务端的客户端的IP地址,而不再记录的是代理服务器的地址
3、ngx_http_headers_module 模块
向由代理服务器响应给客户端的响应报文添加自定义首部,或修改指定首部的值;
服务端向客户端发送自己的响应报文
(1)add_header name value [always];
添加自定义首部;
add_header X-Via $server_addr; //X-Via可自定义名称
add_header X-Accel $server_name;
#示例:
配置代理服务器Nginx配置文件
[root@nginx-proxy ~]# vim /usr/local/nginx/conf.d/web.conf
[root@nginx-proxy ~]# nginx -t
[root@nginx-proxy ~]# nginx -s reload
浏览器访问网站并 F12 打开调试页面查看
(2) expires [modified] time;
expires epoch | max | off;
用于定义Expire或Cache-Control首部的值;
4、缓存模块 proxy_cache_path
代理服务器可实现在本地启用缓存功能;由后端服务器取得的内容缓存下来,基于本地磁盘响应给客户端请求
架构
访问请求多的时候,网络I/O比磁盘I/O更慢
缓存的存储方式:
1、放在内存的哈希表
2、磁盘的目录结构
开启缓存
注意: 缓存空间需要先定义,再在location中调用
proxy_cache zone | off;
可定义的配置段: http, server, location
浏览器可使用shift+f5强制刷新,不加shift,请求则可以从缓存中获取内容响应客户端,加shift则不能使用缓存中获取内容响应给客户端
注意:nginxh将缓存都缓存在了磁盘中,基于hash方式;Nginx在用户访问连接上更加高效
定义缓存
在http段中进行定义;默认10分钟清理缓存(非活动时间)
官方配置:
Syntax: proxy_cache_path path [levels=levels] [use_temp_path=on|off] keys_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];
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
http {
....
proxy_cache_path /usr/local/nginx/cache levels=1:1:1 keys_zone=pcache:10m m ax_size=2g;
...
server {
...
location {
...
}
}
}
参数解释:
proxy_cache_path //定义缓存文件路径,需要保证缓存目录存在
levels=1:1:1 //levels指明子目录,并指明每级子目录多少字符;1表示每级子目录16个字符;
keys_zone=名称:大小 //定义缓存名称以及内存分配多少空间保存hash表
max_size=大小; //磁盘空间最大使用容量
[root@localhost ~]# mkdir /usr/local/nginx/cache //创建缓存目录
[root@localhost ~]# nginx -t
[root@localhost ~]# nginx -s reload
[root@localhost ~]# ls /usr/local/nginx/cache/
#使用缓存
如果某个站点使用了代理,那么该站点下就可以使用缓存
[root@nginx-proxy ~]# vim /usr/local/nginx/conf.d/web.conf
server{
...
proxy_cache 缓存名称; //此处缓存名称为keys_zone定义的名称
proxycache_key $requesst_uri; //定义键
proxy_cache_valid 200 302 10m; //定义各类响应码可缓存的时间
proxy_cache_use_stale http_502; //根据后端服务器状态进行响应
localtion {
...
}
}
[root@nginx-proxy ~]# nginx -t
[root@nginx-proxy ~]# nginx -s reload
#浏览器访问
http://www.ilinux.com/web/
#查看缓存目录
[root@nginx-proxy cache]# tree
.
└── 1 //一级子目录
└── 8 //二级子目录
└── 2 //三级子目录
└── 50d3e5509ac52e81e4ecbc30ed112281
此处标黄:1表示一级子目录 8表示二级字母 2表示三级子目录
#查看缓存文件内容
Nginx 负载均衡
Nginx 实现 7 层负载均衡
ngx_http_upstream_module模块
可定义的段: http上下文段中
upstream name { ... }
定义后端服务器组,会引入一个新的上下文;Context: http
hhtp {
....
upstream uri {
server ...
erver ...
...
}
server {
listem 80;
server_name www.ilinux.com;
location / {
proxy_pass http://uri
}
}
}
#计算通信的方式:单播、组播、广播
组播:向一个组播域内的主机进行通信
#负载均衡集群:
硬件: F5 BigIP,A10.NetScaler
软件:
四层调度:lvs, Nginx(伪四层,使用stream模块nginx在1.9.0增加了stream 模块), haporxy(需工作在tcp模式下)
七层调度:nginx(http_upstream_module), haporxy(需工作在http模式下), httpd
#session sticky(粘性):
会话绑定;Nginx工作在http层可通过cookie进行绑定
#session 会话集群
通过组播(多播)的方式传给集群中与之该session服务器在同一组播域中的其他session服务器
#存储集群
用户---获取会话---检查存储集群---获取数据---返回给用户
存储集群解决方案:redis、Memcached;都是内存级存储,每秒事务(tps)数量50-100万个,普通X86服务器就可以实现
1、memcached:缓存系统,不支持持久化,宕机后所有会话都会丢失
2、redis:支持持久化、主从集群
负载调度算法
-
RR 轮询(默认,权重默认为 1) 一次一个的来(理论上的,实际实验可能会有间隔)
-
weight 权重(加权轮询) 权重高多分发一些 服务器硬件更好的设置权重更高一些
upstream URI {
server ip[:port] weight=nember;
server ip[:port] weight=nember;
...
}
可在命令进行检测:
[root@localhost~ ]# for i in {1..10};do curl www.xxx.com;done
示例:
- ip_hash 等价于 hash $remote_addr;同一个 IP,所有的访问都分发到同一个 web
服务器;只要第一次请求被绑定在后端的某台服务器,则IP地址则一直访问为同一服务器
注意:此方法不推荐;使用此方法后 同一组中的backup不可用
- hash
hash $remote_addr; //同一ip请求全部分发到同一个后端服务器
hash $request_uri; //把同一URI请求绑定在同一个后端服务器上
* 相关参数设置
* max_conns 最大并发连接数(最大调度给后端服务器多少的请求)
* max_fails=number 健康状态检测;定义失败多少次后将该服务定义为超时,默认1次;0表示不做健康状态机制
* fail_timeout=time 每隔多长时间检测一次,默认超时周期时间10s
* backup 当所有服务器都挂了之后,定义backup的服务才会上线
#官方示例:
upstream backend {
server backend1.example.com weight=5;
server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
server unix:/tmp/backend3;
server backup1.example.com backup;
}
Nginx 实现 4 层负载均衡
ngx_stream_core_module 模块
注意:如果不提供http服务,则不需要定义在http上下文中,直接定义为stream上下文中
官方示例:
worker_processes auto;
error_log /var/log/nginx/error.log info;
events {
worker_connections 1024;
}
stream {
upstream backend {
hash $remote_addr consistent;
server backend1.example.com:12345 weight=5;
server 127.0.0.1:12345 max_fails=3 fail_timeout=30s;
server unix:/tmp/backend3;
}
upstream dns {
server 192.168.0.1:53535;
server dns.example.com:53;
}
server {
listen 12345;
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;
}
}
实现Nginx 4层反代
ngx_stream_proxy_module
实现Nginx4层负载均衡
ngx_stream_upstream_module
Nginx 装载模块方式
1、编译安装:
前提:开发环境,包括 nginx 编译要启用的功能依赖到的开发库;
[root @nginx-proxy~]# yum groupinstall "Development Tools" "Server Platform Development"
[root @nginx-proxy~]# yum -y pcre-devel openssl-devel
编译过程:
[root @nginx-proxy~]# useradd -r nginx
[root @nginx-proxy~]# cd nginx-1.15.9
[root @nginx-proxy~]#./configure --prefix=/usr/local/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --user=nginx --group=nginx --with-http_ssl_module --with-http_stub_status_module --with- http_flv_module --with-http_mp4_module --with-threads --with-file-aio
[root @nginx-proxy~]# make && make install
2、添加模块:
使用—add-module 进行重新编译,注意编译完后千万不要进行 make install,不然会被覆盖掉
[root @nginx-proxy~]# cd nginx-1.15.9
[root @nginx-proxy~]# ./configure --prefix = / usr / local / nginx --with-http_ssl_module --with-http_sub_module --with-http_gzip_static_module --with-http_stub_status_module --add-module=/data/software/ngx_http_substitutions_filter_module --add-module=/数据/软件/ngx_http_google_filter_module
[root @nginx-proxy~]# make
3、替换二进制文件:
# cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak # cp /root/nginx-1.15.9/objs/nginx /usr/local/nginx/sbin/
默认配置文件详解
#user nobody;
worker_processes auto; >>>所能够打开worker进程的个数;通常少于cpu物理核心数;auto表示自动
events { >>>配置事件驱动模型;可实现单进程响应多个进程
worker_connections 1024; >>>单进程响应1024个进程;修改此参数可以增加访问并发数;当前主机一共可以并发响应的进程数为worker_processes数乘以worker_connections的乘级
}
http {
include mime.types;
default_type application/octet-stream;
#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;
#keepalive_timeout 0;
keepalive_timeout 65; >>>保持连接启用,超时时间65s
#gzip on;
server {
listen 80;
server_name localhost;
#charset koi8-r;
#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;
}
}
}
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于