nginx
简介
nginx是一款轻量级的web服务器/反向代理服务器/电子邮件(IMAP,POP3)代理服务器,并在一个BSD-like协议下发行。
nginx的特点是内存占用少,并发能力强。,在同类网页服务器中表现比较好。
特性与优点
特性
- 能支持最高50000个并发连接数的响应
- nginx作为负载均衡服务器,既可以作为http服务器对外服务,也可内部直接支持php程序对外服务(反向代理)
- nginx采用c编写,系统资源开销或cpu使用效率都高于perlbal( Perl 编写的单线程的事件驱动服务器,可充当 Web 服务器 和 HTTP 负载均衡)
优点
- 高并发连接,最多支持5万并发,生产环境能到2~3万并发连接数
- 内存消耗少,3万并发连接下,10个nginx进程占用150M内存
- 配置文件通俗易懂(相对)
- 成本低廉(开源软件)
- 支持rewrite重写规则,根据域名,统一资源定位器URL,将http请求分发到不同后端服务器群组。
- 内置健康检测,不会因为单个web服务器宕机影响前端访问
- 节省带宽,可以添加浏览器本地缓存
- 模块化设计,支持动态编译。
- 外围支持好:模块和二次开发多
- 支持热部署: 不停机重载配置文件
- 支持事件驱动,AIO(AsyncIO,异步IO)、mmap(Memory Map,内存映射)等性能优化
nginx功能
基本功能
-
静态资源的web服务器
-
http,smtp,pop3协议的反向代理服务器
-
缓存加速,负载均衡(负载均衡离不开反向代理,二者相互依存)
-
支持FastCGI(fpm,LNMP),uWSGI(python)等
-
模块化
-
支持SSL(证书https等)
扩展功能
-
基于名称和IP的虚拟主机
-
支持keepalive(长连接,不是高可用!)
-
支持平滑升级
-
定制访问日志、支持使用日志缓冲区提高日志存储性能
-
支持URL重写
-
支持路径别名
-
支持基于IP及用户的访问控制
-
支持速率限制,支持并发数限制
应用类别
-
使用nginx结合FastCGI运行PHP、JSP、Perl等程序
-
使用nginx作反向代理、负载均衡、规则过滤
-
使用nginx运行静态HTML网页、图片
-
nginx与其他新技术的结合应用
nginx模块与工作原理
nginx
由内核和模块组成。其中,内核的设计非常微小和简洁,完成的工作也非常简单,仅仅通过查找配置文件将客户端请求映射到一个location block(location是nginx配置中的一个指令,用于URL匹配),而在这个location中所配置的每个指令将会启动不同的模块去完成相应的工作。
模块分类
nginx的模块从结构上分为:
核心模块
- HTTP模块
- EVENT模块
- MAIL模块
基础模块
- HTTP Access模块
- HTTP FastCGI模块
- HTTP Proxy模块
- HTTP Rewrite模块
第三方模块
- HTTP Upstream模块
- Request Hash模块
- Notice模块
- HTTP Access Key模块
nginx模块从功能上分类,分为三类:
- Handlers(处理器模块)。此类模块直接处理请求,并进行输出内容和修改headers信息等操作。handlers处理器模块一般只能有一个
- Filters(过滤器模块)。此类模块主要对其他处理器模块输出的内容进行修改操作,最后由nginx输出
- Proxies(代理器模块)。就是nginx的HTTP Upstream之类的模块,这些模块主要与后端一些服务比如fastcgi等操作交互,实现服务代理和负载均衡等功能
nginx模块分为:核心模块、事件模块、标准Http模块、可选Http模块、邮件模块、第三方模块和补丁等
- nginx基本模块:所谓基本模块,指的是nginx默认的功能模块,它们提供的指令,允许你使用定义nginx基本功能的变量,在编译时不能被禁用,包括:
- 核心模块:基本功能和指令,如进程管理和安全。常见的核心模块指令,大部分是放置在配置文件的顶部(配置文件行的最左)
- 事件模块:在Nginx内配置网络使用的能力。常见的events(事件)模块指令,大部分是放置在配置文件的顶部
- 配置模块:提供包含机制(include)
工作原理
nginx模块被直接编译进nginx,属于静态编译方式。
启动时将模块编译为一个so文件,然后在配置文件中决定是否加载模块。
nginx启动,产生一个master进程,该进程不处理任何客户端请求,而是用来产生worker线程。worker线程用来处理多个request(请求)
基本的WEB服务请求步骤:
nginx安装与配置
安装(源码)
//防火墙selinux关闭
systemctl stop firewalld.service
setenforce 0
//创建nginx用户
[root@node1 ~]# useradd -r -M -s /sbin/nologin nginx
//安装开发工具组和依赖包
[root@node1 ~]# yum -y install pcre-devel openssl openssl-devel gd-devel gcc gcc-c++ make
[root@node1 ~]# yum -y groups mark install 'development tools'
//创建日志存放目录
[root@node1 ~]# mkdir -p /var/log/nginx
[root@node1 ~]# chown -R nginx.nginx /var/log/nginx
//下载源码包
[root@node1 ~]# cd /usr/src/
[root@node1 src]# wget http://nginx.org/download/nginx-1.20.0.tar.gz
[root@node1 src]# ll
...
-rw-r--r--. 1 root root 1061070 Apr 20 22:46 nginx-1.20.0.tar.gz
//解压
[root@node1 src]# tar xf nginx-1.20.0.tar.gz
[root@node1 src]# cd nginx-1.20.0/
//编译安装
[root@node1 nginx-1.20.0]# ./configure \
> --prefix=/usr/local/nginx \ #指定路径
> --user=nginx \ #指定用户
> --group=nginx \ #指定组
> --with-debug \ #启用debug测试
> --with-http_ssl_module \ #启用ssl证书模块
> --with-http_realip_module \ #启用http真实ip模块
> --with-http_image_filter_module \ #启用http图像过滤器模块
> --with-http_gunzip_module \ #启用http压缩模块
> --with-http_gzip_static_module \ #启用静态压缩
> --with-http_stub_status_module \ #启用状态页面
> --http-log-path=/var/log/nginx/access.log \ #指定日http访问日志路径
> --error-log-path=/var/log/nginx/error.log #指定报错日志路径
//启用多核心加速安装
[root@node1 nginx-1.20.0]# make -j $(grep 'processor' /proc/cpuinfo | wc -l) && make install
配置
配置文件详解
默认是“nginx安装路径/conf/nginx.conf'
配置文件 | 作用 |
---|---|
nginx.conf | nginx的基本配置文件 |
mime.types | MIME类型关联的扩展文件 |
fastcgi.conf | 与fastcgi相关的配置 |
proxy.conf | 与proxy相关的配置 |
sites.conf | 配置nginx提供的网站,包括虚拟主机 |
//添加环境变量
[root@node1 nginx-1.20.0]# echo 'export PATH=/usr/local/nginx/sbin:$PATH' > /etc/profile.d/nginx.sh
[root@node1 nginx-1.20.0]# source /etc/profile.d/nginx.sh
[root@node1 nginx-1.20.0]# which nginx
/usr/local/nginx/sbin/nginx
//语法
[root@node1 nginx-1.20.0]# nginx -help
nginx version: nginx/1.20.0
Usage: nginx [-?hvVtTq] [-s signal] [-p prefix]
[-e filename] [-c filename] [-g directives]
Options:
-?,-h : this help #帮助信息
-v : show version and exit #显示版本
-V : show version and configure options then exit #显示版本和配置选项
-t : test configuration and exit #测试配置并退出
-T : test configuration, dump it and exit #测试配置
-q : suppress non-error messages during configuration testing #配置测试期间只输出错误信息
-s signal : send signal to a master process: stop, quit, reopen, reload #传递控制信号给主进程
-p prefix : set prefix path (default: /usr/local/nginx/) #设置路径
-e filename : set error log file (default: /var/log/nginx/error.log) #设置错误日志路径
-c filename : set configuration file (default: conf/nginx.conf) #设置配置文件路径
-g directives : set global directives out of configuration file #从配置文件中设置全局指令
//启动测试
[root@node1 nginx-1.20.0]# nginx
[root@node1 nginx-1.20.0]# 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 [::]:*
nginx.conf配置文件详解
- main配置段:全局配置段。其中main配置段中可能包含event配置段
- event {}:定义event模型工作特性
- http {}:定义http协议相关的配置
语法格式:
derective value1 [value2 ...];
设置变量:
set VAR_NAME value
用于调试,定位问题的配置
daemon on|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 NUM; #指定每个worker进程最大可以打开的文件数(默认1024,最大65535)kvm设置过。
worker_rlimit_core NUM; #设置给worker进程的最大核心数(推荐为总核心数-1)
性能优化的配置参数
timer_resolution interval; #单位ms计时器解析度。降低此值,可减少gettimeofday()系统调用的次数
worker_priority number; #指明worker进程的nice值(-20~20)
worker_processes n; #启动n个worker进程,为了避免上下文切换,通常设置为cpu总核心数-1或等于总核心数
worker_cpu_affinity cpumask ...; #将进程绑定到指定cpu避免频繁刷新内存用二进制表示绑定cpu 0001 0010 0100 1000
事件相关配置
accept_mutex {off|on}; #master调度用户请求至各worker进程时使用的负载均衡锁;on表示能让多个worker轮流地、序列化地去响应新请求
lock_file file; #accept_mutex用到的互斥锁锁文件路径,二者一般绑定出现
use [epoll | rtsig | select | poll]; #指明使用的事件模型,建议让nginx自行选择
worker_connections #每个进程能够接受的最大连接数
网络相关配置参数
keepalive_timeout number; #长连接的超时时长,默认为65(s)
keepalive_requests number; #在一个长连接上所能够允许请求的最大资源数
keepalive_disable [msie6|safari|none]; #为指定类型的UserAgent(浏览器类型)禁用长连接
tcp_nodelay on|off; #是否对长连接使用TCP_NODELAY选项,为了提升用户体验,通常设为on
client_header_timeout number; #读取http请求报文首部的超时时长
client_body_timeout number; #读取http请求报文body(文本内容)部分的超时时长
send_timeout number; #发送响应报文的超时时长
长连接:数据传输完成了保持TCP连接不断开(不发RST包、不四次握手),等待在同域名下继续用这个通道传输数据
fastcgi配置参数
lnmp部署时参数修改
#单服务器部署,取消注释即可。分离部署需修改反向代理ip和端口
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;
}
nginx作为web服务器的配置
http {
include 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 logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
https配置
生成私钥后证书签署并获得证书,nginx如下配置
server {
listen 443 ssl;
server_name www.idfsoft.com;
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.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;
}
}
访问控制
针对ip,套接字,无类别域间路由(Classless Inter-Domain Routing、CIDR)的访问控制
allow
Syntax: allow address | CIDR | unix: | all;
Default: —
Context: http, server, location, limit_except
deny
Syntax: deny address | CIDR | unix: | all;
Default: —
Context: http, server, location, limit_except
用户认证
auth_basic "欢迎信息";
auth_basic_user_file "/path/to/user_auth_file"
//用户认证文件内容格式为:
username:password
//建议用htpasswd来创建此文件
htpasswd -c -m /path/to/.user_auth_file USERNAME
开启状态界面
stub_status
Syntax: stub_status;
Default: —
Context: server, location
location /status {
stub_status {on | off}; #自定义状态页面是否开启
allow 172.16.0.0/16; #针对访问控制
deny all;
}
rewrite
通过执行URL重定向,在不改变用户习惯的前提下将资源迁移至新空间。防止恶意访问,替换的可以是路径,也可以是url。
rewrite 正则 替换 flag;
context: location
//匹配"/images/"开头"任意.jpg"结尾的标识符,请求转发到/img/(.*.jpg)内容
rewrite ^/images/(.*\.jpg)$ /imgs/$1 break;
//匹配"/bbs"开头的"/任意结尾的"的临时重定向到新的url"http://www.idfsoft.com/index.html"去
rewrite ^/bbs/(.*)$ http://www.idfsoft.com/index.html redirect;
常见flag
flag | 作用 |
---|---|
last | 表示当前匹配结束,继续下一个匹配,最多匹配10~20。 不再被后面rewrite规则处理,而是对重写后的url再执行一次 |
break | 终止匹配:重写完成后,不会被当前location内的任何rewrite规则所检查 |
redirect | 临时重定向http状态302返回新的url |
permanent | 永久重定向http状态301返回新的url |
nginx使用的语法源于Perl兼容正则表达式(PCRE)库,基本语法如下:
标识符 | 意义 |
---|---|
^ | 必须以^后的实体开头 |
$ | 必须以$前的实体结尾 |
. | 匹配任意字符 |
[] | 匹配指定字符集内的任意字符 |
[^] | 匹配任何不包括在指定字符集内的任意字符串 |
| | 匹配 | 之前或之后的实体 |
() | 分组,组成一组用于匹配的实体,通常会有| 来协助 |
实例:
[root@node1 ~]# cd /usr/local/nginx/html
[root@node1 html]# mkdir images
[root@node1 html]# cd images/
[root@node1 images]# ll
total 452
-rw-r--r--. 1 root root 459622 Jun 1 21:49 moto.jpg
//模拟图片访问路径改变
[root@node1 html]# mkdir newimgs
[root@node1 html]# mv images/moto.jpg newimgs/
//rewrite重写规则
[root@node1 html]# vim ../conf/nginx.conf
location /images {
rewrite ^/images/(.*\.jpg)$ /newimgs/$1 break;
}
[root@node1 html]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@node1 html]# nginx -s reload
再次刷新正常访问
if条件判断
判断条件是否满足,满足则执行规则。
Syntax: if (condition) { ... }
Default: —
Context: server, location
//例子
if ($http_user_agent ~ MSIE) {
rewrite ^(.*)$ /msie/$1 break; #判断浏览器是否是IE,是则重定向到/msie目录下的资源
}
if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
set $id $1;
}
if ($request_method = POST) { #请求方法为POST时,返回状态码405
return 405;
}
if ($slow) {
limit_rate 10k;
}
//防盗链
location ~* \.(jpg|gif|jpeg|png)$ {#不区分大小写的图片资源
valid_referers none blocked www.idfsoft.com;#定义有效链接
if ($invalid_referer) { #判断是否为无效链接
rewrite ^/ http://www.idfsoft.com/403.html;#成立则返回403状态页面
}
}
负载均衡和反向代理
upstream
文档_http_upstream_module (nginx.org)
通过这个模块能实现nginx的负载均衡
Syntax: upstream name { ... }
Default: —
Context: http #与server平级
//用到的参数
server #后端服务器域名(或ip)默认端口80
weight #权重:默认1,权重越大请求越多。
ip hash #用户经常访问的后端服务器绑定
nginx常用负载均衡算法
-
轮询(默认算法):每个请求会依次分配给后端不同的应用程序服务器,不理会后端服务器的实际压力
-
加权轮询:权重越大的服务器,被分配到的次数就会越多,通常用于后端服务器性能不一致的情况
-
IP HASH:当同IP进行重复访问时会被指定到上次访问到的服务器,可以解决动态网站SESSION共享问题
测试
node2,node4安装http,node1安装nignx。
修改2和4的index.html,方便验证
ssystemctl stop firewalld
setenforce 0
[root@node2 ~]# echo node2> /var/www/html/index.html
[root@node4 ~]# echo node4> /var/www/html/index.html
//负载均衡配置
[root@node1 html]# vim ../conf/nginx.conf
...
upstream loadbalance { #定义一个服务器组
server 192.168.94.143:80 ; #node2服务器
server 192.168.94.130:80 ; #node4服务器
}
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
proxy_pass http://loadbalance; #代理转发调用刚刚定义的“loadbalance”
}
[root@node1 html]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@node1 html]# nginx -s reload
//访问测试
[root@node1 html]# curl 192.168.94.141
node4
[root@node1 html]# curl 192.168.94.141
node2