Nginx基础
============================================================================
概述:
本章我们将介绍Nginx,内容权重都很重量级,内容包括:
- Nginx的相关概念,功能,解决的问题,官方站点;
- 5种I/O模型的介绍;
- Nginx的程序架构概述;
- Nginx的编译安装;
- Nginx中配置文件的构成;
- Nginx主配置段详解;
- Nginx中http协议的核心模块配置
Nginx介绍
★engineX = Nginx
- NGINX is a free, open-source,high-performance HTTP server and reverse proxy, as well as an IMAP/POP3 proxyserver.
(NGINX是一个免费、开源、高性能的HTTP服务器和反向代理,以及IMAP/POP3代理服务器)。
⊙功能:
- 是http协议的实现:可作为web服务器(类似于httpd);
- http reverse proxy反向代理(类似于httpd);
- imap/pop3 reverse proxy(邮件服务器的反向代理)
⊙官方站点:nginx.org
⊙C10K(10K Connections):解决C10K(一万个并发链接)的问题
★相关概念:
⊙并发连接数:
⊙C10K问题:
- 指的是客户端向服务器发起请求,并建立了TCP连接。每秒钟服务器链接的总TCP数量,就是并发连接数。
★国内nginx的二次开发:
- 网络服务在处理数以万计的客户端连接时,往往出现效率低下甚至完全瘫痪,这被称为C10K问题。
- Tengine
- OpenResty
http协议回顾:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIn5GcuUzNwgTTsJUZKN3REFUQtJEbPdXdNh3TnFDTvl2S39CX3QzLclDOvwFMw00LcJDMzZWe39CXt92Yu8GdjFTNuMzcvw1LcpDc0RHaiojIsJye.png)
I/0模型介绍
阻塞型、非阻塞型、复用型、信号驱动型、异步
★同步/异步:关注消息通知机制;
消息通知:
- 同步:等待对方返回消息;
- 异步:被调用者通过状态、通知或回调机制通知调用者被调用者的运行状态;
★阻塞/非阻塞:
关注调用者在等待结果返回之前所处的状态;
★一次IO请求,都会由两阶段组成:
- 阻塞:blocking,调用结果返回之前,调用者被挂起;
- 非阻塞:nonblocking,调用结果返回之前,调用者不会被挂起;
★复用型IO调用:
- 第一步:等待数据,即数据从磁盘到内核内存;
- 第二步:复制数据,即数据内核内存到进程内存;
- select():1024
- poll():
★I/O模型
⊙阻塞I/O模型
应用程序调用一个IO函数,导致应用程序阻塞,等待数据准备好。
如果数据没有准备好,一直等待。。。。
数据准备好了,从内核拷贝到用户空间
I/O函数返回成功指示
![]()
1.Nginx基础(一) ⊙非阻塞I/O模型
我们把一个套接口设置为非阻塞就是告诉内核,当所请求的I/O操作无法完成时,不要将进程睡眠,而是返回一个错误。这样我们的I/O操作函数将不断的测试 数据是否已经准备好,如果没有准备好,继续测试,直到数据准备好为止。在这个不断测试的过程中,会大量的占用CPU的时间。
![]()
1.Nginx基础(一) ⊙I/O复用模型
I/O复用模型会用到select或者poll函数,这两个函数也会使进程阻塞,但是和阻塞I/O所不同的的,这两个函数可以同时阻塞多个I/O操作。而且可以同时对多个读操作,多个写操作的I/O函数进行检测,直到有数据可读或可写时,才真正调用I/O操作函数。
![]()
1.Nginx基础(一) ⊙信号驱动I/O模型
首先我们允许套接口进行信号驱动I/O,并安装一个信号处理函数,进程继续运行并不阻塞。当数据准备好时,进程会收到一个SIGIO信号,可以在信号处理函数中调用I/O操作函数处理数据。
![]()
1.Nginx基础(一) ⊙异步I/O模型
调用aio_read函数,告诉内核描述字,缓冲区指针,缓冲区大小,文件偏移以及通知的方式,然后立即返回。当内核将数据拷贝到缓冲区后,再通知应用程序。
★5个I/O模型的比较![]()
1.Nginx基础(一) ![]()
1.Nginx基础(一)
Nginx的程序架构:
★master/worker(两级架构)
⊙一个master进程:
⊙一个或多个worker进程
- 负载加载配置文件、管理worker进程、平滑升级;
⊙缓存相关的进程:
- 处理并响应用户请求;
★特性:异步、事件驱动和非阻塞
- cache loader:载入缓存对象
- cache manager:管理缓存对象
★nginx高度模块块:
- 并发请求处理:通过kevent/epoll/select
- 文件IO:高级IO sendfile,异步,mmap
- 高度模块化,但其模块早期不支持DSO机制;近期版本支持动态装载和卸载;
⊙模块分类:
◆核心模块:core module
◆标准模块:
- Standard HTTP modules(标准模块)
- Optional HTTP modules(可选模块)
- Mail modules
- Stream modules
◆3rd party modules(第三方模块)
★nginx的功用:
- 静态的web资源服务器;
- 结合FastCGI/uwSGI/SCGI等协议反代动态资源请求;(也可以缓存动态资源)
- http/https协议的反向代理;
- imap4/pop3协议的反抽代理;
- tcp/udp协议的反代;
附图:
Ningx程序架构图
![]()
1.Nginx基础(一)
Nginx的安装配置
★官方的预制包:★编译安装:
- http://nginx.org/packages/centos/7/x86_64/RPMS/
- yum groupinstall "Development tools" "Server Platform Development" 准备开发环境
- yum install pcre-devel openssl-devel zlib-devel 解决依赖关系
- useradd -r nginx
- ./configure --prefix=/usr/local/nginx --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/lock/nginx.lock --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_dav_module --with-http_stub_status_module --with-threads --with-file-aio
- # make && make install
编译安装:
[root@centos7 nginx]# ls # 如下,这是我从官网下载的源码包和rpm包。
nginx-1.10.0-1.el7.ngx.x86_64.rpm nginx-1.10.0.tar.gz
# 这里我们首先进行编译安装
[root@centos7 nginx]# tar xvf nginx-1.10.0.tar.gz # 解压源码包
[root@centos7 nginx]# ls
nginx-1.10.0 (解压后的目录) nginx-1.10.0-1.el7.ngx.x86_64.rpm nginx-1.10.0.tar.gz
[root@centos7 nginx]# cd nginx-1.10.0/ # 进入目录
[root@centos7 nginx-1.10.0]# ls
auto CHANGES CHANGES.ru conf configure contrib html LICENSE man README src
# 如上可以看到目录中的文件和我们之前编译过的程序大体相同,也同样遵循三步曲
首先我们查看 ./configure --help 查看常用的选项
1.在执行之前我们还要创建一个nginx的系统用户 :
2.执行./configure 指明要存放的程序位置,及配置文件,要添加的模块等等
[root@centos7 nginx-1.10.0]# ./configure --prefix=/usr/local/nginx --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 --user=nginx --group=nginx
--with-http_ssl_module --with-http_v2_module --with-http_dav_module --with-http_stub_status_module
--with-threads --with-file-aio
Configuration summary
+ using threads
+ using system PCRE library
+ using system OpenSSL library
+ md5: using OpenSSL library
+ sha1: using OpenSSL library
+ using system zlib library
nginx path prefix: "/usr/local/nginx"
nginx binary file: "/usr/local/nginx/sbin/nginx"
nginx modules path: "/usr/local/nginx/modules"
nginx configuration prefix: "/etc/nginx"
nginx configuration file: "/etc/nginx/nginx.conf"
nginx pid file: "/var/run/nginx.pid"
nginx error log file: "/var/log/nginx/error.log"
nginx http access log file: "/var/log/nginx/access.log"
nginx http client request body temporary files: "client_body_temp"
nginx http proxy temporary files: "proxy_temp"
nginx http fastcgi temporary files: "fastcgi_temp"
nginx http uwsgi temporary files: "uwsgi_temp"
nginx http scgi temporary files: "scgi_temp"
3.如上第一步已经完成,下面我们执行 make && make install
4.接下来,要把主程序文件添加至PATH环境变量
# 在/etc/profile.d/下创建一个脚本配置文件
[root@centos7 nginx-1.10.0]# vim /etc/profile.d/nginx.sh
1 export PATH=/user/local/nginx/sbin:$PATH
# 然后保存退出,重读配置文件
[root@centos7 nginx-1.10.0]# . /etc/profile.d/nginx.sh
# 可以测试一下语法
[root@centos7 ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
如上整个编译过程就已将完成,因为这里没有UNIT file文件或者service脚本所以直接nginx就可启动程序(注意:httpd和nginx只能启动一个,如果httpd启动了,nginx就启动不了了)
[root@centos7 ~]# nginx # 启动程序
[root@centos7 ~]# ss -tnl # 查看80端口
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 25 *:514 *:*
LISTEN 0 128 *:80 *:*
LISTEN 0 128 *:22 *:*
LISTEN 0 128 127.0.0.1:631 *:*
LISTEN 0 100 127.0.0.1:25 *:*
LISTEN 0 128 127.0.0.1:6010 *:*
LISTEN 0 25 :::514 :::*
LISTEN 0 128 :::22 :::*
LISTEN 0 128 ::1:631 :::*
LISTEN 0 100 ::1:25 :::*
LISTEN 0 128 ::1:6010 :::*
nginx提供的网页文件在/usr/local/nginx/html
[root@centos7 ~]# ls /usr/local/nginx/
client_body_temp fastcgi_temp html proxy_temp sbin scgi_temp uwsgi_temp
[root@centos7 ~]# ls /usr/local/nginx/html/
50x.html index.html
现在我们打开浏览器,访问服务如下:
5.为nginx提供SysV init脚本:
新建文件/etc/rc.d/init.d/nginx,内容如下:
#!/bin/sh
#
# nginx - this script starts and stops the nginx daemon
#
# chkconfig: - 85 15
# description: Nginx is an HTTP(S) server, HTTP(S) reverse \
# proxy and IMAP/POP3 proxy server
# processname: nginx
# config: /etc/nginx/nginx.conf
# config: /etc/sysconfig/nginx
# pidfile: /var/run/nginx.pid
# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0
nginx="/usr/local/nginx/sbin/nginx"
prog=$(basename $nginx)
NGINX_CONF_FILE="/etc/nginx/nginx.conf"
[ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx
lockfile=/var/lock/subsys/nginx
make_dirs() {
# make required directories
user=`nginx -V 2>&1 | grep "configure arguments:" | sed 's/[^*]*--user=\([^ ]*\).*/\1/g' -`
options=`$nginx -V 2>&1 | grep 'configure arguments:'`
for opt in $options; do
if [ `echo $opt | grep '.*-temp-path'` ]; then
value=`echo $opt | cut -d "=" -f 2`
if [ ! -d "$value" ]; then
# echo "creating" $value
mkdir -p $value && chown -R $user $value
fi
fi
done
}
start() {
[ -x $nginx ] || exit 5
[ -f $NGINX_CONF_FILE ] || exit 6
make_dirs
echo -n $"Starting $prog: "
daemon $nginx -c $NGINX_CONF_FILE
retval=$?
echo
[ $retval -eq 0 ] && touch $lockfile
return $retval
}
stop() {
echo -n $"Stopping $prog: "
killproc $prog -QUIT
retval=$?
echo
[ $retval -eq 0 ] && rm -f $lockfile
return $retval
}
restart() {
configtest || return $?
stop
sleep 1
start
}
reload() {
configtest || return $?
echo -n $"Reloading $prog: "
killproc $nginx -HUP
RETVAL=$?
echo
}
force_reload() {
restart
}
configtest() {
$nginx -t -c $NGINX_CONF_FILE
}
rh_status() {
status $prog
}
rh_status_q() {
rh_status >/dev/null 2>&1
}
case "$1" in
start)
rh_status_q && exit 0
$1
;;
stop)
rh_status_q || exit 0
$1
;;
restart|configtest)
$1
;;
reload)
rh_status_q || exit 7
$1
;;
force-reload)
force_reload
;;
status)
rh_status
;;
condrestart|try-restart)
rh_status_q || exit 0
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"
exit 2
esac
#==================================================================================
而后为此脚本赋予执行权限:
# chmod +x /etc/rc.d/init.d/nginx
添加至服务管理列表,并让其开机自动启动:
# chkconfig --add nginx
# chkconfig nginx on
而后就可以启动服务并测试了:
# service nginx start
Nginx的相关配置
★配置文件的组成部分:
⊙主配置文件:
- nginx.conf
- include conf.d/*.conf (这里没有指明)
⊙fastcgi,uwsgi,scgi等协议相关的配置文件
⊙mime.types:支持的mime类型
★主配置文件的配置指令:
⊙格式:
- directive value [value2 ...];
注意:
◆指令必须以分号结尾;
◆支持使用配置变量;
- 内建变量:由Nginx模块引入,可直接引用;
- 自定义变量:由用户使用set命令定义;
set variable_name value;
引用变量:$variable_name
★主配置文件结构:
☉http协议相关的配置结构(所有和web相关的都要在这里配置)![]()
1.Nginx基础(一) ![]()
1.Nginx基础(一)
演示:
[root@centos7 ~]# cd /etc/nginx/
[root@centos7 nginx]# ls
conf.d fastcgi.conf fastcgi_params koi-utf mime.types nginx.conf scgi_params uwsgi_params win-utf
default.d fastcgi.conf.default fastcgi_params.default koi-win mime.types.default nginx.conf.default scgi_params.default uwsgi_params.default
[root@centos7 nginx]# cp nginx.conf{,.bak} # 备份主配置文件
[root@centos7 nginx]# vim nginx.conf # 编辑配置文件
# 主配置段如下:
1
2 #user nobody;
3 worker_processes 1;
4
5 #error_log logs/error.log;
6 #error_log logs/error.log notice;
7 #error_log logs/error.log info;
8
9 #pid logs/nginx.pid;
10
11
12 events {
13 worker_connections 1024;
14 }
15
16# ========================================================================
17 # http配置段
http {
18 include mime.types;
19 default_type application/octet-stream;
20
21 #log_format main '$remote_addr - $remote_user [$time_local] "$request" '
22 # '$status $body_bytes_sent "$http_referer" '
23 # '"$http_user_agent" "$http_x_forwarded_for"';
24
25 #access_log logs/access.log main;
26
27 sendfile on;
28 #tcp_nopush on;
29
30 #keepalive_timeout 0;
31 keepalive_timeout 65;
32
33 #gzip on;
34
35 server {
36 listen 80;
37 server_name localhost;
38
39 #charset koi8-r;
40
41 #access_log logs/host.access.log main;
42
43 location / {
44 root html;
45 index index.html index.htm;
46 }
......
Nginx主配置段详述
主配置段(main block)
★分类:⊙正常运行必备的配置:
- 正常运行必备的配置
- 优化性能相关的配置
- 用于调试及定位问题相关的配置
- 事件驱动相关的配置
⊙性能优化相关的配置:![]()
1.Nginx基础(一) ![]()
1.Nginx基础(一) 示例:
1.worker_cpu_affinity auto [cpumask] ...;
2.worker_priority number;[root@centos7 ~]# vim /etc/nginx/nginx.conf #user nobody; worker_processes 2; worker_cpu_affinity 00000001 00000010; (# 表示仅用0号和1号cpu) # 测试语法并重载nginx [root@centos7 ~]# nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful [root@centos7 ~]# nginx -s reload # 查看进程,可见只有两个worker [root@centos7 ~]# ps aux root 1127 0.0 0.3 47604 3512 ? Ss 17:38 0:00 nginx: master process nginx nginx 1171 0.0 0.3 50180 3932 ? S 17:51 0:00 nginx: worker process nginx 1172 0.0 0.3 50180 3932 ? S 17:51 0:00 nginx: worker process [root@centos7 ~]# ps axo pid,comm,psr PID COMMAND PSR 1171 nginx 0 1172 nginx 1 ============================================================================================= # worker_cpu_affinity auto 表示nginx启动自己选择好一颗cpu绑定 [root@centos7 ~]# vim /etc/nginx/nginx.conf #user nobody; worker_processes auto; worker_cpu_affinity auto; [root@centos7 ~]# ps axo pid,comm,psr PID COMMAND PSR 1235 nginx 0 1236 nginx 1 1237 nginx 2 1238 nginx 3
⊙调试、定位问题:[root@centos7 ~]# ps axo pid,comm,psr PID COMMAND PSR NI 1235 nginx 0 0 1236 nginx 1 0 1237 nginx 2 0 # 默认nice为0 1238 nginx 3 0 [root@centos7 ~]# vim /etc/nginx/nginx.conf #user nobody; worker_processes auto; worker_cpu_affinity auto; worker_priority -5; # 修改nice为-5 [root@centos7 ~]# nginx -s reload [root@centos7 ~]# ps axo pid,comm,psr,nice PID COMMAND PSR NI 1296 nginx 0 -5 1297 nginx 1 -5 1298 nginx 2 -5 # 变为-5 1299 nginx 3 -5
⊙事件驱动相关的配置:引入了新的上下文,定义在events{...}zhong![]()
1.Nginx基础(一) ![]()
1.Nginx基础(一)
http协议配置详述:
1.ngx_http_core_module(核心模块)
★配置结构:![]()
1.Nginx基础(一) ★与套接字相关的配置
⊙server { ... },配置一个虚拟主机
⊙listen PORT|address[:port]|unix:/PATH/TO/SOCKET_FILE![]()
1.Nginx基础(一) ⊙server_name name ...;![]()
1.Nginx基础(一) ⊙tcp_nodelay on | off; 无延迟![]()
1.Nginx基础(一) ⊙sendfile on | off;
- 在keepalived模式下的连接是否启用TCP_NODELAY选项;
- 建议为on(表示不启用打包多个小包为一个打包发送,无延迟,用户请求即相应)
- 表示是否启用sendfile功能;
- sendfile 表示直接在内核级别封装资源传送给客户端,在效率上要高很多。
- 优化nginx:建议启用 on
配置基于端口的虚拟主机
1.首先创建虚拟主机的根目录,并提供页面文件
[root@centos7 ~]# mkdir -pv /vnhosts/www{1,2}
mkdir: created directory ‘/vnhosts’
mkdir: created directory ‘/vnhosts/www1’
mkdir: created directory ‘/vnhosts/www2’
[root@centos7 ~]# echo "www1.taotao.com" > /vnhosts/www1/index.html
[root@centos7 ~]# echo "www2.taotao.com" > /vnhosts/www2/index.html
[root@centos7 ~]# cat /vnhosts/www1/index.html
www1.taotao.com
[root@centos7 ~]# cat /vnhosts/www2/index.html
www2.taotao.com
2.编辑配置文件/etc/nginx/nginx.conf
[root@centos7 ~]# vim /etc/nginx/nginx.conf
# 定义两个基于端口的虚拟主机
server {
84 listen 8080;
85 server_name www1.taotao.com;
86 root /vnhosts/www1;
87 }
88 server {
89 listen 8088;
90 server_name www2.taotao.com;
91 root /vnhosts/www2;
92 }
3.定义好之后保存退出,测试语法,重载,并查看端口8080和8088
[root@centos7 ~]# nginx -t # 测试语法
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@centos7 ~]# nginx -s reload # 重载
[root@centos7 ~]# ss -tnl # 查看端口8080和8088
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 25 *:514 *:*
LISTEN 0 128 *:8080 *:*
LISTEN 0 128 *:80 *:*
LISTEN 0 128 *:22 *:*
LISTEN 0 128 127.0.0.1:631 *:*
LISTEN 0 128 *:8088 *:*
LISTEN 0 100 127.0.0.1:25 *:*
LISTEN 0 128 127.0.0.1:6010 *:*
LISTEN 0 25 :::514 :::*
LISTEN 0 128 :::22 :::*
LISTEN 0 128 ::1:631 :::*
LISTEN 0 100 ::1:25 :::*
LISTEN 0 128 ::1:6010 :::*
浏览器访问如下:
后续内容将详见http://1992tao.blog.51cto.com/11606804/1866443,将继续介绍nginx中http配置段的内容,谢谢关注!!!