一、集群介绍

1、传统web访问模型

(1)传统web访问模型完成一次请求的步骤

1)用户发起请求

2)服务器接受请求

3)服务器处理请求(压力最大)

4)服务器响应请求

(2)传统模型缺点

单点故障;

单台服务器资源有限(客户端则是无限的);

单台服务器处理耗时长(客户等待时间过长);

(3)传统模型优化——单点故障解决方案

  • 优化方案一:部署一台备份服务器,宕机直接切换

    该方案可以有效解决服务器故障导致的单点故障,但且服务器利用率低、成本高,切换不及时,且无法解决服务器业务压力问题。
  • 优化方案二:部署多台服务器,根据DNS的轮询解析机制去实现用户分发

    优势是用户处理速度得到了提升,但是当其中一台故障,dns并不会知道它故障了,依然将请求分给这个服务器,导致一部分用户访问不了业务。

2、并行处理解决方案

1)DNS轮询解析方案

2)多机阵列——集群模式

图中,前面两台服务器负责接受请求和分发请求,它自己并不处理请求,将请求分发给后面的业务服务器来处理。业务服务器处理完请求后,将请求发还给分发器,再由分发器将请求发送给客户,因此分发器还承担了响应请求的任务。

  由此可见之前传统模型中服务器端需要承担的服务器接收请求和响应请求都交给分发器处理了,而业务压力最大的处理请求则交给业务服务器完成。

  分发器和dns虽然都是进行了分发的工作,但不同点在于分发器是自己部署的服务器,而DNS都是使用的运营商的,因此可以调整分发器的逻辑判断规则。

3、集群

  • 计算机集群简称集群,是一种计算机系统, 它通过一组松散集成的计算机软件或硬件连接起来高度紧密地协作完成计算工作。在某种意义上,他们可以被看作是一台计算机。 (百度解释)
  • 将多个物理机器组成一个逻辑计算机,实现负载均衡和容错。

组成要素:

  1)VIP: 给分发器的一个虚IP

  2)分发器:nginx

  3)数据服务器:web服务器

4、Nginx集群原理

在Nginx集群中Nginx扮演的角色是:分发器。

  任务:接受请求、分发请求、响应请求。

  功能模块:

    1)ngx_http_upstream_module:基于应用层(七层)分发模块

    2)ngx_stream_core_module:基于传输层(四层)分发模块(1.9开始提供该功能)

(1)Nginx集群的实质

Nginx集群其实是:虚拟主机+反向代理+upstream分发模块组成的。

  虚拟主机:负责接受和响应请求。

  反向代理:带领用户去数据服务器拿数据。

  upstream:告诉nginx去哪个数据服务器拿数据。

(2)数据走向(请求处理流程)

1)虚拟主机接受用户请求

  2)虚拟主机去找反向代理(问反向代理去哪拿数据)

  3)反向代理让去找upstream

  4)upstream告诉一个数据服务器IP

  5)Nginx去找数据服务器,并发起用户的请求

  6)数据服务器接受请求并处理请求

  7)数据服务器响应请求给Nginx

  8)Nginx响应请求给用户

二、使用Nginx分发器构建一个WEB集群

1、环境准备

实验机 : Vmware 虚拟机 2核4G

  网卡:桥接

  系统:centos7.5

  防火墙:关闭

  Selinux:关闭

  网段:192.168.31.0/24

  准备四台实验机:都安装nginx服务,两台当作分发器,两台当作web服务器。

主机名 IP 角色
Master.ayitula.com 192.168.31.40 主分发器
Backup.ayitula.com 192.168.31.41 备分发器
Web01.ayitula.com 192.168.31.42 数据服务器1
Web02.ayitula.com 192.168.31.43 数据服务器2

2、配置web业务机器

(1)nginx安装脚本

#!/bin/bash

nginx_pkg='nginx-1.5.1.tar.gz'
nginx_prefix=/usr/local/nginx
html=/var/nginx
log=/var/log/nginx check13 () {
[ $UID -ne 0 ] && echo "need to be root to that" && exit 1
[ ! -f $nginx_pkg ] && echo "not found source packager" && exit 1
[ ! -d $html ] && mkdir -p $html
[ ! -d $log ] && mkdir -p $log
} nginx_install () {
source_pkg=`echo $nginx_pkg|awk -F ".tar" '{print $1}'`
[ -d /usr/src/$source_pkg ]&&rm -rf /usr/src/$source_pkg
tar xf $nginx_pkg -C /usr/src
cp nginxd /usr/src/$source_pkg
if [ $? -eq 0 ];then
cd /usr/src/$source_pkg
if [ $? -eq 0 ];then
yum -y install gcc-* pcre pcre-devel zlib zlib-devel openssl-* &> /dev/null
[ $? -ne 0 ]&&"YUM set error" && exit 1
./configure --prefix=$nginx_prefix
if [ $? -eq 0 ];then
make
if [ $? -eq 0 ];then
make install
if [ $? -eq 0 ];then
ln -s -f $nginx_prefix/conf/nginx.conf /etc/
ln -s -f $nginx_prefix/logs/ $log/logs
ln -s -f $nginx_prefix/html $html/html
ln -s -f $nginx_prefix/sbin/ /usr/sbin/
cp nginxd /etc/init.d/nginx;chmod 755 /etc/init.d/nginx
else
exit 1
fi
else
exit 1
fi
else
exit 1
fi
else
exit 1
fi
else
exit 1
fi
[ $? -eq 0 ]&&clear||exit
echo -e "\n\033[32m Nginx Install Success: \033[0m"
echo -e "\n"
echo -e "\tNginx_conf: /etc/nginx.conf"
echo -e "\tNginx_html: $html/html"
echo -e "\tNginx_access_log: $log/logs/access.log"
echo -e "\tNginx_error_log: $log/logs/error.log\n\n\n\n"
read -n1 -p "press any key and exit...."
echo
} check13
nginx_install

(2)配置web服务器操作

[root@web02 ~]# sh nginx_install     # 脚本安装nginx
[root@web02 ~]# echo web02 > /usr/local/nginx/html/index.html # 写入页面
[root@web02 ~]# yum -y install elinks &>/dev/null # 安装文本浏览器
[root@web02 ~]# /usr/local/nginx/sbin/nginx # 启动nginx
[root@web02 ~]# elinks http://localhost -dump
web02

3、配置分发器(轮询方式分发)

# 清除空行和注释项
$ sed -i '/#/d' nginx.conf
$ sed -i '/^$/d' nginx.conf # 配置nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
upstream web{ # 名为web的反向代理群组
server 192.168.31.42;
server 192.168.31.43;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://web; # 去找反向代理
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}

4、集群分发测试(默认轮询)

客户端访问分发器地址,默认按照轮询的方式来进行分发。

[root@web02 ~]# elinks http://192.168.31.40 -dump
web01
[root@web02 ~]# elinks http://192.168.31.40 -dump
web02
[root@web02 ~]# elinks http://192.168.31.40 -dump
web01
[root@web02 ~]# elinks http://192.168.31.40 -dump
web02

三、Nginx分发算法

集群分发算法:如何将用户请求按照一定的规律分发给业务服务器。主要分为Nginx集群默认算法和基于请求头分发算法。

1、Nginx集群默认算法

upstream module

  nginx的upstream 目前支持4种方式的分配

(1)轮询(默认)

  每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。

(2)weight

  指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。

(3)ip_hash

  每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务,好处是可以解决session的问题。

  因此前两种只能处理静态页面,而这种方式可以处理动态网站。

(4)fair(第三方)

  按后端服务器的响应时间来分配请求,响应时间短的优先分配。

(5)url_hash(第三方)

  按访问url的hash结果来分配请求,使每个url定向到同一个后端服务 ,后端服务器为缓存时比较有效。

2、Nginx业务服务器状态

每个设备的状态设置参数:

  • down

    表示当前的server暂时不参与负载;
  • weight

    默认为1,weight越大,负载的权重就越大;
  • max_fails

    允许请求失败的次数默认为1,当超过最大次数时,返回proxy_next_upstream模块定义的错误;
  • fail_timeout

    失败超时时间,在连接Server时,如果在超时时间之内超过max_fails指定的失败次数,会认为在fail_timeout时间内Server不可用,默认为10s
  • backup

    其他所有的非backup机器down或者忙的时候,请求backup机器。所以这台机器压力会最轻。

3、Nginx集群默认算法测试

集群环境与之前完全相同。

主机名 IP 角色 系统 配置
Master.ayitula.com 192.168.31.40 主分发器 centos7.5 2核4G
Backup.ayitula.com 192.168.31.41 备分发器 centos7.5 2核4G
Web01.ayitula.com 192.168.31.42 数据服务器1 centos7.5 2核4G
Web02.ayitula.com 192.168.31.43 数据服务器2 centos7.5 2核4G

(1)轮询算法分发

upstream web {
server 192.168.31.42;
server 192.168.31.43;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://web;
}
}

前面已经测试验证了轮询算法分发。配置backup参数如下所示:

upstream web {
server 192.168.31.42 weight=1;
server 192.168.31.43 weight=1 backup;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://web;
}
}

关停第一个节点情况,访问尝试:

[root@web02 ~]# elinks http://192.168.31.40 -dump
web02
[root@web02 ~]# elinks http://192.168.31.40 -dump
web02
[root@web02 ~]# elinks http://192.168.31.40 -dump
web02

(2)基于权重的分发

upstream web {
# 设置权重比例1:2
server 192.168.31.42 weight=1;
server 192.168.31.43 weight=2;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://web;
}
}

访问测试验证:

[root@web02 ~]# elinks http://192.168.31.40 -dump
web01
[root@web02 ~]# elinks http://192.168.31.40 -dump
web02
[root@web02 ~]# elinks http://192.168.31.40 -dump
web02
[root@web02 ~]# elinks http://192.168.31.40 -dump
web01
[root@web02 ~]# elinks http://192.168.31.40 -dump
web02
[root@web02 ~]# elinks http://192.168.31.40 -dump
web02

通过权重比例的分配,可以让性能更强的服务器承担处理更多的请求。

(3)基于ip_hash分发

ip_hash算法能够保证来自同样源地址的请求都分发到同一台主机。

  需要注意:ip_hash算法不支持backup、weight设置。默认权重为1。

upstream web {
ip_hash; # 指定ip_hash即可,默认weight权重比例1: 1
server 192.168.31.42;
server 192.168.31.43;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://web;
}
}

访问测试验证:

# 源ip固定
[root@web01 ~]# elinks http://192.168.31.40 -dump
web02
[root@web01 ~]# elinks http://192.168.31.40 -dump
web02
[root@web01 ~]# elinks http://192.168.31.40 -dump
web02
MacBook-Pro:~ hqs$ elinks http://192.168.31.40 -dump
web01
MacBook-Pro:~ hqs$ elinks http://192.168.31.40 -dump
web01
MacBook-Pro:~ hqs$ elinks http://192.168.31.40 -dump
web01

四、Nginx基于请求头的分发

前面的分发方式都是基于一个集群分发的,而基于请求头分发一般都是用于多集群分发的。

  浏览器开发者工具network工具下,获取请求的请求头信息如下所示:

Request URL: http://192.168.31.43/     # 请求的URL
Request Method: GET # 请求的方法
Status Code: 200 OK
Remote Address: 192.168.31.43:80
Referrer Policy: no-referrer-when-downgrade # 请求的策略 Response headers # 响应头
Accept-Ranges: bytes
Connection: keep-alive
Content-Length: 6
Content-Type: text/html
Date: Fri, 26 Oct 2018 12:43:02 GMT
ETag: "5bd3014d-6"
Last-Modified: Fri, 26 Oct 2018 11:58:05 GMT
Server: nginx/1.15.5 Request Headers # 请求头
GET /index.php HTTP/1.1 # 请求方法是GET;域名后面的部分就是路径,默认是‘/’;使用的HTTP协议是1.1
Host: 192.168.31.43 # 访问的域名(域名或IP均可)
Connection: keep-alive # 长连接
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36 # 用户浏览器的类型
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 # 可以接受的数据类型
Accept-Encoding: gzip, deflate # 压缩
Accept-Language: zh-CN,zh;q=0.9 # 语言

1、基于host分发

基于host分发这种分发方式适用于多集群分发。例如:一个公司有多个网站,每个网站就是一个集群。

http {
upstream web1 { # 名为web1的反向代理群组
server 192.168.31.42;
server 192.168.31.52;
}
upstream web2 { # 名为web2的反向代理群组
server 192.168.31.43;
server 192.168.31.53;
}
server { # web1虚拟主机
listen 80;
server_name www.web1.com; # 基于域名分发必须有域名
location / {
proxy_pass http://web1;
}
}
server { # web2虚拟主机
listen 80;
server_name www.web2.com; # 基于域名分发必须有域名
location / {
proxy_pass http://web2;
}
}
}

基于域名的分发测试:

[root@web02 ~]# elinks http://www.web1.com -dump
web01
[root@web02 ~]# elinks http://www.web1.com -dump
web01
[root@web02 ~]# elinks http://www.web1.com -dump
web01
[root@web02 ~]# elinks http://www.web2.com -dump
web02
[root@web02 ~]# elinks http://www.web2.com -dump
web02
[root@web02 ~]# elinks http://www.web2.com -dump
web02

2、基于开发语言分发

这种分发方式适用于混合开发的网站,某些大型网站既有php也有jsp,就可以基于开发语言分发。

# 192.168.31.40分发器上nginx配置
http {
upstream php {
server 192.168.31.42;
}
upstream html {
server 192.168.31.43;
}
server {
location ~* \.php$ { # 以php结尾的
proxy_pass http://php;
}
location ~* \.html$ { # 以html结尾的
proxy_pass http://html;
}
}
}

测试验证:

# 安装php环境
$ yum install httpd php # 安装apache和php
# 启动apache,自带php
$ systemctl start httpd
# 编写php文件
$ echo "<?php phpinfo(); ?>" > /var/www/html/index.php
# 访问192.168.31.40/index.php 可以看到php-info信息页面
# 访问192.168.31.40/index.html 可以看到web02

3、基于浏览器的分发

这种基于浏览器的分发,常应用于PC端和移动端区分或浏览器适配。

(1)由于没有第三个机器,在42这台业务服务器上,启动一个虚拟主机。

$ vim /usr/local/nginx/conf/nginx.conf
http {
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
}
server {
listen 81;
server_name localhost;
location / {
root web3;
index index.html index.htm
}
}
}
$ mkdir /usr/local/nginx/web3
$ echo web03 > /usr/local/nginx/web3/index.html
$ /user/local/nginx/sbin/nginx

(2)基于浏览器分发的分发器配置

upstream elinks { server 192.168.31.42; }
upstream chrome { server 192.168.31.43; }
upstream any { server 192.168.31.42:81; }
server {
listen 80;
server_name www.web1.com;
location / {
proxy_pass http://any;
if ( $http_user_agent ~* Elinks ) {
proxy_pass http://elinks;
}
if ( $http_user_agent ~* chrome ) {
proxy_pass http://chrome;
}
}
}

(3)访问测试

任何机器访问,只要是使用elinks访问的都将访问web01;只要使用chrome浏览器访问都将访问web02;而使用firefox或者safari则将访问web03.

4、基于源IP分发

像腾讯新闻、58同城等等网站,往往在什么地方登陆则获取哪个地方的数据。服务器通过源IP匹配判断,从对应的数据库中获取数据。

(1)geo模块

Nginx的geo模块不仅可以有限速白名单的作用,还可以做全局负载均衡,可以要根据客户端ip访问到不同的server。

  geo指令是通过ngx_http_geo_module模块提供的。默认情况下,nginx安装时是会自动加载这个模块,除非安装时人为的手动添加--without-http_geo_module。

  ngx_http_geo_module模块可以用来创建变量,其值依赖于客户端IP地址。

(2)基于源IP分发配置

upstream bj.server {
server 192.168.31.42; # web01
}
upstream sh.server {
server 192.168.31.43; # web02
}
upstream default.server {
server 192.168.31.42:81; # web03
}
geo $geo { # IP库
default default;
192.168.31.241/32 bj; # 北京
192.168.31.242/32 sh; # 上海
}
server {
listen 80;
server_name www.web1.com; location / {
proxy_pass http://$geo.server$request_uri;
}
}

五、算法特性(应用场景)总结

Nginx集群(负载均衡)的更多相关文章

  1. 图文解说:Nginx+tomcat配置集群负载均衡

    图文解说:Nginx+tomcat配置集群负载均衡 博客分类: appserver nginxTomcatUbuntuLinux网络应用  作者:niumd Blog:http://ari.iteye ...

  2. 转】Nginx+tomcat配置集群负载均衡

    原博文出自于:http://blog.csdn.net/bruce_6/article/details/38228299         感谢! 相信很多人都听过nginx,这个小巧的东西慢慢地在吞食 ...

  3. 【nginx+tomcat集群】Nginx1.12.2+Tomcat7集群+负载均衡+Session共享

    今天想着将项目优化一下,就想的实现集群分布,在本机测试:利用nginx+tomcat实现 通过上一篇博客(http://www.cnblogs.com/qlqwjy/p/8535235.html),N ...

  4. .net core 跨平台开发 微服务架构 基于Nginx反向代理 服务集群负载均衡

    1.概述 反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客 ...

  5. 【Nginx(三)】Nginx配置集群 负载均衡策略

    Nginx配置集群 负载均衡策略 一.安装环境 1.安装JDK8的环境,配置JDK8的环境变量 2.上传jar包demo-1.jar 和 demo-2.jar demo-1.jar 监听8080端口; ...

  6. ngnix apache tomcat集群负载均衡配置

    http://w.gdu.me/wiki/Java/tomcat_cluster.html 参考: Tomcat与Apache或Nginx的集群负载均衡设置: http://huangrs.blog. ...

  7. lunix 集群,负载均衡,location

       nginx location语法: location支持的语法优先级: 复制代码location匹配顺序 #  www.s14hanju.com/1.location = / {  我是代码1} ...

  8. 运维小知识之nginx---nginx配置Jboss集群负载均衡

      codyl 2016-01-26 00:53:00 浏览385 评论0 负载均衡 转自 运维小知识之nginx---nginx配置Jboss集群负载均衡-博客-云栖社区-阿里云https://yq ...

  9. Apache+Tomcat +mod_proxy集群负载均衡及session

      序言: 在玩Apache+Tomcat +mod_jk集群负载均衡及session的时候发现,还有一种方式可以实现,就是网上各位大牛们说的mod_proxy反向代理. 实在弄的我的知识细胞洋洋.实 ...

  10. Apache + Tomcat集群 + 负载均衡

    Part I: 取经处: http://www.ramkitech.com/2012/10/tomcat-clustering-series-simple-load.html  http://blog ...

随机推荐

  1. 在Windows上搭建Git Server (2)

      第一步:下载Java,下载地址:http://www.java.com/zh_CN/ 第二步:安装Java.安装步骤不再详述. 第三步:配置Java环境变量. 右键”计算机” => ”属性” ...

  2. linux 下PATH环境变量

    环境变量简介 什么是环境变量呢?简要的说,就是指定一个目录,运行软件的时候,相关的程序将会按照该目录寻找相关文件. 在linux系统下,如果你下载并安装了应用程序,很有可能在键入它的名称时出现&quo ...

  3. celery实现异步任务

    celery==3.1.25 rabbitmq开启服务 tasks.py代码如下: from celery import Celery broker = 'amqp://guest:guest@loc ...

  4. quill 设置 初始值...

    1down voteaccepted For your first issue change this: text.value = JSON.stringify(quill.root.innerHTM ...

  5. P1353_[USACO08JAN]跑步Running 我死了。。。

    我死了...被绿题虐...看来我的水平有待提高...QWQ 好吧,就是跑步的时候只能从跑步的状态转移过来 休息的时候可以从上一次休息时转移过来,也可以从某次跑步的时转移过来,需要枚举从哪一个状态转移来 ...

  6. linux安装PHP7以及扩展

    Linux下安装PHP7 事先升级gcc4.8,然后安装PHP7,安装步骤参考:CentOS安装PHP7 1.Linux下编译的php没有php.ini 解决办法:从源代码目录中复制php.ini-d ...

  7. win10 安装MySQL8.0.11记录。

    参考了博客A:https://blog.csdn.net/m0_37788308/article/details/79965378 博客B:https://blog.csdn.net/fxbin123 ...

  8. 【记录】adb连不上手机

    1.\用户\.android文件夹下新建adb_usb.ini,内容为手机的VID值,如0x9BB5 2.重启adb adb kill-server adb start-server adb devi ...

  9. jar 启动关闭

    1.后台启动 startTest.sh #设置工程路径project_path=/root/testcd $project_path#nohup后台启动,输出日志到test.lognohup java ...

  10. <a>标签深入讲解

    标签中 href 和 onclick 的区别,以及href="javascript:xxx(this);"与onclick="xxx(this);" 传递thi ...