我正在学习 HTTP2 并使用 jetty 开发了一个 POC,它在 chrome 中运行良好。
但是,当我在 firefox 中点击相同的 URL 时,我的 HTTP2 URL 请求得到了空白页面,异常显示“您尝试查看的页面无法显示,因为无法验证接收到的数据的真实性。” 四处搜索后发现在firefox中我必须从“about:config”启用network.http.spdy.enabled.http2。
我的问题是,如果浏览器不支持 HTTP2,服务器或浏览器端是否有任何机制可以回退到 HTTP1。
由于我不是专家,所以我有一个关于 HTTP/2 的一般性问题。
众所周知,HTTP2 压缩标头以减小消息大小。这仅适用于响应还是也适用于请求?如果做一个小实验并运行两个小型 HTTP 服务器,一个使用版本 1.1,另一个使用版本 2,让它们发送完全相同的内容,然后在 Firefox 中请求两个页面,我可以看到响应标头大小显着小于HTTP/2 版本。但是,请求头大小几乎相同。根据我的理解,这是有道理的,因为浏览器事先不知道服务器是否支持 HTTP/2,因此无法预先压缩标头。我对吗?如果是这样,有没有办法“强制”客户端使用 HTTP/2(对于客户端,我不是指 brwoser,而是程序化的)并压缩请求标头?
还有一个问题:如果我想在负载下对 HTTP/1.1 与 HTTP/2 的性能进行基准测试,那么有用的测试设置应该是什么样的,哪些参数会变化,哪些指标可以衡量(RTT、TTFB、. ..?)
是否可以使用 http2 将响应从节点流式传输回浏览器?
在我的网络应用程序中,用户按下启动服务器进程的按钮。此过程可能需要 10 分钟或更长时间才能完成。我想将状态更新流回客户端/浏览器。
我相信我可以用 websockets 来做到这一点,但我希望 http2 能让这更容易。我知道它支持“推送”,但据我所知,这仅用于推送用户将来可能需要的文件。
或者我什至不需要http2?浏览器将保持连接打开多长时间?我res.write()可以无限期地坚持下去吗?
我在共享主机上有一个网站,在每个页面请求上都使用这些 HTTP 标头进行响应:
HTTP/1.1 200 OK
Date: Thu, 21 Sep 2017 14:34:46 GMT
Server: Apache
X-Powered-By: PHP/5.6.31
Access-Control-Allow-Origin: *
Upgrade: h2,h2c
Connection: Upgrade, Keep-Alive
Keep-Alive: timeout=5, max=400
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8
Run Code Online (Sandbox Code Playgroud)
正如您所注意到的,有Upgrade一个来自 Apache 的关于支持 HTTP2 协议的声明的标头。
出于某种原因,我需要禁用 Apache 的这种行为,以便在没有Upgrade标头的情况下发送响应。
谁知道如何从 .htaccess 文件中禁用它?我已经找到了这个解决方案:
Header unset Upgrade
Run Code Online (Sandbox Code Playgroud)
但这不是一个好方法,因为有时我需要Upgrade从我的代码中输出一个自定义标题(需要将固件升级广播到某些热敏打印机设备)。
谢谢
我们正在开发一个 Android 应用程序,它应该使用 Http/2 连接到我们的 Azure 应用服务。在 Azure 应用服务上,我们使用以下博客文章中的步骤启用了 Http/2:https : //blogs.msdn.microsoft.com/appserviceteam/2018/04/13/annoucing-http2-support-in-azure -应用服务/
我们的请求使用 Mutual SSL 进行保护,因此应用程序必须发送它的客户端证书。
当我们尝试使用 OkHttp 执行对我们的应用服务的调用时,我们总是收到以下错误和堆栈跟踪。当我们尝试使用相同的 Android 代码调用 twitter api 时,这是有效的。
有没有人知道如何解决这个问题?
我们使用的是 OkHttp 3.10.0 版。
堆栈跟踪:
06-08 15:54:00.173 31318-31351/be.wgkovl.evdt W/be.wgkovl.evdt.utils.BaseService:流被重置:HTTP_1_1_REQUIREDokhttp3.internal.http2.StreamResetException:流被重置:HTTP_1RED_1
在 okhttp3.internal.http2.Http2Stream.takeResponseHeaders(Http2Stream.java:153) ~[na:0.0]
在 okhttp3.internal.http2.Http2Codec.readResponseHeaders(Http2Codec.java:125) ~[na:0.0]
在 okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.java:88) ~[na:0.0]
在 okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) ~[na:0.0]
在 okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:45) ~[na:0.0]
在 okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) ~[na:0.0]
在 okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121) ~[na:0.0]
在 okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93) ~[na:0.0]
在 okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) ~[na:0.0]
在 okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121) ~[na:0.0]
在 okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93) ~[na:0.0]
在 okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) ~[na:0.0]
在 okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:126) ~[na:0.0]
在 okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) ~[na:0.0]
在 okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121) … gRPC 客户端流/双向流是如何通过 HTTP/2 实现的?
服务器流传输是有道理的,因为它可以利用服务器推送向请求发送多个响应,但我不清楚它如何像通过 websocket 那样通过 HTTP/2 进行双向消息传递。
当我使用Application Load Balancer (ALB)将我的 Web 应用程序部署到 AWS 环境时,我的一些 Web 服务端点不会返回任何数据,并且我的 Chrome 浏览器会为一些 http 调用报告此错误:ERR_SPDY_PROTOCOL_ERROR
找到这个建议后,我在我的 ALB 配置中禁用了HTTP/2支持,现在一切正常。
为什么我必须在我的 ALB 中禁用HTTP/2?这里的根本问题是什么?我是否需要更改 Web 服务代码中的某些内容才能使用HTTP/2?
更新
以下是响应头:
HTTP/1.1 200
Date: Wed, 09 Jan 2019 21:39:13 GMT
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Locations Reached: Data to populate locations reached map
Run Code Online (Sandbox Code Playgroud)
正如下面的一个答案所建议的那样,罪魁祸首可能是我的一个标题(到达的位置)在名称中有一个空格,这是无效/格式错误的。我会确保空格被破折号取代。
load-balancing amazon-web-services amazon-elb http2 aws-application-load-balancer
一些描述 http/2 的文章称赞它是双向和全双工的。
AFAIK 双向意味着通信是双向的,所以双工本质上是双向的,是吗?
双工可以由一个在某些特定点反转的单工流创建(半双工),也可以创建为两个相反的单工流(全双工)。
也许双向是关于如何发起消息交换?在 http/1 中,只有客户端可以通过向服务器发送请求来启动,服务器在其中返回响应。在 http/2 中,服务器可以发送(推送)一些资源而无需明确要求它。但是我们可以Server-sent events在http/1.1中使用(也就是说,在客户端和服务器上都做了一些配置后,如果它愿意,服务器可以推送消息,但它仍然是通过http/1.1协议)。
当您考虑它时,您可能会注意到 http/1 也是双向和全双工的(因为在半双工中流水线是不可能的)。所以从 http/2 的角度来看这里没有变化。
发生变化的是 http/1 要求响应按照请求的确切顺序到达。http/2 通过流和多路复用提升了这一点。
我捕获了 HTTP/2 fetching https://example.com。捕获的初始行上的三个条目是:
HyperText Transfer Protocol 2
Stream: Magic
Stream: SETTINGS, Stream ID: 0, Length 18
Stream: WINDOW_UPDATE, Stream ID: 0, Length 4
Run Code Online (Sandbox Code Playgroud)
我应该如何参考这些?我可以说它们是来自stream 0和的三个初始帧吗Magic,SETTINGS和WINDOW_UPDATE帧?
我想使用 gRPC 公开一个接口,用于在两个服务之间双向传输大型数据集(~100 MB)。因为默认情况下 gRPC 强加了 4 MB 的消息大小限制,所以似乎首选的方法是手动编码块的流,并在接收端重新组装它们 [ 1 ][ 2 ]。
但是,gRPC 还允许通过grpc.max_receive_message_length和增加消息大小限制grpc.max_send_message_length,从而可以直接传输大小高达 ~2 GB 的消息,而无需任何手动分块或流式传输。快速测试表明,这种更简单的方法在性能和吞吐量方面同样有效,使其看起来更适合此用例。假设整个数据集都需要在内存中。
这些方法中的一种是否天生比另一种更好?更简单的非分块方法是否有任何潜在的副作用?我是否可以依靠较低层的 MTU 相关分片足以避免网络延迟和其他障碍?
参考: