Nginx是一个轻量级/高性能的反向代理Web服务器,实现非常高效的反向代理、负载平衡,他可以处理2-3万并发连接数,采用一种进程池+IO多路复用的这种模式。
应用场景
http服务器。Nginx是一个http服务可以独立提供http服务。可以做网页静态服务器。
反向代理,负载均衡。当网站的访问量达到一定程度后,单台服务器不能满足用户的请求时,需要用多台服务器集群可以使用nginx做反向代理。并且多台服务器可以平均分担负载,不会应为某台服务器负载高宕机而某台服务器闲置的情况。
处理请求过程
1.Nginx 在启动时,会解析配置文件,得到需要监听的端口与 IP 地址。
2.在 Nginx 的 Master 进程里面先初始化好这个监控的Socket
3.一个现有进程调用 fork 函数创建一个新的子进程。
4.子进程会竞争接收到的新连接
5.客户端就可以向 nginx 发起连接了。当客户端与nginx进行三次握手,建立好一个连接
6.子进程会接收成功,得到这个建立好的连接的Socket
7.设置读写事件处理函数,并添加读写事件来与客户端进行数据的交换。
8.Nginx 或客户端来主动关掉连接
nginx和apache的区别
apache是同步多进程模型,一个连接对应一个进程
nginx是异步的,采用单线程来异步非阻塞处理请求,多个连接可以对应一个进程
nginx.conf结构
worker_processes 1;# worker进程的数量
events { # 事件区块开始
worker_connections 1024; # 每个worker进程支持的最大连接数
} # 事件区块结束
http { # HTTP区块开始
include mime.types; # Nginx支持的媒体类型库文件
default_type application/octet-stream; # 默认的媒体类型
sendfile on; # 开启高效传输模式
keepalive_timeout 65; # 连接超时
server { # 第一个Server区块开始,表示一个独立的虚拟主机站点
listen 80; # 提供服务的端口,默认80
server_name localhost; # 提供服务的域名主机名
location / { # 第一个location区块开始
root html; # 站点的根目录,相当于Nginx的安装目录
index index.html index.htm; # 默认的首页文件,多个用空格分开
} # 第一个location区块结果
动静分离
location /image/ {
root /usr/local/static/;
autoindex on;
}
error_page 500502503504 /50x.html; # 出现对应的http状态码时,使用50x.html回应客户
location = /50x.html { # location区块开始,访问50x.html
root html; # 指定对应的站点目录为html
}
}
}
location的语法
=:精准匹配
#优先级1,精确匹配,根路径
location =/ {
return 400;
}
^~:以某个字符串开头
#优先级2,以某个字符串开头,以av开头的,优先匹配这里,区分大小写
location ^~ /av {
root /data/av/;
}
~:区分大小写的正则匹配
#优先级3,区分大小写的正则匹配,匹配/media*****路径
location ~ /media {
alias /data/static/;
}
~:不区分大小写的正则匹配
#优先级4 ,不区分大小写的正则匹配,所有的***.jpg|gif|png 都走这里
location ~* ..(jpg|gif|png|js|css)$ {
root /data/av/;
}
!~:区分大小写不匹配的正则
!~:不区分大小写不匹配的正则
/:通用匹配,任何请求都会匹配到
#优先7,通用匹配
location / {
return 403;
}
Nginx 是如何实现高并发的
每进来一个 request ,会有一个 worker 进程去处理。采用异步非阻塞的方式进行处理,发送完请求后,注册一个事件,
上游服务器返回了,就会触发这个事件,worker 才会来接手,这个 request 才会接着往下走。
Nginx负载均衡的算法
1 .轮询(默认)
upstream backserver {
server 192.168.0.12;
server 192.168.0.13;
}
2.权重 weight
# 权重越高,在被访问的概率越大,如上例,分别是20%,80%。
upstream backserver {
server 192.168.0.12 weight=2;
server 192.168.0.13 weight=8;
}
3.ip_hash( IP绑定)
#每个请求按访问IP的哈希结果分配,使来自同一个IP的访客固定访问一台后端服务器,并且可以有效解决动态网页存在的session共享问题
upstream backserver {
ip_hash;
server 192.168.0.12:88;
server 192.168.0.13:80;
}
4.fair(第三方插件)
#fair算法可以根据页面大小和加载时间长短智能地进行负载均衡,响应时间短的优先分配。
upstream backserver {
server server1;
server server2;
fair;
}
5.url_hash(第三方插件)
#按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,可以进一步提高后端缓存服务器的效率。
upstream backserver {
server squid1:3128;
server squid2:3128;
hash $request_uri;
hash_method crc32;
}
Nginx的限流都是基于漏桶流算法
1、正常限制访问频率(正常流量):
在nginx.conf配置文件中可以使用 limit_req_zone 命令及 limit_req 命令限制单个IP的请求处理频率。
# 定义限流维度,一个用户一分钟一个请求进来,多余的全部漏掉 1r/s代表1秒一个请求,1r/m一分钟接收一个请求
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/m;
# 绑定限流维度
server{
location /seckill.html{
limit_req zone=zone;
proxy_pass http://lj_seckill;
}
}
2.突发限制访问频率(突发流量)
Nginx提供burst参数结合nodelay参数可以解决流量突发的问题,可以设置能处理的超过设置的请求数外能额外处理的请求数。我们可以将之前的例子添加burst参数以及nodelay参数
# 定义限流维度,一个用户一分钟一个请求进来,多余的全部漏掉
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/m;
# 绑定限流维度
server{
location/seckill.html{
limit_req zone=zone burst=5 nodelay;
proxy_pass http://lj_seckill;
}
}
3.限制并发连接数
单个IP同时并发连接数最多只能10个连接,并且设置了整个虚拟服务器同时最大并发数最多只能100个链接
http {
limit_conn_zone $binary_remote_addr zone=myip:10m;
limit_conn_zone $server_name zone=myServerName:10m;
}
server {
ocation / {
limit_conn myip 10;
limit_conn myServerName 100;
rewrite / http://www.lijie.net permanent;
}
}
高可用性配置
当上游服务器(真实访问服务器),一旦出现故障或者是没有及时相应的话,应该直接轮训到下一台服务器,保证服务器的高可用
server {
listen 80;
server_name www.lijie.com;
location / {
### 指定上游服务器负载均衡服务器
proxy_pass http://backServer;
###nginx与上游服务器(真实访问的服务器)超时时间 后端服务器连接的超时时间_发起握手等候响应超时时间
proxy_connect_timeout 1s;
###nginx发送给上游服务器(真实访问的服务器)超时时间
proxy_send_timeout 1s;
### nginx接受上游服务器(真实访问的服务器)超时时间
proxy_read_timeout 1s;
index index.html index.htm;
}
}
Rewrite全局变量
$remote_addr //获取客户端ip
$binary_remote_addr //客户端ip(二进制)
$remote_port //客户端port,如:50472
$remote_user //已经经过Auth Basic Module验证的用户名
$host //请求主机头字段,否则为服务器名称,如:blog.sakmon.com
$request //用户请求信息,如:GET ?a=1&b=2 HTTP/1.1
$request_filename //当前请求的文件的路径名,由root或alias和URI request组合而成,如:/2013/81.html
$status //请求的响应状态码,如:200
$body_bytes_sent // 响应时送出的body字节数数量。即使连接中断,这个数据也是精确的,如:40
$content_length // 等于请求行的“Content_Length”的值
$content_type // 等于请求行的“Content_Type”的值
$http_referer // 引用地址
$http_user_agent // 客户端agent信息,如:Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.76 Safari/537.36
$ args //与$query_string相同 等于当中URL的参数(GET),如a=1&b=2
$ document_uri //与
u
r
i
相
同
这
个
变
量
指
当
前
的
请
求
U
R
I
,
不
包
括
任
何
参
数
(
见
uri相同 这个变量指当前的请求URI,不包括任何参数(见
uri相同这个变量指当前的请求URI,不包括任何参数(见args) 如:/2013/81.html
$document_root //针对当前请求的根路径设置值
$hostname //如:centos53.localdomain
$http_cookie //客户端cookie信息
$cookie_COOKIE //cookie COOKIE变量的值
i
s
a
r
g
s
/
/
如
果
有
is_args //如果有
isargs//如果有args参数,这个变量等于”?”,否则等于”",空值,如?
$limit_rate //这个变量可以限制连接速率,0表示不限速
q
u
e
r
y
s
t
r
i
n
g
/
/
与
query_string // 与
querystring//与args相同 等于当中URL的参数(GET),如a=1&b=2
$request_body // 记录POST过来的数据信息
$request_body_file //客户端请求主体信息的临时文件名
$request_method //客户端请求的动作,通常为GET或POST,如:GET
$request_uri //包含请求参数的原始URI,不包含主机名,如:/2013/81.html?a=1&b=2
$scheme //HTTP方法(如http,https),如:http
u
r
i
/
/
这
个
变
量
指
当
前
的
请
求
U
R
I
,
不
包
括
任
何
参
数
(
见
uri //这个变量指当前的请求URI,不包括任何参数(见
uri//这个变量指当前的请求URI,不包括任何参数(见args) 如:/2013/81.html
$request_completion //如果请求结束,设置为OK. 当请求未结束或如果该请求不是请求链串的最后一个时,为空(Empty),如:OK
$server_protocol //请求使用的协议,通常是HTTP/1.0或HTTP/1.1,如:HTTP/1.1
$server_addr //服务器IP地址,在完成一次系统调用后可以确定这个值
$server_name //服务器名称,如:blog.sakmon.com
$server_port //请求到达服务器的端口号,如:80
Nginx 实现后端服务的健康检查
方式一,利用 nginx 自带模块 ngx_http_proxy_module 和 ngx_http_upstream_module 对后端节点做健康检查。
方式二(推荐),利用 nginx_upstream_check_module 模块对后端节点做健康检查