定义
负载均衡
将最前端的访问负载分摊到多个后端服务器中,具有高并发、伸缩性、高可用和安全防护的特性
集群
相互独立的节点组成的一个较大的计算机服务系统,每个集群节点都是运行各自服务的独立服务器,可以彼此通信,共享数据
联系
用keepalived来保证集群高可用,通常结合负载均衡来实现,比如Nginx+keepalived,LVS-DR+keepalived,MySQL+keepalived
包含内容
常见负载均衡:Nginx负载均衡、LVS负载均衡、Tomcat负载均衡
常见集群:Mysql、Redis、Rabbitmq的集群模式
Nginx
Nginx作为反向代理服务器,隐藏了真实的服务器,把请求分转发到真实提供服务的各台服务器。负载均衡就是用代理的方法去实现的,分摊流量到多台内容一致的服务器
LVS
Linux virtual server,由ipvsadm(用户空间)和ipvs(内核空间)组成,ipvs工作于INPUT链上,若有请求报文被ipvs事先定义,则根据其特定的模型进行修改,再转发到POSTROUTING链上送出TCP/IP协议栈。
Tomcat
作为Java容器,也叫web中间件,Nginx处理静态,Tomcat处理动态程序,结合Nginx做单机多实例的负载均衡
MySQL
用多台机器向外提供同一个服务,共享数据,mysql第三方集群:galera
Redis
Redis集群是一个由多个主从节点群组成的分布式服务集群,无中心,具有复制、高可用和分片特性,不需要sentinel哨兵也能完成节点移除和故障转移的功能。
Rabbitmq
生产者发送的消息被缓存到RabbitMQ中,生产者不需要等待消息被消费就可以继续执行,提高生产者的效率。RabbitMQ可以在多个消费者之间分配消息,实现负载均衡。他的镜像集群模式属于高可用模式,每次写消息到 queue
的时候,都会自动把消息到多个实例的 queue
里进行消息同步。
修改配置
Nginx
#反向代理(一个)
#Nginx1.24的配置文件位置:/etc/nginx/conf.d/default.conf
#Nginx1.20在主配置文件修改:/etc/nginx/nginx.conf
vim /etc/nginx/conf.d/default.conf
server {
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://IP; #真实后端服务器地址,可以是ip或域名
proxy_redirect default;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 30;
proxy_send_timeout 60;
proxy_read_timeout 60;
}
}
#负载均衡(多个)
#位置跟上面一样
vim /etc/nginx/conf.d/default.conf
upstream testapp {
server IP:port weight=1; # IP为真实服务器地址,testapp可以是任意名字
server IP:port weight=2;
}
server {
....
location / {
proxy_pass http://testapp; #请求转向 testapp 定义的服务器列表
}
LVS(DR模式)
#分发器上操作
yum install -y ipvsadm #先安装ipvsadm
service ipvsadm start
ip a a dev ens33 VIP/32 #设置VIP,访问的虚拟IP
ipvsadm -C #清除内核虚拟服务器表中的所有记录。
ipvsadm -A -t VIP:port -s rr #指定轮询转发
ipvsadm -a -t VIP:port -r RIP1 -g #指定转发的RIP1
ipvsadm -a -t VIP:port -r RIP2 -g #指定转发的RIP2
ipvsadm -S > /etc/sysconfig/ipvsadm #保存方式,保存到一个文件中
ipvsadm -ln #查看IP转发和轮询
-A:添加VIP
-t:用的是tcp协议
-a:添加的是lo网卡的vip地址
-r:转发到realserverip
-s:算法
-L|-l –list #显示内核虚拟服务器表
--numeric, -n:#以数字形式输出地址和端口号
-g --gatewaying #指定LVS工作模式为直接路由器模式(也是LVS默认的模式)
-S -save #保存虚拟服务器规则到标准输出,输出为-R 选项可读的格式
rr:轮循
#如果添加ip错了,删除命令如下:
ip a del IP dev ens33
#rs上操作
ip a a dev lo VIP/32 #在lo网卡接口上绑定VIP
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore #忽略arp广播
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce #匹配精确ip地址回包
Tomcat
#tomcat单机多实例负载均衡配置
#先安装单实例Tomcat
tar -xzvf apache-tomcat-8.5.88.tar.gz -C /usr/local/
ln -s /usr/local/apache-tomcat-8.5.88/ /usr/local/tomcat
或者:# mv /usr/local/apache-tomcat-8.5.88/ /usr/local/tomcat
#定义Tomcat所需环境变量
vim /etc/profile
CATALINA_HOME=/usr/local/tomcat #Tomcat安装目录(基准、工作)
export CATALINA_HOME
source /etc/profile
/usr/local/tomcat/bin/version.sh #查看tomcat版本
/usr/local/tomcat/bin/startup.sh #启动Tomcat
/usr/local/tomcat/bin/shutdown.sh #关闭tomcat
#再此基础上部署多实例,对应的实例生成的目录和端口如下
instance1: /usr/local/tomcat/instance1/{conf,logs,temp,work} 8081 8091
instance2: /usr/local/tomcat/instance2/{conf,logs,temp,work} 8082 8092
instance3: /usr/local/tomcat/instance3/{conf,logs,temp,work} 8083 8093
/usr/local/tomcat/bin/shutdown.sh #先关闭原来的Tomcat实例
mkdir /usr/local/tomcat/instance{1..3} #创建多实例的目录并拷贝配置、日志、temp和work目录
cp -r /usr/local/tomcat/{conf,logs,temp,work} /usr/local/tomcat/instance1/
cp -r /usr/local/tomcat/{conf,logs,temp,work} /usr/local/tomcat/instance2/
cp -r /usr/local/tomcat/{conf,logs,temp,work} /usr/local/tomcat/instance3/
#配置每个实例的server.xml,把端口和基准目录修改为对应的
#实例1配置修改为:
vim /usr/local/tomcat/instance1/conf/server.xml
<Server port="8091" shutdown="SHUTDOWN">
<Connector port="8081" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<!-- <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> -->
#直接将8009端口这一行注释掉 tomcat8.5.88这个是注释的,可以不动他
<Host name="localhost" appBase="/usr/local/tomcat/webapps" //修改网站基准目录
unpackWARs="true" autoDeploy="true">
#实例2配置修改为:
vim /usr/local/tomcat/instance2/conf/server.xml
<Server port="8092" shutdown="SHUTDOWN">
<Connector port="8082" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<!-- <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> -->
<Host name="localhost" appBase="/usr/local/tomcat//webapps"
unpackWARs="true" autoDeploy="true">
#实例3配置修改:
vim /usr/local/tomcat/instance3/conf/server.xml
<Server port="8093" shutdown="SHUTDOWN">
<Connector port="8083" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<!-- <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> -->
<Host name="localhost" appBase="/usr/local/tomcat//webapps"
unpackWARs="true" autoDeploy="true">
#利用原来的Tomcat编写启动脚本
#vim /usr/local/tomcat/instance1/ins1.sh
#!/bin/bash
. /etc/init.d/functions
export CATALINA_BASE="/usr/local/tomcat/instance1"
case "$1" in
start)
$CATALINA_HOME/bin/startup.sh;;
stop)
$CATALINA_HOME/bin/shutdown.sh;;
restart)
$CATALINA_HOME/bin/shutdown.sh
sleep 5
$CATALINA_HOME/bin/startup.sh;;
esac
export JAVA_OPTS='-Xms64m -Xmx128m'
# chmod a+x /usr/local/tomcat/instance1/ins1.sh
#vim /usr/local/tomcat/instance2/ins2.sh
#!/bin/bash
. /etc/init.d/functions
export CATALINA_BASE="/usr/local/tomcat/instance2"
case "$1" in
start)
$CATALINA_HOME/bin/startup.sh;;
stop)
$CATALINA_HOME/bin/shutdown.sh;;
restart)
$CATALINA_HOME/bin/shutdown.sh
sleep 5
$CATALINA_HOME/bin/startup.sh;;
esac
export JAVA_OPTS='-Xms64m -Xmx128m'
# chmod a+x /usr/local/tomcat/instance2/ins2.sh
# vim /usr/local/tomcat/instance3/ins3.sh
#!/bin/bash
. /etc/init.d/functions
export CATALINA_BASE="/usr/local/tomcat/instance3"
case "$1" in
start)
$CATALINA_HOME/bin/startup.sh;;
stop)
$CATALINA_HOME/bin/shutdown.sh;;
restart)
$CATALINA_HOME/bin/shutdown.sh
sleep 5
$CATALINA_HOME/bin/startup.sh;;
esac
export JAVA_OPTS='-Xms64m -Xmx128m'
#添加执行权限
# chmod a+x /usr/local/tomcat/instance3/ins1.sh
# chmod a+x /usr/local/tomcat/instance3/ins2.sh
# chmod a+x /usr/local/tomcat/instance3/ins3.sh
#陆续启动
/usr/local/tomcat/instance1/ins1.sh start
/usr/local/tomcat/instance2/ins2.sh start
/usr/local/tomcat/instance3/ins3.sh start
MySQL
#准备环境
#主机解析
cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
IP1 galera1
IP2 galera2
IP3 galera3
IP4 galera4
#关闭防火墙和selinux
#下载和安装Galera(每台都需要安装)
配置yum源
vim /etc/yum.repos.d/galera.repo
[galera]
name=galera
baseurl=http://releases.galeracluster.com/mysql-wsrep-5.7/centos/7/x86_64/
enabled=1
gpgcheck=0
yum -y install epel* #需要epel源提供galera包
yum install mysql-wsrep-5.7.x86_64 galera rsync -y
systemctl start mysqld
mysqladmin -u root -p'2rttwxb?3_oP' password '新密码' #修改密码
mysql -u root -p'新密码'
mysql> grant all on *.* to 'syncuser'@'%' identified by '设置密码';
#修改每台机器的配置文件,逐一启动
#galera1
vim /etc/my.cnf #追加以下内容
server-id=1
binlog_format=row
innodb_file_per_table=1
innodb_autoinc_lock_mode=2
wsrep_on=ON
wsrep_provider=/usr/lib64/galera/libgalera_smm.so
wsrep_cluster_name='galera'
wsrep_cluster_address='gcomm://'
wsrep_node_name='galera1'
wsrep_node_address='IP1'
wsrep_sst_auth=syncuser:'mysql同步账户的密码'
wsrep_sst_method=rsync
systemctl restart mysqld #重启服务
#galera2
vim /etc/my.cnf #追加以下内容
server-id=2
binlog_format=row
innodb_file_per_table=1
innodb_autoinc_lock_mode=2
wsrep_on=ON
wsrep_provider=/usr/lib64/galera/libgalera_smm.so
wsrep_cluster_name='galera'
wsrep_cluster_address='gcomm://galera1'
wsrep_node_name='galera2'
wsrep_node_address='IP2'
wsrep_sst_auth=syncuser:'mysql同步账户的密码'
wsrep_sst_method=rsync
systemctl restart mysqld #重启服务
#galera3
vim /etc/my.cnf #追加以下内容
server-id=3
binlog_format=row
innodb_file_per_table=1
innodb_autoinc_lock_mode=2
wsrep_on=ON
wsrep_provider=/usr/lib64/galera/libgalera_smm.so
wsrep_cluster_name='galera'
wsrep_cluster_address='gcomm://galera1,galera2'
wsrep_node_name='galera3'
wsrep_node_address='IP3'
wsrep_sst_auth=syncuser:'mysql同步账户的密码'
wsrep_sst_method=rsync
systemctl restart mysqld #重启服务
#galera4
vim /etc/my.cnf #追加以下内容
server-id=4
binlog_format=row
innodb_file_per_table=1
innodb_autoinc_lock_mode=2
wsrep_on=ON
wsrep_provider=/usr/lib64/galera/libgalera_smm.so
wsrep_cluster_name='galera'
wsrep_cluster_address='gcomm://galera1,galera2,galera3'
wsrep_node_name='galera4'
wsrep_node_address='IP4'
wsrep_sst_auth=syncuser:'mysql同步账户的密码'
wsrep_sst_method=rsync
systemctl restart mysqld #重启服务
Redis
#环境准备
#所有机器关闭防火墙和selinux,修改一下主机名
hostnamectl set-hostname redis-cluster1
hostnamectl set-hostname redis-cluster2
hostnamectl set-hostname redis-cluster3
vim /etc/hosts #所有机器做好hosts解析,添加以下内容
IP1 redis-cluster1
IP2 redis-cluster2
IP3 redis-cluster3
#安装redis
yum update -y #更新源
yum install -y centos-release-scl #安装scl源
yum install -y devtoolset-9-toolchain #安装gcc工具链
scl enable devtoolset-9 bash #临时覆盖旧版本gcc引用,针对本次会话有效
echo "source /opt/rh/devtoolset-9/enable" >>/etc/profile
source /etc/profile #为了避免需要再次激活devtoolset-9使其长期有效
gcc -v #查看gcc版本
#下载redis压缩包
wget http://download.redis.io/releases/redis-7.0.11.tar.gz
tar -xzvf redis-7.0.11.tar.gz -C /usr/local/
mv /usr/local/redis-7.0.11 /usr/local/redis
cd /usr/local/redis/
make && make install
mkdir /data/redis/data -p #创建存放数据的目录
#创建节点目录:按照规划在每台redis节点的安装目录中创建对应的目录,以端口号命名
cd /data/redis
mkdir cluster #创建集群目录
mkdir cluster/{7000,7001} #机器1创建节点目录,机器2和3类似,文件名字陆续为7002-7005
#拷贝配置文件到节点目录中,三台机器相同操作,机器2和3类似,文件名字陆续为7002-7005
cp /usr/local/redis/redis.conf 7000/
cp /usr/local/redis/redis.conf 7001/
#修改集群每个redis配置文件。(主要是端口、ip、pid文件,三台机器相同操作),机器1为例,修改如下:
cd 7000/
cp redis.conf{,.bak}
vim redis.conf #修改如下
bind IP1 #每个实例的配置文件修改为对应节点的ip地址
port 7000 #监听端口,运行多个实例时,需要指定规划的每个实例不同的端口号
daemonize yes #redis后台运行
pidfile /var/run/redis_7000.pid #pid文件,运行多个实例时,需要指定不同的pid文件
logfile /var/log/redis_7000.log #日志文件位置,运行多实例时,需要将文件修改的不同。
dir /data/redis/data #存放数据的目录
appendonly yes #开启AOF持久化
appendfilename "appendonly.aof" #AOF文件名称
appendfsync everysec #表示对写操作进行累积,每秒同步一次
protected-mode no #受保护模式,默认是yes开启的,将它修改成no
#以下为打开注释并修改:
cluster-enabled yes #启用集群
cluster-config-file nodes-7000.conf #运行多实例时请注修改为对应端口
cluster-node-timeout 5000 #单位毫秒。集群节点超时时间
cluster-replica-validity-factor 10 #默认就是10,单位是秒
cluster-migration-barrier 1 #默认配置是一个迁移临界值。
cluster-require-full-coverage yes #集群中的所有slot(16384个)全部覆盖,把注释打开就好了
#7001操作:
[root@redis-cluster1 7001]# mv redis.conf redis.conf.bak
[root@redis-cluster1 7001]# cp ../7000/redis.conf ./
[root@redis-cluster1 7001]# vim redis.conf #把7000修改成7001:%s/7000/7001/g
#以此类推,把修改好的配置文件发给每个机器,再把bind和4个端口号修改
#启动各个实例,以此类推
/usr/local/redis/src/redis-server /data/redis/cluster/7000/redis.conf
#创建集群:在其中一个节点操作就可以
cd /usr/local/redis/src/
./redis-cli --cluster create --cluster-replicas 1 IP1:7000 IP2:7001 IP3:7002 IP4:7003 IP5:7004 IP6:7005
Rabbitmq
#修改主机名字,添加解析,关闭防火墙
vim /etc/hosts
IP1 rabbitmq-1
IP2 rabbitmq-2
IP3 rabbitmq-3
#三个节点配置安装rabbitmq软件
yum install -y *epel* gcc-c++ unixODBC unixODBC-devel openssl-devel ncurses-devel #安装依赖
curl -s https://packagecloud.io/install/repositories/rabbitmq/erlang/script.rpm.sh | sudo bash
yum install erlang-21.3.8.21-1.el7.x86_64 -y #安装erlang
erl #测试是否有erl环境
Erlang/OTP 21 [erts-10.3.5.16] [source] [64-bit] [smp:2:2] [ds:2:2:10] [async-threads:1] [hipe]
Eshell V10.3.5.16 (abort with ^G)
1> #crtl g
User switch command
--> q #退出;h列出功能
yum install -y socat #安装 socat
yum install -y rabbitmq-server-3.7.10-1.el7.noarch.rpm #安装rabbitmq
systemctl daemon-reload #启动rabbitmq
systemctl enable --now rabbitmq-server.service #启动并加入开机自启
#任意一个节点创建用户并修改权限
rabbitmqctl add_user admin admin #添加一个admin的用户
rabbitmqctl set_user_tags admin administrator #设置角色为管理员
rabbitmqctl list_users #查看用户
rabbitmqctl set_permissions -p "/" admin ".*" ".*" ".*" #对admin这个用户设置所有资源可读可写
#3台机器都开启用户远程登录
cd /etc/rabbitmq/
cp /usr/share/doc/rabbitmq-server-3.7.10/rabbitmq.config.example /etc/rabbitmq/rabbitmq.config
cp rabbitmq.config{,.bak}
vim rabbitmq.config #修改如下:
%% {loopback_users, []}, #改成: {loopback_users, []}
systemctl restart rabbitmq-server #三台机器都操作重启服务
#部署集群,所有机器都要操作
mkdir -p /data/rabbitmq/{data,logs}
chmod 777 -R /data/rabbitmq
chown rabbitmq.rabbitmq /data/ -R
vim /etc/rabbitmq/rabbitmq-env.conf #创建配置文件
RABBITMQ_MNESIA_BASE=/data/rabbitmq/data
RABBITMQ_LOG_BASE=/data/rabbitmq/logs
systemctl restart rabbitmq-server #重启服务
#将rabbitmq-1节点的.erlang.cookie的值复制到其他两个节点中
cat /var/lib/rabbitmq/.erlang.cookie
TLRCSBNSYLEYNYUALPRM
scp /var/lib/rabbitmq/.erlang.cookie root@IP2:/var/lib/rabbitmq/
scp /var/lib/rabbitmq/.erlang.cookie root@IP3:/var/lib/rabbitmq/
#在rabbitmq-2、rabbitmq-3执行如下命令
systemctl restart rabbitmq-server.service #先重启一下rabbitmq
rabbitmqctl stop_app #停止节点,切记不是停止服务
#将两个节点加入集群,指定角色,执行相同操作
rabbitmqctl join_cluster --ram rabbit@rabbitmq-1 #添加到内存节点 --ram
rabbitmqctl start_app #启动节点
rabbitmqctl cluster_status #任意节点上查看是否集群配置成功