Nginx
介绍
特点
- 处理响应请求快(异步非阻塞I/O,零拷贝,mmap,缓存机制)
- 扩展性好(模块化设计)
- 内存消耗低(异步非阻塞,多阶段处理)
- 可靠性好
- 热部署
- 高并发连接(事件驱动模型,多进程机制)
- 自由的 BSD 许可协议(可以自己修改代码后发布)
架构
Nginx特点:
- 事件驱动&异步非阻塞:事件驱动机制就是指当有读/写/连接事件就绪时 再去做读/写/接受连接这些事情,而不是一直在那里傻傻的等,基于事件驱动思想设计的多路复用I/O(如select/poll,epoll),相对于传统I/O模型,达到了异步非阻塞的效果
- 多进程机制:Nginx 有两种类型的进程,一种是Master主进程,一种是Worker工作进程。主进程主要负责3项工作:加载配置、启动工作进程及非停升级。另外work进程是主进程启动后,fork而来的。假设 Nginx fork 了多个 Worker 进程,并且在 Master 进程中通过 socket 套接字监听(listen)80端口。然后每个worker 进程都可以去 accept 这个监听的 socket。 当一个连接进来后,所有 Worker 进程,都会收到消息,但是只有一个 Worker 进程可以 accept 这个连接,其它的则 accept 失败,Nginx 保证只有一个Worker去accept的方式就是加锁(accept_mutex)。有了锁之后,在同一时刻,就只会有一个Worker进程去 accpet 连接,在 Worker 进程拿到 Http 请求后,就开始按照worker进程内的预置模块去处理该 Http 请求,最后返回响应结果并断开连接
- Proxy Cache(服务端缓存):Nginx 服务器在接收到被代理服务器的响应数据之后,一方面将数据传递给客户端,另一方面根据 Proxy Cache 的配置将这些数据缓存到本地硬盘上。当客户端再次访问相同的数据时,Nginx 服务器直接从硬盘检索到相应的数据返回给用户,从而减少与被代理服务器交互的时间。在缓存数据时,运用了零拷贝以及 mmap 技术,使得数据 copy 性能大幅提升
- 反向代理:通过反向代理,可以隐藏真正的服务,增加其安全性,同时便于统一管理处理请求,另外可以很容易的做个负载均衡,更好的面对高并发的场景
模块
Nginx 模块图如下:
- 核心模块:Nginx 服务器正常运行不可缺少的部分,提供错误日志解析、配置文件解析、事件驱动机制、进 程管理等核心功能
- 标准HTTP模块:提供 HTTP 协议相关的功能,如:端口配置、网页编码配置、HTTP 响应头设置等
- 可选HTTP模块:用户拓展标准的 HTTP 功能,让 Nginx 能处理一些特殊的服务,如:Flash 多媒体传输、解析 GeoIP 请求、SSL 支持等
- 邮件服务模块:主要用于支持 Nginx 的邮件服务,包括对 POP3 协议、IMAP 协议和 SMTP 协议的支持
- 第三方模块:JSON 支持、Lua 支持等
常见应用场景
- 反向代理
- 负载均衡
- 缓存
- 限流
- 静态资源服务
- 跨域
- 防盗链
- 高可用
目录
[root@localhost /]# tree /usr/local/nginx/ -L 2
/usr/local/nginx/
├── conf #存放一系列配置文件的目录
│ ├── fastcgi.conf #fastcgi程序相关配置文件
│ ├── fastcgi.conf.default #fastcgi程序相关配置文件备份
│ ├── fastcgi_params #fastcgi程序参数文件
│ ├── fastcgi_params.default #fastcgi程序参数文件备份
│ ├── koi-utf #编码映射文件
│ ├── koi-win #编码映射文件
│ ├── mime.types #媒体类型控制文件
│ ├── mime.types.default#媒体类型控制文件备份
│ ├── nginx.conf #主配置文件
│ ├── nginx.conf.default#主配置文件备份
│ ├── scgi_params #scgi程序相关配置文件
│ ├── scgi_params.default #scgi程序相关配置文件备份
│ ├── uwsgi_params #uwsgi程序相关配置文件
│ ├── uwsgi_params.default#uwsgi程序相关配置文件备份
│ └── win-utf #编码映射文件
├── html #存放网页文档
│ ├── 50x.html #错误页码显示网页文件
│ └── index.html #网页的首页文件
├── logs #存放nginx的日志文件
├── sbin #存放启动程序
│ ├── nginx #nginx启动程序
│ └── nginx.old
└── test # 我自己建的目录,不用管这个
├── abc
└── cba
15 directories, 26 files
nginx.conf
nginx.conf
文件是由一个一个的指令块组成的,用{}
标识一个指令块
指令块有:
- 全局块
- events 块
- http 块
- location 块
- upstream 块
全局模块
event模块
http模块
upstream模块
server模块
location块
location块
....
server模块
location块
location块
...
....
- **全局模块:**配置影响 Nginx 全局的指令,比如运行 Nginx 的用户名、进程 pid 存放路径、日志存放路径、配置文件引入、worker 进程数等
- **events 模块:**配置影响 Nginx 服务器或与其他用户的网络连接,例如:每个进程的最大连接数,选取哪种时间驱动模型(select/poll epoll 或者是其他 Nginx 支持的)来处理连接请求,是否允许同时接受多个网络连接,开启多个网络连接序列化等
- **http 模块:**可以嵌套多个 server,配置代理、缓存、日志格式等绝大多数功能和第三方模块的配置。如:文件引入、mime-type 定义、日志自定义、是否使用 sendfile 传输文件、连接超时时间、单连接请求数等
- **server 模块:**配置虚拟主机的相关参数比如域名端口等,一个 http 中可以有多个 server
- **localtion 块:**配置 url 路由规则
- **upstream 块:**配置上游服务器的地址以及负载均衡策略和重试策略等
# 注意:有些指令是可以在不同指令块使用的(需要时可以去官网看看对应指令的作用域)。我这里只是演示
# 这里我以/usr/local/nginx/conf/nginx.conf文件为例
[root@localhost /usr/local/nginx]# cat /usr/local/nginx/conf/nginx.conf
#user nobody; # 指定Nginx Worker进程运行用户以及用户组,默认由nobody账号运行
worker_processes 1; # 指定工作进程的个数,默认是1个。具体可以根据服务器cpu数量进行设置, 比如cpu有4个,可以设置为4。如果不知道cpu的数量,可以设置为auto。 nginx会自动判断服务器的cpu个数,并设置相应的进程数
#error_log logs/error.log; # 用来定义全局错误日志文件输出路径,这个设置也可以放入http块,server块,日志输出级别有debug、info、notice、warn、error、crit可供选择,其中,debug输出日志最为最详细,而crit输出日志最少。
#error_log logs/error.log notice;
#error_log logs/error.log info; # 指定error日志位置和日志级别
#pid logs/nginx.pid; # 用来指定进程pid的存储文件位置
events {
accept_mutex on; # 设置网路连接序列化,防止惊群现象发生,默认为on
# Nginx支持的工作模式有select、poll、kqueue、epoll、rtsig和/dev/poll,其中select和poll都是标准的工作模式,kqueue和epoll是高效的工作模式,不同的是epoll用在Linux平台上,而kqueue用在BSD系统中,对于Linux系统,epoll工作模式是首选
use epoll;
# 用于定义Nginx每个工作进程的最大连接数,默认是1024。最大客户端连接数由worker_processes和worker_connections决定,即Max_client=worker_processes*worker_connections在作为反向代理时,max_clients变为:max_clients = worker_processes *worker_connections/4。进程的最大连接数受Linux系统进程的最大打开文件数限制,在执行操作系统命令“ulimit -n 65536”后worker_connections的设置才能生效
worker_connections 1024;
}
# 对HTTP服务器相关属性的配置如下
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; # 开启零拷贝 省去了内核到用户态的两次copy故在文件传输时性能会有很大提升
#tcp_nopush on; # 数据包会累计到一定大小之后才会发送,减小了额外开销,提高网络效率
keepalive_timeout 65; # 设置nginx服务器与客户端会话的超时时间。超过这个时间之后服务器会关闭该连接,客户端再次发起请求,则需要再次进行三次握手。
#gzip on; # 开启压缩功能,减少文件传输大小,节省带宽。
sendfile_max_chunk 100k; #每个进程每次调用传输数量不能大于设定的值,默认为0,即不设上限。
# 配置你的上游服务(即被nginx代理的后端服务)的ip和端口/域名
upstream backend_server {
server 172.30.128.65:8080;
server 172.30.128.65:8081 backup; #备机
}
server {
listen 80; #nginx服务器监听的端口
server_name localhost; #监听的地址 nginx服务器域名/ip 多个使用英文逗号分割
#access_log logs/host.access.log main; # 设置日志输出路径以及 级别,会覆盖http指令块的access_log配置
# location用于定义请求匹配规则。 以下是实际使用中常见的3中配置(即分为:首页,静态,动态三种)
# 第一种:直接匹配网站根目录,通过域名访问网站首页比较频繁,使用这个会加速处理,一般这个规则配成网站首页,假设此时我们的网站首页文件就是: usr/local/nginx/html/index.html
location = / {
root html; # 静态资源文件的根目录 比如我的是 /usr/local/nginx/html/
index index.html index.htm; # 静态资源文件名称 比如:网站首页html文件
}
# 第二种:静态资源匹配(静态文件修改少访问频繁,可以直接放到nginx或者统一放到文件服务器,减少后端服务的压力),假设把静态文件我们这里放到了 usr/local/nginx/webroot/static/目录下
location ^~ /static/ {
alias /webroot/static/; 访问 ip:80/static/xxx.jpg后,将会去获取/url/local/nginx/webroot/static/xxx.jpg 文件并响应
}
# 第二种的另外一种方式:拦截所有 后缀名是gif,jpg,jpeg,png,css.js,ico这些 类静态的的请求,让他们都去直接访问静态文件目录即可
location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
root /webroot/static/;
}
# 第三种:用来拦截非首页、非静态资源的动态数据请求,并转发到后端应用服务器
location / {
proxy_pass http://backend_server; #请求转向 upstream是backend_server 指令块所定义的服务器列表
deny 192.168.3.29; #拒绝的ip (黑名单)
allow 192.168.5.10; #允许的ip(白名单)
}
# 定义错误返回的页面,凡是状态码是 500 502 503 504 总之50开头的都会返回这个 根目录下html文件夹下的50x.html文件内容
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
# 其余的server配置 ,如果有需要的话
#server {
......
# location / {
....
# }
#}
# include /etc/nginx/conf.d/*.conf; # 一般我们实际使用中有很多配置,通常的做法并不是将其直接写到nginx.conf文件,
# 而是写到新文件 然后使用include指令 将其引入到nginx.conf即可,这样使得主配置nginx.conf文件更加清晰。
}