[Nginx基础]-①概念篇
[Nginx基础]-①概念篇
1.基本概念
nginx是一款自由的、开源的、高性能的HTTP服务器和反向代理服务器;同时也是一个IMAP、POP3、SMTP代理服务器;nginx可以作为一个HTTP服务器进行网站的发布处理,还可作为反向代理进行负载均衡的实现
nginx作用
发布网站(静态, html,css,js)
实现负载均衡
代理服务器
作为邮件服务器实现收发邮件等功能
【1】正向代理 VS 反向代理
正向代理
正向代理:正向代理是最常接触的到的代理模式,可以从两个角度(软件方面和生活方面来)理解正向代理的处理模式
场景分析:科学上网
在如今的网络环境下,可能会由于技术需要访问国外的某些网站,此时如果单纯借助浏览器是没办法直接访问国外网站的,因此借助FQ操作进行访问,而FQ方式则主要是找到一个可以访问国外网站的代理服务器,客户端将请求发送给代理服务器,由代理服务器去访问国外的网站/资源,随后将访问到的数据传递给客户端
上述场景的代理模式则称为正向代理,正向代理最大的特点是客户端非常明确要访问的服务器地址;服务器只清楚请求来自哪个代理服务器,而不清楚来自哪个具体的客户端,也就是说,正向代理模式屏蔽或者隐藏了真实客户端信息。
反向代理
场景分析:分布式部署
以某宝为例,每天同时连接到网站的访问人数已经爆表,单个服务器远远不能满足人民日益增长的购买欲望(无法承载流量),因此引入一个概念:分布式部署,通过部署多台服务器来解决访问人数限制的问题;
某宝网站中大部分功能也是直接使用nginx进行反向代理实现,并且通过封装nginx和其他的组件构成了Tengine,从而适配业务需求
通过上述的图解可以看到,多个客户端给服务器发送的请求,nginx服务器接在接收请求之后,按照一定的规则分发给了后端的业务处理服务器进行处理。此时请求的来源(即客户端)是明确的,但是请求具体由哪台服务器处理的则不明确了,nginx在此处扮演的就是一个反向代理角色
反向代理,主要用于服务器集群分布式部署的情况下,反向代理隐藏了服务器的信息!
项目场景
在通常情况下实际项目操作时,正向代理和反向代理很有可能会存在在一个应用场景中**,正向代理代理客户端的请求去访问目标服务器,目标服务器是一个反向代理服务器,反向代理了多台真实的业务处理服务器。**具体的拓扑图如下
【2】反向代理-Nginx
负载均衡
在了解代理服务的基础上,可以知道nginx扮演的是反向代理服务器的角色,进一步了解nginx是以依据什么样的规则进行请求分发的呢?不用的项目应用场景,分发的规则是否可以控制呢?
负载量
负载量:客户端发送的、nginx反向代理服务器接收到的请求数量
负载均衡
负载均衡:请求数量按照一定的规则进行分发到不同的服务器处理的规则,就是一种均衡规则。因此,将服务器接收到的请求按照规则分发的过程,称为负载均衡
负载均衡在实际项目操作过程中,有硬件负载均衡和软件负载均衡两种,硬件负载均衡也称为硬负载,如F5负载均衡,相对造价昂贵成本较高,但是数据的稳定性安全性等等有非常好的保障,如中国移动中国联通这样的公司才会选择硬负载进行操作;更多的公司考虑到成本原因,会选择使用软件负载均衡,软件负载均衡是利用现有的技术结合主机硬件实现的一种消息队列分发机制
nginx支持的负载均衡调度算法:
weight轮询(默认):接收到的请求按照顺序逐一分配到不同的后端服务器,即使在使用过程中,某一台后端服务器宕机,nginx会自动将该服务器剔除出队列,请求受理情况不会受到任何影响。 加权轮询这种方式下,可以给不同的后端服务器设置一个权重值(weight),用于调整不同的服务器上请求的分配率;权重数据越大,被分配到请求的几率越大;该权重值,主要是针对实际工作环境中不同的后端服务器硬件配置进行调整的。
ip_hash:每个请求按照发起客户端的ip的hash结果进行匹配,基于该算法下一个固定ip地址的客户端总会访问到同一个后端服务器,这也在一定程度上解决了集群部署环境下session共享的问题。
fair:智能调整调度算法,动态的根据后端服务器的请求处理到响应的时间进行均衡分配,响应时间短处理效率高的服务器分配到请求的概率高,响应时间长处理效率低的服务器分配到的请求少;结合了前两者的优点的一种调度算法,但是需要注意的是nginx默认不支持fair算法,如果要使用这种调度算法,需要安装upstream_fair模块
url_hash:按照访问的url的hash结果分配请求,每个请求的url会指向后端固定的某个服务器,可以在nginx作为静态服务器的情况下提高缓存效率。如果要使用这种调度算法,需要安装nginx的hash软件包
Nginx的功能特性
2.Nginx的安装、配置
【1】nginx安装、配置
linux环境
进入nginx官网,下载指定版本的.tar.gz文件
将下载好的nginx安装包上传到虚拟机指定路径,通过ls -l查看文件属性
# 也可通过wget获取安装包
wget http://nginx.org/download/nginx-1.15.3.tar.gz
安装依赖环境
#安装Nginx依赖环境,‐y表示所有提示默认选择y
yum -y install pcre pcre-devel
yum ‐y install zlib zlib‐devel
yum ‐y install openssl openssl‐devel
解压和编译安装、启动nginx服务器
# 1.将nginx解压至指定目录(此处解压到/usr/local/software/)并重命名
tar -zxvf nginx-1.17.5.tar.gz -C /usr/local/software/
mv nginx-1.17.5 nginx
# 2.进入nginx目录,编译并安装【确保有gcc编译环境】
# 编译和测试
cd nginx
./configure
# PS:也可直接指定nginx目录配置的形式执行指令: ./configure --prefix=/usr/local/software/nginx --conf-path=/usr/local/software/nginx/nginxconf/nginx.conf)
# 安装
make
make install
# 3.安装成功之后,在/usr/local下生成了nginx目录,进入nginx/sbin目录
cd /usr/local/nginx/sbin
# 在sbin目录下控制nignx服务(启动、停止、重写加载)
./nginx # 启动
./nginx ‐s stop # 停止
./nginx ‐s reload # 重写加载
# 也可直接通过sbin/nginx执行操作
sbin/nginx -v # 查看nginx版本
sbin/nginx # 启动nginx
# 启动成功后查看是否有nginx的线程是否存在
ps ‐ef | grep nginx
开放linux的对外访问的端口80,在默认情况下,Linux不会开放80端口号,需要编辑iptables文件。此外,如果出现端口号被占用,则有可能是其他的服务占用80端口(例如httpd),可以通过修改默认端口号,也可以通过关闭httpd服务进行测试。完成安装配置,在网页上直接访问相应的ip地址即可
# 查看当前端口号被谁占用
lsof -i:80
# 查看80相关的端口占用情况
netstat -lnp | grep 80
# 关闭相关进程
kill -9 pid(进程id)
window环境
【2】nginx配置文件说明
以linux环境下nginx配置文件进行说明
🔖main模块
基本概念
全局块:全局块是默认配置文件从开始到events块直接的一部分内容,主要设置一些影响nginx服务器整体运行的配置指令(指令作用域为nginx服务器全局)。
通常包括配置运行nginx服务器的用户(组)、允许生成的worker process数、nginx进程PID存放路径 、日志的存放路径和类型、配置文件引入
配置说明
- 存放在main全局配置模块中的配置项(配置指定的安装目录下的路径):
#user nobody;
worker_processes 2 ;
#error_log logs/error.log;
error_log /usr/local/software/nginx/logs/error.log crit;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
pid /usr/local/software/nginx/logs/nginx.pid;
worker_rlimit_nofile 65535;
user:指定nginx worker进程运行用户以及用户组,默认nobody账号运行
worker_processes:指定nginx要开启的子进程数量,运行过程中监控每个进程消耗内存(一般几M~几十M不等)根据实际情况进行调整,通常数量是CPU内核数量的整数倍
error_log:定义错误日志文件的位置及输出级别【debug / info / notice / warn / error / crit】;crit 记录的日志最少,而debug记录的日志最多。需根据实际情况选择配置日志级别(建议保持默认,配置级别低则可能出现无用信息太多,级别高则信息太少而不容易排查问题)
pid:指定进程id的存储文件的位置
worker_rlimit_nofile:用于指定一个进程可以打开最多文件数量的描述。这个指令是指当一个nginx进程打开的最多文件描述符数目,理论值应该是最多打开文件数(ulimit -n)与nginx进程数相除,但是nginx分配请求并不是那么均匀,所以最好与ulimit -n 的值保持一致(在linux 2.6内核下开启文件打开数为65535,worker_rlimit_nofile就相应应该填写65535)。因为nginx调度时分配请求到进程并不是那么的均衡,所以假如填写10240,总并发量达到3-4万时就有进程可能超过10240了,这时会返回502错误
🔖Event模块
基本概念
events块涉及的指令主要影响nginx与用户的网络连接。
常用到的设置包括是否开启对多worker process下的网络连接进行序列化,是否允许同时接收多个网络连接,选取何种事件驱动模型处理连接请求,每个worker process可以同时支持的最大连接数等
这部分的指令对nginx服务器的性能影响比较大,在实际配置中应该根据实际情况灵活调整
配置说明
- 针对nginx服务器的工作模式的一些操作配置
event {
worker_connections 1024;
multi_accept on;
use epoll;
}
worker_connections:指定最大可以同时接收的连接数量(最大连接数量是和worker processes共同决定,最大连接数=连接数*进程数)
multi_accept:配置指定nginx在收到一个新连接通知后尽可能多的接受更多的连接
use epoll :use [ kqueue | rtsig | epoll | /dev/poll | select | poll ],配置指定了线程轮询的方法(如果是linux2.6+,使用epoll;如果是FreeBSD使用Kqueue)
- 其余配置
# keepalive超时时间
keepalive_timeout 60;
# client_header_buffer_size客户端请求头部的缓冲区大小(设置为“系统分页大小”的整倍数)
client_header_buffer_size 4k;
# 为打开文件指定缓存(默认未启用),max指定缓存数量,建议和打开文件数一致,inactive是指经过多长时间文件没被请求后删除缓存
open_file_cache max=65535 inactive=60s;
# 多长时间检查一次缓存的有效信息
open_file_cache_valid 80s;
# 指定了一定的时间范围内可以使用的最小文件数,如果使用更大的值,文件描述符在cache中总是打开状态
open_file_cache_min_uses 1;
# 指定是否在搜索一个文件时记录cache错误(on|off)
open_file_cache_errors on;
🔖http模块
基本概念
http模块是nginx服务器配置中的重要部分,代理、缓存和日志定义等绝大多数动能和第三方模块的配置都可再次配置
http包含自己的全局块,也可包含server块,server块中又可包含location块,可以在http全局块中配置的指令包括文件引入、MIME-Type定义、日志自定义、是否使用sendfile传输文件、连接超时时间、单连接请求数上限等
作为web服务器,http模块是nginx最核心的一个模块,配置项也是比较多的,项目中会设置到很多的实际业务场景,需要根据硬件信息进行适当的配置,常规情况下,使用默认配置即可!
(1)基础配置
配置说明
#文件扩展名与文件类型映射表
include mime.types;
#默认文件类型
default_type application/octet-stream;
#默认编码
# charset utf-8;
sendfile on:配置on让sendfile发挥作用,将文件的回写过程交给数据缓冲去去完成,而不是放在应用中完成,这样的话在性能提升有有好处
#开启高效文件传输模式,sendfile指令指定nginx是否调用sendfile函数来输出文件,对于普通应用设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络I/O处理速度,降低系统的负载。注意:如果图片显示不正常把这个改成off。
#sendfile指令指定 nginx 是否调用sendfile 函数(zero copy 方式)来输出文件,对于普通应用,必须设为on。如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络IO处理速度,降低系统uptime。
tc_nopush on:让nginx在一个数据包中发送所有的头文件,而不是一个一个单独发
tcp_nodelay on:让nginx不要缓存数据,而是一段一段发送,如果数据的传输有实时性的要求的话可以配置它,发送完一小段数据就立刻能得到返回值,但是不要滥用哦
keepalive_timeout 10:给客户端分配连接超时时间,服务器会在这个时间过后关闭连接。一般设置时间较短,可以让nginx工作持续性更好
client_header_timeout 10:设置请求头的超时时间
client_body_timeout 10:设置请求体的超时时间
send_timeout 10:指定客户端响应超时时间,如果客户端两次操作间隔超过这个时间,服务器就会关闭这个链接
#服务器名字的hash表大小
server_names_hash_bucket_size 128;
#客户端请求头部的缓冲区大小
client_header_buffer_size 4 32k;
#客户请求头缓冲大小。nginx默认会用client_header_buffer_size这个buffer来读取header值,如果header过大,它会使用large_client_header_buf fers来读取。
large_client_header_buffers 4 64k;
#设定通过nginx上传文件的大小
client_max_body_size 8m;
(2)日志配置
access_log logs/access.log:设置存储访问记录的日志
error_log logs/error.log:设置存储记录错误发生的日志
#日志格式设定
#$remote_addr与$http_x_forwarded_for用以记录客户端的ip地址;
#$remote_user:用来记录客户端用户名称;
#$time_local: 用来记录访问时间与时区;
#$request: 用来记录请求的url与http协议;
#$status: 用来记录请求状态;成功是200,
#$body_bytes_sent :记录发送给客户端文件主体内容大小;
#$http_referer:用来记录从那个页面链接访问过来的;
#$http_user_agent:记录客户浏览器的相关信息;
#通常web服务器放在反向代理的后面,这样就不能获取到客户的IP地址了,通过$remote_add拿到的IP地址是反向代理服务器的iP地址。反向代理服务器在转发请求的http头信息中,可以增加x_forwarded_for信息,用以记录原有客户端的IP地址和原来客户端的请求的服务器地址。
log_format access '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" $http_x_forwarded_for';
日志定时备份处理
在日常开发中,需要运维对nginx日志进行切割和分析处理,可通过编写shell脚本实现日志切分,随后编写定时器对脚本进行调度
crontab -e */1 * * * * sh /usr/local/nginx/sbin/log.sh
(3)gzip模块设置
gzip on; #开启gzip压缩输出
gzip_min_length 1k; #最小压缩文件大小
gzip_buffers 4 16k; #压缩缓冲区
gzip_http_version 1.0; #压缩版本(默认1.1,前端如果是squid2.5请使用1.0)
gzip_comp_level 2; #压缩等级
gzip_types text/plain application/x-javascript text/css application/xml; #压缩类型,默认就已经包含textml,如果显式指定texttml不会报错但会有一个warn
gzip_vary on;
🔖server模块
基本概念
srever模块配置是http模块中的一个子模块,用来定义一个虚拟访问主机,也就是一个虚拟服务器的配置信息
配置说明
server {
listen 80;
server_name localhost 192.168.1.100;
root /nginx/www;
index index.php index.html index.html;
charset utf-8;
access_log logs/access.log;
error_log logs/error.log;
......
}
server:一个虚拟主机的配置,一个http中可以配置多个server
server_name:用力啊指定ip地址或者域名,多个配置之间用空格分隔
root:表示整个server虚拟主机内的根目录,所有当前主机中web项目的根目录
index:用户访问web网站时的全局首页
charset:用于设置www/路径中配置的网页的默认编码格式
access_log:用于指定该虚拟主机服务器中的访问记录日志存放路径
error_log:用于指定该虚拟主机服务器中访问错误日志的存放路径
【3】nginx配置参考
📌虚拟主机相关配置
(1)配置多个虚拟机
server{
listen 8082;
server_name 192.168.8.254;
charset UTF-8;
location / {
root home;
index index.html index.jsp;
}
}
(2)配置反向代理tomcat服务器
需求分析
配置反向代理tomcat服务器:拦截.jsp结尾的请求转向到tomcat
配置步骤参考
1)在其中的Nginx服务器下配置如下代码
nginx安装目录(/usr/local/software/nginx):nginxconf/nginx.conf 添加如下代码:在http/server/location层次结构下完成配置
# 注意空格,否则配置出错
location ~ \.jsp$ {
proxy_pass http://192.168.8.113:8080;
#上述语句配置反向代理tomcat服务器
}
2)在192.168.8.113服务器上的tomcat/webapps/ROOT/下添加一个test.jsp文件用于测试
<%@ page session="false" pageEncoding="UTF-8" contentType="text/html; charset=UTF-8" %>
<html>
<body>
Test Page!!<br/><br/>
remote ip:<%=request.getHeader("X-real-ip")%><br/>
nginx serve ip:<%=request.getRemoteAddr()%>
</body>
</html>
3)启动服务器上的tomcat(或者等待tomcat热加载自动重启)
# 进入tomcat安装目录/bin,tomcat启动
./startup.sh
# tomcat关闭
./shutdown.sh
# nginx启动
sbin/nginx
# ngin关闭
sbin/nginx -s stop
4)分别通过tomcat、nginx这两种方式访问验证反向代理
# tomcat方式访问
http://192.168.8.113:8080/test.jsp
# nginx验证反向代理(端口号以nginx配置为参考)
http://192.168.8.113:8081/test.jsp
配置负载均衡
tomcat环境准备
假设现有三台服务器,在这三台服务器上分别配置tomcat(将已安装好的tomcat文件复制到指定服务器目录完成安装)
服务器 | IP | tomcat安装目录 |
---|---|---|
服务器A | 192.168.8.113 | /usr/local/software/ |
服务器B | 192.168.8.114 | /usr/local/software/ |
服务器C | 192.168.8.115 | /usr/local/software/ |
# 在A中配置tomcat,通过scp指令将配置完成的tomcat目录转移到B、C下指定目录
scp -r tomcat8.5/ 192.168.8.114:/usr/local/software/
scp -r tomcat8.5/ 192.168.8.115:/usr/local/software/
负载均衡配置
1)使用轮询或者加权轮询的方式配置负载均衡
upstream myapp{
server 192.168.8.113:8080 weight=1 max_fails=2 fail_timeout=30s;
server 192.168.8.114:8080 weight=1 max_fails=2 fail_timeout=30s;
server 192.168.8.115:8080 weight=1 max_fails=2 fail_timeout=30s;
}
2)完成负载均衡和反向代理的配置
注意原有测试时配置的影响,保证配置”干净”
location / {
proxy_set_header X-real-ip $remote_addr;
proxy_pass http://myapp;
root html;
index index.html index.htm;
}
最终配置结果参考如下图所示
3)此处测试参考以在tomcat/ROOT下添加test.jsp为参考,将三台服务器上的test.jsp作相应修改,用于验证不同的显示内容
由于其余两台服务器中的tomcat内容是从192.168.8.113服务器复制过去的,因此需要修改相应tomcat下webapps下的test.jsp内容,用于更明确显示当前访问的是哪个服务器的tomcat(由于当前指配置了单个服务器,因此此处无论访问哪个tomcat服务器,其server ip均是由当前配置的服务器决定的,如果不修改test.jsp文件,仅仅由表面的测试结果难以观察结果的正确性)
修改文件test.jsp后,分别启动每台服务器上的tomcat,清空浏览器缓存数据,依次按照一定顺序访问数据:
http://192.168.8.113:8081/test.jsp
最终显示结果参考如下所示,由结果可知虽然浏览器访问服务器A的文件,经由nginx反向代理转发后依次访问到A、B、C服务器的内容,从而验证负载均衡配置完成