- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
代理,其实全称应该叫做代理服务器,它是客户端与服务器之间得中间层,本质上来说代理就是一个服务器,在HTTP的链路中插入的一个中间环节,就是代理服务器啦。所谓的代理服务就是指:服务本身不生产内容,而是处于中间位置转发上下游的请求和响应,具有双重身份。面向下游的用户时,表现为服务器,代表源服务器响应客户端的请求。而面上上游源服务器时,又表现为客户端,代表客户端发送请求.
我们发现,其实代理服务器在中间既是客户端,又是服务器,那么其实他就可以在请求或响应经过它的时候,夹带上一些额外的东西.
代理有很多种类,比如匿名代理、透明代理、正向代理、反向代理.
而我们最常听说的,就是正向代理和反向代理,其中正向代理其实代理的是客户端,服务器不知道真正的客户端是谁,客户端对服务器隐蔽。而反向代理则代理的是服务器,客户端不知道源服务器是谁。而反向代理则是现代服务器技术的基本实践了,几乎各个应用的服务器都会搞一下反向代理.
反向代理在传输链路中更接近源服务器,为源服务器提供代理服务,我们今天讲的其实就是反向代理.
我们简单的了解了代理的概念,那么接下来我们看看代理有啥用处呢?或者说反向代理的作用是什么呢?
我记得我之前说过,在最开始讲互联网分层模型的时候,计算机科学领域里的任何问题,都可以通过引入一个中间层来解决,如果一个中间层解决不了,那就再加一层。哈哈哈哈,所以不仅仅是在TCP/IP模型中是这样,在代理中也是这样.
代理(以下所有的“代理”都指反向代理,不再重复)一个最基本的功能就是负载均衡,因为反向代理在面向客户端得时候屏蔽了真实服务器,客户端看到的只是代理服务器,源服务器究竟有多少台、是哪些IP地址都不知道,于是服务器就可以掌握请求分发的大权,决定由哪一台隐藏在背后的服务器去响应请求.
代理中常用的负载均衡算法大概有轮询、一致性哈希等,大家了解下就行了,这些算法的目标都是尽量把外部的流量合理的分散到多台源服务器,提高系统的整体资源利用率和性能.
在负载均衡的同时,代理服务还可以执行更多的功能,比如:
代理的好处很多,因为它欺上瞒下的特点,所以对上下游都隐藏了很多信息,但是如果双方想要获得这些信息怎么办呢?
首先,代理服务器需要用 Via 字段来表明代理的身份.
Via是一个通用头字段,客户端和服务器都可以使用,没经过一个代理节点,代理服务器就会把信息增加到字段末尾,有点像盖章的感觉。如果通信链路中又很多代理,就会在Via中形成一个链表,这样就可以知道报文究竟经过了多少环节才到达了目的地.
假设我们的中间代理有两个:proxy1和proxy2,当客户端发送请求到服务器时,会经过这两个代理,那么Via字段就是这样的:
Via: proxy1, proxy2
等到服务器发送响应报文的时候,到达客户端的就是这样的:
Via: proxy2, proxy1
但是Via字段只解决了 客户端和源服务器判断是否存在代理的问题 ,还不能知道对方的真实信息.
但是,服务器的信息必然应该是保密的,一般不会让客户端知道。但是往往服务器要知道客户端的一些真实信息,比如IP地址啥的,用来做用户画像,统计分析等等.
可惜的是,HTTP标准里并没有定义相关的头字段,但是已经出现了很多“事实上的标准”,最常用的两个头字段就是“ X-Forwarded-For ”和“ X-Real-IP ”.
"X-Forwarded-For"的字面意思是“为谁而转发”,形式上和“Via”差不多,也是没经过一个代理节点就会在字段里追加一个信息。但“Via”追加的是代理主机名或者域名,而“X-Forwarded-For”追加的是请求方的IP地址。所以在字段最左边的IP地址就是客户端的地址.
“X-Real-IP”是另一种获取客户端真实 IP 的手段,它的作用很简单,就是记录客户端 IP 地址,没有中间的代理信息,相当于是“X-Forwarded-For”的简化版。如果客户端和源服务器之间只有一个代理,那么这两个字段的值就是相同的.
除了"X-Forwarded-For"和“X-Real-IP”还有“X-Forwarded-Host”和“X-Forwarded-Proto”,它们的作用与“X-Real-IP”类似,只记录客户端的信息,分别是客户端请求的原始域名和原始协议名.
有了"X-Forwarded-For"等字段,源服务器就可以拿到准确的客户端信息了。但是你发现一个问题没有,这些信息都是写在HTTP头里的,换句话说,通过这些字段来操作代理信息就需要解析HTTP头,然后再在解析的头里去修改HTTP头,这对代理来说就需要较高的成本了,我本来需要做的就只是转发一下,现在你还要让我读一下,改一下,肯定会降低代理转发的性能,原来我一秒能传几百次,结果经历了解析和修改的过程,只能传几十次了.
再有一个就是,“X-Forwarded-For”等字段,必须要修改原始报文,但是其实有些情况是不允许甚至不可能修改的,比如应用HTTPS加密报文,要知道现在正经的浏览器站点,几乎全部使用HTTPS.
所以就出现了一个专门的“代理协议”(The PROXY protocol),它由知名的代理软件 HAProxy 所定义,也是一个“事实标准”,被广泛采用(注意并不是 RFC噢)。“代理协议”有 v1 和 v2 两个版本,v1 和 HTTP 差不多,也是明文,而 v2 是二进制格式。今天只介绍比较好理解的 v1,它在 HTTP 报文前增加了一行 ASCII 码文本,相当于又多了一个头.
这一行文本其实非常简单,开头必须是“PROXY”五个大写字母,然后是“TCP4”或者“TCP6”,表示客户端的 IP 地址类型,再后面是请求方地址、应答方地址、请求方端口号、应答方端口号,最后用一个回车换行(\r\n)结束。就像这样:
PROXY TCP4 1.1 . 1.1 2.2 . 2.2 55555 80 \r\n GET / HTTP/ 1.1 \r\n Host: www.zaking.com\r\n \r\n
服务器看到这样的报文,只需要解析第一行就可以拿到客户端地址了,不需要再去解析整个HTTP报文,省了很多数据.
不过代理协议并不支持“X-Forwarded-For”的链式地址形式,所以拿到客户端地址后再如何处理就需要代理服务器与后端自行约定.
本篇,我们了解了下代理是什么,以及反向代理在HTTP中所应用的一些请求头。理解上来说并不复杂,就是记录代理链路中必要的信息。那么下面我们来通过问题回忆一下本篇的内容和知识.
好啦,本篇就到这里了,下一篇是关于HTTP/1.1的最后一篇文章啦~~ 。
最后此篇关于真正“搞”懂HTTP协议11之代理服务的文章就讲到这里了,如果你想了解更多关于真正“搞”懂HTTP协议11之代理服务的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
据我了解,HTTP POST 请求的正文大小没有限制。因此,客户端可能会在一个 HTTP 请求中发送 千兆字节 的数据。现在我想知道 HTTP 服务器应该如何处理此类请求。 Tomcat 和 Jett
在了解Web Deploy我遇到了一些讨论 http://+:80 和 http://*:80 的 netsh.exe 命令。这些是什么意思? 最佳答案 引自URLPrefix Strings (Wi
假设我有一个负载均衡器,然后是 2 个 Web 服务器,然后是一个负载均衡器,然后是 4 个应用程序服务器。 HTTP 响应是否遵循与 HTTP 请求服务相同的路径? 最佳答案 按路径,我假设您是网络
我有一个带有 uri /api/books/122 的资源,如果在客户端为此资源发送 HTTP Delete 时该资源不存在,那么相应的响应代码是什么这个 Action ?是不是404 Not Fou
是否有特定的(或约定的)HTTP 响应消息(或除断开连接之外的其他操作)来阐明服务器不接受 pipelined HTTP requests ? 我正在寻找能让客户端停止流水线化它的请求并分别发送每个请
在了解Web Deploy我遇到了一些讨论 http://+:80 和 http://*:80 的 netsh.exe 命令。这些是什么意思? 最佳答案 引自URLPrefix Strings (Wi
我有一个带有 uri /api/books/122 的资源,如果在客户端为此资源发送 HTTP Delete 时该资源不存在,那么相应的响应代码是什么这个 Action ?是不是404 Not Fou
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 8 年前。 Improve this qu
我使用 Mule 作为 REST API AMQP。我必须发送自定义请求方法:“PRINT”,但我收到: Status Code: 400 Bad Request The request could
我需要针对具有不同 HTTP 响应代码的 URL 测试我的脚本。我如何获取响应代码 300、303 或 307 等的示例/示例现有 URL? 谢谢! 最佳答案 您可以使用 httpbin为此目的。 例
我正在尝试编写一个程序来匹配 HTTP 请求及其相应的响应。似乎在大多数情况下一切都运行良好(当传输完全有序时,即使不是,通过使用 TCP 序列号)。 我发现的唯一问题是当我有流水线请求时。在那之后,
RESTful Web Services鼓励使用 HTTP 303将客户端重定向到资源的规范表示。它仅在 HTTP GET 的上下文中讨论主题。 这是否也适用于其他 HTTP 方法?如果客户端尝试对非
当使用chunked HTTP传输编码时,为什么服务器需要同时写出chunk的字节大小并且后续的chunk数据以CRLF结尾? 这不会使发送二进制数据“CRLF-unclean”和方法有点多余吗? 如
这个问题在这里已经有了答案: Is it acceptable for a server to send a HTTP response before the entire request has
如果我向同一台服务器发出多个 HTTP Get 请求并收到每个请求的 HTTP 200 OK 响应,我如何使用 Wireshark 判断哪个请求映射到哪个响应? 目前看起来像是发出了一个 http 请
func main() { http.HandleFunc("/", handler) } func handler(w http.ResponseWriter, r http.Request
我找不到有值(value)的 NodeJS with Typescript 教程,所以我在无指导下潜入水中,果然我有一个问题。 我不明白这两行之间的区别: import * as http from
问一个关于Are HTTP headers case-sensitive?的问题,如果 HTTP 方法区分大小写,大多数服务器如何处理“get”或“post”与“GET”或“POST”? 例如,看起来
我正在使用ASP.NET,在其中我通过动词GET接收查询,该应用程序专用于该URL。 该代码有效,但是如果用户发送的密码使http 200无效,请回答我,并在消息的正文中显示“Fail user or
Closed. This question needs details or clarity。它当前不接受答案。 想改善这个问题吗?添加详细信息,并通过editing this post阐明问题。 9
我是一名优秀的程序员,十分优秀!