Nginx?

1
2
3
4
Who?    俄罗斯人开发
What?   十分轻量级的HTTP服务器, 'engine X'
How?    高性能、模块丰富、配置灵活、低消耗
Why?    基于事件驱动方式编写 

Nginx 有那些功能?

关于 Nginx,有这些标签:「异步」「事件」「模块化」「高性能」「高并发」「反向代理」「负载均衡」

HTTP基础功能

  • 处理静态文件、索引文件以及自动索引

  • 无缓存的反向代理加速,简单的负载均衡喝容错

  • FastCGI:快速通用网关接口

  • 模块化结构:过滤器包括 gizpping、byte ranges、chunked responses、以及 SSI-Filter, 在SSI-Filter过滤器中,到同一个 proxy 或 FastCGI 的多个自请求并发处理。

  • SSL & TLS SNI 支持

IMAP/POP3代理服务功能

  • 使用外部 HTTP 认证服务器重定向用户到 IMAP/POP3 后端
  • 使用外部 HTTP 认证服务器认证用户后连接重定向到内部的 SMTP 后端
  • ……

结构与扩展

  • 一个主进程和多个工作进程。工作进程是单线程的,且不需要特殊的授权即可运行。

  • 10,000 非活动的 HTTP keep-alive 连接仅需 2.5M 内存

  • 最小化的数据拷贝

其他HTTP功能

  • 基于 IP 和 名称的虚拟主机服务

  • Memcached 的 GET 接口

  • 支持 keep-alive 和 管道连接

  • 重新配置和在线升级-不用中断客户的工作进程

  • 可定制访问日志和写入缓存

  • 4xx & 5xx 错误代码重定向

  • 基于客户端 IP 地址和 HTTP 基本认证的访问控制

  • 带宽限制

Nginx 如何工作呢?

初探nginx架构:多进程

Nginx Process Model

基本的 Nginx 体系结构由 master 进程和其他 worker 进程组成。master 进程读取配置文件,并维护 worker 进程,而 worker 进程则处理实际的请求。

Master 进程

Master 进程如何管理 Worker 进程工作呢?

  • 接收来自外界的信号,向各 worker 进程发送信号,监控 worker 进程的运行状态
  • 当 worker 进程退出后(异常退出),会自动重新启动新的 worker 进程

Worker 进程

Worker 进程干什么呢?

首先,需要明白各个 worker 进程是对等的,他们同等竞争来自客户端的请求,且各 worker 进程间相互独立

  • 一个请求,只能在一个 worker 进程中被处理
  • 一个 worker 进程,不能处理其他进程的请求
  • worker 进程的数量可以设置(一般设置为:cpu 核数)

Nginx 的优缺点是?

优点

nginx 最主要的特点:支持 kqueue(FreeBSD 4.1+)eqoll(Linux 2.6+) 等网络IO事件模型,由此支持高并发

  • 高并发:可支持高达 50,000 个并发响应
  • 内存消耗少:30,000 并发响应,Nginx 进程消耗内存不到 200M
  • HTTP反向代理,即负载均衡。
  • 支持 Cache

缺点

  • 内置了对 RS(Real Server) 服务器的健康检查功能。但,如果 nginx proxy 后端某台业务服务器宕机,不会影响前端访问,这个功能还是比较弱,需要改进。

返回目录

Nginx 初体验

安装

先装依赖库

g++、gcc、openssl-devel(ssl模块)、pcre-devel(rewrite模块)、zlib-devel(gzip模块)

1
2
3
4
$ yum install gcc-c++  
$ yum install pcre pcre-devel  
$ yum install zlib zlib-devel  
$ yum install openssl openssl--devel 

安装 nginx

方式一: 从源码编译安装

CentOS7.3安装Nginx 1.7.4
Centos下 Nginx安装与配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 先检查是否已安装 nginx
$ find -name nginx

# 如果系统已经安装了nginx,那么就先卸载
$ yum remove nginx  

# 首先进入/usr/local目录
$ cd /usr/local

# 从官网下载最新版的nginx
$ wget http://nginx.org/download/nginx-1.7.4.tar.gz 

# 解压nginx压缩包
$ tar -zxvf nginx-1.7.4.tar.gz

# 会产生一个nginx-1.7.4 目录,这时进入nginx-1.7.4目录
$ cd  nginx-1.7.4  

# 接下来安装,使用--prefix参数指定nginx安装的目录,make、make install安装
$ ./configure  # 默认安装在/usr/local/nginx  
$ make  
$ make install

# 如果没有报错,顺利完成后,最好看一下nginx的安装目录
$ whereis nginx 

方式二:通过 repo 安装

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# 创建nginx 的 yum 源
$ cd /etc/yum.repos.d/ && touch nginx.repo
$ vim nginx.repo

# 添加如下内容:
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1
# end

$ yum install nginx -y

# 测试是否成功
$ nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

配置开机启动

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 编辑 vi /lib/systemd/system/nginx.service 文件,没有创建一个 nginx.service 

# start
[Unit]
Description=nginx - high performance web server
Documentation=http://nginx.org/en/docs/
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target

[Service]
Type=forking
PIDFile=/var/run/nginx.pid
ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID

[Install]
WantedBy=multi-user.target
# end

# 设置开机启动,使配置生效
$ systemctl enable nginx.service

目录介绍

1
2
3
4
5
6
7
8
9
Nginx的:

默认站点根目录:/usr/share/nginx/html/

默认站点配置在:/etc/nginx/conf.d/default.conf

主配置文件是在:/etc/nginx/nginx.conf 
    |
    \__ 在这个配置文件里,会用到include指令,其它地方的配置文件会包含到这个主要的配置文件里,用这种方法可以让配置文件更有条理,也更容易维护。

Nginx 的 Hello World

1
2
3
4
5
6
7
8
# 检查 80 端口是否被占用
$ netstat -ultup | grep 80

# 如果有输出, kill it
$ kill -9 ${pid}

# 如果没有,启动服务
$ systemctl start nginx && systemctl status nginx

Nginx Hello World:

Nginx Hello World

返回目录

Nginx 运行和控制

nginx 控制信号

当 nginx 实例运行时,可通过发送相应的信号来管理:

  • nginx -s signal // send signal to a master process: stop|quit|reopen|reload
    • stop: 快速关闭
    • quit: 优雅关闭(等待worker线程完成处理)
    • reload: 重载配置文件
    • reopen: 重新打开日志文件

指令和上下文(域)

配置文件由下面的部分构成:

  • 指令 可选项,包含名称和参数,一分号结尾

    gzip on;

  • 上下文 分块, 分块中可声明指令,类似编程语言中的作用域,分块用 {} 符号

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    worker_process 2;   # 全局上下文指令
            
    http {              # http 上下文(域)
        gzip on;        # http 上下文指令
    
        server {        # server 上下文(域)
            listen 80;  # server 上下文中的指令
        }
    }

    指令类型

    在多个上下文中使用相同的额指令时,必须要小心,因为继承模型不同时有着不同的指令。

    有三种类型的指令,每种都有自己的继承模型

    普通指令

    在每个上下文仅有唯一值。而且,他只能在当前上下文中定义一次。子级上下文可以覆盖父级中的值,并且这个覆盖值只在当前的子级上下文中有效。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    
    gzip on;
    gzip off; # 非法,不能再同一个上下文中指定同一普通指令2次
    
    server {
    location /downlaods {
        gzip off;
    }
    
    location /assets {
        # gzip is on herre, 继承了父级 gzip 的值
    }
    }

数组指令

在同一上下文中添加多条指令,将添加多个值,而不是完全覆盖。在子级上下文中定义指令将覆盖给父级上下文中的值。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
error_log /var/log/nginx/error.log;
error_log /var/log/nginx/error_notive.log notice;
error_log /var/log/nginx/error_debug.log debug;

server {
    location /downloads {
        # 下面的配置会覆盖父级域中的额指令
        error_log /var/log/nginx/error_downloads.log;
    }
}

行动指令

Nginx 模块

核心模块

基本模块

其他模块

Mail模块

Nginx Config Examples

See Also

Thanks to the authors 🙂