使用nginx实现动静分离的负载均衡集群
Nginx官网源码包下载链接:http://nginx.org/en/download.html
官方文档:http://nginx.org/en/docs/
Nginx简介;
-
概述:Nginx是一款由俄罗斯开发的开源的高性能HTTP服务器和反向代理服务器,同时支持IMAP/POP3/SMTP代理服务,其性能优势着为显著,官网上称:单台nginx服务器可以处理50000并发;
-
特点:高性能、稳定、消耗硬件资源小、能够处理大并发,主要用于静态的解析,动静页面的分离;
-
优势:
1.作为Web服务器,nginx处理静态文件、索引文件以及自动索引效率非常高。
2.作为代理服务器,Nginx可以实现无缓存的反向代理加速,提高网站运行速度。
3.作为负载均衡服务器,Nginx既可以在内部直接支持Rails和PHP,也可以支持HTTP代理服务器,对外进行服务。同时支持简单的容错和利用算法进行负载均衡。
-
在性能方面,Nginx在实现上非常注重效率。它采用内核Poll模型,可以支持更多的并发连接,最大可以支持对50 000个并发连接数的响应,而且占用很低的内存资源。
-
在稳定性方面,Nginx采取了分阶段资源分配技术,使得对CPU与内存的占用率非常低。Nginx官方表示Nginx保持10 000个没有活动的连接,这些连接只占2.5M内存,因此,类似DOS这样的攻击对Nginx来说基本上是没有任何作用的。
-
在高可用性方面,Nginx支持热部署,启动速度特别迅速,因此可以在不间断服务的情况下,对软件版本或者配置进行升级,即使运行数月也无需重新启动,几乎可以做到7*24小时的不间断运行。
Nginx实现原理;
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的进程模型:
单工作进程模式:除主进程外,还有一个工作进程,工作进程是单线程的,默认为此模式;
多工作进程模式:每个工作进程包含多个线程;
Nginx master进程:
1.接收外界传递给Nginx的信号,进而管理服务的状态等;
2.管理worker进程,向各worker进程发送信号,监控worker进程的运行状态,当worker进程异常情况下退出后,会自动重新启动新的worker进程;
3.master进程充当整个进程组与用户的交互接口,同时对进程进行监护。它不需要处理网络事件,不负责业务的执行,只会通过管理worker进程来实现重启服务、平滑升级、更换日志文件、配置文件实时生效等功能。
worker进程:
1.处理基本的网络事件,多个worker进程之间是对等的,他们同等竞争来自客户端的请求,各进程互相之间是独立的。一个请求,只可能在一个worker进程中处理,一个worker进程,不可能处理其它进程的请求。worker进程的个数是可以设置的,一般我们会设置与机器cpu核♥数一致;
Nginx支持高并发的原因;
I/O模型之select:
1.每个连接对应一个描述。select模型受限于 FD_SETSIZE(即进程最大打开的描述符数),linux2.6.35为1024,实际上linux每个进程所能打开描数字的个数仅受限于内存大小,然而在设计select的系统调用时,却是参考FD_SETSIZE的值。可通过重新编译内核更改此值,但不能根治此问题,对于百万级的用户连接请求即便增加相应进程数,仍显得杯水车薪;
2、select每次请求都会扫描一个文件描述符的集合,这个集合的大小是作为select第一个参数传入的值。但是每个进程所能打开文件描述符若是增加了,扫描的效率也将减小;
3、内核到用户空间,采用内存复制方式传递信息,这样就增加了不必要的复制延迟;
I/O模型之epoll模型:
1.请求无文件描述字大小限制,仅与内存大小相关;
2.epoll返回时已经明确的知道哪个socket fd发生了什么事件,不用像select那样再一个个比对;
3.内核到用户空间,采用共享内存方式传递消息,使用mmap加速内核与用户空间的消息传递;
apache:Apache 2.2.9之前只支持select模型,2.2.9之后支持epoll模型;
Nginx:支持epoll模型;
LB负载均衡集群分两类: LVS (四层)和 nginx或haproxy (七层)
客户端通过访问分发器的VIP来访问网站
|
现在应用更复杂,比如现在网站页面有: .php .html .png .jpeg .jsp 等, 有动态页面有静态页面。静态页面一般是不变的,想访问更快些,前面学习过SQUID。
|
但是前面的LVS是四层的。基于IP的。现在需要在应用层基于不同的应用进行分发。
|
七层LB , Nginx / Haproxy都可以支持7层LB
理想的效果是这样:
静态文件处理:可以使用nginx 或apache
动文件处理: apache ,tomcat
图片文件处理: squid
使用nginx实现动静分离的负载均衡集群
Nginx 负载均衡基础知识
Nginx 的 upstream 负载的5种方式,目前最常用 前3 种方式
-
1)、轮询(默认)
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器 down 掉,能自动剔除。
-
2)、weight
指定轮询几率,weight 和访问比率成正比,用于后端服务器性能不均的情况。
-
3)、ip_hash
每个请求按访问 ip 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决 session 的问题。
-
4)、fair(第三方)
按后端服务器的响应时间来分配请求,响应时间短的优先分配。
- 5)、url_hash(第三方) url哈西
按访问url的hash结果来分配请求,使同样的url定向到同一个后端服务器,后端服务器为缓存时比较有效
正向代理和反向代理
反向代理,外部机器通过网关访问网关后面服务器上的内容,网关起到了反向代理的功能,我们平时通过浏览器访问远程的web服务器大都是这样实现的。
正向代理,就是上面的过程反过来,我们平时说的代理上网,局域网中的用户通过网关做代理访问外部的网络。
使用nginx实现负载均衡和动静分离
- 源码编译安装nginx
一、安装nginx时必须先安装相应的编译工具和相关依赖
[root@harry63 ~]# yum -y install gcc gcc-c++ autoconf automake
[root@harry63 ~]# yum -y install zlib zlib-devel openssl openssl-devel pcre pcre-devel
zlib:nginx提供gzip模块,需要zlib库支持
openssl:nginx提供ssl功能
pcre:支持地址重写rewrite功能
- 安装nginx:
[root@harry63 ~]# ll nginx-1.8.0.tar.gz -h #整个nginx文件不到只813K,很小
-rw-r--r-- 1 root root 813K Jul 14 20:17 nginx-1.8.0.tar.gz
[root@harry63 ~]# tar -zxvf nginx-1.8.0.tar.gz -C /usr/local/src/
[root@harry63 ~]# cd /usr/local/src/nginx-1.8.0/
[root@harry63 ~]# ./configure --prefix=/usr/local/nginx --with-http_dav_module --with-http_stub_status_module --with-http_addition_module --with-http_sub_module --with-http_flv_module --with-http_mp4_module
##查看参数:
[root@harry63 nginx-1.8.0]# ./configure --help | grep mp4
- 参数说明:
--with-http_dav_module 启用ngx_http_dav_module支持(增加PUT,DELETE,MKCOL:创建集合,COPY和MOVE方法)默认情况下为关闭,需编译开启
--with-http_stub_status_module启用ngx_http_stub_status_module支持(获取nginx自上次启动以来的工作状态)
--with-http_addition_module 启用ngx_http_addition_module支持(作为一个输出过滤器,支持不完全缓冲,分部分响应请求)
--with-http_sub_module 启用ngx_http_sub_module支持(允许用一些其他文本替换nginx响应中的一些文本)
--with-http_flv_module 启用ngx_http_flv_module支持(提供寻求内存使用基于时间的偏移量文件)
--with-http_mp4_module 启用对mp4文件支持(提供寻求内存使用基于时间的偏移量文件)
- 编译和安装: (查看CPU逻辑数cat /proc/cpuinfo | grep processor | wc -l)
[root@harry63 ~]#make -j 4
[root@harry63 ~]#make install
- 生成运行nginx的用户:
[root@harry63 nginx-1.8.0]# useradd -u 8000 -s /sbin/nologin nginx
[root@harry63 nginx-1.8.0]# id !$
id nginx
uid=8000(nginx) gid=8000(nginx) groups=8000(nginx)
- nginx主要目录结构说明:
[root@harry63 /]# ls /server/nginx-1.8.0/
conf html logs sbin
conf #配置文件
conf #配置文件
html #网站根目录
logs #日志
sbin #nginx启动脚本
- 主配置文件:
[root@harry63 /]# ls /server/nginx-1.8.0/conf/nginx.conf
- 启动nginx:
[root@harry63 /]# /server/nginx-1.8.0/sbin/nginx
[root@harry63 /]# netstat -antup | grep :80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 5281/httpd
[root@harry63 /]# netstat -antup | grep :80
- 开机启动:
[root@harry63 nginx-1.8.0]# echo '/server/nginx-1.8.0/sbin/nginx & ' >> /etc/rc.local
测试在浏览器访问:
nginx服务日常操作:
- 测试配置文件语法:
[root@harry63 nginx-1.8.0]# /server/nginx-1.8.0/sbin/nginx -t
nginx: the configuration file /server/nginx-1.8.0/conf/nginx.confsyntax is ok
nginx: configuration file /server/nginx-1.8.0/conf/nginx.conf test is successful
- 重新加载配置文件
[root@harry63 nginx-1.8.0]# /server/nginx-1.8.0/sbin/nginx -s reload
- 关闭nginx
[root@harry63 /]# /server/nginx-1.8.0/sbin/nginx -s stop
[root@harry63 /]# /server/nginx-1.8.0/sbin/nginx -s start #没有start参数
nginx: invalid option: "-s start"
配置nginx成为分发器,实现动静分离
[root@harry63 conf]# cd /server/nginx-1.8.0/conf #配置文件目录
[root@harry63 conf]# cp nginx.conf nginx.conf.back #备份一下配置文件
[root@harry63 conf]# vim nginx.conf
[root@harry63 nginx-1.8.0]# vim /server/nginx-1.8.0/conf/nginx.conf #指定启动nginx用户
改:# user nobody;
为:user nginx nginx;
改:
location / {
root html;
index index.html index.htm; #在location / { 。。。} 中添加以下内容 #定义分发策略
location / {
root html;
index index.html index.htm;
if ($request_uri ~* .html$){
proxy_pass http://htmlservers;
}
if ($request_uri ~* .php$){
proxy_pass http://phpservers;
}
proxy_pass http://picservers;
}
把以下内容注释掉,否则php文件直接在nginx服务器上解析了,不再解析给后端服务器:
location ~ .php$ {
73 # root html;
74 # fastcgi_pass 127.0.0.1:9000;
75 # fastcgi_index index.php;
76 # fastcgi_param SCRIPT_FILENAME /server/nginx-1.8.0/html$fastcgi_script_name;
77 # include fastcgi_params;
78 # }
- 定义负载均衡设备的 Ip
在配置文件nginx.conf的最后一行}前,添加以下内容:
upstream htmlservers { #定义负载均衡服务器组名称
server 192.168.1.62:80;
server 192.168.1.64:80;
}
upstream phpservers{
server 192.168.1.62:80;
server 192.168.1.64:80;
}
upstream picservers {
server 192.168.1.62:80;
server 192.168.1.64:80;
}
后期可根据需要,配置成具体业务的IP地址
wq保存退出。
- 重新加载nginx服务器配置文件:
[root@harry63 conf]# /server/nginx-1.8.0/sbin/nginx -t
nginx: the configuration file /server/nginx-1.8.0/conf/nginx.conf syntax is ok
nginx: configuration file /server/nginx-1.8.0/conf/nginx.conf test is successful
[root@harry63 conf]# /server/nginx-1.8.0/sbin/nginx -s reload
- 配置web服务器:
[root@harry62 html]# yum install httpd php -y
- 生成静态测试文件:
[root@harry62 html]#echo 192.168.1.62 > /var/www/html/index.html
- 生成动态测试文件:
[root@harry62 html]#vim /var/www/html/test.php #写如以下内容:
192.168.1.62-php
<?php
phpinfo();
?>
- 生成图片文件:
上传如下图片,到“Rich七哥62网站/var/www/html/目录下:
- 启动apache服务器:
[root@harry62 html]# service httpd restart
- 配置后端服务器: Rich七哥64
IP: 192.168.1.64
- 配置web服务器:
[root@harry64 html]# yum install httpd php -y
- 生成静态测试文件:
echo 192.168.1.64 > /var/www/html/index.html
- 生成动态测试文件:
vim /var/www/html/test.php #写如以下内容:
192.168.1.64-php
<?php
phpinfo();
?>
生成图片文件:
上传图片,到“Rich七哥64网站/var/www/html/目录下:
[root@harry64 html]# service httpd restart
到此nginx实现负载均衡结束。
测试负载均衡
测试转发静态页面:
测试转发动态页面:
测试转发图片:
测试自动剔除坏的节点:
[root@harry64 html]# service httpd stop
Stopping httpd: [ OK ]
访问:
都访问到:
测试性能:
扩展: 文件打开数过多
[root@harry64 html]# ab -n 1000 -c 1000 http://192.168.1.62/index.html #运行正常
[root@harry64 html]# ab -n 2000 -c 2000 http://192.168.1.62/index.html #报错
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 192.168.1.62 (be patient)
socket: Too many open files (24) # 测试时,一次打开的socket文件太多。
ulimit -a #查看
ulimit -n
1024
系统默认一个进程最多同时允许打开1024的文件
解决:
ulimit -n 10240 #报错的解决方法
Nginx负载的5种策略设置方法(在nginx配置文件里添加):
1、轮询(默认)
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。
upstream backserver {
server 192.168.1.62;
server 192.168.1.64;
}
2、指定权重
指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。
upstream backserver {
server 192.168.1.62 weight=1;
server 192.168.1.64 weight=2;
}
3、IP绑定 ip_hash
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
upstream backserver {
ip_hash;
server 192.168.1.62:80;
server 192.168.1.64:80;
}
4、fair(第三方)
按后端服务器的响应时间来分配请求,响应时间短的优先分配。
upstream backserver {
server server1;
server server2;
fair;
}
5、url_hash(第三方)
按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。
upstream backserver {
server squid1:3128;
server squid2:3128;
hash $request_uri;
hash_method crc32;
}
总结,扩展:
如有tomcat ,apache,squid 配置为如下:
[root@harry63 conf]# vim nginx.conf # 在最后添加以下内容。 定义Rich七哥服务器组
upstream tomcat_servers {
server 192.168.1.2:8080;
server 192.168.1.1:8080;
server 192.168.1.11:8080;
}
upstream apache_servers {
server 192.168.1.5:80;
server 192.168.1.177:80;
server 192.168.1.15:80;
}
upstream squid_servers {
server 192.168.1.26:3128;
server 192.168.1.55:3128;
server 192.168.1.18:3128;
}