我们正在设计一个接受客户端请求的中间件。这个中间件应该是可扩展的,并且位于负载均衡器后面。
我们的中间件的主要工作是处理请求,并将其转发到外部服务器进行额外处理。
我们需要考虑的一件事是计划处理;例如,一个特定的请求可以被安排在未来的特定时间转发ONLY(例如3小时后(。
正因为如此,它引入了持久化计划作业的需求;它需要处理这样的场景,即1台服务器宕机,然后其他服务器仍然可以接起它。
我们已经考虑过这种方法:
- 使用数据库存储持久化计划作业
- 中间件有后台作业定期查询数据库,如果有任何挂起的作业需要发送
- 使用某种DB并发性来处理多个中间件实例,这些实例可能看起来是相同的调度作业
然而,我认为这种设计可能不是最佳的?特别是在重复出现的后台作业中,因为似乎浪费了一些处理(例如,如果数据库中总是存在数据争用(。
编辑:另一个替代解决方案
- 中间件接收调度请求
- 中间件创建调度请求/将其推送到消息队列(具有时间延迟(
- 从消息队列接收托管的独立函数(例如Azure函数(
- 功能处理计划的请求
这种方法似乎更具可扩展性?
您可以使用temporal.io。以下是使用Java SDK(还支持Go、PHP、Ruby(实现业务逻辑的方式:
public void execute(Request r) {
Workflow.sleep(Duration.ofHours(3));
activities.forwardRequest(r);
}
时态保留函数的完整状态。因此,即使在存在进程和其他基础设施故障的情况下,代码也能保证执行。因此,同步睡眠任何一段时间(甚至几个月(都是可以的。
与这个问题没有直接关系,但我仍然认为值得一提的是,Temporal已经是一个中间件,它的功能比您试图实现的功能多得多。所以我相信你并不真的需要实现你自己的:(。我建议您将应用程序设计为直接使用Temporal SDK。