使用zookeeper可以实现服务的注册和发现,而Curator是对zookeeper进行的一层封装,自然也封装了一套实现服务的注册和发现,本文就介绍如何使用Curator实现服务的注册和发现
首先要安装zookeeper,我这里安装的是:zookeeper-3.4.6
curator 的依赖版本如下:
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-x-discovery-server</artifactId>
<version>2.9.1</version>
</dependency>
做服务的注册和发现,自然要有服务端和客户端
服务端代码如下:
服务端一:
package com.mall.zk.service;
/**
* 服务的附加信息
*/
public class ServiceDetail {
//服务注册的根路径
public static final String REGISTER_ROOT_PATH = "/mall";
private String desc;
private int weight;
public ServiceDetail() {}
public ServiceDetail(String desc, int weight) {
this.desc = desc;
this.weight = weight;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
@Override
public String toString() {
return "ServiceDetail [desc=" + desc + ", weight=" + weight + "]";
}
}
package com.mall.zk.server;
import java.util.concurrent.TimeUnit;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.curator.x.discovery.ServiceDiscovery;
import org.apache.curator.x.discovery.ServiceDiscoveryBuilder;
import org.apache.curator.x.discovery.ServiceInstance;
import org.apache.curator.x.discovery.ServiceInstanceBuilder;
import org.apache.curator.x.discovery.details.JsonInstanceSerializer;
import com.mall.zk.service.ServiceDetail;
public class AppServer {
public static void main(String[] args) throws Exception {
CuratorFramework client = CuratorFrameworkFactory.newClient("192.168.1.101:2181", new ExponentialBackoffRetry(1000, 3));
client.start();
client.blockUntilConnected();
/**
* 指定服务的 地址,端口,名称
*/
ServiceInstanceBuilder<ServiceDetail> sib = ServiceInstance.builder();
sib.address("192.168.1.100");
sib.port(8855);
sib.name("tomcat");
sib.payload(new ServiceDetail("主站web程序", 1));
ServiceInstance<ServiceDetail> instance = sib.build();
ServiceDiscovery<ServiceDetail> serviceDiscovery = ServiceDiscoveryBuilder.builder(ServiceDetail.class)
.client(client)
.serializer(new JsonInstanceSerializer<ServiceDetail>(ServiceDetail.class))
.basePath(ServiceDetail.REGISTER_ROOT_PATH)
.build();
//服务注册
serviceDiscovery.registerService(instance);
serviceDiscovery.start();
TimeUnit.SECONDS.sleep(70);
serviceDiscovery.close();
client.close();
}
}
服务端二:
package com.mall.zk.server;
import java.util.concurrent.TimeUnit;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.curator.x.discovery.ServiceDiscovery;
import org.apache.curator.x.discovery.ServiceDiscoveryBuilder;
import org.apache.curator.x.discovery.ServiceInstance;
import org.apache.curator.x.discovery.ServiceInstanceBuilder;
import org.apache.curator.x.discovery.details.JsonInstanceSerializer;
import com.mall.zk.service.ServiceDetail;
public class AppServer2 {
public static void main(String[] args) throws Exception {
CuratorFramework client = CuratorFrameworkFactory.newClient("192.168.1.101:2181", new ExponentialBackoffRetry(1000, 3));
client.start();
client.blockUntilConnected();
/**
* 指定服务的 地址,端口,名称
*/
ServiceInstanceBuilder<ServiceDetail> sib = ServiceInstance.builder();
sib.address("192.168.1.100");
sib.port(8866);
sib.name("tomcat");
sib.payload(new ServiceDetail("主站web程序", 2));
ServiceInstance<ServiceDetail> instance = sib.build();
ServiceDiscovery<ServiceDetail> serviceDiscovery = ServiceDiscoveryBuilder.builder(ServiceDetail.class)
.client(client)
.serializer(new JsonInstanceSerializer<ServiceDetail>(ServiceDetail.class))
.basePath(ServiceDetail.REGISTER_ROOT_PATH)
.build();
//服务注册
serviceDiscovery.registerService(instance);
serviceDiscovery.start();
TimeUnit.SECONDS.sleep(70);
serviceDiscovery.close();
client.close();
}
}
上面两个服务端代码,几乎一样,只是服务端口,权重不一样。然后运行上面两个main方法
然后,去zk里面查看
[zk: localhost:2181(CONNECTED) 54] ls /mall/tomcat
[a8657594-ef32-4efc-b2b0-3077d105e486, b5b55bbc-ce04-4b70-9413-1ec3c54023b8]
可以看到,有2个临时节点,也就意味着有两个服务
客户端代码:
package com.mall.zk.client;
import java.util.Collection;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.curator.x.discovery.ServiceDiscovery;
import org.apache.curator.x.discovery.ServiceDiscoveryBuilder;
import org.apache.curator.x.discovery.ServiceInstance;
import com.mall.zk.service.ServiceDetail;
public class AppClient {
public static void main(String[] args) throws Exception{
CuratorFramework client = CuratorFrameworkFactory.newClient("192.168.1.101:2181", new ExponentialBackoffRetry(1000, 3));
client.start();
client.blockUntilConnected();
ServiceDiscovery<ServiceDetail> serviceDiscovery = ServiceDiscoveryBuilder.builder(ServiceDetail.class)
.client(client)
.basePath(ServiceDetail.REGISTER_ROOT_PATH)
.build();
serviceDiscovery.start();
//根据名称获取服务
Collection<ServiceInstance<ServiceDetail>> services = serviceDiscovery.queryForInstances("tomcat");
for(ServiceInstance<ServiceDetail> service : services) {
System.out.println(service.getPayload());
System.out.println(service.getAddress() + "\t" + service.getPort());
System.out.println("---------------------");
}
serviceDiscovery.close();
client.close();
}
}
运行客户端,输出:
ServiceDetail [desc=主站web程序, weight=2]
192.168.1.100 8866
---------------------
ServiceDetail [desc=主站web程序, weight=1]
192.168.1.100 8855
---------------------