[apache/dubbo]通过@DubboReference方式注入服务,如何提前完成初始化工作,避免服务接口首次调用出现耗时较久的问题。

2024-06-24 29 views
0
@Configuration
public class ReferenceConfiguration {

    @Bean
    @DubboReference(interfaceClass = IdGeneratorService.Iface.class, version = "1.0", timeout = 5000, init = true, lazy = false)
    public ReferenceBean<IdGeneratorService.Iface> idGeneratorService() {
        return new ReferenceBean<IdGeneratorService.Iface>();
    }

}

如上配置,并没有解决首次调用慢的问题(注:服务为thrift协议)

回答

2

首次调用还涉及了类加载等过程,如果要从根本上避免首次调用慢可以自己加些预热

2

我看3.0版本ReferenceBean的getObject方法引入了lazyProxy概念,而不是像2.7版本直接调用get(),是不是目前官方没有提供提前预热的能力了?

3

lazyProxy 只是订阅是否是 lazy 创建的,本身是为了解决循环依赖的问题。预热还是要独立做的

8

能不能提供点思路,需要预热哪些东西,怎么预热?

1

这样没办法处理服务的上下线或缩扩容。 A 依赖B服务,但A启动时B还没启动完成,如何监听B上线呢,因为B上线时A需要预热

2

那就是服务端的预热了,可以用 local 订阅

4

接口调用前,先进行了下面的动作:

    @Bean
    @DubboReference(interfaceClass = IdGeneratorService.Iface.class, version = "1.0", timeout = 5000, init = true, lazy = false)
    public ReferenceBean<IdGeneratorService.Iface> idGeneratorService() {
        return new ReferenceBean<IdGeneratorService.Iface>();
    }

    @Bean
    public IdGeneratorService.Iface initIdGeneratorService(ReferenceBean<IdGeneratorService.Iface> idGeneratorService) {
        IdGeneratorService.Iface initedId = idGeneratorService.getObject(); 
        idGeneratorService.getReferenceConfig().setCheck(false);
        idGeneratorService.getReferenceConfig().get();      
        return initedId;
    }

后面通过下面方式注入

    @Autowired
    private IdGeneratorService.Iface initIdGeneratorService;

首次进行接口调用的时候,耗时有大幅缩减,但是相较于后续的调用,还是大概多耗时100ms,请指点下,这部分差距在进行什么动作,如何预热?

7

目前看来,可能导致首次调用慢的因素有两个:

  1. lazy proxy 导致首次调用发生时才启动个订阅动作。这个问题看起来你已经解决了
  2. 另一个可能是 provider 侧自身需要预热

具体需要依赖你那边再分析一下耗时发生在了哪个位置。

8

现象上看不像是 provider 侧,A调用B,重启B,重启后A请求B的第一次,同样会出现耗时久的现象。

9

首次请求会触发建连,可以网络抓下包看看用了多久