Table of Contents
Nginx的简介
Nginx[engine x]是HTTP和反向代理服务器,邮件代理服务器和通用TCP / UDP代理服务器
优点:
- 高并发、高性能且可扩展性强
- 可以用进行二次开发
- 内存消耗少
- 配置文件简单
- 相比f5成本低
- 支持重写规则
基本的HTTP服务器功能
- 提供静态和索引文件,自动索引;打开文件描述符缓存;
- 带有缓存的加速反向代理;负载平衡和容错;
- 对FastCGI、uwsgi、SCGI和memcached服务器进行缓存的加速支持;负载平衡和容错;
- 模块化架构。过滤器包括gzipping,字节范围,分块响应,XSLT,SSL和图像转换过滤器。如果由代理服务器或FastCGI / uwsgi / SCGI 服务器处理单个页面中的多个SSI包括,则可以并行处理;
- SSL和TLS SNI支持;
- 通过加权和基于依赖项的优先级支持HTTP / 2
其他HTTP服务器功能
- 基于名称和基于IP的虚拟服务器;
- 保持活动和管道连接支持;
- 访问日志格式,缓冲日志写入,快速日志循环和syslog日志;
- 3xx - 5xx错误代码重定向;
- 重写模块:使用正则表达式更改URI;
- 根据客户地址执行不同的功能;
- 基于客户端IP地址,密码(HTTP基本身份认证)和子请求结果的访问控制;
- HTTP Referer的验证;
- PUT,DELETE,MKCOL,复制和移动方法;
- FLV和MP4流媒体;
- 响应率限制;
- 限制来自一个地址同时连接或请求的数量;
- 基于IP的地理位置;
- A / B测试;
- 请求镜像;
- 嵌入式Perl;
- njs脚本语言;
邮件代理服务器功能
- 使用外部HTTP身份验证服务器将用户重定向到IMAP或POP3服务器;
- 使用外部HTTP身份验证服务器的用户身份验证以及到内部SMTP服务器的连接重定向;
- 认证方式:
- POP3:USER / PASS,APOP,AUTH LOGIN / PLAIN / CRAM-MD5;
- IMAP:登录,授权登录 / 普通 / CRAM-MD5;
- SMTP:AUTH LOGIN / PLAIN / CRAM-MD5;
- SSL支持;
- STARTTLS 和 STLS 支持
TCP / UDP 代理服务器功能
- TCP和UDP的通用代理;
- SSL和TLS SNI 对TCP的支持;
- 负载平衡和容错;
- 基于客户地址的访问控制;
- 根据客户地址执行不同的功能;
- 限制来自一个地址的同时连接数;
- 访问日至格式,缓冲日志写入,快速日志循环和syslog日志;
- 基于IP的地理位置;
- A / B 测试;
- njs脚本语言;
本文简单介绍反向代理,负载均衡以及动静分离,之后会被内容进行补充:
反向代理
反向代理服务器处于用户和目标服务器中间,对于用户而言,它即是服务器,用户直接访问反向代理服务器就可以获取到目标服务器的资源。而且用户不需要知道目标服务器信息。反向代理服务器通常用来作为web加速缓存,降低网络和服务器的负载,提高访问效率。
负载均衡
实际情况中,很多时候我们通过单个服务器都没有办法满足需求,这时就需要增加服务器的数量,然后将原先请求单个服务器上的情况改为请求分发到多个服务器上,让多个服务器来均分,共同抗压,这就是负载均衡。
动静分离
根据资源类型不同,分为动态资源和静态资源,将动态页面和静态页面交给不同的服务器来解析,加快解析速度,并降低单个服务器的压力。
Nginx安装
下载安装包:http://nginx.org/en/download.html
查看官方文档:http://nginx.org/en/docs/
- 通过Apache共享到node1
- 解压源码包并进行语法检测[通过字体颜色可以查看是否写错]
添加语法检测前:
添加语法检测:
添加语法检测后:
此时我们就可以直接通过字体颜色来判断输入是否正确
- 查看编译可选参数
- 编译
发现编译过程中报错,查看原因是因为缺少gcc编译环境,安装gcc
再次进行编译
发现有error,提示告诉我们HTTP重写模块缺少PCRE模块,安装pcre模块
再次编译
查看原因是因为我们缺少openssl模块,安装openssl模块
再次进行编译
没有error,编译完成,当前目录下又多了一个objs目录
- make && make install
没有报错,make成功,同时在objs目录下又添加了很多内容
- 切换到安装目录
可以看到/usr/local/目录下有一个nginx目录,这就是nginx的主程序
Nginx的启动
- 查看配置文件
cd /nginx/conf/
vim nginx.conf
默认监听端口为80,默认发布根目录为html,默认发布页面是index.html
- 开启nginx并查看其端口
- 查看当前nginx版本
- 查看进程
其中master进程是负责监控worker进程,而worker进程是真正处理请求的进程
- 访问node1主机80端口,出现nginx默认页面
- 测试
更改默认发布页面
vim /usr/local/nginx/html/index.html
访问
Nginx的版本更新和回退
更新
更新前一定要备份!!!
查看当前版本
- 进入要更新的版本目录进行预编译
- make
注意:一定不要执行make install!!!这步骤只在第一次操作的时候执行,如果此时执行make install会直接覆盖原来的二进制程序,导致出现错误
- 将生成的nginx复制到安装目录,覆盖原文件
- 查看当前版本,版本已经更改
- 查看当前进程
可以看到进程使用的还是原来的二进制文件,因为已经加载到内存中
- 通过kill命令,使得原先进程不再接收信息并生成新的进程
- 关闭原先进程的worker
此时先保留原先版本的master进程,避免因为新版本出现问题,无法正常工作而导致大错。我们可以通过它来恢复原先版本
回退
- 直接使用之前的备份二进制程序覆盖掉新的
kill -HUP 19257 # 更改配置且不需要停止重新启动服务
- 告知1.17版本不再接受请求,并关闭worker进程
- 关闭master进程
Nginx配置示例
日志备份
cd /usr/local/nginx/logs/
ll
这里我们的日志文件大小较小,因为我们先给日志扩容,再做后续操作,在主机中:
请求完成之后,我们再去查看文件大小,可以发现明显大了很多
mv access.log `date +%F -d -1day`_access.log # 修改日志名格式
../sbin/nginx -s reopen # 重新打开nginx,会出现新的access.log
Ngnix压缩
- 编辑index.html文件,将其扩容,随意扩容大小
- 访问192.168.1.11, 并且通过F12进入开发者工具,查看信息,文件大小为1.4MB,转换大小也是1.4MB
- 修改配置文件
gzip on;
gzip_min_length 1;
gzip_comp_level 2;
gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
- 检测并重新加载
[root@node1 conf]# ../sbin/nginx -t
[root@node1 conf]# ../sbin/nginx -s reload
- 访问,查看压缩结果,可以看到我们只转换了21.3KB
设置服务启动方式,可以代替脚本启动方式
- 官方系统自带的服务启动脚本默认位置都在/usr/lib/systemd/system/下
- 自己配置的服务,官方建议放在/etc/systemd/system/下
- 由于nginx配置和http的配置文件相似,因此我们可以直接安装Apache,然后将Apache配置文件复制到/etc/systemd/system/目录下
yum install -y httpd
systemctl status httpd.service
cp /usr/lib/systemd/system/httpd.service /etc/systemd/system/nginx.service
- 编辑nginx.service
cd /etc/systemd/system/
vim nginx.service
###
[Unit]
Description=The Nginx HTTP Server
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/usr/local/nginx/sbin/nginx.pid
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/usr/local/nginx/sbin/nginx -s stop
PrivateTmp=true
[Install]
WantedBy=multi-user.target
###
- 关闭nginx,启动nginx
systemctl stop nginx.service # 关闭nginx
systemctl start nginx.service # 开启nginx
虚拟主机
基于域名的虚拟主机配置
- 编辑配置文件
vim /usr/local/nginx/conf/nginx.conf
- 新建目录,并编辑发布页面
[root@node1 nginx]# mkdir virtualhtml/
[root@node1 nginx]# cd virtualhtml/
[root@node1 virtualhtml]# vim index.html
直接访问
访问虚拟主机
注意:nginx本身只支持静态资源
基于端口的虚拟主机配置
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
server {
listen 81;
server_name www.dsd.com ;
location / {
root virtualhtml;
index index.html index.htm;
}
}
基于IP的虚拟主机配置
server {
listen 192.168.1.11:80;
server_name www.dsd.com;
location / {
root html;
index index.html index.htm;
}
}
server {
listen 192.1668.1.9.80;
server_name bbs.dsd.com;
location / {
root virtualhtml;
index index.html index.htm;
}
}
限制连接数
官方文档地址:https://docs.nginx.com/nginx/admin-guide/security-controls/controlling-access-proxied-http/
只能限制一个并发连接数,多余则会报错
limit_conn_zone $binary_remote_addr zone=addr:10m;
location /download/ {
limit_conn addr 1;
}
- 在html目录下创建download目录,并放入图片
[root@node1 html]# mkdir download
[root@node1 html]# cd download/ # 切换到该目录,将图片放在该目录中
[root@node1 html]# ../sbin/nginx -t # 检测语句
[root@node1 html]# ../sbin/nginx -s reload # 重启
- 访问
Nginx的负载均衡
vim /usr/local/nginx/conf/nginx.conf
配置负载均衡,在用户访问bbs.dsd.com的80端口时,实际访问的是本机的8000 8001 8002 8003端口,且轮循访问,其中weight代表权重,即每访问三次8000端口,其他访问一次。
可以通过设置不同的服务器地址IP,这样就可以将本机看作一个负载均衡器,负责调度请求到真实的服务,这里的配置介绍如何调度请求到其他位置,来均衡调度。
获取真实IP
请求从客户端发起 —> 经过路由器 —> 反向代理服务器 —> Nginx服务器接收过程:
我们的Nginx服务器,只能拿到上层的192.168.1.12 IP,但此IP不是用户的真实IP,这个时候就需要realip模块去获取真实IP,赋值给变量binary_remote_addr、remote_addr,传给上游服务。
那么realip模块是如何获取真实IP呢?其实是通过http头部的 X-Forwardwd-For 与 X-Real-IP ,其中 X-Real-IP 只会记录第一次记录的值,X-Forwardwd-For 则是每次经过一个网络时把IP加入。
在这里我们在一个服务器端来测试一下即可
- 编辑nginx.conf文件
- 语法测试
语法检测报错原因告知我们缺少realip模块,那么我们就需要去重新编译添加该模块
- 添加 --with-http_realip_module 模块
./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_realip_module
make && make install # 正常情况只有第一次安装时才会进行make install,因为会覆盖其中内容,但此时我们只修改了配置文件
- 再次检测,无误后启动nginx
- 访问请求
curl -H "X-Forwarded-For: 1.1.1.1,192.168.1.11" node1.example.org
可以看到,nginx会从http头部的X-Real-IP拿到用户的真实IP