原理图
与dubbo消费者的exchange transport codec基本一致 区别在于 transport层虽都是netty,一个是NioServerSocketChannel,一个是NioSocketChannel
源码分析
DubboProtocol.openServer
private void openServer ( URL url) {
String key = url. getAddress ( ) ;
boolean isServer = url. getParameter ( IS_SERVER_KEY, true ) ;
if ( isServer) {
ExchangeServer server = serverMap. get ( key) ;
if ( server == null ) {
线程安全
synchronized ( this ) {
server = serverMap. get ( key) ;
if ( server == null ) {
创建server
serverMap. put ( key, createServer ( url) ) ;
}
}
} else {
server. reset ( url) ;
}
}
}
createServer
调用Exchangers 完成ExchangeServer创建
private ExchangeServer createServer ( URL url) {
. . . . . . 删除url配置参数代码
ExchangeServer server;
try {
server = Exchangers . bind ( url, requestHandler) ;
} catch ( RemotingException e) {
throw new RpcException ( "Fail to start server(url: " + url + ") " + e. getMessage ( ) , e) ;
}
. . . . . . 删除其他代码
return server;
}
通过HeaderExchanger创建ExchangeServer
handler结构同nettyclient DecodeHandler不同于DubboCodec,DecodeHandler是更精细化的编解码针对dubbo的rpc业务层面,而DubboCodec针对网络传输层面
DecodeHandler HeaderExchangeHandler ExchangeHandlerAdapter 进一步完成Request内部的dubbo协议解码 用于方法调用 完成请求响应映射 查找dubbo exportor集合进行服务调用
public class HeaderExchanger implements Exchanger {
public static final String NAME = "header" ;
@Override
public ExchangeServer bind ( URL url, ExchangeHandler handler) throws RemotingException {
return new HeaderExchangeServer ( Transporters . bind ( url, new DecodeHandler ( new HeaderExchangeHandler ( handler) ) ) ) ;
}
}
Transporter完成bind
通过spi选择NettyTransporter NettyTransporter 负责NettyServer构建
public static Server bind ( URL url, ChannelHandler . . . handlers) throws RemotingException {
return getTransporter ( ) . bind ( url, handler) ;
}
public class NettyTransporter implements Transporter {
public static final String NAME = "netty" ;
@Override
public Server bind ( URL url, ChannelHandler listener) throws RemotingException {
return new NettyServer ( url, listener) ;
}
}
NettyServer构建
完成handler增强 MultiMessageHandler HeartbeatHandler AllChannelHandler 设置DubboCountCodec和handler装饰者到NettyServer的codec和handler属性 doOpen完成netty编排
public NettyServer ( URL url, ChannelHandler handler) throws RemotingException {
super ( url, ChannelHandlers . wrap ( handler, ExecutorUtil . setThreadName ( url, SERVER_THREAD_POOL_NAME) ) ) ;
}
public AbstractServer ( URL url, ChannelHandler handler) throws RemotingException {
设置codec 和handler属性
super ( url, handler) ;
netty编排
doOpen ( ) ;
}
doOpen实现netty编排
完成codec 和 exchange层handler向netty框架的注入编排
protected void doOpen ( ) throws Throwable {
bootstrap = new ServerBootstrap ( ) ;
bossGroup = new NioEventLoopGroup ( 1 , new DefaultThreadFactory ( "NettyServerBoss" , true ) ) ;
workerGroup = new NioEventLoopGroup ( getUrl ( ) . getPositiveParameter ( IO_THREADS_KEY, Constants . DEFAULT_IO_THREADS) ,
new DefaultThreadFactory ( "NettyServerWorker" , true ) ) ;
构建NettyServerHandler
final NettyServerHandler nettyServerHandler = new NettyServerHandler ( getUrl ( ) , this ) ;
channels = nettyServerHandler. getChannels ( ) ;
bootstrap. group ( bossGroup, workerGroup)
. channel ( NioServerSocketChannel . class )
. childOption ( ChannelOption . TCP_NODELAY, Boolean . TRUE)
. childOption ( ChannelOption . SO_REUSEADDR, Boolean . TRUE)
. childOption ( ChannelOption . ALLOCATOR, PooledByteBufAllocator . DEFAULT)
. childHandler ( new ChannelInitializer < NioSocketChannel > ( ) {
@Override
protected void initChannel ( NioSocketChannel ch) throws Exception {
int idleTimeout = UrlUtils . getIdleTimeout ( getUrl ( ) ) ;
构建NettyCodecAdapter
NettyCodecAdapter adapter = new NettyCodecAdapter ( getCodec ( ) , getUrl ( ) , NettyServer . this ) ;
ch. pipeline ( )
. addLast ( "decoder" , adapter. getDecoder ( ) )
. addLast ( "encoder" , adapter. getEncoder ( ) )
. addLast ( "server-idle-handler" , new IdleStateHandler ( 0 , 0 , idleTimeout, MILLISECONDS) )
. addLast ( "handler" , nettyServerHandler) ;
}
} ) ;
ChannelFuture channelFuture = bootstrap. bind ( getBindAddress ( ) ) ;
channelFuture. syncUninterruptibly ( ) ;
channel = channelFuture. channel ( ) ;
}
总结
结合第九篇,概述dubbo remote模块三层架构[exhcange,transport codec] 介绍编解码器以及各层实现基本作用,handler装饰者结构中,各handler基本作用 介绍dubbo的客户端和服务端的可复用共享模型[ip:port]