if (ExtensionLoader.getExtensionLoader(ConfiguratorFactory.class)
.hasExtension(url.getProtocol())) {
// 加载 ConfiguratorFactory,并生成 Configurator 实例,然后通过实例配置 url
url = ExtensionLoader.getExtensionLoader(ConfiguratorFactory.class)
.getExtension(url.getProtocol()).getConfigurator(url).configure(url);
}
// 如果scope=none,则什么都不做
String scope = url.getParameter(SCOPE_KEY);
// don't export when none is configured
if (!SCOPE_NONE.equalsIgnoreCase(scope)) {
// export to local if the config is not remote (export to remote only when config is remote)
// scope != remote,导出到本地
if (!SCOPE_REMOTE.equalsIgnoreCase(scope)) {
exportLocal(url);
}
// export to remote if the config is not local (export to local only when config is local)
// scope != local,导出到远程
if (!SCOPE_LOCAL.equalsIgnoreCase(scope)) {
if (!isOnlyInJvm() && logger.isInfoEnabled()) {
logger.info("Export dubbo service " + interfaceClass.getName() + " to url " + url);
}
if (CollectionUtils.isNotEmpty(registryURLs)) {
for (URL registryURL : registryURLs) {
//if protocol is only injvm ,not register
if (LOCAL_PROTOCOL.equalsIgnoreCase(url.getProtocol())) {
continue;
}
url = url.addParameterIfAbsent(DYNAMIC_KEY, registryURL.getParameter(DYNAMIC_KEY));
// 加载监视器链接
URL monitorUrl = loadMonitor(registryURL);
if (monitorUrl != null) {
// 将监视器链接作为参数添加到 url 中
url = url.addParameterAndEncoded(MONITOR_KEY, monitorUrl.toFullString());
}
if (logger.isInfoEnabled()) {
logger.info("Register dubbo service " + interfaceClass.getName() + " url " + url + " to registry " + registryURL);
}
// For providers, this is used to enable custom proxy to generate invoker
String proxy = url.getParameter(PROXY_KEY);
if (StringUtils.isNotEmpty(proxy)) {
registryURL = registryURL.addParameter(PROXY_KEY, proxy);
}
// 为服务提供者生成invoker
Invoker<?> invoker = PROXY_FACTORY.getInvoker(ref, (Class) interfaceClass, registryURL.addParameterAndEncoded(EXPORT_KEY, url.toFullString()));
// DelegateProviderMetaDataInvoker 用于持有 Invoker 和 ServiceConfig
DelegateProviderMetaDataInvoker wrapperInvoker = new DelegateProviderMetaDataInvoker(invoker, this);
// 导出服务,并生成 Exporter
Exporter<?> exporter = protocol.export(wrapperInvoker);
exporters.add(exporter);
}
// 不存在注册中心,仅导出服务
} else {
Invoker<?> invoker = PROXY_FACTORY.getInvoker(ref, (Class) interfaceClass, url);
DelegateProviderMetaDataInvoker wrapperInvoker = new DelegateProviderMetaDataInvoker(invoker, this);
Exporter<?> exporter = protocol.export(wrapperInvoker);
exporters.add(exporter);
}
/**
* @since 2.7.0
* ServiceData Store
*/
MetadataReportService metadataReportService = null;
if ((metadataReportService = getMetadataReportService()) != null) {
metadataReportService.publishProvider(url);
}
}
}
this.urls.add(url);
}
`
public <T> Exporter<T> export(final Invoker<T> originInvoker) throws RpcException {
/* originInvoker :DelegateProviderMetaDataInvoker类型 */
/* 获取注册中心URL */
URL registryUrl = getRegistryUrl(originInvoker);
// url to export locally
/* 获取服务提供者URL */
URL providerUrl = getProviderUrl(originInvoker);
// Subscribe the override data
/* 获取订阅URL */
final URL overrideSubscribeUrl = getSubscribedOverrideUrl(providerUrl);
/* 创建监听器 */
final OverrideListener overrideSubscribeListener = new OverrideListener(overrideSubscribeUrl, originInvoker);
overrideListeners.put(overrideSubscribeUrl, overrideSubscribeListener);
providerUrl = overrideUrlWithConfig(providerUrl, overrideSubscribeListener);
//export invoker
final ExporterChangeableWrapper<T> exporter = doLocalExport(originInvoker, providerUrl);
/* 获取注册中心实现类,即ZooKeeperRegistry */
final Registry registry = getRegistry(originInvoker);
// 获取已注册的服务提供者 URL
final URL registeredProviderUrl = getRegisteredProviderUrl(providerUrl, registryUrl);
/* 向服务提供者与消费者注册表中注册服务提供者 */
ProviderInvokerWrapper<T> providerInvokerWrapper = ProviderConsumerRegTable.registerProvider(originInvoker,
registryUrl, registeredProviderUrl);
/* 根据 register 的值决定是否注册服务 */
boolean register = registeredProviderUrl.getParameter("register", true);
if (register) {
/* 向注册中心注册服务 */
register(registryUrl, registeredProviderUrl);
providerInvokerWrapper.setReg(true);
}
// Deprecated! Subscribe to override rules in 2.6.x or before.
/* 向注册中心进行订阅 override 数据 */
registry.subscribe(overrideSubscribeUrl, overrideSubscribeListener);
exporter.setRegisterUrl(registeredProviderUrl);
exporter.setSubscribeUrl(overrideSubscribeUrl);
// Ensure that a new exporter instance is returned every time export
return new DestroyableExporter<>(exporter);
}
ConcurrentMap>
`
@Override
public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
URL url = invoker.getUrl();
String key = serviceKey(url);
DubboExporter<T> exporter = new DubboExporter<T>(invoker, key, exporterMap);
exporterMap.put(key, exporter);
/* 本地存根相关代码 */
//export an stub service for dispatching event
/* STUB_EVENT_KEY = "dubbo.stub.event" */
/* DEFAULT_STUB_EVENT = false */
Boolean isStubSupportEvent = url.getParameter(STUB_EVENT_KEY, DEFAULT_STUB_EVENT);
/* IS_CALLBACK_SERVICE = "is_callback_service" */
Boolean isCallbackservice = url.getParameter(IS_CALLBACK_SERVICE, false);
if (isStubSupportEvent && !isCallbackservice) {
/* STUB_EVENT_METHODS_KEY = "dubbo.stub.event.methods" */
String stubServiceMethods = url.getParameter(STUB_EVENT_METHODS_KEY);
if (stubServiceMethods == null || stubServiceMethods.length() == 0) {
if (logger.isWarnEnabled()) {
logger.warn("..."));
}
} else {
stubServiceMethodsMap.put(url.getServiceKey(), stubServiceMethods);
}
}
/* 创建NettyServer,如果没有创建的话 */
openServer(url);
optimizeSerialization(url);
return exporter;
}
`
`
private ExchangeServer createServer(URL url) {
url = URLBuilder.from(url)
// send readonly event when server closes, it's enabled by default
.addParameterIfAbsent("channel.readonly.sent", Boolean.TRUE.toString())
// enable heartbeat by default
.addParameterIfAbsent("heartbeat", String.valueOf(60 * 1000))
.addParameter("codec", "dubbo")
.build();
String str = url.getParameter("server", "netty");
if (str != null && str.length() > 0 && !ExtensionLoader
.getExtensionLoader(Transporter.class).hasExtension(str)) {
throw new RpcException("Unsupported server type: " + str + ", url: " + url);
}
ExchangeServer server = Exchangers.bind(url, requestHandler);
str = url.getParameter("client");
if (str != null && str.length() > 0) {
Set<String> supportedTypes = ExtensionLoader.getExtensionLoader(Transporter.class)
.getSupportedExtensions();
if (!supportedTypes.contains(str)) {
throw new RpcException("Unsupported client type: " + str);
}
}
return server;
}
`
`
@Override
public ExchangeServer bind(URL url, ExchangeHandler handler) throws RemotingException {
return new HeaderExchangeServer(Transporters.bind(url, new DecodeHandler(new HeaderExchangeHandler(handler))));
}
`
默认是NettyTransporter。
`
这里采用org.apache.dubbo.remoting.transport.netty4
的NettyServer。
@Override
protected void doOpen() throws Throwable {
bootstrap = new ServerBootstrap();
bossGroup = new NioEventLoopGroup(1, new DefaultThreadFactory("NettyServerBoss", true));
/* IO_THREADS_KEY:iothreads */
/* 根据配置文件中的dubbo.provider.iothreads设置的值决定 */
/* 如果配置文件没有设置,线程数默认取 (Runtime.getRuntime().availableProcessors() + 1) 和 32 的最小值 */
workerGroup = new NioEventLoopGroup(getUrl().getPositiveParameter(IO_THREADS_KEY, Constants.DEFAULT_IO_THREADS),
new DefaultThreadFactory("NettyServerWorker", true));
/* NettyServerHandler:ChannelInboundHandler与ChannelOutboundHandler的组合体 */
/* 服务提供者与服务消费者进行远程交互的核心处理器 */
final NettyServerHandler nettyServerHandler = new NettyServerHandler(getUrl(), this);
/* channels:Map 也就是 */
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 {
/* heartbeat.timeout */
int idleTimeout = UrlUtils.getIdleTimeout(getUrl());
/* codec:Codec接口类型,由dubbo.provider.codec 或者 dubbo.protocol.codec 指定Codec实现类的全限定名 */
NettyCodecAdapter adapter = new NettyCodecAdapter(codec, url, 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(bindAddress);
channelFuture.syncUninterruptibly();
/* the boss channel that receive connections and dispatch these to worker channel. */
channel = channelFuture.channel();
}
然后看下它的handlerAdded(…)方法,也就是当ChannelHandler添加到ChannelHandlerContext中触发的逻辑,如下:
initialize(…)方法,根据readerIdleTimeNanos、writerIdleTimeNanos、allIdleTimeNanos参数,如果有大于0,则延迟调度对应的ReaderIdleTimeoutTask、WriterIdleTimeoutTask、AllIdleTimeoutTask。实际上是触发ChannelInboundHandler#userEventTriggered(…)方法。