千家信息网

dubbo中MetadataReportService的原理及作用

发表于:2025-02-02 作者:千家信息网编辑
千家信息网最后更新 2025年02月02日,本篇内容介绍了"dubbo中MetadataReportService的原理及作用"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望
千家信息网最后更新 2025年02月02日dubbo中MetadataReportService的原理及作用

本篇内容介绍了"dubbo中MetadataReportService的原理及作用"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

本文主要研究一下dubbo的MetadataReportService

MetadataReportService

dubbo-2.7.2/dubbo-metadata-report/dubbo-metadata-report-api/src/main/java/org/apache/dubbo/metadata/integration/MetadataReportService.java

public class MetadataReportService {    protected final Logger logger = LoggerFactory.getLogger(getClass());    private static volatile MetadataReportService metadataReportService;    private static Object lock = new Object();    private MetadataReportFactory metadataReportFactory = ExtensionLoader.getExtensionLoader(MetadataReportFactory.class).getAdaptiveExtension();    MetadataReport metadataReport;    URL metadataReportUrl;    MetadataReportService(URL metadataReportURL) {        if (METADATA_REPORT_KEY.equals(metadataReportURL.getProtocol())) {            String protocol = metadataReportURL.getParameter(METADATA_REPORT_KEY, DEFAULT_DIRECTORY);            metadataReportURL = URLBuilder.from(metadataReportURL)                    .setProtocol(protocol)                    .removeParameter(METADATA_REPORT_KEY)                    .build();        }        this.metadataReportUrl = metadataReportURL;        metadataReport = metadataReportFactory.getMetadataReport(this.metadataReportUrl);    }    public static MetadataReportService instance(Supplier metadataReportUrl) {        if (metadataReportService == null) {            synchronized (lock) {                if (metadataReportService == null) {                    URL metadataReportURLTmp = metadataReportUrl.get();                    if (metadataReportURLTmp == null) {                        return null;                    }                    metadataReportService = new MetadataReportService(metadataReportURLTmp);                }            }        }        return metadataReportService;    }    public void publishProvider(URL providerUrl) throws RpcException {        //first add into the list        // remove the individul param        providerUrl = providerUrl.removeParameters(PID_KEY, TIMESTAMP_KEY, Constants.BIND_IP_KEY, Constants.BIND_PORT_KEY, TIMESTAMP_KEY);        try {            String interfaceName = providerUrl.getParameter(INTERFACE_KEY);            if (StringUtils.isNotEmpty(interfaceName)) {                Class interfaceClass = Class.forName(interfaceName);                FullServiceDefinition fullServiceDefinition = ServiceDefinitionBuilder.buildFullDefinition(interfaceClass, providerUrl.getParameters());                metadataReport.storeProviderMetadata(new MetadataIdentifier(providerUrl.getServiceInterface(),                        providerUrl.getParameter(VERSION_KEY), providerUrl.getParameter(GROUP_KEY),                        PROVIDER_SIDE, providerUrl.getParameter(APPLICATION_KEY)), fullServiceDefinition);                return;            }            logger.error("publishProvider interfaceName is empty . providerUrl: " + providerUrl.toFullString());        } catch (ClassNotFoundException e) {            //ignore error            logger.error("publishProvider getServiceDescriptor error. providerUrl: " + providerUrl.toFullString(), e);        }    }    public void publishConsumer(URL consumerURL) throws RpcException {        consumerURL = consumerURL.removeParameters(PID_KEY, TIMESTAMP_KEY, Constants.BIND_IP_KEY, Constants.BIND_PORT_KEY, TIMESTAMP_KEY);        metadataReport.storeConsumerMetadata(new MetadataIdentifier(consumerURL.getServiceInterface(),                consumerURL.getParameter(VERSION_KEY), consumerURL.getParameter(GROUP_KEY), CONSUMER_SIDE,                consumerURL.getParameter(APPLICATION_KEY)), consumerURL.getParameters());    }}
  • MetadataReportService的构造器通过metadataReportURL来获取对应的MetadataReport;它定义了publishProvider方法主要是执行metadataReport.storeProviderMetadata方法;还定义了publishConsumer方法主要是执行metadataReport.storeConsumerMetadata方法;同时还提供了一个静态方法使用双重检锁的单例模式创建MetadataReportService

实例

dubbo-2.7.2/dubbo-metadata-report/dubbo-metadata-report-api/src/test/java/org/apache/dubbo/metadata/integration/MetadataReportServiceTest.java

public class MetadataReportServiceTest {    URL url = URL.valueOf("JTest://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.TestService?version=1.0.0&application=vic");    MetadataReportService metadataReportService1;    @BeforeEach    public void before() {        metadataReportService1 = MetadataReportService.instance(() -> url);    }    @Test    public void testInstance() {        MetadataReportService metadataReportService2 = MetadataReportService.instance(new Supplier() {            @Override            public URL get() {                return url;            }        });        Assertions.assertSame(metadataReportService1, metadataReportService2);        Assertions.assertEquals(metadataReportService1.metadataReportUrl, url);    }    @Test    public void testPublishProviderNoInterfaceName() {        URL publishUrl = URL.valueOf("dubbo://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.TestService?version=1.0.0&application=vicpubprovder&side=provider");        metadataReportService1.publishProvider(publishUrl);        Assertions.assertTrue(metadataReportService1.metadataReport instanceof JTestMetadataReport4Test);        JTestMetadataReport4Test jTestMetadataReport4Test = (JTestMetadataReport4Test) metadataReportService1.metadataReport;        Assertions.assertTrue(!jTestMetadataReport4Test.store.containsKey(JTestMetadataReport4Test.getProviderKey(publishUrl)));    }    @Test    public void testPublishProviderWrongInterface() {        URL publishUrl = URL.valueOf("dubbo://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.TestService?version=1.0.0&application=vicpu&interface=ccc&side=provider");        metadataReportService1.publishProvider(publishUrl);        Assertions.assertTrue(metadataReportService1.metadataReport instanceof JTestMetadataReport4Test);        JTestMetadataReport4Test jTestMetadataReport4Test = (JTestMetadataReport4Test) metadataReportService1.metadataReport;        Assertions.assertTrue(!jTestMetadataReport4Test.store.containsKey(JTestMetadataReport4Test.getProviderKey(publishUrl)));    }    @Test    public void testPublishProviderContainInterface() throws InterruptedException {        URL publishUrl = URL.valueOf("dubbo://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.TestService?version=1.0.3&application=vicpubp&interface=org.apache.dubbo.metadata.integration.InterfaceNameTestService&side=provider");        metadataReportService1.publishProvider(publishUrl);        Thread.sleep(300);        Assertions.assertTrue(metadataReportService1.metadataReport instanceof JTestMetadataReport4Test);        JTestMetadataReport4Test jTestMetadataReport4Test = (JTestMetadataReport4Test) metadataReportService1.metadataReport;        Assertions.assertTrue(jTestMetadataReport4Test.store.containsKey(JTestMetadataReport4Test.getProviderKey(publishUrl)));        String value = jTestMetadataReport4Test.store.get(JTestMetadataReport4Test.getProviderKey(publishUrl));        FullServiceDefinition fullServiceDefinition = toServiceDefinition(value);        Map map = fullServiceDefinition.getParameters();        Assertions.assertEquals(map.get("application"), "vicpubp");        Assertions.assertEquals(map.get("version"), "1.0.3");        Assertions.assertEquals(map.get("interface"), "org.apache.dubbo.metadata.integration.InterfaceNameTestService");    }    @Test    public void testPublishConsumer() throws InterruptedException {        URL publishUrl = URL.valueOf("dubbo://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.TestService?version=1.0.x&application=vicpubconsumer&side=consumer");        metadataReportService1.publishConsumer(publishUrl);        Thread.sleep(300);        Assertions.assertTrue(metadataReportService1.metadataReport instanceof JTestMetadataReport4Test);        JTestMetadataReport4Test jTestMetadataReport4Test = (JTestMetadataReport4Test) metadataReportService1.metadataReport;        Assertions.assertTrue(jTestMetadataReport4Test.store.containsKey(JTestMetadataReport4Test.getConsumerKey(publishUrl)));        String value = jTestMetadataReport4Test.store.get(JTestMetadataReport4Test.getConsumerKey(publishUrl));        Gson gson = new Gson();        Map map = gson.fromJson(value, Map.class);        Assertions.assertEquals(map.get("application"), "vicpubconsumer");        Assertions.assertEquals(map.get("version"), "1.0.x");    }    private FullServiceDefinition toServiceDefinition(String urlQuery) {        Gson gson = new Gson();        return gson.fromJson(urlQuery, FullServiceDefinition.class);    }}
  • 这里的testInstance方法验证了单例模式;之后对publishProvider验证了noInterfaceName、wrongInterface、containInterface的场景;最后验证了publishConsumer

小结

MetadataReportService的构造器通过metadataReportURL来获取对应的MetadataReport;它定义了publishProvider方法主要是执行metadataReport.storeProviderMetadata方法;还定义了publishConsumer方法主要是执行metadataReport.storeConsumerMetadata方法;同时还提供了一个静态方法使用双重检锁的单例模式创建MetadataReportService

"dubbo中MetadataReportService的原理及作用"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

0