1-24 6,455 views
整体架构
在分布式架构中,各模块采用多节点部署,对外提供服务,节点数量和服务地址不断会有变化,因此,对于服务调用者,需要动态获取服务地址。ZooKeeper(http://zookeeper.apache.org/)提供分布式协调服务,服务提供者可以将服务注册至ZooKeeper规定路径中,服务调用者再从ZooKeeper规定路径中动态发现服务,如图所示:
服务注册
Curator(http://curator.apache.org/)进一步封装了ZooKeeper API,提供了许多高级功能,包括服务注册和发现。ZooKeeper使用版本3.4.6,Curator使用版本2.9.1,在pom.xml中增加Curator依赖,如下所示:
1 2 3 4 5 6 7 8 9 10 |
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>3.2.5.RELEASE</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-x-discovery</artifactId> <version>2.9.1</version> </dependency> |
使用Curator进行服务注册,代码如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
/* 服务注册 start */ // 创建CuratorFramework实例,封装与ZooKeeper的操作。 CuratorFramework curatorFramework = CuratorFrameworkFactory.newClient("xxx.xxx.xxx.xxx:2181", new RetryNTimes(4, 2000)); curatorFramework.start(); // 创建ServiceInstanceBuilder实例,指定服务名称和地址, // 由ServiceInstanceBuilder实例构建ServiceInstance实例,ServiceInstance实例即服务。 ServiceInstanceBuilder serviceInstanceBuilder = ServiceInstance.builder(); serviceInstanceBuilder.uriSpec(new UriSpec("{scheme}://{address}:{port}")); serviceInstanceBuilder.address("xxx.xxx.xxx.xxx"); serviceInstanceBuilder.port(8080); serviceInstanceBuilder.name("service1"); ServiceInstance serviceInstance = serviceInstanceBuilder.build(); // 创建serviceDiscoveryBuilder实例,指定服务和服务在Zookeeper中所在路径, // 由ServiceDiscoveryBuilder实例构建ServiceDiscovery实例,由ServiceDiscovery实例注册服务。 ServiceDiscoveryBuilder serviceDiscoveryBuilder = ServiceDiscoveryBuilder.builder(Void.class); serviceDiscoveryBuilder.basePath("test"); serviceDiscoveryBuilder.client(curatorFramework); ServiceDiscovery serviceDiscovery = serviceDiscoveryBuilder.build(); serviceDiscovery.start(); //注册服务 serviceDiscovery.registerService(serviceInstance); /* 服务注册 end */ // 等待30秒,这时在ZooKeeper中可以查看到注册的服务 Thread.sleep(30000); // 30秒后,进程关闭,ZooKeeper中注册的服务因是临时节点而被删除,说明服务已不可用 |
启动进程,在ZooKeeper中可以查看到注册的服务,在服务“service1”所在路径“/test/service1”下有一个临时节点“ffd66440-e0b0-41a5-b93a-c558c527b3bc”,表示刚启动、注册的服务,如图所示:
30秒后进程关闭,在ZooKeeper中可以查看到,注册的服务因是临时节点而被删除,说明服务已不可用,如图所示:
服务发现
调用ServiceDiscovery实例的queryForInstances方法可以发现服务,代码如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
/* 服务发现 start */ // 创建CuratorFramework实例,封装与ZooKeeper的操作。 CuratorFramework curatorFramework = CuratorFrameworkFactory.newClient("xxx.xxx.xxx.xxx:2181", new RetryNTimes(4, 2000)); curatorFramework.start(); // 创建serviceDiscoveryBuilder实例,指定服务在Zookeeper中所在路径, // 由ServiceDiscoveryBuilder实例构建ServiceDiscovery实例,由ServiceDiscovery实例发现服务。 ServiceDiscoveryBuilder serviceDiscoveryBuilder = ServiceDiscoveryBuilder.builder(Void.class); serviceDiscoveryBuilder.basePath("test"); serviceDiscoveryBuilder.client(curatorFramework); ServiceDiscovery serviceDiscovery = serviceDiscoveryBuilder.build(); serviceDiscovery.start(); Collection<ServiceInstance> collection = serviceDiscovery.queryForInstances("service1"); if (collection != null && collection.size() > 0) { System.out.println("found " + collection.size() + " service1 services"); for (ServiceInstance serviceInstance : collection) { System.out.println("id: " + serviceInstance.getId()); } } /* 服务发现 end */ |
🙂