nginx
1:nginx简介
nginx是一款轻量级的web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器, nginx的特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好
2:nginx的特性
nginx是一个高性能Web和反向代理服务器,它具有很多非常优越的特性:
- 在高连接并发的情况下,nginx是Apache服务器不错的替代品,能够支持高达50000个并发连接数的响应
- 使用epoll and kqueue作为开发模型
- nginx作为负载均衡服务器:nginx既可在内部直接支持和PHP程序对外进行服务,也可支持作为HTTP代理服务器对外进行服务
- nginx采用C进行编写,不论系统资源开销还是CPU使用效率都比Perlbal要好很多
3:nginx的优点
- 高并发连接:官方测试能够支撑5万并发连接,在实际生产环境中跑到2-3万并发连接数
- 内存消耗少:在3万并发连接下,开启的10个nginx进程才消耗150M内存(15M*10=150M)
- 配置文件非常简单:风格跟程序一样通俗易懂
- 成本低廉:nginx为开源软件,可以免费使用。而购买F5 BIG-IP、NetScaler等硬件负载均衡交换机则需要十多万至几十万人民币
- 支持Rewrite重写规则:能够根据域名、URL的不同,将HTTP请求分到不同的后端服务器群组
- 内置的健康检查功能:如果Nginx Proxy后端的某台Web服务器宕机了,不会影响前端访问
- 节省带宽:支持GZIP压缩,可以添加浏览器本地缓存的Header头
- 稳定性高:用于反向代理,宕机的概率微乎其微
- 模块化设计:模块可以动态编译
- 外围支持好:文档全,二次开发和模块较多
- 支持热部署:可以不停机重载配置文件
- 支持事件驱动、AIO(AsyncIO,异步IO)、mmap(Memory Map,内存映射)等性能优化
4:基本功能和扩展功能
- 静态资源的web服务器,能缓存打开的文件描述符
- http、smtp、pop3协议的反向代理服务器
- 缓存加速、负载均衡
- 支持FastCGI(fpm,LNMP),uWSGI(Python)等
- 模块化(非DSO机制),过滤器zip、SSI及图像的大小调整
- 支持SSL(https)
扩展功能:
- 基于名称和IP的虚拟主机
- 支持keepalive(长连接)
- 支持平滑升级
- 定制访问日志、支持使用日志缓冲区提高日志存储性能
- 支持URL重写
- 支持路径别名
- 支持基于IP及用户的访问控制
- 支持速率限制,支持并发数限制
5:nginx应用类别
- 使用nginx结合FastCGI运行PHP(lamp)、JSP(lamt)、Perl(lamp)等程序
- 使用nginx作反向代理、负载均衡、规则过滤
- 使用nginx运行静态HTML网页、图片
- nginx与其他新技术的结合应用
正向代理、反向代理、透明代理
1: 正向代理需要客户端配置代理服务器地址,客户端先访问代理服务器,代理服务器再请求目标的资源。如一些翻墙的代理。
2:反向代理则被设置在服务端,客户端无需设置。用于接受因特网上的连接请求再转给内网的服务器。
3:透明代理只能设置在网关上,用户访问因特网的数据报必然通过网关,透明代理可看成特殊的正向代理。
6:nginx的模块与工作原理
nginx是由内核和模块组成。其中,内核的设计非常微小简洁,完成的工作也非常简单,仅仅是通过查找配置文件将客户端请求映射到一个 location block(定位块)(location是nginx配置中的一个指令,用于URL匹配),而在这个localtion中所配置的每个指令将会启动不同的模块去完成相应的工作。
nginx模块的分类:
nginx的模块从结构上分为核心模块、基础模块和第三方模块
- HTTP模块、EVENT模块和第三方模块
- HTTP Access模块、HTTP FastGGI模块、HTTP Pproxy模块和HTTP Rewrite模块属于基础模块
- HTTP Upstream模块、Request Hash模块、Notice模块和HTTP Access Key模块属于第三方模块
只要是用户根据自己的需要开发的模块都属于是第三方模块。正式有了如此多模块的支撑。nginx的功能才会如此强大
nginx模块从功能上分为三类,分别是:
- Handlers(处理器模块)。此类模块直接处理请求,并进行输出内容和修改headers信息等操作。handlers处理器模块一般只能有一个
- Filters(过滤器模块)。此类模块主要对其他处理器模块输出的内容进行修改操作,最后由nginx输出
- Proxies(代理器模块)。就是nginx的HTTP Upstream之类的模块,这些模块主要与后端一些服务比如fastcgi等操作交互,实现服务代理和负载均衡等功能
nginx模块分为:核心模块、事件模块、标准Http模块、可选Http模块、邮件模块、第三方模块和补丁等
- nginx基本模块:所谓基本模块,指的是nginx默认的功能模块,它们提供的指令,允许你使用定义nginx基本功能的变量,在编译时不能被禁用,包括:
- 核心模块:基本功能和指令,如进程管理和安全。常见的核心模块指令,大部分是放置在配置文件的顶部
- 事件模块:在Nginx内配置网络使用的能力。常见的events(事件)模块指令,大部分是放置在配置文件的顶部
- 配置模块:提供包含机制
7:nginx工作原理
nginx的模块直接被编译进nginx,因此属于静态编译方式。 启动nginx后,nginx的模块被自动加载,与apache不一样,首先将模块编译为一个so文件,然后在配置文件中指定是否进行加载。在解析配置文件时,nginx的每个模块都有可能去处理某个请求,但是同一个处理请求只能由一个模块来完成。
nginx进程架构
Nginx在启动后,会启动master(主)进程和多个worker进程。master进程主要用来管理worker进程,包含:接收来自外界的信号,向各worker进程发送信号,监控worker进程的运行状态,当worker进程退出后(异常情况下),会自动重新启动新的worker进程。而基本的网络事件,则是放在worker进程中来处理。多个worker进程之间是对等的,他们同等竞争来自客户端的请求,各进程互相之间是独立的。一个请求,只可能在一个worker进程中处理,一个worker进程,不可能处理其它进程的请求。worker进程的个数是可以设置的,一般我们会设置与机器cpu核数一致,这里面的原因与nginx的进程模型以及事件处理模型是分不开的。nginx的进程模型,可以由下图来表示:
master进程会接收来自外界发来的信号,再根据信号做不同的事情。所以我们要控制nginx,只需要向master进程发送信号就行了。
8:nginx安装与配置
#:创建系统用户nginx
[root@localhost ~]# useradd -r -M -s /sbin/nologin nginx
#:安装依赖环境
[root@localhost ~]# yum -y install pcre-devel openssl openssl-devel gd-devel gcc gcc-c++
安装过程略....
[root@localhost ~]# yum -y groups mark install 'Development Tools'
Loaded plugins: product-id, search-disabled-repos, subscription-manager
This system is not registered with an entitlement server. You can use subscription-manager to register.
There is no installed groups file.
Maybe run: yum groups mark convert (see man yum)
Marked install: Development Tools
#:创建日志存放目录
[root@localhost ~]# mkdir -p /var/log/nginx
[root@localhost ~]# chown -R nginx.nginx /var/log/nginx
#:下载nginx
[root@localhost ~]# cd /usr/src/
[root@localhost src]# wget http:#:nginx.org/download/nginx-1.22.1.tar.gz
#:编译安装
[root@localhost src]# ls
anaconda-ks.cfg nginx-1.12.0.tar.gz
[root@localhost src]# tar xf nginx-1.22.1.tar.gz
[root@localhost src]# cd nginx-1.22.1
[root@localhost nginx-1.22.1]# ./configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-debug \
--with-http_ssl_module \
--with-http_realip_module \
--with-http_image_filter_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_stub_status_module \
--http-log-path=/var/log/nginx/access.log \
--error-log-path=/var/log/nginx/error.log
[root@localhost nginx-1.22.1]# make -j $(grep 'processor' /proc/cpuinfo | wc -l) && make install
安装过程略....
安装后的配置
#:配置环境变量
[root@localhost ~]# echo 'export PATH=/usr/local/nginx/sbin:$PATH' > /etc/profile.d/nginx.sh
[root@localhost ~]# . /etc/profile.d/nginx.sh
#:服务控制方式,使用nginx命令
-t #:检查配置文件语法
-v #:输出nginx的版本
-c #:指定配置文件的路径
nginx -t -c <配置文件名> #:检查指定配置文件的语法
-s #:发送服务控制信号,可选值有{stop(暂停)|quit(退出)|reopen(重启)|reload(重载)}
#:启动nginx
[root@localhost ~]# nginx
[root@localhost ~]# ss -antl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 0.0.0.0:80 0.0.0.0:*
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 [::]:22 [::]:*
LISTEN 0 80 *:3306 *:*
9: mginx配置文件详解
nginx主配置文件: /usr/local/nginx/conf/nginx.conf
- 默认启动nginx时,使用的配置文件是主配置文件 (或安装路径/conf/nginx.conf文件)
- 想要使用其他配置文件启动nginx时可以通过-c选项指定要读取的配置文件
nginx常见的配置文件及其作用
配置文件 | 作用 |
---|---|
nginx.conf | nginx的基本配置文件 |
mime.type | MIME类型关联的扩展文件 |
fastcgi.conf | 与fastcgi相关的配置 |
proxy.conf | 与proxy相关的配置 |
sites.conf | 配置nginx提供的网站,包括虚拟主机 |
主配置文件nginx.conf配置
nginx.conf的内容主要分为
- main配置段:全局配置段。其中main配置段中可能包含event配置段
- event{} 段:定义event模型工作特性
- http{}段:定义http协议相关的配置
配置指令格式以分号(;)结尾,语法格式如下
error_log logs/error.log;
10:main段配置
用于调试、定位问题的配置参数
daemon {on|off}; #:是否以守护进程方式运行nginx,调试时应设置为off
master_process {on|off}; #:是否以master/worker模型来运行nginx,调试时可以设置为off
error_log 位置 级别; #:配置错误日志
正常运行需要配置的参数
user USERNAME [GROUPNAME]; #:指定运行worker进程的用户和组
pid /path/to/pid_file; #:指定nginx守护进程的pid文件
worker_rlimit_nofile number; #:设置所有worker进程最大可以打开的文件数,默认为1024
worker_rlimit_core size; #:指明所有worker进程所能够使用的总体的最大核心文件大小,保持默认即可
性能优化相关参数
worker_processes n; #:启动n个worker进程,这里的n为了避免上下文切换,通常设置为cpu总核心数-1或等于总核心数
worker_cpu_affinity cpumask ...; #:将进程绑定到某cpu中,避免频繁刷新缓存
#:cpumask:使用8位二进制表示cpu核心,如:
0000 0001 #:第一颗cpu核心
0000 0010 #:第二颗cpu核心
0000 0100 #:第三颗cpu核心
0000 1000 #:第四颗cpu核心
0001 0000 #:第五颗cpu核心
0010 0000 #:第六颗cpu核心
0100 0000 #:第七颗cpu核心
1000 0000 #:第八颗cpu核心
timer_resolution interval; #:计时器解析度。降低此值,可减少gettimeofday()系统调用的次数
worker_priority <number>; #:指明worker进程的nice值
11:event{}段配置
事件相关配置
accept_mutex {off|on}; #:master调度用户请求至各worker进程时使用的负载均衡锁;on表示能让多个worker轮流地、序列化地去响应新请求
lock_file <file>; #:accept_mutex用到的互斥锁锁文件路径 在main段配置,默认在logs下nginx.lock文件,默认未配置
use [epoll | rtsig | select | poll]; #:指明使用的事件模型,建议让nginx自行选择,可不用配置
worker_connections <此处值乘以核心数小于或稍大于3万>; #:每个进程能够接受的最大连接数
网络相关
keepalive_timeout <number>; #:长连接的超时时长,默认为65s
keepalive_requests <number>; #:在一个长连接上所能够允许请求的最大资源数
keepalive_disable [msie6(IE6)|safari(火狐)|none()]; #:为指定类型的UserAgent(浏览器)禁用长连接
tcp_nodelay on|off; #:是否对长连接使用TCP_NODELAY选项,为了提升用户体验,通常设为on
client_header_timeout <number>; #:读取http请求报文首部的超时时长
client_body_timeout <number>; #:读取http请求报文body部分的超时时长
send_timeout <number>; #:发送响应报文的超时时长
服务相关配置
nginx启用fpm模型
location ~ \.php$ {
root html;
fastcgi_pass 127.0.0.1:9000; #:定义反向代理
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name(更换为$document_root);
include fastcgi_params;
}
12:http段配置
nginx作为web服务器时使用的配置,由ngx_http_core_module模块引入。
http {#:协议级别
include mime.types;
default_type application/octet-stream;
keepalive_timeout 65;
gzip on; #:包传输是否压缩,默认关闭
upstream {#:负载均衡配置
...
}
server {#:服务器级别,每个server类似于httpd中的一个虚拟主机
listen 80;
server_name localhost;
location / {#:请求级别,类似于httpd中的<Location>,用于定义URL与本地文件系统的映射关系
root html;
index index.html index.htm;
}
}
}
定义一个虚拟主机
server {
listen 80;
或listen <ip地址>:<端口>
server_name www.idfsoft.com;
root "/vhosts/web";
}
server_name NAME [...];
后面可跟多个主机,名称可使用正则表达式或通配符
当有多个server时,匹配顺序如下:
- 先做精确匹配检查
- 左侧通配符匹配检查,如
*.idfsoft.com
- 右侧通配符匹配检查,如
mail.*
- 正则表达式匹配检查,如
~ ^.*\.idfsoft\.com$
- default_server (默认首页)
root path;
设置资源路径映射,用于指明请求的URL所对应的资源所在的文件系统上的起始路径,path
为安装路径下的html目录
alias path;
用于location配置段,定义网站路径别名 path
为资源绝对路径,;例: /opt/test/data/
404页面
#:当网站访问不存在时,可以通过访问404页面
#:默认存放位置是安装路径下的html目录
#error_page 404 /404.html;
log_format定义日志格式
log_format <标签名> '$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 <标签名>;
#:注意:此处可用变量为nginx各模块内建变量
访问控制
#:allow 设定允许访问的主机,多个参数用空格隔开 all允许所有
allow 192.168.1.1/32 172.16.0.0/16;
#:deny 设定禁止访问主句,设置方法同allow all拒绝所有
deny all;
基于用户认证
location /test {
auth_basic "欢迎信息";
auth_basic_user_file "密码文件存放位置"
root html;
index index.html;
}
#:生成密码文件
#:安装httpd-tools包
htpasswd -c -m <密码文件存放路径> <用户名>【弹出对话输入密码】
https配置
server {
listen 443 ssl;
server_name www.idfsoft.com;
ssl_certificate <srt文件存放位置>;
ssl_certificate_key <key文件存放路径>;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
root html;
index index.html index.htm;
}
}
13:开启status状态页面
#:将配置文件中以下行取消注释
location /status {
stub_status {on | off}(开启|关闭);
}
#:搭配访问控制可以实现拒绝无关人员访问
#:访问状态页 http://<主机ip>/status
浏览器访问
状态页信息详解
状态码 | 含义 |
---|---|
Active connections | 当前所有处于打开状态的连接数 |
accepts | 总共处理的多少次连接 |
handled | 成功创建多少次握手 |
requests | 总共处理了多少个请求 |
Reading | nginx读取到客户端的Header信息数,表示正处于接收请求状态的连接数 |
Writing | nginx返回给客户端的Header信息数,表示请求已经接收完成,且正处于处理请求或发送响应的过程中的连接数 |
Waiting | 开启keep-alive的情况下,这个值等于active - (reading + writing),意思就是Nginx已处理完正在等候下一次请求指令的驻留连接 |
14:nginx平滑升级
#1:获取老版本的编译信息
使用nginx -V 查看老版本编译参数
[root@localhost ~]# nginx -V
nginx version: nginx/1.22.1
built by gcc 8.5.0 20210514 (Red Hat 8.5.0-4) (GCC)
built with OpenSSL 1.1.1k FIPS 25 Mar 2021
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-debug --with-http_ssl_module --with-http_realip_module --with-http_image_filter_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_stub_status_module --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log
2:备份老版本
3:编译新版本或新功能(不能执行make install)
[root@localhost nginx-1.24.0]# ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-debug --with-http_ssl_module --with-http_realip_module --with-http_image_filter_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_stub_status_module --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --add-module=../echo-nginx-module-master
[root@localhost nginx-1.24.0]# make
#:禁止执行make install
4:手动替换新版本并重启服务
[root@localhost nginx-1.24.0]# cp /usr/local/nginx/sbin/nginx /opt/nginx.old
将老版本服务停止,将编译好的新版本复制到老版本安装位置,将服务重启
[root@localhost nginx-1.24.0]# /usr/local/nginx/sbin/nginx -s stop;\cp -f objs/nginx /usr/local/nginx/sbin/nginx;nginx
5:验证编译
[root@localhost nginx-1.24.0]# nginx -v
nginx version: nginx/1.24.0
rewrite (URL重定向)
语法: rewrite regex replacement flag;
rewrite <正则表达式匹配规则|域名> <替换路径或地址> <终止标志>(last|break)
常见的终止标识
终止标识 | 作用 |
---|---|
last | 基本上都用这个flag,表示当前的匹配结束,继续下一个匹配,最多匹配10个到20个一旦此rewrite规则重写完成后,就不再被后面其它的rewrite规则进行处理而是由UserAgent重新对重写后的URL再一次发起请求,并从头开始执行类似的过程 |
break | 中止Rewrite,不再继续匹配一旦此rewrite规则重写完成后,由UserAgent对新的URL重新发起请求,且不再会被当前location内的任何rewrite规则所检查 |
redirect | 以临时重定向的HTTP状态302返回新的URL |
permanent | 以永久重定向的HTTP状态301返回新的URL |
rewrite模块的作用是用来执行URL重定向。这个机制有利于去掉恶意访问的url利于搜索引擎优化
nginx语法支持的正则表达式
标识符 | 含义 |
---|---|
^ | 匹配必须以某串字符开头 |
$ | 匹配必须以某串字符结尾 |
. | 匹配任意字符 |
[] | 匹配指定字符集内的任意字符 |
[^] | 匹配任何不包括在指定字符集内的任意字符 |
| | 匹配 | 之前或之后的字符 |
() | 分组,组成一组用于匹配的字符串,通常与 | 搭配使用 |
~ | 区分大小写的模式匹配检查 |
~* | 不区分大小写的匹配模式检查 |
结合if语句实现浏览器访问分离
# 火狐浏览器
if ($http_user_agent ~ Firefox) {
rewrite ^(.*)$ /firefox/$1 break;
}
#:IE浏览器
if ($http_user_agent ~ MSIE) {
rewrite ^(.*)$ /msie/$1 break;
}
# 谷歌浏览器
if ($http_user_agent ~ Chrome) {
rewrite ^(.*)$ /chrome/$1 break;
}
防盗链
#:匹配图片格式的访问后缀,将流量转发至403页面
location ~* \.(jpg|gif|jpeg|png)$ {
valid_referers none blocked www.idfsoft.com;
if ($invalid_referer) {
rewrite ^/ http://www.idfsoft.com/403.html;
}
}
15:反向代理与负载均衡
nginx 通常被用作后端服务器的反向代理,这样就可以很方便的实现动静分离以及负载均衡,从而大大提高服务器的处理能力。
nginx实现动静分离,其实就是在反向代理的时候,如果是静态资源,就直接从nginx发布的路径去读取,而不需要从后台服务器获取了。
但是要注意,这种情况下需要保证后端跟前端的程序保持一致,可以使用Rsync做服务端自动同步或者使用NFS、MFS分布式共享存储。
Http Proxy模块、功能很多,但是最常用的是proxy_pass和proxy_cache
如果要使用proxy_cache,需要集成第三方的ngx_cache_purge模块,用来清除指定的URL缓存。这个集成需要在安装nginx的时候添加新模块,如:
./configure --add-module=…/ngx_cache_purge-1.0 …
nginx
通过upstream
模块来实现简单的负载均衡,upstream
需要定义在http
段内
在upstream
段内,定义一个服务器列表,默认的方式是轮询,如果要确定同一个访问者发出的请求总是由同一个后端服务器来处理,可以设置ip_hash,
配置: 参照
#: 在server 段上方同级的地方写入:
upstream dynamic(此处名称可随意) {
ip_hash;
server <动态服务器ip>:<端口号> weight=2
}
upstream static {
server <静态服务器ip>:<端口号> weight=2
}
#:将下面内容取消注释并更改
location ~ \.php$ {
proxy_pass http://dynamic; #:此处名称与上方随意填名称对应
}
nx通过
upstream模块来实现简单的负载均衡,
upstream需要定义在
http`段内
在upstream
段内,定义一个服务器列表,默认的方式是轮询,如果要确定同一个访问者发出的请求总是由同一个后端服务器来处理,可以设置ip_hash,
配置: 参照
#: 在server 段上方同级的地方写入:
upstream dynamic(此处名称可随意) {
ip_hash;
server <动态服务器ip>:<端口号> weight=2
}
upstream static {
server <静态服务器ip>:<端口号> weight=2
}
#:将下面内容取消注释并更改
location ~ \.php$ {
proxy_pass http://dynamic; #:此处名称与上方随意填名称对应
}