由于缺乏知识,我遇到了一个问题。你能帮我解决吗?
我有2台服务器:
- RESTful微服务
- 与数据库交互的微服务
第一个微服务在Controller
类中包含一个端点(为了简单起见,将其设为GET .../{id}
),返回类型为DeferredResult<String>
。
@GetMapping(/{id})
public DeferredResult<String> get(@PathVariable("id") final String id) {
final DeferredResult<String> deferredResult = new DeferredResult<>();
service.get(id, deferredResult);
return deferredResult;
}
第一台和第二台服务器通过Apache Kafka:进行交互
- 第一台服务器获得
GET
请求并调用一个服务,该服务在名为"getData"的主题中生成消息"{id}"> - 第二台服务器在
@KafkaListener
的帮助下使用主题中的"{id}"> - 2nd检索必要的数据,并在主题"returnData"中生成它(当然,数据包含请求的{id})
- 第一台服务器在
@KafkaListener
的帮助下消耗消息
一切都是以异步方式完成的。
第1台服务器获取数据后,需要使用数据进行响应(DeferredResult<String>
实例上的.setResult(data)
)。
这意味着我需要以某种方式将从Kafka消耗的数据与正确的DeferredResult<String>
实例相匹配。
在这一点上,我的方法似乎没有任何结果。如何保持连接打开,并在使用Kafka的数据后将其返回到正确的连接?
我会避免这种方法。无法保证您的命令会被执行,但如果执行了,则无法保证响应时间。
相反,根据主题上的事件构建一个"投影"(例如,持久存储/数据库),并通过RESTAPI以正常方式从中读取。
然而,"写"端可以对您的POST请求做出反应,在您的Kafka主题上发出一条消息(最终将由上述投影生成器接收)
Kafka根据定义是异步的,如果在处理请求后需要响应,则不应该使用Kafka延迟处理。kafka的正确用例更像是:您的请求已收到,这是您的跟踪号码,或者。。。在请求中提供回调并对第二个进程的回调部分进行调用。如果您需要同步响应,但担心背压,请尝试使用ReactiveStreams之类的东西,使用Asyn端点的Dropwizard工作得很好。在您的解决方案中,进程线程(或请求)挂起,等待可能永远不会到来的消息。如果直接处理请求,则会得到相同的结果,但速度更快。我想你在其他流中使用kafka主题,这些流是同步的,在这种情况下,回调可能对你更好。