客户端的多种异步服务调用方式

——《大型网站系统与Java中间件实践》学习笔记

使用NIO能够完成连接复用以及对调用者的同步调用的支持,其调用方式,除了同步调用外,还有如下的几种调用方式。

1 Oneway方式

原理:单向(Oneway)发送特点为只负责发送消息,不等待服务器回应且没有回调函数触发,即只管发送请求而不关心结果。此方式发送消息的过程耗时非常短,一般在微秒级别。在NIO下使用oneway的话,会比同步调用简单很多,如下图所示:

1571470680390.png

把发送的数据放入数据队列中就可以继续后面的任务了。IO线程也只用从数据队列中读出数据然后通过Socket发送出去就好了,Oneway不关心对方是否接收到了数据,也不关心对方收到数据之后最什么或则有什么返回。属于不保证可靠送达的通知。

应用场景:适用于某些耗时非常短,但对可靠性要求并不高的场景,例如日志收集。

public void invokeOneway(String addr, RemotingCommand request, long timeoutMillis) throws InterruptedException, RemotingConnectException, RemotingTooMuchRequestException, RemotingTimeoutException, RemotingSendRequestException {    
    Channel channel = this.getAndCreateChannel(addr);    
    if (channel != null && channel.isActive()) {        
        try {            
            if (this.rpcHook != null) {                
                this.rpcHook.doBeforeRequest(addr, request);            
            }
            this.invokeOnewayImpl(channel, request, timeoutMillis); 
        } catch (RemotingSendRequestException var7) {            
            ······ 
        }    
    } else {        
        ······  
    }
}

上面的代码是com.aliyun.openservices包中mq的onceway的实现,可以看到invokeOnewayImpl()创建channel发送消息,其他的就不关心了。

2 Callback回调方式

这种方式下请求发送方发送请求之后会继续执行自己的操作,等对方有响应时进行一个回调。设计图如下:

1571473877776.png

上图分析:
(1)调用者首先设置了回调对象,然后将数据写入数据队列之后就可以做自己的事了。

(2)后面的IO线程也是一样,从数据队列中取出数据,建立Socket然后发送给服务端。

(3)当服务提供者返回之后,IO线程会通知回调对象,这时候就执行回调方法。

(4)如果需要支持超时,同样通过定时任务来处理,如果超时服务提供者还没有返回,这时候也执行回调方法,通知超时没有结果。

(5)这里需要注意的是,回调函数的执行最好是在单独的线程中,不要放在IO线程中执行,防止回调函数的执行时间长等问题影响了IO线程。

producer.sendAsync(msg, new SendCallback() {    
    @Override    
    public void onSuccess(SendResult sendResult) { 
        // TODO
    }    
    @Override    
    public void onException(OnExceptionContext onExceptionContext) {  
        // TODO
    }
});

上面的代码中sendAsync()方法采用就是Callback回调方式,无论msg是否发送成功,或者是否超时,都会调用SendCallback。

3 Future方式

这种实现的结构如下图:

1571621544852.png

同样是在数据入队前设置Future对象,接着就在线程中发送数据到服务提供者。等到获取到服务提供者的响应之后,就通过Future来获取通信结果并直接控制超时。

4 可靠异步方式(消息队列中间件)

可靠异步要保证异步请求能够在远程被执行,一般通过消息中间件来完成这个保障。

5 总结

上面四种异步通信方式中:
(1)Oneway是单向的通知;
(2)Callback回调是一种被动的方式,Callback的执行不是在原请求线程中。
(3)Future是一种能够主动控制超时、获取结果的方式,并且它的执行仍然在原请求线程中。
(4)可靠异步方式能保证异步请求在远程被执行。


莫小点还有救
219 声望26 粉丝

优秀是一种习惯!