《从菜鸟到大师之路 Nginx 篇》
Nginx 简介
Nginx 是开源
、高性能
、高可靠
的 Web
和反向代理服务器
,而且支持热部署,几乎可以做到 7 * 24 小时不间断运行,即使运行几个月也不需要重新启动,还能在不间断服务的情况下对软件版本进行热更新。性能是 Nginx 最重要的考量,其占用内存少、并发能力强、能支持高达 5w 个并发连接数,最重要的是, Nginx 是免费的并可以商业化,配置使用也比较简单。
官方网站:http://www.nginx.org
Nginx 特点
Web服务器
高性能的WEB服务器软件,与Apache相比,它支持更多的并发连接且占用服务器资源少,效率高
反向代理或负载均衡服务器
作为负载均衡服务器,它可以作为HTTP SERVER或DB等服务的代理服务器,类似Haproxy代理软件的功能,Nginx的代理功能相对简单,效率也不及Haproxy,同时它也是一个优秀的邮件代理服务软件
缓存服务器
Nginx还可以作缓存服务器,类似于专业的缓存软件功能
Nginx 优缺点
Nginx 优点
-
高并发:能支持1-2万甚至更多的并发连接(静态小文件)
-
内存消耗少
-
可以做HTTP反向代理——负载均衡的功能
-
内置对集群节点服务器的健康性查功能,不过功能相对较弱
-
通过cache插件可以实现缓存软件能够实现的功能
Nginx 的缺点
Nginx 仅能支持http、https和Email协议,这样就在适用范围上面小些,这个是它的缺点
对后端服务器的健康检查,只支持通过端口来检测,不支持通过 url来检测。不支持 Session 的直接保持,但能通过 ip_hash 来解决
Nginx 应用场景
Nginx 的最重要的几个使用场景:
-
静态资源服务,通过本地文件系统提供服务;
-
反向代理服务,延伸出包括缓存、负载均衡等;
-
API 服务, OpenResty ;
对于前端来说 Node.js 并不陌生, Nginx 和 Node.js 的很多理念类似, HTTP 服务器、事件驱动、异步非阻塞等,且 Nginx 的大部分功能使用 Node.js 也可以实现,但 Nginx 和 Node.js 并不冲突,都有自己擅长的领域。Nginx 擅长于底层服务器端资源的处理(静态资源处理转发、反向代理,负载均衡等), Node.js 更擅长上层具体业务逻辑的处理,两者可以完美组合。
用一张图表示:
Nginx 到底可以做什么?看完这篇你就懂了!
更多关于Nginx常用场景应用配置可参考:
-
请务必收藏!Nginx 五大常见应用场景
-
彻底搞懂 Nginx 五大应用场景!出去吹牛逼再也不担心了
Apache VS Nginx
Apache和Nginx都属于Web服务器,两者都实现了HTTP 1.1协议。无论是选择哪个,都是根据应用场景来决定的,所以些文件仅从应用场景出发,来对比两者之间的各自特点。要让正确的工具,做出正确的事。
功能对比
Nginx和Apache一样,都是HTTP服务器软件,在功能实现上都采用模块化结构设计,都支持通用的语言接口,如PHP、Perl、Python等,同时还支持正向和反向代理、虚拟主机、URL重写、压缩传输、SSL加密传输等。
-
在功能实现上,Apache的所有模块都支持动、静态编译,而Nginx模块都是静态编译的,
-
对FastCGI的支持,Apache对Fcgi的支持不好,而Nginx对Fcgi的支持非常好;
-
在处理连接方式上,Nginx支持epoll,而Apache却不支持;
-
在空间使用上,Nginx安装包仅仅只有几百K,和Nginx比起来Apache绝对是庞然大物。
Nginx相对apache的优点
-
轻量级,同样起web 服务,比apache 占用更少的内存及资源
-
静态处理,Nginx 静态处理性能比 Apache 高 3倍以上
-
抗并发,nginx 处理请求是异步非阻塞的,而apache则是阻塞型的,在高并发下nginx 能保持低资源低消耗高性能。在- - Apache+PHP(prefork)模式下,如果PHP处理慢或者前端压力很大的情况下,很容易出现Apache进程数飙升,从而拒绝服务的现象。
-
高度模块化的设计,编写模块相对简单
-
社区活跃,各种高性能模块出品迅速啊
apache相对nginx的优点
-
rewrite,比nginx 的rewrite 强大
-
模块超多,基本想到的都可以找到
-
少bug,nginx的bug相对较多
-
超稳定
-
Apache对PHP支持比较简单,Nginx需要配合其他后端用
更多更详细的比较说明请参考:Apache VS Nginx,你选对了吗?
Nginx 安装
本文以CentOS 7.x 系统为例,使用 yum 安装 Nginx。
yum install nginx -y
安装完成后,通过 rpm -ql nginx 命令查看 Nginx 的安装信息。
# Nginx配置文件
/etc/nginx/nginx.conf # nginx 主配置文件
/etc/nginx/nginx.conf.default# 可执行程序文件
/usr/bin/nginx-upgrade
/usr/sbin/nginx# nginx库文件
/usr/lib/systemd/system/nginx.service # 用于配置系统守护进程
/usr/lib64/nginx/modules # Nginx模块目录# 帮助文档
/usr/share/doc/nginx-1.16.1
/usr/share/doc/nginx-1.16.1/CHANGES
/usr/share/doc/nginx-1.16.1/README
/usr/share/doc/nginx-1.16.1/README.dynamic
/usr/share/doc/nginx-1.16.1/UPGRADE-NOTES-1.6-to-1.10# 静态资源目录
/usr/share/nginx/html/404.html
/usr/share/nginx/html/50x.html
/usr/share/nginx/html/index.html# 存放Nginx日志文件
/var/log/nginx
主要关注的文件夹有两个:
-
/etc/nginx/conf.d/是子配置项存放处,/etc/nginx/nginx.conf 主配置文件会默认把这个文件夹中所有子配置项都引入;
-
/usr/share/nginx/html/静态文件都放在这个文件夹,也可以根据你自己的习惯放在其他地方;
Nginx 常用命令
systemctl 系统命令:
# 开机配置
systemctl enable nginx # 开机自动启动
systemctl disable nginx # 关闭开机自动启动# 启动Nginx
systemctl start nginx # 启动Nginx成功后,可以直接访问主机IP,此时会展示Nginx默认页面# 停止Nginx
systemctl stop nginx# 重启Nginx
systemctl restart nginx# 重新加载Nginx
systemctl reload nginx# 查看 Nginx 运行状态
systemctl status nginx# 查看Nginx进程
ps -ef | grep nginx# 杀死Nginx进程
kill -9 pid # 根据上面查看到的Nginx进程号,杀死Nginx进程,-9 表示强制结束进程
Nginx 应用程序命令:
nginx -s reload # 向主进程发送信号,重新加载配置文件,热重启
nginx -s reopen # 重启
nginx -s stop # 快速关闭
nginx -s quit # 等待工作进程处理完成后关闭
nginx -T # 查看当前 Nginx 最终的配置
nginx -t # 检查配置是否有问题
Nginx 配置文件
Nginx 的配置文件结构如下:
# main段配置信息
user nginx; # 运行用户,默认即是nginx,可以不进行设置
worker_processes auto; # Nginx 进程数,一般设置为和 CPU 核数一样
error_log /var/log/nginx/error.log warn; # Nginx 的错误日志存放目录pid /var/run/nginx.pid; # Nginx 服务启动时的 pid 存放位置# events段配置信息
events { use epoll; # 使用epoll的I/O模型(如果你不知道Nginx该使用哪种轮询方法,会自动选择一个最适合你操作系统的)worker_connections 1024; # 每个进程允许最大并发数
}# http段配置信息
# 配置使用最频繁的部分,代理、缓存、日志定义等绝大多数功能和第三方模块的配置都在这里设置
http { # 设置日志模式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; # Nginx访问日志存放位置sendfile on; # 开启高效传输模式tcp_nopush on; # 减少网络报文段的数量tcp_nodelay on; keepalive_timeout 65; # 保持连接的时间,也叫超时时间,单位秒types_hash_max_size 2048; include /etc/nginx/mime.types; # 文件扩展名与类型映射表default_type application/octet-stream; # 默认文件类型include /etc/nginx/conf.d/*.conf; # 加载子配置项# server段配置信息server { listen 80; # 配置监听的端口server_name localhost; # 配置的域名# location段配置信息location / { root /usr/share/nginx/html; # 网站根目录index index.html index.htm; # 默认首页文件deny 172.168.22.11; # 禁止访问的ip地址,可以为allallow 172.168.33.44;# 允许访问的ip地址,可以为all}error_page 500 502 503 504 /50x.html; # 默认50x对应的访问页面error_page 400 404 error.html; # 同上}
}
-
main 全局配置,对全局生效;
-
events 配置影响 Nginx 服务器与用户的网络连接;
-
http 配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置;
-
server 配置虚拟主机的相关参数,一个 http 块中可以有多个 server 块;
-
location 用于配置匹配的 uri ;
-
upstream 配置后端服务器具体地址,负载均衡配置不可或缺的部分;
更多关于Nginx配置文件的介绍可以参考下列文章:
-
史上最全的Nginx配置参数中文说明
-
Nginx 常用配置汇总!从入门到干活足矣
-
Nginx 实践:location 路径匹配
如果你平时配置Nginx比较频繁,我推荐你使用这个神器:强大!Nginx 配置在线一键生成“神器”
Nginx常用的内置变量
Nginx 的进程模型
Nginx 服务器,正常运行过程中:
-
多进程:一个 Master 进程、多个 Worker 进程
-
Master 进程:管理 Worker 进程
-
对外接口:接收外部的操作(信号)
-
对内转发:根据外部的操作的不同,通过信号管理 Worker
-
监控:监控 worker 进程的运行状态,worker 进程异常终止后,自动重启 worker 进程
-
Worker 进程:所有 Worker 进程都是平等的
-
实际处理:网络请求,由 Worker 进程处理;
-
Worker 进程数量:在 nginx.conf 中配置,一般设置为核心数,充分利用 CPU 资源,同时,避免进程数量过多,避免进程竞争 CPU 资源,增加上下文切换的损耗。
为什么Nginx功能如此强大,可以参考:
-
Nginx为什么高效?一文搞明白Nginx核心原理
-
从 Nginx 优秀的核心架构设计,揭秘其为何能支持高并发?
Nginx优化配置
其实核心内容主要是通过修改 Nginx 配置文件来进行调优的!
-
Nginx优化配置详解
-
加速 Nginx 响应的 5 个措施!
在我们的日常工作学习中,我们会该如何去优化自己的Nginx服务器?遇到以下问题我们该如何处理呢?
-
如何自定义返回给客户端的404错误页面
-
如何查看服务器状态信息
-
如何优化Nginx并发量
-
…
这些问题都可以参考这篇文章的解决方案:Nginx 高性能优化配置实战总结
Nginx 是如何实现并发的?为什么 Nginx 不使用多线程?Nginx常见的优化手段有哪些?502错误可能原因有哪些?这种面试问题你肯定是经常被问到。
所以,Nginx 如何实现高并发?常见的优化手段有哪些?
对于Nginx服务器的安全,在日常使用中也是非常重要的,这里给大家分享一点实践经验:如何构建高效安全的Nginx Web服务器
最后给大家分享2个基于HTTPS优化案例:
-
基于 Nginx 的 HTTPS 性能优化实践
-
高性能 Nginx HTTPS 调优!为 HTTPS 提速 30%
Nginx 日志相关
介绍完了安装、配置、优化这些常用的场景之后,日志这块也是非常重要的,大家都知道日常排错,日志起着举足轻重的作用。
Nginx日志主要分为两种:access_log(访问日志)和error_log(错误日志)。通过访问日志我们可以得到用户的IP地址、浏览器的信息,请求的处理时间等信息。错误日志记录了访问出错的信息,可以帮助我们定位错误的原因。
error_log /var/log/nginx/error.log warn;
#配置错误日志的级别及存储目录events {worker_connections 1024;
}http {
..................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; #配置访问日志存储目
}
关于Nginx日志的配置实践看这篇:Nginx 日志配置实践!超详细
由于nginx功能强大,性能突出,越来越多的web应用采用nginx作为http和反向代理的web服务器。而nginx的访问日志不管是做用户行为分析还是安全分析都是非常重要的数据源之一。如何有效便捷的采集nginx的日志进行有效的分析成为大家关注的问题。
通过几个实例来介绍如何通过filebeat、logstash、rsyslog采集nginx的访问日志和错误日志,我也可以:利用ELK分析Nginx日志。
Nginx版本升级
这里我们来聊一聊,在企业实际生产环境中经常遇到的一个情况,如何升级Nginx到新的版本和如何回滚至旧版本。
版本升级其实就是针对二进制文件的升级,过程如下:
[root@nginx ~]# /usr/local/nginx-1.12.2/sbin/nginx -v
nginx version: nginx/1.12.2
[root@nginx ~]# cd /usr/local/nginx-1.12.2/sbin/
[root@nginx sbin]# mv nginx nginx-1.12.2
#首先备份原来的旧版本nginx二进制文件
[root@nginx sbin]# cp /usr/local/nginx-1.14.2/sbin/nginx ./
#拷贝新版本的二进制文件到当前目录
注:其实升级新版本,最重要的就是平滑升级,让前端用户无感知(也就是不中断服务,这个其实不难,生产中多台依次灰度升级)。
对于升级来说,最难的不是升级,而是回滚,因为在实际生产环境回滚的机率是存在,比如:新版本由于某些未知bug导致与现有应用不兼容、或出现运行不稳定的情况等等。
所以,对于我们来说,故障回滚是重点。这里给大家推荐我总结的:1分钟搞定 Nginx 版本的平滑升级与回滚
Nginx 反向代理与负载均衡
反向代理简介
反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。反向代理是为服务端服务的,反向代理可以帮助服务器接收来自客户端的请求,帮助服务器做请求转发,负载均衡等。
反向代理对服务端是透明的,对我们是非透明的,即我们并不知道自己访问的是代理服务器,而服务器知道反向代理在为他服务。
配置实例
http {upstream product_server{ 127.0.0.1:8081;}upstream admin_server{ 127.0.0.1:8082;}upstream test_server{ 127.0.0.1:8083;}server { #默认指向product的serverlocation / {proxy_pass http://product_server;}location /product/{proxy_pass http://product_server;}location /admin/ {proxy_pass http://admin_server;}location /test/ {proxy_pass http://test_server;}}
}
如果你对Nginx 配置中location 的规则不太熟悉,推荐你看看这篇文章:Nginx 实践:location 路径匹配。nginx 每个location都是一个匹配目录,nginx的策略是:访问请求来时,会对访问地址进行解析,从上到下逐个匹配,匹配上就执行对应location大括号中的策略,并根据策略对请求作出相应。
所以,有时候就因为在配置时,少些了一个字符“/”,就造成访问不通报错,这种问题是非常觉的故障原因之一,正所谓:Nginx配置中一个不起眼字符"/"的巨大作用,失之毫厘谬以千里,这篇文章详细进了相关的说明与举例验证。
反向代理的优势:
-
隐藏真实服务器;
-
负载均衡便于横向扩充后端动态服务;
-
动静分离,提升系统健壮性;
Nginx 负载均衡
nginx能实现负载均衡,什么是负载均衡呢?就是说应用部署在不同的服务器上,但是通过统一的域名进入,nginx则对请求进行分发,将请求分发到不同的服务器上去处理,这样就可以有效的减轻了单台服务器的压力。
配置实例
upstream server_pools { server 192.168.1.11:8880 weight=5; server 192.168.1.12:9990 weight=1; server 192.168.1.13:8989 weight=6; #weigth参数表示权值,权值越高被分配到的几率越大
}
server { listen 80; server_name mingongge.com; location / { proxy_pass http://server_pools; }
}
Nginx 实现负载均衡的策略
-
轮询策略:默认情况下采用的策略,将所有客户端请求轮询分配给服务端。这种策略是可以正常工作的,但是如果其中某一台服务器压力太大,出现延迟,会影响所有分配在这台服务器下的用户。
-
最小连接数策略:将请求优先分配给压力较小的服务器,它可以平衡每个队列的长度,并避免向压力大的服务器添加更多的请求。
-
最快响应时间策略:优先分配给响应时间最短的服务器。
-
客户端 ip 绑定策略:来自同一个 ip 的请求永远只分配一台服务器,有效解决了动态网页存在的 session 共享问题。
想要高可用?搞定负载均衡架构是关键,
关于负载均衡和反向代理的区别可以参考:一文详解负载均衡和反向代理的真实区别,关于 nginx 反向代理和负载均衡策略 实战案例。
Nginx 动静分离
Nginx动静分离是让动态网站里的动态网页根据一定规则把不变的资源和经常变的资源区分开来,动静资源做好了拆分以后,我们就可以根据静态资源的特点将其做缓存操作,这就是网站静态化处理的核心思路。推荐:CentOS 7.3:LAMP 动静分离部署可以了解一下Apache的配置,然后再回过头理解Nginx的动静分离可更直观。
server { listen 80; server_name mingongge.com; location /static { root /wwww/web/web_static_site; }
}
也可以使用下面的方法
location /image {alias /web/nginx/static/image/;
}
注意:使用alias末尾一定要添加/,并且它只能位于location中
使用前后端分离后,可以很大程度提升静态资源的访问速度,即使动态服务不可用,静态资源的访问也不会受到影响。
小试牛刀!Nginx 搭建静态资源服务器,这篇文章是给大家介绍整个搭建过程,非常详细。
Nginx 高级功能
除了负载均衡,Nginx还可以做很多,限流、缓存、黑白名单等
重定向配置
location / {return 404; #直接返回状态码
}
location / {return 404 "pages not found"; #返回状态码 + 一段文本
}
location / {return 302 /blog ; #返回状态码 + 重定向地址
}
location / {return https://www.mingongge.com ; #返回重定向地址
}
示例如下
server { listen 80;server_name www.mingongge.com;return 301 http://mingongge.com$request_uri;
}
server {listen 80; server_name www.mingongge.com; location /cn-url { return 301 http://mingongge.com.cn; }
}
server{listen 80;server_name mingongge.com; # 要在本地hosts文件进行配置root html;location /search {rewrite ^/(.*) https://www.mingongge.com redirect;}location /images {rewrite /images/(.*) /pics/$1;}location /pics {rewrite /pics/(.*) /photos/$1;}location /photos {}
}
流量拷贝
需求:将生产环境的流量拷贝到预上线环境或测试环境,这样做有很多好处,比如:
-
可以验证功能是否正常,以及服务的性能;
-
用真实有效的流量请求去验证,又不用造数据,不影响线上正常访问;
-
这跟灰度发布还不太一样,镜像流量不会影响真实流量;
-
可以用来排查线上问题;
-
重构,假如服务做了重构,这也是一种测试方式;
为了实现流量拷贝,Nginx提供了ngx_http_mirror_module模块,这就是 Nginx 又一牛X的功能!流量拷贝
限流
Nginx按请求速率限速模块使用的是漏桶算法,即能够强行保证请求的实时处理速度不会超过设置的阈值。
Nginx官方版本限制IP的连接和并发分别有两个模块:
-
limit_req_zone 用来限制单位时间内的请求数,即速率限制,采用的漏桶算法 “leaky bucket”。
-
limit_req_conn 用来限制同一时间连接数,即并发限制。
葵花宝典!一文搞定 Nginx 限流配置
缓存
Nginx 缓存作为性能优化的一个重要手段,可以极大减轻后端服务器的负载。下面我们将介绍 Nginx 缓存配置的相关指令以及 http 缓存机制,以及 Nginx 缓存实践案例分析。
可参考:Nginx 缓存机制详解!
灰度发布
执行过程:
-
当用户请求到达前端代理服务Nginx,内嵌的lua模块解析Nginx配置文件中的lua脚本代码;
-
Lua变量获得客户端IP地址,去查询memcached缓存内是否有该键值,如果有返回值执行@client_test,否则执行@client。
-
Location @client_test把请求转发给部署了new版代码的服务器,location @client把请求转发给部署了normal版代码的服务器,服务器返回结果。整个过程完成。
下面是安装配置过程详细过程:基于 Nginx+lua+Memcache 实现灰度发布
这里还给大家推荐一篇文章:基于 Nginx 实现灰度发布与 AB 测试
封杀恶意访问
看了 nginx 的访问日志,发现每天有好多国外的 IP 地址来访问我的网站,并且访问的内容基本上都是恶意的。因此我决定禁止国外 IP 来访问我的网站
想要实现这个功能有很多方法,下面我就来介绍基于 NGINX 的 ngx_http_geoip2 模块 来禁止国外 IP 访问网站。详细的解决方案配置如:通过 Nginx 来实现封杀恶意访问
Nginx+keepalived 实现高可用
Keepalived软件起初是专为LVS负载均衡软件设计的,用来管理并监控LVS集群系统中各个服务节点的状态,后来又加入了可以实现高可用的VRRP (Virtual Router Redundancy Protocol ,虚拟路由器冗余协议)功能。因此,Keepalived除了能够管理LVS软件外,还可以作为其他服务(例如:Nginx、Haproxy、MySQL等)的高可用解决方案软件。keepalived高可用集群服务
安装及配置过程请参考:Nginx+keepalived 实现高可用,防盗链及动静分离配置,写得太好了!
Nginx 终极指南
介绍用来提高Nginx服务器的安全性,稳定性和性能的12种操作。
-
保持Nginx的及时升级
-
去掉不用的Nginx模块
-
禁用server_tokens项
-
禁止非法的HTTP User Agents
-
禁掉不需要的 HTTP 方法
-
设置缓冲区容量上限
-
限制最大连接数
-
设置日志监控
-
阻止图片外链
-
禁止 SSL 并且只打开 TLS
-
证书加密(HTTPS)
-
重定向HTTP请求到HTTPS
以上12个具体的配置过程可参考:提高Nginx服务器硬度的12个技巧
Nginx 监控
监控Web服务器对于查看网站上发生的情况至关重要。关注最多的便是日志变动,查看实时日志文件变动大家第一反应应该是’tail -f /path/to/log’命令吧,但是如果每个网站的访问日志都是使用这种方式查看也是相当崩溃的,今天小编就跟大家分享一个强大的Nginx日志监控工具。
一个小工具帮你搞定实时监控Nginx服务器
日常生产环境搭建了Nginx集群后,就需要继续深入研究的就是日常Nginx监控。Nginx如何监控?相信百度就可以找到:nginx-status
通过Nginx-status,实时获取到Nginx监控数据后,如何和现有监控系统集成?一个很好的解决方案:Nginx+Telegraf+Influxdb+Grafana
即通过Telegraf监控插件定时收集Nginx的监控状态,存储到时序数据库Influxdb中,然后通过Grafana展现即可。
这是我发现的又一款管理神器,可以实现配置管理,和性能监控。具体的安装与配置过程,在这篇文章:又一款 Nginx 管理可视化神器!配置、监控一条龙 中介绍过了。