1.概述
dubbo-remoting-api 模块, transport 包,网络传输层。
涉及的类图如下:
2.AbstractPeer
实现 Endpoint、ChannelHandler 接口,Peer 抽象类。
/**
* AbstractPeer
*
* Peer 抽象类
*/
public abstract class AbstractPeer implements Endpoint, ChannelHandler {
/**
* 通道处理器
*/
private final ChannelHandler handler;
/**
* URL
*/
private volatile URL url;
/**
* 正在关闭
*
* {@link #startClose()}
*/
// closing closed means the process is being closed and close is finished
private volatile boolean closing;
/**
* 关闭完成
*
* {@link #close()}
*/
private volatile boolean closed;
public AbstractPeer(URL url, ChannelHandler handler) {
if (url == null) {
throw new IllegalArgumentException("url == null");
}
if (handler == null) {
throw new IllegalArgumentException("handler == null");
}
this.url = url;
this.handler = handler;
}
}
使用装饰模式
3.AbstractEndpoint
实现 Resetable 接口,继承 AbstractPeer 抽象类,端点抽象类。
/**
* AbstractEndpoint
*
* Endpoint 抽象类
*/
public abstract class AbstractEndpoint extends AbstractPeer implements Resetable {
private static final Logger logger = LoggerFactory.getLogger(AbstractEndpoint.class);
/**
* 编解码器
*/
private Codec2 codec;
/**
* 超时时间
*/
private int timeout;
/**
* 连接超时时间
*/
private int connectTimeout;
public AbstractEndpoint(URL url, ChannelHandler handler) {
super(url, handler);
this.codec = getChannelCodec(url);
this.timeout = url.getPositiveParameter(Constants.TIMEOUT_KEY, Constants.DEFAULT_TIMEOUT);
this.connectTimeout = url.getPositiveParameter(Constants.CONNECT_TIMEOUT_KEY, Constants.DEFAULT_CONNECT_TIMEOUT);
}
}
4.Client
4.1 AbstractClient
实现 Client 接口,继承 AbstractEndpoint 抽象类,客户端抽象类,重点实现了公用的重连逻辑,同时抽象了连接等模板方法,供子类实现。抽象方法如下:
/**
* 重连定时任务执行器
*/
private static final ScheduledThreadPoolExecutor reconnectExecutorService = new ScheduledThreadPoolExecutor(2, new NamedThreadFactory("DubboClientReconnectTimer", true));
/**
* 连接锁,用于实现发起连接和断开连接互斥,避免并发。
*/
private final Lock connectLock = new ReentrantLock();
/**
* 发送消息时,若断开,是否重连
*/
private final boolean send_reconnect;
/**
* 重连次数
*/
private final AtomicInteger reconnect_count = new AtomicInteger(0);
/**
* 重连时,是否已经打印过错误日志。
*/
// Reconnection error log has been called before?
private final AtomicBoolean reconnect_error_log_flag = new AtomicBoolean(false);
/**
* 重连 warning 的间隔.(waring多少次之后,warning一次) //for test
*/
// reconnect warning period. Reconnect warning interval (log warning after how many times) //for test
private final int reconnect_warning_period;
/**
* 关闭超时时间
*/
private final long shutdown_timeout;
/**
* 线程池
*
* 在调用 {@link #wrapChannelHandler(URL, ChannelHandler)} 时,会调用 {@link com.alibaba.dubbo.remoting.transport.dispatcher.WrappedChannelHandler} 创建
*/
protected volatile ExecutorService executor;
/**
* 重连执行任务 Future
*/
private volatile ScheduledFuture<?> reconnectExecutorFuture = null;
/**
* 最后成功连接时间
*/
// the last successed connected time
private long lastConnectedTime = System.currentTimeMillis();
public AbstractClient(URL url, ChannelHandler handler) throws RemotingException {
super(url, handler);
// 从 URL 中,获得重连相关配置项
send_reconnect = url.getParameter(Constants.SEND_RECONNECT_KEY, false);
shutdown_timeout = url.getParameter(Constants.SHUTDOWN_TIMEOUT_KEY, Constants.DEFAULT_SHUTDOWN_TIMEOUT);
// The default reconnection interval is 2s, 1800 means warning interval is 1 hour.
reconnect_warning_period = url.getParameter("reconnect.waring.period", 1800);
// 初始化客户端
try {
doOpen();
} catch (Throwable t) {
close(); // 失败,则关闭
throw new RemotingException(url.toInetSocketAddress(), null,
"Failed to start " + getClass().getSimpleName() + " " + NetUtils.getLocalAddress()
+ " connect to the server " + getRemoteAddress() + ", cause: " + t.getMessage(), t);
}
// 连接服务器
try {
// connect.
connect();
if (logger.isInfoEnabled()) {