我的服务器需要处理许多任务。由于工作人员需要满足的API调用速率限制,这些任务必须以特定的给定速率处理。
为了确保不以高于API速率限制的速率执行这些任务,我希望能够配置队列发送消息以进行处理的速率。
此外,该队列还必须保持推送消息的顺序,并以FIFO顺序释放它们以提供公平性。
最后,如果很好的编码方式,使用时将是透明的,那就太好了,这样客户端将通过API调用将消息发送到队列,并且相同的客户端将在消息被释放后接收回该消息。根据工作率和相关顺序排队。例如使用RxJava
waitForMessageToBeReleased(message, queue)
.subscribe(message -> // do some stuff) // message received to the same
client after it was released by the queue according to the defined work rate.
我目前正在使用Redis通过创建一个具有特定TTL数量的变量来控制执行速度,并且其他调用会等到该变量到期为止。但是,它不能处理订单,并且可能导致客户在高负载情况下饿死。
答案 0 :(得分:0)
Cadence Workflow能够以最小的努力支持您的用例。
这是可以满足您要求的稻草人设计:
以下是用Java实现它的工作流程代码(也支持Go客户端):
public interface SerializedExecutionWorkflow {
@WorkflowMethod
void execute();
@SignalMethod
void addTask(Task t);
}
public interface TaskProcessorActivity {
@ActivityMethod
void process(Task poll);
}
public class SerializedExecutionWorkflowImpl implements SerializedExecutionWorkflow {
private final Queue<Task> taskQueue = new ArrayDeque<>();
private final TaskProcesorActivity processor = Workflow.newActivityStub(TaskProcesorActivity.class);
@Override
public void execute() {
while(!taskQueue.isEmpty()) {
processor.process(taskQueue.poll());
}
}
@Override
public void addTask(Task t) {
taskQueue.add(t);
}
}
然后通过信号方法将任务排队到工作流中的代码:
private void addTask(WorkflowClient cadenceClient, Task task) {
// Set workflowId to userId
WorkflowOptions options = new WorkflowOptions.Builder().setWorkflowId(task.getUserId()).build();
// Use workflow interface stub to start/signal workflow instance
SerializedExecutionWorkflow workflow = cadenceClient.newWorkflowStub(SerializedExecutionWorkflow.class, options);
BatchRequest request = cadenceClient.newSignalWithStartRequest();
request.add(workflow::execute);
request.add(workflow::addTask, task);
cadenceClient.signalWithStart(request);
}
与使用队列进行任务处理相比,Cadence具有许多其他优点。
请参见介绍Cadence编程模型的the presentation。