Support multi registries metrics key (#12582)

* init

* fix

* fix

* fix

* fix

* add licence

* fix testcase

* fix testcase

* lowcase

* remove unuse

* opt notify&directory

* fix post&finish

* revert name

* move registerMetadataAndInstance

* move metrics from

* remove some unuse

* remove unuse

* fix style

* fix style

* remove unuse

* remove unuse

* fix default&& move post

* add multi registry lables for subscribe

* fix

* fix url

* fix url

* Fix uts

* add registry key for directory

* Compatible with empty registry keys

* remove unus

* Support registry type

* Fix attachment

* Code enhancement

* Fix registry key

* Fix service discovery notify

* fix

---------

Co-authored-by: songxiaosheng <songxiaosheng@elastic.link>
Co-authored-by: Albumen Kevin <jhq0812@gmail.com>
This commit is contained in:
wxbty 2023-07-31 13:44:46 +08:00 committed by GitHub
parent 10870708eb
commit 0add70e3f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 593 additions and 214 deletions

View File

@ -352,7 +352,7 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
}
}, reconnectTaskPeriod, TimeUnit.MILLISECONDS);
}
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary()));
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta()));
}
/**
@ -366,7 +366,11 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
if (invokersInitialized) {
refreshInvokerInternal();
}
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary()));
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta()));
}
protected Map<String, String> getDirectoryMeta() {
return Collections.emptyMap();
}
private synchronized void refreshInvokerInternal() {
@ -395,7 +399,7 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
removeValidInvoker(invoker);
logger.info("Disable service address: " + invoker.getUrl() + ".");
}
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary()));
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta()));
}
@Override
@ -408,7 +412,7 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
}
}
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary()));
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta()));
}
protected final void refreshRouter(BitList<Invoker<T>> newlyInvokers, Runnable switchAction) {
@ -465,7 +469,7 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
refreshInvokerInternal();
this.invokersInitialized = true;
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary()));
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta()));
}
protected void destroyInvokers() {
@ -480,7 +484,7 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
synchronized (this.validInvokers) {
result = this.validInvokers.add(invoker);
}
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary()));
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta()));
return result;
}
@ -489,7 +493,7 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
synchronized (this.validInvokers) {
result = this.validInvokers.remove(invoker);
}
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary()));
MetricsEventBus.publish(RegistryEvent.refreshDirectoryEvent(applicationModel, getSummary(), getDirectoryMeta()));
return result;
}
@ -519,18 +523,7 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
}
private Map<String, Integer> groupByServiceKey(Collection<Invoker<T>> invokers) {
Map<String, Integer> serviceNumMap = new HashMap<>();
for (Invoker<T> invoker : invokers) {
if (invoker.getClass().getSimpleName().contains("Mockito")) {
return serviceNumMap;
}
}
if (invokers.size() > 0) {
serviceNumMap = invokers.stream().filter(invoker -> invoker.getInterface() != null).collect(Collectors.groupingBy(invoker -> invoker.getInterface().getName(), Collectors.reducing(0, e -> 1, Integer::sum)));
}
return serviceNumMap;
return Collections.singletonMap(getConsumerUrl().getServiceKey(), invokers.size());
}
@Override

View File

@ -27,9 +27,12 @@ import org.apache.dubbo.rpc.cluster.RouterChain;
import org.apache.dubbo.rpc.cluster.SingleRouterChain;
import org.apache.dubbo.rpc.cluster.router.state.BitList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import static org.apache.dubbo.common.constants.LoggerCodeConstants.CLUSTER_FAILED_SITE_SELECTION;
import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_KEY;
/**
* StaticDirectory
@ -125,4 +128,8 @@ public class StaticDirectory<T> extends AbstractDirectory<T> {
return invokers;
}
@Override
protected Map<String, String> getDirectoryMeta() {
return Collections.singletonMap(REGISTRY_KEY, "static");
}
}

View File

@ -241,6 +241,8 @@ public interface CommonConstants {
String INTERFACE_REGISTER_MODE = "interface";
String INSTANCE_REGISTER_MODE = "instance";
String DEFAULT_REGISTER_MODE = "all";
String GENERIC_KEY = "generic";

View File

@ -38,8 +38,6 @@ import org.apache.dubbo.config.invoker.DelegateProviderMetaDataInvoker;
import org.apache.dubbo.config.support.Parameter;
import org.apache.dubbo.config.utils.ConfigValidationUtils;
import org.apache.dubbo.metadata.ServiceNameMapping;
import org.apache.dubbo.metrics.event.MetricsEventBus;
import org.apache.dubbo.metrics.registry.event.RegistryEvent;
import org.apache.dubbo.registry.client.metadata.MetadataUtils;
import org.apache.dubbo.rpc.Exporter;
import org.apache.dubbo.rpc.Invoker;
@ -516,21 +514,17 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
List<URL> registryURLs = ConfigValidationUtils.loadRegistries(this, true);
MetricsEventBus.post(RegistryEvent.toRsEvent(getApplicationModel(), getUniqueServiceName(), protocols.size() * registryURLs.size()), () -> {
for (ProtocolConfig protocolConfig : protocols) {
String pathKey = URL.buildKey(getContextPath(protocolConfig)
.map(p -> p + "/" + path)
.orElse(path), group, version);
// stub service will use generated service name
if (!serverService) {
// In case user specified path, registerImmediately service one more time to map it to path.
repository.registerService(pathKey, interfaceClass);
}
doExportUrlsFor1Protocol(protocolConfig, registryURLs, registerType);
}
return null;
for (ProtocolConfig protocolConfig : protocols) {
String pathKey = URL.buildKey(getContextPath(protocolConfig)
.map(p -> p + "/" + path)
.orElse(path), group, version);
// stub service will use generated service name
if (!serverService) {
// In case user specified path, register service one more time to map it to path.
repository.registerService(pathKey, interfaceClass);
}
);
doExportUrlsFor1Protocol(protocolConfig, registryURLs, registerType);
}
providerModel.setServiceUrls(urls);
}

View File

@ -55,7 +55,6 @@ import org.apache.dubbo.metadata.report.MetadataReportInstance;
import org.apache.dubbo.metrics.collector.DefaultMetricsCollector;
import org.apache.dubbo.metrics.config.event.ConfigCenterEvent;
import org.apache.dubbo.metrics.event.MetricsEventBus;
import org.apache.dubbo.metrics.registry.event.RegistryEvent;
import org.apache.dubbo.metrics.report.DefaultMetricsReporterFactory;
import org.apache.dubbo.metrics.report.MetricsReporter;
import org.apache.dubbo.metrics.report.MetricsReporterFactory;
@ -899,16 +898,10 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
private void registerServiceInstance() {
try {
registered = true;
MetricsEventBus.post(RegistryEvent.toRegisterEvent(applicationModel),
() -> {
ServiceInstanceMetadataUtils.registerMetadataAndInstance(applicationModel);
return null;
}
);
ServiceInstanceMetadataUtils.registerMetadataAndInstance(applicationModel);
} catch (Exception e) {
logger.error(CONFIG_REGISTER_INSTANCE_ERROR, "configuration server disconnected", "", "Register instance error.", e);
}
if (registered) {
// scheduled task for updating Metadata and ServiceInstance
asyncMetadataFuture = frameworkExecutorRepository.getSharedScheduledExecutor().scheduleWithFixedDelay(() -> {

View File

@ -34,7 +34,7 @@ import static org.apache.dubbo.metrics.MetricsConstants.SELF_INCREMENT_SIZE;
public abstract class CombMetricsCollector<E extends TimeCounterEvent> extends AbstractMetricsListener<E> implements ApplicationMetricsCollector<E>, ServiceMetricsCollector<E>, MethodMetricsCollector<E> {
private final BaseStatComposite stats;
protected final BaseStatComposite stats;
private MetricsEventMulticaster eventMulticaster;
@ -108,5 +108,9 @@ public abstract class CombMetricsCollector<E extends TimeCounterEvent> extends A
public void onEventError(TimeCounterEvent event) {
eventMulticaster.publishErrorEvent(event);
}
protected BaseStatComposite getStats() {
return stats;
}
}

View File

@ -18,8 +18,10 @@
package org.apache.dubbo.metrics.data;
import org.apache.dubbo.metrics.collector.MetricsCollector;
import org.apache.dubbo.metrics.model.ApplicationMetric;
import org.apache.dubbo.metrics.model.MethodMetric;
import org.apache.dubbo.metrics.model.MetricsCategory;
import org.apache.dubbo.metrics.model.ServiceKeyMetric;
import org.apache.dubbo.metrics.model.key.MetricsKey;
import org.apache.dubbo.metrics.model.key.MetricsKeyWrapper;
import org.apache.dubbo.metrics.model.sample.MetricSample;
@ -29,6 +31,7 @@ import org.apache.dubbo.rpc.model.ApplicationModel;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
@ -70,11 +73,11 @@ public abstract class BaseStatComposite implements MetricsExport {
}
public void calcApplicationRt(String registryOpType, Long responseTime) {
rtStatComposite.calcApplicationRt(registryOpType, responseTime);
rtStatComposite.calcServiceKeyRt(registryOpType, responseTime, new ApplicationMetric(rtStatComposite.getApplicationModel()));
}
public void calcServiceKeyRt(String serviceKey, String registryOpType, Long responseTime) {
rtStatComposite.calcServiceKeyRt(serviceKey, registryOpType, responseTime);
rtStatComposite.calcServiceKeyRt(registryOpType, responseTime, new ServiceKeyMetric(rtStatComposite.getApplicationModel(), serviceKey));
}
public void calcServiceKeyRt(Invocation invocation, String registryOpType, Long responseTime) {
@ -89,6 +92,10 @@ public abstract class BaseStatComposite implements MetricsExport {
serviceStatComposite.setServiceKey(metricsKey, serviceKey, num);
}
public void setServiceKey(MetricsKeyWrapper metricsKey, String serviceKey, int num, Map<String, String> extra) {
serviceStatComposite.setExtraServiceKey(metricsKey, serviceKey, num, extra);
}
public void incrementApp(MetricsKey metricsKey, int size) {
applicationStatComposite.incrementSize(metricsKey, size);
}
@ -97,6 +104,10 @@ public abstract class BaseStatComposite implements MetricsExport {
serviceStatComposite.incrementServiceKey(metricsKeyWrapper, attServiceKey, size);
}
public void incrementServiceKey(MetricsKeyWrapper metricsKeyWrapper, String attServiceKey, Map<String, String> extra, int size) {
serviceStatComposite.incrementExtraServiceKey(metricsKeyWrapper, attServiceKey, extra, size);
}
public void incrementMethodKey(MetricsKeyWrapper metricsKeyWrapper, MethodMetric methodMetric, int size) {
methodStatComposite.incrementMethodKey(metricsKeyWrapper, methodMetric, size);
}

View File

@ -17,7 +17,6 @@
package org.apache.dubbo.metrics.data;
import org.apache.dubbo.metrics.model.ApplicationMetric;
import org.apache.dubbo.metrics.model.MethodMetric;
import org.apache.dubbo.metrics.model.Metric;
import org.apache.dubbo.metrics.model.MetricsCategory;
@ -89,20 +88,7 @@ public class RtStatComposite extends AbstractMetricsExport {
return singleRtStats;
}
public void calcApplicationRt(String registryOpType, Long responseTime) {
ApplicationMetric key = new ApplicationMetric(getApplicationModel());
for (LongContainer container : rtStats.get(registryOpType)) {
Number current = (Number) container.get(key);
if (current == null) {
container.putIfAbsent(key, container.getInitFunc().apply(key));
current = (Number) container.get(key);
}
container.getConsumerFunc().accept(responseTime, current);
}
}
public void calcServiceKeyRt(String serviceKey, String registryOpType, Long responseTime) {
ServiceKeyMetric key = new ServiceKeyMetric(getApplicationModel(), serviceKey);
public void calcServiceKeyRt(String registryOpType, Long responseTime, Metric key) {
for (LongContainer container : rtStats.get(registryOpType)) {
Number current = (Number) container.get(key);
if (current == null) {

View File

@ -53,21 +53,37 @@ public class ServiceStatComposite extends AbstractMetricsExport {
}
public void incrementServiceKey(MetricsKeyWrapper wrapper, String serviceKey, int size) {
incrementExtraServiceKey(wrapper, serviceKey, null, size);
}
public void incrementExtraServiceKey(MetricsKeyWrapper wrapper, String serviceKey, Map<String, String> extra, int size) {
if (!serviceWrapperNumStats.containsKey(wrapper)) {
return;
}
serviceWrapperNumStats.get(wrapper).computeIfAbsent(new ServiceKeyMetric(getApplicationModel(), serviceKey), k -> new AtomicLong(0L)).getAndAdd(size);
ServiceKeyMetric serviceKeyMetric = new ServiceKeyMetric(getApplicationModel(), serviceKey);
if (extra != null) {
serviceKeyMetric.setExtraInfo(extra);
}
serviceWrapperNumStats.get(wrapper).computeIfAbsent(serviceKeyMetric, k -> new AtomicLong(0L)).getAndAdd(size);
// MetricsSupport.fillZero(serviceWrapperNumStats);
}
public void setServiceKey(MetricsKeyWrapper wrapper, String serviceKey, int num) {
setExtraServiceKey(wrapper, serviceKey, num, null);
}
public void setExtraServiceKey(MetricsKeyWrapper wrapper, String serviceKey, int num, Map<String, String> extra) {
if (!serviceWrapperNumStats.containsKey(wrapper)) {
return;
}
serviceWrapperNumStats.get(wrapper).computeIfAbsent(new ServiceKeyMetric(getApplicationModel(), serviceKey), k -> new AtomicLong(0L)).set(num);
// MetricsSupport.fillZero(serviceWrapperNumStats);
ServiceKeyMetric serviceKeyMetric = new ServiceKeyMetric(getApplicationModel(), serviceKey);
if (extra != null) {
serviceKeyMetric.setExtraInfo(extra);
}
serviceWrapperNumStats.get(wrapper).computeIfAbsent(serviceKeyMetric, k -> new AtomicLong(0L)).set(num);
}
@Override
public List<MetricSample> export(MetricsCategory category) {
List<MetricSample> list = new ArrayList<>();
for (MetricsKeyWrapper wrapper : serviceWrapperNumStats.keySet()) {

View File

@ -23,6 +23,7 @@ import org.apache.dubbo.metrics.model.MethodMetric;
import org.apache.dubbo.metrics.model.key.TypeWrapper;
import org.apache.dubbo.rpc.model.ApplicationModel;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.Map;
@ -40,7 +41,7 @@ public abstract class MetricsEvent {
private final String appName;
private final MetricsDispatcher metricsDispatcher;
private final Map<String, Object> attachment = new IdentityHashMap<>(8);
private final Map<String, Object> attachments = new IdentityHashMap<>(8);
public MetricsEvent(ApplicationModel source, TypeWrapper typeWrapper) {
this(source, null, null, typeWrapper);
@ -82,11 +83,19 @@ public abstract class MetricsEvent {
if (key == null) {
throw new MetricsNeverHappenException("Attachment key is null");
}
return (T) attachment.get(key);
return (T) attachments.get(key);
}
public Map<String, Object> getAttachments() {
return Collections.unmodifiableMap(attachments);
}
public void putAttachment(String key, Object value) {
attachment.put(key, value);
attachments.put(key, value);
}
public void putAttachments(Map<String, String> attachments) {
this.attachments.putAll(attachments);
}
public void setAvailable(boolean available) {

View File

@ -27,6 +27,7 @@ import java.util.function.Consumer;
/**
* According to the event template of {@link MetricsEventBus},
* build a consistent static method for general and custom monitoring consume methods
*
*/
public abstract class AbstractMetricsKeyListener extends AbstractMetricsListener<TimeCounterEvent> implements MetricsLifeListener<TimeCounterEvent> {

View File

@ -28,7 +28,7 @@ public abstract class AbstractMetricsListener<E extends MetricsEvent> implements
private final Map<Integer, Boolean> eventMatchCache = new ConcurrentHashMap<>();
/**
* Whether to support the general determination of event points depends on the event type
* Only interested in events of the current listener's generic parameter type
*/
public boolean isSupport(MetricsEvent event) {
Boolean eventMatch = eventMatchCache.get(System.identityHashCode(event.getClass()));

View File

@ -21,19 +21,37 @@ import org.apache.dubbo.metrics.collector.CombMetricsCollector;
import org.apache.dubbo.metrics.model.key.MetricsKey;
import org.apache.dubbo.metrics.model.key.MetricsPlaceValue;
/**
* App-level listener type, in most cases, can use the static method
* to produce an anonymous listener for general monitoring
*/
public class MetricsApplicationListener extends AbstractMetricsKeyListener {
public MetricsApplicationListener(MetricsKey metricsKey) {
super(metricsKey);
}
public static AbstractMetricsKeyListener onPostEventBuild(MetricsKey metricsKey, CombMetricsCollector collector) {
/**
* Perform auto-increment on the monitored key,
* Can use a custom listener instead of this generic operation
*
* @param metricsKey Monitor key
* @param collector Corresponding collector
*/
public static AbstractMetricsKeyListener onPostEventBuild(MetricsKey metricsKey, CombMetricsCollector<?> collector) {
return AbstractMetricsKeyListener.onEvent(metricsKey,
event -> collector.increment(metricsKey)
event -> collector.increment(metricsKey)
);
}
public static AbstractMetricsKeyListener onFinishEventBuild(MetricsKey metricsKey, MetricsPlaceValue placeType, CombMetricsCollector collector) {
/**
* To end the monitoring normally, in addition to increasing the number of corresponding indicators,
* use the introspection method to calculate the relevant rt indicators
*
* @param metricsKey Monitor key
* @param collector Corresponding collector
*/
public static AbstractMetricsKeyListener onFinishEventBuild(MetricsKey metricsKey, MetricsPlaceValue placeType, CombMetricsCollector<?> collector) {
return AbstractMetricsKeyListener.onFinish(metricsKey,
event -> {
collector.increment(metricsKey);
@ -42,7 +60,10 @@ public class MetricsApplicationListener extends AbstractMetricsKeyListener {
);
}
public static AbstractMetricsKeyListener onErrorEventBuild(MetricsKey metricsKey, MetricsPlaceValue placeType, CombMetricsCollector collector) {
/**
* Similar to onFinishEventBuild
*/
public static AbstractMetricsKeyListener onErrorEventBuild(MetricsKey metricsKey, MetricsPlaceValue placeType, CombMetricsCollector<?> collector) {
return AbstractMetricsKeyListener.onError(metricsKey,
event -> {
collector.increment(metricsKey);

View File

@ -23,6 +23,11 @@ import org.apache.dubbo.metrics.model.MetricsSupport;
import org.apache.dubbo.metrics.model.key.MetricsKey;
import org.apache.dubbo.metrics.model.key.MetricsPlaceValue;
/**
* Service-level listener type, in most cases, can use the static method
* to produce an anonymous listener for general monitoring.
* Similar to App-level
*/
public class MetricsServiceListener extends AbstractMetricsKeyListener {
public MetricsServiceListener(MetricsKey metricsKey) {

View File

@ -17,25 +17,14 @@
package org.apache.dubbo.metrics.model;
import org.apache.dubbo.common.Version;
import org.apache.dubbo.metrics.model.key.MetricsKey;
import org.apache.dubbo.rpc.model.ApplicationModel;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import static org.apache.dubbo.common.constants.MetricsConstants.TAG_APPLICATION_NAME;
import static org.apache.dubbo.common.constants.MetricsConstants.TAG_APPLICATION_VERSION_KEY;
import static org.apache.dubbo.common.constants.MetricsConstants.TAG_HOSTNAME;
import static org.apache.dubbo.common.constants.MetricsConstants.TAG_IP;
import static org.apache.dubbo.common.utils.NetUtils.getLocalHost;
import static org.apache.dubbo.common.utils.NetUtils.getLocalHostName;
public class ApplicationMetric implements Metric {
private final ApplicationModel applicationModel;
private static final String version = Version.getVersion();
private static final String commitId = Version.getLastCommitId();
protected Map<String, String> extraInfo;
public ApplicationMetric(ApplicationModel applicationModel) {
this.applicationModel = applicationModel;
@ -49,27 +38,29 @@ public class ApplicationMetric implements Metric {
return getApplicationModel().getApplicationName();
}
public String getData() {
return version;
}
@Override
public Map<String, String> getTags() {
Map<String, String> tags = new HashMap<>();
tags.put(TAG_IP, getLocalHost());
tags.put(TAG_HOSTNAME, getLocalHostName());
tags.put(TAG_APPLICATION_NAME, getApplicationName());
tags.put(TAG_APPLICATION_VERSION_KEY, version);
tags.put(MetricsKey.METADATA_GIT_COMMITID_METRIC.getName(), commitId);
return tags;
return MetricsSupport.applicationTags(applicationModel, getExtraInfo());
}
public Map<String, String> getExtraInfo() {
return extraInfo;
}
public void setExtraInfo(Map<String, String> extraInfo) {
this.extraInfo = extraInfo;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof ApplicationMetric)) return false;
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
ApplicationMetric that = (ApplicationMetric) o;
return Objects.equals(getApplicationName(), that.applicationModel.getApplicationName());
return getApplicationName().equals(that.applicationModel.getApplicationName()) && Objects.equals(extraInfo, that.extraInfo);
}
private volatile int hashCode;
@ -77,8 +68,9 @@ public class ApplicationMetric implements Metric {
@Override
public int hashCode() {
if (hashCode == 0) {
hashCode = Objects.hash(getApplicationName());
hashCode = Objects.hash(getApplicationName(), extraInfo);
}
return hashCode;
}
}

View File

@ -18,12 +18,12 @@
package org.apache.dubbo.metrics.model;
import org.apache.dubbo.common.Version;
import org.apache.dubbo.common.lang.Nullable;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.metrics.collector.MethodMetricsCollector;
import org.apache.dubbo.metrics.collector.ServiceMetricsCollector;
import org.apache.dubbo.metrics.event.MetricsEvent;
import org.apache.dubbo.metrics.event.TimeCounterEvent;
import org.apache.dubbo.metrics.exception.MetricsNeverHappenException;
import org.apache.dubbo.metrics.model.key.MetricsKey;
import org.apache.dubbo.metrics.model.key.MetricsKeyWrapper;
import org.apache.dubbo.metrics.model.key.MetricsPlaceValue;
@ -62,6 +62,10 @@ public class MetricsSupport {
private static final String commitId = Version.getLastCommitId();
public static Map<String, String> applicationTags(ApplicationModel applicationModel) {
return applicationTags(applicationModel, null);
}
public static Map<String, String> applicationTags(ApplicationModel applicationModel, @Nullable Map<String, String> extraInfo) {
Map<String, String> tags = new HashMap<>();
tags.put(TAG_IP, getLocalHost());
tags.put(TAG_HOSTNAME, getLocalHostName());
@ -69,23 +73,18 @@ public class MetricsSupport {
tags.put(TAG_APPLICATION_MODULE, applicationModel.getInternalId());
tags.put(TAG_APPLICATION_VERSION_KEY, version);
tags.put(MetricsKey.METADATA_GIT_COMMITID_METRIC.getName(), commitId);
if (CollectionUtils.isNotEmptyMap(extraInfo)) {
tags.putAll(extraInfo);
}
return tags;
}
public static Map<String, String> serviceTags(ApplicationModel applicationModel, String serviceKey) {
Map<String, String> tags = applicationTags(applicationModel);
public static Map<String, String> serviceTags(ApplicationModel applicationModel, String serviceKey, Map<String, String> extraInfo) {
Map<String, String> tags = applicationTags(applicationModel, extraInfo);
tags.put(TAG_INTERFACE_KEY, serviceKey);
return tags;
}
public static Map<String, String> methodTags(ApplicationModel applicationModel, String names) {
String[] keys = names.split("_");
if (keys.length != 2) {
throw new MetricsNeverHappenException("Error names: " + names);
}
return methodTags(applicationModel, keys[0], keys[1]);
}
public static Map<String, String> methodTags(ApplicationModel applicationModel, String serviceKey, String methodName) {
Map<String, String> tags = applicationTags(applicationModel);
tags.put(TAG_INTERFACE_KEY, serviceKey);
@ -211,7 +210,6 @@ public class MetricsSupport {
Invocation invocation = event.getAttachmentValue(INVOCATION);
if (invocation != null) {
collector.addServiceRt(invocation, placeType.getType(), event.getTimePair().calc());
return;
} else {
collector.addServiceRt((String) event.getAttachmentValue(ATTACHMENT_KEY_SERVICE), placeType.getType(), event.getTimePair().calc());
}
@ -240,9 +238,9 @@ public class MetricsSupport {
}
/**
* Generate a complete indicator item for an interface/method
* Generate a complete indicator item for an interface/method
*/
public static <T> void fillZero(Map<MetricsKeyWrapper, Map<T, AtomicLong>> data) {
public static <T> void fillZero(Map<?, Map<T, AtomicLong>> data) {
if (CollectionUtils.isEmptyMap(data)) {
return;
}

View File

@ -35,7 +35,7 @@ public class ServiceKeyMetric extends ApplicationMetric {
@Override
public Map<String, String> getTags() {
return MetricsSupport.serviceTags(getApplicationModel(), serviceKey);
return MetricsSupport.serviceTags(getApplicationModel(), serviceKey, getExtraInfo());
}
public String getServiceKey() {
@ -47,16 +47,11 @@ public class ServiceKeyMetric extends ApplicationMetric {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
if (!(o instanceof ServiceKeyMetric)) {
return false;
}
ServiceKeyMetric that = (ServiceKeyMetric) o;
if (!getApplicationName().equals(that.getApplicationName())) {
return false;
}
return serviceKey.equals(that.serviceKey);
return serviceKey.equals(that.serviceKey) && Objects.equals(extraInfo, that.extraInfo);
}
@ -65,7 +60,7 @@ public class ServiceKeyMetric extends ApplicationMetric {
@Override
public int hashCode() {
if (hashCode == 0) {
hashCode = Objects.hash(getApplicationName(), serviceKey);
hashCode = Objects.hash(getApplicationName(), serviceKey, extraInfo);
}
return hashCode;
}

View File

@ -43,7 +43,7 @@ public class MetricsCat {
}
/**
* @param tpFunc Ternary function, corresponding to finish and error events, because an additional record rt is required, and the type type of metricsKey is required
* @param tpFunc Ternary function, corresponding to finish and error events, because an additional record rt is required, and the type of metricsKey is required
*/
public MetricsCat(MetricsKey metricsKey, TpFunction<MetricsKey, MetricsPlaceValue, CombMetricsCollector, AbstractMetricsKeyListener> tpFunc) {
this.eventFunc = collector -> tpFunc.apply(metricsKey, placeType, collector);

View File

@ -18,11 +18,8 @@
package org.apache.dubbo.metrics.model.key;
import io.micrometer.common.lang.Nullable;
import org.apache.dubbo.metrics.model.MetricsSupport;
import org.apache.dubbo.metrics.model.sample.MetricSample;
import org.apache.dubbo.rpc.model.ApplicationModel;
import java.util.Map;
import java.util.Objects;
/**
@ -105,19 +102,6 @@ public class MetricsKeyWrapper {
}
}
public Map<String, String> tagName(ApplicationModel applicationModel, String key) {
MetricsLevel level = getLevel();
switch (level) {
case APP:
return MetricsSupport.applicationTags(applicationModel);
case SERVICE:
return MetricsSupport.serviceTags(applicationModel, key);
case METHOD:
return MetricsSupport.methodTags(applicationModel, key);
}
return MetricsSupport.applicationTags(applicationModel);
}
public static MetricsKeyWrapper wrapper(MetricsKey metricsKey) {
return new MetricsKeyWrapper(metricsKey, null);
}

View File

@ -18,5 +18,5 @@
package org.apache.dubbo.metrics.model.key;
public enum MetricsLevel {
APP, SERVICE, METHOD, CONFIG
APP, SERVICE, METHOD, CONFIG, REGISTRY
}

View File

@ -23,6 +23,7 @@ import org.apache.dubbo.metrics.model.key.MetricsLevel;
import org.apache.dubbo.metrics.model.key.MetricsPlaceValue;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static org.apache.dubbo.metrics.model.key.MetricsKey.DIRECTORY_METRIC_NUM_ALL;
@ -46,17 +47,23 @@ import static org.apache.dubbo.metrics.model.key.MetricsKey.SUBSCRIBE_METRIC_NUM
public interface RegistryMetricsConstants {
String ATTACHMENT_REGISTRY_KEY = "registryKey";
String ATTACHMENT_REGISTRY_SINGLE_KEY = "registrySingleKey";
MetricsPlaceValue OP_TYPE_REGISTER = MetricsPlaceValue.of("register", MetricsLevel.APP);
MetricsPlaceValue OP_TYPE_SUBSCRIBE = MetricsPlaceValue.of("subscribe", MetricsLevel.APP);
MetricsPlaceValue OP_TYPE_NOTIFY = MetricsPlaceValue.of("notify", MetricsLevel.APP);
MetricsPlaceValue OP_TYPE_DIRECTORY = MetricsPlaceValue.of("directory", MetricsLevel.APP);
MetricsPlaceValue OP_TYPE_REGISTER_SERVICE = MetricsPlaceValue.of("register.service", MetricsLevel.SERVICE);
MetricsPlaceValue OP_TYPE_REGISTER_SERVICE = MetricsPlaceValue.of("register.service", MetricsLevel.REGISTRY);
MetricsPlaceValue OP_TYPE_SUBSCRIBE_SERVICE = MetricsPlaceValue.of("subscribe.service", MetricsLevel.SERVICE);
// App-level
List<MetricsKey> APP_LEVEL_KEYS = Arrays.asList(REGISTER_METRIC_REQUESTS, REGISTER_METRIC_REQUESTS_SUCCEED, REGISTER_METRIC_REQUESTS_FAILED,
SUBSCRIBE_METRIC_NUM, SUBSCRIBE_METRIC_NUM_SUCCEED, SUBSCRIBE_METRIC_NUM_FAILED,
NOTIFY_METRIC_REQUESTS);
List<MetricsKey> APP_LEVEL_KEYS = Collections.singletonList(NOTIFY_METRIC_REQUESTS);
// Registry-level
List<MetricsKey> REGISTER_LEVEL_KEYS = Arrays.asList(REGISTER_METRIC_REQUESTS, REGISTER_METRIC_REQUESTS_SUCCEED, REGISTER_METRIC_REQUESTS_FAILED,
SUBSCRIBE_METRIC_NUM, SUBSCRIBE_METRIC_NUM_SUCCEED, SUBSCRIBE_METRIC_NUM_FAILED
);
// Service-level
List<MetricsKeyWrapper> SERVICE_LEVEL_KEYS = Arrays.asList(

View File

@ -17,6 +17,7 @@
package org.apache.dubbo.metrics.registry.collector;
import org.apache.dubbo.common.constants.RegistryConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.config.context.ConfigManager;
import org.apache.dubbo.metrics.collector.CombMetricsCollector;
@ -25,7 +26,11 @@ import org.apache.dubbo.metrics.data.ApplicationStatComposite;
import org.apache.dubbo.metrics.data.BaseStatComposite;
import org.apache.dubbo.metrics.data.RtStatComposite;
import org.apache.dubbo.metrics.data.ServiceStatComposite;
import org.apache.dubbo.metrics.model.ApplicationMetric;
import org.apache.dubbo.metrics.model.MetricsCategory;
import org.apache.dubbo.metrics.model.ServiceKeyMetric;
import org.apache.dubbo.metrics.model.key.MetricsKey;
import org.apache.dubbo.metrics.model.key.MetricsKeyWrapper;
import org.apache.dubbo.metrics.model.sample.MetricSample;
import org.apache.dubbo.metrics.registry.RegistryMetricsConstants;
import org.apache.dubbo.metrics.registry.event.RegistryEvent;
@ -33,7 +38,9 @@ import org.apache.dubbo.metrics.registry.event.RegistrySubDispatcher;
import org.apache.dubbo.rpc.model.ApplicationModel;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import static org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE_NOTIFY;
@ -51,6 +58,7 @@ public class RegistryMetricsCollector extends CombMetricsCollector<RegistryEvent
private Boolean collectEnabled = null;
private final ApplicationModel applicationModel;
private final RegistryStatComposite internalStat;
public RegistryMetricsCollector(ApplicationModel applicationModel) {
super(new BaseStatComposite(applicationModel) {
@ -73,6 +81,7 @@ public class RegistryMetricsCollector extends CombMetricsCollector<RegistryEvent
}
});
super.setEventMulticaster(new RegistrySubDispatcher(this));
internalStat = new RegistryStatComposite(applicationModel);
this.applicationModel = applicationModel;
}
@ -99,7 +108,45 @@ public class RegistryMetricsCollector extends CombMetricsCollector<RegistryEvent
return list;
}
list.addAll(super.export(MetricsCategory.REGISTRY));
list.addAll(internalStat.export(MetricsCategory.REGISTRY));
return list;
}
public void incrMetricsNum(MetricsKey metricsKey, List<String> registryClusterNames) {
registryClusterNames.forEach(name -> internalStat.incrMetricsNum(metricsKey, name));
}
public void incrRegisterFinishNum(MetricsKey metricsKey, String registryOpType, List<String> registryClusterNames, Long responseTime) {
registryClusterNames.forEach(name ->
{
ApplicationMetric applicationMetric = new ApplicationMetric(applicationModel);
applicationMetric.setExtraInfo(Collections.singletonMap(RegistryConstants.REGISTRY_CLUSTER_KEY.toLowerCase(), name));
internalStat.incrMetricsNum(metricsKey, name);
getStats().getRtStatComposite().calcServiceKeyRt(registryOpType, responseTime, applicationMetric);
});
}
public void incrServiceRegisterNum(MetricsKeyWrapper wrapper, String serviceKey, List<String> registryClusterNames, int size) {
registryClusterNames.forEach(name ->
stats.incrementServiceKey(wrapper, serviceKey, Collections.singletonMap(RegistryConstants.REGISTRY_CLUSTER_KEY.toLowerCase(), name), size)
);
}
public void incrServiceRegisterFinishNum(MetricsKeyWrapper wrapper, String serviceKey, List<String> registryClusterNames, int size, Long responseTime) {
registryClusterNames.forEach(name ->
{
Map<String, String> extraInfo = Collections.singletonMap(RegistryConstants.REGISTRY_CLUSTER_KEY.toLowerCase(), name);
ServiceKeyMetric serviceKeyMetric = new ServiceKeyMetric(applicationModel, serviceKey);
serviceKeyMetric.setExtraInfo(extraInfo);
stats.incrementServiceKey(wrapper, serviceKey, extraInfo, size);
getStats().getRtStatComposite().calcServiceKeyRt(wrapper.getType(), responseTime, serviceKeyMetric);
}
);
}
public void setNum(MetricsKeyWrapper metricsKey, String serviceKey, int num, Map<String, String> attachments) {
this.stats.setServiceKey(metricsKey, serviceKey, num, attachments);
}
}

View File

@ -0,0 +1,81 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.metrics.registry.collector;
import org.apache.dubbo.common.constants.RegistryConstants;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.metrics.model.ApplicationMetric;
import org.apache.dubbo.metrics.model.MetricsCategory;
import org.apache.dubbo.metrics.model.MetricsSupport;
import org.apache.dubbo.metrics.model.key.MetricsKey;
import org.apache.dubbo.metrics.model.sample.GaugeMetricSample;
import org.apache.dubbo.metrics.model.sample.MetricSample;
import org.apache.dubbo.metrics.registry.RegistryMetricsConstants;
import org.apache.dubbo.metrics.report.AbstractMetricsExport;
import org.apache.dubbo.rpc.model.ApplicationModel;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import static org.apache.dubbo.metrics.MetricsConstants.SELF_INCREMENT_SIZE;
public class RegistryStatComposite extends AbstractMetricsExport {
private final Map<MetricsKey, Map<ApplicationMetric, AtomicLong>> appStats = new ConcurrentHashMap<>();
public RegistryStatComposite(ApplicationModel applicationModel) {
super(applicationModel);
init(RegistryMetricsConstants.REGISTER_LEVEL_KEYS);
}
public void init(List<MetricsKey> appKeys) {
if (CollectionUtils.isEmpty(appKeys)) {
return;
}
appKeys.forEach(appKey -> appStats.put(appKey, new ConcurrentHashMap<>()));
}
@Override
public List<MetricSample> export(MetricsCategory category) {
List<MetricSample> list = new ArrayList<>();
for (MetricsKey metricsKey : appStats.keySet()) {
Map<ApplicationMetric, AtomicLong> stringAtomicLongMap = appStats.get(metricsKey);
for (ApplicationMetric registerKeyMetric : stringAtomicLongMap.keySet()) {
list.add(new GaugeMetricSample<>(metricsKey, registerKeyMetric.getTags(), category, stringAtomicLongMap, value -> value.get(registerKeyMetric).get()));
}
}
return list;
}
public void incrMetricsNum(MetricsKey metricsKey, String name) {
if (!appStats.containsKey(metricsKey)) {
return;
}
ApplicationMetric applicationMetric = new ApplicationMetric(getApplicationModel());
applicationMetric.setExtraInfo(Collections.singletonMap(RegistryConstants.REGISTRY_CLUSTER_KEY.toLowerCase(), name));
appStats.get(metricsKey).computeIfAbsent(applicationMetric, k -> new AtomicLong(0L)).getAndAdd(SELF_INCREMENT_SIZE);
MetricsSupport.fillZero(appStats);
}
public Map<MetricsKey, Map<ApplicationMetric, AtomicLong>> getAppStats() {
return appStats;
}
}

View File

@ -22,9 +22,12 @@ import org.apache.dubbo.metrics.event.TimeCounterEvent;
import org.apache.dubbo.metrics.model.key.MetricsKey;
import org.apache.dubbo.metrics.model.key.MetricsLevel;
import org.apache.dubbo.metrics.model.key.TypeWrapper;
import org.apache.dubbo.metrics.registry.RegistryMetricsConstants;
import org.apache.dubbo.metrics.registry.collector.RegistryMetricsCollector;
import org.apache.dubbo.rpc.model.ApplicationModel;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import static org.apache.dubbo.metrics.MetricsConstants.ATTACHMENT_DIRECTORY_MAP;
@ -48,18 +51,25 @@ public class RegistryEvent extends TimeCounterEvent {
}
private static final TypeWrapper REGISTER_EVENT = new TypeWrapper(MetricsLevel.APP, MetricsKey.REGISTER_METRIC_REQUESTS, MetricsKey.REGISTER_METRIC_REQUESTS_SUCCEED, MetricsKey.REGISTER_METRIC_REQUESTS_FAILED);
public static RegistryEvent toRegisterEvent(ApplicationModel applicationModel) {
return new RegistryEvent(applicationModel, REGISTER_EVENT);
public static RegistryEvent toRegisterEvent(ApplicationModel applicationModel, List<String> registryClusterNames) {
RegistryEvent registryEvent = new RegistryEvent(applicationModel, REGISTER_EVENT);
registryEvent.putAttachment(RegistryMetricsConstants.ATTACHMENT_REGISTRY_KEY, registryClusterNames);
return registryEvent;
}
private static final TypeWrapper SUBSCRIBE_EVENT = new TypeWrapper(MetricsLevel.APP, MetricsKey.SUBSCRIBE_METRIC_NUM, MetricsKey.SUBSCRIBE_METRIC_NUM_SUCCEED, MetricsKey.SUBSCRIBE_METRIC_NUM_FAILED);
public static RegistryEvent toSubscribeEvent(ApplicationModel applicationModel) {
return new RegistryEvent(applicationModel, SUBSCRIBE_EVENT);
public static RegistryEvent toSubscribeEvent(ApplicationModel applicationModel, String registryClusterName) {
RegistryEvent ddEvent = new RegistryEvent(applicationModel, SUBSCRIBE_EVENT);
ddEvent.putAttachment(RegistryMetricsConstants.ATTACHMENT_REGISTRY_KEY, Collections.singletonList(registryClusterName));
return ddEvent;
}
private static final TypeWrapper NOTIFY_EVENT = new TypeWrapper(MetricsLevel.APP, MetricsKey.NOTIFY_METRIC_REQUESTS, MetricsKey.NOTIFY_METRIC_NUM_LAST, (MetricsKey) null);
public static RegistryEvent toNotifyEvent(ApplicationModel applicationModel) {
return new RegistryEvent(applicationModel, NOTIFY_EVENT) {
@Override
@ -70,24 +80,31 @@ public class RegistryEvent extends TimeCounterEvent {
}
private static final TypeWrapper RS_EVENT = new TypeWrapper(MetricsLevel.SERVICE, MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS, MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS_SUCCEED, MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS_FAILED);
public static RegistryEvent toRsEvent(ApplicationModel applicationModel, String serviceKey, int size) {
public static RegistryEvent toRsEvent(ApplicationModel applicationModel, String serviceKey, int size, List<String> serviceDiscoveryNames) {
RegistryEvent ddEvent = new RegistryEvent(applicationModel, RS_EVENT);
ddEvent.putAttachment(ATTACHMENT_KEY_SERVICE, serviceKey);
ddEvent.putAttachment(ATTACHMENT_KEY_SIZE, size);
ddEvent.putAttachment(RegistryMetricsConstants.ATTACHMENT_REGISTRY_KEY, serviceDiscoveryNames);
return ddEvent;
}
private static final TypeWrapper SS_EVENT = new TypeWrapper(MetricsLevel.SERVICE, MetricsKey.SERVICE_SUBSCRIBE_METRIC_NUM, MetricsKey.SERVICE_SUBSCRIBE_METRIC_NUM_SUCCEED, MetricsKey.SERVICE_SUBSCRIBE_METRIC_NUM_FAILED);
public static RegistryEvent toSsEvent(ApplicationModel applicationModel, String serviceKey) {
public static RegistryEvent toSsEvent(ApplicationModel applicationModel, String serviceKey, List<String> serviceDiscoveryNames) {
RegistryEvent ddEvent = new RegistryEvent(applicationModel, SS_EVENT);
ddEvent.putAttachment(ATTACHMENT_KEY_SERVICE, serviceKey);
ddEvent.putAttachment(ATTACHMENT_KEY_SIZE, 1);
ddEvent.putAttachment(RegistryMetricsConstants.ATTACHMENT_REGISTRY_KEY, serviceDiscoveryNames);
return ddEvent;
}
private static final TypeWrapper DIRECTORY_EVENT = new TypeWrapper(MetricsLevel.APP, MetricsKey.DIRECTORY_METRIC_NUM_VALID, null, null);
public static RegistryEvent refreshDirectoryEvent(ApplicationModel applicationModel, Map<MetricsKey, Map<String, Integer>> summaryMap) {
public static RegistryEvent refreshDirectoryEvent(ApplicationModel applicationModel, Map<MetricsKey, Map<String, Integer>> summaryMap, Map<String, String> attachments) {
RegistryEvent registryEvent = new RegistryEvent(applicationModel, DIRECTORY_EVENT);
registryEvent.putAttachment(ATTACHMENT_DIRECTORY_MAP, summaryMap);
registryEvent.putAttachments(attachments);
return registryEvent;
}

View File

@ -0,0 +1,154 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.metrics.registry.event;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.metrics.collector.CombMetricsCollector;
import org.apache.dubbo.metrics.event.MetricsEvent;
import org.apache.dubbo.metrics.listener.AbstractMetricsKeyListener;
import org.apache.dubbo.metrics.listener.MetricsApplicationListener;
import org.apache.dubbo.metrics.model.key.MetricsKey;
import org.apache.dubbo.metrics.model.key.MetricsKeyWrapper;
import org.apache.dubbo.metrics.model.key.MetricsPlaceValue;
import org.apache.dubbo.metrics.registry.RegistryMetricsConstants;
import org.apache.dubbo.metrics.registry.collector.RegistryMetricsCollector;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import static org.apache.dubbo.metrics.MetricsConstants.ATTACHMENT_DIRECTORY_MAP;
import static org.apache.dubbo.metrics.MetricsConstants.ATTACHMENT_KEY_LAST_NUM_MAP;
import static org.apache.dubbo.metrics.MetricsConstants.ATTACHMENT_KEY_SERVICE;
import static org.apache.dubbo.metrics.MetricsConstants.ATTACHMENT_KEY_SIZE;
import static org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE_DIRECTORY;
import static org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE_NOTIFY;
import static org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE_REGISTER;
/**
* Different from the general-purpose listener constructor {@link MetricsApplicationListener} ,
* it provides registry custom listeners
*/
public class RegistrySpecListener {
/**
* Perform auto-increment on the monitored key,
* Can use a custom listener instead of this generic operation
*/
public static AbstractMetricsKeyListener onPost(MetricsKey metricsKey, CombMetricsCollector<?> collector) {
return AbstractMetricsKeyListener.onEvent(metricsKey,
event -> ((RegistryMetricsCollector) collector).incrMetricsNum(metricsKey, getRgs(event))
);
}
public static AbstractMetricsKeyListener onFinish(MetricsKey metricsKey, CombMetricsCollector<?> collector) {
return AbstractMetricsKeyListener.onFinish(metricsKey,
event -> ((RegistryMetricsCollector) collector).incrRegisterFinishNum(metricsKey, OP_TYPE_REGISTER.getType(), getRgs(event), event.getTimePair().calc())
);
}
public static AbstractMetricsKeyListener onError(MetricsKey metricsKey, CombMetricsCollector<?> collector) {
return AbstractMetricsKeyListener.onError(metricsKey,
event -> ((RegistryMetricsCollector) collector).incrRegisterFinishNum(metricsKey, OP_TYPE_REGISTER.getType(), getRgs(event), event.getTimePair().calc())
);
}
public static AbstractMetricsKeyListener onPostOfService(MetricsKey metricsKey, MetricsPlaceValue placeType, CombMetricsCollector<?> collector) {
return AbstractMetricsKeyListener.onEvent(metricsKey,
event -> ((RegistryMetricsCollector) collector).incrServiceRegisterNum(new MetricsKeyWrapper(metricsKey, placeType), getServiceKey(event), getRgs(event), getSize(event))
);
}
public static AbstractMetricsKeyListener onFinishOfService(MetricsKey metricsKey, MetricsPlaceValue placeType, CombMetricsCollector<?> collector) {
return AbstractMetricsKeyListener.onFinish(metricsKey,
event -> ((RegistryMetricsCollector) collector).incrServiceRegisterFinishNum(new MetricsKeyWrapper(metricsKey, placeType), getServiceKey(event), getRgs(event), getSize(event), event.getTimePair().calc())
);
}
public static AbstractMetricsKeyListener onErrorOfService(MetricsKey metricsKey, MetricsPlaceValue placeType, CombMetricsCollector<?> collector) {
return AbstractMetricsKeyListener.onError(metricsKey,
event -> ((RegistryMetricsCollector) collector).incrServiceRegisterFinishNum(new MetricsKeyWrapper(metricsKey, placeType), getServiceKey(event), getRgs(event), getSize(event), event.getTimePair().calc())
);
}
/**
* Every time an event is triggered, multiple serviceKey related to notify are increment
*/
public static AbstractMetricsKeyListener onFinishOfNotify(MetricsKey metricsKey, MetricsPlaceValue placeType, CombMetricsCollector<?> collector) {
return AbstractMetricsKeyListener.onFinish(metricsKey,
event ->
{
collector.addServiceRt(event.appName(), placeType.getType(), event.getTimePair().calc());
Map<String, Integer> lastNumMap = Collections.unmodifiableMap(event.getAttachmentValue(ATTACHMENT_KEY_LAST_NUM_MAP));
lastNumMap.forEach(
(k, v) -> collector.setNum(new MetricsKeyWrapper(metricsKey, OP_TYPE_NOTIFY), k, v));
}
);
}
/**
* Every time an event is triggered, multiple fixed key related to directory are increment, which has nothing to do with the monitored key
*/
public static AbstractMetricsKeyListener onPostOfDirectory(MetricsKey metricsKey, CombMetricsCollector<?> collector) {
return AbstractMetricsKeyListener.onEvent(metricsKey,
event -> {
Map<MetricsKey, Map<String, Integer>> summaryMap = event.getAttachmentValue(ATTACHMENT_DIRECTORY_MAP);
Map<String, String> otherAttachments = new HashMap<>();
for (Map.Entry<String, Object> entry : event.getAttachments().entrySet()) {
if (entry.getValue() instanceof String) {
otherAttachments.put(entry.getKey().toLowerCase(Locale.ROOT), (String) entry.getValue());
}
}
summaryMap.forEach((summaryKey, map) ->
map.forEach(
(k, v) ->
{
if (CollectionUtils.isEmptyMap(otherAttachments)) {
collector.setNum(new MetricsKeyWrapper(summaryKey, OP_TYPE_DIRECTORY), k, v);
} else {
((RegistryMetricsCollector) collector).setNum(new MetricsKeyWrapper(summaryKey, OP_TYPE_DIRECTORY), k, v, otherAttachments);
}
}
));
}
);
}
/**
* Get the number of multiple registries
*/
public static List<String> getRgs(MetricsEvent event) {
return event.getAttachmentValue(RegistryMetricsConstants.ATTACHMENT_REGISTRY_KEY);
}
/**
* Get the exposed number of the protocol
*/
public static int getSize(MetricsEvent event) {
return event.getAttachmentValue(ATTACHMENT_KEY_SIZE);
}
public static String getServiceKey(MetricsEvent event) {
return event.getAttachmentValue(ATTACHMENT_KEY_SERVICE);
}
}

View File

@ -18,22 +18,15 @@
package org.apache.dubbo.metrics.registry.event;
import org.apache.dubbo.metrics.event.SimpleMetricsEventMulticaster;
import org.apache.dubbo.metrics.listener.AbstractMetricsKeyListener;
import org.apache.dubbo.metrics.listener.MetricsApplicationListener;
import org.apache.dubbo.metrics.listener.MetricsServiceListener;
import org.apache.dubbo.metrics.model.key.CategoryOverall;
import org.apache.dubbo.metrics.model.key.MetricsCat;
import org.apache.dubbo.metrics.model.key.MetricsKey;
import org.apache.dubbo.metrics.model.key.MetricsKeyWrapper;
import org.apache.dubbo.metrics.registry.collector.RegistryMetricsCollector;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import static org.apache.dubbo.metrics.MetricsConstants.ATTACHMENT_DIRECTORY_MAP;
import static org.apache.dubbo.metrics.MetricsConstants.ATTACHMENT_KEY_LAST_NUM_MAP;
import static org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE_DIRECTORY;
import static org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE_NOTIFY;
import static org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE_REGISTER;
@ -74,55 +67,37 @@ public final class RegistrySubDispatcher extends SimpleMetricsEventMulticaster {
/**
* {@link MetricsCat} MetricsCat collection, for better classification processing
* Except for a few custom functions, most of them can build standard event listening functions through the static methods of MetricsApplicationListener
* {@link MetricsCat} MetricsCat collection, for better classification processing
* Except for a few custom functions, most of them can build standard event listening functions through the static methods of MetricsApplicationListener
*/
interface MCat {
// MetricsRegisterListener
MetricsCat APPLICATION_REGISTER_POST = new MetricsCat(MetricsKey.REGISTER_METRIC_REQUESTS, MetricsApplicationListener::onPostEventBuild);
MetricsCat APPLICATION_REGISTER_FINISH = new MetricsCat(MetricsKey.REGISTER_METRIC_REQUESTS_SUCCEED, MetricsApplicationListener::onFinishEventBuild);
MetricsCat APPLICATION_REGISTER_ERROR = new MetricsCat(MetricsKey.REGISTER_METRIC_REQUESTS_FAILED, MetricsApplicationListener::onErrorEventBuild);
MetricsCat APPLICATION_REGISTER_POST = new MetricsCat(MetricsKey.REGISTER_METRIC_REQUESTS, RegistrySpecListener::onPost);
MetricsCat APPLICATION_REGISTER_FINISH = new MetricsCat(MetricsKey.REGISTER_METRIC_REQUESTS_SUCCEED, RegistrySpecListener::onFinish);
MetricsCat APPLICATION_REGISTER_ERROR = new MetricsCat(MetricsKey.REGISTER_METRIC_REQUESTS_FAILED, RegistrySpecListener::onError);
// MetricsSubscribeListener
MetricsCat APPLICATION_SUBSCRIBE_POST = new MetricsCat(MetricsKey.SUBSCRIBE_METRIC_NUM, MetricsApplicationListener::onPostEventBuild);
MetricsCat APPLICATION_SUBSCRIBE_FINISH = new MetricsCat(MetricsKey.SUBSCRIBE_METRIC_NUM_SUCCEED, MetricsApplicationListener::onFinishEventBuild);
MetricsCat APPLICATION_SUBSCRIBE_ERROR = new MetricsCat(MetricsKey.SUBSCRIBE_METRIC_NUM_FAILED, MetricsApplicationListener::onErrorEventBuild);
MetricsCat APPLICATION_SUBSCRIBE_POST = new MetricsCat(MetricsKey.SUBSCRIBE_METRIC_NUM, RegistrySpecListener::onPost);
MetricsCat APPLICATION_SUBSCRIBE_FINISH = new MetricsCat(MetricsKey.SUBSCRIBE_METRIC_NUM_SUCCEED, RegistrySpecListener::onFinish);
MetricsCat APPLICATION_SUBSCRIBE_ERROR = new MetricsCat(MetricsKey.SUBSCRIBE_METRIC_NUM_FAILED, RegistrySpecListener::onError);
// MetricsNotifyListener
MetricsCat APPLICATION_NOTIFY_POST = new MetricsCat(MetricsKey.NOTIFY_METRIC_REQUESTS, MetricsApplicationListener::onPostEventBuild);
MetricsCat APPLICATION_NOTIFY_FINISH = new MetricsCat(MetricsKey.NOTIFY_METRIC_NUM_LAST,
(key, placeType, collector) -> AbstractMetricsKeyListener.onFinish(key,
event -> {
collector.addServiceRt(event.appName(), placeType.getType(), event.getTimePair().calc());
Map<String, Integer> lastNumMap = Collections.unmodifiableMap(event.getAttachmentValue(ATTACHMENT_KEY_LAST_NUM_MAP));
lastNumMap.forEach(
(k, v) -> collector.setNum(new MetricsKeyWrapper(key, OP_TYPE_NOTIFY), k, v));
MetricsCat APPLICATION_NOTIFY_FINISH = new MetricsCat(MetricsKey.NOTIFY_METRIC_NUM_LAST, RegistrySpecListener::onFinishOfNotify);
}
));
MetricsCat APPLICATION_DIRECTORY_POST = new MetricsCat(MetricsKey.DIRECTORY_METRIC_NUM_VALID, (key, placeType, collector) -> AbstractMetricsKeyListener.onEvent(key,
event ->
{
Map<MetricsKey, Map<String, Integer>> summaryMap = event.getAttachmentValue(ATTACHMENT_DIRECTORY_MAP);
summaryMap.forEach((metricsKey, map) ->
map.forEach(
(k, v) -> collector.setNum(new MetricsKeyWrapper(metricsKey, OP_TYPE_DIRECTORY), k, v)));
}
));
MetricsCat APPLICATION_DIRECTORY_POST = new MetricsCat(MetricsKey.DIRECTORY_METRIC_NUM_VALID, RegistrySpecListener::onPostOfDirectory);
// MetricsServiceRegisterListener
MetricsCat SERVICE_REGISTER_POST = new MetricsCat(MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS, MetricsServiceListener::onPostEventBuild);
MetricsCat SERVICE_REGISTER_FINISH = new MetricsCat(MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS_SUCCEED, MetricsServiceListener::onFinishEventBuild);
MetricsCat SERVICE_REGISTER_ERROR = new MetricsCat(MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS_FAILED, MetricsServiceListener::onErrorEventBuild);
MetricsCat SERVICE_REGISTER_POST = new MetricsCat(MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS, RegistrySpecListener::onPostOfService);
MetricsCat SERVICE_REGISTER_FINISH = new MetricsCat(MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS_SUCCEED, RegistrySpecListener::onFinishOfService);
MetricsCat SERVICE_REGISTER_ERROR = new MetricsCat(MetricsKey.SERVICE_REGISTER_METRIC_REQUESTS_FAILED, RegistrySpecListener::onErrorOfService);
// MetricsServiceSubscribeListener
MetricsCat SERVICE_SUBSCRIBE_POST = new MetricsCat(MetricsKey.SERVICE_SUBSCRIBE_METRIC_NUM, MetricsServiceListener::onPostEventBuild);
MetricsCat SERVICE_SUBSCRIBE_FINISH = new MetricsCat(MetricsKey.SERVICE_SUBSCRIBE_METRIC_NUM_SUCCEED, MetricsServiceListener::onFinishEventBuild);
MetricsCat SERVICE_SUBSCRIBE_ERROR = new MetricsCat(MetricsKey.SERVICE_SUBSCRIBE_METRIC_NUM_FAILED, MetricsServiceListener::onErrorEventBuild);
MetricsCat SERVICE_SUBSCRIBE_POST = new MetricsCat(MetricsKey.SERVICE_SUBSCRIBE_METRIC_NUM, RegistrySpecListener::onPostOfService);
MetricsCat SERVICE_SUBSCRIBE_FINISH = new MetricsCat(MetricsKey.SERVICE_SUBSCRIBE_METRIC_NUM_SUCCEED, RegistrySpecListener::onFinishOfService);
MetricsCat SERVICE_SUBSCRIBE_ERROR = new MetricsCat(MetricsKey.SERVICE_SUBSCRIBE_METRIC_NUM_FAILED, RegistrySpecListener::onErrorOfService);
}

View File

@ -17,6 +17,7 @@
package org.apache.dubbo.metrics.registry.metrics.collector;
import com.google.common.collect.Lists;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.metrics.event.MetricsDispatcher;
import org.apache.dubbo.metrics.event.MetricsEventBus;
@ -30,12 +31,12 @@ import org.apache.dubbo.metrics.registry.collector.RegistryMetricsCollector;
import org.apache.dubbo.metrics.registry.event.RegistryEvent;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.FrameworkModel;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -43,9 +44,11 @@ import java.util.Objects;
import java.util.stream.Collectors;
import static org.apache.dubbo.common.constants.MetricsConstants.TAG_APPLICATION_NAME;
import static org.apache.dubbo.metrics.registry.RegistryMetricsConstants.APP_LEVEL_KEYS;
import static org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE_REGISTER;
import static org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE_REGISTER_SERVICE;
import static org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE_SUBSCRIBE_SERVICE;
import static org.apache.dubbo.metrics.registry.RegistryMetricsConstants.REGISTER_LEVEL_KEYS;
class RegistryMetricsCollectorTest {
@ -74,12 +77,12 @@ class RegistryMetricsCollectorTest {
@Test
void testRegisterMetrics() {
RegistryEvent registryEvent = RegistryEvent.toRegisterEvent(applicationModel);
RegistryEvent registryEvent = RegistryEvent.toRegisterEvent(applicationModel, Lists.newArrayList("reg1"));
MetricsEventBus.post(registryEvent,
() -> {
List<MetricSample> metricSamples = collector.collect();
// push success +1 -> other default 0 = RegistryMetricsConstants.APP_LEVEL_KEYS.size()
Assertions.assertEquals(RegistryMetricsConstants.APP_LEVEL_KEYS.size(), metricSamples.size());
// push success +1 -> other default 0 = APP_LEVEL_KEYS.size()
Assertions.assertEquals(APP_LEVEL_KEYS.size() + REGISTER_LEVEL_KEYS.size(), metricSamples.size());
Assertions.assertTrue(metricSamples.stream().allMatch(metricSample -> metricSample instanceof GaugeMetricSample));
Assertions.assertTrue(metricSamples.stream().anyMatch(metricSample -> ((GaugeMetricSample) metricSample).applyAsDouble() == 1));
return null;
@ -88,12 +91,12 @@ class RegistryMetricsCollectorTest {
// push finish rt +1
List<MetricSample> metricSamples = collector.collect();
// RegistryMetricsConstants.APP_LEVEL_KEYS.size() + rt(5) = 12
Assertions.assertEquals(RegistryMetricsConstants.APP_LEVEL_KEYS.size() + 5, metricSamples.size());
// APP_LEVEL_KEYS.size() + rt(5) = 12
Assertions.assertEquals(APP_LEVEL_KEYS.size() + REGISTER_LEVEL_KEYS.size() + 5, metricSamples.size());
long c1 = registryEvent.getTimePair().calc();
registryEvent = RegistryEvent.toRegisterEvent(applicationModel);
registryEvent = RegistryEvent.toRegisterEvent(applicationModel, Lists.newArrayList("reg1"));
TimePair lastTimePair = registryEvent.getTimePair();
MetricsEventBus.post(registryEvent,
() -> {
@ -111,7 +114,7 @@ class RegistryMetricsCollectorTest {
metricSamples = collector.collect();
// num(total+success+error) + rt(5)
Assertions.assertEquals(RegistryMetricsConstants.APP_LEVEL_KEYS.size() + 5, metricSamples.size());
Assertions.assertEquals(APP_LEVEL_KEYS.size() + REGISTER_LEVEL_KEYS.size() + 5, metricSamples.size());
// calc rt
for (MetricSample sample : metricSamples) {
@ -134,8 +137,9 @@ class RegistryMetricsCollectorTest {
void testServicePushMetrics() {
String serviceName = "demo.gameService";
List<String> rcNames = Lists.newArrayList("demo1");
RegistryEvent registryEvent = RegistryEvent.toRsEvent(applicationModel, serviceName, 2);
RegistryEvent registryEvent = RegistryEvent.toRsEvent(applicationModel, serviceName, 2, rcNames);
MetricsEventBus.post(registryEvent,
() -> {
List<MetricSample> metricSamples = collector.collect();
@ -154,7 +158,7 @@ class RegistryMetricsCollectorTest {
Assertions.assertEquals(RegistryMetricsConstants.APP_LEVEL_KEYS.size() + 5 + 2, metricSamples.size());
long c1 = registryEvent.getTimePair().calc();
registryEvent = RegistryEvent.toRsEvent(applicationModel, serviceName, 2);
registryEvent = RegistryEvent.toRsEvent(applicationModel, serviceName, 2, rcNames);
TimePair lastTimePair = registryEvent.getTimePair();
MetricsEventBus.post(registryEvent,
() -> {
@ -196,7 +200,7 @@ class RegistryMetricsCollectorTest {
String serviceName = "demo.gameService";
RegistryEvent subscribeEvent = RegistryEvent.toSsEvent(applicationModel, serviceName);
RegistryEvent subscribeEvent = RegistryEvent.toSsEvent(applicationModel, serviceName, Collections.singletonList("demo1"));
MetricsEventBus.post(subscribeEvent,
() -> {
List<MetricSample> metricSamples = collector.collect();
@ -216,7 +220,7 @@ class RegistryMetricsCollectorTest {
Assertions.assertEquals(RegistryMetricsConstants.APP_LEVEL_KEYS.size() + 5 + 2, metricSamples.size());
long c1 = subscribeEvent.getTimePair().calc();
subscribeEvent = RegistryEvent.toSsEvent(applicationModel, serviceName);
subscribeEvent = RegistryEvent.toSsEvent(applicationModel, serviceName, Collections.singletonList("demo1"));
TimePair lastTimePair = subscribeEvent.getTimePair();
MetricsEventBus.post(subscribeEvent,
() -> {

View File

@ -17,6 +17,7 @@
package org.apache.dubbo.metrics.registry.metrics.collector;
import com.google.common.collect.Lists;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.MetricsConfig;
import org.apache.dubbo.config.context.ConfigManager;
@ -28,7 +29,6 @@ import org.apache.dubbo.metrics.registry.collector.RegistryMetricsCollector;
import org.apache.dubbo.metrics.registry.event.RegistryEvent;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.FrameworkModel;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@ -289,19 +289,20 @@ public class RegistryMetricsTest {
}
RegistryEvent registerEvent() {
RegistryEvent event = RegistryEvent.toRegisterEvent(applicationModel);
RegistryEvent event = RegistryEvent.toRegisterEvent(applicationModel, Lists.newArrayList("reg1"));
event.setAvailable(true);
return event;
}
RegistryEvent rsEvent() {
RegistryEvent event = RegistryEvent.toRsEvent(applicationModel, "TestServiceInterface1", 1);
List<String> rcNames = Lists.newArrayList("demo1");
RegistryEvent event = RegistryEvent.toRsEvent(applicationModel, "TestServiceInterface1", 1, rcNames);
event.setAvailable(true);
return event;
}
RegistryEvent subscribeEvent() {
RegistryEvent event = RegistryEvent.toSubscribeEvent(applicationModel);
RegistryEvent event = RegistryEvent.toSubscribeEvent(applicationModel, "registryClusterName_test");
event.setAvailable(true);
return event;
}

View File

@ -17,6 +17,7 @@
package org.apache.dubbo.metrics.registry.metrics.collector;
import org.apache.dubbo.common.constants.RegistryConstants;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.metrics.data.ApplicationStatComposite;
import org.apache.dubbo.metrics.data.BaseStatComposite;
@ -29,12 +30,15 @@ import org.apache.dubbo.metrics.model.container.LongContainer;
import org.apache.dubbo.metrics.model.sample.GaugeMetricSample;
import org.apache.dubbo.metrics.model.sample.MetricSample;
import org.apache.dubbo.metrics.registry.RegistryMetricsConstants;
import org.apache.dubbo.metrics.registry.collector.RegistryStatComposite;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.FrameworkModel;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@ -55,6 +59,7 @@ public class RegistryStatCompositeTest {
private ApplicationModel applicationModel;
private String applicationName;
private BaseStatComposite statComposite;
private RegistryStatComposite regStatComposite;
@BeforeEach
public void setup() {
@ -83,6 +88,7 @@ public class RegistryStatCompositeTest {
rtStatComposite.init(OP_TYPE_REGISTER, OP_TYPE_SUBSCRIBE, OP_TYPE_NOTIFY, OP_TYPE_REGISTER_SERVICE, OP_TYPE_SUBSCRIBE_SERVICE);
}
};
regStatComposite = new RegistryStatComposite(applicationModel);
}
@Test
@ -102,8 +108,10 @@ public class RegistryStatCompositeTest {
@Test
void testIncrement() {
statComposite.incrementApp(REGISTER_METRIC_REQUESTS, 1);
Assertions.assertEquals(1L, statComposite.getApplicationStatComposite().getApplicationNumStats().get(REGISTER_METRIC_REQUESTS).get());
regStatComposite.incrMetricsNum(REGISTER_METRIC_REQUESTS, "beijing");
ApplicationMetric applicationMetric = new ApplicationMetric(applicationModel);
applicationMetric.setExtraInfo(Collections.singletonMap(RegistryConstants.REGISTRY_CLUSTER_KEY.toLowerCase(), "beijing"));
Assertions.assertEquals(1L, regStatComposite.getAppStats().get(REGISTER_METRIC_REQUESTS).get(applicationMetric).get());
}
@Test

View File

@ -17,6 +17,7 @@
package org.apache.dubbo.registry.client;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.constants.RegistryConstants;
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.CollectionUtils;
@ -33,6 +34,7 @@ import org.apache.dubbo.registry.client.event.listener.ServiceInstancesChangedLi
import org.apache.dubbo.registry.support.FailbackRegistry;
import org.apache.dubbo.rpc.model.ApplicationModel;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -328,7 +330,9 @@ public class ServiceDiscoveryRegistry extends FailbackRegistry {
serviceInstancesChangedListener.addListenerAndNotify(url, listener);
ServiceInstancesChangedListener finalServiceInstancesChangedListener = serviceInstancesChangedListener;
MetricsEventBus.post(RegistryEvent.toSsEvent(url.getApplicationModel(), serviceKey),
String serviceDiscoveryName = url.getParameter(RegistryConstants.REGISTRY_CLUSTER_KEY, url.getProtocol());
MetricsEventBus.post(RegistryEvent.toSsEvent(url.getApplicationModel(), serviceKey, Collections.singletonList(serviceDiscoveryName)),
() -> {
serviceDiscovery.addServiceInstancesChangedListener(finalServiceInstancesChangedListener);
return null;

View File

@ -21,6 +21,7 @@ import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.URLBuilder;
import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.constants.RegistryConstants;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
import org.apache.dubbo.common.logger.LoggerFactory;
@ -34,6 +35,7 @@ import org.apache.dubbo.metadata.MetadataInfo;
import org.apache.dubbo.registry.AddressListener;
import org.apache.dubbo.registry.Constants;
import org.apache.dubbo.registry.ProviderFirstParams;
import org.apache.dubbo.registry.Registry;
import org.apache.dubbo.registry.integration.AbstractConfiguratorListener;
import org.apache.dubbo.registry.integration.DynamicDirectory;
import org.apache.dubbo.rpc.Invocation;
@ -58,6 +60,7 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@ -66,6 +69,7 @@ import java.util.stream.Collectors;
import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.DISABLED_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.ENABLED_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.INSTANCE_REGISTER_MODE;
import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.SIDE_KEY;
import static org.apache.dubbo.common.constants.LoggerCodeConstants.PROTOCOL_FAILED_DESTROY_INVOKER;
@ -73,6 +77,8 @@ import static org.apache.dubbo.common.constants.LoggerCodeConstants.PROTOCOL_FAI
import static org.apache.dubbo.common.constants.LoggerCodeConstants.PROTOCOL_UNSUPPORTED;
import static org.apache.dubbo.common.constants.RegistryConstants.DEFAULT_HASHMAP_LOAD_FACTOR;
import static org.apache.dubbo.common.constants.RegistryConstants.EMPTY_PROTOCOL;
import static org.apache.dubbo.common.constants.RegistryConstants.REGISTER_MODE_KEY;
import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_KEY;
import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_TYPE_KEY;
import static org.apache.dubbo.common.constants.RegistryConstants.SERVICE_REGISTRY_TYPE;
import static org.apache.dubbo.registry.Constants.CONFIGURATORS_SUFFIX;
@ -498,6 +504,18 @@ public class ServiceDiscoveryRegistryDirectory<T> extends DynamicDirectory<T> {
this.destroyInvokers();
}
@Override
protected Map<String, String> getDirectoryMeta() {
String registryKey = Optional.ofNullable(getRegistry())
.map(Registry::getUrl)
.map(url -> url.getParameter(RegistryConstants.REGISTRY_CLUSTER_KEY, url.getParameter(RegistryConstants.REGISTRY_KEY, url.getProtocol())))
.orElse("unknown");
Map<String, String> metas = new HashMap<>();
metas.put(REGISTRY_KEY, registryKey);
metas.put(REGISTER_MODE_KEY, INSTANCE_REGISTER_MODE);
return metas;
}
/**
* Check whether the invoker in the cache needs to be destroyed
* If set attribute of url: refer.autodestroy=false, the invokers will only increase without decreasing,there may be a refer leak

View File

@ -17,6 +17,7 @@
package org.apache.dubbo.registry.client.metadata;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.constants.RegistryConstants;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
import org.apache.dubbo.common.logger.LoggerFactory;
@ -24,6 +25,8 @@ import org.apache.dubbo.common.utils.JsonUtils;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.metadata.MetadataInfo;
import org.apache.dubbo.metadata.MetadataService;
import org.apache.dubbo.metrics.event.MetricsEventBus;
import org.apache.dubbo.metrics.registry.event.RegistryEvent;
import org.apache.dubbo.registry.client.DefaultServiceInstance;
import org.apache.dubbo.registry.client.DefaultServiceInstance.Endpoint;
import org.apache.dubbo.registry.client.ServiceDiscovery;
@ -33,6 +36,7 @@ import org.apache.dubbo.registry.support.RegistryManager;
import org.apache.dubbo.rpc.model.ApplicationModel;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@ -44,6 +48,7 @@ import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.PORT_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.TIMESTAMP_KEY;
import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_KEY;
import static org.apache.dubbo.common.utils.StringUtils.isBlank;
import static org.apache.dubbo.registry.integration.InterfaceCompatibleRegistryProtocol.DEFAULT_REGISTER_PROVIDER_KEYS;
import static org.apache.dubbo.rpc.Constants.DEPRECATED_KEY;
@ -201,7 +206,22 @@ public class ServiceInstanceMetadataUtils {
LOGGER.info("Start registering instance address to registry.");
RegistryManager registryManager = applicationModel.getBeanFactory().getBean(RegistryManager.class);
// register service instance
registryManager.getServiceDiscoveries().forEach(ServiceDiscovery::register);
List<ServiceDiscovery> serviceDiscoveries = registryManager.getServiceDiscoveries();
for (ServiceDiscovery serviceDiscovery : serviceDiscoveries) {
MetricsEventBus.post(RegistryEvent.toRegisterEvent(applicationModel,
Collections.singletonList(getServiceDiscoveryName(serviceDiscovery))),
() -> {
// register service instance
serviceDiscoveries.forEach(ServiceDiscovery::register);
return null;
}
);
}
}
private static String getServiceDiscoveryName(ServiceDiscovery serviceDiscovery) {
return serviceDiscovery.getUrl().getParameter(RegistryConstants.REGISTRY_CLUSTER_KEY,
serviceDiscovery.getUrl().getParameter(REGISTRY_KEY));
}
public static void refreshMetadataAndInstance(ApplicationModel applicationModel) {

View File

@ -19,6 +19,7 @@ package org.apache.dubbo.registry.integration;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.URLBuilder;
import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
import org.apache.dubbo.common.constants.RegistryConstants;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
import org.apache.dubbo.common.logger.LoggerFactory;
@ -33,6 +34,7 @@ import org.apache.dubbo.common.utils.UrlUtils;
import org.apache.dubbo.metrics.event.MetricsEventBus;
import org.apache.dubbo.metrics.registry.event.RegistryEvent;
import org.apache.dubbo.registry.AddressListener;
import org.apache.dubbo.registry.Registry;
import org.apache.dubbo.remoting.Constants;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.Protocol;
@ -62,6 +64,7 @@ import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.DISABLED_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_PROTOCOL;
import static org.apache.dubbo.common.constants.CommonConstants.ENABLED_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_REGISTER_MODE;
import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.SIDE_KEY;
import static org.apache.dubbo.common.constants.LoggerCodeConstants.PROTOCOL_FAILED_INIT_SERIALIZATION_OPTIMIZER;
@ -79,6 +82,8 @@ import static org.apache.dubbo.common.constants.RegistryConstants.DEFAULT_HASHMA
import static org.apache.dubbo.common.constants.RegistryConstants.DYNAMIC_CONFIGURATORS_CATEGORY;
import static org.apache.dubbo.common.constants.RegistryConstants.EMPTY_PROTOCOL;
import static org.apache.dubbo.common.constants.RegistryConstants.PROVIDERS_CATEGORY;
import static org.apache.dubbo.common.constants.RegistryConstants.REGISTER_MODE_KEY;
import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_KEY;
import static org.apache.dubbo.common.constants.RegistryConstants.ROUTERS_CATEGORY;
import static org.apache.dubbo.common.constants.RegistryConstants.ROUTE_PROTOCOL;
import static org.apache.dubbo.registry.Constants.CONFIGURATORS_SUFFIX;
@ -130,7 +135,8 @@ public class RegistryDirectory<T> extends DynamicDirectory<T> {
}
ApplicationModel applicationModel = url.getApplicationModel();
MetricsEventBus.post(RegistryEvent.toSubscribeEvent(applicationModel), () ->
String registryClusterName = registry.getUrl().getParameter(RegistryConstants.REGISTRY_CLUSTER_KEY, registry.getUrl().getParameter(PROTOCOL_KEY));
MetricsEventBus.post(RegistryEvent.toSubscribeEvent(applicationModel,registryClusterName), () ->
{
super.subscribe(url);
return null;
@ -644,6 +650,18 @@ public class RegistryDirectory<T> extends DynamicDirectory<T> {
return false;
}
@Override
protected Map<String, String> getDirectoryMeta() {
String registryKey = Optional.ofNullable(getRegistry())
.map(Registry::getUrl)
.map(url -> url.getParameter(RegistryConstants.REGISTRY_CLUSTER_KEY, url.getProtocol()))
.orElse("unknown");
Map<String, String> metas = new HashMap<>();
metas.put(REGISTRY_KEY, registryKey);
metas.put(REGISTER_MODE_KEY, INTERFACE_REGISTER_MODE);
return metas;
}
private boolean isNotCompatibleFor26x(URL url) {
return StringUtils.isEmpty(url.getParameter(COMPATIBLE_CONFIG_KEY));
}

View File

@ -18,6 +18,7 @@ package org.apache.dubbo.registry.integration;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
import org.apache.dubbo.common.constants.RegistryConstants;
import org.apache.dubbo.common.deploy.ApplicationDeployer;
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
import org.apache.dubbo.common.logger.LoggerFactory;
@ -29,6 +30,8 @@ import org.apache.dubbo.common.utils.ConcurrentHashSet;
import org.apache.dubbo.common.utils.NamedThreadFactory;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.common.utils.UrlUtils;
import org.apache.dubbo.metrics.event.MetricsEventBus;
import org.apache.dubbo.metrics.registry.event.RegistryEvent;
import org.apache.dubbo.registry.NotifyListener;
import org.apache.dubbo.registry.Registry;
import org.apache.dubbo.registry.RegistryFactory;
@ -61,9 +64,11 @@ import org.apache.dubbo.rpc.protocol.InvokerWrapper;
import org.apache.dubbo.rpc.support.ProtocolUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@ -224,7 +229,16 @@ public class RegistryProtocol implements Protocol, ScopeModelAware {
ApplicationDeployer deployer = registeredProviderUrl.getOrDefaultApplicationModel().getDeployer();
try {
deployer.increaseServiceRefreshCount();
registry.register(registeredProviderUrl);
String registryName = Optional.ofNullable(registry.getUrl())
.map(u -> u.getParameter(RegistryConstants.REGISTRY_CLUSTER_KEY,
UrlUtils.isServiceDiscoveryURL(u) ? u.getParameter(REGISTRY_KEY) : u.getProtocol()))
.filter(StringUtils::isNotEmpty)
.orElse("unknown");
MetricsEventBus.post(RegistryEvent.toRsEvent(registeredProviderUrl.getApplicationModel(), registeredProviderUrl.getServiceKey(), 1, Collections.singletonList(registryName)),
() -> {
registry.register(registeredProviderUrl);
return null;
});
} finally {
deployer.decreaseServiceRefreshCount();
}