异步http和同步http原理和差异

开发服务器端程序时,一种常见的需求是,通过向另一个http服务器发送请求,获得数据。最常规的作法是使用同步http请求的方式,过程如下

这种方式简单好用,但是在高并发场景下有缺陷。在单线程环境下,程序发送http请求是串行的,也就是第一个请求未完成的情况下,第二个请求发不出去,就像一条单行车道,车子只能一辆一辆的过。 为此我们会引入多线程提高并发性,然而多线程对并发发送http请求的提升也是有限的,比如8个线程同时只能发送8个请求,假如每个请求从发送到得到结果的时间是1秒,那么8个线程每秒钟也只能发送8个请求,而线程不能无线多开,因此多线程并不能很好的解决客户端高并发发送请求的问题。

这听起来很扯淡,我们使用的服务器配置动不动就8核16G,为什么发送http请求的能力如此弱鸡,实际上这并不是服务器的锅,也不是java的锅,而是http工作模式的原因,在发送数据和得到数据的过程中有一个等待的过程,等待的过程并不消耗CPU,但是会让当前线程陷入等待,干不了别的事情。如果把多线程转换成线程池的模式,那么使用同步http时,在高并发场景下,线程池的队列中会堆积大量请求任务发不出去,而被请求的目标服务器,却还远没有达到瓶颈。

解决方案是使用异步http模型,我们知道nodejs因为天生的异步高性能而出名,实际上异步并不是nodejs的专利,任何主流的高级语言都支持,如 java、c++、.net等。

异步为什么快呢?因为异步http去除了同步http请求的等待过程,只保留了发送和处理得到数据的过程, 这听起来很扯蛋,发送http怎么可能没有等待呢?我在浏览器里访问网站不也要等一会才能打开页面吗? 实际上异步http请求并不是没有等待,只是把等待的这个步骤从当前线程转移到了别的地方,当前线程除了发送数据, 可以不干别的事情,而发送数据非常快,每一刻都是成千上万,可以充分利用计算机资源,而不是空等啥都干不了。

而http结果的响应,可以理解成以事件响应的形式触发,或者更通用的说法是回调函数的形式,所以发送数据和处理结果是两个不同的分支,也可以理解成处于不同的线程,互不干扰。

要较为深刻的理解异步http,还需要从TCP说起。TCP连接就像一根双向流通的管道,客户端从一端发送数据给服务器,服务器也从另一端发送数据给客户端。http本质上也是这种工作模式。客户端把一些http规范指定的必须数据项,包括请求头、请求主体、内容长度等信息打包成一个http请求数据包,通过TCP连接发送给服务器。服务器接受到http请求数据包,解码处理后,组装一个http响应包,发送给客户端。所以http本质上还是基于TCP的。

异步http就是这种底层工作模式的体现,客户端向服务器发送http请求,然后去做别的事情了,比如发另一个请求给服务器。至于服务器何时把响应数据包发送过来,客户端可以不管,至少在当前执行的上下文中可以不管,因为当服务器响应时,会有另外的线程被唤醒处理这个响应。

既然异步http更接近http的本质,性能也更高,那么为什么还会有同步http出现呢?而且通常还是使用http请求的默认模式。主要原因还是同步 http使用简单,易于理解,更符合人类正常思考问题的思维,也更容易让新手入门。

同步http只是将异步http进行了封装,当客户端发送一个http请求时,让当前线程进入等待,当结果响应了再让当前线程唤醒处理结果。这样整个http的过程变的简单了,但是却远离了tcp的本质,性能也更差劲了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/409489.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

linux调用so库之一

任务:linux系统,已经生成so库,需要调用。 参考文献: Linux 调用动态库(.SO文件)总结_linux deviceio.so-CSDN博客 可以看他的第一部分,即显式调用。但是会报错,我的版本是64位的U…

【SpringBoot】Spring常用注解总结

目录 ⭐spring springmvc和springboot的区别 Autowired 和Resource的区别和联系 1. SpringBootApplication 2. Spring Bean 相关 2.1. Autowired 2.2. Component,Repository,Service, Controller 2.3. RestController 2.4. Scope 2.5. Configuration 3. 处理常见的 HT…

vue3(vite)+electron打包踩坑记录(1)

vue3(vite)electron打包踩坑记录 - 打包vue 第一步 编译vue 使用vite构建vue,package.json如下 {"name": "central-manager","private": true,"version": "0.0.0","type": "commonjs",&q…

Autosar 开篇

背景 AUTOSAR(Automotive Open System Architecture)是一个跨汽车行业的标准化软件架构,旨在促进汽车电子系统的开发和部署。下面是AUTOSAR发展的一些关键点: 起源和背景: AUTOSAR最初于2003年由汽车制造商宝马、戴姆…

x(x-1)的含义

一.二进制中x&(x-1)的含义 把x的二进制最后一个1变为0 找一下规律: 二.应用 我们可以利用这个特性,来数这个数字中有多少数字1 算法分析:放入一个计数器,每循环一次,就把这个数字的最后一个1变为0,计数…

【JavaEE】 spring boot的配置文件详解

spring boot的配置文件详解 文章目录 spring boot的配置文件详解常用配置spring boot的配置文件1. properties 文件2. YAML 文件3. 多环境配置4. 配置文件优先级5. 配置属性注入特殊说明 properties配置文件基本语法 例子peoperties文件的缺点 YML配置文件YML使用yml 配置不同数…

阿里云-系统盘-磁盘扩容

阿里云系统磁盘扩容 之前是测试环境磁盘用的默认的有 40G,后面升级到正式的 磁盘怕不够用打算升级到 100G, 系统镜像: Alibaba Cloud Linux 3.2104 LTS 64 位 磁盘 ESSD 40G 升级步骤: 扩容与创建快照 在阿里云后台首先去扩容…

【Docker】三、日志控制

三、日志控制 使用Docker部署服务器,要对Docker日志定时处理。否则,服务器运行一段时间后,磁盘占比报警。 出现磁盘占比报警,大概率是大文件的问题,可查看服务器中的大文件,排除问题。 (一&am…

apache 模式、优化、功能 与 nginx优化、应用

一、I/O模型——Input/Output模型 1.同步/异步 A程序需要调用B程序的某一个功能,A发送一个请求需要B完成一个任务 同步:B不会主动去通知A是否完成需要A自己去问 异步:B会主动通知A是否完成 2.阻塞/非阻塞 A发送一个请求需要B完成一个任务 …

Python文件和异常(二)

目录 三、异常 (一)处理 ZeroDivisionError 异常 (二)使用 try-except 代码块 (三)使用异常避免崩溃 (四)else 代码块 (五)处理 FileNotFoundError 异常…

单片机05__串口USART通信__按键控制向上位机传输字符串

串口USART通信 通用UART介绍 1.通信的概念 计算机与外界进行信息交换的过程称之为通信。 在通信的过程中,通信双方都需要遵守的规则称之为通信协议。 硬件协议:将数据以什么样的方式传输过去 软件协议:将数据以什么样的顺序传输过去 2.常用…

042 继承

代码实现 首先定义Person类(人类) /*** 人的基础特征** author Admin*/ public class Person {/*** 姓名*/String name;/*** 生日*/Date birthday;/*** 手机号码*/String tel;/*** 身份证号码*/String idCode;public Person() {}public Person(String …

BlackberryQ10 是可以安装 Android 4.3 应用的,Web UserAgent 版本信息

BlackberryQ10 是可以安装 Android 4.3 应用的 最近淘了个 Q10 手机,非常稀罕它,拿着手感一流。这么好的东西,就想给它装点东西,但目前所有的应用都已经抛弃这个安卓版本了。 一、开发环境介绍 BlackBerry Q10 的 安卓版本是 4.…

Spring Boot对接RocketMQ示例

部署服务 参考RocketMq入门介绍 示例 引入maven依赖 <dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-spring-boot-starter</artifactId><version>2.2.2</version></dependency>完整依赖如下&am…

栈和队列笔试题

答案&#xff1a;&#xff08;1&#xff09;seqn[tail]data; tail(tail1)%SEQLEN; &#xff08;2&#xff09;data seqn[head]; head (head1)%SEQLEN; &#xff08;3&#xff09;head tail; &#xff08;4&#xff09;(tail1)%SEQLEN head; (5) while(head!tail) head (h…

PHP WebSocket:技术解析与实用指南

本文旨在帮助初学者掌握在PHP中使用WebSocket的关键概念和技术。我们将深入讨论从建立连接、绑定到监听等各方面的操作&#xff0c;并提供易于理解和实践的指导。 一、socket协议的简介 WebSocket是什么&#xff0c;有什么优点 WebSocket是一个持久化的协议&#xff0c;这是…

基于相位的运动放大:如何检测和放大难以察觉的运动(01/2)

基于相位的运动放大&#xff1a;如何检测和放大难以察觉的运动 目录 一、说明二、结果的峰值三、金字塔背景3.1 可操纵金字塔3.2 亚倍频程复数可控金字塔 四、基本方针4.1 1D 问题陈述4.2 一维方法4.3 实际实施说明 五、放大倍率的限制5.1 空间支持的影响5.2 频带的影响 六、推…

【Oracle】玩转Oracle数据库(五):PL/SQL编程

前言 嗨&#xff0c;各位数据库达人&#xff01;准备好迎接数据库编程的新挑战了吗&#xff1f;今天我们要探索的是Oracle数据库中的神秘魔法——PL/SQL编程&#xff01;&#x1f52e;&#x1f4bb; 在这篇博文【Oracle】玩转Oracle数据库&#xff08;五&#xff09;&#xff1…

2.25基础会计学

资本公积是指由股东投入、但不能构成“股本”或“实收资本”的资金部分。 盈余公积是指公司按照规定从净利润中提取的各种积累资金。 所以区别在于盈余公积来自净利润。 借贷其实就是钱从哪来和到哪去的问题&#xff0c;来源是贷&#xff0c;流向是借。比如购入9w原材料&…

【监控】grafana图表使用快速上手

目录 1.前言 2.连接 3.图表 4.job和path 5.总结 1.前言 上一篇文章中&#xff0c;我们使用spring actuatorPrometheusgrafana实现了对一个spring boot应用的可视化监控。 【监控】Spring BootPrometheusGrafana实现可视化监控-CSDN博客 其中对grafana只是打开了一下&am…