我有一个在 nginx 代理后面运行的 node.js 服务器。 node.js 在端口 3000 上运行 HTTP 1.1(无 SSL)服务器。两者都在同一台服务器上运行。
我最近将 nginx 设置为使用带有 SSL (h2) 的 HTTP2。看来 HTTP2 确实已启用并正常工作。
但是,我想知道代理连接 (nginx <--> node.js) 使用 HTTP 1.1 的事实是否会影响性能。也就是说,我是否因为我的内部连接是 HTTP 1.1 而错过了 HTTP2 在速度方面的优势?
-->
最佳答案
一般来说,HTTP/2 最大的直接好处是 multiplexing 提供的速度提升。对于经常受到高延迟(即缓慢的往返速度)阻碍的浏览器连接。这些还减少了多个连接的需求(和费用),这是一种尝试在 HTTP/1.1 中实现类似性能优势的解决方法。
对于内部连接(例如,充当反向代理的网络服务器和后端应用服务器之间),延迟通常非常非常低,因此 HTTP/2 的速度优势可以忽略不计。此外,每个应用服务器通常已经是一个单独的连接,因此这里也没有任何好处。
因此,仅在边缘支持 HTTP/2,您将获得大部分的性能优势。这是一个相当常见的设置 - 类似于 HTTPS 经常在反向代理/负载平衡器上终止而不是一直通过的方式。
然而,从始至终支持 HTTP/2 有潜在的好处。例如,它可以允许服务器从应用程序一路推送。由于 HTTP/2 的二进制性质和 header 压缩,减少最后一跳的数据包大小也有潜在的好处。尽管与延迟一样,带宽对于内部连接而言通常不是问题,因此其重要性是值得商榷的。最后,有些人认为反向代理连接 HTTP/2 连接到 HTTP/2 连接的工作比连接到 HTTP/1.1 连接的工作少,因为不需要将一种协议(protocol)转换为另一种协议(protocol),尽管我对此持怀疑态度。很明显,因为它们是单独的连接(除非它只是充当 TCP 直通代理)。所以,对我来说,端到端 HTTP/2 的主要原因是允许端到端服务器推送,但是 even that is probably better handled with HTTP Link Headers and 103-Early Hints due to the complications in managing push across multiple connections而且我不知道有任何 HTTP 代理服务器会支持这一点(后端支持 HTTP/2 的支持太少了,更不用说像这样链接 HTTP/2 连接了)所以你需要一个第 4 层负载均衡器来转发 TCP 打包程序而不是链接 HTTP 请求 - 这会带来其他复杂性。
目前,虽然服务器仍在添加支持并且服务器推送使用率很低(并且仍在试验以定义最佳实践),但我建议仅在端点使用 HTTP/2。 Nginx 在撰写本文时也不支持 HTTP/2 用于 ProxyPass 连接(尽管 Apache 支持),并且有 no plans to add this ,并且他们提出了一个有趣的观点,即单个 HTTP/2 连接是否会引入缓慢(强调我的):
Is HTTP/2 proxy support planned for the near future?
Short answer:
No, there are no plans.
Long answer:
There is almost no sense to implement it, as the main HTTP/2 benefit is that it allows multiplexing many requests within a single connection, thus [almost] removing the limit on number of simalteneous requests - and there is no such limit when talking to your own backends. Moreover, things may even become worse when using HTTP/2 to backends, due to single TCP connection being used instead of multiple ones.
On the other hand, implementing HTTP/2 protocol and request multiplexing within a single connection in the upstream module will require major changes to the upstream module.
Due to the above, there are no plans to implement HTTP/2 support in the upstream module, at least in the foreseeable future. If you still think that talking to backends via HTTP/2 is something needed - feel free to provide patches.
最后,还应该注意的是,虽然浏览器需要 HTTP/2 (h2) 的 HTTPS,但大多数服务器不需要,因此可以支持 HTTP 上的最后一跳 (h2c)。因此,如果 Node 部分不存在端到端加密(通常不存在),则不需要端到端加密。但是,根据后端服务器相对于前端服务器的位置,如果流量将通过不安全的网络传输(例如,CDN 到 Internet 上的源服务器),那么即使对于这种连接也应该考虑使用 HTTPS。
2021 年 8 月编辑
HTTP/1.1 基于文本而不是 binary确实使它容易受到各种请求走私攻击。在 Defcon 2021 PortSwigger demonstrated a number of real-life attacks ,主要与将前端 HTTP/2 请求降级为后端 HTTP/1.1 请求时的问题有关。这些可能主要通过始终使用 HTTP/2 来避免,但鉴于当前支持前端服务器和 CDN 对后端使用 HTTP/2,以及支持 HTTP/2 的后端,这似乎需要很长时间因为这很常见,前端 HTTP/2 服务器确保这些攻击不可被利用似乎是更现实的解决方案。
关于node.js - HTTP2 与 node.js 在 nginx 代理后面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41637076/
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou
我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur
1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里
Rails中有没有一种方法可以提取与路由关联的HTTP动词?例如,给定这样的路线:将“users”匹配到:“users#show”,通过:[:get,:post]我能实现这样的目标吗?users_path.respond_to?(:get)(显然#respond_to不是正确的方法)我最接近的是通过执行以下操作,但它似乎并不令人满意。Rails.application.routes.routes.named_routes["users"].constraints[:request_method]#=>/^GET$/对于上下文,我有一个设置cookie然后执行redirect_to:ba
我正在使用Heroku(heroku.com)来部署我的Rails应用程序,并且正在构建一个iPhone客户端来与之交互。我的目的是将手机的唯一设备标识符作为HTTPheader传递给应用程序以进行身份验证。当我在本地测试时,我的header通过得很好,但在Heroku上它似乎去掉了我的自定义header。我用ruby脚本验证:url=URI.parse('http://#{myapp}.heroku.com/')#url=URI.parse('http://localhost:3000/')req=Net::HTTP::Post.new(url.path)#boguspara
我试图在我的网站上实现使用Facebook登录功能,但在尝试从Facebook取回访问token时遇到障碍。这是我的代码:ifparams[:error_reason]=="user_denied"thenflash[:error]="TologinwithFacebook,youmustclick'Allow'toletthesiteaccessyourinformation"redirect_to:loginelsifparams[:code]thentoken_uri=URI.parse("https://graph.facebook.com/oauth/access_token
我是Ruby的新手。我试过查看在线文档,但没有找到任何有效的方法。我想在以下HTTP请求botget_response()和get()中包含一个用户代理。有人可以指出我正确的方向吗?#PreliminarycheckthatProggitisupcheck=Net::HTTP.get_response(URI.parse(proggit_url))ifcheck.code!="200"puts"ErrorcontactingProggit"returnend#Attempttogetthejsonresponse=Net::HTTP.get(URI.parse(proggit_url)
有人知道如何将capybarapoltergeist的用户代理覆盖到移动用户代理以进行测试吗?我发现了一些有关为seleniumwebdriver配置它的信息:http://blog.plataformatec.com.br/2011/03/configuring-user-agents-with-capybara-selenium-webdriver/这在capybara闹鬼中怎么可能? 最佳答案 请参阅poltergeistgithub页面上的链接:https://github.com/teampoltergeist/polte
我正在使用Ruby/Mechanize编写一个“自动填写表格”应用程序。它几乎可以工作。我可以使用精彩CharlesWeb代理以查看服务器和我的Firefox浏览器之间的交换。现在我想使用Charles查看服务器和我的应用程序之间的交换。Charles在端口8888上代理。假设服务器位于https://my.host.com。.一件不起作用的事情是:@agent||=Mechanize.newdo|agent|agent.set_proxy("my.host.com",8888)end这会导致Net::HTTP::Persistent::Error:...lib/net/http/pe