异步处理http请求同步返回结果

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了异步处理http请求同步返回结果相关的知识,希望对你有一定的参考价值。

参考技术A   异步处理,同步返回?为什么会有这样一个需求?既然接口要求同步返回,那么直接阻塞就好了,要什么异步消息同步返回?高并发保护系统的手段是缓存、限流、降级。限流有许多的手段,想令牌桶、漏桶算法按数量限流,也有使用消息队列,排队限流的。至于使用消息队列的好处就不多说了,这里主要将如何实现这个需求,有一个系统比较的不稳定,但是没人维护,又不能替换它,只能在他的上层加一层来保护她,可以限流处理,也可以用mq让它以他的最大处理能力处理。说白了这东西就是一个缓冲系统,可替代性高,存粹的技术型应用,由于新鲜所以我觉得可以一试;

  首先我们来选型,分析需求:使用消息队列异步请求,那么选型消息队列: zeromq、rabbitmq、activemq、kafka、rocketmq等等,消息队列很多如果没有什么要求,那么都可以选,但是首先我们需要考虑实现问题呢,使用的mq是否支持。我们需要可以排队,那么zeromq就不能选了,activemq有较小概率丢失消息,一般我不太爱用这个。好了我们实现这个需求不需要什么复杂的功能,那么剩下的都是可以选的,接下来就是考虑架设成本和易用性的问题。rabbitmq的时效性非常的好,但是吞吐量不及kafka和rocketmq,而且隔热你用的较少;所以一般来说我习惯在kafka和rocketmq中选择。rocketmq综合性能比较好,而且有很多的功能(消息提交重新消费、延时消费等),做支付金融首选rocketmq,但是我们这里不需要用到这些,所以这里用了kafka。
  有了异步处理消息的mq,我们还需要一个保存mq处理完的返回值队列,能让阻塞的线程获取到。因为要分布式的,所以这个队列不能是java中的数据,所以这里使用redis保存mq处理完的数据。

  接下来我们先构造系统,首先我们有一个web服务,用来接收http的请求,接受请求后发送mq处理,然后阻塞当前处理的线程,等待mq处理完成,从redis的队列中取出数据,现在还差一个mq的接收方,实现一个server服务,接受mq消息并处理,然后将数据放入redis,并且通知web的这个线程消息已经处理完毕,让web这个阻塞的线程取出redis中处理完成的数据。至于通知需要广播通知,因为分布式的话这个处理请求的线程会在任意一台web服务中,至于这个通知我们可以用redis的发布订阅功能来实现;
  整体我们就有2个服务,一个web,一个server,之间通过mq通信,redis共享数据,redis发布订阅同步状态唤醒线程。

  首先是web端的实现,简单的springboot项目加上web依赖,这里不赘述,这里我们模拟场景:我们需要去一个三方系统获取用户信息,通过后台http调用获取他的用户信息,用户要么输入手机,用户名或邮箱和密码(加密的);

以上是web端的处理,是关键部分,接下来是server端的处理,比较简单,就简单叙述下:
在web中向kafka中推送了一条获取用户信息的消息,接下来就只要处理一下步骤:
srver端消费消息
反序列化
http调用第三方,同步获取返回结果(这里注意配置http调用的超时时间和异常处理)
将http的返回结果用消息中的requestId作为key写入redis
最后通过发布订阅返回requestId处理完成的消息

到这里这条请求的处理又回到了web端:
web端收到了redis的发布订阅消息,从 GlobalThreadMap 中用发布订阅的requestId(也就是一开始的UUID生成的id)取出被park的线程执行unpark唤醒,之后 result.get(5, TimeUnit.SECONDS) 就能获取从redis中取出的数据完成一次请求处理;

HTTP请求中同步与异步有啥不同

参考技术A 举个例子:普通B/S模式(同步)AJAX技术(异步)

同步:提交请求->等待服务器处理->处理完毕返回 这个期间客户端浏览器不能干任何事

异步: 请求通过事件触发->服务器处理(这是浏览器仍然可以作其他事情)->处理完毕

同步就是你叫我去吃饭,我听到了就和你去吃饭;如果没有听到,你就不停的叫,直到我告诉你听到了,才一起去吃饭。

异步就是你叫我,然后自己去吃饭,我得到消息后可能立即走,也可能等到下班才去吃饭。

所以,要我请你吃饭就用同步的方法,要请我吃饭就用异步的方法,这样你可以省钱。本回答被提问者和网友采纳

以上是关于异步处理http请求同步返回结果的主要内容,如果未能解决你的问题,请参考以下文章

(05)使用DeferredResult多线程异步处理请求

总结对异步处理的http接口进行性能测试

[异步][事务][流程][设计]同步当场处理并返回处理结果,异步后怎样返回. 怎样解决?

同步阻塞同步非阻塞异步阻塞异步非阻塞--简明介绍

HTTP请求中同步与异步有啥不同

架构设计|异步请求如何同步处理?