dubbo异步化实战

168 阅读1分钟

1. 生产端异步化

1.1 通过AsyncContext asyncContext = RpcContext.startAsync(); 开启异步

private ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(4, 4,0L,TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());

@Override
public String queryUserById(String id) {
    String resultMsg = "id = " + id + ", my name is bob";
    System.out.println(resultMsg);
    //开启异步
    AsyncContext asyncContext = RpcContext.startAsync();
    poolExecutor.execute(() -> {
        // 2. 如果要使用上下文,则必须要放在第一句执行
        asyncContext.signalContextSwitch();;

        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        // 3. 将业务结果写回
        System.out.println("invoke result: " + resultMsg);
        asyncContext.write(resultMsg);
    });

    return null;
}

消费端调用测试

public static void main(String[] args) throws IOException {
    ApplicationConfig applicationConfig = new ApplicationConfig("dubbo-consumer");
    applicationConfig.setQosEnable(false);
    RegistryConfig registryConfig = new RegistryConfig("zookeeper://1.117.109.40:2181?backup=1.117.109.40:2182,1.117.109.40:2183");

    // 创建引用 UserUpdateFacade 这个服务象
    ReferenceConfig<AsyncUserQueryFacade> referenceConfig = new ReferenceConfig<>();
    referenceConfig.setApplication(applicationConfig);
    referenceConfig.setRegistry(registryConfig);
    referenceConfig.setInterface(AsyncUserQueryFacade.class);
    referenceConfig.setTimeout(4000);

    // 直接拿到引用的代理对象,然后进行远程调用
    AsyncUserQueryFacade asyncUserQueryFacade = referenceConfig.get();
    System.out.println(asyncUserQueryFacade.queryUserById("来自丁亚武德测试"));
    System.out.println();

    //阻塞等待
    System.in.read();
}

1.2 返回CompletableFuture异步处理

@Override
public CompletableFuture<String> queryUserByName(String name) {
    CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {

        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        String resultMsg = "async name = " + name + ", my name is bob";
        return resultMsg;
    });
    return completableFuture;
}

消费端调用

public static void main(String[] args) throws IOException {
    // 设置应用服务名称
    ApplicationConfig applicationConfig = new ApplicationConfig("dubbo-consumer");
    // 设置注册中心地址
    RegistryConfig registryConfig = new RegistryConfig("zookeeper://1.117.109.40:2181?backup=1.117.109.40:2182,1.117.109.40:2183");

    // 创建引用 UserUpdateFacade 这个服务的对象
    ReferenceConfig<AsyncUserQueryFacade> referenceConfig = new ReferenceConfig<>();
    referenceConfig.setApplication(applicationConfig);
    referenceConfig.setRegistry(registryConfig);
    referenceConfig.setInterface(AsyncUserQueryFacade.class);
    referenceConfig.setTimeout(12000);

    // 直接拿到引用的代理对象,然后进行远程调用
    AsyncUserQueryFacade asyncUserQueryFacade = referenceConfig.get();
    CompletableFuture<String> completableFuture = asyncUserQueryFacade.queryUserByName("tom");
    completableFuture.whenComplete((value, e) -> {
        if(e != null) {
            e.printStackTrace();
        }
        else {
            System.out.println(value);
        }
    });
    //阻塞等待
    System.in.read();
}

2. 消费端异步化

2.1 通过getFuture调用等待结果

public class AsyncGetFutureResultJavaCodeConsumerApplication {  
  
public static void main(String[] args) throws IOException, ExecutionException, InterruptedException {  
ApplicationConfig applicationConfig = new ApplicationConfig("dubbo-consumer");  
applicationConfig.setQosEnable(false);  
RegistryConfig registryConfig = new RegistryConfig("zookeeper://1.117.109.40:2181?backup=1.117.109.40:2182,1.117.109.40:2183");  
  
// 创建引用 UserUpdateFacade 这个服务的对象  
ReferenceConfig<AsyncUserQueryFacade> referenceConfig = new ReferenceConfig<>();  
referenceConfig.setApplication(applicationConfig);  
referenceConfig.setRegistry(registryConfig);  
referenceConfig.setInterface(AsyncUserQueryFacade.class);  
referenceConfig.setTimeout(12000);  
//真正开启异步化调用,让调用方可以通过 Future 拿到结果  
referenceConfig.setAsync(true);  
  
// 直接拿到引用的代理对象,然后进行远程调用  
AsyncUserQueryFacade asyncUserQueryFacade = referenceConfig.get();  
//开启异步的话拿不到返回结果  
System.out.println(asyncUserQueryFacade.queryUserById("111"));  
  
// 拿到一个 Future 对象, 这个 Future 对象哪里来的呢?其实是从 RpcContext 远程调用上下文中获取得到的  
System.out.println(RpcContext.getContext().getFuture().get());  
  
//阻塞等待  
//System.in.read();  
}  
}

2.2 通过setCallback调用等待结果

public class AsyncCompletableFutureJavaCodeConsumerApplication {  
  
public static void main(String[] args) throws IOException {  
// 设置应用服务名称  
ApplicationConfig applicationConfig = new ApplicationConfig("dubbo-consumer");  
// 设置注册中心地址  
RegistryConfig registryConfig = new RegistryConfig("zookeeper://1.117.109.40:2181?backup=1.117.109.40:2182,1.117.109.40:2183");  
  
// 创建引用 UserUpdateFacade 这个服务的对象  
ReferenceConfig<AsyncUserQueryFacade> referenceConfig = new ReferenceConfig<>();  
referenceConfig.setApplication(applicationConfig);  
referenceConfig.setRegistry(registryConfig);  
referenceConfig.setInterface(AsyncUserQueryFacade.class);  
referenceConfig.setTimeout(12000);  
  
// 直接拿到引用的代理对象,然后进行远程调用  
AsyncUserQueryFacade asyncUserQueryFacade = referenceConfig.get();  
CompletableFuture<String> completableFuture = asyncUserQueryFacade.queryUserByName("tom");  
completableFuture.whenComplete((result, e) -> {  
if(e != null) {  
System.out.println(e);  
}  
else {  
System.out.println(result);  
}  
});  
//阻塞等待  
System.in.read();  
}  
}


2.3 通过getCompletableFuture调用等待结果

public class AsyncGetCompletableFutureResultJavaCodeConsumerApplication {  
  
public static void main(String[] args) throws IOException, ExecutionException, InterruptedException {  
// 设置应用服务名称  
ApplicationConfig applicationConfig = new ApplicationConfig("dubbo-consumer");  
// 设置注册中心地址  
RegistryConfig registryConfig = new RegistryConfig("zookeeper://");  
// 创建引用 UserUpdateFacade 这个服务的对象  
ReferenceConfig<AsyncUserQueryFacade> referenceConfig = new ReferenceConfig<>();  
referenceConfig.setApplication(applicationConfig);  
referenceConfig.setRegistry(registryConfig);  
referenceConfig.setInterface(AsyncUserQueryFacade.class);  
//真正开启异步化调用,让调用方可以通过 Future 拿到结果  
referenceConfig.setAsync(true);  
  
// 直接拿到引用的代理对象,然后进行远程调用  
AsyncUserQueryFacade asyncUserQueryFacade = referenceConfig.get();  
//开启异步的话拿不到返回结果  
System.out.println(asyncUserQueryFacade.queryUserById("111"));  
  
// 拿到一个 Future 对象, 这个 Future 对象哪里来的呢?其实是从 RpcContext 远程调用上下文中获取得到的  
System.out.println(RpcContext.getContext().getFuture().get());  
  
CompletableFuture<Object> completableFuture = RpcContext.getContext().getCompletableFuture();  
completableFuture.whenComplete((result, e) ->{  
if(e == null) {  
System.out.println("注定可以拿到结果:" + result);  
}  
else {  
System.out.println("非常意外走到了异常分支:" + e.getLocalizedMessage());  
}  
});  
  
//阻塞等待  
System.in.read();  
}  
}