模拟微服务并行调用外部接口

模拟微服务并行调用外部接口

假如一个RPC接口需要依赖另外三个服务的功能,如果三个服务的响应时间假设分别为3秒、1秒、2秒,这时候如果顺序执行需要6秒的时间。如果依赖的服务逐渐增多,那么响应的时间也会越来越长。
模拟微服务并行调用外部接口_第1张图片

如果让三个服务并行执行,那么这个接口理论上响应时间为3秒。
模拟微服务并行调用外部接口_第2张图片

  • 如果接口调用不关心返回值,则可以使用异步的方式;
  • 如果接口调用需要返回值,则需要采用并行执行;

本文模拟需要返回值,采用并行线程,减少RPC接口响应时间。

创建3个模拟RPC服务接口

private static String getUser() {
       //模拟查询需要两秒
       try {
           Thread.sleep(2000);
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
       return "张三";
   }

   private static String getClasz() {
       //模拟查询需要3秒
       try {
           Thread.sleep(3000);
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
       return "1班";
   }

   private static String getAddress() {
       //模拟查询需要1秒
       try {
           Thread.sleep(1000);
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
       return "深圳";
   }

如果我们采用顺序执行,执行时间大约6s.

private static void test() {
       long start = System.currentTimeMillis();
       System.out.println(getUser());
       System.out.println(getClasz());
       System.out.println(getAddress());
       long end = System.currentTimeMillis();
       System.out.println("执行时间为:  " + (end - start));
   }

模拟微服务并行调用外部接口_第3张图片

这里提供两种方法

  1. Future
private static void test01() {
      long start = System.currentTimeMillis();

      CountDownLatch countDownLatch = new CountDownLatch(3);
      ExecutorService es = Executors.newFixedThreadPool(3);
      Future getUserInfo = es.submit(() -> {
          String user = getUser();
          countDownLatch.countDown();
          return user;
      });
      Future getClaszInfo = es.submit(() -> {
          String clasz = getClasz();
          countDownLatch.countDown();
          return clasz;
      });
      Future getAddressInfo = es.submit(() -> {
          String address = getAddress();
          countDownLatch.countDown();
          return address;
      });

      try {
          //同步等待所有线程执行完之后再继续
          countDownLatch.await();
          System.out.println(getUserInfo.get());
          System.out.println(getClaszInfo.get());
          System.out.println(getAddressInfo.get());
      } catch (Exception e) {
          e.printStackTrace();
      } finally {
          es.shutdown();
      }

      long end = System.currentTimeMillis();
      System.out.println("执行时间为:  " + (end - start));
  }

执行时间为3秒多,效率明显上去了。
模拟微服务并行调用外部接口_第4张图片

  1. CompletableFutures
    private static void test02() {
       long start = System.currentTimeMillis();

       CompletableFuture<String> getUserInfo = CompletableFuture.supplyAsync(() -> {
           return getUser();
       });
       CompletableFuture<String> getClaszInfo = CompletableFuture.supplyAsync(() -> {
          try {
              return getClasz();
          }catch (Exception e){
              return e.toString();
          }
       });
       CompletableFuture<String> getAddressInfo = CompletableFuture.supplyAsync(() -> {
           return getAddress();
       });
       CompletableFuture.allOf(getUserInfo, getClaszInfo, getAddressInfo);
       try {
           System.out.println(getUserInfo.get());
           System.out.println(getClaszInfo.get());
           System.out.println(getAddressInfo.get());
       } catch (InterruptedException e) {
           e.printStackTrace();
       } catch (ExecutionException e) {
           e.printStackTrace();
       }
       long end = System.currentTimeMillis();
       System.out.println("执行时间为:  " + (end - start));
   }

响应速度也是3秒多,效率与顺序执行相比提高了一半。
模拟微服务并行调用外部接口_第5张图片

你可能感兴趣的:(算法,算法,java,分布式)