服务注册与发现用mysql_服务注册与发现

随着业务的发展,用户量日益上升,单一的系统越来越复杂,越来越庞大,单纯的提升服务器性能始终有顶天的一天,我们可以通过分布式技术,例如:服务器集群,水平业务划分,应用分解,系统分流,微服务架构等方式来解决系统性能问题和复杂业务问题。

第一篇:架构演进

在分布式体系下服务注册与发现将会以核心组件而存在,也将是接下来讨论的话题。

Lazy服务注册与发现(一)

由于应用的分解,微服务的引入,服务越来越多,业务系统与服务系统之间的调用,都需要有效管理。

在服务化的早期,服务不是很多,服务的注册与发现并不是什么新鲜的名词,Nginx+内部域名服务器方式,甚至Nginx+host文件配置方式也能完成服务的注册与发现。

架构图如下:

c144a577f3d1

(架构一)

各组件角色如下:

Nginx通过多域名配置实现生产者服务路由,通过upstream对生产者提供负载均衡,通过checkhealth对生产者提供健康检查。

在内部域名服务器/本地host文件配置服务域名的方式,实现域名与服务的绑定。

生产者提供服务给消费者访问,并通过Nginx来进行请求分发。在服务化的早期,服务较少,访问量较小,解决了服务的注册与发现与负载均衡等问题。随着业务的发展,用户量日益上升,服务也越来越多,该架构的问题暴露出来:

1)最明显的问题是所有的请求都需要nginx来转发,同时随着访问量的提升,会成为一个性能瓶颈。

2)随着内部服务的越来越多,服务上线nginx的配置,内部域名的配置也越来越多,不利于快速部署。

3)一旦内部网络调整,nginx upstream也需要做对应的配置调整。

Lazy服务注册与发现(二)

由于所有的请求都需要nginx来转发,同时随着访问量的提升,会成为一个性能瓶颈,为了解决这个瓶颈,引入下面这个架构。

c144a577f3d1

(架构二)

这个架构在nginx的上层加入了LVS,LVS基于第四层的IP转发,一定限度提高了并发能力,但是所有请求都通过LVS来转发。

同时nginx分组,服务分组,虽然nginx不再是瓶颈的所在,但是这样带来的代价太高,配置越来越多,工作量越来越大,对系统压力需要有预见性,有效nginx分组,服务分组部署。

Lazy服务注册与发现(三)

由于所有的请求都需要LVS来转发,同时随着访问量的提升,会成为一个性能瓶颈,为了解决这个瓶颈,引入下面这个架构。

c144a577f3d1

(架构三)

在这个架构基础上需要做两件事情:

对系统压力需要有预见性,有效nginx分组,服务分组部署。

消费端需要编程实现分组选择,可以是轮训,random等实现,我们每一个消费者同时承担了的负载均衡的职责。

ZK服务注册与发现 (一)

通过架构三解决了nginx的瓶紧,但是服务上下线需要在nginx,域名服务器做相应的配置,一旦服务的IP端口发生变化,都需要在nginx上做相应的配置,为了解决这个问题引入下面这个架构。

c144a577f3d1

(架构四)

服务在启动的时候就将endpoint注册到Zookeeper对服务进行统一管理。

服务节点增加Endpoint不需要做任何配置,ZK将以Watch机制通知消费者。

消费者本地缓存了提供者服务列表,不需要转发,直接发起服务调用。

缺点:

需要通过zookeeper API来实现服务注册与发现,负载均衡,以及容错,为了解决nginx的瓶紧架构三也是需要通过编程的方式实现负载均衡。

ZK服务注册与发现 (二)

Zookeeper数据模型结构是一个树状层次结构。每个节点叫做Znode,节点可以拥有子节点,同时允许将少量数据存储在该节点下,客户端可以通过NodeCacheListener监听节点的数据变更,PathChildrenCacheListener监听子节点变更来实时获取Znode的变更(Wather机制)。

以下是点融成都服务注册结构,见下图,接下来的讲解也将以这个结构为基础:

c144a577f3d1

ZK服务注册与发现 (三)

1./com/dianrong/cfg/1.0.0/rpcservice: 命名空间,用来跟其他用途区分。

2./com/dianrong/cfg/1.0.0/rpcservice下的所有子目录由两部分组成,

“应用名称” + “-” +  “分组名称”例如:ProductService-SG1,ProductService-SG2, 对应Nginx注册中心Nginx-SG1, Nginx-SG2

c144a577f3d1

3. 服务分组下的所有子节点为临时节点,key为“PROVIDER”+ IP(去符号.)  + “-” + 端口,Value为endpoint信息。

例如:PROVIDER1921681010-8080   = http://192.168.10.10:8080

第二篇:代码分析

项目说明

有了上面的理论我们接下来针对基于ZK的服务与发现的代码分析,代码已经提交到git

GIT地址:

https://code.dianrong.com/projects/PLAT/repos/platform/compare/commits?sourceBranch=refs%2Fheads%2FEVER-81-zk&targetBranch=refs%2Fheads%2Fmaster

说明:

1. 该组件建立在Curator基础之上,Curator是Netflix开源的一套ZooKeeper客户端框架封装ZooKeeper client与ZooKeeper server之间的连接处理。

2. Curator提供如下机制,保证我们不需要关注网络通信,而把主要精力放在业务逻辑的处理。

重试机制:提供可插拔的重试机制, 它将给捕获所有可恢复的异常配置一个重试策略, 并且内部也提供了几种标准的重试策略

连接状态监控: Curator初始化之后会一直的对zk连接进行监听, 一旦发现连接状态发生变化, 将作出相应的处理

ZK客户端实例管理:Curator对zk客户端到server集群连接进行管理. 并在需要的情况, 透明重建zk实例, 保证与zk集群的可靠连接

基于ZK的服务与发现UML类图:

c144a577f3d1

目标

1. 统一配置中心

数据实时性,一旦zk节点发生变化,实时通知本地hash同步刷新。

2. 服务注册

服务启动完成,服务IP,端口以临时节点的形式注册到zk,在网络正常的情况下,一直存在。

3. 服务发现

服务启动完成,将服务注册信息刷新到本地hash。

4. 服务上下线

服务注册到zk将实时通知服务发现方,更新本地hash,服务下线也将实时通知服务发现方,更新本地hash。

5. 负载均衡

服务发现方获取服务缓存在本地hash,通过random,robin等负载均衡算法完成服务选择性调用。

6. 网络中断容灾

针对注册方网络中断,服务下线,网络恢复,服务上线,并通知服务发现方更新本地Hash;

针对发现方网络中断,通过本地hash负载均衡,网络恢复重刷hash,负载均衡重新分配。

7. Zookeeper宕机容灾

针对注册方Zookeeper宕机,服务下线,尝试重连, Zookeeper 启动重连成功,服务上线,并通知服务发现方更新本地hash,针对发现方Zookeeper宕机,通过本地hash负载均衡,尝试重连,  Zookeeper 启动重连成功,重刷hash,负载均衡重新分配。

基本配置

PathConfig.java

包含服务注册的命名空间和统一配置的命名空间的配置。

SgConfig.java

包含服务名和分组名的配置

ZookeeperConfig.java

包含zookeeper地址,会话超时时间,连接超时时间,命名空间以及认证信息的配置

ZK操作框架

IzookeeperManager.java

定义了一套zookeeper操作规范(类似JDBC操作数据数据库规范),有待继续完善。

ZookeeperManager.java

针对IzookeeperManager接口规范的实现(类似Mysql驱动对Mysql操作的实现)

ZookeeperManagerPool.java

针对ZookeeperManager实例的缓存,不同配置缓存不同ZookeeperManager实例,避免zookeeper连接创建的开销,同时可以根据zookeeper水平分组扩展zookeeper

实例。

统一配置,服务注册与发现

AbstractZookeeperFeature.java

内部两个接口定义:

IConfigService 提供针对统一配置接口的定义, IManagementService提供服务注册与发现接口的定义。

ConfigService.java

统一配置的实现。

ManagementService.java

服务注册与发现的实现。

负载均衡

LbStrategy.java

负载均衡策略接口定义,目前实现了两种负载均衡算法,Random负载均衡和Robin负载均衡。

RandomStrategy.java

基于随机负载均衡的实现。

RobinStrategy.java

基于轮循负载均衡的实现。

统一配置Listener

ConfigPathChildrenCacheListener.java

统一配置结点监听, 针对CHILD_REMOVED,CHILD_ADDED,CHILD_UPDATED事件对本地hash实时更新。

服务注册与发现Listener

ZookeeperStateListener.java

Zookeeper状态监听接口定义,定义需要关心的三种事件:

LOST-断开连接达到一定时间

CONNECTED-第一次连接成功

RECONNECTED-重连成功触发事件。

ServiceRegistStateListener.java

服务注册状态监听实现:

1.一旦网络丢包严重/ zk宕机/ zk重启,客户端将会与zk断开,服务下线,网络恢复将触发reconnected连接,服务重新注册。

2.一旦zk断开服务下线,长时间连接不上触发Lost事件,ServiceRegistStateListener将会尝试不断连接直到连上为止,服务重新注册。

ServiceDiscoverStateListener.java

服务发现状态监听实现:

1.一旦网络丢包严重/ zk宕机/ zk重启,客户端将会与zk断开,网络恢复将触发reconnected连接,重新获取服务列表,刷新本地hash。

2.一旦zk断开服务下线,长时间连接不上触发Lost事件,ServiceDiscoverStateListener将会尝试不断连接直到连上为止,以便刷新本地hash。

ServicePathChildrenCacheListener.java

服务发现结点监听, 针对CHILD_REMOVED,CHILD_ADDED,CHILD_UPDATED事件消费者对本地hash实时更新,以便及时刷新服务上下线。

第三篇:单元测试

环境准备

1. 在zookeeper中准备结点 com/dianrong/cfg/1.0.0/rpcservice

create /com/dianrong/cfg/1.0.0/rpcservice  “”

2. 模拟docker/JVM启动参数设置

由于点融网是通过物理机IP加端口映射到docker实例IP加端口的方式对外提供服务,因此需要通过java -D配置宿主机的IP加端口以便应用程序获取服务IP加端口用来进行服务注册。

c144a577f3d1

服务注册

1. 在服务注册之前通过zookeeper控制台查看,期望的注册节点目前为空。

c144a577f3d1

2. 启动服务注册单元测试,sleep 10s。

c144a577f3d1

3. 观察zookeeper中注册结点,期望的临时节点已经存在。

c144a577f3d1

服务发现

通过服务注册以后然后服务发现,发现节点与预期注册结点一致。

c144a577f3d1

负载均衡

通过服务注册以后然后负载均衡,负载均衡获取节点与预期节点一致。

c144a577f3d1

服务上下线

1. 准备两套单元测试并模拟docker/JVM启动参数设置。

c144a577f3d1

c144a577f3d1

2.启动服务注册,服务发现,负载均衡集成单元测试,测试控制台按照预期打印出服务注册信息,注册了两个服务节点通过负载均衡交叉出现。

c144a577f3d1

c144a577f3d1

3. 通过zookeeper控制台查看成功注册两个节点。

c144a577f3d1

4.关闭机器1单元测试,结点1在zookeeper离线,结点2在zookeeper在线。

c144a577f3d1

c144a577f3d1

负载均衡只有一个节点存在达到预期目的

c144a577f3d1

网络中断

1. 启动服务注册,服务发现,负载均衡集成单元测试,测试控制台按照预期打印出服务注册信息。

c144a577f3d1

2. 通过Linux iptables开启防火墙,模拟网络中断。

c144a577f3d1

服务掉线,通过zookeeper控制台查看注册节点消失。

c144a577f3d1

服务发现方任然可以从本地Hash中获取服务节点。

c144a577f3d1

3. 关闭Iptables,服务上线。

c144a577f3d1

服务上线,通过zookeeper控制台查看注册节点出现。

c144a577f3d1

服务发现方获取服务节点重刷本地Hash中。

c144a577f3d1

Zookeeper宕机

1. 启动服务注册,服务发现,负载均衡集成单元测试,测试控制台按照预期打印出服务注册信息。

c144a577f3d1

2.关闭zookeeper,单元测试出现连接拒绝错误,但是任然能按照预期获取本地hash中的服务注册信息。

c144a577f3d1

c144a577f3d1

3. 启动zookeeper,单元测试打印出重连信息,并重刷本地服务hash。

c144a577f3d1

c144a577f3d1

本文作者:秦瑜 Chris.Qin(点融黑帮),来自点融BE Team, 2015年10月加入点融,多年大并发分布式互联网架构经验。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值