1、传统web访问模型
(1)传统web访问模型完成一次请求的步骤
(2)传统模型缺点
(3)传统模型优化——单点故障解决方案
优化方案一:部署一台备份服务器,宕机直接切换该方案可以有效解决服务器故障导致的单点故障,但且服务器利用率低、成本高,切换不及时,且无法解决服务器业务压力问题。
优化方案二:部署多台服务器,根据DNS的轮询解析机制去实现用户分发
优势是用户处理速度得到了提升,但是当其中一台故障,dns并不会知道它故障了,依然将请求分给这个服务器,导致一部分用户访问不了业务。
2、并行处理解决方案
3、集群
组成要素:
4、Nginx集群原理
功能模块:
1)ngx_http_upstream_module:基于应用层(七层)分发模块
2)ngx_stream_core_module:基于传输层(四层)分发模块(1.9开始提供该功能)
(1)Nginx集群的实质
(2)数据走向(请求处理流程)
1、环境准备
![在这里插入图片描述](https://img-blog.csdnimg.cn/20201226222701154.png#pic_center
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
为了答谢大家关注和支持,这次给大家准备了限时领取福利:阿里面试题、百度面试题、滴滴面试题、华为面试题、京东面试题、美团面试题、腾讯面试题、头条面试题、中兴面试题。
还等什么小编推荐自己的linuxC/C++语言交流群:【1106675687】整理了一些个人觉得比较好的学习书籍、视频资料共享在群文件里面,有需要的可以自行添加哦!前100名进群领取,额外赠送一份价值199的C/C++、linux资料包含(视频教程、电子书、实战项目及代码),下面部分展示。
集群分发算法:如何将用户请求按照一定的规律分发给业务服务器。主要分为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集群默认算法测试
集群环境与之前完全相同。
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
前面的分发方式都是基于一个集群分发的,而基于请求头分发一般都是用于多集群分发的。
浏览器开发者工具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 "" > /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模块
(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;
}
}