一、选择Nginx作为中间件的原因:
1、IO多路复用epoll
多个文件描述符的I/O操作都能在一个线程内并发交替地顺序完成,这里的复用,指的是复用同一个线程。
仍然还是一个线程来处理多个IO流请求,但与单线程的方式不同,其由IO流来主动上报,上报了,那么这个线程就去处理,其他线程等待
I/O多路复用就通过一种机制,可以监视多个文件描述符,一旦某个文件描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。
同步IO和异步IO
select,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的
而异步I/O则无需自己负责进行读写,异步I/O的实现会负责把数据从内核拷贝到用户空间。
epoll实现
①epoll采用事件驱动模型,每当FD就绪,采用系统的回调函数将fd放入就绪的列表,这样就知道队列中的哪个线程完成了,效率更高(不需要再进行轮询了)
②最大连接无限制
2、轻量级(功能模块少,代码模块化)
3、CPU亲和(affinity)
cpu亲和是一种把cpu核心和Nginx工作进程绑定方式,把每个worker进程固定在一个cpu上执行,减少切换cpu的cahce miss(cpu高速缓存),获得更好的性能
4.nginx的sendfile
请求一个文件要经过操作系统的内核空间->用户空间最终到达socket,socket再response给用户
linux2.2以后的零拷贝
只通过内核空间到socket,不通过用户空间的复杂逻辑运算
二、安装目录及作用
1、/etc/logrotate.d/nginx 类型:配置文件
作用:nginx日志轮转,用于logrotate服务的日志切割
2、/etc/nginx/ 类型:nginx相关的配置文件
作用:各种配置文件需求修改位置
3、/var/log/nginx/ 类型:日志文件存放目录
作用:存放访问日志,er1ror日志
三、nginx的配置文件
1、nginx.conf默认配置语法
user 设置nginx服务的系统使用用户
worker_processes 工作进程数
error_log nginx的错误日志
pid nginx服务启动时的pid
events work_connections 每个进程允许最大连接数
use 工作进程数
2.default.conf(/etc/nginx/conf.d/)
主要关于server的配置信息,包括监听端口、服务域名、访问目录和错误页面的访问定义。
3、HTTP请求
每次HTTP请求包括一次request和response
request:包括请求行、请求头部、请求数据
response:包括状态行、消息报头、响应正文
四、nginx日志类型
包括:error.log access.log
log_format:在nginx配置文件中记录了语法
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
Nginx变量
HTTP请求变量-- arg_PARAMETER、http_HEADER、sent_http_HEADER
内置变量-- Nginx内置
自定义变量
五、Nginx模块
nginx官方模块、第三方模块
编译安装时用--with指定开启模块功能
模块功能:
--with-http_stub_status_module (sub_status)
nginx客户端的状态
--with-http_random_index_module (random_index)
目录中选择一个随机主页
--with-http_sub_module (sub_filter 'str' 'new str')(sub_filter_once off 匹配到的全部替换 )
HTTP内容替换
连接频率的限制:limit_conn_module
配置语法:limit_conn_zone key zone=name:size;
默认状态:-
配置方法:http
配置语法:limit_conn zone number;
默认状态:-
配置方法:http、server、location
请求频率限制:limit_req_module
配置语法:limit_req_zone key zone=name:size rate=rate;
默认状态:-
配置方法:http
配置语法:limit_req_zone=name [burst=number] [nodelay] ;
默认状态:-
配置方法:http、server、location
例: 同一个ip,限制为每秒钟只能访问一次,
limit_req_zone $binary_remote_addr zone=req_zone:1m rate=1r/s
zone=req_zone:1m:定义一个空间,名字为zone,大小为1兆
remtoe_addr:客户端的ip
重点:HTTP访问控制模块
ngx_http_access_module
指令
allow、deny
语法: allow address | CIDR | unix: | all;
默认值: –
配置段: http, server, location, limit_except
允许或者禁止某个ip或者一个ip段访问。如果指定unix:,那将允许或者禁止socket的访问,unix在1.5.1才新加入。
弊端:若中间访问存在代理,访问控制只识别中间代理的IP,并不能控制客户端的访问IP。
解决办法:1、利用http_x_forwarded_for模块(此办法不安全,容易被修改)
模块会携带服务端IP信息消息的头信息。
http_x_forwarded_for=Client IP,Proxy(1)IP,Proxy(2)IP,……
2、结合geo模块解决
3、通过HTTP自定义变量传递
基于用户登录认证:http_auth_basic_module
Syntax: auth_basic string | off;
Default: auth_basic off; #默认是关闭的
Context: http, server, location, limit_except
Syntax: auth_basic_user_file file;
Default: —
Context: http, server, location, limit_except
# 指定保存用户名和密码的文件,格式如下
name1:password1
name2:password2:comment
name3:password3
http_auth_basic_module
局限性
- 用户信息依赖文件方式,管理操作机械,效率不高
解决方法:
- Nginx结合LUA实现高效验证
- Nginx结合LDAP,利用
nginx_auth_ldap
模块