关于keepalived:keep-自定义编排动作
在keep上如何自定义编排动作1.首页->全副课程->动作训练->自建编排
在keep上如何自定义编排动作1.首页->全副课程->动作训练->自建编排
Keepalived装置部署 下载地址:点我下载通过ftp工具上传到linux中,/home/software解压tar -zxvf keepalived-2.0.18.tar.gz解压后进入到解压进去的目录,看到会有 configure ,那么就能够做配置了(配置装置和nginx截然不同)配置 Keepalived - 主 通过命令 vim keepalived.conf 关上配置文件 global_defs {# 路由id:以后装置keepalived的节点主机标识符,保障全局惟一router_id keep_171}vrrp_instance VI_1 {# 示意状态是MASTER主机还是备用机BACKUPstate MASTER# 该实例绑定的网卡interface ens33# 保障主备节点统一即可virtual_router_id 51# 权重,master权重个别高于backup,如果有多个,那就是选举,谁的权重高,谁就入选priority 100# 主备之间同步查看工夫距离,单位秒advert_int 2# 认证权限明码,避免非法节点进入authentication {auth_type PASSauth_pass 1111}# 虚构进去的ip,能够有多个(vip)virtual_ipaddress {192.168.1.161}}附:查看网卡名称 启动 Keepalived在sbin目录中进行启动(同nginx),如下图:配置 Keepalived - 备 通过命令 vim keepalived.conf 关上配置文件 global_defs {router_id keep_172}vrrp_instance VI_1 {# 备用机设置为BACKUPstate BACKUPinterface ens33virtual_router_id 51# 权重低于MASTERpriority 80advert_int 2authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {# 留神:主备两台的vip都是一样的,绑定到同一个vip192.168.1.161}}启动 Keepalived # 启动keepalivedsystemctl start keepalived# 进行keepalivedsystemctl stop keepalived# 重启keepalivedsystemctl restart keepalived查看过程 ...
每一台配置下keepalived #master01 配置:cat >/etc/keepalived/keepalived.conf<<"EOF"! Configuration File for keepalivedglobal_defs { router_id LVS_DEVEL script_user root enable_script_security}vrrp_script chk_apiserver { script "/etc/keepalived/check_apiserver.sh" interval 5 weight -5 fall 2 rise 1 #检测一次胜利,则认为在线}vrrp_instance VI_1 { state BACKUP nopreempt interface ens160 mcast_src_ip 10.0.0.20 virtual_router_id 51 priority 100 advert_int 2 authentication { auth_type PASS auth_pass K8SHA_KA_AUTH } virtual_ipaddress { 10.0.0.30 } track_script { chk_apiserver }}EOF#Master02 配置:cat >/etc/keepalived/keepalived.conf<<"EOF"! Configuration File for keepalivedglobal_defs { router_id LVS_DEVEL script_user root enable_script_security}vrrp_script chk_apiserver { script "/etc/keepalived/check_apiserver.sh" interval 5 weight -5 fall 2 rise 1}vrrp_instance VI_1 { state BACKUP nopreempt interface ens160 mcast_src_ip 10.0.0.21 virtual_router_id 51 priority 99 advert_int 2 authentication { auth_type PASS auth_pass K8SHA_KA_AUTH } virtual_ipaddress { 10.0.0.30 } track_script { chk_apiserver }}EOF#Master03 配置:cat >/etc/keepalived/keepalived.conf<<"EOF"! Configuration File for keepalivedglobal_defs { router_id LVS_DEVEL script_user root enable_script_security}vrrp_script chk_apiserver { script "/etc/keepalived/check_apiserver.sh" interval 5 weight -5 fall 2 rise 1}vrrp_instance VI_1 { state BACKUP nopreempt interface ens160 mcast_src_ip 10.0.0.22 virtual_router_id 51 priority 98 advert_int 2 authentication { auth_type PASS auth_pass K8SHA_KA_AUTH } virtual_ipaddress { 10.0.0.30 } track_script { chk_apiserver }EOF健康检查脚本 ...
yum install keepalivedvi /etc/keepalived/keepalived.conf<code>vrrp_script chk_haproxy {script "pidof haproxy" interval 2}vrrp_instance VI_1 { debug 2 interface eth0 # interface to monitor state MASTER virtual_router_id 51 # Assign one ID for this route priority 101 # 101 on master, 100 on backup unicast_src_ip x.x.x.x # My IP unicast_peer { x.x.x.x # Peer IP } track_script { chk_haproxy } virtual_ipaddress { x.x.x.x dev eth0 }}</code>Backupvi /etc/keepalived/keepalived.conf<code>vrrp_script chk_haproxy {script "pidof haproxy" interval 2}vrrp_instance VI_1 { debug 2 interface eth0 # interface to monitor state BACKUP virtual_router_id 51 # Assign one ID for this route priority 100 # 101 on master, 100 on backup unicast_src_ip x.x.x.x # My IP unicast_peer { x.x.x.x # Peer IP } track_script { chk_haproxy } virtual_ipaddress { x.x.x.x dev eth0 }}</code>ip a
问题咱们常常应用浮动 IP(SIP,或叫 VIP),来实现数据库的高可用部署。业务通过拜访浮动 IP,始终拜访主数据库。如果业务正在拜访数据库时,数据库主从产生切换,导致 SIP 漂移,那正在应用的数据库连贯会受到影响么? 试验咱们创立同子网的两台虚拟机,别离装置 MySQL。再筹备一台额定的虚拟机,用来模仿业务,拜访数据库,此处省略装置过程。这两台虚拟机的 IP 别离是 x.x.x.37 和 x.x.x.39,为了容易辨别,咱们设置 PS1,来辨别两个 linux 的会话。下图以 37 为例,这里设置了 PS1,并确认机器上有创立好数据库, 39 与之相似: 咱们再选取一个 SIP: x.x.x.200,将其绑定到 37 上, 向子网进行 arp 宣告,告诉大家 ip 变更了: 当初业务机器上,测试一下拜访 SIP 胜利: 咱们在数据库中用 sysbench 灌入数据,此处省略步骤,只看后果: 而后向数据库执行一个 select,这里咱们用了一个 sleep,使得数据库返回后果集慢一些,大略每秒输入 1000 行左右: 执行 SQL 后,MySQL 客户端会不停输入后果,如果产生了任何连贯问题,咱们能够立即发现。当初让 SIP 产生一次切换。筹备好如下命令:先在 37 上卸下 SIP,再在 39 上加上 SIP,发送 arp 宣告。 ...
写在前面最近都在折腾 Nginx 服务器的学习和测试,前几天稍微温习了一下计算机网络方面的知识(一方面是兴趣,一方面是这次学习过程中因为这些计算机基础遗忘,有很多细节问题让人很懵逼),也在 Linux 上试了一下 tcpdump 命令,通过抓包来验证自己之前的各种猜想(因为不懂所以瞎猜),分析数据包依旧是用的 Wireshark 之前一直以为只要使用 Http1.1 协议就可以复用连接,节省反复握手挥手的时间消耗,但抓包后才发现,"简简单单"的长连接使用,还真是涉及了 Nginx 、 JMeter 、 Tomcat 里的很多配置啊 JMeter 虽然在 Http 请求的配置中默认勾选了使用 KeepAlive,但是实际使用中并没有生效Nginx 涉及到与客户端的配置 keepalive_timeout 和 keepalive_requests,与后端服务器的配置 keepalive(1.15.3之后,upstream 模块也新增了 keepalive_timeout 和 keepalive_requests,本篇暂不涉及)Tomcat 默认也有一个 keepAliveTimeout 配置知道了这些相关配置后,一方面想实战下 tcpdump 和 Wireshark 的使用,一方面也想用数据验证下 Nginx 的这三个配置,所以就有了接下来的内容 环境说明Nginx 1.14.0Linux 2.6.32JMeter 5.0Wireshark 2.6.4JMeter 所在主机 IP 172.16.40.199Tomcat 所在主机 IP 172.16.40.201Nginx 所在主机 IP 172.16.40.2240. 和客户端的长连接超时时间指令说明语法: keepalive_timeout timeout [header_timeout];默认值: keepalive_timeout 75s; 上下文: http, server, location 第一个参数设置客户端的长连接在服务器端保持的最长时间(在此时间客户端未发起新请求,则长连接关闭)。 第二个参数为可选项,设置“Keep-Alive: timeout=time”响应头的值。 可以为这两个参数设置不同的值。 ...
最近在使用vue + element-UI开发的后台管理项目中,优化 keep-alive 的使用方式时遇到了一些问题 优化前使用的 if 判断来控制页面是否可以缓存,这样做页面切换的动画效果不是太理想 <transition> <keep-alive> <router-view v-if="$route.meta.keepAlive"></router-view> </keep-alive></transition><transition> <router-view v-if="!$route.meta.keepAlive"></router-view></transition>优化想使用 include 来控制页面是否可以缓存,也可以让页面切换起来更流畅些 <transition> <keep-alive :include="keepLive"> <router-view></router-view> </keep-alive></transition><script> export default { data() { return {} }, computed: { keepLive() { // 此处使用 store getters 计算过的 keepLive 数组 //(在 store 拿到 routes,循环出 meta 里面带有 keepLive: true 的 route 的 name 放到 keepLive) return this.$store.getters.keepLive } } }</script>路由里面 export default new Router({ routes: [ { path: '/a', name: 'a', component: () => import('src/views/a'), meta: { keepAlive: true } }, { path: '/b', name: 'a', component: () => import('src/views/b'), meta: { keepAlive: true } } ]})此时,我感觉准备工作已经做完了,可以运行项目看一下效果了。果然,切换动画是有了,但是查看控制台,页面竟然没有了请求! ...
双主 + keepalived 是一个比较简单的 MySQL 高可用架构,适用于中小 MySQL 集群,今天就说说怎么用 keepalived 做 MySQL 的高可用。1 概述1.1 keepalived 简介简单地说,keepalived 就是通过管理 VIP 来实现机器的高可用的,在使用 keepalived 的情况下,只有一台服务器能够提供服务(通过 VIP 来实现),当 Master 主机宕机后,VIP 会自动飘移到另一台服务器keepalived 采用 Master/Slave 模式, 在 Master 上设置配置文件的 VIP,当 Master 宕机后,VIP 自动漂移到另一台 keepalived 服务器上keepalived 可以用来做各种软件的高可用集群,它会一直检测服务器的状态,如果有一台服务器宕机,或工作出现故障,keepalived 将检测到,并将有故障的服务器从系统中剔除,同时使用其他服务器代替该服务器的工作,当服务器工作正常后 keepalived 自动将服务器加入到服务器群中。1.2 keepalived 配合双主keepalived 使用默认配置只能做到主机级别的高可用,但是我们的 MySQL 要做高可用至少要增加以下功能能够检测 MySQL 服务状态主节点 read_only=0,备节点 read_only=1切换时,备节点要等待主节点同步完成所以,keepalived 实现 MySQL 高可用需要使用自定义脚本来进行扩展2 环境准备2.1 数据库环境操作前已经准备好了一套主主架构数据库,搭建方法参考 MySQL集群搭建(2)-主主从模式节点信息IP系统端口MySQL版本节点读写说明10.0.0.247Centos6.533065.7.9Master读写主节点10.0.0.248Centos6.533065.7.9Standby只读,可切换为读写备主节点VIP 信息简称VIP类型RW-VIP10.0.0.237读写VIPMaster 参考配置[client]port = 3306default-character-set=utf8mb4socket = /data/mysql_db/test_db/mysql.sock[mysqld]datadir = /data/mysql_db/test_dbbasedir = /usr/local/mysql57tmpdir = /tmpsocket = /data/mysql_db/test_db/mysql.sockpid-file = /data/mysql_db/test_db/mysql.pidskip-external-locking = 1skip-name-resolve = 1port = 3306server_id = 2473306default-storage-engine = InnoDBcharacter-set-server = utf8mb4default_password_lifetime=0auto_increment_offset = 1auto_increment_increment = 2#### log ####log_timestamps=systemlog_bin = /data/mysql_log/test_db/mysql-binlog_bin_index = /data/mysql_log/test_db/mysql-bin.indexbinlog_format = rowrelay_log_recovery=ONrelay_log=/data/mysql_log/test_db/mysql-relay-binrelay_log_index=/data/mysql_log/test_db/mysql-relay-bin.indexlog_error = /data/mysql_log/test_db/mysql-error.log#### replication ####log_slave_updates = 1replicate_wild_ignore_table = information_schema.%,performance_schema.%,sys.%#### semi sync replication settings #####plugin_dir=/usr/local/mysql57/lib/pluginplugin_load = “rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so"loose_rpl_semi_sync_master_enabled = 1loose_rpl_semi_sync_slave_enabled = 1Slave 参考配置[client]port = 3306default-character-set=utf8mb4socket = /data/mysql_db/test_db/mysql.sock[mysqld]datadir = /data/mysql_db/test_dbbasedir = /usr/local/mysql57tmpdir = /tmpsocket = /data/mysql_db/test_db/mysql.sockpid-file = /data/mysql_db/test_db/mysql.pidskip-external-locking = 1skip-name-resolve = 1port = 3306server_id = 2483306default-storage-engine = InnoDBcharacter-set-server = utf8mb4default_password_lifetime=0auto_increment_offset = 2auto_increment_increment = 2#### log ####log_timestamps=systemlog_bin = /data/mysql_log/test_db/mysql-binlog_bin_index = /data/mysql_log/test_db/mysql-bin.indexbinlog_format = rowrelay_log_recovery=ONrelay_log=/data/mysql_log/test_db/mysql-relay-binrelay_log_index=/data/mysql_log/test_db/mysql-relay-bin.indexlog_error = /data/mysql_log/test_db/mysql-error.log#### replication ####log_slave_updates = 1replicate_wild_ignore_table = information_schema.%,performance_schema.%,sys.%#### semi sync replication settings #####plugin_dir=/usr/local/mysql57/lib/pluginplugin_load = “rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so"loose_rpl_semi_sync_master_enabled = 1loose_rpl_semi_sync_slave_enabled = 12.2 创建监控用的账号- 由于是测试环境,账号密码设置比较随便create user monitor@’localhost’ identified by ‘monitor’;grant all on . to monitor@’localhost’;flush privileges;2.3 安装 keepalived我们在 Master 和 Slave 上部署 keepalived1). yum 安装如果有对应的 yum 源,直接安装就可以了yum install -y keepalived2). 源码安装下载安装包, 下载地址 keepalived, 使用 1.2.24 版本举例# 安装依赖yum install -y gcc popt-devel openssl openssl-devel libssl-dev libnl-devel popt-devel libnfnetlink-devel# 下载包wget http://www.keepalived.org/software/keepalived-1.2.24.tar.gz# 解压安装tar -xvz -f keepalived-1.2.24.tar.gzcd keepalived-1.2.24./configure –prefix=/usr/local/keepalivedmake && make installcp /usr/local/keepalived/sbin/keepalived /usr/sbin/cp /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/mkdir /etc/keepalived/cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/3 配置高可用3.1 keepalived 配置打开 /etc/keepalived/keepalived.conf 文件, 按照实际情况加上下面的配置global_defs { router_id MYSQL_MM # 标识 vrrp_skip_check_adv_addr vrrp_strict # 严格执行 VRRP 协议规范 vrrp_garp_interval 0 vrrp_gna_interval 0}vrrp_script check_mysql { script “/bin/sh /etc/keepalived/keepalived_mysql_check.sh” # 检查脚本 interval 10 # 检查周期}vrrp_instance MYSQL_MM { state BACKUP # 都设为 BACKUP,避免起来后抢占 interface eth0 # 网卡名称,根据实际情况填写 virtual_router_id 243 # 用来区分 VRRP 组播的标记,取值 0-255 priority 100 advert_int 1 nopreempt # 设为非抢占 authentication { auth_type PASS auth_pass 1111 } # Master 节点可以注释掉下面语句,防止启动 keepalived 的时候执行脚本 notify_master “/bin/sh /etc/keepalived/keepalived_mysql_start.sh” # 变为 MASTER 时执行 virtual_ipaddress { 10.0.0.237 } # Slave 节点可以注释下面检查脚本,Slave 没有必要一直检查 track_script { check_mysql }}3.2 配置检查脚本打开 /etc/keepalived/keepalived_mysql_check.sh, 写入检测脚本#!/bin/sh# @Author: chengqm# MySQL 检测脚本MyPath=$(cd $(dirname $0); pwd)cd $MyPathThisTime=date '+%F %T'log_file=’/var/log/keepalived_mysql.log’# MySQL 连接方式,根据实际情况调整export MYSQL_PWD=‘monitor’MYSQL_USER=‘monitor’MYSQL_SOCKET="/data/mysql_db/test_db/mysql.sock"mysql_connect=“mysql -u${MYSQL_USER} -S${MYSQL_SOCKET} “# 美化输出function techo() { message=$1 message_level=$2 if [ -e $message_level ];then message_level=‘info’ fi echo “date '+%F %T' - [${message_level}] $message” >> $log_file}# 检查函数, 正常返回 0function check { ret=$mysql_connect -N -e 'select 1 as value' if [ $? -ne 0 ] || [ $ret -ne ‘1’ ];then return 1 else return 0 fi}function read_only { param=$1 $mysql_connect -e “set global read_only = ${param}” techo “设置是否只读 read_only ${param}”}# 失效转移function failover { techo “开始执行失效转移” # 1. 停止 keepalived killall keepalived # 2. 如果还能执行的话,设为 read_only read_only 1 if [ $? -eq 0 ];then # 3. 如果还能执行,kill 所有的连接 $mysql_connect -e “select concat(‘KILL ‘,id,’;’) from information_schema.processlist where user!=‘root’ AND db is not null into outfile ‘/tmp/kill.txt.${ThisTime}’;” if [ $? -eq 0 ];then $mysql_connect -e “source /tmp/kill.txt.${ThisTime};” fi fi # 4. 其他操作,比如说自动关机 techo “失效转移执行成功,当前数据库关闭访问”}# 有问题检查 4 次for ((i=1; i<=4; i ++)) do check if [ $? -eq 0 ];then techo “MySQL is ok” # 正常退出脚本 exit 0 else techo “Connection failed $i time(s)” sleep 1 fidonetecho ‘无法连接当前数据库’# 失效转移failover注意:脚本没有经过严格测试,需要根据实际情况调整3.3 配置提升为 Master 时执行的脚本打开 /bin/sh /etc/keepalived/keepalived_mysql_start.sh”, 写入脚本内容#!/bin/sh# @Author: chengqm# keepalived 变为 Master 时执行MyPath=$(cd $(dirname $0); pwd)cd $MyPathThisTime=date '+%F %T'log_file=’/var/log/keepalived_mysql.log’# MySQL 连接方式,根据实际情况调整export MYSQL_PWD=‘monitor’MYSQL_USER=‘monitor’MYSQL_SOCKET="/data/mysql_db/test_db/mysql.sock"mysql_connect=“mysql -u${MYSQL_USER} -S${MYSQL_SOCKET} “# 美化输出function techo() { message=$1 message_level=$2 if [ -e $message_level ];then message_level=‘info’ fi echo “date '+%F %T' - [${message_level}] $message” >> $log_file}# 检查函数, 正常返回 0function check { ret=$mysql_connect -N -e 'select 1 as value' if [ $? -ne 0 ] || [ $ret -ne ‘1’ ];then return 1 else return 0 fi}# 获取 slave status 的信息function slave_info() { tmp_file=/tmp/slave_info.tmp $mysql_connect -e ‘show slave status\G’ > /tmp/slave_info.tmp slave_sql=grep 'Slave_SQL_Running:' $tmp_file | sed 's/\s*//g' | tr "A-Z" "a-z" | awk -F":" '{print $2}' seconds_behind_master=grep 'Seconds_Behind_Master:' $tmp_file | sed 's/\s*//g' | tr "A-Z" "a-z" | awk -F":" '{print $2}' master_log_file=grep 'Master_Log_File:' $tmp_file | head -1 | sed 's/\s*//g' | tr "A-Z" "a-z" | awk -F":" '{print $2}' master_log_pos=grep 'Read_Master_Log_Pos:' $tmp_file | sed 's/\s*//g' | tr "A-Z" "a-z" | awk -F":" '{print $2}' relay_master_log_file=grep 'Relay_Master_Log_File:' $tmp_file | sed 's/\s*//g' | tr "A-Z" "a-z" | awk -F":" '{print $2}' exec_master_log_pos=grep 'Exec_Master_Log_Pos:' $tmp_file | sed 's/\s*//g' | tr "A-Z" "a-z" | awk -F":" '{print $2}'}# 设置是否可读function read_only { param=$1 $mysql_connect -e “set global read_only = ${param}” techo “设置是否只读 read_only ${param}”}# 处理数据同步function sync_master_log() { # 如果是数据一致性优先,等待同步完毕。如果是服务可用性优先,可以注销下面的代码 slave_info if [ $slave_sql == “yes” ];then techo “当前同步位置 Master ${master_log_file} ${master_log_pos}” techo “等待同步到 Master ${master_log_file} ${master_log_pos}” $mysql_connect -e “select master_pos_wait(’$master_log_file’, $master_log_pos);” > /dev/null techo “同步完毕” fi}techo “当前数据库提升为主库"checkif [ $? -ne 0 ];then techo “无法连接当前数据库” exit 1fi# 等待同步sync_master_log# 设为可写read_only 0注意:脚本没有经过严格测试,需要根据实际情况调整3.4 启动 keepalived由于配置了 BACKUP 模式,所以两个 keepalived 先起来的是主,先后在主备节点执行/etc/init.d/keepalived start检查 /var/log/message 日志,确认 keepalived 没有报错检查 Master IP 状态, 确认设置了 VIP[root@cluster01 shell]# ip addr1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid_lft forever preferred_lft forever2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether fa:16:3e🇩🇪80:33 brd ff:ff:ff:ff:ff:ff inet 10.0.0.247/16 brd 10.0.255.255 scope global eth0 inet 10.0.0.237/32 scope global eth0 inet6 fe80::f816:3eff:fede:8033/64 scope link valid_lft forever preferred_lft forever检查 MySQL 检测脚本执行情况,确认正常运行[root@cluster01 ~]# tail -f /var/log/keepalived_mysql.log …2019-01-28 15:04:18 - [info] MySQL is ok2019-01-28 15:04:28 - [info] MySQL is ok4 失效转移测试在 mytest 库里新建 nowdate 测试表,只有 id 和 ctime 字段,然后每秒插入一条数据[root@cluster03 ~]# while true; do date;mysql -h10.0.0.237 -P3306 -umytest -e ‘use mytest;insert into nowdate values (null, now());’; sleep 1;doneMon Jan 28 15:04:26 CST 2019Mon Jan 28 15:04:27 CST 2019…kill 掉 Master 进程killall mysqld查看旧 Master 日志2019-01-28 15:04:48 - [info] MySQL is ok2019-01-28 15:04:58 - [info] Connection failed 1 time(s)2019-01-28 15:04:59 - [info] Connection failed 2 time(s)2019-01-28 15:05:00 - [info] Connection failed 3 time(s)2019-01-28 15:05:01 - [info] Connection failed 4 time(s)2019-01-28 15:05:02 - [info] 无法连接当前数据库2019-01-28 15:05:02 - [info] 开始执行失效转移2019-01-28 15:05:02 - [info] 设置是否只读 read_only 12019-01-28 15:05:02 - [info] 失效转移执行成功,当前数据库关闭访问查看新 Master 日志2019-01-28 15:05:04 - [info] 当前数据库提升为主库2019-01-28 15:05:04 - [info] 当前同步位置 Master mysql-bin.000015 323382019-01-28 15:05:04 - [info] 等待同步到 Master mysql-bin.000015 323382019-01-28 15:05:04 - [info] 同步完毕2019-01-28 15:05:04 - [info] 设置是否只读 read_only 02019-01-28 15:05:05 - [info] MySQL is ok查看新 Master IP,确认 VIP 已经飘过来了[root@cluster02 ~]# ip addr1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid_lft forever preferred_lft forever2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether fa:16:3e:66:7e:e8 brd ff:ff:ff:ff:ff:ff inet 10.0.0.248/16 brd 10.0.255.255 scope global eth0 inet 10.0.0.237/32 scope global eth0 inet6 fe80::f816:3eff:fe66:7ee8/64 scope link valid_lft forever preferred_lft forever查看插入数据执行情况,大概有 12 秒是不可用的Mon Jan 28 15:04:51 CST 2019ERROR 2003 (HY000): Can’t connect to MySQL server on ‘10.0.0.237’ (111)Mon Jan 28 15:04:52 CST 2019ERROR 2003 (HY000): Can’t connect to MySQL server on ‘10.0.0.237’ (111)Mon Jan 28 15:04:53 CST 2019ERROR 2003 (HY000): Can’t connect to MySQL server on ‘10.0.0.237’ (111)Mon Jan 28 15:04:54 CST 2019ERROR 2003 (HY000): Can’t connect to MySQL server on ‘10.0.0.237’ (111)Mon Jan 28 15:04:55 CST 2019ERROR 2003 (HY000): Can’t connect to MySQL server on ‘10.0.0.237’ (111)Mon Jan 28 15:04:56 CST 2019ERROR 2003 (HY000): Can’t connect to MySQL server on ‘10.0.0.237’ (111)Mon Jan 28 15:04:57 CST 2019ERROR 2003 (HY000): Can’t connect to MySQL server on ‘10.0.0.237’ (111)Mon Jan 28 15:04:58 CST 2019ERROR 2003 (HY000): Can’t connect to MySQL server on ‘10.0.0.237’ (111)Mon Jan 28 15:05:00 CST 2019ERROR 2003 (HY000): Can’t connect to MySQL server on ‘10.0.0.237’ (111)Mon Jan 28 15:05:01 CST 2019ERROR 2003 (HY000): Can’t connect to MySQL server on ‘10.0.0.237’ (111)Mon Jan 28 15:05:02 CST 2019ERROR 2003 (HY000): Can’t connect to MySQL server on ‘10.0.0.237’ (111)Mon Jan 28 15:05:03 CST 2019失效切换成功5 总结使用双主 + keepalived 的优点是部署简单,双主加半同步情况下,理论上不会丢数据,适用于中小型 MySQL 集群。缺点也比较明显,就是增加从节点的情况下,从节点不会主动切换同步对象,而且脚本需要自己实现,有一定风险。 ...
上接前文,前文提到web服务器附件不同步的问题,这里补上文件同步的配置。安装同步软件# 安装同步服务所需的软件yum -y install rsync配置密码本mkdir -p /etc/rsyncfg/# 注意:下面的两个SyncPwd必须一致echo ‘SyncName:SyncPwd’ > /etc/rsyncfg/server.pwdecho ‘SyncPwd’ > /etc/rsyncfg/client.pwd# 密码文件配置权限chmod 600 /etc/rsyncfg/server.pwdchmod 600 /etc/rsyncfg/client.pwd配置防火墙端口# 开启防火墙端口firewall-cmd –zone=public –add-port=873/tcp –permanentfirewall-cmd –reload配置同步软件# 编辑配置文件vim /etc/rsyncd.conf# 配置文件内容uid = rootgid = rootuse chroot = yesmax connections = 4exclude = lost+found/transfer logging = yestimeout = 900ignore nonreadable = yesdont compress = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2[uploads]path = /home/wwwroot/PublishPath/uploadscomment = Host:192.168.6.100 uploads filesignore errorsread only = yeswrite only = nolist = noauth users = syncersecrets file = /etc/rsyncfg/server.pwdhosts allow = 192.168.6.110重启服务service rsyncd restart && service rsyncd status执行同步操作echo ’’ > /etc/rsyncfg/sync.logecho ‘rsync -auv –password-file=/etc/rsyncfg/client.pwd SyncName@192.168.6.100::uploads /home/wwwroot/PublishPath/uploads/’ > /etc/rsyncfg/sync.shchmod +x /etc/rsyncfg/sync.shcp /etc/rsyncfg/sync.sh /usr/sbin/配置计划任务crontab -e# 添加任务# * * * * * /etc/rsyncfg/sync.sh # 取消前面的注释即可# 重启定时任务服务service crond restart && service crond status问题汇总ERROR: auth failed on module XXX@ERROR: auth failed on module XXXrsync error: error starting client-server protocol (code 5) at main.c(xxx) [Receiver=x.x.x]1、密码输入错误:请再次确认你登录用户的密码无误2、secrets file格式错误:secrets file的文件格式是 upload:123456表示upload用户的rsync密码是1234563、配置文件写错:最坑爹的一个,看看自己模块配置下面的auth users、secrets file有没写错4、secrets file权限问题服务端的secrets file权限必须是600,可以使用chmod 600 /home/user/test/rsync/etc/test.pass5、secrets file文件拥有者与rsync运行者服务端rsync服务是以什么用户运行,则必须保证secrets file文件拥有者必须是同一个假设root运行rsync –daemon,则secrets file的owner也必须是root6、如果是以–password-file=file的方式附带密码确保客户端密码文件格式无误,与服务端的密码文件不同,客户端的不用加上用户名,即直接是 123456rsync: failed to connect to X.X.X.X Connection timed out (110)rsync: failed to connect to 192.168.6.100 (192.168.6.100): Connection timed out (110)rsync error: error in socket IO (code 10) at clientserver.c(125) [Receiver=3.1.2]端口不通,开启防火墙的873端口:firewall-cmd –zone=public –add-port=873/tcp –permanentfirewall-cmd –reloadERROR: password file must not be other-accessibleERROR: password file must not be other-accessiblersync error: syntax or usage error (code 1) at authenticate.c(196) [Receiver=3.1.2]密码本权限不对:chmod 600 /etc/rsyncfg/server.pwdchmod 600 /etc/rsyncfg/client.pwd ...
前三篇已实现了最基本的负载均衡,但是还存在问题,如两个数据库不同步,上传的附件不同步,数据库没有制定备份计划,负载均衡参数还有待优化等问题。这里先把双机互备和自动备份的内容补齐。配置MySQL数据库的账户密码(以下命令仅用参考,这里的目的是要有一个可供内网其他服务器访问本机数据库的账户);# 停止数据库服务service mysql stop# 免验证启动数据库服务mysqld –user=mysql –skip-grant-tables –skip-networking# 登录mysqlmysql -u root mysql# 修改用户密码的几种方式mysql> UPDATE user SET authentication_string=PASSWORD(‘dbpwd’) where USER=‘dbadmin’;mysql> UPDATE user SET authentication_string=PASSWORD(‘dbpwd’) where USER=‘dbbaker’;mysql> UPDATE user SET Password=PASSWORD(‘dbpwd’) where USER=‘dbadmin’;mysql> alter user user() identified by “dbpwd”;# 使配置生效mysql> FLUSH PRIVILEGES;mysql> quit;# 重启mysql服务,注意,这里的mysql如果找不到服务,可以尝试mysqld,再不行就通过ps -ef | grep mysql找到进程ID(pid),然后通过kill -9 pid停止服务;service mysql restartmysql -udbadmin -p# Enter password: <输入新密码newpassword># 创建用户并配置权限:mysql> GRANT ALL ON . TO ‘dbadmin’@’%’ IDENTIFIED BY ‘dbpwd’ WITH GRANT OPTION;# 移除权限# REVOKE ALL ON . TO ‘dbadmin’@’%’;FLUSH PRIVILEGES;# 全局层级:.# 数据库层级:db_name.# 表层级:db_name.tbl_name# ALL是指分配所有权限,具体权限可以通过下面的查询语句查看# 查询用户权限select * from mysql.user \G;# 删除用户# delete from mysql.user where Host <> ‘%’;# 至此,数据库可以通过以上账户进行远程连接了。配置MySQL的双机互备 - 主数据库服务器(192.168.6.200 /etc/my.cnf的配置请参考LNMP+HAProxy+Keepalived负载均衡(三)- 配置文件汇总);# 在主数据库服务器上执行配置:vim /etc/my.cnf# 修改配置内容:server-id=6 # 数据库集群中唯一lower_case_table_names=1 # 新增行,数据表不区分大小写replicate_wild_do_table=sync_db_name.% # 只同步“sync_db_name”库下的表log-slave-updates=YES # 从服务器同步后记录日志# 保存配置后重启MySQL服务:service mysql restart# 进入MySQL命令行,查看主数据库状态信息,其中的“File”和“Position”值后面会用到:mysql> use sync_db_name;mysql> show master status;配置MySQL的双机互备 - 备数据库服务器(192.168.6.210);# 停止slave:mysql> stop slave;# 进入MySQL命令行,配置要同步的主库来源:mysql> CHANGE MASTER TO MASTER_HOST=‘192.168.6.200’,MASTER_PORT=10002,MASTER_USER=‘dbadmin’,MASTER_PASSWORD=‘dbpwd’,MASTER_LOG_FILE=‘mysql-bin.000016’,MASTER_LOG_POS=1285;# MASTER_HOST:主数据库的IP;# MASTER_PORT:主数据库的端口(int),默认3306;# MASTER_USER,MASTER_PASSWORD:主数据库账户、密码;# MASTER_LOG_FILE:主数据库中查询到的“File”值;# MASTER_LOG_POS:主数据库中查询到的“Position”值;# 启动slave:mysql> start slave;# 检查slave:mysql> show slave status \G;# 命令行汇总:show master status;stop slave;Slave_IO_Running、Slave_SQL_Running 均显示为 Yes 说明主备同步服务正常运行,如下图:同步数据库的初始状态; 在启动同步服务前,还需要手动同步下数据库的初始状态,之后可以通过修改其中主数据库中的表来查看从数据库是否同步变更;# 锁定要同步的数据库(192.168.6.200):msyql> use sync_db_name;msyql> flush tables with read lock;# 将要同步的数据库导出脚本:mysqldump -udbadmin -pdbpwd sync_db_name >/home/backup/sync_db_name.sql# 解锁前面锁定的数据库:msyql> unlock tables;# 将上方备份的sql拷贝到从数据库服务器(192.168.6.210),然后创建同名数据库,恢复数据:msyql> create database sync_db_name;msyql> use sync_db_name;msyql> source /home/backup/sync_db_name.sql;做双机互备或多机循环互备; 然后将主从数据库服务器反转(即将192.168.6.200和192.168.6.210的主备身份调换),然后再配置一次同步即可。即192.168.6.200变更会同步到192.168.6.210,反之亦然。简单讲就是: 双机互备:A主B从 + A从B主; 多机循环互备:A主B从 + B主C从 + C主N从 + N主A从(建议不要过多,尤其是数据库数据量大,且变更频繁的情况下,同步毕竟也是有延迟的);数据库的自动备份(前三步前面的文章都有提到);安装计划工具;yum -y install crontabs编辑MySQL的配置文件;vim /etc/my.cnf# 添加配置文件内容:[mysqldump]# 用于备份数据库user=dbbakerpassword=dbpwd重启数据库服务;service mysql restart & service mysql status准备备份脚本;mkdir -p /home/bakup/lgd_system# 编辑bakdb.sh的内容:echo ‘mysqldump sync_db_name | gzip > /home/backup/lgd_system/sync_db_name_$(date +%Y%m%d_%H%M%S).sql.gz’ > /home/bakup/bakdb.shchmod +x /home/bakcup/bakdb.sh# 解压缩指定的备份文件:gunzip sync_db_name_.gz添加备份计划;# 方式一:crontab -e# 方式二:vim /etc/crontab # 编辑计划:# Example of job definition:# .—————- minute (0 - 59) *表示每分钟# | .————- hour (0 - 23) *表示每小时# | | .———- day of month (1 - 31) *表示每天# | | | .——- month (1 - 12) OR jan,feb,mar,apr … *表示每月# | | | | .—- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat *表示每天# | | | | |# * * * * * user-name(用户名) command to be executed(脚本路径)# 30 10 * * * /home/backup/bakdb.sh # 表示每天10:30执行一次备份脚本(前方的注释去掉即可)计划任务常用操作命令;service crond start # 启动服务service crond stop # 关闭服务service crond restart # 重启服务service crond reload # 重新载入配置service crond status # 查看服务状态tail -f /var/log/cron # 查看执行日志备份文件解压缩gzip命令:选项参数:-c:将压缩后的数据显示到屏幕上,可以用于重定向;-d:解压缩的参数;-t:检验压缩的一致性,看是否有错误;-v:显示 源文件大小/压缩文件大小 的压缩比;-#:# 为数字的意思,代表压缩等級,-1 最快,但是压缩比最差、-9 最慢,但是压缩比最好!默认是 -6gzip -v => 压缩文件,-v查看压缩比gzip -d gunzip file.gz ...
Nginx的操作命令vim /usr/local/nginx/conf/nginx.conf# 将端口由80修改为10001,修改内容如下:listen 10001 default_server;# 具体配置可参考下面的nginx配置文件# 重启Nginx,并查看其状态;service nginx restart & service nginx statusNginx的配置文件(Web服务器需要修改的配置,仅用参考)user www www;worker_processes auto;error_log /home/wwwlogs/nginx_error.log crit;pid /usr/local/nginx/logs/nginx.pid;#Specifies the value for maximum file descriptors that can be opened by this process.worker_rlimit_nofile 51200;events{ use epoll; worker_connections 51200; multi_accept on;}http{ include mime.types; default_type application/octet-stream; server_names_hash_bucket_size 128; client_header_buffer_size 32k; large_client_header_buffers 4 32k; client_max_body_size 50m; sendfile on; tcp_nopush on; keepalive_timeout 60; tcp_nodelay on; fastcgi_connect_timeout 300; fastcgi_send_timeout 300; fastcgi_read_timeout 300; fastcgi_buffer_size 64k; fastcgi_buffers 4 64k; fastcgi_busy_buffers_size 128k; fastcgi_temp_file_write_size 256k; gzip on; gzip_min_length 1k; gzip_buffers 4 16k; gzip_http_version 1.1; gzip_comp_level 2; gzip_types text/plain application/javascript application/x-javascript text/javascript text/css application/xml application/xml+rss; gzip_vary on; gzip_proxied expired no-cache no-store private auth; gzip_disable “MSIE [1-6].”; #limit_conn_zone $binary_remote_addr zone=perip:10m; ##If enable limit_conn_zone,add “limit_conn perip 10;” to server section. server_tokens off; access_log off; server { # 端口根据自己的情况修改 listen 10001 default_server; server_name _; index index.html index.htm index.php default.html default.htm default.php; # 站点根目录 root /home/wwwroot/publishPath; include rewrite/laravel.conf; #error_page 404 /404.html; # Deny access to PHP files in specific directory #location ~ /(wp-content|uploads|wp-includes|images)/..php$ { deny all; } include enable-php.conf; location ~ ..(gif|jpg|jpeg|png|bmp|swf)$ { expires 30d; } location ~ ..(js|css)?$ { expires 12h; } location ~ /.well-known { allow all; } location ~ /. { deny all; } access_log off; } # 可以加载自己的配置文件,这里我把配置文件中的内容直接替换了原本的server节点配置; # include vhost/.conf;}MySQL的操作命令vim /etc/my.cnfservice mysql restart & service mysql statuslnmp restartMySQL的配置文件(DB服务器需要修改的配置,仅用参考)[client]port = 10002socket = /tmp/mysql.sock[mysqld]port = 10002socket = /tmp/mysql.sock# 数据库文件存放位置datadir = /home/lnmp/mysql/dataskip-external-lockingkey_buffer_size = 128Mmax_allowed_packet = 1Mtable_open_cache = 512sort_buffer_size = 2Mnet_buffer_length = 8Kread_buffer_size = 2Mread_rnd_buffer_size = 512Kmyisam_sort_buffer_size = 32Mthread_cache_size = 64query_cache_size = 64Mtmp_table_size = 64Mperformance_schema_max_table_instances = 4000explicit_defaults_for_timestamp = true#skip-networkingmax_connections = 500max_connect_errors = 100open_files_limit = 65535log-bin=mysql-binbinlog_format=mixedserver-id = 51lower_case_table_names = 1expire_logs_days = 10replicate_wild_do_table=lgd_system.%# relay_log=mysqld-relay-binlog-slave-updates=YESdefault_storage_engine = InnoDBinnodb_file_per_table = 1innodb_data_home_dir = /home/lnmp/mysql/datainnodb_data_file_path = ibdata1:10M:autoextendinnodb_log_group_home_dir = /home/lnmp/mysql/datainnodb_buffer_pool_size = 512Minnodb_log_file_size = 128Minnodb_log_buffer_size = 8Minnodb_flush_log_at_trx_commit = 1innodb_lock_wait_timeout = 50[mysqldump]# 数据库备份账户,自行创建并分配相应的权限user=bakuserpassword=ZXdfty^&quickmax_allowed_packet = 16M[mysql]no-auto-rehash[myisamchk]key_buffer_size = 128Msort_buffer_size = 2Mread_buffer = 2Mwrite_buffer = 2M[mysqlhotcopy]interactive-timeoutHAProxy的操作命令# 负载状态监测:# Web服务器HAProxy - http://192.168.6.111:8080/web# DB服务器HAProxy - http://192.168.6.211:8080/db# 如果需要通过外网访问,需要把8080端口映射到外网端口即可。# 常用命令:vim /etc/haproxy/haproxy.cfgservice haproxy restart & service haproxy statusHAProxy的配置文件(Web服务器)#———————————————————————# Global settings#———————————————————————global # 全局的日志配置,使用log关键字,指定使用127.0.0.1上的syslog服务中的local0日志设备,记录日志等级为info的日志 log 127.0.0.1 local3 # 软件工作目录 chroot /var/lib/haproxy # haproxy的pid存放路径,启动进程的用户必须有权限访问此文件 pidfile /usr/local/haproxy/haproxy.pid # 最大连接数,默认4000 maxconn 30000 # 所属用户 user haproxy # 所属组 group haproxy # 以守护进程方式运行haproxy daemon # turn on stats unix socket # stats socket /var/lib/haproxy/stats # socket路径#———————————————————————# common defaults that all the ’listen’ and ‘backend’ sections will# use if not designated in their block#———————————————————————defaults mode http # 默认的模式mode { tcp|http|health },tcp是4层,http是7层,health只会返回OK log global # 采用全局定义的日志 option httplog # 启用日志记录HTTP请求,默认haproxy日志记录是不记录HTTP请求日志 option dontlognull # 不记录健康检查的日志信息 option http-server-close # 每次请求完毕后主动关闭http通道 # 如果后端服务器需要获得客户端真实ip需要配置的参数,可以从Http Header中获得客户端ip option forwardfor except 127.0.0.0/8 option redispatch # serverId对应的服务器挂掉后,强制定向到其他健康的服务器 retries 3 # 3次连接失败就认为服务不可用,也可以通过后面设置 timeout http-request 10s # http请求超时时间 timeout queue 1m # 一个请求在队列里的超时时间 timeout connect 10s # 连接超时 timeout client 1m # 客户端连接超时 timeout server 1m # 服务器连接超时 timeout http-keep-alive 10s # 设置http-keep-alive的超时时间 timeout check 10s # 检测超时 maxconn 3000 # 最大连接数#———————————————————————# main frontend which proxys to the backends#———————————————————————# 前端配置frontend main *:80 acl url_static path_beg -i /static /images /javascript /stylesheets acl url_static path_end -i .jpg .gif .png .css .js use_backend static if url_static default_backend servers#———————————————————————# static backend for serving up images, stylesheets and such#———————————————————————# 后台静态文件服务配置backend static balance roundrobin server static1 192.168.6.100:10001 check inter 2000 fall 3 weight 50 server static2 192.168.6.110:10001 check inter 2000 fall 3 weight 50#———————————————————————# round robin balancing between the various backends#———————————————————————# 后台服务配置backend servers balance roundrobin # 添加cookie配置,将某客户端引导到之前为其服务过的后端服务器上,即和后端某服务器保持联系,防止登录验证失效 cookie app_cook insert nocache server app1 192.168.6.100:10001 check inter 2000 fall 3 weight 50 cookie server1 server app2 192.168.6.110:10001 check inter 2000 fall 3 weight 50 cookie server2# HAProxy状态监控服务配置listen stats # 绑定端口 bind *:8080 mode http # stats enable # 访问地址:192.168.6.100:8080/web 和 192.168.6.110:8080/web stats uri /web stats realm Global\ statistics # 管理员账户 stats auth hapadmin:1qazse$#2HAProxy的配置文件(DB服务器)#———————————————————————# Global settings#———————————————————————global pidfile /var/run/haproxy.pid maxconn 30000 user haproxy group haproxy daemon nbproc 1#———————————————————————# common defaults that all the ’listen’ and ‘backend’ sections will# use if not designated in their block#———————————————————————defaults mode tcp option redispatch retries 3 timeout queue 1m timeout connect 10s timeout client 1m timeout server 1m timeout check 10s maxconn 4096 option abortonclosefrontend main bind :3306 default_backend serversbackend servers server mysql1 192.168.6.200:10002 check inter 3000 fall 3 weight 50 server mysql2 192.168.6.210:10002 check inter 3000 fall 3 weight 50# 监控访问地址:192.168.6.210:8080/db 和 192.168.6.200:8080/dblisten stats mode http bind 0.0.0.0:8080 stats enable stats uri /db stats realm Global\ statistics stats auth dbadmin:1qazse$#2Keeplived的操作命令# 查看已安装的Keepalived的版本:keepalived -v# 查看配置:cat /etc/keepalived/keepalived.conf# 编辑配置文件:vim /etc/keepalived/keepalived.conf# 测试高可用的远程访问:mysql -h 远程数据库ip地址 -P 端口 -u 用户名 -pmysql -h 192.168.6.200 -P 3306 -u dbuser -p# 开通服务器间的 vrrp 协议通信,用于Keepalived通信:firewall-cmd –direct –permanent –add-rule ipv4 filter INPUT 0 –in-interface 网卡名称 –destination 224.0.0.18 –protocol vrrp -j ACCEPT;firewall-cmd –reload;# 服务器的网卡名称请根据自己的情况修改,# INPUT代表接收224.0.0.18的报文。# 在VIP服务器上测试VIP漂移:ip addr | grep 网卡名称# 停止VIP所在服务器的keepalived服务,并查看VIP是否移除,并查看备用服务器是否获取到VIP:service keepalived stop && service keepalived statusip addr | grep 网卡名称# 在之前停止keepalived服务的服务器上开启keepalived服务,查看VIP是否已取回:service keepalived start && service keepalived statusip addr | grep 网卡名称Keeplived的配置(Web服务器)Web主服务器的配置:# Master的配置内容:! Configuration File for keepalivedglobal_defs { notification_email { example@domain.com # 收邮件人,可以定义多个 } notification_email_from HaproxyMaster@web.haproxy # 发件人,可伪装 smtp_server 127.0.0.1 # 发送邮件的服务器地址 smtp_connect_timeout 30 # 连接超时时间 no_email_faults router_id WebMaster vrrp_skip_check_adv_addr vrrp_strict vrrp_garp_interval 0 vrrp_gna_interval 0}vrrp_script chk_haproxy { # HAProxy服务监测脚本 script ‘/etc/keepalived/check_haproxy.sh’ interval 2 weight 2}vrrp_instance VI_1 { # 每一个vrrp_instance就是定义一个虚拟路由器 state MASTER # 由初始状态状态转换为master状态 interface 网卡名称 # 网卡名称,如eth0,根据自己的情况修改 virtual_router_id 100 # 虚拟路由的id号,一般不能大于255的 priority 100 # 优先级,数字越大,优先级越高,主比次大 advert_int 1 # 初始化通告 authentication { # 认证机制 auth_type PASS auth_pass 666 # 密码,自行更改,主备一致即可 } track_script { chk_haproxy } virtual_ipaddress { # Web服务的虚拟ip地址:vip,前面提到的备用的虚拟IP。 #<IPADDR>/<MASK> brd <IPADDR> dev <STRING> scope <SCOPT> label <LABEL> #192.168.200.18/24 dev eth2 label eth2:1 192.168.6.111 } notify_master ‘/etc/keepalived/clean_arp.sh 192.168.6.111’}Web备服务器的配置:# Backup的配置内容:! Configuration File for keepalivedglobal_defs { notification_email { example@domain.com # 收邮件人,可以定义多个 } notification_email_from HaproxyBackup@web.haproxy # 发件人,可伪装 smtp_server 127.0.0.1 # 发送邮件的服务器地址 smtp_connect_timeout 30 # 连接超时时间 no_email_faults router_id WebBackup vrrp_skip_check_adv_addr vrrp_strict vrrp_garp_interval 0 vrrp_gna_interval 0}vrrp_script chk_haproxy { # HAProxy服务监测脚本 script ‘/etc/keepalived/check_haproxy.sh’ interval 2 weight 2}vrrp_instance VI_1 { # 每一个vrrp_instance就是定义一个虚拟路由器 state BACKUP # 由初始状态状态转换为backup状态 interface 网卡名称 # 网卡名称,如eth0,根据自己的情况修改 virtual_router_id 100 # 虚拟路由的id号,一般不能大于255的 priority 90 # 优先级,数字越大,优先级越高,主比次大 advert_int 1 # 初始化通告 authentication { # 认证机制 auth_type PASS auth_pass 666 # 密码,自行更改,主备一致即可 } track_script { chk_haproxy } virtual_ipaddress { # Web服务的虚拟ip地址:vip,前面提到的备用的虚拟IP。 #<IPADDR>/<MASK> brd <IPADDR> dev <STRING> scope <SCOPT> label <LABEL> #192.168.200.18/24 dev eth2 label eth2:1 192.168.6.111 } notify_master ‘/etc/keepalived/clean_arp.sh 192.168.6.111’}Keeplived的配置(DB服务器)DB主服务器的配置:# Master的配置内容:! Configuration File for keepalivedglobal_defs { notification_email { example@domain.com # 收邮件人,可以定义多个 } notification_email_from HaproxyMaster@db.haproxy # 发件人,可伪装 smtp_server 127.0.0.1 # 发送邮件的服务器地址 smtp_connect_timeout 30 # 连接超时时间 no_email_faults router_id DBMaster vrrp_skip_check_adv_addr vrrp_strict vrrp_garp_interval 0 vrrp_gna_interval 0}vrrp_script chk_haproxy { # HAProxy服务监测脚本 script ‘/etc/keepalived/check_haproxy.sh’ interval 2 weight 2}vrrp_instance VI_1 { # 每一个vrrp_instance就是定义一个虚拟路由器 state MASTER # 由初始状态状态转换为master状态 interface 网卡名称 # 网卡名称,如eth0,根据自己的情况修改 virtual_router_id 99 # 虚拟路由的id号,一般不能大于255的 priority 100 # 优先级,数字越大,优先级越高,主比次大 advert_int 1 # 初始化通告 authentication { # 认证机制 auth_type PASS auth_pass 666 # 密码,自行更改,主备一致即可 } track_script { chk_haproxy } virtual_ipaddress { # DB服务的虚拟ip地址:vip,前面提到的备用的虚拟IP。 #<IPADDR>/<MASK> brd <IPADDR> dev <STRING> scope <SCOPT> label <LABEL> #192.168.200.18/24 dev eth2 label eth2:1 192.168.6.211 } notify_master ‘/etc/keepalived/clean_arp.sh 192.168.6.211’}DB备服务器的配置:# Backup的配置内容:! Configuration File for keepalivedglobal_defs { notification_email { example@domain.com # 收邮件人,可以定义多个 } notification_email_from HaproxyBackup@db.haproxy # 发件人,可伪装 smtp_server 127.0.0.1 # 发送邮件的服务器地址 smtp_connect_timeout 30 # 连接超时时间 no_email_faults router_id DBBackup vrrp_skip_check_adv_addr vrrp_strict vrrp_garp_interval 0 vrrp_gna_interval 0}vrrp_script chk_haproxy { # HAProxy服务监测脚本 script ‘/etc/keepalived/check_haproxy.sh’ interval 2 weight 2}vrrp_instance VI_1 { # 每一个vrrp_instance就是定义一个虚拟路由器 state BACKUP # 由初始状态状态转换为master状态 interface 网卡名称 # 网卡名称,如eth0,根据自己的情况修改 virtual_router_id 99 # 虚拟路由的id号,一般不能大于255的 priority 90 # 优先级,数字越大,优先级越高,主比次大 advert_int 1 # 初始化通告 authentication { # 认证机制 auth_type PASS auth_pass 666 # 密码,自行更改,主备一致即可 } track_script { chk_haproxy } virtual_ipaddress { # DB服务的虚拟ip地址:vip,前面提到的备用的虚拟IP。 #<IPADDR>/<MASK> brd <IPADDR> dev <STRING> scope <SCOPT> label <LABEL> #192.168.200.18/24 dev eth2 label eth2:1 192.168.6.211 } notify_master ‘/etc/keepalived/clean_arp.sh 192.168.6.211’}创建Keepalived调用的脚本操作命令mkdir /etc/keepalived/echo ’’ > /etc/keepalived/check_haproxy.shecho ’’ > /etc/keepalived/clean_arp.shchmod +x /etc/keepalived/.sh# 然后编辑两个脚本的内容,如下/etc/keepalived/check_haproxy.sh#!/bin/bash# 判断haproxy是否已经启动if [ $(ps -C haproxy –no-header | wc -l) -eq 0 ]; then # 如果没有启动,则启动haproxy程序 haproxy -f /etc/haproxy/haproxy.cfgfi# 睡眠两秒钟,等待haproxy完全启动sleep 2# 判断haproxy是否已经启动if [ $(ps -C haproxy –no-header | wc -l) -eq 0 ]; then # 如果haproxy没有启动起来,则将keepalived停掉,则VIP自动漂移到另外一台haproxy机器,实现了对haproxy的高可用 service keepalived stop/etc/keepalived/clean_arp.sh#!/bin/shVIP=$1GATEWAY=192.168.6.255 # 本机的网卡网关地址/sbin/arping -I ens160 -c 5 -s $VIP $GATEWAY &>/dev/null发布文件的配置# 站点根目录赋权chmod -R 777 /home/wwwroot/publishPath# PHP环境配置vim /home/wwwroot/publishPath/.env# 编辑配置内容:APP_DEBUG=false# Web的内网VIP,如需外网访问,则需要将192.168.6.111映射到外网,然后将该处的IP改成外网IPAPP_URL=http://192.168.6.111DB_CONNECTION=mysql# DB的内网VIPDB_HOST=192.168.6.211# DB的内网端口DB_PORT=3306# 数据库名称DB_DATABASE=dbName# 数据库用户名DB_USERNAME=dbuser# 数据库密码DB_PASSWORD=dbpwd# 其他配置选项使用默认设置,这里省略。# 配置保存退出后重启php服务:service php-fpm restart关于IP的说明 以上说到的IP都是内网IP,所有的配置都使用内网IP即可。如需外网访问,只需要把两个虚拟IP和端口映射到外网即可(注意修改php配置的APP_URL)。 ...
日志服务修改日志服务配置并重启日志服务;vim /etc/rsyslog.conf编辑系统日志配置,指定包含的配置文件路径和规则:$IncludeConfig /etc/rsyslog.d/.conf为haproxy创建一个独立的配置文件;vim /etc/rsyslog.d/haproxy.conf编辑配置文件的内容如下:$ModLoad imudp # 取消注释$UDPServerRun 514 # 取消注释# 与“/etc/haproxy/haproxy.cfg”中的配置“log 127.0.0.1 local3”对应local3. /var/log/haproxy.log# 如果不加 “&~”,则除了在/var/log/haproxy.log中写入日志外,也会写入message文件&~配置“rsyslog”的主配置文件,开启远程日志;vim /etc/sysconfig/rsyslog修改配置内容如下:SYSLOGD_OPTIONS="-c 2 -r -m 0"# -c 2 使用兼容模式,默认是 -c 5# -r 开启远程日志# -m 0 标记时间戳,单位是分钟,为0表示禁用该功能重启HAProxy和日志服务并查看各自服务状态:service haproxy restart & service haproxy statusservice rsyslog restart & service rsyslog status# 查看PHP的错误日志配置cat /usr/local/php/etc/php.ini | grep error_log防火墙服务开通端口(根据自身需求配置):firewall-cmd –zone=public –add-port=3306/tcp –permanentfirewall-cmd –zone=public –add-port=873/tcp –permanentfirewall-cmd –zone=public –add-port=10002/tcp –permanentfirewall-cmd –zone=public –add-port=10001/tcp –permanentfirewall-cmd –zone=public –add-port=80/tcp –permanentfirewall-cmd –zone=public –add-port=8080/tcp –permanent重启/重新加载防火墙服务并查看其状态:systemctl restart firewalld.serviceservice firewalld restart && service firewalld statusfirewall-cmd –reload测试端口:telnet ip port第三方防火墙 这里推荐semanage,优点自行百度,安装配置:# 安装端口管理工具semanage;yum -y install policycoreutils-python# 查看已开通端口;semanage port -l|grep http# 开通端口;semanage port -a -t http_port_t -p tcp port_number # 开放端口port_number,要开通的端口号semanage port -d -t http_port_t -p tcp port_number # 关闭端口port_number,http_port_t为端口组名其他命令# 查看服务的pid:ps -ef | grep ServiceName# 停止服务:kill -9 service_pid# 查看端口占用情况:lsof -i tcp:80# 列出所有端口:netstat -ntlp# 分区及挂载操作# 查看当前空间df -h# 查看可用磁盘fdisk -lfdisk /dev/sdb# 创建分区,多数操作可以默认Command (m for help): m# 根据提示进行操作:# 分区后格式化mkfs -t ext4 /dev/sdb1mkfs -t ext4 /dev/sdb2# 挂载到已有目录mount -w /dev/sdb1 /mnt/lnmpmount -w /dev/sdb2 /mnt/backupmount -o remount -w /dev/sdb2 /mnt/backup ...
项目要求(商品列表):pageA -> pageB -> pageA 常用的:keep-alive 路由缓存(不多解说) 但上面很多时候,因页面需求原因,不能使用这种实现方式,在网上找了很多方法,但是都不是很好用,现在自己实现了一个还算不错的。 首先,在vue-router中,scrollBehavior这个方法是可以打印访问过的页面,滚动的位置的。【注意:在刷新页面时,不会触发该事件】 我们可以使用vuex储存滚动的位置(因页面会做接口请求数据,所以要在数据渲染完成后,再进行跳转) store.commit('SET_ROUTER_POSITION', savedPosition || {}) 好。我们获取到滚动的位置并且储存后,我们在需要在指定页面进行页面渲染后,调用滚动事件。 封装mixin方法,免得每个页面都需要写一次 ...
环境版本说明:服务器系统:CentOS 7.5:cat /etc/redhat-releaseCentOS Linux release 7.5.1804 (Core) # 输出结果服务器IP地址: 服务器A:192.168.6.100 服务器B:192.168.6.200LNMP版本: lnmp1.5 下载地址:http://soft.vpser.net/lnmp/ln…准备安装环境(两台服务器都需要执行):# 关闭selinux(如果是centos系统,默认会开启selinux,会引发很多权限问题)vim /etc/selinux/config# 把SELINUX=enforcing改为SELINUX=disabled# 保存退出,并执行下面的命令使配置立即生效:setenforce 0# 升级所有包,改变软件设置和系统设置,系统版本内核都升级# yum -y update# 升级所有包,不改变软件设置和系统设置,系统版本升级,内核不改变yum -y upgrade# 安装后面用到的软件yum -y install haproxy keepalived vim crontabs mlocate && updatedb# 创建文件夹,并将lnmp安装包下载到当前新创建的文件夹mkdir -p /home/soft && cd /home/soft && wget http://soft.vpser.net/lnmp/lnmp1.5-full.tar.gz# 解压安装包tar -xvf lnmp1.5-full.tar.gz安装lnmp:cd /home/soft/lnmp1.5-full./install.sh根据自己的需要选择MySQL、PHP等软件的版本,按提示操作,然后等待安装完成。我这里都选择最新版本。记好设置的相关密码,后面会用到。其他命令集合(仅用参考,无需执行):# 添加用户组和用户,并为其分配相关文件夹的最高权限:groupadd -r GroupName useradd -g UserName -M -s /sbin/nologin GroupNamechown -R GroupName:UserName /usr/local/haproxy# 工具版本查看mysql -uroot -pPwdStr # 登录后就可以看到mysql的版本nginx -v # nginx versionhaproxy -v # HA-Proxy versionkeepalived -v # keepalived 版本# 编辑配置文件集合:vim /etc/keepalived/keepalived.confvim /etc/rsyslog.conf # 编辑系统日志配置vim /etc/rsyslog.d/haproxy.conf # HAProxy的日志vim /etc/sysconfig/rsyslog # rsyslog的主配置vim /usr/local/nginx/conf/nginx.conf # Nginx的配置vim /etc/haproxy/haproxy.cfg # HAProxy的配置vim /etc/my.cnf # MySQL的配置# 将相关服务设置为开机启动:chkconfig nginx on # Web服务chkconfig mysql on # 数据库服务chkconfig haproxy on # 反向代理服务chkconfig keepalived on # 服务状态监测chkconfig crond on # 计划任务服务chkconfig rsyslog on # 日志服务# 重启各服务集合:service haproxy restart & service haproxy statusservice rsyslog restart & service rsyslog statusservice nginx restart & service nginx statusservice mysql restart & service mysql statusservice keepalived restart & service keepalived statusservice crond restart & service crond statuslnmp restart离线安装 如果要安装的服务器无法连接外网,安装就要麻烦很多,无法使用lnmp的一键安装包了。只能通过PC下载,然后远程上传到服务器,然后再编译安装。这里就不列举所有软件的安装。下载MySQL 点击官方下载 mysql-8.0.13-1.el7.x86_64.rpm-bundle.tar;安装MySQL# 卸载系统自带数据库:rpm -qa | grep MySQL-rpm -ev xxxrpm -e –nodeps mysqlyum -y remove mari*# 将下载的文件通过Xftp上传到服务器# 解压文件到当前目录:tar -xvf mysql-8.0.13-1.el7.x86_64.rpm-bundle.tar# 安装 MySQL:rpm -ivh MySQL_# 创建用户组和用户:groupadd -r mysqluseradd -g mysql mysql# 为MySQL的数据库文件夹授权:chown -R mysql:mysql /home/lnmp/mysql/data/# 相应的依赖 # 1. libaio # 2. net-tools # 3. perl# 安装perl./Configure -des -Dprefix=/usr/bin/perlmake && make testmake installperl -v# 只需要安装一下四个组件就可以了:# 因为具有依赖关系,所以需要按顺序执行:rpm -ivh mysql-community-common-.rpmrpm -ivh mysql-community-libs-.rpmrpm -ivh mysql-community-client-.rpmrpm -ivh mysql-community-server-*.rpm# 查看mysql是否启动service mysqld status# 启动mysqlservice mysqld start# 停止mysqlservice mysqld stop# 重启mysqlservice mysqld restart配置MySQL# 安装完成后,打印出的安装日志里面有一些有用的提示信息,如:# 查看临时密码:cat /root/.mysql_secret# /usr/bin/mysql_secure_installation# New default config file was created as /usr/my.cnf and# will be used by default by the server when you start it.# WARNING: Default config file /etc/my.cnf exists on the system# This file will be read by default by the MySQL server# If you do not want to use this, either remove it, or use the# –defaults-file argument to mysqld_safe when starting the server# 登录后修改密码:mysql> SET PASSWORD = PASSWORD(‘DBPwdStr’);# 为数据库创建访问账户,修改账户的限制IP,查询用户表:mysql> GRANT ALL ON . TO ‘username’@’%’ IDENTIFIED BY ‘DBPwdStr’ WITH GRANT OPTION;mysql> update mysql.user set host=’%’ where host=’::1’;mysql> delete from mysql.user where host<>’%’;mysql> select * from mysql.user \G;# 编辑MySQL的配置文件:vim /etc/my.cnf# 启动MySQL服务:service mysql restart && service mysql status# 启动错误# The server quit without updating PID file (/home/lnmp/mysql/data/localhost.localdomain.pid).# 1.可能是/usr/local/mysql/data/rekfan.pid文件没有写的权限# 解决方法 :给予权限,执行 “chown -R mysql:mysql /var/data” “chmod -R 755 /usr/local/mysql/data” 然后重新启动mysqld!# 2.可能进程里已经存在mysql进程# 解决方法:用命令“ps -ef|grep mysqld”查看是否有mysqld进程,如果有使用“kill -9 进程号”杀死,然后重新启动mysqld!# 3.可能是第二次在机器上安装mysql,有残余数据影响了服务的启动。# 解决方法:去mysql的数据目录/data看看,如果存在mysql-bin.index,将它删除。# 4.mysql在启动时没有指定配置文件时会使用/etc/my.cnf配置文件,查看该文件的[mysqld]下有没有指定的数据目录(datadir)。# 解决方法:请在[mysqld]下设置这一行:datadir = /usr/local/mysql/data安装计划任务管理工具 - crontabs 点击链接下载 crontabs-1.11-6.20121102git.el7.noarch.rpm,如需下载其他版本,请访问官网; 安装:rpm -ivh crontabs-1.11-6.20121102git.el7.noarch.rpm 添加自动备份任务,具体操作请参考MySQL的自动备份。下载(需要连接VPN)并安装HAProxy 点击链接下载 haproxy-1.5.19.tar.gz,如需下载其他版本请访问官网; 安装HAProxy:# 添加用户组和用户:groupadd -r haproxy useradd -g haproxy -M -s /sbin/nologin haproxy# 为安装文件夹授权:chown -R haproxy:haproxy /usr/local/haproxy# 查看内核:uname -r# 解压安装包tar -xvf haproxy-1.5.19.tar.gzcd haproxy-1.5.19# 根据内核版本进行编译(这里的版本对应的目标是linux310):make TARGET=linux310 ARCH=x86_64 PREFIX=/usr/local/haproxymake install PREFIX=/usr/local/# 将可执行文件拷贝到全局目录下:cp /usr/local/haproxy/sbin/haproxy /usr/sbin/haproxy配置HAProxy# 配置HAProxy;cat /etc/haproxy/haproxy.cfgvim /etc/haproxy/haproxy.cfg# 编辑配置文件内容,请参考HAProxy的负载均衡# 重启HAProxy服务;haproxy -f /etc/haproxy/haproxy.cfg# 测试HAProxy;ps -ef | grep haproxy# 访问HAProxy代理的地址和端口,分别停掉备服务器的Nginx服务后,继续访问正常则说明基本配置没问题;下载并安装Keepalived 点击链接下载Keepalived 1.4.5,下载其他版本请访问官网; 安装Keeplived;tar -xvf keepalived-1.4.5.tar.gzcd keepalived-1.4.5./configure –prefix=/usr/local/keepalivedmake && make installmkdir /etc/keepalivedcp /usr/local/keepalived/sbin/keepalived /usr/bin/keepalivedcp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/keepalived.confcp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/keepalived# 设置开机启动chkconfig keepalived on# 服务操作命令service keepalived startservice keepalived stopservice keepalived restartservice keepalived statusservice keepalived restart & service keepalived status配置Keepalived;# 编辑配置文件:vim /etc/keepalived/keepalived.conf# 主从服务器的配置略有差别,具体配置请参照Keepalived的配置; ...
上篇文章 MySQL集群搭建(3)-MMM高可用架构 介绍了 MMM 高可用集群的搭建方法, 里面有提到 MMM 可以配置多个读 VIP, 今天这篇文章教大家怎么用 LVS 对这些读 VIP 做一个负载均衡。1 LVS 介绍1.1 简介LVS 是 Linux Virtual Server 的简写,意即 Linux 虚拟服务器,是一个虚拟的服务器集群系统。本项目在 1998 年 5 月由章文嵩博士成立,是中国国内最早出现的自由软件项目之一。LVS 集群采用 IP 负载均衡技术和基于内容请求分发技术。调度器具有很好的吞吐率,将请求均衡地转移到不同的服务器上执行,且调度器自动屏蔽掉服务器的故障,从而将一组服务器构成一个高性能的、高可用的虚拟服务器。比如说,用 LVS 做 Web 负载均衡,那么请求 LVS 调度器的时候,请求会根据配置的算法分发给后端某台 Web 服务器,后端 Web 服务器机器对于请求者来说是透明的。1.1 LVS 工作模式LVS 包含以下三种常用工作模式1). NAT 模式NAT (Network Address Translation) 即网路地址装换,NAT 的工作原理是更改报文头(目标地址、源地址和端口等)后,转发请求都后端地址。流程如下客户端请求 LVS 的 IPLVS 更改请求的目的 IP,改为后端服务器其中一个 IP,然后转发请求后端服务器处理完,返回数据给 LVS,LVS 更改源 IP 为 LVS 机器的 IP 然后返回给请求端NAT 模式的所有数据都会经过 LVS 服务器,简单来说就是从 LVS 进,从 LVS 出,如图2). TUN 模式在 NAT 的集群系统中,请求和响应的数据报文都需要通过 LVS 服务器,当真实服务器的数目在10台和20台之间时,负载调度器将成为整个集群系统的新瓶颈。大多数 Internet服务都有这样的特点:请求报文较短而响应报文往往包含大量的数据。如果能将请求和响应分开处理,即在负载调度器中只负责调度请求而响应直接返回给客户,将极大地提高整个集群系统的吞吐量。IP 隧道(IP tunneling)是将一个IP报文封装在另一个IP报文的技术,这可以使得目标为一个IP地址的数据报文能被封装和转发到另一个IP地址。IP隧道技 术亦称为IP封装技术(IP encapsulation)。IP隧道主要用于移动主机和虚拟私有网络(Virtual Private Network),在其中隧道都是静态建立的,隧道一端有一个IP地址,另一端也有唯一的IP地址。我们利用IP隧道技术将请求报文封装转发给后端服务器,响应报文能从后端服务器直接返回给客户(要求后端真实服务器与外部网络连接)。TUN 模式工作流程如下:客户端请求数据,调度器根据各个服务器的负载情况,动态地选择一台服务器, 将请求报文封装在另一个IP报文中,再将封装后的IP报文转发给选出的服务器服务器收到报文后,先将报文解封获得原来目标地址为VIP的报文,服务器发 现VIP地址被配置在本地的IP隧道设备上,所以就处理这个请求,然后根据路由表将响应报文直接返回给客户。3). DR 模式DR 模式中,负载调度器中只负责调度请求,而服务器直接将响应返回给客户, DR 模式架构图DR 模式的执行流程如下客户端请求数据,调度器根据各个服务器的负载情况,动态地选择一台服务器,不修改也不封装IP报文,而是将数据帧的MAC 地址改为选出服务器的 MAC 地址,再将修改后 的数据帧在与服务器组的局域网上发送。因为数据帧的 MAC 地址是选出的服务器,所以服务器肯定可以收到这个数据帧,从中可以获得该 IP 报文。当服务器发现 报文的目标地址VIP是在本地的网络设备上,服务器处理这个报文,然后根据路由表将响应报文直接返回给客户。关于三种模式选择NAT模式下,所有流量会经过 LVS 服务器, 很容易有瓶颈;TUN 模式需要内核支持,部署成本比较高;DR模式性能高、容易部署,一般使用这种模式。本小节内容参考: LVS集群中的IP负载均衡技术1.2 LVS 调度算法这里简单介绍 LVS 的 8 种调度算法静态调度轮询调度(rr): 轮询调就是依次将请求调度不同的服务器,即每次调度执行i = (i + 1) mod n,并选出第i台服务器。算法的优点是其简洁性,它无需记录当前所有连接的状态,所以它是一种无状态调度。加权轮询(wrr): 加权轮询算法可以解决服务器间性能不一的情况,它用相应的权值表示服务器的处理性能,服务器的缺省权值为1。假设服务器A的权值为1,B的 权值为2,则表示服务器B的处理性能是A的两倍。加权轮询调度算法是按权值的高低和轮叫方式分配请求到各服务器。源地址散列(sh): 该算法正好与目标地址散列调度算法相反,它根据请求的源IP地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器,若该服务器是可用的且未超载,将请求发送到该服务器,否则返回空。目标地址散列(dh): 该算法也是针对目标IP地址的负载均衡,但它是一种静态映射算法,通过一个散列(Hash)函数将一个目标IP地址映射到一台服务器。动态调度最少连接(lc): 最少连接是把新的连接请求分配到当前连接数最小的服务器。加权最少连接(wlc): 加权最少连接算法是最小连接调度的超集,各个服务器用相应的权值表示其处理性能。基于局部性的最少连接(lblc): 该算法是针对请求报文的目标IP地址的负载均衡调度,目前主要用于Cache集群系统,因为在Cache集群中 客户请求报文的目标IP地址是变化的。带复制的基于局部性最少连接(lblcr): 该算法也是针对目标IP地址的负载均衡,目前主要用于Cache集群系统。它与LBLC算法的不同之处是它要 维护从一个目标IP地址到一组服务器的映射,而LBLC算法维护从一个目标IP地址到一台服务器的映射。本小节内容参考: LVS集群的负载调度2 Keepalived 简介Keepalived 起初是为 LVS 件设计, 用来管理和监控 LVS 各个服务器节点状态的工具Keepalived 采用 Master/Slave 模式, 在 Master 上设置配置文件的 VIP,当 Master 宕机后,VIP 自动漂移到另一台 Keepalived 服务器上Keepalived 可以用来做各种软件的高可用集群,它会一直检测服务器的状态,如果有一台服务器宕机,或工作出现故障,Keepalived 将检测到,并将有故障的服务器从系统中剔除,同时使用其他服务器代替该服务器的工作,当服务器工作正常后 Keepalived 自动将服务器加入到服务器群中。简单来说,Keepalived 就是用来实现机器的高可用的,在使用 Keepalived 的情况下,只有一台服务器能够提供服务(通过 VIP 来实现),当 Master 主机宕机后,VIP 会自动飘移到另一台服务器3 环境准备3.1 服务器与 MySQL 环境MySQL 环境采用上篇文章部署的那一套,然后新增一台服务器作为 LVS 的备用节点节点信息IP系统端口MySQL版本节点读写说明10.0.0.247Centos6.533065.7.9Master读写主节点10.0.0.248Centos6.533065.7.9Standby只读,可切换为读写备主节点10.0.0.249Centos6.533065.7.9Slave只读从节点10.0.1.24Centos6.5–MMM Monitor/LVS-MMM Monitor/LVS Keepalive Master10.0.1.85Centos6.5–LVS-LVS Keepalive SlaveVIP 信息简称VIP类型RW-VIP10.0.0.237读写VIPRO-VIP110.0.0.238读VIPRO-VIP210.0.0.239读VIPLVS-RO10.0.0.236LVS Keepalived VIP3.2 Keepalved 安装配置我们在10.0.1.24和10.0.1.85上部署 Keepalived1). yum 安装如果有对应的 yum 源,直接安装就可以了yum install -y keepalived2). 源码安装下载安装包, 下载地址 keepalived, 使用 1.2.24 版本举例# 安装依赖yum install -y gcc popt-devel openssl openssl-devel libssl-dev libnl-devel popt-devel libnfnetlink-devel# 下载包wget http://www.keepalived.org/software/keepalived-1.2.24.tar.gz# 解压安装tar -xvz -f keepalived-1.2.24.tar.gzcd keepalived-1.2.24./configure –prefix=/usr/local/keepalivedmake && make installcp /usr/local/keepalived/sbin/keepalived /usr/sbin/cp /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/mkdir /etc/keepalived/cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/3). 配置 Keepalived打开 /etc/keepalived/keepalived.conf 文件, 加上上面的配置global_defs { notification_email { } router_id MYSQL_MMM}vrrp_instance MMM_TEST { state BACKUP interface eth0 virtual_router_id 24 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 10.0.0.236 }}router_id: 标识用的state: MASTER或BACKUP, 当其他节点起来的时候会重新选举,所以这里设为 BACKUP 就可以了virtual_router_id: 用来区分 VRRP 组播的标记,取值 0-255priority: 优先级advert_int: 监控检测间隔authentication: 认证相关virtual_ipaddress: 要设置的 VIP注意: 在同一个广播域内 virtual_router_id 不能重复 4). 启动由于在priority都相同,所以先启动为 Master, 我们在10.0.1.24和10.0.1.85上轮流启动Keepalived/etc/init.d/keepalived start启动后观察10.0.1.24 IP 状态[root@chengqm ~]# ip addr1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid_lft forever preferred_lft forever2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether fa:16:3e:ee:ae:a1 brd ff:ff:ff:ff:ff:ff inet 10.0.1.24/16 brd 10.0.255.255 scope global eth0 inet 10.0.0.236/32 scope global eth0 inet6 fe80::f816:3eff:feee:aea1/64 scope link valid_lft forever preferred_lft forever3.3 LVS 安装配置本次测试,负载调度的算法采用 加权最少连接(wlc),工作模式采用 DR 模式1). 安装LVS 采用 yum 安装就可以了yum install -y ipvsadm2). 增加配置文件继续打开 /etc/keepalived/keepalived.conf 文件, 在后面加上 LVS 配置, 转发VIP为10.0.0.236的3306端口到MMM的虚IPvirtual_server 10.0.0.236 3306 { delay_loop 6 # 健康检查时间,单位是秒 lb_algo wlc # 负载调度的算法 lb_kind DR # LVS 工作模式 nat_mask 255.255.255.255 # 掩码 persistence_timeout 0 protocol TCP real_server 10.0.0.237 3306 { # 指定后端真实服务器的IP地址, 这里直接指到 MMM 虚 IP 上 weight 1 # 节点权重, 数字越大, 权重越大 TCP_CHECK { # 检测参数 connect_timeout 10 nb_get_retry 3 delay_before_retry 3 connect_port 3306 } } real_server 10.0.0.238 3306 { weight 3 TCP_CHECK { connect_timeout 10 nb_get_retry 3 delay_before_retry 3 connect_port 3306 } } real_server 10.0.0.239 3306 { weight 3 TCP_CHECK { connect_timeout 10 nb_get_retry 3 delay_before_retry 3 connect_port 3306 } }} 更改完毕重启 keepalived3). 后端真实服务器抑制 ARP 广播由于 DR 模式的原理是 LVS 与后端真实服务器配置同一个 VIP,后端服务器 不允许arp广播,这样路由器接收到请求就会发给 LVS,LVS 修改请求的 MAC 地址。这样路由器和后端服务器通过 MAC 地址进行通信,达到负载均衡的目的。在 10.0.0.247, 10.0.0.248, 10.0.0.249 服务器上执行以下命令VIP=10.0.0.236ifconfig lo:0 $VIP netmask 255.255.255.255 broadcast $VIP/sbin/route add -host $VIP dev lo:0echo “1” >/proc/sys/net/ipv4/conf/lo/arp_ignoreecho “2” >/proc/sys/net/ipv4/conf/lo/arp_announceecho “1” >/proc/sys/net/ipv4/conf/all/arp_ignoreecho “2” >/proc/sys/net/ipv4/conf/all/arp_announcesysctl -p >/dev/null 2>&1注意: 后端真实服务器的 VIP 绑在 lo 上如果想取消,可以反着操作ifconfig lo:0 downroute del VIP >/dev/null 2>&1echo “0” >/proc/sys/net/ipv4/conf/lo/arp_ignoreecho “0” >/proc/sys/net/ipv4/conf/lo/arp_announceecho “0” >/proc/sys/net/ipv4/conf/all/arp_ignoreecho “0” >/proc/sys/net/ipv4/conf/all/arp_announce4). 检查 LVS 状态[root@chengqm ~]# ipvsadm -lIP Virtual Server version 1.2.1 (size=4096)Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConnTCP 10.0.0.236:mysql wlc -> 10.0.0.237:mysql Route 1 0 0 -> 10.0.0.238:mysql Route 3 0 0 -> 10.0.0.239:mysql Route 3 0 0 LVS 负载均衡已经生效4 测试4.1 负载均衡测试LVS 配置好了,让我们测试一下效果, 目前 Keepalived Master在 10.0.1.24, 并且已经预先创建了一个测试账号,那么我们在其他机器发起请求看看[root@mysql-test-83 ~]# mysql -umytest -p -h10.0.0.236 -P3306 -e “show variables like ‘hostname’“Enter password: +—————+———–+| Variable_name | Value |+—————+———–+| hostname | cluster01 |+—————+———–+[root@mysql-test-83 ~]# mysql -umytest -p -h10.0.0.236 -P3306 -e “show variables like ‘hostname’“Enter password: +—————+———–+| Variable_name | Value |+—————+———–+| hostname | cluster02 |+—————+———–+可以看到,LVS 负载均衡已经生效4.2 高可用测试10.0.1.24 和 10.0.1.85部署了 Keepalived服务,我们停掉Master的Keepalived, VIP 会自动飘移到另一台机器现在停掉10.0.1.24的Keepalived[root@chengqm ~]# /etc/init.d/keepalived stopStopping keepalived: [ OK ]查看10.0.1.85的IP[root@yexm ~]# ip addr1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid_lft forever preferred_lft forever2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether fa:16:3e:3c:81:1b brd ff:ff:ff:ff:ff:ff inet 10.0.1.85/16 brd 10.0.255.255 scope global eth0 inet6 fe80::f816:3eff:fe3c:811b/64 scope link valid_lft forever preferred_lft forever[root@yexm ~]# ip addr1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid_lft forever preferred_lft forever2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether fa:16:3e:3c:81:1b brd ff:ff:ff:ff:ff:ff inet 10.0.1.85/16 brd 10.0.255.255 scope global eth0 inet 10.0.0.236/32 scope global eth0 inet6 fe80::f816:3eff:fe3c:811b/64 scope link valid_lft forever preferred_lft forever可以看到 VIP 已经飘移到另一台 LVS 服务器5 结语LVS + MMM下既可以实现多台 MySQL 节点的负载均衡,也避免了因为同步延迟、同步失败等问题造成的数据不一致问题,是一个非常不错的架构方式。参考: http://www.linuxvirtualserver.org/zh/lvs1.html ...
前言关于HTTP的知识比较繁杂,也比较零散,于是想要通过这篇文章对常用知识点进行总结,一些知识点描述是从网上搜集而来,如有侵权,可以联系我进行修改。提出问题Http的报文结构。Http request的几种类型。Http的状态码含义。Http1.1和Http1.0的区别,以及缓存原理Http长连接keep-alive。Cookie与Session的作用于原理。电脑上访问一个网页,整个过程是怎么样的:DNS、HTTP、TCP、OSPF、IP、ARP。解答1. Http的报文结构http协议的请求报文和响应报文都是由以下4部分组成:请求行请求头空行 CR + LF,回车 + 换行请求体2. Http request的几种类型请求行Request格式:【方法 URL HTTP版本】 例如: GET /csrfToken HTTP/1.1HTTP版本:目前有 HTTP/1.0、HTTP/1.1、HTTP/2.0 版本,其中 HTTP1.1 版本使用较广泛方法说明支持HTTP协议版本GET获取资源1.0 、1.1POST传输实体主体1.0、1.1PUT传输文件1.0、1.1HEAD获得报文首部1.0、1.1DELETE删除资源1.0、1.1OPTIONS询问支持的方法1.1TRACE追踪路径1.1CONNECT要求用隧道协议连接代理1.1LINK建立和资源之间的联系1.0UNLINK断开连接关系1.0Response格式:【HTTP版本 状态码 描述】 例如: HTTP/1.1 200 OK、HTTP/1.1 404 NOT FOUND 类别原因短语1xxInformational(信息性状态码)接收的请求正在处理2xxSuccess(成功状态码)请求正常处理完毕3xxRedirection(重定向状态码)需要进行附加操作以完成请求4xxClient Error(客户端错误状态码)服务器无法处理请求5xxServer Error(服务器错误状态码)服务器处理请求出错3. Http的状态码含义常用状态码200:OK,请求被正常处理204:No Content,请求被受理但没有资源可以返回,返回204响应,浏览器显示的页面不发生更新206:Partial Content,客户端进行范围请求,服务器成功执行了这部分的GET请求,响应报文中包含由Content-Range指定范围的实体内容301:Moved Permanently,永久性重定向,比如访问http://test.zhixue.com/zbptadmin,服务器会返回301,response的headers中会包含一个字段:Location: http://test.zhixue.com/zbptadmin/,浏览器会按照这个地址重新请求,并且如果用户保存了书签,浏览器会自动按照Location更新书签302:Found,临时性重定向,和301类似,但是浏览器不会更新书签303:See Other,和302类似,但303明确表示客户端应该使用GET方法获取Location资源备注:当301,302,303响应状态码返回时,几乎所有的浏览器都会把POST改成GET,并删除请求报文内的主体,之后请求会自动再次发送。301,302标准是禁止将POST方法改成GET方法的,但实际使用时浏览器厂商都会这么做。304:Not Modified,发送附带条件的请求时,(附带条件的请求是指采用GET方法的请求报文中包含If-Match,If-Modified-Since,If-None-Match,If-Range,If-Unmodified-Since中任一首部),条件不满足返回304,可直接使用客户端缓存,与重定向无关307:Temporary Redirect,临时重定向,与302类似,只是强制要求使用POST方法400:Bad Request,请求报文中存在语法错误,服务器无法识别401:Unauthorized,请求需要认证403:Forbidden,请求对应的资源禁止被访问404:Not Found,服务器无法找到对应资源500:Internal Server Error,服务器内部错误503:Service Unavailable,服务器正忙常见HTTP首部字段通用首部字段(请求报文与响应报文都会使用的首部字段)Date:创建报文的时间Connection:连接的管理Cache-Control:缓存的控制Transfer-Encoding:报文主题的传输编码方式请求首部字段(请求报文会使用的首部字段)Host:请求资源所在的服务器Accept:可处理的媒体类型Accept-Charset:可接收的字符集Accept-Encoding:可接收的内容编码Accept-Language:可接收的自然语言响应首部字段(响应报文会使用的首部字段)Accept-Range:可接收的字节范围Location:让客户端重定向到的URIServer:HTTP服务器的安装信息实体首部字段(请求报文与响应报文的实体部分使用的首部字段)Allow:资源可支持的HTTP方法Content-Type:实体主类的类型Content-Encoding:实体主体适用的编码方式Content-Language:实体主体的自然语言Content-Length:实体主体的字节数Content-Range:实体主体的位置范围,一般用于发出部分请求时使用4. HTTP1.0、HTTP1.1、HTTP2.0区别HTTP1.0 和 HTTP1.1 主要区别长连接HTTP1.0需要使用keep-alive参数告知服务器要建立一个长连接,而HTTP1.1默认支持长连接HTTP是基于TCP/IP协议的,创建一个TCP连接是需要经过三次握手的,有一定的开销,如果每次通讯都要重新建立连接的话,对性能有影响。因此最好能维持一个长连接,可以用这个长连接来发送多个请求节约带宽HTTP1.1支持只发送header信息,也就是HTTP的HEAD Method,如果服务器认为客户端有权限请求服务器,则返回100,否则返回401。客户端如果接收到100,才开始把请求体body发送到服务器。这样,当服务器返回401的时候,客户端就可以不用发送请求体了,节约了带宽HTTP1.1支持分块传输,比如206状态码,由Content-Range指定传输内容,这是支持文件断点续传的基础。HOST域现在一台服务器上可以有多个虚拟主机,这些虚拟站点可以共享同一个ip和端口,HTTP1.0是没有host域的,HTTP1.1才支持这个参数HTTP1.1 和 HTTP2.0的区别多路复用HTTP2.0使用了多路复用的技术,做到同一个连接并发处理多个请求,而且并发请求的数量比HTTP1.1大了好几个数量级当然HTTP1.1也可以多建立几个TCP连接,来支持处理更多并发的请求,但是创建TCP连接本身也是有开销的TCP连接有一个预热和保护的过程,先检查数据是否传送成功,一旦成功过,则慢慢加大传输速度。因此对应瞬时并发的连接,服务器的响应就会变慢。所以最好能使用一个建立的连接,并且这个连接可以支持瞬时并发的请求HTTP/1.1,若干个请求排队串行化单线程处理,后面的请求等待前面请求的返回才能获得执行机会,一旦有某个请求超时,后续请求只能被阻塞,也就是人们常说的线头阻塞HTTP/2.0,多个请求可同时在一个连接上并行执行,某个任务耗时严重,不会影响到其他连接的正常执行数据压缩HTTP1.1不支持header数据的压缩,HTTP2.0使用HPACK算法对header的数据进行压缩,这样数据体积小了,在网络上传输就会更快服务器推送当我们对HTTP2.0的web server请求数据的时候,服务器会顺便把一些客户端需要的资源一起推送到客户端,免得客户端再次创建连接发送请求到服务器获取。这种方式非常适合加载静态资源。服务器推送的这些资源其实存在客户端的某个地方,客户端直接从本地加载这些资源就可以了,不用走网络,速度自然快很多。HTTP缓存缓存分类强缓存浏览器在加载资源时,先根据这个资源的一些http header判断它是否命中强缓存,如果命中,浏览器直接从自己的缓存中读取资源,不会发请求到服务器,此时状态码是200,但是看Size项是from memory cache或from disk cache协商缓存当强缓存没有命中时,浏览器一定会发送一个请求到服务器,通过服务器端依据资源的另外一些http header验证这个资源是否命中协商缓存,如果命中,服务器会将这个请求返回304,但是不会返回这个资源的数据,而是告诉客户端可以直接从缓存中加载这个资源,于是浏览器就又会从自己的缓存中去加载这个资源;如果没有命中,则将资源返回客户端,状态为200,浏览器同时依据response header中的相关项更新本地缓存数据from memory cache 和 from disk cache区别from memory cache 是从内存中读取缓存资源,很快,关闭浏览器后,内存中的资源就消失了from disk cache 是从磁盘中读取缓存资源,要比 from memory cache 慢,但是持久化,关闭浏览器后仍然存在哪些资源存在memory,哪些资源存在disk看了一些文章,大部分观点是说:资源在disk和memory中都会存当关闭浏览器,再打开那个页面的时候,从disk cache中获取缓存资源,同时将缓存资源存在了内存中,当再次刷新页面的时候,就从memory cache中读取,因为这样会更快一些我自己试了一些页面,再次刷新还是有的from disk cache,有的from memory cache,所以这个持保留观点还有的文章说css文件存在disk中,js等脚本存在memory中,个人认为这个不太靠谱,因为memory中的缓存在关闭浏览器就消失了,如果js只存在memory,就起不到缓存的作用了强缓存相关http headerExpiresExpires的值是服务端返回的到期时间,用GMT格式的字符串表示,如:Expires: Thu, 31 Dec 2016 23:55:55 GMT。即下一次请求时,请求时间小于服务器返回的到期时间,直接使用缓存数据。不过Expires是HTTP1.0的东西,现在浏览器默认使用HTTP1.1,所以它的作用基本忽略。另一个问题是,到期时间是由服务器生成的,但是客户端时间可能和服务器时间有偏差,这就会导致缓存命中的误差。所以HTTP1.1的版本中,使用Cache-Control替代。Cache-ControlCache-Control是最重要的规则。常见的取值有:- private:客户端可以缓存- public:客户端和代理服务器都可以缓存- max-age=xxx:缓存的内容将在xxx秒后失效,单位是秒- no-cache:需要使用协商缓存来验证缓存数据- no-store:不缓存协商缓存相关http header第1组:Last-Modified/If-Modified—SinceLast-Modified:第一次请求资源时,服务器返回的http header,告诉浏览器资源的最后修改时间,为GMT格式,如Last-Modified: Thu, 24 Jan 2017 23:55:55 GMTIf-Modified-Since:再次请求服务器资源时,浏览器设置在请求header中,值 为该资源第一次请求时服务器设置的Last-Modified`值,如If-Modified-Since: Thu, 24 Jan 2017 23:55:55 GMT,服务器收到请求后发现request header中有If-Modified-Since,则与被请求资源的最后修改时间进行比对。若资源的最后修改时间大于If-Modified-Since,说明资源又被改动过,则返回资源内容,状态码200,同时浏览器依据相应response header更新缓存资源;若资源的最后修改时间小于或等于If-Modified-Since,说明资源无新修改,则返回状态码304,但是不返回资源,告知浏览器继续使用所保存的cache第2组:Etag/If-None-MatchEtag:服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识(生成规则由服务器确定),如Etag: W/“5886c231-8d9"If-None-Match:再次请求服务器时,通过此字段告知服务器该资源的唯一标识,如If-None-Match: W/“5886c231-8d9”,服务器收到请求后发现request header中有If-None-Match,则与被请求资源的唯一标识进行比对,若不同,说明资源又被改动过,则返回资源内容,状态码200,同时浏览器依据相应response header更新缓存资源;若相同,则说明资源无更改,返回304,告知浏览器继续使用所保存的缓存资源为什么要有Etag?Last-Modified颗粒度是秒,只能记录秒级的修改,比如1s内修改了N次,If-Modified-Since就无法判断了,所以要引入Etag。总结先执行强缓存策略,服务器通知浏览器一个缓存有效时间,在有效时间内,下次请求时直接使用缓存,不发起http请求,缓存从from memory cache或from disk cache中读取,若超过了有效时间,则执行协商缓存策略对于协商缓存,将缓存信息中的Etag和Last-Modified的值通过If-None-Match和If-Modified-Since发送给服务器,由服务器进行校验,若资源无更改,返回304,浏览器继续使用缓存,若资源被更改,则返回资源,状态码200,同时浏览器更新缓存流程图浏览器第一次请求:浏览器第二次请求:5. Http长连接keep-alive三个概念短连接所谓短连接,就是每次请求一个资源就建立连接,请求完成后立马关闭。每次请求都经过“创建TCP连接 -> 请求资源 -> 响应资源 -> 释放连接”。长连接所谓长连接(persistent connection),就是只建立一次TCP连接,多次HTTP请求都复用该连接。并行连接所谓并行连接(multiple connection),其实就是并发的短连接。keep-alive在HTTP/1.0里,为了实现client到web-server能支持长连接,必须在HTTP请求头里显式指定Connection: keep-alive在HTTP/1.1里,就默认开启了keep-alive,要关闭keep-alive必须在HTTP请求头里显式指定Connection: close现在大多数浏览器都默认是使用HTTP/1.1,所以keep-alive都是默认打开的。一旦client和server达成协议,那么长连接就建立好了。keepalive_timeoutHttpd守护进程,一般都提供了keep-alive timeout时间设置参数。比如nginx的keepalive_timeout,和Apache的KeepAliveTimeout。这个keepalive_timout时间值意味着:一个http产生的tcp连接在传送完最后一个响应后,还需要hold住keepalive_timeout秒后,才开始关闭这个连接。Nginx配置中的keepalive_timeout默认为75s,6. cookie与Session这个重点在于理解,这里就不赘述了。7. 网页经历了什么这个东西很多,后面会专门写一篇文章来进行说明。参考文章:HTTP1.0、HTTP1.1 和 HTTP2.0 的区别彻底弄懂HTTP缓存机制及原理What is the difference between memory cache and disk cache in Chrome?理解HTTP之keep-alive ...