【问题标题】:Initial call on ServiceFabric proxy is VERY slowServiceFabric 代理的初始调用非常慢
【发布时间】:2017-10-13 06:43:30
【问题描述】:

每当我从另一个调用一个服务结构服务时,代理上的第一个调用非常慢,即比所有后续调用慢 100 倍。我已经在调用前的时间记录中记录了时间,然后在被调用的服务方法中立即记录了时间,这很容易超过 60 秒!服务结构集群是在 12 个节点/VM 上运行的独立集群。

有趣的是,第一次调用的时间长度似乎与节点的数量有关,即如果我停用一半的节点,时间会减少(尽管不是一半)。此外,当在我的本地 PC 上运行的开发集群上运行完全相同的代码时,第一次调用的时间长度通常约为 8 秒,随后的调用在任一系统上的时间都小于 10 毫秒。此外,在同一个客户端进程中为同一个服务创建另一个代理仍然会导致快速调用时间,似乎代理工厂(我相信 SF 缓存每个客户端进程)是在第一次使用代理时创建的,并采取很长一段时间。

有趣的是,没有抛出异常并且服务确实有效!

所以我的问题是,为什么第一次在使用 ServiceProxy.Create() 创建的代理上从一个服务调用另一个服务需要这么长时间?

【问题讨论】:

    标签: performance proxy azure-service-fabric


    【解决方案1】:

    根据The SF remoting docs(见下文,强调我的),ServiceProxy.Create 是对 ServiceProxyFactory 的包装,第一次调用还涉及为后续调用设置工厂。

    ServiceProxyFactory 是一个为不同的远程接口创建代理的工厂。 如果您使用 API ServiceProxy.Create 创建代理,则框架会创建单例 ServiceProxyFactory。 当您需要覆盖 IServiceRemotingClientFactory 属性时,手动创建一个很有用。工厂是一项昂贵的操作。 ServiceProxyFactory 维护通信客户端的缓存。最佳做法是尽可能长时间地缓存 ServiceProxyFactory。

    【讨论】:

      【解决方案2】:

      我没有遇到过像您所拥有的那样缓慢的解决方案,但是当我的 API 服务使用依赖注入启动时,我会创建代理。

      我的系统设置方式是无状态 API 服务(asp.net 核心)与后端 SF 服务通信。

      实际上我可能遇到了更长的延迟,但是当我开始使用应用程序时,解决过程已经开始并完成,而不是在我向应用程序发出第一个请求时开始解决。

          private void InitializeContainer(IApplicationBuilder app)
          {
              // Add application presentation components:
              Container.RegisterMvcControllers(app);
              Container.RegisterMvcViewComponents(app);
      
              // Add application services.
              Container.Register(() => ServiceProxy.Create<IContestService>(FabricUrl.ContestService), Lifestyle.Transient);
              Container.Register(() => ServiceProxy.Create<IFriendService>(FabricUrl.FriendService), Lifestyle.Transient);
              Container.Register(() => ServiceProxy.Create<IUserService>(FabricUrl.UserService), Lifestyle.Transient);
              Container.Register(() => ServiceProxy.Create<IBillingService>(FabricUrl.BillingService), Lifestyle.Transient);
              Container.RegisterSingleton(AutoMapperApi.Configure());
      
              // Cross-wire ASP.NET services (if any). For instance:
              Container.RegisterSingleton(app.ApplicationServices.GetService<ILoggerFactory>());
              // NOTE: Prevent cross-wired instances as much as possible.
              // See: https://simpleinjector.org/blog/2016/07/
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-03-27
        • 1970-01-01
        • 1970-01-01
        • 2011-02-24
        • 2011-10-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多