【问题标题】:Vaadin ui ready eventVaadin ui 就绪事件
【发布时间】:2021-10-07 10:49:55
【问题描述】:

在云环境中,我需要能够找出 Spring Boot vaadin 服务何时准备好用于用户连接。 我已经尝试调用 /actuator/health ,但服务在 vaadin beeing 准备好之前就已经启动了...... 有人遇到过同样的问题并找到了解决方案吗?

为了清楚起见,我的问题更多是在负载平衡级别。我需要找到一种方法来告诉负载均衡器(我正在使用粘性会话)新生成的 vaadin 服务已准备好接收用户......这是我使用 /actuator/health 但服务已启动的地方在 vaadin 准备好之前。

【问题讨论】:

  • 你应该描述你真正想要达到的目标,你的问题现在太模糊了。先仔细阅读本章:vaadin.com/docs/v14/flow/advanced/…
  • 我明白了,您可能对 Vaadin 会话或 UI 初始化事件感兴趣,但您也可能对组件级附加事件或路由生命周期事件感兴趣。选项太多了,所以需要更多细节。
  • 感谢您的回答。我的问题更多是在负载平衡级别。我需要找到一种方法来告诉负载均衡器(我正在使用粘性会话)新生成的 vaadin 服务已准备好接收用户......这是我使用 /actuator/health 但服务已启动的地方在vaadin 准备好之前。所以我认为这早于 Vaadin 会话或 UI 初始化事件没有?
  • 好的,这通常在比 Vaadin 更低级别的堆栈中完成。大多数现成的云服务都在应用服务器和负载均衡器配置之间构建了这种机制,因此应用程序开发人员无需为此烦恼。既然你在问这个,我假设你有自定义的本地设置,这需要一些 DIY。 Vaadin 没有太多关于如何以正确方式执行此操作的信息。我们通常依赖 3rd 方集成,例如Hazelcast 在这里提到vaadin.com/learn/tutorials/microservices/high-availability
  • 您好,感谢您的回答。不,我使用的是真正的云配置,负载均衡器依靠 http 调用来确定服务是否可用。这种方法在负载平衡过程中很常见。一般来说,服务是候选者,一旦从自动发现机制可见,就可以接收连接,但在这里我的服务在 Vaddin 准备好之前是可见的,因此需要额外检查。我已经在 Vaadin 的高可用性上花费了一些时间,但不幸的是,这不是一个可行的解决方案,因为它会产生大量开销,因此不适用于大规模部署

标签: cloud vaadin vaadin-flow


【解决方案1】:

我们的应用程序(使用 Application Load Balancer 部署在 AWS 上)基于 Spring Boot 和 Vaadin 14。我们一直在使用 ServletFilter 来指示负载均衡器引导流量:

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class HealthCheckFilter implements Filter {

    public static final String HEALTH_CHECK_PATH = "/healthcheck";
    private boolean vaadinIsInitialized = false;

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        if (request.getRequestURI().endsWith(HEALTH_CHECK_PATH) && vaadinIsInitialized) {                
            response.setStatus(HttpServletResponse.SC_OK);
        } else {
            filterChain.doFilter(servletRequest, servletResponse);
        }
    }

    @EventListener({ContextRefreshedEvent.class})
    public void contextRefreshedEvent() {
        // invoked after Spring finishes loading the application context, which is after
        // Vaadin and the embedded application server has started
        vaadinIsInitialized = true;
    }
}

在我们的应用程序初始化过程中至少会发生两个有趣的事件,可用于指示应用程序已准备好为请求提供服务。

  1. ServiceInitEvent - 发布到任何实现 VaadinServiceInitListener 的 Spring bean(如果您不使用 Spring,IIRC,您可以注册此事件)。根据文档是在“初始化 VaadinService 时”发布的。这意味着它发生在 Vaadin 完全初始化之前。在一个简单的应用程序中,我观察到这种情况发生在应用程序准备好接收请求之前的几毫秒。
  2. (如果您将 Vaadin 与 Spring 一起使用)ContextRefreshedEvent - 这发生在 Vaadin 和 Spring 都完全初始化之后。在此事件发生时,应用程序已准备好为 Vaadin 请求提供服务 - 因此它是向负载均衡器发出信号的理想候选者。

【讨论】:

  • 嗨,咕哝,谢谢,这是一个很好的开始。我要这样挖。
  • 为什么要使用过滤器而不是 REST 端点?那不是更简单吗?
  • 您好,未尝试使用 REST 端点进行测试。目前,我无法获得任何 vaadin 就绪状态。 VaadinServiceInitListener 完全是关于 UI 所以会话。因此,我目前唯一的解决方案是捕获 spring 就绪事件并将 200 健康检查响应代码延迟一段时间。我已将其设置为 2 分钟,但我需要使用类似生产的系统来完善这个数字,因为 vaadin 行为在 dev 和 prod 中不一样
  • @muzii 我认为 VaadinServiceInitListener 是要走的路。这是关于服务,而不是关于会话。可以在没有任何会话 AFAIK 的情况下初始化服务。
  • @muzii 你让我想更好地理解 Spring 和 Vaadin 之间的初始化事件。我已根据所学内容更新了我的答案及其示例。
猜你喜欢
  • 2016-05-31
  • 2011-07-20
  • 2011-12-04
  • 2020-05-30
  • 2016-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多