1. 程式人生 > >使用Apache Curator實現服務的註冊和發現

使用Apache Curator實現服務的註冊和發現

使用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
---------------------