nginx 集群介绍
完成一次请求的步骤
1)用户发起请求
2)服务器接受请求
3)服务器处理请求(压力最大)
4)服务器响应请求
缺点:单点故障
单台服务器资源有限
单台服务器处理耗时长
·1)部署一台备份服务器,宕机直接切换
·2)部署多台服务器,根据DNS的轮询解析机制去实现用户分发
问题:
1方案:服务器利用率低,成本高,切换不及时,服务器压力依然大
2方案:优势是用户处理速度得到了提升,但是当其中一台故障,就会有一部分用户访问不了网站
·将多个物理机器组成一个逻辑计算机,实现负载均衡和容错
计算机集群简称集群,是一种计算机系统,它通过一组松散集成的计算机软件或硬件连接起来高度紧密地协作完成计算工作。在某种意义上,他们可以被看作是一台计算机。
组成要素
1)VIP:一个IP地址
2)分发器(负载均衡):nginx
3)数据服务器:Web服务器
在该集群中间两台Nginx扮演的角色是:分发器
任务:接受请求、分发请求、响应请求
功能模块:
1)ngx_http_upstream_module 基于应用层分发模块
2)ngx_stream_core_module 基于传输层分发模块(1.9开始提供)
Nginx集群原理
Nginx集群其实是:虚拟主机+反向代理+upstream分发模块组成的
虚拟主机:接受和响应请求
反向代理:带用户去数据服务器拿数据
upstream:告诉Nginx去哪个数据服务器拿数据
数据走向
1)虚拟主机接受用户请求
2)虚拟主机去找反向代理
3)反向代理让去找upstream
4)upstream 告诉一个数据服务器IP
5)Nginx去找数据服务器并发起用户的请求
6)数据服务器接受请求并处理请求
7)数据服务器响应请求给Nginx
8)Nginx响应请求给用户
防火墙:关闭
Selinux:关闭
网段:192.168.10.0/24
主机名 IP 角色
配置一个web集群
1)Nginx安装
2)配置业务服务器页面
3)配置Nginx分发器
4)测试分发
配置web业务机器
#web02
troot@web02~]# sh nginx_install
troot@web02~]# echo web02>/usr/local/nginx/html/index.html
troot@web02~]# yum -y install elinks &>/dev/null
troot@web02~]#/usr/local/nginx/sbin/nginx
[rootaweb02~l# elinks http:/ocalhost-dump
web02
集群实现
配置分发器
Syntax:upstream name{.…)
Dofault:-
Context:http
upstream web{ server 192.168.10.42; server 192.168.10.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; } }
#upstream模块
[root@web02~]# elinks http://192.168.10.40-dump
web01
[root@web02~]# elinks http://192.168.10.40-dump
web02
[root@web02~]# elinks http://192.168.10.40-dump
web01
[root@web02~]# elinks http:/192.168.10.40-dump
web02
集群分发测试
利用 nginx 本身的 upstream 模块能够实现负载均衡的分发工作,但如果分发器宕机了,就坏了,所以需要,主备多台分发器来保证负载均衡的高可用性。就是分发器也得有人看着,哪一个坏了就自动切换。
利用后面的 keepalived 软件软件能够实现。
Nginx 分发算法
集群分发算法介绍
分发算法
如何将用户请求按照一定的规律分发给业务服务器
思考
假如你有1000块钱,你怎么分配给身边的3个好朋友呢?
Nginx集群默认算法
upstream module
nginx的upstream目前支持4种方式的分配
1、轮询(默认)
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。
2、weight
指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。
3、ip_hash
动态请求
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
4、fair(第三方)
按后端服务器的响应时间来分配请求,响应时间短的优先分配。
5、url_hash(第三方)
按访问url的hash结果来分配请求,使每个ul定向到同一个后端服务器,后端服务器为缓存时比较有效。
Nginx业务服务器状态
每个设备的状态设置为:
1.down 表示单前的server暂时不参与负载
2.weight 默认为1 weight越大,负载的权重就越大。
3.max_fails:允许请求失败的次数默认为1,当超过最大次数时,返回proxynext_upstream模块定义的错误
4.fall_timeout 失败超时时间,在连接Server时,如果在超时时间之内超过max_fails指定的失败次数,会认为在fail_timeout时间内Server不可用。默认为10s。
5.backup:其它所有的非backup机器down或者忙的时候,请求backup机器。所以这台机器压力会最轻。
Nginx分发算法测试
upstream web{ server 192.168.10.42; server 192.168.10.43; } server{ listen 80; server_name localhost; location /{ proxy_pass http://web; } }
轮询分发
upstream web{ server 192.168.10.42 weight=1; server 192.168.10.43 weight=2;} server{ listen 80; server_name localhost; location/{ proxy_pass http://web; } }
基于权重的分发
upstream web{
ip_hash;
server 192.168.10.42; #不支持 down 参数
server 192.168.10.43;
}
server{
listen 80;
server_name localhost;
location/{
proxy_pass http://web;
}
}
iphash 算法能够保证来自同样源地址的请求,都分发到同一台主机
[rootoweb01 ~J# elinks http://192.168.10.40 -dump
web02
ip_hash 保证来自同样源地址的请求,都分发到同一台主机
基于请求头的分发
1)基于host集群(不同虚拟主机)分发
2)基于开发语言分发
3)基于浏览器的分发
4)基于ip
connection: keep-alived 长连接
http{ upstream web1{ server 192.168.10.42; } upstream web2{ server 192.168.10.43; } server{ listen 80; server_name www.web1.com; location / { proxy_pass http://web1; } } server{ listen 80; server_name www.web2.com; location / { proxy_pass http://web2; } } }
基于host分发,多集群。两个域名虚拟主机 有各自的集群
http { upstream php { server 192.168.10.42; } upstream html { server 192.168.10.43; } server { listen 80; server_name www.web1.com; location ~* \.php$ { proxy_pass http://php; } location ~* \.html$ { proxy_pass http://html; } } }
基于开发语言分发
upstream elinks { server 192.168.10.42; }
upstream chrome { server 192.168.10.43; }
upstream any { server 192.168.10.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;
}
}
}
基于浏览器分发
手机和pc端分开
./configure --with-http_geoip_module # 需要重新编译的模块
upstream bj.server {
server 192.168.10.42;
}
upstream sh.server {
server 192.168.10.43;
}
upstream default.server {
server 192.168.10.42:81;
}
geo $geo { # 匹配属于哪个地方 ip 库
default default;
192.168.10.241/32 bj;
192.168.10.41/32 sh;
}
location / {
proxy_pass http://$geo.server$request_uri;
} # 防止uri 丢掉
# http://192.168.10.40/a/b/c/index.php http://192.168.10.42
基于源ip分发
keepalived 高可用
分发器宕机怎么办
数据服务器宕机怎么办
Keepalived的作用是检测服务器的状态,如果有一台web服务器宕机,或工作出现故障,Keepalived将检测到,并将有故障的服务器从系统中剔除,同时使用其他服务器代替该服务器的工作,当服务器工作正常后Keepalived自动将服务器加入到服务器群中,这些工作全部自动完成,不需要人工干涉,需要人工做的只是修复故障的服务器。
一个监控+自愈的软件
运行协议 vrrp
主分发器的KP会向网络中发组播宣告自己还活着 224.0.0.18
安装在哪里分发器上
分发器 Nginx+keepalvied
安装、配置高可用
keepalived 获得
#wget http://www.keepalived.org/software/keepalived-2.0.8.tar.gzkeepalived 安装
#cat keepalived_install.sh
# 安装
#!/bin/bash
pkg=keepalived-2.0.8.tar.gz
tar xf $pkg
yum -y install kernel-devel
ln -s /usr/src/kernels/3.10.0-862.14.4.el7.x86_64/ /usr/src/linux
cd keepalived-2.0.8/
yum install openssl-* -y
./configure --prefix=/usr/local/keepalived
make
make install
mkdir -pv /etc/keepalived
cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/
ln -s /usr/local/keepalived/sbin/keepalived /sbin/
配置
#cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
router_id NGINX_DEVEL
}
vrrp_script check_nginx {
script "/etc/keepalived/nginx_pid.sh" # 检查nginx状态脚本位置
interval 2 # 探针 每2s运行
fall 1 # 失败次数
}
vrrp_instance nginx {
state MASTER # 主
interface ens33 # 网卡
mcast_src_ip 192.168.10.40 # 发主播的地址,主分发器的KP会向网络中发组播宣告自己还活着 224.0.0.18
virtual_router_id 51
priority 100 # 优先级
advert_int 1 # 多久发一次主播
authentication { # 主播认证密码
auth_type PASS
auth_pass 1111
}
track_script {
check_nginx # 调用检查分发器的脚本
}
virtual_ipaddress {
192.168.10.213/24 # 虚拟 vip
}
}
/etc/keepalived/keepalived.conf
chmod 755 /etc/keepalived/nginx_pid.sh
cat /etc/keepalived/nginx_pid.sh
#!/bin/bash
nginx_kp_check () {
nginxpid=`ps -C nginx --no-header |wc -l`
if [ $nginxpid -eq 0 ];then
/usr/local/nginx/sbin/nginx # 重启
sleep 1
nginxpid=`ps -C nginx --no-header |wc -l`
if [ $nginxpid -eq 0 ];then
systemctl stop keepalived
fi
fi
}
nginx_kp_check
检查状态 /etc/keepalived/nginx_pid.sh
#cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
router_id NGINX_DEVEL
}
vrrp_script check_nginx {
script "/etc/keepalived/nginx_pid.sh"
interval 2
fall 1
}
vrrp_instance nginx {
state BACKUP # 状态
interface ens33
mcast_src_ip 192.168.10.41
virtual_router_id 51
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
track_script {
check_nginx
}
virtual_ipaddress {
192.168.10.213/24
}
}
BACKUP备负载均衡
检查脚本要给权限 chmod 755 nginx_pid.sh
tcpdump -nn -vvv -i ens33 vrrp
每隔1秒杀死nginx
watch -n1 killall nginx
分发器对应的web服务器,也要容错机制
多少秒内,失败了几次,分发器(nginx)就分发到集群其他机器
upstream web {
server 192.168.10.42 max_fails=2 fail_timeout=3;
server 192.168.10.43 max_fails=2 fail_timeout=3;
}
闲置的 lb02 可以用来做其他服务
案例介绍及Nginx安装
部署流程
Cnetos7.5+Nginx+python+Django+uwsgi+mysql
实验部署流程
1)安装Nginx
2)安装python
3)安装mysql
4)部署发布平台
5)测试
WEB01:192.168.10.42
Mysql介绍
一个关系型数据库,由瑞典的AB公司开发,后来卖给了oracle公司,目前分为商业版和社区版目前有最大版本mysql5 和mysql8目前建议大家先使用5.7最新版本即可。官方提供了RPM和源码两种格式
1)安装依赖包2)升级cmake工具3)升级boost库文件 1.594)安装mysql5)启动测试cmake 安装1)获得软件 https://cmake.org/download/ yum install gcc cmake 2)安装软件 tar xf cmake-3.6.0-rc1.tar cd cmake-3.6.0-rc1 /configure make make install make -j4 多核编译
Mysql安装步骤
-DCMAKE_INSTALL_PREFIX #指定安装路径
-DMYSQL_DATADIR #指定存放数据文件的目录位置
-DMYSQL_UNIX_ADDR #指定mysql.sock的路径
-DDOWNLOAD_BOOST=0 #不下载boost库文件
-DWITH_INNODBBASE_STORAGE_ENGINE=1 # 指定默认存储引擎
-DENABLE_LOCAL_INFILE=1 #允许客户端使用local data local 导入本地数据文件
-DEXTRA_CHARSETS=all #持所有字符集
-DDEFAULT_CHARSET=utf8 #默认字符集是UTF-8
-DDEFAULT_COLLATION=utf8_general_ci #数据库校对规则
-DMYSQL_USER=mysql # 管理用户是mysql
-DWITH_DEBUG=0 #关闭debug
-DWITH_EMBEDED_SERVER=0 #生成一个libmysqld.a(.so)的库, 这个库同时集成了mysql服务与客户端API
-DWITH_BOOST=/usr/local/boost #指定boost的路径
cmake 参数分解
mysql_install
1) cmake命令 2.8以上
https://cmake.org/download/
boost Boost库是⼀个可移植、提供源代码的C++库,作为标准库的后备,是C++标准化进程的开发引擎之⼀
https://www.boost.org/
mysql
https://dev.mysql.com/downloads/mysql/5.7.html#downloads
⼆、 install
yum -y install ncurses-devel gcc-* bzip2-*
1)cmake install
tar xf cmake-3.6.0-rc1.tar
cd cmake-3.6.0-rc1
./configure
make
make install
2) boost
tar xf boost_1_59_0.tar.bz2
mv boost_1_59_0 /usr/local/boost
前期准备 依赖包
3
useradd -s /sbin/nologin -r mysql
mkdir -pv /usr/local/mysql/data
tar xf mysql...tar.xx
cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DMYSQL_DATADIR=/usr/local/mysql/data/ -DMYSQL_UNIX_ADDR=/usr/local/mysql/mysql.sock -DDOWNLOAD_BOOST=0 -DWITH_INNODBBASE_STORAGE_ENGINE=1 -DENABLE_LOCAL_INFILE=1 -DEXTRA_CHARSETS=all -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DMYSQL_USER=mysql -DWITH_DEBUG=0 -DWITH_EMBEDED_SERVER=0 -DDOWNLOAD_BOOST=1 -DWITH_BOOST=/usr/local/boost
mysql参数配置
4)安装后操作
cp support-files/mysql.server /etc/init.d/mysql
chmod 755 /etc/init.d/mysql
chown mysql.mysql /usr/local/mysql/ -R
ln -sf /usr/local/mysql/bin/* /usr/bin/
ln -sf /usr/local/mysql/lib/* /usr/lib/
ln -sf /usr/local/mysql/libexec/* /usr/local/libexec
ln -sf /usr/local/mysql/share/man/man1/* /usr/share/man/man1
ln -sf /usr/local/mysql/share/man/man8/* /usr/share/man/man8
/usr/local/mysql/bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql/ --datadir=/usr/local/mysql/data/
修改配置文件 确保路径正确
[root@web01 ~]# egrep -v "^#|^$" /etc/my.cnf
[mysqld]
datadir=/usr/local/mysql/data
socket=/usr/local/mysql/mysql.sock
symbolic-links=0
[mysqld_safe]
log-error=/var/log/mysql.log
pid-file=/var/run/mysql.pid
!includedir /etc/my.cnf.d
5)启动mysql
初始化 root@localhost: /q%Zpaoio5i1
6)密码修改
修改密码
mysql_secure_installation
view
打开ssl模块
重新编译
# CSV file helper
#_CSV_csv.c
# Socket module helper for socket(2)
#_socket socketmodule.c
# Socket module helper for SSL support; you must comment out the other
# socket line above, and possibly edit the SSL variable:
SSL=/usr/loca1/ss1
ss1_ssl.c\
-DUSE_SSL -IS(SSL)/include -I$(SSL)/include/openss1\
-LS(SSL)/1ib-1ssl-1crypto
# The crypt module is now disabled by default because it breaks builds
# on many systems(where-lcrypt is needed),e.g. Linux(I believe).
#_crypt_cryptmodule.c#-lcrypt # crypt(3); needs-lcrypt on some syst
报错
virtualenv -p python3 web
在虚拟环境目录下创建django项目
(web)[ root@ web01 myweb]#ls
manage.py myweb
(web)[ root@web01 myweb]# python manage.py runserver 192.168.10.42:8000
django 里面配置打开,不然无法访问
ALLOWED_HOSTS=[*]
uwsgi 配置
[root@web01 ~]# vim /etc/uwsgi/uwsgi.ini
[uwsgi]
uid = root
gid = root
socket = 127.0.0.1:9090
master = true //启动主进程
vhost = true //多站模式
no-site = true //多站模式时不设置⼊⼝模块和⽂件
workers = 2 //⼦进程数
reload-mercy = 10 //平滑的重启
vacuum = true //退出、 重启时清理⽂件
max-requests = 1000 //开启10000个进程后, ⾃动respawn下
limit-as = 512 // 将进程的总内存量控制在512M
buffer-size = 30000
pidfile = /var/run/uwsgi9090.pid //pid⽂件, ⽤于下⾯的脚本启动、 停⽌该进程
daemonize = /var/log/uwsgi9090.log
编写服务器启动脚本
/etc/uwsgi/uwsgi.ini