有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Spring引导冷启动

我有一个SpringBoot应用程序,它运行在openshift集群中的docker容器中。在稳定状态下,有N个应用程序实例(假设N=5),请求的负载平衡到这N个实例。一切运行正常,响应时间较低(总吞吐量约为60k,响应时间约为5ms)

每当我添加一个新实例时,响应时间会短暂增加(高达~70毫秒),然后恢复正常

我能做些什么来避免这种冷启动?在发送流量之前,我尝试通过连续拨打约100个curl电话来预热应用程序,但这没有帮助

我需要更好的高并发预热脚本吗?有没有更好的方法来处理这个问题

谢谢


共 (3) 个答案

  1. # 1 楼答案

    我们的微服务也面临类似的问题,为了预热,我们添加了一个组件

    ApplicationStartup implements ApplicationListener<ApplicationReadyEvent> 
    

    在应用程序中,在应用程序启动后立即调用服务,这对我们很有用。 使用此解决方案,可以保证负载中使用的所有类都将在每个实例中的实例启动后立即加载,并且不需要外部脚本来进行调用。 外部脚本也有问题,我们不能确定新实例在哪里处理调用

    @Component
    public class ApplicationStartup implements ApplicationListener<ApplicationReadyEvent> {
    
        @Autowired
        YourService yourService;
    
        @Override
        public void onApplicationEvent(final ApplicationReadyEvent event) {
    
            System.out.println("ApplicationReadyEvent: application is up");
            try {
                // some code to call yourservice with property driven or constant inputs 
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    
    } 
    
  2. # 2 楼答案

    如果向应用程序提供请求时应用程序运行正常,但仍然存在响应速度慢的问题,则应尝试启用分层编译

    -XX:CompileThreshold -XX:TieredCompilation
    

    通常,VM使用解释器来收集输入编译器的方法的分析信息。在分层方案中,除了解释器之外,客户机编译器还用于生成方法的编译版本,这些方法收集有关自身的分析信息

    由于编译后的代码比解释后的代码快得多,因此程序在分析阶段的执行性能更好

  3. # 3 楼答案

    在我的场景中,我模拟100多个curl请求来初始化这些客户机池、预加载缓存或其他延迟加载的家伙

    我在WarmupHealthIndicator implements HealthIndicator完成这项工作,它实现了一个spring执行器健康检查端点

    最后,在热身结束之前,Nginx(或其他负载平衡器)的任何healch检查都将获得5xx状态代码和body消息。状态更新后,应用程序初始化将不会花费任何流量时间

    {
      "status": "DOWN",
      "details": {
        "warmup": {
          "status": "DOWN"
        },
        "diskSpace": {
          "status": "UP",
          "details": {
            "total": 536608768000,
            "free": 395195826176,
            "threshold": 10485760
          }
        }
      }
    }
    

    此外,NGINX Plus还有一个付费功能slow_start,可以为您的兴趣做同样的事情