最近研究了一下Vert.x3.0 基于ZK的分布式调用
maven依赖
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.miaozhen</groupId> <artifactId>vertx.cluster.consumer</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>vertx.cluster.consumer</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <vertx.version>3.2.1</vertx.version> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>io.vertx</groupId> <artifactId>vertx-zookeeper</artifactId> <version>3.2.0-SNAPSHOT</version> </dependency> <dependency> <groupId>io.vertx</groupId> <artifactId>vertx-service-proxy</artifactId> <version>${vertx.version}</version> </dependency> <dependency> <groupId>io.vertx</groupId> <artifactId>vertx-core</artifactId> <version>${vertx.version}</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.5</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-web</artifactId> <version>2.5</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j-impl</artifactId> <version>2.5</version> </dependency> </dependencies> <build> <defaultGoal>package</defaultGoal> <resources> <resource> <directory>src/main/resource</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> </resource> </resources> <plugins> <plugin> <artifactId>maven-assembly-plugin</artifactId> <version>2.2</version> <configuration> <archive> <manifest> <mainClass>com.miaozhen.vertx.cluster.consumer.ServiceVerticle</mainClass> </manifest> </archive> <descriptors> <descriptor>src/main/assemble/package.xml</descriptor> </descriptors> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>2.3.2</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <encoding>UTF-8</encoding> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> </project>
注意:vertx-zookeeper的jar不能直接使用,因为负载均衡算法有问题(永远只取第一个),而且provider的创建也是永久的节点并非临时节点,此处的jar包是我从github上下载并修改源码编译的版本,附上github地址:https://github.com/vert-x3/vertx-zookeeper.git
需要修改源码的地方:
/** * @author <a href="http://tfox.org">Tim Fox</a> */ class ChoosableSet<T> implements ChoosableIterable<T>, Serializable { ....... //此处是需要修改的位置,为了方便我只是随机获取,有兴趣的同学可以改成其他负载均衡算法 public synchronized T choose() { if (!ids.isEmpty()) { List<T> list = Lists.newArrayList(ids); Random random = new Random(); return list.get(random.nextInt(list.size())); } else if (ids.size() == 1) { return ids.iterator().next(); } else { return null; } } }
package io.vertx.spi.cluster.impl.zookeeper; /** * Created by Stream.Liu */ abstract class ZKMap<K, V> { ...... //此处是需要修改的地方 protected static final String EVENTBUS_PATH = "/" + ZK_PATH_ASYNC_MULTI_MAP + "/__vertx.subs/"; ....... }
服务端代码
package com.miaozhen.vertx.cluster.consumer; import java.util.Properties; import io.vertx.core.AbstractVerticle; import io.vertx.core.Handler; import io.vertx.core.Vertx; import io.vertx.core.VertxOptions; import io.vertx.core.eventbus.EventBus; import io.vertx.core.eventbus.Message; import io.vertx.core.json.Json; import io.vertx.core.spi.cluster.ClusterManager; import io.vertx.serviceproxy.ProxyHelper; import io.vertx.spi.cluster.impl.zookeeper.ZookeeperClusterManager; public class ServiceVerticle extends AbstractVerticle { @Override public void start() throws Exception { //这里为了做示范就直接写死在代码中了,实际运用可以从配置文件获取 Properties zkConfig = new Properties(); zkConfig.setProperty("hosts.zookeeper", "192.168.2.62"); zkConfig.setProperty("path.root", "io.vertx"); zkConfig.setProperty("retry.initialSleepTime", "1000"); zkConfig.setProperty("retry.intervalTimes", "3"); ClusterManager mgr = new ZookeeperClusterManager(zkConfig); VertxOptions options = new VertxOptions().setClusterManager(mgr); Vertx.clusteredVertx(options, res -> { if (res.succeeded()) { vertx = res.result(); EventBus eb = vertx.eventBus(); eb.consumer("Test", new Handler<Message<String>>() { @Override public void handle(Message<String> event) { event.reply(event.body() +" . Hi"); } }); } else { // failed! } }); } public static void main(String[] args) { ServiceVerticle mainVerticle = new ServiceVerticle(); try { mainVerticle.start(); } catch (Exception e) { e.printStackTrace(); } } }
客户端代码
package com.miaozhen.vertx.cluster; import java.util.Properties; import io.vertx.core.AbstractVerticle; import io.vertx.core.Handler; import io.vertx.core.Vertx; import io.vertx.core.VertxOptions; import io.vertx.core.eventbus.EventBus; import io.vertx.core.eventbus.SendContext; import io.vertx.core.http.HttpServer; import io.vertx.core.spi.cluster.ClusterManager; import io.vertx.ext.web.Router; import io.vertx.spi.cluster.impl.zookeeper.ZookeeperClusterManager; public class ClientVerticle extends AbstractVerticle { @Override public void start() throws Exception { System.out.println("MainVerticle startting in thread: " + Thread.currentThread().getName()); Properties zkConfig = new Properties(); zkConfig.setProperty("hosts.zookeeper", "192.168.2.62"); zkConfig.setProperty("path.root", "io.vertx"); zkConfig.setProperty("retry.initialSleepTime", "1000"); zkConfig.setProperty("retry.intervalTimes", "3"); ClusterManager mgr = new ZookeeperClusterManager(zkConfig); VertxOptions options = new VertxOptions().setClusterManager(mgr); Vertx.clusteredVertx(options, res -> { if (res.succeeded()) { vertx = res.result(); HttpServer server = vertx.createHttpServer(); Router route = Router.router(vertx); route.get("/hello").handler(new Handler<RoutingContext>() { @Override public void handle(RoutingContext event) { eb.send("Test", "Hello",new Handler<AsyncResult<Message<String>>>() { @Override public void handle(AsyncResult<Message<String>> result) { if(result.succeeded()){ event.response().end(Buffer.buffer(result.result().body())); }else{ event.response().end(Buffer.buffer("failed")); } } }); } }); server.requestHandler(route::accept); server.listen(8090); } else { // failed! } }); } @Override public void stop() throws Exception { super.stop(); } public static void main(String[] args) { ClientVerticle mainVerticle = new ClientVerticle(); try { mainVerticle.start(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
最后附一张请求成功的图片
好了,关于Vert.x 3.0基于ZK的分布式就先到这里吧