apache / dubbo

The java implementation of Apache Dubbo. An RPC and microservice framework.
https://dubbo.apache.org/
Apache License 2.0
40.39k stars 26.41k forks source link

When MonitorFilter invoked for the first time, no statistics is collected #7181

Open zhangyz-hd opened 3 years ago

zhangyz-hd commented 3 years ago

Environment

Steps to reproduce this issue

  1. Implements OopsMonitor and OopsMonitorFactory (extends AbstractMonitorFactory), and add to SPI configuration file.
    oops=org.apache.dubbo.demo.monitor.OopsMonitorFactory
  2. Run a provider and a consumer, use oops monitor.
    dubbo.monitor.address=oops://127.0.0.1
  3. Let consumer call provider's service, "org.apache.dubbo.demo.monitor.OopsMonitor#collect" is not executed at the first service call.

Reproduce this issue:

https://github.com/zhangyz-hd/dubbo-issues/tree/main/7181

Reason:

AbstractMonitorFactory#createMonitor() is executed asynchronously, so AbstractMonitorFactory#getMonitor() always return null for the first time.

    @Override
    public Monitor getMonitor(URL url) {
        url = url.setPath(MonitorService.class.getName()).addParameter(INTERFACE_KEY, MonitorService.class.getName());
        String key = url.toServiceStringWithoutResolving();
        Monitor monitor = MONITORS.get(key);
        Future<Monitor> future = FUTURES.get(key);
        if (monitor != null || future != null) {
            return monitor;
        }

        LOCK.lock();
        try {
            monitor = MONITORS.get(key);
            future = FUTURES.get(key);
            if (monitor != null || future != null) {
                return monitor;
            }

            final URL monitorUrl = url;
            final CompletableFuture<Monitor> completableFuture = CompletableFuture.supplyAsync(() -> AbstractMonitorFactory.this.createMonitor(monitorUrl));
            FUTURES.put(key, completableFuture);
            completableFuture.thenRunAsync(new MonitorListener(key), EXECUTOR);

            return null; //<-HERE(≧∇≦)
        } finally {
            // unlock
            LOCK.unlock();
        }
    }

Consumer Log:

[08/02/21 10:21:37:185 CST] main  INFO consumer.Consumer:  [DUBBO] ROUND=1, result=Hello world, response from provider: 192.168.3.41:20881, dubbo version: 2.7.8, current host: 192.168.3.41
[08/02/21 10:21:38:194 CST] main  INFO monitor.OopsMonitor:  [DUBBO] Oops~collect:ROUND=2, dubbo version: 2.7.8, current host: 192.168.3.41
[08/02/21 10:21:38:194 CST] main  INFO consumer.Consumer:  [DUBBO] ROUND=2, result=Hello world, response from provider: 192.168.3.41:20881, dubbo version: 2.7.8, current host: 192.168.3.41
[08/02/21 10:21:39:201 CST] main  INFO monitor.OopsMonitor:  [DUBBO] Oops~collect:ROUND=3, dubbo version: 2.7.8, current host: 192.168.3.41
[08/02/21 10:21:39:201 CST] main  INFO consumer.Consumer:  [DUBBO] ROUND=3, result=Hello world, response from provider: 192.168.3.41:20881, dubbo version: 2.7.8, current host: 192.168.3.41
[08/02/21 10:21:40:208 CST] main  INFO monitor.OopsMonitor:  [DUBBO] Oops~collect:ROUND=4, dubbo version: 2.7.8, current host: 192.168.3.41
[08/02/21 10:21:40:208 CST] main  INFO consumer.Consumer:  [DUBBO] ROUND=4, result=Hello world, response from provider: 192.168.3.41:20881, dubbo version: 2.7.8, current host: 192.168.3.41
[08/02/21 10:21:41:212 CST] main  INFO monitor.OopsMonitor:  [DUBBO] Oops~collect:ROUND=5, dubbo version: 2.7.8, current host: 192.168.3.41
[08/02/21 10:21:41:212 CST] main  INFO consumer.Consumer:  [DUBBO] ROUND=5, result=Hello world, response from provider: 192.168.3.41:20881, dubbo version: 2.7.8, current host: 192.168.3.41
zhangyz-hd commented 3 years ago

fix at #7191

xiaonayue commented 1 year ago

assign to me