当前位置: 首页 > news >正文

长连接的原理

Apollo的长连接实现是

  • Spring的DeferredResult来实现的,先看怎么用

import ...@RestController
@RequestMapping("deferredResult")
public class DeferredResultController {private Map<String, Consumer<DeferredResultResponse>> taskMap = new HashMap<>();private String requestId = "demo";@GetMapping("get")public DeferredResult<DeferredResultResponse> deferredResult(){DeferredResult<DeferredResultResponse> ret = new DeferredResult<>();ret.onTimeout(() -> {DeferredResultResponse deferredResultResponse = new DeferredResultResponse();deferredResultResponse.setCode(HttpStatus.REQUEST_TIMEOUT.value());deferredResultResponse.setMsg(DeferredResultResponse.Msg.TIMEOUT.getDesc());ret.setResult(deferredResultResponse);});taskMap.put(requestId, ret::setResult);return ret;}@GetMapping("set")public void setResult(){DeferredResultResponse deferredResultResponse = new DeferredResultResponse();deferredResultResponse.setCode(HttpStatus.OK.value());deferredResultResponse.setMsg(DeferredResultResponse.Msg.SUCCESS.getDesc());taskMap.get(requestId).accept(deferredResultResponse);taskMap.remove(requestId);}public static class DeferredResultResponse{private Integer code;private String msg;...public enum Msg {TIMEOUT("超时"),FAILED("失败"),SUCCESS("成功");private String desc;...Msg(String desc) {this.desc = desc;}}}
}
  • 这时候请求get接口,客户端是卡住的
    在这里插入图片描述

  • 当有结果设置的时候才会响应,调set接口来设置结果
    在这里插入图片描述

  • 如果一直没有结果设置,就会等到超时的时候才会响应
    在这里插入图片描述

  • 对于Apollo的客户端来说请求流程也是这样的
    调用notification/v3接口等待获取变更的数据(namespace),如果一直没有变更,就会等到60秒超时的时候才响应。

原理

在了解原理之前,问几个问题?

  • 这个客户端阻塞是怎么实现的?
  • 超时是怎么唤醒的?
  • 设置值的时候如果找到原来的请求

回答

  • 阻塞是通过socket来实现的,只要socket请求之后不往回写response,就会一直等待
    spring判断controller是DeferredResult异步请求,就会把这个请求挂起,请求的信息先保存起来,不返回response
  • 超时唤醒是利用tomcat的能力,tomcat会启动线程去扫描队列里面挂起的请求,如果有超时时间到的,会重新dispatch
  • setResult会AsyncManager保存的request,把结果设置之后,重新dispatch
http://www.lryc.cn/news/207427.html

相关文章:

  • 软考系列(系统架构师)- 2015年系统架构师软考案例分析考点
  • 小程序开发——小程序的视图与渲染
  • 用python实现操作mongodb的插入和查找操作
  • 代码审计及示例
  • 【Kotlin精简】第6章 反射
  • 基于FPGA的电风扇控制器verilog,视频/代码
  • 【MySQL】区分:等值连接/自连接/自然连接/外连接 以及ON和Where使用
  • Windows环境下Apache安装部署说明及常见问题解决
  • Linux-安装docker-compose
  • 机器学习实验一:KNN算法,手写数字数据集(使用汉明距离)
  • Java零基础入门-赋值运算符
  • xshell+xming显示jmeter的gui页面
  • el-tree业务
  • 警惕Mallox勒索病毒的最新变种malloxx,您需要知道的预防和恢复方法。
  • linux中断下文之tasklet(中断二)
  • Mysql事务+redo日志+锁分类+隔离级别+mvcc
  • Kafka-Java四:Spring配置Kafka消费者提交Offset的策略
  • Python 训练集、测试集以及验证集切分方法:sklearn及手动切分
  • 数据结构,及分类(存储分类、逻辑分类)介绍
  • Powershell脚本自动备份dhcp数据库
  • 第十六章总结:反射和注解
  • mysql 切割字符串函数
  • 汽车发动机电机右盖设计
  • ETHERNET/IP从站转CANOPEN主站连接AB系统的配置方法
  • 人工智能和机器学习:走向智能未来的关键
  • openGauss本地Centos7.6单机安装和简单应用
  • LeetCode--1 两数之和
  • Hafnium安全分区管理器和示例参考软件栈
  • Python解读市场趋势:LSTM 和 GRU 在预测 Google 股价方面的探索
  • vue源码分析(二)——vue的入口发生了什么