代理,其实全称应该叫做代理服务器,它是客户端与服务器之间得中间层,本质上来说代理就是一个服务器,在HTTP的链路中插入的一个中间环节,就是代理服务器啦。所谓的代理服务就是指:服务本身不生产内容,而是处于中间位置转发上下游的请求和响应,具有双重身份。面向下游的用户时,表现为服务器,代表源服务器响应客户端的请求。而面上上游源服务器时,又表现为客户端,代表客户端发送请求。

  我们发现,其实代理服务器在中间既是客户端,又是服务器,那么其实他就可以在请求或响应经过它的时候,夹带上一些额外的东西。

  代理有很多种类,比如匿名代理、透明代理、正向代理、反向代理。

  而我们最常听说的,就是正向代理和反向代理,其中正向代理其实代理的是客户端,服务器不知道真正的客户端是谁,客户端对服务器隐蔽。而反向代理则代理的是服务器,客户端不知道源服务器是谁。而反向代理则是现代服务器技术的基本实践了,几乎各个应用的服务器都会搞一下反向代理。

  反向代理在传输链路中更接近源服务器,为源服务器提供代理服务,我们今天讲的其实就是反向代理。

一、代理的作用

  我们简单的了解了代理的概念,那么接下来我们看看代理有啥用处呢?或者说反向代理的作用是什么呢?

  我记得我之前说过,在最开始讲互联网分层模型的时候,计算机科学领域里的任何问题,都可以通过引入一个中间层来解决,如果一个中间层解决不了,那就再加一层。哈哈哈哈,所以不仅仅是在TCP/IP模型中是这样,在代理中也是这样。

  代理(以下所有的“代理”都指反向代理,不再重复)一个最基本的功能就是负载均衡,因为反向代理在面向客户端得时候屏蔽了真实服务器,客户端看到的只是代理服务器,源服务器究竟有多少台、是哪些IP地址都不知道,于是服务器就可以掌握请求分发的大权,决定由哪一台隐藏在背后的服务器去响应请求。

  代理中常用的负载均衡算法大概有轮询、一致性哈希等,大家了解下就行了,这些算法的目标都是尽量把外部的流量合理的分散到多台源服务器,提高系统的整体资源利用率和性能。

  在负载均衡的同时,代理服务还可以执行更多的功能,比如:

  • 健康检查:使用“心跳”等机制监控后端服务器,发现有故障就及时“踢出”集群,保证服务高可用;
  • 安全防护:保护被代理的后端服务器,限制 IP 地址或流量,抵御网络攻击和过载;
  • 加密卸载:对外网使用 SSL/TLS 加密通信认证,而在安全的内网不加密,消除加解密成本;
  • 数据过滤:拦截上下行的数据,任意指定策略修改请求或者响应;
  • 内容缓存:暂存、复用服务器响应。

二、代理相关头字段

  代理的好处很多,因为它欺上瞒下的特点,所以对上下游都隐藏了很多信息,但是如果双方想要获得这些信息怎么办呢?

  首先,代理服务器需要用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中所应用的一些请求头。理解上来说并不复杂,就是记录代理链路中必要的信息。那么下面我们来通过问题回忆一下本篇的内容和知识。

  1. 我们学习了Via以及X-Forwarded-For、X-Real-IP等关于代理的字段,那么其中哪些是HTTP协议所定义的?哪些只是“事实标准”呢?
  2. 除了X-Forwarded-For、X-Real-IP你还知道哪些关于代理的头字段呢?
  3. 代理协议是啥东东?

  好啦,本篇就到这里了,下一篇是关于HTTP/1.1的最后一篇文章啦~~

真正“搞”懂HTTP协议11之代理服务的更多相关文章

  1. 搞懂分布式技术11:分布式session解决方案与一致性hash

    搞懂分布式技术11:分布式session解决方案与一致性hash session一致性架构设计实践 原创: 58沈剑 架构师之路 2017-05-18 一.缘起 什么是session? 服务器为每个用 ...

  2. 真正“搞”懂HTTP协议02之空间穿梭

    时隔四年,这个系列鸽了四年,我终于觉得我可以按照自己的思路和想法把这个系列完整的表达出来了. 想起四年前,那时候还是2018年的六月份,那时候我还工作不到两年,那时候我翻译了RFC2616的部分内容, ...

  3. 真正“搞”懂http协议01—背景故事

    去年读了<图解HTTP>.<图解TCP/IP>以及<图解网络硬件>但是读了之后并没有什么深刻的印象,只是有了一层模糊的脉络,刚好最近又接触了一些有关http的相关内 ...

  4. 真正“搞”懂HTTP协议03之时间穿梭

    上一篇我们简单的介绍了一下DoD模型和OSI模型,还着重的讲解了TCP的三次握手和四次挥手,让我们在空间层面,稍稍宏观的了解了HTTP所依赖的底层模型,那么这一篇,我们来追溯一下HTTP的历史,看一看 ...

  5. 搞懂Redis协议RESP

    RESP (REdis Serialization Protocal) Redis客户端和服务端之间通信的协议.它很简单,建立在TCP协议上,提供简单.高性能.可读性强的数据序列化的规范和语义. 5种 ...

  6. 搞懂分布式技术4:ZAB协议概述与选主流程详解

    搞懂分布式技术4:ZAB协议概述与选主流程详解 ZAB协议 ZAB(Zookeeper Atomic Broadcast)协议是专门为zookeeper实现分布式协调功能而设计.zookeeper主要 ...

  7. 搞懂分布式技术2:分布式一致性协议与Paxos,Raft算法

    搞懂分布式技术2:分布式一致性协议与Paxos,Raft算法 2PC 由于BASE理论需要在一致性和可用性方面做出权衡,因此涌现了很多关于一致性的算法和协议.其中比较著名的有二阶提交协议(2 Phas ...

  8. [转帖]USB-C和Thunderbolt 3连接线你搞懂了吗?---没搞明白.

    USB-C和Thunderbolt 3连接线你搞懂了吗? 2018年11月25日 07:30 6318 次阅读 稿源:威锋网 3 条评论 按照计算行业的风潮,USB Type-C 将会是下一代主流的接 ...

  9. 搞懂分布式技术9:Nginx负载均衡原理与实践

    搞懂分布式技术9:Nginx负载均衡原理与实践 本篇摘自<亿级流量网站架构核心技术>第二章 Nginx负载均衡与反向代理 部分内容. 当我们的应用单实例不能支撑用户请求时,此时就需要扩容, ...

  10. 一泡尿的时间,快速读懂QUIC协议

    1.TCP协议到底怎么了? 现时的互联网应用中,Web平台(准确地说是基于HTTP及其延伸协议的客户端/服务器应用)的数据传输都基于 TCP 协议. 但TCP 协议在创建连接之前需要进行三次握手(如下 ...

随机推荐

  1. "xxx cannot be cast to jakarta.servlet.Servlet "报错解决方式

    在做jsp的上机时候同学出现了一个500错误:com.kailong.servlet.ComputeBill cannot be cast to jaka.servlet.Servlet 然后因为我用 ...

  2. SpringCloud(七) - 微信支付

    1.开发文档 微信开发文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1 安全规范:https://pay.weixin.q ...

  3. 从 洛谷P5309 Ynoi2011 初始化 看卡常

    一般情况下,程序运行消耗时间主要与时间复杂度有关,超时与否取决于算法是否正确. 但对于某些题目,时间复杂度正确的程序也无法通过,这时我们就需要卡常数,即通过优化一些操作的常数因子减少时间消耗. 比如这 ...

  4. gorm

    特性 全功能 ORM 关联 (Has One,Has Many,Belongs To,Many To Many,多态,单表继承) Create,Save,Update,Delete,Find 中钩子方 ...

  5. RocketMQ 在同程旅行的落地实践

    本文作者:刘树东 - 同程艺龙技术专家 01/使用概况 同程旅行选择RocketMQ主要基于以下几个方面的考虑: 技术栈:公司主要以 Java 开发为主,因此我们倾向于选择一款用 Java 实现的MQ ...

  6. nginx的域名重写和转发案例

    对url进行重写 location = /tongyong_OTA_1.0.3.bin { rewrite ^(.*)$ http://36.133.87.223/lecode-server/leco ...

  7. python-py文件打包成exe可执行文件

    方法一::打包完成后可以直接被他人使用,他人不用安装python环境的 可以使用pyinstaller模块实现将python项目打包成exe执行文件 """ 先安装模块 ...

  8. vscode+springboot+gradle

    vscode+springboot+gradle 项目搭建 demo 目标:项目中抛弃所有xml格式文件 啰嗦: 一直在用maven作为项目的依赖包管理,最近看到基于Java17 的 Spring f ...

  9. 单点登录系统使用Spring Security的权限功能

    背景 在配置中心增加权限功能 目前配置中心已经包含了单点登录功能,可以通过统一页面进行登录,登录完会将用户写入用户表 RBAC的用户.角色.权限表CRUD.授权等都已经完成 希望不用用户再次登录,就可 ...

  10. Go 每日一库之 go-carbon,优雅的golang日期时间处理库

    Carbon 是一个轻量级.语义化.对开发者友好的 golang 时间处理库,支持链式调用. Carbon 已被 awesome-go 收录, 如果您觉得不错,请给个 star 吧. github.c ...