Haproxy+Keepalived+Varnish+LAMP+Memcacked+NFS 实现web站点的动静分离

Haproxy+Keepalived+Varnish+LAMP+Memcacked+NFS 实现web站点的动静分离

(一)架构拓扑图展示


这里写图片描述

(二)架构的简要说明


  • 本次动静分离的源码使用WordPress的开源程序,WordPress程序自身可以做到前台与后台的完全分离。为了演示效果,使用NFS共享存储(文件系统级共享)对外提供静态资源和动态资源,并且将静态资源挂载至静态主机,动态资源挂载至动态主机。从外观上感觉实现了动静分离

(三)架构的实现的方式说明


  • 1:WordPress源码放在动态服务器上,将静态资源复制一份给NFS共享存储目录,将共享存储目录挂载至静态服务器的站点。再将共享存储目录挂载至动态服务器对应的目录,这样使得程序的前台和后台能够正常的访问
  • 2:当用户的请求到达Load balance的时候,将动态请求反向代理至APP Servers,将静态请求反向代理至Varnish Servers
  • 3:当APP Servers接到动态请求,PHP引擎会根据是否需要查询数据库做出判断,将解析的结果返回给haproxy反代服务器,再返回给用户
  • 4:当Varnish Servers接到静态请求的时候,会先查询缓存机制中的子历程,根据子历程来判断是否能够查询缓存,如何不能重新缓存的静态请求通过调度算法,直接发往Static Servers服务器
  • 5:APP Servers服务器使用Memcached会话保持服务器,实现会话保持
  • 6:NFS共享存储用来提供静态资源的共享

(四)架构过程演示


一:配置keepalived双主模型,实现Haproxy的高可用
  • 1:在haproxy1和haproxy2上安装keepalived和haproxy
yum install -y keepalived haproxy
  • 2:配置haproxy1节点的keepalived主配置文件 /etc/keepalived/keepalived.conf
# 全局配置段

! Configuration File for keepalived
# 实现邮件报警功能,但是这里必须首先在/etc/mail.rc中配置好第三方的邮件代理服务器

global_defs {
   notification_email {
    307443272@qq.com
   }
   notification_email_from yinhuanyi_cn@163.com
   smtp_server smtp.163.com
   smtp_connect_timeout 30
   # 给节点取一个id名
   router_id haproxy1
   # 指定传递心跳信息的多播地址
   vrrp_mcast_group4 224.0.100.18
}

# 定义一个监控haproxy是否正常工作的脚本,监控脚本需要写在公共区,如果haproxy服务挂了,那么就将其优先级减去20
# 这样这个节点就是备节点,IP就会漂移
vrrp_script check_haproxy_available { 
    script "killall -0 haproxy" 
    interval 2 
    weight -20 
}

# 配置虚拟路由第一个实例
vrrp_instance VI_1 {
    # haproxy1为主
    state MASTER
    interface enp0s3
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111 
    }
    virtual_ipaddress {
        # 这里最好给VIP取一个别名,这样就能够使用ifconfig命令查看VIP了
        192.168.23.100/24 dev enp0s3 label enp0s3:0
    }
    # 下面三行的意义是当VIP发生漂移的时候调用,例如notify_master表示:当VIP漂移到master节点,调用后面的脚本
    notify_master "/root/notify.sh master"
    notify_backup "/root/notify.sh backup"
    notify_fault "/root/notify.sh fault"
    # 这里就是调用在公共区定义的监控haproxy健康状态的脚本
    track_script { 
    check_haproxy_available  
    }
}
# 配置虚拟路由第二个实例
vrrp_instance VI_2 {
    # 第二个实例中,是从节点
    state BACKUP
    interface enp0s3
    virtual_router_id 52
    priority 95
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 2222
    }
    virtual_ipaddress {
        192.168.23.101/24 dev enp0s3 label enp0s3:1
    }
    # 下面三行的意义是当VIP发生漂移的时候调用,例如notify_master表示:当VIP漂移到master节点,调用后面的脚本
    notify_master "/root/notify.sh master"
    notify_backup "/root/notify.sh backup"
    notify_fault "/root/notify.sh fault"
    track_script {
        check_haproxy_available
    }
}
  • 3:配置haproxy2节点的keepalived主配置文件 /etc/keepalived/keepalived.conf (与haproxy1节点不一样的地方已经做出了修改提示)
! Configuration File for keepalived

global_defs {
   notification_email {
    307443272@qq.com
   }
   notification_email_from yinhuanyi_cn@163.com
   smtp_server smtp.163.com
   smtp_connect_timeout 30
   router_id haproxy2 # 需要修改
   vrrp_mcast_group4 224.0.100.18
}

vrrp_script check_haproxy_available {
    script "killall -0 haproxy"
    interval 2
    weight -20
}

vrrp_instance VI_1 {
    state BACKUP  # 需要修改
    interface enp0s3
    virtual_router_id 51 
    priority 95 # 需要修改
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111 
    }
    virtual_ipaddress {
        192.168.23.100/24 dev enp0s3 label enp0s3:0
    }
    notify_master "/root/notify.sh master"
    notify_backup "/root/notify.sh backup"
    notify_fault "/root/notify.sh fault"
    track_script {
        check_haproxy_available
    }
}
vrrp_instance VI_2 {
    state MASTER  # 需要修改
    interface enp0s3
    virtual_router_id 52
    priority 100 # 需要修改
    advert_int 1
    authentication {  
        auth_type PASS
        auth_pass 2222
    }
    virtual_ipaddress { 
        192.168.23.101/24 dev enp0s3 label enp0s3:1
    }
    notify_master "/root/notify.sh master"
    notify_backup "/root/notify.sh backup"
    notify_fault "/root/notify.sh fault"
    track_script {
        check_haproxy_available
    }
}
  • 4:当VIP在haproxy1和haproxy2节点漂移的时候,调用的脚本如下
#!/bin/bash 
# 
contact='307443272@qq.com' 
notify() { 
mailsubject="$(hostname) to be $1 and vip is floating " 
mailbody="$(date +'%F %T'),$(hostname) change to be $1" 
echo "$mailbody" | mail -s "$mailsubject" $contact 
} 
case $1 in 
master) 
# 发送报警邮件
notify master
# 如果成为主节点,需要启动haproxy
systemctl start haproxy.service
echo "send mail to $contact " 
;; 
backup) 
# 发送报警邮件
notify backup 
# 如果成为备节点,先强制重启一下haproxy
systemctl restart haproxy.service
echo "send mail to $contact"
;; 
fault) 
notify fault 
;; 
*) 
echo "usage: $(basename $0) {master|backup|fault}" 
;; 
esac
  • 5:既然是邮件报警提示,那么需要配置/etc/mail.rc文件
# 注意smtp-auth-password的值不是登入邮件服务器的密码,而是代理使用第三方邮件客户端发送邮件的授权码哦
set from=yinhuanyi_cn@163.com smtp=smtp.163.com
set smtp-auth-user=yinhuanyi_cn@163.com smtp-auth-password=xxxxxxxx
set smtp-auth=login
  • 6:现在就可以启动haproxy1和haproxy2的keepalived服务了
systemctl start keepalived.service
二:配置Haproxy反代服务,实现动静分离
  • 1:配置haproxy1的主配置文件/etc/haproxy/haproxy.cfg ,haproxy2的配置文件与haproxy1的一样
# 全局配置段
global
    # 指定日志记录路径,这个local2和local3是需要在/etc/rsyslog.conf文件中指定的,指定了日志存储路径之后,需要重启rsyslog服务哦
    log         127.0.0.1 local2
    log         127.0.0.1 local3
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon
    # 设置后台运行4个haproxy进程会报出警告,所以注释
    # nbproc 4

    # turn on stats unix socket
    stats socket /var/lib/haproxy/stats

# 这里是默认的选项,如何在listen段,backend段,frontend段中将这些选项按需求重新制定
defaults
    # 指定默认的模式mode,
    mode                    http
    # 调用全局的日志区
    log                     global
    option                  httplog
    option                  dontlognull
    option http-server-close
    # 在后端的web服务中可以记录客户端的源IP地址
    option forwardfor       except 127.0.0.0/8
    # 虽然使用cookie机制,但是当调度到后端的服务器不用时,强行调离至其他的后端服务器
    option                  redispatch
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    # 指定接受3000个并发
    maxconn                 30000

# haproxy的统计页面配置段
listen stats 
    bind *:9001 
    mode http
    stats enable  
    # 如果不设置URI,默认是/haproxy?stats
    stats uri /stats  
    # 指定认证提示符
    stats realm HAProxy\ statistics
    # 指定用户名和密码
    stats auth yhy:xxxxxxxx  
    stats refresh 20
    stats admin if TRUE 
    #隐藏统计页面上HAProxy的版本信息
    stats hide-version

# 指定后端php动态资源主机组,后端的动态资源不做缓存,直接将请求反代值后端的app servers中
backend phpservers_backend  

    # 这里使用了cookie粘性机制,当客户端没有被设置cookie值的时候,通过轮询调度到app servers主机上
    balance roundrobin

    # 指定我们需要插入的cookie的key为PHP,使用的是insert方法,indirect表示如何会话已经有cookie值了,将不会再次发送cookie到客户端,nocache表示如果客户端和haproxy之间有代理,那么指定nocache将不会将所有的请求都发往一台服务器,会清除缓存
    cookie PHP insert indirect nocache

    # server后面的cookie参数是给当前server指定cookie值,使得同一个用户的请求始终发往同一台服务器
    server phpserver1 192.168.23.23:8000 check weight 1 cookie phpserver1 maxconn 300
    server phpserver2 192.168.23.24:8000 check weight 2 cookie phpserver2 maxconn 600

# 指定后端varnish静态资源缓存主机组
backend varnish_backend

    # 对用户请求的URL做哈希计算,使得同一URL的请求始终发往同一台服务器,基于URL做哈希计算,使得varnish缓存的命中率提高,uri算法适用于后端为缓存服务器的场景
    balance uri

    # 使用的的hash类型是动态hash,即一致性哈希算法
    hash-type consistent

    # 使用http协议做健康状态检查,默认是tcp协议
    option httpchk  
    server varnish_server1 192.168.23.17:7000 check maxconn 10000
    server varnish_server2 192.168.23.18:7000 check maxconn 10000

# 指定当请求到达的时候,如果是.php结尾的请求,直接发给后端的php主机组,默认是发送给后端web静态资源主机组
frontend myservers_frontend   
    bind *:80
    # 设置一个访问控制规则,只要请求路径为静态资源的都会被匹配到,并且发往varnish主机组
    acl varnish_page       path_beg       -i /static /images /javascript /stylesheets
    acl varnish_page       path_end       -i .jpg .gif .png .jpeg .css .js .html .txt .htm .ico
    use_backend varnish_backend if varnish_page
    # 没有被匹配到的请求全部发往phpservers_backend服务器
    default_backend phpservers_backend
  • 2:检查haproxy配置文件的语法
[root@haproxy2 ~] haproxy -c -f /etc/haproxy/haproxy.cfg
Configuration file is valid
  • 3:通过haproxy的数据统计页面来监控后端节点的状态信息
http://192.168.23.100:9001/stats
三:配置Varnish,为反复请求的静态资源提供内存缓存(yum 安装varnish)
  • 1:配置varnish1的对于varnish进程参数的配置文件/etc/varnish/varnish.params

# 指定重新reload varnish的时候,重新reload一下VCL配置文件
RELOAD_VCL=1

# 指定VCL的配置文件
VARNISH_VCL_CONF=/etc/varnish/default.vcl

# 指定varnish作为反代时候监听的地址和端口
# 在企业级情况下,varnish通常是面向的Nginx或haproxy这样的反代负载均衡器,可以实现端口映射的功能,不一定是80端口
VARNISH_LISTEN_PORT=7000

# 指定varnishadm的shell登入接口
VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1
VARNISH_ADMIN_LISTEN_PORT=6082

# 指定shell接口使用的密钥文件
VARNISH_SECRET_FILE=/etc/varnish/secret


# 指定varnish存储的类型,以及大小,这里使用默认的内存缓存,大小为256M即可
VARNISH_STORAGE="malloc,256M"

# 指定varnish进程的属主和属组
VARNISH_USER=varnish
VARNISH_GROUP=varnish

# 指定运行时的参数,使用-p选项来指定
DAEMON_OPTS="-p thread_pools=6 -p thread_pool_min=5 -p thread_pool_max=500 -p thread_pool_timeout=300"
  • 2:配置varnish1的vcl规则:/etc/varnish/default.vcl
vcl 4.0;

# 导入调度器模块
import directors;

# 指定调度到后端的主机
backend web1 {
    .host = "192.168.23.21";
    .port = "8000";
    .probe = {
        # 指定做健康状态检查的URL,既然给了这个URL,一定需要让后端主机的站点目录里面有这个URL,如果没有varnish将不会将请求调度到这台主机上
    .url = "/health.html";
        # 指定检查的超时时长
    .timeout = 2s;
    # 检查每次检查的时间间隔
    .interval = 4s;
        # 指定一个检测多少次
    .window = 5;
    # 指定最少成功多少次认为后端主机有效
    .threshold = 3;
    } 
}

backend web2 {
    .host = "192.168.23.22";
    .port = "8000";
    .probe = {
        # 指定做健康状态检查的URL
    .url = "/health.html";
        # 指定检查的超时时长
    .timeout = 2s;
    # 检查每次检查的时间间隔
    .interval = 4s;
        # 指定一个检测多少次
    .window = 5;
    # 指定最少成功多少次认为后端主机有效
    .threshold = 3;
    } 
}


# 定义负载均衡调度器
sub vcl_init {
    # 创建一个调度器对象,directors.round_robin()指定了轮询调度算法
    new static = directors.round_robin();
    static.add_backend(web1);
    static.add_backend(web2);
}

# 第一个子历程,当收到请求处理的子历程
sub vcl_recv {

    # 指定varnish接受到的请求全部发往后端的static主机组
    set req.backend_hint = static.backend();


    # 如何请求方法是pri,直接返回synth子历程
    if (req.method == "PRI") {
        /* We do not support SPDY or HTTP/2.0 */
        return (synth(405));
    }


    # 如果不是一下七中方法的任意一个,直接返回pipe子历程
    if (req.method != "GET" &&
      req.method != "HEAD" &&
      req.method != "PUT" &&
      req.method != "POST" &&
      req.method != "TRACE" &&
      req.method != "OPTIONS" &&
      req.method != "DELETE") {
        /* Non-RFC2616 or CONNECT which is weird. */
        return (pipe);
    }


    # 如果不是get或者head方法,我们就不用去查缓存,直接交由后端主机处理就是
    if (req.method != "GET" && req.method != "HEAD") {
        /* We only deal with GET and HEAD by default */
        return (pass);
    }


    # 如果客户端的请求报文中的http首部包含认证信息或cookie信息,也直接交由后端主机处理,这是保密的静态内容
    # 由于在haproxy对于动态请求都会在用户的浏览器中设置cookie信息,因此,下面这项先将其注释掉,以免请求都不能查询缓存
    #if (req.http.Authorization || req.http.Cookie) {
    #    /* Not cacheable by default */
    #   return (pass);
    #}


    # 如何请求的方法是PURGE,那么直接发往purge子历程处理,但是我这里使用curl命令请求返回501错误,不知道为什么
    if (req.method == "PURGE") {
        #if (!client.ip ~ purgers) {
        #    return(synth(405));
        #}
        return (purge);
    }



    # 否则其他的请求都通过hash子历程处理
    return (hash);
}

# 指定purge的子历程,视乎不起作用,错误提示无法处理,因此注释
#sub vcl_purge {

#    return (synth(200,"Purged"));
#}

# 指定后端主机响应的响应报文子历程
sub vcl_backend_response {

    # 如何发往后端主机的请求报文的http首部中没有s-maxage参数,那么做两个if判断
    # 1:如果请求的是css样式代码,设置其ttl值为7200s,并且删除Set-Cookie参数
    # 2:如果请求的是jpg图片,设置其ttl值为7200s,并且删除Set-Cookie参数
    # 其他的请求都交由deliver子历程处理
    if (beresp.http.cache-control !~ "s-maxage"){ 
        if (bereq.url ~ "(?i)\.css$") {

            set beresp.ttl = 7200s;
            unset beresp.http.Set-Cookie;
        }
        if (bereq.url ~ "(?i)\.jpg$") {
                set beresp.ttl = 7200s;
                unset beresp.http.Set-Cookie;
        }
    }
    return (deliver);
}

# 这一条子历程是最后一个子历程,通过此子历程的请求报文执行协议给用户
# 在deliver子历程中可以修改响应报文http的首部
sub vcl_deliver {

    # 如果客户端的请求被缓存命中,那么加一个http的首部参数,明确告诉用户请求的资源是从缓存加载的
    if (obj.hits>0)
    {

    set resp.http.X-Cache = "HIT via " + server.hostname;

    }else{

    set resp.http.X-Cache = "MISS via " + server.hostname;

    }

}
  • 3:varnish1节点和varnish2节点的配置文件都一样,因此,直接scp一份到varnish2即可
  • 4:启动varnish
systemctl start varnish.service
四:配置NFS服务器提供共享存储(yum 安装 nfs-utils)
  • 1:在NFS节点上为静态服务器和动态服务器提供共享存储目录
[root@nfs1 ~]# mkdir -pv /data/{static,dynamic}

# 在静态共享目录中提供WordPress源码的静态资源代码,直接删除.php结尾的文件剩下的都是静态文件了
[root@nfs1 ~]# cd /data/static/
[root@nfs1 static]# find ./ -type f -name "*.php" | xargs rm -f 

# 在静态共享目录中提供WordPress源码的静态资源代码,直接删除.css .jpg .html等结尾的文件剩下的都是动态文件
[root@nfs1 static]# cd /data/dynamic/
[root@nfs1 dynamic]# find ./ -type f -name "*.css" | xargs rm -f 
  • 2:配置/etc/exports文件,将刚刚创建的共享目录共享出去,同时拷贝一份到NFS2节点
/data                   192.168.23.0/24(rw,no_root_squash)
  • 3:在NFS2节点查看共享目录
[root@nfs2 ~]# showmount -e 192.168.23.25
Export list for 192.168.23.25:
/data 192.168.23.0/24
  • 4:由于在static servers ,nfs , app servers 节点上都存在apache用户和apache组,并且UID和GID都一样,因此,直接设置apache用户对共享目录的访问权限即可。但是如果NFS服务器没有apache用户,或uid和gid和其他节点不一样,需要添加apache用户。另外,如果是LNMP架构,最好是将Nginx ,php-fpm,NFS统一创建一个用户,例如 www用户,这样也可以实现批量管理操作
[root@nfs1 data]# setfacl -m u:apache:rwx /data/dynamic
[root@nfs1 data]# setfacl -m u:apache:rwx /data/static
  • 5:在static servers,app servers将共享目录挂载
[root@web1 ~]# mount -t nfs 192.168.23.25:/data/static /var/www/html/
[root@web2 ~]#  mount -t nfs 192.168.23.25:/data/static /var/www/html/ 
[root@php1 ~]# mount -t nfs 192.168.23.25:/data/dynamic /var/www/html/
[root@php2 ~]# mount -t nfs 192.168.23.25:/data/dynamic /var/www/html/
五:配置Mariadb服务器
  • 登入mariadb,创建一个wp数据库,然后再给这个数据库创建授权一个wp_user的用户即可。并且修改源码中wp-config.php文件,填写好数据库的相关参数。
  • 到这里整套架构基本上就完成了90%,现在可以访问http://192.168.23.100创建博客站点了
六:配置Memcached服务器,实现会话保持
  • 1:动态服务器的cookie信息是保持在本地的文件系统上的,虽然haproxy在调度时候,已经做了基于cookie的粘性绑定,但是如果动态服务器挂一台,那么基于这台动态服务器的会话保持都将失效,因此有必要在动态服务器组后端配置一台会话保持的服务器,实现session server
  • 2:安装memcached服务和php与memcached连接的驱动
yum install -y memcached
yum install -y php-pecl-memcache
  • 3:在动态服务器上编辑php.ini文件
编辑php.ini文件,确保如下两个参数的值分别如下所示:
session.save_handler = memcache
session.save_path = "tcp://192.168.23.28:11211?persistent=1&weight=1&timeout=1&retry_interval=15"
  • 4:只要php程序调用php连接memcached的接口,就能实现session server。这里介绍的较为简单,之后我们将使用redis取代memcached,实现会话保持功能
七:配置 Keepalived + Rsync + Inotify 服务解决NFS单点故障的问题 (yum 安装 keepalived 、inotify-tools)
  • 1:从架构图中我们可以知道,NFS2作为NFS1容灾备用需要做到NFS1和NFS2的共享目录数据同步。并且,当一台NFS挂了,另一台会马上抢夺VIP,替代挂掉的主机,那么又要使用keepalived来实现了
  • 2:首先将静态资源和动态资源的共享目录卸载掉,因为,接下来我们将NFS1,NFS2通过keepalived实现高可用,如同架构图所示,通过VIP对外提供服务
  • 3:在NFS1的共享目录/data的所有文件拷贝一份到NFS2,并且为了保证目录权限有效,重新设置下/data/目录的访问权限
[root@nfs2 ~]# mkdir -pv /data
[root@nfs1 data]# scp -rpv ./* 192.168.23.26:/data
[root@nfs2 data]# setfacl -m u:apache:rwx /data/dynamic
[root@nfs2 data]# setfacl -m u:apache:rwx /data/static
  • 4:在NFS1和NFS2 yum安装keepalived,NFS1为主节点,NFS2为备节点, 主备节点配置文件分别如下,这里需要说明的是,在配置文件中没有添加脚本报警功能
! Configuration File for keepalived

global_defs {
   notification_email {
    307443272@qq.com
   }
   notification_email_from yinhuanyi_cn@163.com
   smtp_server smtp.163.com
   smtp_connect_timeout 30
   router_id NFS1
   vrrp_mcast_group4 224.0.101.18
}

# 定义对NFS服务做健康状态检查的脚本
vrrp_script check_nfs_available {
    script "killall -0 rpcbind && killall -0 rpc.statd && killall -0 rpc.mountd"
    interval 2
    weight -20
}


vrrp_instance VI_1 {
    state MASTER
    interface enp0s3
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 3333
    }
    virtual_ipaddress {
    192.168.23.51/24 dev enp0s3 label enp0s3:0
    }
    track_script {
        check_nfs_available
    }
}
! Configuration File for keepalived

global_defs {
   notification_email {
    307443272@qq.com
   }
   notification_email_from yinhuanyi_cn@163.com
   smtp_server smtp.163.com
   smtp_connect_timeout 30
   router_id NFS2
   vrrp_mcast_group4 224.0.101.18
}

# 定义对NFS服务做健康状态检查的脚本
vrrp_script check_nfs_available {
    script "killall -0 rpcbind && killall -0 rpc.statd && killall -0 rpc.mountd"
    interval 2
    weight -20
}


vrrp_instance VI_1 {
    state BACKUP
    interface enp0s3
    virtual_router_id 51
    priority 95
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 3333
    }
    virtual_ipaddress {
    192.168.23.51/24 dev enp0s3 label enp0s3:0
    }
    track_script {
        check_nfs_available
    }
}
  • 5:让内核重读一下,nfs的配置文件 , 并且查看共享目录
exportfs -r
[root@nfs2 keepalived]# showmount -e 192.168.23.51
Export list for 192.168.23.51:
/data 192.168.23.0/24
  • 6:重新将共享目录挂载到静态服务器和动态服务器
[root@web1 ~]# mount -t nfs 192.168.23.51:/data/static /var/www/html/
[root@web2 ~]# mount -t nfs 192.168.23.51:/data/static /var/www/html/
[root@php1 ~]# mount -t nfs 192.168.23.51:/data/dynamic /var/www/html/
[root@php2 ~]# mount -t nfs 192.168.23.51:/data/dynamic /var/www/html/
  • 7:在NFS2配置rsync服务,修改/etc/rsyncd.conf配置文件
# /etc/rsyncd: configuration file for rsync daemon mode

# See rsyncd.conf man page for more options.

# configuration example:
 # 指定访问本地共享目录的属主和属组,当客户端连接到服务端,那么进程就以这里指定的uid和gid运行
 uid = rsync
 gid = rsync
 # 不禁锢
 use chroot = no
 # 指定服务端最大并发连接数量
 max connections = 2000
 # 指定超时时长
 timeout = 900
 # 指定程序的pid路径
 pid file = /var/run/rsyncd.pid
 # 指定日志路径
 log file = /var/log/rsyncd.log
 # 指定文件系统锁路径
 lock file = /var/run/rsyncd.lock
 # 指定推送时出现错误忽略
 ignore errors
 # 指定客户端可以向服务端推送数据,因此必须是可读写
 read only = false
 # 关闭远程列表
 list = false
 # 指定允许连接rsync服务端的网络地址
 hosts allow = 192.168.23.0/24
 hosts deny = 0.0.0.0/32
 # 启用虚拟用户
 auth users = nfs
 # 指定用户名和密码的文件,这个文件里面的用户名就是auth users指定的用户名,然后给个密码就好
 secrets file = /etc/rsync.password
 #transfer logging = yes
 #ignore nonreadable = yes
 #dont compress   = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2

 # 指定一个模块,用来指定接受客户端推送的目录
 [data]
        path = /data
        comment = shared remoted NFS directory /data
  • 8:设置备份目录的访问权限,创建用户,密码
useradd rsync -s /sbin/nologin -M # 在NFS2节点创建一个rsync用户,不能登入,不创建家目录
chmod -R rsync /data #  修改/data目录的属主为rsync,这样rsyncd进程就能够向目录里面写数据
echo "nfs:xxxxxx" > /etc/rsync.password # 由于在/etc/rsyncd.conf主配置文件中指定了客户端登入的用户名以及密钥文件路径,那么根据路径创建用户密码即可
chmod 600 /etc/rsync.password # 修改密码文件的权限
  • 9:配置rsync服务配置进程文件/etc/sysconfig/rsyncd
OPTIONS="--address=192.168.23.26" # 将rsync服务监听到固定的IP地址上
  • 10:在NFS1节点安装inotify-tools监听工具,实现调用rsync自动远程同步
# 1:安装inotify-tools监控工具
yum install -y inotify-tools

# 2:创建同步时候使用的密钥文件
echo "自己在rsync服务端设置的密码" > /etc/rsync.password
  • 11:写一个脚本监控/data目录的变化,使用inotifywait监控,同时调用rsync自动远程同步,脚本名称就交inotify.sh,通过bash inotify.sh & ,使得脚本在后台运行,并且加入到/etc/rc.local文件中,开机自动运行脚本文件
#!/bin/bash
inotify=/usr/bin/inotifywait
$inotify -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f' -e modify,delete,create,attrib,close_write /data \
| while read file; do
        /usr/bin/rsync -avz --delete /data/ nfs@192.168.23.26::backup --password-file=/etc/rsync.password
done
八:总结架构中存在的不足
  • 1:虽然给NFS共享存储做了高可用,但是当NFS1挂掉,会出现服务无法访问的问题,那么就需要手动卸载,然后再次挂载(此时的NFS服务的VIP已经漂移)
# 手动停止NFS1的nfs服务,节点漂移,但是不会卸载之前的挂载点,再重新挂载,出现的错误如下
[root@web1 www]# ll
ls: 无法访问html: 权限不够
总用量 0
drwxr-xr-x 2 root root 6 1115 02:05 cgi-bin
?????????? ? ?    ?    ?            ? html

# 需要手动卸载
[root@web1 www]# umount 192.168.23.51:/data/static
[root@web1 www]# ll
总用量 0
drwxr-xr-x 2 root root  6 1115 02:05 cgi-bin
drwxr-xr-x 5 root root 74 414 05:11 html

# 再次挂载NFS
mount -t nfs 192.168.23.51:/data/static /var/www/html/
mount -t nfs 192.168.23.51:/data/dynamic /var/www/html/
  • 2:架构中没有将MySQL数据库的目录通过NFS服务进行提供,是因为考虑到MySQL是单点,并没有配置MySQL的主从
  • 3:前端的负载均衡调度器使用的是Haproxy将用户的请求进行动静分离,但是Haproxy没有缓存功能。因此,如果前端使用的是Nginx做负载均衡调度器,Nginx有透床式缓存功能,可以对前端的用户请求多一层缓存功能。
  • 4:对于整个架构,并没有假设zabbix监控系统,无法对架构中的各个节点的监控状态进行监控
  • 5:架构中没有假设自动化运维工具ansible,运维无法实现对集群中各个节点的服务进行有效的管理
  • 6:架构没有实现从裸机(或无系统虚拟节点)开始完成系统的统一安装与系统调优工作
  • 7:架构中没有日志分析系统
九:架构展望和升级(对于架构中存在的不足提供解决方案)
  • 1:集群使用corosync + pacemaker解决集群服务自动管理,这样当NFS挂掉之后,可以实现自动卸载挂载点,自动挂载,也可以实现服务出现故障时,自动重启的功能
  • 2:将MySQL数据库实现主从模式,解决单点问题,并且在MySQL集群前加入缓存,解决MySQL并发I/O慢的问题
  • 3:前端的负载均衡器改用Nginx
  • 4:在架构中添加zabbix监控系统
  • 5:加入ansible自动化运维工具,对整个架构的服务全面的掌控
  • 6:借助Cobbler + kickstarts文件实现各个节点从系统安装到服务正常运行的一键式完成
  • 7:通过添加ELK日志分析系统,实现各个节点的日志汇总管理与分析
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值