微服务框架(十五)Dubbo 超时机制及服务降级

简介: 此系列文章将会描述Java框架Spring Boot、服务治理框架Dubbo、应用容器引擎Docker,及使用Spring Boot集成Dubbo、Mybatis等开源框架,其中穿插着Spring Boot中日志切面等技术的实现,然后通过gitlab-CI以持续集成为Docker镜像。 本文为Dubbo超时机制及服务降级当服务出现创建超时的时候,TimeoutFilter会打印该创建记录的详细信息,日志级别为WARN,即为可恢复异常,或瞬时的状态不一致

  此系列文章将会描述Java框架Spring Boot、服务治理框架Dubbo、应用容器引擎Docker,及使用Spring Boot集成Dubbo、Mybatis等开源框架,其中穿插着Spring Boot中日志切面等技术的实现,然后通过gitlab-CI以持续集成为Docker镜像。
  本文为Dubbo超时机制及服务降级

本系列文章中所使用的框架版本为Spring Boot 2.0.3-RELEASE,Spring 5.0.7-RELEASE,Dubbo 2.6.2。

生产者超时机制

创建超时

当服务出现创建超时的时候,TimeoutFilter会打印该创建记录的详细信息,日志级别为WARN,即为可恢复异常,或瞬时的状态不一致

/**
 * Log any invocation timeout, but don't stop server from running
 */
@Activate(group = Constants.PROVIDER)
public class TimeoutFilter implements Filter {
   
   

    private static final Logger logger = LoggerFactory.getLogger(TimeoutFilter.class);

    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
   
   
        long start = System.currentTimeMillis();
        Result result = invoker.invoke(invocation);
        long elapsed = System.currentTimeMillis() - start;
        if (invoker.getUrl() != null
                && elapsed > invoker.getUrl().getMethodParameter(invocation.getMethodName(),
                "timeout", Integer.MAX_VALUE)) {
   
   
            if (logger.isWarnEnabled()) {
   
   
                logger.warn("invoke time out. method: " + invocation.getMethodName()
                        + " arguments: " + Arrays.toString(invocation.getArguments()) + " , url is "
                        + invoker.getUrl() + ", invoke elapsed " + elapsed + " ms.");
            }
        }
        return result;
    }

}

线程池满载

当业务线程池满载,且没设置线程池队列时,AbortPolicyWithReport会打印线程池的详细信息,日志级别为WARN,并dump出十分钟内的堆栈信息

[WARN] [2018-12-16 22:06:00][com.alibaba.dubbo.common.threadpool.support.AbortPolicyWithReport] [DUBBO] Thread pool is EXHAUSTED! Thread Name: DubboServerHandler-127.0.0.1:9000, Pool Size: 10 (active: 10, core: 10, max: 10, largest: 10), Task: 3350 (completed: 3340), Executor status:(isShutdown:false, isTerminated:false, isTerminating:false), in dubbo://127.0.0.1:9000!, dubbo version: 2.6.2, current host: 127.0.0.1

建议不要设置线程池队列,当线程程池时应立即失败

消费者超时机制

Dubbo默认采用了netty作为网络组件,它属于NIO的模式。消费者发起远程请求后,线程不会阻塞等待服务端的返回,而是马上得到一个ResponseFuture,消费端通过不断的轮询机制判断结果是否有返回。

DefaultFuture实现了ResponseFuture接口,在NIO(Non-blocking IO)Channel中轮循获取结果。当请求超时或抛出中断异常(InterruptedException)时,对外抛出TimeoutException

//DefaultFuture#get()
@Override
public Object get(int timeout) throws RemotingException {
   
   
    if (timeout <= 0) {
   
   
        timeout = Constants.DEFAULT_TIMEOUT;
    }
    if (!isDone()) {
   
   
        long start = System.currentTimeMillis();
        lock.lock();
        try {
   
   
            while (!isDone()) {
   
   
                done.await(timeout, TimeUnit.MILLISECONDS);
                if (isDone() || System.currentTimeMillis() - start > timeout) {
   
   
                    break;
                }
            }
        } catch (InterruptedException e) {
   
   
            throw new RuntimeException(e);
        } finally {
   
   
            lock.unlock();
        }
        if (!isDone()) {
   
   
            throw new TimeoutException(sent > 0, channel, getTimeoutMessage(false));
        }
    }
    return returnFromResponse();
}

超时配置及优先级

超时配置

建议Provider 上尽量多配置 Consumer 端属性

  • 作服务的提供者,比服务使用方更清楚服务性能参数,如调用的超时时间、合理的重试次数等
  • 在 Provider 配置后,Consumer 不配置则会使用 Provider 的配置值,即 Provider 配置可以作为 Consumer 的缺省值。否则,Consumer 会使用 Consumer 端的全局设置,这对于 Provider 是不可控的,并且往往是不合理的
  • Provider 上尽量多配置 Consumer 端的属性,让 Provider 实现者一开始就思考 Provider 服务特点、服务质量等问题。

配置覆盖关系

以 timeout 为例,显示了配置的查找顺序,其它 retries, loadbalance, actives 等类似:(详见官方文档)

  • 方法级优先,接口级次之,全局配置再次之。
  • 如果级别一样,则消费方优先,提供方次之。

其中,服务提供方配置,通过 URL 经由注册中心传递给消费方。

服务降级

  • 可以通过服务降级功能,临时屏蔽某个出错的非关键服务,并定义降级后的返回策略。
  • 当整个微服务架构整体的负载超出了预设的上限阈值或即将到来的流量预计将会超过预设的阈值时,为了保证重要或基本的服务能正常运行,我们可以将一些不重要不紧急的服务或任务进行服务的延迟使用暂停使用

在Dubbo服务中配置dubbo.service.mock = fail:return+null,当消费方对该服务的方法调用在失败后,再返回null值,不抛异常。用来容忍不重要服务不稳定时对调用方的影响。


参考资料:

  1. dubbo源码分析(二):超时原理以及应用场景
  2. Dubbo推荐用法
  3. Dubbo线程模型
  4. Dubbo服务降级
  5. 微服务架构—服务降级
相关文章
|
3天前
|
存储 负载均衡 数据库
探索微服务架构中的服务发现机制
【7月更文挑战第24天】在微服务架构的复杂网络中,服务发现是确保通信流畅与系统弹性的关键组件。本文将深入探讨服务发现的工作原理、面临的挑战以及解决方案,同时比较不同服务发现工具的性能特点,旨在为开发者提供实现高效服务发现的实战指南。
|
3天前
|
敏捷开发 设计模式 负载均衡
深入理解微服务架构中的服务发现与注册机制
【7月更文挑战第24天】在微服务架构的海洋中,服务发现与注册机制如同灯塔指引着航行的船只。本文将探索这一机制的重要性、实现原理以及面临的挑战,带领读者领略微服务架构中的关键导航系统。
|
8天前
|
存储 负载均衡 开发者
深入理解微服务架构中的服务发现机制
【7月更文挑战第19天】在微服务架构的海洋中,服务发现是一艘至关重要的航船,它指引着各个微服务之间的通信与协作。本文将揭开服务发现的神秘面纱,探索其工作原理、实现方式及面临的挑战,为开发者提供清晰的导航,确保服务间的顺畅航行。
|
7天前
|
敏捷开发 设计模式 监控
探索微服务架构中的服务发现机制
【7月更文挑战第20天】在微服务架构的海洋中,服务发现是一艘必不可少的航船,它指引着各个服务如何相互寻觅和沟通。本文将深入探讨服务发现的核心原理、主流解决方案以及在实际应用中的考量因素,为构建高效、稳定的微服务系统提供导航。
16 2
|
11天前
|
消息中间件 负载均衡 网络协议
探索微服务架构中的服务通信模式
【7月更文挑战第16天】在微服务架构的海洋中,服务间的通信宛如细丝相连,维系着整个系统的协同与和谐。本文将深入探讨微服务之间如何通过同步与异步通信模式进行交互,并剖析这些模式背后的技术原理及其对系统性能和可扩展性的影响。我们将从理论到实践,一探究竟。
49 6
|
12天前
|
负载均衡 监控 Kubernetes
Service Mesh 是一种用于处理服务间通信的基础设施层,它通常与微服务架构一起使用,以提供诸如服务发现、负载均衡、熔断、监控、追踪和安全性等功能。
Service Mesh 是一种用于处理服务间通信的基础设施层,它通常与微服务架构一起使用,以提供诸如服务发现、负载均衡、熔断、监控、追踪和安全性等功能。
|
11天前
|
Kubernetes Cloud Native Java
从一个服务预热不生效问题谈微服务无损上线
本文基于阿里云技术服务团队和产研团队,在解决易易互联使用 MSE(微服务引擎)产品无损上线功能所遇到问题的过程总结而成。本文将从问题和解决方法谈起,再介绍相关原理,后进一步拓展到对微服务引擎和云原生网关无损上线能力的介绍。
11618 2
|
12天前
|
消息中间件 API 数据库
在微服务架构中,每个服务通常都是一个独立运行、独立部署、独立扩展的组件,它们之间通过轻量级的通信机制(如HTTP/RESTful API、gRPC等)进行通信。
在微服务架构中,每个服务通常都是一个独立运行、独立部署、独立扩展的组件,它们之间通过轻量级的通信机制(如HTTP/RESTful API、gRPC等)进行通信。
|
7天前
|
敏捷开发 存储 设计模式
探索微服务架构中的服务发现与注册机制
在微服务架构的复杂网络中,服务的发现与注册是确保高效通信的关键。本文将深入剖析服务发现与注册的核心原理、主流技术实现及其在现代后端系统中的应用,旨在为开发者提供一套实践指南,以应对动态变化的云环境挑战。 【7月更文挑战第20天】
11 0
|
4天前
|
Kubernetes 持续交付 开发者
探索后端技术的未来:微服务架构与容器化部署的融合
在数字化时代的浪潮中,后端技术正经历着前所未有的变革。本文将深入探讨微服务架构和容器化部署如何共同推动后端技术的发展,提升应用的性能、可扩展性和可靠性。通过分析现代软件开发的需求,我们将揭示这两种技术如何互补,以及它们在未来后端开发中的潜力和挑战。

热门文章

最新文章