文章目录
Nginx
概念
Nginx 是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。
Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行。其特点是占有内存少,并发能力强,nginx的并发能力在同类型的网页服务器中表现较好。(百度百科)
使用原因
- 多平台可用,配置简单
- 反向代理,支持高并发连接:官方监测支持5万并发
- 内存消耗小,开启10个nginx服务消耗150m内存
- 适合处理静态文件,如上传附件,图片查看等
- 内置健康检查功能:如果有服务器宕机,会进行宕机检查,后续的请求不会再发送到宕机的服务器上,而是会重新提交到其他节点上
- nginx的稳定性很高:宕机的概率很低
- 接受用户的请求是异步的
- 节省宽带:支持GZIP压缩,可以添加至浏览器缓存
- 可以隐藏服务器ip
高性能原因
异步非阻塞事件处理机制:运用了epoll模型,提供了一个队列,排队解决。
处理请求的方式
nginx接收一个请求后,首先由listen和server_name指令匹配server模块,再匹配server模块里的location,location就是实际地址。
server { # 第一个Server区块开始,表示一个独立的虚拟主机站点
listen 80; # 提供服务的端口,默认80
server_name localhost; # 提供服务的域名主机名
location / { # 第一个location区块开始
root html; # 站点的根目录,相当于Nginx的安装目录
index index.html index.htm; # 默认的首页文件,多个用空格分开
} # 第一个location区块结果
}
正向代理与反向代理
- 反向代理就是请求由中间服务器统一接受,然后对请求进行转发,按照一定的规则分发给后端服务器
- 正向代理是请求直接发送到目标服务器
反向代理可以隐藏服务器的地址和特征,作为web服务器与后端服务器的中间层。安全。
优缺点
优点:
- 多平台可用,配置简单
- 反向代理,支持高并发连接:官方监测支持5万并发
- 内存消耗小,开启10个nginx服务消耗150m内存
- 适合处理静态文件,如上传附件,图片查看等
- 内置健康检查功能:如果有服务器宕机,会进行宕机检查,后续的请求不会再发送到宕机的服务器上,而是会重新提交到其他节点上
- nginx的稳定性很高:宕机的概率很低
- 接受用户的请求是异步的
- 节省宽带:支持GZIP压缩,可以添加至浏览器缓存
- 可以隐藏服务器ip
缺点:
动态处理能力较差,一般作为前端服务器
使用场景
- 反向代理: 负载均衡,多台服务器集群可以使用nginx作为反向代理服务器,进行请求的平均分发,防止某台服务器压力过大宕机
- 安全管理:使用nginx搭建api接口网关,对接口服务进行guol
- 虚拟主机:在一台服务器上虚拟出多个网站
- http服务器:提供独立的http服务,作为网页的静态服务器
目录结构
├── client_body_temp
├── conf # Nginx所有配置文件的目录
│ ├── fastcgi.conf # fastcgi相关参数的配置文件
│ ├── fastcgi.conf.default # fastcgi.conf的原始备份文件
│ ├── fastcgi_params # fastcgi的参数文件
│ ├── fastcgi_params.default
│ ├── koi-utf
│ ├── koi-win
│ ├── mime.types # 媒体类型
│ ├── mime.types.default
│ ├── nginx.conf # Nginx主配置文件
│ ├── nginx.conf.default
│ ├── scgi_params # scgi相关参数文件
│ ├── scgi_params.default
│ ├── uwsgi_params # uwsgi相关参数文件
│ ├── uwsgi_params.default
│ └── win-utf
├── fastcgi_temp # fastcgi临时数据目录
├── html # Nginx默认站点目录
│ ├── 50x.html # 错误页面优雅替代显示文件,例如当出现502错误时会调用此页面
│ └── index.html # 默认的首页文件
├── logs # Nginx日志目录
│ ├── access.log # 访问日志文件
│ ├── error.log # 错误日志文件
│ └── nginx.pid # pid文件,Nginx进程启动后,会把所有进程的ID号写到此文件
├── proxy_temp # 临时目录
├── sbin # Nginx命令目录
│ └── nginx # Nginx的启动命令
├── scgi_temp # 临时目录
└── uwsgi_temp # 临时目录
属性模块
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区块结果
error_page 500502503504 /50x.html; # 出现对应的http状态码时,使用50x.html回应客户
location = /50x.html { # location区块开始,访问50x.html
root html; # 指定对应的站点目录为html
}
}
跨域问题
nignx进行请求转发,将跨域的接口写成调本域的接口,再将这些接口转发到真正的请求地址
虚拟主机配置
基于域名的虚拟主机(外部网站):
#当客户端访问www.xxx.com,监听端口号为80,直接跳转到data/www目录下文件
server {
listen 80;
server_name www.xxx.com;
location / {
root data/www;
index index.html index.htm;
}
}
#当客户端访问www.xxxx.com,监听端口号为80,直接跳转到data/bbs目录下文件
server {
listen 80;
server_name www.xxxx.com;
location / {
root data/bbs;
index index.html index.htm;
}
}
基于端口的虚拟主机(内部网站):
#当客户端访问www.xxx.com,监听端口号为8080,直接跳转到data/www目录下文件
server {
listen 8080;
server_name 8080.xxx.com;
location / {
root data/www;
index index.html index.htm;
}
}
#当客户端访问www.xxxx.com,监听端口号为80直接跳转到真实ip服务器地址 127.0.0.1:8080
server {
listen 80;
server_name www.xxxx.com;
location / {
proxy_pass http://127.0.0.1:8080;
index index.html index.htm;
}
}
location的作用
匹配符 | 匹配规则 | 优先级 |
---|---|---|
= | 精准匹配 | 1 |
^~ | 以某个字符串开头 | 2 |
~ | 区分大小写的正则 | 3 |
~* | 不区分大小写的正则 | 4 |
!~ | 区分大小写不匹配的正则 | 5 |
!~* | 不区分大小写不匹配的正则 | 6 |
/ | 通用匹配 | 7 |
限流
正常限制访问频率
#定义限流维度,一个用户一分钟一个请求进来,多余的全部漏掉
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;
}
}
1r/s代表1秒一个请求,1r/m一分钟接收一个请求, 如果Nginx这时还有别人的请求没有处理完,Nginx就会拒绝处理该用户请求。
突发限制访问频率
#定义限流维度,一个用户一分钟一个请求进来,多余的全部漏掉
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;
}
}
burst=5 nodelay; 代表Nginx对于一个用户的请求会立即处理前五个,多余的就慢慢来落
限制并发连接数
http {
limit_conn_zone $binary_remote_addr zone=myip:10m;
limit_conn_zone $server_name zone=myServerName:10m;
}
server {
location / {
limit_conn myip 10;
limit_conn myServerName 100;
rewrite / http://www.lijie.net permanent;
}
}
单个IP同时并发连接数最多只能10个连接,并且设置了整个虚拟服务器同时最大并发数最多只能100个链接。
限流算法
漏桶算法
nginx使用的算法。
突发流量会进入到一个漏桶,漏桶会按照我们定义的速率依次处理请求,如果水流过大也就是突发流量过大就会直接溢出,则多余的请求会被拒绝。所以漏桶算法能控制数据的传输速率。
令牌算法
令牌桶算法是网络流量整形和速率限制中最常使用的一种算法。典型情况下,令牌桶算法用来控制发送到网络上的数据的数目,并允许突发数据的发送。Google开源项目Guava中的RateLimiter使用的就是令牌桶控制算法。
令牌桶算法的机制如下:存在一个大小固定的令牌桶,会以恒定的速率源源不断产生令牌。如果令牌消耗速率小于生产令牌的速度,令牌就会一直产生直至装满整个令牌桶。
动静分离原因
- nginx的静态处理能力很强,但是处理动态资源的能力不足
- 静态资源与动态资源分别走不同的服务器,缓解压力
- 浏览器接收到静态资源的访问请求时,直接走nginx,无需将请求转发给后端服务器
- 动态网站做好动静资源拆分后,将静态资源做好缓存,提高访问速度
nginx的动静分离
location /image/ {
root /usr/local/static/;
autoindex on;
}
mkdir /usr/local/static/image # 创建目录
cd /usr/local/static/image
xx.jpg
nginx -s reload
server_name/image/1.jpg # 访问图片资源
负载均衡
轮询
upstream xx-windows {
server 127.0.0.1:8091;
server 127.0.0.1:8092;
server 127.0.0.1:8093;
}
#后台管理服务器 用户访问manage.xx.com时访问localhost:8091
server {
listen 80;
server_name manage.xx.com;
location / {
#代理路径
proxy_pass http://xx-windows;
}
}
权重 weight
upstream jt-windows {
server 127.0.0.1:8091 weight=6;
server 127.0.0.1:8092 weight=3;
server 127.0.0.1:8093 weight=1;
}
ip_hash
upstream jt-windows {
ip_hash;
server 127.0.0.1:8091;
server 127.0.0.1:8092;
server 127.0.0.1:8093;
}
问题描述:用户信息保存到Seesion中时,由于负载均衡的配置.导致用户每次访问的服务器都不同,导致用户信息不能共享.
策略说明:使用IPHASH策略.将用户IP地址与tomcat服务器进行绑定.保证每次访问都是相同的tomcat.
缺点:
- 用户的IP地址可能发生变化,这时需要重新登录.
- 如果后台服务器宕机.则影响一部分用户不能正常访问.
- 用户负载不均.
总结:IPhash工作中不常使用. 测试操作时可能用到.
实际开发中使用SSO(单点登录)实现用户数据共享
SSO:只要用户登录其中一台服务器,则可能访问相互之间信任的全部服务器.
fair
第三方插件
upstream backserver {
server server1;
server server2;
fair;
}
对比 weight、ip_hash更加智能的负载均衡算法,fair算法可以根据页面大小和加载时间长短智能地进行负载均衡,响应时间短的优先分配。
哪个服务器的响应速度快,就将请求分配到那个服务器上。
url_hash
第三方插件
upstream backserver {
server squid1:3128;
server squid2:3128;
hash $request_uri;
hash_method crc32;
}
按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,可以进一步提高后端缓存服务器的效率。
配置高可用
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;
}
}
限制ip访问
# 如果访问的ip地址为192.168.9.115,则返回403
if ($remote_addr = 192.168.9.115) {
return 403;
}
限制浏览器访问
## 不允许谷歌浏览器访问 如果是谷歌浏览器返回500
if ($http_user_agent ~ Chrome) {
return 500;
}
rewrite全局变量
变量 | 含义 |
---|---|
$args | 请求行中的参数 |
$content length | 请求头中的content length字段 |
$content_type | 请求头中的content_type字段 |
$document_root | 当前请求在root指令中的值 |
$host | 请求主机头字段,否则为服务器名称 |
$http_user_agent | 客户端agent信息 |
$http_cookie | 客户端cookie信息 |
$limit_rate | 限制链接速率 |
$request_mehtod | 客户端请求动作,get post |
$remote_addr | 客户端ip地址 |
$remote_port | 客户端端口 |
$remote_user | 已经经过auth验证过的用户名 |
$request_filename | 当前请求的文件路径 |
$scheme | http方法(http,https) |
$server_protocol | 请求使用的协议(http/1.0,http/1.1) |
$server_addr | 服务器地址 |
$server_name | 服务器名称 |
$server_port | 请求到达的服务端端口 |
$request)uri | 包含请求参数的原始url,不含主机名 |
$uri | 不带请求参数的当前url,不包含主机名 |
$document_uri | 不带请求参数的当前url,不包含主机名 |