[apache/dubbo]如何监控服务不可用?

2024-05-30 807 views
2

有想过用回声测试,但要拿到所有需要监控的引用,有没有更灵活的办法?

回答

8

要拿到所有被监控的引用,这个也不难吧,你看看AbstractDirectory类里面有个方法:

    public List<Invoker<T>> list(Invocation invocation) throws RpcException {
        if (destroyed){
            throw new RpcException("Directory already destroyed .url: "+ getUrl());
        }
        List<Invoker<T>> invokers = doList(invocation);
        List<Router> localRouters = this.routers; // local reference
        if (localRouters != null && localRouters.size() > 0) {
            for (Router router: localRouters){
                try {
                    if (router.getUrl() == null || router.getUrl().getParameter(Constants.RUNTIME_KEY, true)) {
                        invokers = router.route(invokers, getConsumerUrl(), invocation);
                    }
                } catch (Throwable t) {
                    logger.error("Failed to execute router: " + getUrl() + ", cause: " + t.getMessage(), t);
                }
            }
        }
        return invokers;
    }

通过这个方法拿到所有的Invoker,你看里面有一个for循环,里面有个判断,在判断里面加上这段半段代码,就可以拿到监控的:

invoker.getUrl().hasParameter(Constants.MONITOR_KEY)
6

Dubbo自身不是就有服务调用时输出异常日志的吗?监控日志不行吗?如果要主动发现,也可以用定时器去轮训。 如果要在调用过程中发现不可用的话看看这个类com.alibaba.dubbo.monitor.support.MonitorFilter

    // 调用过程拦截
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        if (invoker.getUrl().hasParameter(Constants.MONITOR_KEY)) {
            RpcContext context = RpcContext.getContext(); // 提供方必须在invoke()之前获取context信息
            long start = System.currentTimeMillis(); // 记录起始时间戮
            getConcurrent(invoker, invocation).incrementAndGet(); // 并发计数
            try {
                Result result = invoker.invoke(invocation); // 让调用链往下执行
                collect(invoker, invocation, result, context, start, false);
                return result;
            } catch (RpcException e) {
                collect(invoker, invocation, null, context, start, true);
                throw e;
            } finally {
                getConcurrent(invoker, invocation).decrementAndGet(); // 并发计数
            }
        } else {
            return invoker.invoke(invocation);
        }
    }

这里面有异常捕获,你在catch中可以做一些告警操作,或者自己实现一个filter去监控;

最近在dubbo中集成Hystrix做熔断器,可以动态控制服务的可用性,hystrix有一个管理平台也可以看到所有调用的统计情况

7

要拿到所有需要监控的引用 可以 订阅 RegistryService通知,自己维护所有要监控服务的cache,基于这个cache去做回声测试。

2

@qct 你好,RegistryService会通知到listener,这个需要自己实现一个NotifyListener,在notify方法里来维护服务的变更cache对吗?

2

@zylele 是的。 实现 NotifyListener 接收通知维护缓存 可以参考 RegistryServerSync

或者这里(打个广告,嘿嘿): RegistryServerSync

8

@qct 哈哈好巧我就说头像很眼熟,我就是在看dubbokeeper的这个类的服务cache维护的,你就是这个项目作者吧?多谢多谢!

2

@zylele 作者是 bieber 我只是暂时在维护

5

@qct 看了下dubbokeeper项目,挺好的啊,star一下 ^_^