【CS.CN】深入解析HTTP中的Expect: 100-continue头:性能优化的利器还是鸡肋?

news2024/11/15 21:55:41

在这里插入图片描述

目录

  • 0 序言
    • 0.1 由来
    • 0.2 使用场景
    • 0.3 现在还需要吗?
  • 1 Expect: 100-continue的机制
  • 2 语法 && 通过重新设置空的Expect头优化性能
  • 3 实例分析:长连接中的Expect问题解决
  • 4 总结

0 序言

0.1 由来

Expect: 100-continue头部字段最早在HTTP/1.1规范中引入。其主要目的是在客户端发送大请求主体(如文件上传)之前,确保服务器能够处理该请求,从而避免不必要的数据传输。

可以将Expect: 100-continue机制比作一个礼貌的问询:

  1. 情景设定
    • 想象你要向朋友送一个大礼物(比如一个大箱子)。
    • 你不确定朋友是否有地方存放这个大箱子。
  2. 正常流程
    • 你打电话(建立TCP连接),告诉朋友你有一个大箱子(发送请求头)。
    • 朋友确认他们有地方放这个大箱子(服务器响应100 Continue)。
    • 你再送过去(发送请求主体)。
  3. 使用Expect: 100-continue
    • 你先打电话(建立TCP连接),告诉朋友你有一个大箱子,但等朋友确认他们有地方放这个大箱子后你才送过去(发送Expect: 100-continue头并等待100 Continue响应)。
    • 如果朋友说没有地方(返回错误状态),你就不送了(节省了不必要的传输)。

0.2 使用场景

  • 大数据上传:当客户端需要上传大文件或大数据时,使用Expect: 100-continue可以确保服务器能够接受这些数据,从而避免在服务器不能处理请求的情况下浪费带宽。
  • 带宽受限的环境:在带宽较低或受限的网络环境中,通过此机制可以减少不必要的数据传输,提高效率。
    • 节省带宽:避免在服务器不能处理请求的情况下发送大量数据,节省网络带宽。
    • 提高效率:在服务器无法处理请求时,客户端能尽早得知,避免等待无效的传输过程。

0.3 现在还需要吗?

虽然Expect: 100-continue在某些情况下依然有用,但现代网络环境和服务器架构的进步使其重要性有所降低:

  • 快速网络:现代网络速度提高,使得发送请求头和等待100 Continue响应的时间成本变得相对较高。
  • 高效服务器:现代服务器处理能力提升,通常可以快速判断并响应请求,无需客户端等待确认。
  • 其他优化手段:现在有更多的优化手段和更好的网络协议(如HTTP/2, HTTP/3)可以提升传输效率。

是否需要使用Expect: 100-continue取决于具体的应用场景:

  • 需要:在高带宽消耗的应用场景中,尤其是大数据上传或受限带宽环境中,依然可以使用。
  • 不需要:在一般的Web请求或快速网络环境中,去掉Expect: 100-continue头可以减少等待时间,优化性能。

1 Expect: 100-continue的机制

Expect 是一个请求消息头,包含一个期望条件,表示服务器只有在满足此期望条件的情况下才能妥善地处理请求。

规范中只规定了一个期望条件,即 Expect: 100-continue, 对此服务器可以做出如下回应:

  • 100 如果消息头中的期望条件可以得到满足,使得请求可以顺利进行的话,
  • 417 (Expectation Failed) 如果服务器不能满足期望条件的话;也可以是其他任意表示客户端错误的状态码(4xx)。

例如,如果请求中 Content-Length 的值太大的话,可能会遭到服务器的拒绝。常见的浏览器不会发送 Expect 消息头,但是其他类型的客户端如 cURL 默认会这么做

Client Server HTTP Request (Headers with Expect: 100-continue) Client waits for 100 Continue response HTTP/1.1 100 Continue Client sends request body after receiving 100 Continue HTTP Request (Body) HTTP Response (Final Response) Client Server

在持久连接中,Expect头可以显著影响请求的性能。默认情况下,客户端可能会添加Expect: 100-continue头,这要求服务器在接受请求主体前响应100 Continue。虽然这种机制有助于避免无效数据的传输,但在某些环境下可能导致不必要的延迟。

客户端发送带有Expect: 100-continue头的请求,服务器在确认可以处理请求后响应100 Continue,然后客户端发送请求主体。如果服务器没有及时响应,客户端将在等待一段时间后继续发送请求主体。这种等待时间会增加请求的总耗时,尤其在长连接中更明显。

在HTTP长连接(持久连接)中,客户端与服务器之间会复用同一个TCP连接以发送多个请求/响应对话。这通常会显著降低延迟和资源消耗,但在某些情况下可能会遇到性能问题。

HTTP协议中的Expect头字段通常用于通知服务器客户端期望的特定行为。默认情况下,客户端可能会自动添加Expect: 100-continue头,这意味着在发送大数据请求主体(例如文件上传)之前,客户端希望服务器先确认请求是否会被接受。

这种机制可以有效避免不必要的数据传输,但在使用长连接时,客户端等待服务器响应100 Continue可能导致显著的延迟。如果服务器未及时响应,客户端将等待一个超时时间,然后再发送请求主体,这会增加总体请求耗时。

注意: Expect: 100-continue机制与连接的长短无关。无论是短连接还是长连接,当客户端发送一个包含Expect: 100-continue头的请求时,都会触发同样的机制:客户端在发送请求主体前等待服务器的100 Continue响应。所以在短连接中,Expect: 100-continue头的存在同样会导致客户端在发送请求主体前等待服务器的100 Continue响应。如果服务器的响应不及时或网络延迟较大,这段等待时间会增加整个请求的耗时。

2 语法 && 通过重新设置空的Expect头优化性能

目前规范中只规定了 “100-continue” 这一个期望条件: 表示通知接收方客户端要发送一个体积可能很大的消息体,期望收到状态码为100 (Continue) 的临时回复。

Expect: 100-continue

e.g.比如curl库默认设置, 或者发送大消息体时: 服务器开始检查请求消息头,可能会返回一个状态码为 100 (Continue) 的回复来告知客户端继续发送消息体,也可能会返回一个状态码为417 (Expectation Failed) 的回复来告知对方要求不能得到满足。

# 客户端发送带有 Expect 消息头的请求,等服务器回复后再发送消息体。

PUT /somewhere/fun HTTP/1.1
Host: origin.example.com
Content-Type: video/h264
Content-Length: 1234567890987
Expect: 100-continue

为了避免这种延迟,可以显式设置空的Expect头。这样,客户端会直接发送请求主体,而不等待服务器响应100 Continue。这减少了等待时间,提高了请求的整体速度。

3 实例分析:长连接中的Expect问题解决

3.1 实际应用中的问题与解决过程

在实际应用中,我负责将一个使用cURL库访问上游接口的系统从原本的短连接改为长连接。我们的初衷是通过长连接减少频繁建立和关闭连接的开销,从而显著降低接口调用的耗时。然而,改为长连接后,监控视图却显示接口调用的平均耗时不降反增。

在这里插入图片描述

3.2 问题发现与初步分析

为了进一步了解问题,我们开始对接口调用过程进行抓包分析。在抓包数据中,我们发现每次发起HTTP请求时,第一跳的请求会出现几百毫秒的延迟。这种延迟在后续请求中并未消失,导致整体耗时增加。

3.2 抓包分析与根本原因

以下是抓包分析的关键步骤和示例:

  1. 抓包工具:使用Wireshark等抓包工具,捕获HTTP请求和响应数据包。
  2. 筛选HTTP请求:在Wireshark中筛选HTTP请求,定位包含Expect: 100-continue头的请求。
  3. 分析时间戳:检查包含Expect头的请求和后续发送请求主体的时间戳,确认延迟发生的具体位置。
  4. 确认问题:发现客户端在发送请求头后,等待服务器返回100 Continue响应的过程中出现了明显延迟。
Frame 1: 102 bytes on wire (816 bits), 102 bytes captured (816 bits) on interface eth0, id 0
    Arrival Time: Jan  1, 2024 15:45:12.123456789 UTC
    [Time shift for this packet: 0.000000000 seconds]
    Epoch Time: 1672598712.123456789 seconds
    [Time delta from previous captured frame: 0.000000000 seconds]
    [Time delta from previous displayed frame: 0.000000000 seconds]
    [Time since reference or first frame: 0.000000000 seconds]
    Frame Number: 1
    Frame Length: 102 bytes (816 bits)
    Capture Length: 102 bytes (816 bits)
    [Frame is marked: False]
    [Frame is ignored: False]
    [Protocols in frame: eth:ethertype:ip:tcp:http]
Ethernet II, Src: Vmware_00:00:00 (00:50:56:c0:00:08), Dst: Vmware_00:00:01 (00:50:56:c0:00:01)
Internet Protocol Version 4, Src: 10.0.0.2, Dst: 10.0.0.3
Transmission Control Protocol, Src Port: 49152, Dst Port: 80, Seq: 1, Ack: 1, Len: 40
Hypertext Transfer Protocol
    GET / HTTP/1.1\r\n
    Host: www.example.com\r\n
    User-Agent: curl/7.68.0\r\n
    Accept: */*\r\n
    Expect: 100-continue\r\n
    \r\n

通过深入分析抓包数据,我们注意到客户端在发送请求头后,等待了较长时间才继续发送请求主体。进一步检查HTTP头部字段,我们发现请求头中包含了Expect: 100-continue。这种配置要求服务器在收到请求头后,先返回一个100 Continue响应,然后客户端才发送请求主体。如果服务器响应不及时,客户端会等待一段时间,从而导致整体耗时增加。

3.3 解决方案与实施

为了解决这一问题,我们决定通过显式设置空的Expect头,绕过100-continue机制,让客户端在发送请求时直接发送请求主体。具体实现如下:

std::list<std::string> lstHeader;
xx_api::Prom* prom = xx_api::Prom::GetInstance();
lstHeader.push_back("Content-Type: application/xml;charset=utf-8");
lstHeader.push_back("MsgTp:" + msgTp);
lstHeader.push_back("OriIssrId:" + kPyeeAcctIssrId);
lstHeader.push_back("Expect:");

3.4 结果验证与性能提升

在这里插入图片描述
在实施这一改动后,我们再次进行了性能测试。监控视图显示,HTTP请求的平均耗时显著下降,之前的几百毫秒延迟不复存在。经过多次测试和实际运行,确认这种改动有效解决了因Expect: 100-continue头导致的延迟问题。

4 总结

无论是短连接还是长连接,通过去掉Expect: 100-continue头可以避免等待服务器的100 Continue响应,从而减少请求的整体耗时,提升性能。

1000.06.CS.CN.7.2.4-HTTP-连接管理-Expect头的使用与性能影响-Created: 2024-06-06.Thursday17:51

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

国产操作系统上给麒麟虚拟机安装virtualbox增强工具 _ 统信 _ 麒麟 _ 中科方德

原文链接&#xff1a;国产操作系统上给麒麟虚拟机安装virtualbox增强工具 | 统信 | 麒麟 | 中科方德 Hello&#xff0c;大家好啊&#xff01;昨天给大家带来了一篇在国产操作系统上给VirtualBox中的Win7虚拟机安装增强工具的文章&#xff0c;今天我们将继续深入&#xff0c;介绍…

Interview preparation--RabbitMQ

AMQP AMQP(Advanced Message Queueing protocol). 高级消息队列协议&#xff0c;是进程之间床底一步新消息的网络协议AMQP工作原理如下&#xff1a; 发布者&#xff08;Publisher&#xff09;发布消息&#xff08;Message&#xff09;经过交换机&#xff08;Exchange&#xff…

【Python】认识 Python

一、计算机基础概念 1、什么是计算机 很多老一辈的人&#xff0c;管下面这个叫做计算机。然而&#xff0c;它只是 “计算器”&#xff0c;和计算机是有很大区别的。 现在我们所说的计算机&#xff0c;不光能进行算术运算&#xff0c;还能进行逻辑判断、数据存储、网络通信等…

uniapp原生插件开发实战——集成Android端的Twitter登陆

Android集成Twitter登陆的官方教程:https://github.com/twitter-archive/twitter-kit-android/wiki 项目创建 首先可以先看下uniapp原生插件开发教程 uniapp原生插件类型分为两种: Module模式:能力扩展,无嵌入窗体的UI控件,类似于功能插件。Component模式:在窗体中内嵌…

websocket php workerman 服务器nginx配置wss协议

首先 Nginx的版本要高&#xff0c;尽量用当前最新稳定版本。 其次 WSS协议&#xff0c;是在HTTPS协议的基础上&#xff0c;进行协议升级&#xff0c;进行通讯的&#xff0c;所以先要保证你有一个 HTTPS正常的WEB站点。 所以&#xff0c;通过Nginx -V 请保证 一定有 --with-ht…

监控摄像机接入GB28181平台如何获取监控视频

各种型号监控摄像头或硬盘录像机接入 GB28181平台配置过程非常简单明了&#xff0c;但有些细节需要注意&#xff0c;避免走弯路。 1、基本要求 &#xff08;1&#xff09;网络要求 总的来说&#xff0c;只要监控设备和GB28181平台的网络是连通的&#xff0c;设备可以主动访问…

Linux 35.5 + JetPack v5.1.3@FC-Planner编译安装

Linux 35.5 JetPack v5.1.3FC-Planner编译安装 1. 源由2. 编译&安装Step 1&#xff1a;依赖库安装Step 2&#xff1a;克隆工程Step 3&#xff1a;编译工程Step 4&#xff1a;LKH编译Step 5&#xff1a;安装工程 3. 问题汇总3.1 Killed signal terminated program cc1plus3…

跟着小白学linux的基础命令

小白学习记录&#xff1a; 前情提要&#xff1a;Linux命令基础格式!查看 lsLinux 的7种文件类型及各颜色代表含义 进入指定目录 cd查看当前工作目录 pwd创建一个新的目录(文件夹&#xff09; mkdir创建文件 touch查看文件内容 cat、more操作文件、文件夹- 复制 cp- 移动 mv- 删…

Vxe UI vxe-form 实现折叠表单,当表单很多时实现自动收起与展开

Vxe UI vue vxe-form 实现折叠表单&#xff0c;当表单很多时实现自动收起与展开 代码 folding 用于将当前表单项设置为默认隐藏 collapse-node 设置折叠按钮&#xff0c;加上之后会自动在该表单项的右侧显示一个折叠按钮 <template><div><vxe-formtitle-colo…

windows 系统通过 cmd 命令终止进程

windows 系统通过 cmd 命令终止进程 1、使用 netstat 命令查看特定端口的占用情况 例如&#xff0c;要查看端口号为 8015 的情况&#xff0c;可以执行以下命令&#xff1a; netstat -ano | findstr 8105此命令会显示所有占用端口 8105 的网络连接&#xff0c;并列出 PID&…

24.Labview移位寄存器的使用及数据流解析

本文讲解移位寄存器的常用场景及其数据流的方向解析。 在Labview中移位寄存器是存在于循环结构中的&#xff0c;也就是说for循环和while循环中&#xff0c;在了解移位寄存器之前首先要了解一下for循环和while循环的原理及其数据流的流动方向&#xff0c;题主之前讲过for循环的文…

Redis的事务与关系型数据库事务有何不同?

引言&#xff1a;关于 Redis 的事务很多人可能都是一知半解&#xff0c;大多数人只了解数据库的事务&#xff0c;并且是单体事务&#xff0c;对于 Redis 事务和常见关系型数据库的事务的区别还没有去了解过&#xff0c;本文就来详细进行介绍。 题目 Redis的事务与关系型数据库…

【三】Linux网络配置详解

在RHEL 7系统中配置网络的方法有好几种&#xff0c;咱们这边先讲一下使用图形化工具和修改配置文件这两种方法来配置&#xff0c;其他方法大家可以下去自己研究研究。 一、使用图形化方式配置&#xff1a; 在电脑左上角开始一次点击Applications、System Tools、Settings&…

如何使用共享GPU平台搭建LLAMA3环境(LLaMA-Factory)

0. 简介 最近受到优刻得的使用邀请&#xff0c;正好解决了我在大模型和自动驾驶行业对GPU的使用需求。UCloud云计算旗下的[Compshare](https://www.compshare.cn/? ytagGPU_lovelyyoshino_Lcsdn_csdn_display)的GPU算力云平台。他们提供高性价比的4090 GPU&#xff0c;按时收…

[word] word悬挂缩进怎么设置? #经验分享#职场发展#经验分享

word悬挂缩进怎么设置&#xff1f; 在编辑Word的时候上方会有个Word标尺&#xff0c;相信很多伙伴都没使用过。其实它隐藏着很多好用的功能&#xff0c;今天就给大家分享下利用这个word标尺的悬挂缩进怎么设置&#xff0c;一起来看看吧&#xff01; 1、悬挂缩进 选中全文&…

VBA语言専攻通知20240608

通知20240608 各位学员∶本周MF系列VBA技术资料增加621-625讲&#xff0c;T3学员看到通知后请免费领取,领取时间6月7日晚上19:00-6月8日晚上20:00。本次增加内容&#xff1a; MF621:为组合框添加工作表数据 MF622:在代码中使用π值 MF623:在窗体上使用切换按钮 MF624:删除…

使用difflib实现文件差异比较用html显示

1.默认方式&#xff0c;其中加入文本过长&#xff0c;需要换行&#xff0c;因此做 contenthtml_output.replace(</style>,table.diff td {word-wrap: break-word;white-space: pre-wrap;max-width: 100%;}</style>)&#xff0c;添加换行操作 ps&#xff1a;当前te…

最新PHP众筹网站源码 支持报名众筹+商品众筹+公益众筹等多种众筹模式 含完整代码包和部署教程

在当今互联网飞速发展的时代&#xff0c;众筹模式逐渐成为了创新项目、商品销售和公益活动融资的重要渠道。分享一款最新版的PHP众筹网站源码&#xff0c;支持报名众筹、商品众筹和公益众筹等多种众筹模式。该源码包含了完整的代码包和详细的部署教程&#xff0c;让新手也可以轻…

【Mac】Downie 4 for Mac(视频download工具)兼容14系统软件介绍及安装教程

前言 Downie 每周都会更新一个版本适配视频网站&#xff0c;如果遇到视频download不了的情况&#xff0c;请搜索最新版本https://mac.shuiche.cc/search/downie。 注意&#xff1a;Downie Mac特别版不能升级&#xff0c;在设置中找到更新一列&#xff0c;把自动更新和自动downl…

DeepDriving | 多目标跟踪算法之SORT

本文来源公众号“DeepDriving”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;多目标跟踪算法之SORT 1 简介 SORT是2016年发表的一篇文章《Simple Online and Realtime Tracking》中提出的一个经典的多目标跟踪算法&#xff0c;…