技术开发 频道

实现高可用的两种方案与实战

  【IT168 技术】我之前在一片文章 用Nginx+Redis实现session共享的均衡负载 中做了一个负载均衡的实验,其主要架构如下:

  把debian1作为调度服务器承担请求分发的任务,即用户访问的是debian1,然后debain1把请求按照一定的策略发送给应用服务器:debian2或者debain3,甚至更多的debain4、5、6......

  状态和数据可以放在外部的分布式缓存服务和分布式数据库服务中,这样应用服务本身就是无状态的,所以机器增减都是很容易的,应用的高可用是有保证的(对于有状态的高可用不仅要注意机器增减与切换、还要注意备份冗余、数据一致性等问题)。但是当时忽略了一个地方,那就是调度服务器debian1本身的高可用性没有考虑到,存在单点问题。

  高可用的首要想法就是双机热备,故障时自动切换,所以我们要给debian1加一个备机debain1'。我现在按照自己的知识粗浅的把解决方案分为两类:客户端有感知的高可用、对客户端透明的高可用,并分别挑选一个示例做一下实验。

  注:下面实现高可用都用的是双机热备,为了方便,把调度服务器debian1简称为主机,把调度服务器debian1的备机debian1'简称为备机。

  客户端有感知的高可用

  客户端有感知的高可用,也就是需要客户端的配合,客户端自己去确认服务器的变更并切换访问的目标。比如说我们的主机、备机都在ZooKeeper(或者其他类似的注册中心比如redis)中进行注册,客户端监听ZooKeeper中服务器的信息,发现主机下线自己就切换访问备机即可。

  ZooKeeper伪集群搭建

  首先在本机搭建包含3个节点的ZooKeeper伪集群。在官网下载版本3.5.4-beta,解压,然后复制3份,每一份都要做如下操作:

  进入conf文件夹 创建一个配置文件zoo.cfg。代码如下:

  创建上面的dataDir和dataLogDir,并在dataDir目录下必须创建myid文件,写入不同的整数ID,也就是上面的server.x的x,比如1

  分别进入bin目录,在zkServer.cmd中call之前加入set ZOOCFG=../conf/zoo.cfg 并用其启动。

  顺带一提,代码开发我就使用我之前的项目CHKV了,因为这个项目中的NameNode或者DataNode也可以用ZooKeeper实现高可用,欢迎和我一起完善这个项目,一块进步。

  调度服务端开发

  调度服务器主要向ZooKeeper注册自己,并向客户端提供服务。我们使用curator框架来和ZooKeeper交互,特别要注意版本问题。

  主要代码如下:

  完整代码在GitHub上。

  客户端开发

  客户端主要向ZooKeeper监听调度服务器变更事件,并向其发起应用请求。实际上应用服务器也可以使用这部分代码来监听调度服务器的变化。

  主要代码如下:

  完整代码在GitHub上。

  对客户端透明的高可用

  对客户端透明的高可用,也就是客户端不需要做什么工作,服务器切换不切换客户端根本不知道也不关心。主要实现方式有两种,一种是客户端通过域名访问主机,那么监控主机下线后就把域名重新分配给备机,当然这个切换会有时间成本,视定义的DNS缓存时间而定;第二种就是客户端通过IP访问主机,监控到主机下线后就通过IP漂移技术把对外的IP(或者说虚拟IP)分配给备机,这样就能做到及时的切换。

  实际环境中常常使用keepalived来实现IP漂移。

  搭建过程参考了The keepalived solution for LVS和官网文档

  首先主机、备机都要安装keepalived,然后配置主机/etc/keepalived/keepalived.conf:

  配置备机/etc/keepalived/keepalived.conf,与主机类似,但是state是backup,且权重较低即可:

  反思

  说白了,这两种高可用的实现方式前者是在应用层实现的,而后者是在传输层实现的,那么我们就可以想到,计算机网络的每一层其实都是可以做负载均衡和高可用的。

0
相关文章