在nginx以前
同步异步阻塞非阻塞、并发并行
1)同步与异步html
- 同步:当一个同步调用发出后,调用者要一直等待调用的结果返回,才能进行后续的执行
- 异步:当一个异步调用发出后,调用者没必要一直等待调用结果的返回;异步调用要获取结果,有两种方式:
- 主动轮询异步调用的结果
- 被调用方经过callback(回调通知)来通知调用方调用结果
2)阻塞与非阻塞linux
阻塞与非阻塞的重点在于进/线程等待消息时的行为:在等待消息的时候,当前线程是挂起状态,仍是非挂起状态nginx
- 阻塞:调用发出后,在消息返回前,当前线程被挂起,直到有消息返回,当前进/线程才会被激活
- 非阻塞:调用发出后,不会阻塞当前进/线程,而会当即返回
总结:同步与异步,重点在于消息通知的方式;阻塞与非阻塞,重点在等待消息时的行为。c++
Nginx采用异步非阻塞的方式工做。跟Linux中的epoll模型有关。web
3)并发与并行正则表达式
并发(concurrency)和并行(parallellism)是:docker
- 解释一:并行是指两个或者多个事件在同一时刻发生;而并发是指两个或多个事件在同一时间间隔发生。
- 解释二:并行是在不一样实体上的多个事件,并发是在同一实体上的多个事件。
- 解释三:在一台处理器上“同时”处理多个任务,在多台处理器上同时处理多个任务。
如hadoop分布式集群 因此并发编程的目标是充分的利用处理器的每个核,以达到最高的处理性能shell
epoll
I/O多路复用的epoll模型apache
当有I/O事件产生时,epoll就会去告诉进程哪一个连接有I/O事件,而后进程就去处理这个事件编程
nginx原理
每进来一个request,会有一个worker进程去处理。但不是全程处理,处理到可能发生阻塞的地方。好比向后端服务器转发request,并等待结果返回。那么,这个worker不会这么傻等着,他会在发完请求后,注册一个事件:“若是后端服务返回了,告诉我一声,我接着干”。因而他休息去了。此时,若是再有新的request进来,他就能够很快再以这种方式处理。而一旦后端服务返回了,就会触发这个事件,worker才会来接手,这个request都会接着往下走。经过这种快速处理,快速释放请求的方式,达到一样的配置能够处理更大并发量的目的。
概述
nginx是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。
nginx支持fastCGI(默认支持)
nginx有两种工做模式
- master-worker模式
- 单进程模式
master-worker模式:有一个master进程和至少一个worker进程。master进程负责处理系统信号、加载配置、管理worker进程(启动、杀死、监控、发送消息/信号等)。worker进程负责处理具体业务逻辑,也就是说,真正提供服务的是worker进程。生产环境下通常使用这种模式。
单进程模式:todo...
模块分类
- 核心模块:HTTP模块、EVENT模块和MAIL模块
- 基础模块:HTTP Access、HTTP FastCGI、HTTP Proxy、HTTP Rewrite
- 第三方模块:HTTP Upstream Request Hash、Notive、HTTP Access Key
nginx的高并发利益于采用epoll模型,epoll模型是linux2.6之后才出现,apache采用select模型。
应用场景
三大应用场景
- 静态资源服务
- 反向代理服务
- API服务
安装(linux)
安装环境:CentOS 7
方式一:make
-
安装nginx依赖的其它包
- pcre-devel,nginx的配置文件中使用了正则表达式,所以要安装来支持。
- 还有其它的依赖,如gcc、gcc-c++、zlib-devel、openssl-devel等,根据须要来安装(通常都建议安装上)。
-
安装 nginx
$ wget http://nginx.org/download/nginx-1.12.1.tar.gz $ tar -zxvf nginx-1.12.1.tar.gz $ cd nginx-1.12.1/ $ ./configure $ make $ sudo make install
默认安装在/usr/local/nginx
,也能够在./configure
时指定安装的路径./configure --prefix=/home/geek/nginx
默认安装的log
和conf
都在/usr/local/nginx
下面
/usr/local/nginx
目录以下:
├── conf │ ├── fastcgi.conf │ ├── fastcgi.conf.default │ ├── fastcgi_params │ ├── fastcgi_params.default │ ├── koi-utf │ ├── koi-win │ ├── mime.types │ ├── mime.types.default │ ├── nginx.conf │ ├── nginx.conf.default │ ├── scgi_params │ ├── scgi_params.default │ ├── uwsgi_params │ ├── uwsgi_params.default │ └── win-utf ├── html │ ├── 50x.html │ └── index.html ├── logs │ ├── access.log │ ├── error.log │ └── nginx.pid ├── sbin │ └── nginx
源码安装官方文档:http://nginx.org/en/docs/configure.html
- 启动 & 关闭
$ sudo /usr/local/nginx/sbin/nginx -t # 检查配置信息是否有错 $ sudo /usr/local/nginx/sbin/nginx # 启动nginx,虚拟机要关闭防火墙或开放80端口 $ sudo /usr/local/nginx/sbin/nginx -s stop # 强制中止nginx $ sudo /usr/local/nginx/sbin/nginx -s quit # 优雅关闭nginx $ sudo /usr/local/nginx/sbin/nginx -s reload # 从新加载nginx.conf文件 $ /usr/local/nginx/sbin/nginx -v # 显示nginx版本信息
方式二:yum
1)先安装yum-utils
sudo yum install yum-utils
2)添加yum源
vim /etc/yum.repos.d/nginx.repo
添加如下内容
[nginx-stable] name=nginx stable repo baseurl=http://nginx.org/packages/centos/$releasever/$basearch/ gpgcheck=1 enabled=1 gpgkey=https://nginx.org/keys/nginx_signing.key [nginx-mainline] name=nginx mainline repo baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/ gpgcheck=1 enabled=0 gpgkey=https://nginx.org/keys/nginx_signing.key
3)安装nginx
sudo yum install nginx
默认安装最新的stable版本,之后也能够经过上面配置的yum源来更新版本
官方文档:http://nginx.org/en/linux_packages.html#RHEL-CentOS
[root@localhost test]# whereis nginx nginx: /usr/sbin/nginx /usr/lib64/nginx /etc/nginx /usr/share/nginx /usr/share/man/man8/nginx.8.gz
方式三:docker
nginx经常使用命令
命令格式:nginx -s reload
- 帮助:-? -h
- 使用指定的配置文件:-c
- 指定配置指令:-g
- 指定运行目录:-p
- 发送信号:-s
- 当即中止服务:nginx -s stop
- 优雅中止服务:nginx -s quit
- 重载配置文件:nginx -s reload
- 从新开始记录日志文件:nginx -s reopen
- 测试配置文件是否有语法错误:-t -T
- 打印nginx版本、编译信息:-v -V
nginx.conf
本机nginx.conf文件位置的说明
centos 7 使用 yum 安装的 nginx 默认的安装目录以下:
[root@localhost docs]# whereis nginx nginx: /usr/sbin/nginx /usr/lib64/nginx /etc/nginx /usr/share/nginx /usr/share/man/man8/nginx.8.gz
全部配置文件位于 /etc/nginx/ 下,/etc/nginx/nginx.conf是主配置文件,它使用了include指令引入的其它位置的配置文件。
也就是配置文件有 /etc/nginx/nginx.conf 和 /etc/nginx/conf.d/*.conf
nginx.conf:
user nginx; worker_processes 1; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { 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; }
配置文件结构
配置文件结构,三大部分:
- 主配置块:从开始到even块之间的内容
- even块:主要影响Nginx服务器与用户的网络链接
- http块:
- http全局块
- upstream块
- server块
- 全局server块
- location块
main block # 主配置段,即全局配置,对http/mail都有效 events { worker_connections 1024; } http { upstream ifacesuportservice_dyexp { } gzip on; server { listen 80; server_name localhost; location /webstatic { gzip off; } } server { listen 81; server_name www.baidu.com; location /webstatic { } } } mail { } stream { }
指令块由一个块配置项名和一对大括号组成。经常使用的有http、server、upstream、location。
配置语法
- 配置文件由指令和指令块构成
- 每条指令以
;
结尾,指令与参数之间以空格分隔 - 指令块以{}大括号将多条指令组织在一块儿
- include语句容许组合多个配置文件,以提升能够维护性
- 使用#符号添加注释,提升可读性
- 使用$符号使用变量
- 部分指令的参数支持正则表达式
参数单位
-
时间
- ms,milliseconds
- s,seconds
- m,minutes
- h,hours
- d,days
- w,weeks
- M,months,30d ays
- y,years,365 days
-
空间
- 不写单位,bytes
- k/K,kilobytes
- m/M,megabytes
- g/G,gigabytes
配置变量
- 内建变量,由nginx模块提供,可直接引用,官网:http://nginx.org/en/docs/varindex.html
- 自定义变量,用户使用set命令定义,
set variable_name value
- 引用变量,
$variable_name
全局配置
1)性能优化相关配置
- worker_processes number | auto,worker进程数量,一般为主机的物理核数
- worker_cpu_affinity
- worker_priority
- worker_rlimit_nofile
2)events事件驱动相关配置
events { worker_connections 1024; accept_mutex on | off; }
accept_mutex on | off 互斥,处理新的链接请求
- on指由各个worker轮流处理新请求
- off指每一个新请求的到达都会通知(唤醒)全部进程,但只有一个进程可得到链接,形成“惊群”,影响性能
3)调试和定位问题
daemon on | off;
是否以守护进程运行nginx,默认onmaster_process on | off;
是否以master/worker模型运行nginx,默认onerror_log file [level];
错误日志文件及其级别,出于调试须要,可设定为debug,但debug仅在编译时使用了 --with-debug 选项时才有效,默认:error_log logs/error.log error;
静态资源web服务器
首先,本机nginx环境:
[root@localhost docs]# whereis nginx nginx: /usr/sbin/nginx /usr/lib64/nginx /etc/nginx /usr/share/nginx /usr/share/man/man8/nginx.8.gz
1)将tomcat 9 的 docs 上传到 /usr/share/nginx/tomcat9/
2)配置nginx.conf
最简单的配置
server { listen 8080; server_name localhost; #charset koi8-r; #access_log /var/log/nginx/host.access.log main; location / { #root /usr/share/nginx/html; #index index.html index.htm; alias /usr/share/nginx/tomcat9/docs/; } #error_page 404 /404.html; # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } }
作了两点修改:
- 监听8080端口
- 在 location / 块 使用了 alias,而没有使用 root
在http块中,开启 gzip,这里的数字仅用于测试,压缩后文件小了不少:
gzip on; gzip_min_length 1; gzip_comp_level 2; gzip_types text/plain application/xml;
参考官方:http://nginx.org/en/docs/http/ngx_http_gzip_module.html
参考博客:http://www.javashuo.com/article/p-dgsfkyol-ka.html
关于日志
日志配置所在的块结构内的日志都会记录在相应的目录
如上面 server 块内的 access_log /var/log/nginx/host.access.log main
会记录全部请求8080端口的日志
配置多台虚拟主机
在nginx.conf的http块下配置多个server块就是多个虚拟主机
server块要配置不一样的server_name以表示主机名,而后须要在hosts文件中作ip与主机之间的映射
http { upstream ifacesuportservice_dyexp { } server { listen 80; server_name localhost; location /webstatic { gzip off; } } server { listen 81; server_name www.baidu.com; location /webstatic { } } }
日志
1)在http块中定义日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"';
2)在各个块(http、server)中引用日志格式,并指定日志位置、日志文件名称
access_log /var/log/nginx/access.log main;
日志配置所在的块结构内的日志都会记录在相应的目录,也就是各个块的日志能够分开记录
日志切分——实现一个定时任务处理nginx日志
1)编写一个shell脚本log.sh
,定义如何切分(备份)日志
#!/bin/sh BASE_DIR=/usr/local/nginx BASE_FILE_NAME=bhz.com.access.log CURRENT_PATH=$BASE_DIR/logs BAK_PATH=$BASE_DIR/datalogs CURRENT_FILE=$CURRENT_PATH/$BASE_FILE_NAME BAK_TIME=`/bin/date -d yesterday +%Y%m%d%H%M` BAK_FILE=$BAK_PATH/$BAK_TIME-$BASE_FILE_NAME echo $BAK_FILE $BASE_DIR/sbin/nginx -s stop mv $CURRENT_FILE $BAK_FILE $BASE_DIR/sbin/nginx
2)实现定时任务
crontab -e
添加内容以下:
*/1 * * * * * sh /usr/local/nginx/sbin/log.sh
记得修改成本身的文件路径
location块
语法:
Syntax: location [ = | ~ | ~* | ^~ ] uri { ... } location @name { ... } Default: — Context: server, location
官方文档:http://nginx.org/en/docs/http/ngx_http_core_module.html#location
- location = pattern {} 精准匹配
- location ~ pattern {} 正则匹配,大小写敏感
- location ~* pattern {} 正则匹配,大小写不敏感
- location ^~ /path/path {} 不检查正则表达式
location = /50x.html { root /usr/share/nginx/html; }
题外话:能够安装一个【正则表达式终端测试工具】来测试正则表达式:
# yum install -y pcre-tools
如何使用?
- re:输入正则表达式,//表示开头和结束
- data:测试的数据
[root@localhost ~]# pcretest PCRE version 8.32 2012-11-30 re> /(\d+)\.(\d+)\.(\d+)\.(\d+)/ data> 192.168.12.133 0: 192.168.12.133 1: 192 2: 168 3: 12 4: 133
rewrite的写法
官方文档:http://nginx.org/en/docs/http/ngx_http_rewrite_module.html
Syntax: rewrite regex replacement [flag]; Default: — Context: server, location, if
flag有
- last 本条规则匹配完成后继续向下匹配新的location URI规则
- break 本条规则匹配完成后终止,不在匹配任何规则
- redirect 返回302临时重定向,地址栏改变
- permanent 返回301永久重定向,地址栏改变
参考:https://www.cnblogs.com/brianzhu/p/8624703.html
last与break区别:
总结:
- last,匹配到路径后,会按照新的路径请求一次nginx
- break,匹配到路径后,不会按照新的路径请求一次nginx,而是会去root目录寻找文件;若是在location中,则用break,则不是last。