01 Nginx 快速入门


Nginx 简介

什么是 Nginx

  1. Nginx是一个开源且高性能、可靠的HTTP中间件和代理服务软件。

Nginx 高性能

  1. 作为Web服务器,与Apache相比,Nginx能够支持更多的并发连接访问,但占用的资源却更少,效率更高。

  2. 为什么Nginx总体性能比Apache高? Nginx 与 Apache同样是基于IO多路复用, 需要了解IO模型

五种 IO Model

1
2
3
4
5
# 1、blocking IO         阻塞IO
# 2、nonblocking IO 非阻塞IO
# 3、IO multiplexing IO多路复用
# 4、signal driven IO 信号驱动IO
# 5、asynchronous IO 异步IO
  1. 通常一次IO操作(Network IO read) ,一般会涉及到两个系统对象:
    • 一个是调用这个IO的process (or thread)
    • 另一个就是系统内核(kernel)。
  1. 当一个IO操作发生时,该操作会经历两个阶段:等待数据和拷贝数据两个阶段
    • 阻塞IO: 在这两个阶段,线程都将被阻塞
    • 非阻塞IP: 用户进程其实是需要不断的主动询问kernel数据准备好了没有,等待数据侧不阻塞但是拷贝数据依然阻塞。
  1. IO多路复用:
    • 一个进程可以同时对多个客户请求进行服务
    • 复用一个进程(select和epoll)来对多个IO进行服务,在这两个阶段都不会阻塞
    • 可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知应用程序进行相应的读写操作。
    • IO多路复⽤的实现⽅式有select、poll、Epool
  1. select 能够监视⽂件描述符的数量存在最⼤限制
    • 每次调用select,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大
    • 同时每次调用select都需要在内核遍历传递进来的所有fd,这个开销在fd很多时也很大
    • select支持的文件描述符数量太小了,默认是1024,所以需要调整配置打开文件最大数等内核参数
  1. Epool 无须遍历整个被侦听的fd集合
    • 给每一个监听对象都绑定一个回调函数
    • 数据准备就绪时,调用回调函数,把就绪fd放入就绪链表中
  1. 总结:select 线性轮询 随着连接数增加,性能减少, epell轮询就绪链表,只有准备好的才执行。
    • select 上洗手间 每个孩子都要过问一次
    • Epool 想上洗手间的孩子 排好队站在约定好的地方,epoll看有谁来了 就带谁去

CPU亲和(affinity)

1
2
将CPU核心和Nginx工作进程绑定方式,把每个worker进程固定在1个cpu上执行,
减少切换cpu的切换(cache miss) ,获得更好的性能。

Sendfile 文件传输

  1. nginx在支持了sendfile系统调用后,避免了内核层与用户层的上线文切换(content swith)工作,大大减少了系统性能的开销。
  2. 查看系统中上下文切换 vmstat
  3. 所以当 Nginx 是一个静态文件服务器的时候,开启 SENDFILE 配置项能大大提高 Nginx 的性能,高效传输。
  4. 但是当 Nginx 是作为一个反向代理来使用的时候,SENDFILE 则没什么用了,因为 Nginx 是反向代理的时候。
    in_fd 就不是文件句柄而是 socket,此时就不符合 sendfile 函数的参数要求了。
1
sendfile on

Nginx 的使用场景

1
2
3
4
5
6
7
1. 静态处理
2. 反向代理 - 代理一台
3. 负载均衡 - 负载集群
4. 资源缓存
5. 安全防护 - nginx + lua
6. 访问限制
7. 访问认
1
2
3
4
Nginx作为Web服务器的主要应用场景包括:
1、使用Nginx运行HTML、JS、CSS、小图片等静态数据(此功能类似Lighttpd软件)
2、Nginx结合FastCGI运行PHP等动态程序(例如使用fastcgi_pass方式)
3、Nginx结合Tomcat/Resin等支持Java动态程序(常用proxy_pass)方式

Nginx 与 Apache 特点比较

1
2
3
4
5
6
7
8
apache: 
- 基于传统的select模型,高并发能力有限。
- 高并发时消耗系统资源相对多一些。
- 支持扩展库,通过DSO、apxs方法编译安装额外的插件功能,不需要重新编译Apache
nginx:
- 基于epoll模型,高并发能力很强。
- 高并发时消耗系统资源较低。
- 不支持类似Apache的DSO模式,扩展库必须编译进主程序(缺点)

常用的http软件

1
2
3
4
5
1. HTTPD -> Apache基金会
2. IIS -> 微软
3. GWS -> Google
4. openrestry -> nginx+lua
5. tengline -> 淘宝基于Nginx开

Nginx YUM安装

版本选取

Mainline version 开发版
Stable version 稳定版 # 选取长期维护的稳定版
Legacy version 历史版本

启动aliyun主机

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
位置 
香港
突发性能实例 t5
# 2U 4G
操作系统
# CentOS 7.4
公网带宽
# 100M
端口开放
# 80、443
创建密钥对
# home-leo
实例名称
# Ecs_Nginx
主机名
# Nginx-node1
创建实例

yum 安装稳定版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 基本组件安装
[root@Nginx-node1 ~]# yum install -y gcc gcc-c++ autoconf pcre pcre-devel make automake wget httpd-tools vim tree

# 检查防火墙
[root@Nginx-node1 ~]# systemctl status firewalld

# 检查selinux
[root@Nginx-node1 ~]# setenforce 0

# 初始化基本目录
[root@Nginx-node1 ~]# mkdir -p /soft/{code,logs,package/src,backup}
[root@Nginx-node1 ~]# tree /soft/
/soft/
├── backup
├── code
├── logs
└── package
└── src
1
2
3
4
5
6
7
8
9
10
11
# 配置Nginx官方yum源
# 官方提供的yum
# 阿里云epel的不是最新稳定版

vim /etc/yum.repos.d/nginx.repo

[nginx]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1
1
2
3
4
5
6
7
8
# 安装
[root@Nginx-node1 ~]# yum install nginx -y

[root@Nginx-node1 ~]# nginx -v
nginx version: nginx/1.16.1

[root@Nginx-node1 ~]# rpm -qa|grep nginx
nginx-1.16.1-1.el7.ngx.x86_64
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 查看安装的依赖

[root@Nginx-node1 ~]# nginx -V
nginx version: nginx/1.16.1
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules
--conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log
--http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid
--lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp
--http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp
--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp
--user=nginx --group=nginx --with-compat --with-file-aio --with-threads
--with-http_addition_module --with-http_auth_request_module
--with-http_dav_module --with-http_flv_module --with-http_gunzip_module
--with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module
--with-http_realip_module --with-http_secure_link_module --with-http_slice_module
--with-http_ssl_module --with-http_stub_status_module
--with-http_sub_module --with-http_v2_module --with-mail
--with-mail_ssl_module --with-stream --with-stream_realip_module
--with-stream_ssl_module --with-stream_ssl_preread_module
--with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie'
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
26
27
28
29
30
31
32
33
34
35
# 查看安装了那些东西
[root@Nginx-node1 ~]# rpm -ql nginx
/etc/logrotate.d/nginx
/etc/nginx
/etc/nginx/conf.d
/etc/nginx/conf.d/default.conf
/etc/nginx/fastcgi_params
/etc/nginx/koi-utf
/etc/nginx/koi-win
/etc/nginx/mime.types
/etc/nginx/modules
/etc/nginx/nginx.conf
/etc/nginx/scgi_params
/etc/nginx/uwsgi_params
/etc/nginx/win-utf
/etc/sysconfig/nginx
/etc/sysconfig/nginx-debug
/usr/lib/systemd/system/nginx-debug.service
/usr/lib/systemd/system/nginx.service
/usr/lib64/nginx
/usr/lib64/nginx/modules
/usr/libexec/initscripts/legacy-actions/nginx
/usr/libexec/initscripts/legacy-actions/nginx/check-reload
/usr/libexec/initscripts/legacy-actions/nginx/upgrade
/usr/sbin/nginx
/usr/sbin/nginx-debug
/usr/share/doc/nginx-1.16.1
/usr/share/doc/nginx-1.16.1/COPYRIGHT
/usr/share/man/man8/nginx.8.gz
/usr/share/nginx
/usr/share/nginx/html
/usr/share/nginx/html/50x.html
/usr/share/nginx/html/index.html
/var/cache/nginx
/var/log/nginx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 看配置文件

[root@Nginx-node1 ~]# rpm -qc nginx
/etc/logrotate.d/nginx
/etc/nginx/conf.d/default.conf
/etc/nginx/fastcgi_params
/etc/nginx/koi-utf
/etc/nginx/koi-win
/etc/nginx/mime.types
/etc/nginx/nginx.conf
/etc/nginx/scgi_params
/etc/nginx/uwsgi_params
/etc/nginx/win-utf
/etc/sysconfig/nginx
/etc/sysconfig/nginx-debug

Nginx 安装目录

Nginx 编译参数

1
[root@Nginx-node1 ~]# nginx -V

Nginx 常用模块

Nginx 内置变量

1
2
常用:
$remote_addr 记录客户端IP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 启动服务 查看日志和记录格式
[root@Nginx-node1 ~]# nginx

[root@Nginx-node1 ~]# ps -aux |grep nginx
root 20255 0.0 0.0 46384 976 ? Ss 17:52 0:00 nginx: master process nginx
nginx 20256 0.0 0.0 46796 1932 ? S 17:52 0:00 nginx: worker process
root 20258 0.0 0.0 112660 968 pts/0 S+ 17:52 0:00 grep --color=auto nginx

# 日志
[root@Nginx-node1 ~]# tailf /var/log/nginx/access.log
访问阿里云IP = http://47.56.134.107/

[root@Nginx-node1 nginx]# tailf /var/log/nginx/access.log
222.131.240.109 - - [18/Oct/2019:17:58:31 +0800] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36" "-"
222.131.240.109 - - [18/Oct/2019:17:58:40 +0800] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36" "-"

# 日志记录格式
[root@Nginx-node1 ~]# vim /etc/nginx/nginx.conf
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状态码(HTTP Status Code)是用以表示网页服务器HTTP响应状态的3位数字代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
301—永久移动。被请求的资源已被永久移动位置;

302—请求的资源现在临时从不同的 URI 响应请求;

305—使用代理。被请求的资源必须通过指定的代理才能被访问;

307—临时跳转。被请求的资源在临时从不同的URL响应请求;

400—错误请求;

402—需要付款。该状态码是为了将来可能的需求而预留的,用于一些数字货币或者是微支付;

403—禁止访问。服务器已经理解请求,但是拒绝执行它;

404—找不到对象。请求失败,资源不存在;

406—不可接受的。请求的资源的内容特性无法满足请求头中的条件,因而无法生成响应实体;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
301—永久移动。被请求的资源已被永久移动位置;

302—请求的资源现在临时从不同的 URI 响应请求;

305—使用代理。被请求的资源必须通过指定的代理才能被访问;

307—临时跳转。被请求的资源在临时从不同的URL响应请求;

400—错误请求;

402—需要付款。该状态码是为了将来可能的需求而预留的,用于一些数字货币或者是微支付;

403—禁止访问。服务器已经理解请求,但是拒绝执行它;

404—找不到对象。请求失败,资源不存在;

406—不可接受的。请求的资源的内容特性无法满足请求头中的条件,因而无法生成响应实体

502 后端服务没启动

504 请求成功 但是响应超时

Nginx 主配置文件描述

  1. Nginx主配置文件nginx.conf是一个纯文本类型的文件(其他配置文件大多也是如此),它位于nginx安装目录下的conf目录中,
    整个配置文件是以区块的形式组织的。一般,每个区块以一个大括号{}来表示,区块可以分为几个层次。
1
2
3
4
1.Main位于 nginx.conf配置文件最高层
2.Main层下可以有 Event、HTTP 层
3.HTTP层下⾯有允许有多个 Server 层, 用于对不同的网站做不同的配置
4.Server层也允许有多个 Location ,
  1. Nginx整个配置文件nginx.conf的主体框架为:

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
26
27
28
29
30
31
32
33
34
35
[root@Nginx-node1 conf.d]# vim /etc/nginx/nginx.conf

user nginx;
worker_processes 1; # 工作进程,配置和CPU个数一致

error_log /var/log/nginx/error.log warn; # 错误日志 路径 级别 一般常用的是error
pid /var/run/nginx.pid; # Nginx服务启动时的pid

events {
worker_connections 1024; # 每个work进程的最大连接数 一般配置 10000个
use epool;
}


http {
# 公共配置定义在http里面 , server的外面

include /etc/nginx/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 /var/log/nginx/access.log main;

sendfile on;
#tcp_nopush on;

keepalive_timeout 65;

#gzip on;

include /etc/nginx/conf.d/*.conf;
}
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
[root@Nginx-node1 conf.d]# vim /etc/nginx/conf.d/default.conf
# 每个虚拟主机使用1个server{}

server {
listen 80; # 监听端口 默认80
server_name localhost; # 提供服务的域名或者主机名

#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;

# location 控制网站访问路径
location / {
root /usr/share/nginx/html; # 存放的网站路径
index index.html index.htm; # 默认访问首页文件
}

#error_page 404 /404.html;

# redirect server error pages to the static page /50x.html
#
# 指定错误代码,统一定义错误页面,错误代码重定向到新的Locaiton
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}

# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}

# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}

# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}

部署一个 静态小游戏

  1. 端口还是使用80 使用hosts文件解析一个域名访问
  2. 增加一个server虚拟主机
1
2
3
4
5
# 上传游戏目录 解压
[root@Nginx-node1 conf.d]# mkdir -p /data/www/xiaoniao
[root@Nginx-node1 xiaoniao]# unzip xiaoniaofeifei.zip
[root@Nginx-node1 xiaoniao]# ls
2000.png 21.js icon.png img index.html sound1.mp3
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
# 新增xiaoniao.conf配置文件
[root@Nginx-node1 xiaoniao]# cd /etc/nginx/conf.d/

[root@Nginx-node1 conf.d]# vim xiaoniao.conf

server {
listen 80;
server_name www.xiaoniao.com;

root /data/www/xiaoniao;
index index.html index.htm;

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}


# 修改本机的hosts文件
C:\Windows\System32\drivers\etc\hosts
47.56.134.107 www.xiaoniao.com

# 本地访问
www.xiaoniao.com