UDN-企业互联网技术人气社区

板块导航

浏览  : 1588
回复  : 0

[资源分享] 使用Vert.x开发响应式微服务

[复制链接]
瞌睡虫的头像 楼主
发表于 2016-11-3 09:59:59 | 显示全部楼层 |阅读模式
  响应式系统是一种建立分布式应用程序新方式,利用现代的处理器架构的优势,更有效地使用资源。结合微服务,它提供了一个惊人的灵活性,每个组件单独开发,发布,部署,更新和退出。建设微服架构却不容易。需要管理许多方面,如部署设施、服务发现、服务之间的相互作用、弹性模式、可扩展性等。
  
  Eclipse Vert.x是一个建立微服务的工具。它给你塑造你的系统的自由,确保其响应性,弹性。你的组件之间通信是异步的,利用非堵塞异步性Vert.x。
  
  Vert.x是一个简单的,可扩展的,类似actor模型的可部署和并发模型。Verticles是一些代码块,能部署和运行在Vert中。Vert.x应用程序通常是由许多Verticles实例运行在同一个Vert.x实例中。Vert.x实例彼此之间通过事件总线发送消息实现异步交互。
  
  默认Verticles是运行在Vert.x事件循环中,必须不能有堵塞代码,Vert.x确保每个Verticles总是被同样线程执行。
  
  Verticles可由许多语言支持,Java需要拓展AbstractVerticle,它的start和stop方法对应Verticles部署和卸载的生命周期阶段。
  
  import io.vertx.core.AbstractVerticle;
  
  public class MyVerticle extends AbstractVerticle {
  
  @Override
  
  public void start() throws Exception {
  
  // Executed when the verticle is deployed
  
  }
  
  @Override
  
  public void stop() throws Exception {
  
  // Executed when the verticle is undeployed
  
  }
  
  }
  
  一个verticle 能通过传入配置部署其他verticle ,可以创建很多verticle 实例,每个实例运行在不同的event loop事件循环中,Vert.x会平衡这些实例负载,这样就能充分利用你的CPU多核威力。
  
  public class MyDeployingVerticle extends AbstractVerticle {
  
  @Override
  
  public void start() throws Exception {
  
  // Pass a configuration
  
  JsonObject config = new JsonObject().put("key", "value");
  
  vertx.deployVerticle(io.vertx.starter.MyVerticle.class.getName(),
  
  new DeploymentOptions().setConfig(config));
  
  // Set the number of instances
  
  vertx.deployVerticle(io.vertx.starter.MyVerticle.class.getName(),
  
  new DeploymentOptions().setInstances(2));
  
  }
  
  }
  
  创建第一个Vert.x项目
  
  创建Maven项目:
  
  git clone https://github.com/vert-x3/vertx-maven-starter.git PROJECT_NAME
  
  解压目录运行:./redeploy.sh(redeploy.bat),浏览器打开 http://localhost:8080, 你会看到第一个Vert.x项目。
  
  实现REST API
  
  看看使用 Vert.x Web如何实现简单REST API ,增加依赖到你的pom.xml:
  
  ‹dependency›
  
  ‹groupId›io.vertx‹/groupId›
  
  ‹artifactId›vertx-web‹/artifactId›
  
  ‹/dependency›
  
  Vert.x Web是一个基于Vert.x让你方便实现REST API的组件,提供服务器端模板 静态文件支持 错误页面。提供路由Router概念,每个route有一个处理器处理请求建立响应。
  
  下面是以讹增加名称的简单案例:
  
  package io.vertx.starter;
  
  import io.vertx.core.AbstractVerticle;
  
  import io.vertx.core.json.Json;
  
  import io.vertx.ext.web.Router;
  
  import io.vertx.ext.web.handler.BodyHandler;
  
  import java.util.ArrayList;
  
  import java.util.List;
  
  public class MyRestAPIVerticle extends AbstractVerticle {
  
  // Maintain a simple list of names维持名称简单列表
  
  private List names = new ArrayList<>();
  
  @Override
  
  public void start() {
  
  // Create a Vert.x web router
  
  Router router = Router.router(vertx);
  
  // Register a simple first route on / 注册一个简单首个route在根路径/
  
  router.get("/").handler(rc -> {
  
  rc.response().end("Welcome");
  
  });
  
  // Register a second router retrieving all stored names as JSON注册第二个router返回名称列表
  
  router.get("/names").handler(
  
  // Just encode the list as JSON and return.
  
  rc -> rc.response()
  
  .putHeader("content-type", "application/json")
  
  .end(Json.encode(names)));
  
  // Register a body handler indicating that other routes need
  
  // to read the request body
  
  router.route().handler(BodyHandler.create());
  
  // Register a third route to add names注册第三个router增加名称
  
  router.post("/names").handler(
  
  rc -> {
  
  // Read the body
  
  String name = rc.getBody().toString();
  
  if (name.isEmpty()) {
  
  // Invalid body -> Bad request
  
  rc.response().setStatusCode(400).end();
  
  } else if (names.contains(name)) {
  
  // Already included name -> Conflict
  
  rc.response().setStatusCode(409).end();
  
  } else {
  
  // Add the name to the list -> Created
  
  names.add(name);
  
  rc.response().setStatusCode(201).end(name);
  
  }
  
  });
  
  vertx.createHttpServer()
  
  // Pass the router's accept method as request handler
  
  .requestHandler(router::accept)
  
  .listen(8080);
  
  }
  
  }
  
  消费REST API
  
  当建立微服务时,你需要使用调用服务,也就是需要消费REST API,vert.x提供异步HTTP客户端。
  
  package io.vertx.starter;
  
  import io.vertx.core.AsyncResult;
  
  import io.vertx.core.Future;
  
  import io.vertx.core.Handler;
  
  import io.vertx.core.Vertx;
  
  import io.vertx.core.http.HttpClient;
  
  import io.vertx.core.http.HttpClientOptions;
  
  import io.vertx.core.json.JsonArray;
  
  public class MyRestAPIClient {
  
  private HttpClient client;
  
  public MyRestAPIClient(Vertx vertx) {
  
  // Create the HTTP client and configure the host and post.
  
  client = vertx.createHttpClient(new HttpClientOptions()
  
  .setDefaultHost("localhost")
  
  .setDefaultPort(8080)
  
  );
  
  }
  
  public void close() {
  
  // Don't forget to close the client when you are done.
  
  client.close();
  
  }
  
  public void getNames(Handler<asyncresult> handler) {
  
  // Emit a HTTP GET
  
  client.get("/names",
  
  response ->
  
  // Handler called when the response is received
  
  // We register a second handler to retrieve the body
  
  response.bodyHandler(body -> {
  
  // When the body is read, invoke the result handler
  
  handler.handle(Future.succeededFuture(body.toJsonArray()));
  
  }))
  
  .exceptionHandler(t -> {
  
  // If something bad happen, report the failure to the passed handler
  
  handler.handle(Future.failedFuture(t));
  
  })
  
  // Call end to send the request
  
  .end();
  
  }
  
  public void addName(String name, Handler<asyncresult> handler) {
  
  // Emit a HTTP POST
  
  client.post("/names",
  
  response -> {
  
  // Check the status code and act accordingly
  
  if (response.statusCode() == 200) {
  
  handler.handle(Future.succeededFuture());
  
  } else {
  
  handler.handle(Future.failedFuture(response.statusMessage()));
  
  }
  
  })
  
  .exceptionHandler(t -> handler.handle(Future.failedFuture(t)))
  
  // Pass the name we want to add
  
  .end(name);
  
  }
  
  }
  
  下面代码显示上面客户端代码是具体如何被调用:
  
  Vertx vertx = Vertx.vertx();
  
  MyRestAPIClient client = new MyRestAPIClient(vertx);
  
  client.getNames(ar -> {
  
  if (ar.succeeded()) {
  
  System.out.println("Names: " + ar.result().encode());
  
  } else {
  
  System.out.println("Unable to retrieve the list of names: "
  
  + ar.cause().getMessage());
  
  }
  
  });

来源:解道


相关帖子

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关于我们
联系我们
  • 电话:010-86393388
  • 邮件:udn@yonyou.com
  • 地址:北京市海淀区北清路68号
移动客户端下载
关注我们
  • 微信公众号:yonyouudn
  • 扫描右侧二维码关注我们
  • 专注企业互联网的技术社区
版权所有:用友网络科技股份有限公司82041 京ICP备05007539号-11 京公网网备安1101080209224 Powered by Discuz!
快速回复 返回列表 返回顶部