use of com.alibaba.dubbo.rpc.Exporter in project dubbo by alibaba.
the class RegistryProtocol method export.
public <T> Exporter<T> export(final Invoker<T> originInvoker) throws RpcException {
//export invoker
final ExporterChangeableWrapper<T> exporter = doLocalExport(originInvoker);
//registry provider
final Registry registry = getRegistry(originInvoker);
final URL registedProviderUrl = getRegistedProviderUrl(originInvoker);
registry.register(registedProviderUrl);
// 订阅override数据
// FIXME 提供者订阅时,会影响同一JVM即暴露服务,又引用同一服务的的场景,因为subscribed以服务名为缓存的key,导致订阅信息覆盖。
final URL overrideSubscribeUrl = getSubscribedOverrideUrl(registedProviderUrl);
final OverrideListener overrideSubscribeListener = new OverrideListener(overrideSubscribeUrl);
overrideListeners.put(overrideSubscribeUrl, overrideSubscribeListener);
registry.subscribe(overrideSubscribeUrl, overrideSubscribeListener);
//保证每次export都返回一个新的exporter实例
return new Exporter<T>() {
public Invoker<T> getInvoker() {
return exporter.getInvoker();
}
public void unexport() {
try {
exporter.unexport();
} catch (Throwable t) {
logger.warn(t.getMessage(), t);
}
try {
registry.unregister(registedProviderUrl);
} catch (Throwable t) {
logger.warn(t.getMessage(), t);
}
try {
overrideListeners.remove(overrideSubscribeUrl);
registry.unsubscribe(overrideSubscribeUrl, overrideSubscribeListener);
} catch (Throwable t) {
logger.warn(t.getMessage(), t);
}
}
};
}
use of com.alibaba.dubbo.rpc.Exporter in project dubbo by alibaba.
the class CallbackServiceCodec method exportOrunexportCallbackService.
/**
* client 端export callback service
* @param channel
* @param clazz
* @param inst
* @param export
* @param out
* @throws IOException
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
private static String exportOrunexportCallbackService(Channel channel, URL url, Class clazz, Object inst, Boolean export) throws IOException {
int instid = System.identityHashCode(inst);
Map<String, String> params = new HashMap<String, String>(3);
//不需要在重新new client
params.put(Constants.IS_SERVER_KEY, Boolean.FALSE.toString());
//标识callback 变于排查问题
params.put(Constants.IS_CALLBACK_SERVICE, Boolean.TRUE.toString());
String group = url.getParameter(Constants.GROUP_KEY);
if (group != null && group.length() > 0) {
params.put(Constants.GROUP_KEY, group);
}
//增加方法,变于方法检查,自动降级(见dubbo protocol)
params.put(Constants.METHODS_KEY, StringUtils.join(Wrapper.getWrapper(clazz).getDeclaredMethodNames(), ","));
Map<String, String> tmpmap = new HashMap<String, String>(url.getParameters());
tmpmap.putAll(params);
//callback不需要区分version
tmpmap.remove(Constants.VERSION_KEY);
tmpmap.put(Constants.INTERFACE_KEY, clazz.getName());
URL exporturl = new URL(DubboProtocol.NAME, channel.getLocalAddress().getAddress().getHostAddress(), channel.getLocalAddress().getPort(), clazz.getName() + "." + instid, tmpmap);
//同一个jvm不需要对不同的channel产生多个exporter cache key不会碰撞
String cacheKey = getClientSideCallbackServiceCacheKey(instid);
String countkey = getClientSideCountKey(clazz.getName());
if (export) {
//同一个channel 可以有多个callback instance. 不同的instance不重新export
if (!channel.hasAttribute(cacheKey)) {
if (!isInstancesOverLimit(channel, url, clazz.getName(), instid, false)) {
Invoker<?> invoker = proxyFactory.getInvoker(inst, clazz, exporturl);
//资源销毁?
Exporter<?> exporter = protocol.export(invoker);
//这个用来记录instid是否发布过服务
channel.setAttribute(cacheKey, exporter);
logger.info("export a callback service :" + exporturl + ", on " + channel + ", url is: " + url);
increaseInstanceCount(channel, countkey);
}
}
} else {
if (channel.hasAttribute(cacheKey)) {
Exporter<?> exporter = (Exporter<?>) channel.getAttribute(cacheKey);
exporter.unexport();
channel.removeAttribute(cacheKey);
decreaseInstanceCount(channel, countkey);
}
}
return String.valueOf(instid);
}