首先介绍Zookeeper的命名服务
命名服务,客户端能够根据指定节点的名字来获取资源或者服务地址,然后进行下一步操作
Zookeeper集群的负载均衡
可使用Nginx(或Haproxy) +keepalived 来实现Zookeeper集群的负载均衡
单个Zookeeper 中znode的轮询
java代码实现轮询:
当节点服务关闭,不会影响其他节点服务的使用
/**
*
* 模拟两秒一个请求,分配到 /bank/下的bk1,bk2,bk3,bk4,bk5
* 实际不能这么写 = = 这只是一个测试,一个思想,具体线程安全等问题没有实现
* @author start_lie
*
*/
public class MyZookeeper {
private final static Logger log = Logger.getLogger(MyZookeeper.class);
private static ZooKeeper zk=null;
private final static String CONNECT_STRING="192.168.83.128:2991";
private final static int SESSION_TIMEOUT=20*1000;
private static int cutNum=1;
private static int nextWindow=1;
private static int totalWindow=5;
static{
try {
zk=new ZooKeeper(CONNECT_STRING, SESSION_TIMEOUT, (even)->{});
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void createZnode(String path,String data) throws KeeperException, InterruptedException {
zk.create(path, data.getBytes(), Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);
}
public String getZnode(String path) throws KeeperException, InterruptedException {
byte[] result = zk.getData(path, new Watcher() {
@Override
public void process(WatchedEvent event) {
// TODO Auto-generated method stub
try {
getZnode(path);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, new Stat());
String dat = new String(result);
log.info("now this node value is :"+dat);
return dat;
}
public static String getZnode1(String path) throws KeeperException, InterruptedException {
byte[] result = zk.getData(path, false, new Stat());
String dat = new String(result);
//log.info("now this node value is :"+dat);
return dat;
}
public static String doRequest(String path) throws Exception {
List<String> list = zk.getChildren(path, false);
int sign=0;
while(true) {
sign++;
if(list.contains("bk"+nextWindow)) {
nextWindow++;
return getZnode1(path+"/bk"+(nextWindow-1));
}else {
if(nextWindow>=totalWindow) {
nextWindow=1;
}else {
nextWindow++;
}
}
if(sign==totalWindow) {
return "No useable Znode!";
}
}
}
public static void main(String[] args) throws Exception {
// MyZookeeper mzk = new MyZookeeper();
// String path = "/myzoo";
// String data = "zuishuai goodlook";
// String result = mzk.getZnode(path);
// if(result==null) {
// mzk.createZnode(path, data);
// }else {
// log.info("i have this node");
// }
// Thread.sleep(Long.MAX_VALUE);
while(true) {
String reault = doRequest("/bank");
System.out.println("Curstom : "+(cutNum++)+" result :"+reault);
Thread.sleep(2000);
}
}
}
与Dubbo整合
web.xml中整合spring
pom.xml加依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.5.7</version>
<exclusions>
<exclusion>
<!-- 排除传递spring依赖 -->
<artifactId>spring</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.3.3</version>
</dependency>
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
<version>0.1</version>
</dependency>
在resourse下新建文件夹dubbo,在里面新建dubbo.xml文件,内容(设置服务实现类,并将其接口暴露):
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- 提供方应用信息,用于计算依赖关系 -->
<dubbo:application name="dubboProvider" />
<!-- 这里使用的注册中心是zookeeper,请换成自己的IP地址 -->
<dubbo:registry address="zookeeper://192.168.1.167:2181" client="zkclient" />
<!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="20880"/>
<!-- 将该接口暴露到dubbo中 -->
<dubbo:service ref="bookServiceImpl" interface="com.test.dubbo.service.BookService"/>
<!-- 将具体的实现类加入到Spring容器中 -->
<bean id="bookServiceImpl" class="com.test.dubbo.BookServiceImpl" />
</beans>
消费者服务中resourse下建立dubbo/dubbo.xml :
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- 提供方应用信息 -->
<dubbo:application name="dubboConsumer" />
<!--注册中心是zookeeper -->
<dubbo:registry address="zookeeper://192.168.83.128:2991" client="zkclient" />
<!-- 从注册中心中查找服务 -->
<dubbo:reference id="bookService" interface="com.test.service.BookService" />
</beans>
用spring自动注入该service就可以调用了
注册多节点+轮询算法可以实现软负载均衡