【问题标题】:Is it recomended to use Server Sent Events for pushing notifications by continuous querying of the database?是否推荐使用 Server Sent Events 通过持续查询数据库来推送通知?
【发布时间】:2020-05-26 02:43:33
【问题描述】:

我想通过不断查询数据库将实时通知(登录用户的 DTO 对象)推送到客户端。我正在使用服务器端事件来实现相同的目的。但是,我在实现这一目标方面面临一些问题。我在 javascript 中使用 EventSource API。

  1. 在无限循环中轮询

由于我的数据位于数据库中,我经常需要运行查询以获取最新条目并使用executor.execute(()->{ while(true) {emitter.send(data)} } Thread.sleep(5000)) 直到用户注销。 (a) 在无限循环中查询数据库和 (b) 创建新的 ExecutorService 对象导致 JDBC 池耗尽异常并最终冻结应用程序。

  1. 使用弹簧启动@Scheduled 这也不起作用,因为我需要登录 user_id,我无法使用 SpringContextHolder.getAuthentication 进入 @Scheduled 注释方法,因为此 Cron 不是由用户启动的。

我在这里选择 SSE 而不是 Web Sockets 是不是做错了,或者有什么办法可以为这个特定的用例实现服务器端?

请帮助/指导我。

【问题讨论】:

    标签: java spring-boot websocket push-notification server-sent-events


    【解决方案1】:

    如果您想将事件推送到您的客户端,您最好在后端也有事件概念,而不是轮询。如果你想轮询你的数据库,你最好让客户端来做。 SSE 或 websocket 在该决定中并不重要。

    CDI 活动可能是满足您需求的合适解决方案。

    • 创建一个EntityForLoggedInUsersChanged 事件类。
    • 在您的服务中注入一个Event<EntityForLoggedInUsersChanged>,以更改与登录用户相关的实体。当他们这样做时触发事件。
    • 创建一个服务,将@Observe 那些事件,构造你要推送的dto,获取到相关用户的通道,然后推送它。

    【讨论】:

      【解决方案2】:

      令人惊讶的是,是的,这是一个有效的模式。

      与让数据库发送推送通知(即使假设数据库支持)相比,每 5 秒轮询一次可能会使用更少的总体资源。

      与让客户端每 5 秒进行一次 AJAX 调用(每次都需要建立一个 DB 连接)相比,它也可能更有效(以始终保持 SSE 套接字打开为代价) .

      创建新的 ExecutorService 对象会导致 JDBC 池耗尽异常并最终冻结应用程序。

      池耗尽是否来自只有一个用户,每 5 秒轮询一次?还是因为拥有大量用户,每个用户都保持一个数据库连接打开?

      如果是后者,请使池足够大,以支持您希望允许的最大同时连接用户数。

      如果是前者,您要么必须在轮询后、在 5000 毫秒睡眠之前释放资源,要么在循环外打开资源一次,然后找到一种方法在无限循环内重新运行查询。

      (抱歉我对ExecutorServiceSpring不熟悉;可能只是对查询数据库的抽象太高级,需要使用低级函数?)

      顺便说一句,SSE 与 Web Sockets 在这里并没有什么不同。 Web Sockets 为您提供了一个更复杂的协议,以换取它是双向连接而不是单向连接,但其他一切都基本相同。 IE。您仍然在客户端和 Web 服务之间有一个专用套接字,并且您仍然有一个无限循环轮询数据库。

      【讨论】:

      • 只是为了与上面的一点相矛盾,在 websocket 的情况下,我不需要连续循环我的数据库。每当发生事件时(比如说创建评论/通知),在我的应用程序代码中,我可以通过专用的 websocket 通道广播一条消息。 EventSource 没有通道的概念。
      • @VipulKumar 如果您可以在 websocket 服务器中发生事件(然后广播)时收到通知,那么您也可以为 EventSource 执行此操作。 (顺便说一句,您可以指定 event 标头来获取通道的概念,但我通常建议不要使用它,并在单个消息处理程序中处理所有内容。例如,请参阅 stackoverflow.com/a/9936764/841830 那里的人得出了相同的结论。)
      • 达伦库克感谢您的意见。但是,我们仍然需要不断循环/轮询我们的数据库。
      猜你喜欢
      • 2018-05-06
      • 1970-01-01
      • 1970-01-01
      • 2016-04-25
      • 1970-01-01
      • 1970-01-01
      • 2023-03-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多