try {
// handle data.
Object result = handler.reply(channel, msg); //真正的业务逻辑类
res.setStatus(Response.OK);
res.setResult(result);
} catch (Throwable e) {
res.setStatus(Response.SERVICE_ERROR);
res.setErrorMessage(StringUtils.toString(e));
}
return res;
}
public void received(Channel channel, Object message) throws RemotingException {
…
if (message instanceof Request) {
// handle request.
Request request = (Request) message;
if (request.isTwoWay()) {
Response response = handleRequest(exchangeChannel, request); //处理业务逻辑,得到一个Response
channel.send(response); //回写response
}
}
…
}
1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.33.34.35.36.37.
channel.send(response)最终调用了NioServerSocketPipelineSink里的方法把返回报文放入队列。
9.服务端IO线程从队列中取出数据
=================
与流程3一样
10.服务端IO线程把回复数据写入Socket发送缓冲区
============================
IO线程写数据的时候,写入到TCP缓冲区就算成功了。但是如果缓冲区满了,会写不进去。对于阻塞和非阻塞IO,返回结果不一样,阻塞IO会一直等,而非阻塞IO会立刻失败,让调用者选择策略。
Netty的策略是尝试最多写16次,如果不成功,则暂时停掉IO线程的写操作,等待连接可写时再写,writeSpinCount默认是16,可以通过参数调整。
for (int i = writeSpinCount; i > 0; i --) {
localWrittenBytes = buf.transferTo(ch);
if (localWrittenBytes != 0) {
writtenBytes += localWrittenBytes;
break;
}
if (buf.finished()) {
break;
}
}
if (buf.finished()) {
// Successful write - proceed to the next message.
buf.release();
channel.currentWriteEvent = null;
channel.currentWriteBuffer = null;
evt = null;
buf = null;
future.setSuccess();
} else {
// Not written fully - perhaps the kernel buffer is full.
addOpWrite = true;
channel.writeSuspended = true;
1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.
11.数据传输
=======
数据在网络上传输主要取决于带宽和网络环境。
12.客户端IO线程把数据从缓冲区读出
===================
这个过程跟流程6是一样的
13.IO线程把数据交给Dubbo业务线程池
======================
这一步与流程7是一样的,这个线程池名字为DubboClientHandler。
14.业务线程池根据消息ID通知主线程
===================
先通过HeaderExchangeHandler的received函数得知是Response,然后调用handleResponse,
public class HeaderExchangeHandler implements ChannelHandl