Nginx之upstream分布式部署
Nginx的好处:
Nginx是高性能的HTTP 和反向代理的web服务器,有着强大的处理高并发得能力,能经受高负载,并且占有内存少。
反向代理:
反向代理,其实客户端对代理是无感知的,因为客户端不需要任何配置就可以访问。
我们只 需要将请求发送到反向代理服务器,由反向代理服务器去选择目标服务器获取数据后,在返 回给客户端,此时反向代理服务器和目标服务器对外就是一个服务器,暴露的是代理服务器 地址,隐藏了真实服务器 IP 地址。
1:Nginx的工作原理
Mater和worker
众所周知,nginx性能高,而nginx的高性能与其架构是分不开的
Nginx在启动后,会有一个master进程和多个worker进程。master进程主要用来管理worker进程,包含:接收来自外界的信号,向各worker进程发送信号,监控worker进程的运行状态,当worker进程退出后(异常情况下),会自动重新启动新的worker进程。而基本的网络事件,则是放在worker进程中来处理了。多个worker进程之间是对等的,他们同等竞争来自客户端的请求,各进程互相之间是独立的。一个请求,只可能在一个worker进程中处理,一个worker进程,不可能处理其它进程的请求。worker进程的个数是可以设置的,一般我们会设置与机器cpu核数一致,这里面的原因与nginx的进程模型以及事件处理模型是分不开的
master进程会接收来自外界发来的信号,再根据信号做不同的事情。所以我们要控制nginx,只需要向master进程发送信号就行了。比如我们常用的修改配置文件之后的重启 ./nginx -s reload等这些高效命令,首先master进程在接到信号后,会先重新加载配置文件,然后再启动新的worker进程,并向所有老的worker进程发送信号,告诉他们可以光荣退休了。新的worker在启动后,就开始接收新的请求,而老的worker在收到来自master的信号后,就不再接收新的请求,并且在当前进程中的所有未处理完的请求处理完成后,再退出。
设置多少个 worker?
Nginx 同 redis 类似都采用了 io 多路复用机制,每个 worker 都是一个独立的进程,但每个进 程里只有一个主线程,通过异步非阻塞的方式来处理请求, 即使是千上万个请求也不在话 下。每个 worker 的线程可以把一个 cpu 的性能发挥到极致。所以 worker 数和服务器的 cpu 数相等是最为适宜的。设少了会浪费 cpu,设多了会造成 cpu 频繁切换上下文带来的损耗。worker 数和服务器的 cpu 数相等是最为适宜。(最多是服务器cup的2倍)
总结:nginx 启动后,是由两个进程组成的。master(管理者)和worker(工作者)。
一个nginx 只有一个master。但可以有多个worker,过来的请求由master管理,worker进行争抢式的方式去获取请求。
2:nginx的部署
Nginx 是 C语言 开发,建议在 Linux 上运行,当然,也可以安装 Windows 版本,本篇则使用 CentOS 7 作为安装环境。
一. gcc 安装
安装 nginx 需要先将官网下载的源码进行编译,编译依赖 gcc 环境,它可以编译 C,C++,Ada,Object C和Java等语言,如果没有 gcc 环境,则需要安装:
命令:gcc -v查看gcc版本
yum install gcc-c++
二. PCRE pcre-devel 安装
PCRE(Perl Compatible Regular Expressions) 是一个Perl库,包括 perl 兼容的正则表达式库。nginx 的 http 模块使用 pcre 来解析正则表达式,所以需要在 linux 上安装 pcre 库,pcre-devel 是使用 pcre 开发的一个二次开发库。nginx也需要此库。命令:
yum install -y pcre pcre-devel
三. zlib 安装
zlib 库提供了很多种压缩和解压缩的方式, nginx 使用 zlib 对 http 包的内容进行 gzip ,所以需要在 Centos 上安装 zlib 库。
yum install -y zlib zlib-devel
四. OpenSSL 安装
OpenSSL 是一个强大的安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理功能及 SSL 协议,并提供丰富的应用程序供测试或其它目的使用。
nginx 不仅支持 http 协议,还支持 https(即在ssl协议上传输http),所以需要在 Centos 安装 OpenSSL 库。
openssl是web安全通信的基石,没有openssl,可以说我们的信息都是在裸奔。。。。。。
yum install -y openssl openssl-devel
官网下载
1.直接下载.tar.gz安装包,地址:nginx: download
2. 使用wget命令下载(推荐)。确保系统已经安装了wget,如果没有安装,执行 yum install wget 安装。
*一般安装在/usr/local/nginx目录下面,没有nginx目录的话可以mkdir创建
wget -c https://nginx.org/download/nginx-1.12.0.tar.gz
我下载的是1.12.0版本,这个是目前的稳定版。
解压
依然是直接命令:
tar -zxvf
解压之后会出现一层新的nginx目录,把这个目录下的东西全部移上来
命令:cp -r nginx/* /usr/local/nginx
配置
其实在 nginx-1.12.0 版本中你就不需要去配置相关东西,默认就可以了。当然,如果你要自己配置目录也是可以的。
1.使用默认配置输入下面三个命令
./configure(是用来检测你的安装平台的目标特征的。比如它会检测你是不是有CC或GCC,并不是需要CC或GCC,它是个shell脚本)
make(是用来编译的,它从Makefile中读取指令,然后编译)
make install(是用来编译安装的,它也从Makefile中读取指令,安装到指定的位置)
2.自定义配置(不推荐)
./configure \
--prefix=/usr/local/nginx \
--conf-path=/usr/local/nginx/conf/nginx.conf \
--pid-path=/usr/local/nginx/conf/nginx.pid \
--lock-path=/var/lock/nginx.lock \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--with-http_gzip_static_module \
--http-client-body-temp-path=/var/temp/nginx/client \
--http-proxy-temp-path=/var/temp/nginx/proxy \
--http-fastcgi-temp-path=/var/temp/nginx/fastcgi \
--http-uwsgi-temp-path=/var/temp/nginx/uwsgi \
--http-scgi-temp-path=/var/temp/nginx/scgi
注:将临时文件目录指定为/var/temp/nginx,需要在/var下创建temp及nginx目录
查找安装路径:
whereis nginx
启动、停止nginx
cd /usr/local/nginx/sbin/
./nginx (直接启动)
./nginx -s stop(直接停止)
./nginx -s quit(完成接受的任务后退出)
./nginx -s reload(重启)
启动时报80端口被占用:
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
解决办法:1、安装net-tool 包:yum install net-tools
./nginx -s quit:此方式停止步骤是待nginx进程处理任务完毕进行停止。
./nginx -s stop:此方式相当于先查出nginx进程id再使用kill命令强制杀掉进程。
3:nginx.config配置详解
Nginx配置示例如下所示:
3.1:全局配置
从配置文件开始到events块之间,主要是设置一些影响nginx服务器整体运行的配置指令,对全局生效。
全局块# 运行用户,默认即是nginx,可以不进行设置
user root;
Nginx 进程数,一般设置为和 CPU 核数一样
worker_processes 8;
Nginx 的错误日志存放目录
error_log logs/error.log;
Nginx 服务启动时的 pid 存放位置
pid logs/nginx.pid;
3.2:events配置
影响Nginx服务器与用户的网络连接
events块events {
# 使用epoll的I/O模型(如果你不知道Nginx该使用哪种轮询方法,会自动选择一个最适合你操作系统的)
use epoll;
#每个进程允许最大并发数
worker_connections 1024;
#是否打开负载均衡互斥锁,默认是off,推荐打开
accept_mutex on;
}
3.3:http模块核心参数
3.3.1:一般配置说明
sendfile on
配置on让sendfile发挥作用,将文件的回写过程交给数据缓冲去去完成,而不是放在应用中完成,这样的话在性能提升有有好处
tcp_nopush on
配置on让nginx在一个数据包中发送所有的头文件,而不是一个一个单独发
tcp_nodelay on
配置on让nginx不要缓存数据,而是一段一段发送,如果数据的传输有实时性的要求的话可以配置它,发送完一小段数据就立刻能得到返回值,但是不要滥用哦
keepalive_timeout
给客户端分配连接超时时间,服务器会在这个时间过后关闭连接。一般设置时间较短,可以让nginx工作持续性更好
client_header_timeout
设置请求头的超时时间
client_body_timeout
设置请求体的超时时间
send_timeout
指定客户端响应超时时间,如果客户端两次操作间隔超过这个时间,服务器就会关闭这个链接
limit_conn addr
给定的key设置最大连接数
server_tokens
虽然不会让nginx执行速度更快,但是可以在错误页面关闭nginx版本提示,对于网站安全性的提升有好处
access_log
设置存储访问记录的日志
error_log
设置存储记录错误发生的日志
open_file_cache
打开缓存的同时也指定了缓存最大数目,以及缓存的时间。我们可以设置一个相对高的最大时间,这样我们可以在它们不活动超过20秒后清除掉。
open_file_cache_valid
在open_file_cache中指定检测正确信息的间隔时间。
open_file_cache_min_uses
定义了open_file_cache中指令参数不活动时间期间里最小的文件数。
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_comp_level 6;
gzip_types text/plain application/javascript text/css application/xml application/json text/javascript image/jpeg image/gif image/png;
gzip_vary on;
#开启或关闭gzip on off
gzip_static on;
3.3.2:server模块
srever 模块配置是http模块中的一个子模块,用来定义一个虚拟访问主机,也就是一个虚拟服务器的配置信息,一个http下面可以配置多个server。
server_name 指定虚拟主机的配置
charset 指定www/路径中配置的默认编码格式
access_log
error_log 指定该虚拟主机的访问日志路径
3.3.3location模块
location模块是Nginx配置中出现最多的一个配置,主要用于配置路由访问信息。
root 于指定访问根目录时,访问虚拟主机的web目录
lndex 在不指定访问具体资源时,默认展示的资源文件列表
try_files 是nginx配置中的一个重要指令,用于按顺序检查指定文件的路径,通常用于处理静态文件请求,实现url重写和改变应用进程的路由机制。
alias 指定静态资源目录位置,它只能写在location中
location中的反斜线/
location /test {....
}
不带/的时候nginx先找是否有test目录,如果有,则找到test目录下的index.html;如果没有则找到test目录,那么nginx则去找是否有test文件。
带/当访问nginx先找是否有test目录,如果有则找test目录下的index.html,如果没有它也不会去找是否存在test文件。
proxy_pass也是nginx配置中一个非常重要的指令,它用于将请求转发到其它的服务器,在location配置中使用proxy_pass可以实现反向代理。
4:upstream部署
upstream配置块是nginx里面的一个非常重要的组成部分,它可以定义一组后端服务器,可以把请求负载均衡地分布给这些服务器,通过upstream配置块,可以轻松的在nginx中实现负载均衡反向代理,对于提高性能、可用性以及实现弹性扩展等场景非常有用。
安装的nginx如果没有下载upstream模块,就算在配置文件中定义了也无法使用,高版本的nginx会直接支持
可进入到nginx的sbin目录下使用./nginx -V查看是否有编译upstream模块
4.1定义upstream
要定义一个upstream,需要在http配置块里面创建一个upstream配置块,为其定义一个名字,这个名字在server配置块中进行引用,在location配置块中,可以使用proxy_pass配置项将请求转发到指定的upstream。
如:
httP{
upstream backend_server {
server 192.168.111.111;
server 192.168.112.112;
}
server {
listen 80;
server_name localhost;
location /api {
proxy_pass http://backend_server;
}
}
}
4.2upstream常用配置
1:Weight
指定轮询几率,weight和访问的几率成正比,用语后端服务器性能不均匀的情况下,默认weight不指定的情况下,各服务器weight相同,如果后端服务器down掉能自动剔除。也可配置需要down掉的服务器。
如:
upstrean backend_server {
server 192.168.111.111 weight = 2;
server 192.168.112.112 weight = 1;
server 192.168.111.113 weight = 1 down; #down掉的服务器不参与分布
}
2:Ip_hash
对客户端请求的ip进行hash操作,然后根据hash结果将同一个客户端ip的请求分发给同一台服务器进行处理,可以解决session不共享的问题,如果后端服务器down掉,要手动down掉。
upstream backend_server {
Ip_hash;
server 192.168.112.112 weight = 2;
server 192.168.111.113 weight = 1 down;
}
3:round_robin
默认的方法,请求按照顺序分发给每一台后端服务器
upstream backend_server {
server 192.168.111.111;
server 192.168.112.112;
}
4:fail
按照后端服务器的响应时间来分配请求,响应时间短的优先分配
upstream backend_server {
server 192.168.111.111;
server 192.168.112.112;
fail;
}
设备的状态有:
1:down:标识当前的server暂时不参与负载
2:weight:权重,默认为1,参数越大负载的权重越大
3:max_fails:允许请求失败的次数,默认为1,当超过最大次数时返回paoxy_next_upatream模块定义错误
4:fail_timeout:max_fails次失败后,暂停的时间,默认10s
5:backup:备用服务器,其他所有非backup机器down或者忙的时候会请求backup服务器,这台服务器一般压力最轻
httP{
upstream backend_server {
Ip_hash;
server 192.168.111.111 weight = 5 max_fails = 3 fail_timeout = 30s;
server 192.168.112.112 weight = 1 max_fails = 3 fail_timeout = 30s;
server 192.168.113.113 weight = 2 max_fails = 3 fail_timeout = 30s backup;
server 192.168.114.114 weight = 1 max_fails = 3 fail_timeout = 30s down;
}
server {
listen 80;
server_name localhost;
location /api {
proxy_pass http://backend_server;
}
}
}
上列服务器中设置最大失败数为3,也就是最多进行3尝试,且超时时间为30s,当有服务器down掉或者其他服务器处理忙的时候会请求192.168.113.113这台服务器。
注意:
1:当upatream中只有一个server时,max_fails和fail_timeout参数不会起作用
2:weight/backup不能和ip_hash关键字一起使用
3:最后在需要使用负载均衡的server中增加proxy_pass http://backend_server/ 一定要对应upstream中定义的名字