永康住房城乡建设局网站锦州网站seo
news/
2025/10/7 6:11:24/
文章来源:
永康住房城乡建设局网站,锦州网站seo,成都网站建设服务密需湖南岚鸿案例,中国软件公司文章目录 前言声明前置知识服务注册和发现Zookeeper 工作原理实现过程注册中心服务注册服务发现 总结 前言
无论是采用SOA还是微服务架构#xff0c;都需要使用服务注册和服务发现组件。我刚开始接触 Dubbo 时一直对服务注册/发现以及 Zookeeper 的作用感到困惑#xff0c;现… 文章目录 前言声明前置知识服务注册和发现Zookeeper 工作原理实现过程注册中心服务注册服务发现 总结 前言
无论是采用SOA还是微服务架构都需要使用服务注册和服务发现组件。我刚开始接触 Dubbo 时一直对服务注册/发现以及 Zookeeper 的作用感到困惑现在看来是因为对分布式系统的理解不够深入对 Dubbo 和 Zookeeper 的工作原理不够清楚。
本文将基于 Zookeeper 实现服务注册和服务发现功能如果跟我一样有同样的困惑希望可以通过本文了解其他组件如何使用 Zookeeper 作为注册中心的工作原理。
声明
文章中所提供的代码仅供参考旨在帮助缺乏基础知识的开发人员更好地理解服务注册和服务发现的概念。请注意这些代码并不适用于实际应用中。
前置知识
服务注册和发现
在SOA或微服务架构中由于存在大量的服务以及可能的相互调用为了更有效地管理这些服务我们通常需要引入一个统一的地方即注册中心来集中管理它们而注册中心最基本的功能就是服务注册/发现。
服务注册将该服务实例的元数据如IP地址、端口号、健康状态等注册到注册中心这样其他服务或客户端可以发现和使用该服务。服务发现当一个服务需要调用别的服务时使用静态配置是不可行的这个时候可以去注册中心获取可用的服务实例并调用。
Zookeeper
Zookeeper 是一个传统的分布式协调服务它更多的被用来作为一个协调器使用比如来协调管理 Hadoop 集群、协调 Kafka 的 leader 选举等。
为什么会有组件将其视为一个注册中心使用我想有几个原因
Zookeeper 在分布式系统中具有更强的一致性和可靠性可以确保各个服务的注册信息保持一致。Zookeeper 使用内存存储数据具有很高的读写性能。这对于注册中心来说非常关键因为它需要快速地响应客户端的请求。Zookeeper 的 Watcher 机制可以让客户端监听指定节点的变化。当某个节点注册中心发生变化时Zookeeper 可以通知其他服务实现实时更新。
工作原理
以下图为例可以看到 Dubbo 是如何使用 Zookeeper 实现服务注册/发现的。 服务提供者向 /dubbo/com.foo.BarService/providers 目录下写入自己的 URL 地址。服务消费者订阅 /dubbo/com.foo.BarService/providers 目录下的提供者 URL 地址。并向 /dubbo/com.foo.BarService/consumers 目录下写入自己的 URL 地址。
这里的目录就是 Zookeeper 的数据结构原理非常简单本质上就是服务提供者和消费者按照约定在 Zookeeper 上读写数据同时借用其 Watcher 机制、临时节点和可靠性等特性高效的实现以下功能
当提供者服务出现断电等异常停机时注册中心能自动删除提供者信息。当注册中心重启时能自动恢复注册数据以及订阅请求。
实现过程
注册中心
下面通过 Zookeeper 的 Java API 实现一个只包含服务注册/发现的注册中心代码如下
public class RegistrationCenter {// 连接信息private String connectString 192.168.10.11:2181,192.168.10.11:2182,192.168.10.11:2183;// 超时时间private int sessionTimeOut 30000;private final String ROOT_PATH /servers;private ZooKeeper client;public RegistrationCenter() {this(null);}public RegistrationCenter(ConsumerListString consumer) {try {getConnection(null consumer ? null : watchedEvent - {//监听服务器地址的上下线if (watchedEvent.getType() Watcher.Event.EventType.NodeChildrenChanged) {try {consumer.accept(subServers());} catch (Exception e) {e.printStackTrace();}}});Stat stat client.exists(ROOT_PATH, false);if (stat null) {//创建根节点client.create(ROOT_PATH, ROOT_PATH.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);}} catch (Exception e) {e.printStackTrace();}}/*** param serverName 将服务器注册到zk集群时所需的服务名称* param metadata 服务元数据* throws Exception*/public void doRegister(String serverName, Metadata metadata) throws Exception {/*** ZooDefs.Ids.OPEN_ACL_UNSAFE: 此权限表示允许所有人访问该节点服务器* CreateMode.EPHEMERAL_SEQUENTIAL: 由于服务器是动态上下线的上线后存在下线后不存在所以是临时节点* 而服务器一般都是有序号的所以是临时、有序的节点.*/String node client.create(ROOT_PATH / serverName, metadata.toString().getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);System.out.println(serverName 已经上线);}/*** 发现/订阅服务*/public ListString subServers() throws InterruptedException, KeeperException {ListString zkChildren client.getChildren(ROOT_PATH, true);ListString servers new ArrayList();zkChildren.forEach(node - {//拼接服务完整信息try {byte[] data client.getData(ROOT_PATH / node, false, null);servers.add(new String(data));} catch (Exception e) {e.printStackTrace();}});return servers;}private void getConnection(Watcher watcher) throws IOException {this.client new ZooKeeper(connectString, sessionTimeOut, watcher);}/*** 服务元数据*/public static class Metadata {public Metadata() {}public Metadata(String ip, int port) {this.ip ip;this.port port;}private String ip;private int port;public String getIp() {return ip;}public void setIp(String ip) {this.ip ip;}public int getPort() {return port;}public void setPort(int port) {this.port port;}Overridepublic String toString() {return { ip ip \ , port port };}}
}该类中两个核心方法doRegister()、subServers() 服务注册和订阅。
doRegister()主要是往 Zookeeper 中创建了一个临时节点数据临时节点的优势就是当服务出现断电等异常停机时节点会自动删除。subServers()则是去 Zookeeper 读取了所有服务提供者的信息并且监听了节点状态当节点发生创建、删除、更新等事件时重新获取服务者的信息做到数据实时更新。
至此一个简单的注册中心就完成了当然如果要实现一个成熟的注册中心还要考虑负载均衡、高可用性和容错、服务治理和路由控制等功能这里先不展开。
服务注册
当有了注册中心服务提供者就可以调用 doRegister() 进行注册代码如下
public class ProviderServer {public static void main(String[] args) throws Exception {RegistrationCenter registrationCenter new RegistrationCenter();registrationCenter.doRegister(provider, new RegistrationCenter.Metadata(127.0.0.1, 8080));Thread.sleep(Long.MAX_VALUE);}
}
服务发现
同样服务消费者可以调用 subServers() 发现服务提供者同时当服务提供者发生变化时会通知到消费者。代码如下
public class ConsumerServer {public static void main(String[] args) throws Exception {RegistrationCenter registrationCenter new RegistrationCenter(newServers - {System.out.println(服务更新了...newServers);});ListString servers registrationCenter.subServers();System.out.println(servers);Thread.sleep(Long.MAX_VALUE);}
}
总结
服务注册和服务发现功能是为了解决分布式系统中的服务管理和通信问题而设计的经过不断的发展与负载均衡、健康监测、服务治理和路由控制等功能完善成为一个注册中心。服务注册和服务发现有助于实现系统的弹性和可扩展性因为新的服务实例可以动态地加入系统而无需手动配置和修改已有的代码。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/930002.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!