请求从客户端到服务器的过程简单分析

当我们在客户端(以浏览器为例)使用域名发送一个HTTP请求的时候,DNS协议会尝试将域名解析为对应的IP。(我们知道每一个台服务器都可以通过ip和端口直接被访问。但是,用户对于由数字组成的ip是很难有记忆点的,所以就出现了域名,域名可以映射到ip。那么域名是如何与ip进行映射的,就需要DNS协议的帮忙

1.OS会先检查自己本地的hosts文件是否有这个网址映射关系,如果有,就先调用这个IP地址映射,完成域名解析。

Linux下默认hosts文件位置是/etc/hosts

Windows下默认是c:\windows\system32\drivers\etc\hosts

2.如果hosts里没有这个域名的映射,则查找本地DNS解析器缓存,是否有这个网址映射关系,如果有,直接返回,完成域名解析。

3.如果hosts与本地DNS解析器缓存都没有相应的网址映射关系,会在本地DNS服务器查询,此服务器收到查询时,如果要查询的域名,包含在本地配置区域资源中,则返回解析结果给客户机,完成域名解析,此解析具有权威性。

在Linux下,DNS客户机配置文件为/etc/resolv.conf

Linux下的DNS服务器在进行DNS解析的时候,默认的解析超时时间是5秒,默认的重试次数是两次。我们可以看到,当DNS解析慢的时候,我们可能在DNS解析的过程中发费10秒钟,这在有些时候是很致命的。

在我们使用HttpCient等工具请求第三方接口(比如百度的定位接口)的时候,会出现超时非常严重的情况,我们在排查的时候发现我们已经设置各种超时时间,读超时,链接超时等等,但是还是出现了超时很严重的情况,这是为什么呢,因为HttpClient并没有提供一个线程运行总时长的超时时间配置,这导致了DNS解析可能花了10秒才完成,导致了调用时间非常长。那么如何去解决DNS解析失败的问题呢?在使用OKHTTP时,我们可以使用HTTPDNS来解决,这样就会变成IP直连,省去了DNS解析的步骤,但是这样会有一个问题,就是当你变成了IP直连的时候,连接无法复用了,这个时候是有问题的,但是好在OKHTTP在底层帮我们实现了链接复用。而对于HTTPClient,也可以使用HTTPDNS解决DNS解析失败,但是是否会帮我们实现链接复用,还没有测试过。

在Windows下,DNS的配置就不多说了。在“控制面板”-“网络”中配置。

4.如果要查询的域名,不由本地DNS服务器区域解析,但该服务器已缓存了此网址映射关系,则调用这个IP地址映射,完成域名解析,此解析不具有权威性。

5、如果本地DNS服务器本地区域文件与缓存解析都失效,则根据本地DNS服务器的设置(是否设置转发器)进行查询,如果未用转发模式,本地DNS就把请求发至13台根DNS,根DNS服务器收到请求后会判断这个域名(.com)是谁来授权管理,并会返回一个负责该顶级域名服务器的一个IP。本地DNS服务器收到IP信息后,将会联系负责.com域的这台服务器。这台负责.com域的服务器收到请求后,如果自己无法解析,它就会找一个管理.com域的下一级DNS服务器地址(qq.com)给本地DNS服务器。当本地DNS服务器收到这个地址后,就会找qq.com域服务器,重复上面的动作,进行查询,直至找到www.qq.com主机。

6、如果用的是转发模式,此DNS服务器就会把请求转发至上一级DNS服务器,由上一级服务器进行解析,上一级服务器如果不能解析,或找根DNS或把转请求转至上上级,以此循环。不管是本地DNS服务器用是是转发,还是根提示,最后都是把结果返回给本地DNS服务器,由此DNS服务器再返回给客户机。

从客户端到本地DNS服务器是属于递归查询,而DNS服务器之间的交互查询就是迭代查询。

而在如今的后端架构中,要做到高可用,服务器都是多个节点的。通过DNS解析出来的IP其实一般都不是服务器的IP,而是反向代理服务器的IP,当前求到达反向代理服务器的时候,反向代理服务器会根据负载均衡策略将请求分发到相应的服务器上。

但是随之有一个问题,如果代理服务器挂掉了,那么就会导致所有的请求都到不了服务器,所以我们要做到代理服务器的高可用。而要做到代理服务器高可用,对于我们常用的代理服务器NG来说,我们可以采用keepalived结合NG来做到高可用。

keepalived分别安装在主机A和备机B上,双方启动以后,主机A就会向局域网内发送arp响应包,该arp响应包的ip地址被设为vip,mac地址被设为macA,所有接收到此报文的电脑就会将这个对应关系写入自己的ARP缓存表中,下次访问vip时,就会根据对应的mac地址访问到主机A当备机B监听到主机A挂了的时候,就会向局域网内发送arp响应包,并将arp响应包的ip地址设为vip,mac地址设为macB,所有接收的此报文的电脑就会将这个对应关系写入自己的ARP缓存表中,下次访问vip时,就会根据对应的mac地址访问到备机B这样就实现了高可用。

从上述分析中,我们可以得知,一个客户端请求要到达服务器,可能会经过层层转发,那么就会有一个问题,我们要怎么去获取用户的真实IP呢?

在业界中,我们会使用X-Forwarded-For这个请求头来帮助我们获取到客户端真实IP.它最开始是由 Squid 这个缓存代理软件引入,用来表示 HTTP 请求端真实 IP。如今它已经成为事实上的标准,被各大 HTTP 代理、负载均衡等转发服务广泛使用,并被写入RFC 7239(Forwarded HTTP Extension)标准之中。

请求头的格式如下

X-Forwarded-For: client, proxy1, proxy2

最开始的ip代表最远端的客户端IP,接下来依次是每层代理的IP。
当服务器要获取客户端真实IP的时候,我们只需要获取X-Forwarded-For的第一个IP即可。

一般代理服务器处理X-Forwarded-For这个请求头都是这样的。

获取上一层传递过来的X-Forwarded-For请求头
通过获取remote_addr获取上一层的真实ip,将上一层的真实ip加入到X-Forwarded-For请求头尾部,然后再将X-Forwarded-For请求体转发给下一层。

但是正因为这样的机制,导致了我们只要在客户端伪造X-Forwarded-For请求头,就会导致服务器拿不到正确的客户端IP。

我们要如何应对伪造X-Forwarded-For请求头的情况呢?

我们知道Remote Address是无法伪造的,这个IP一定是和目标主机完成TCP连接的地址。
因为建立 TCP 连接需要三次握手,如果伪造了源 IP,无法建立 TCP 连接,更不会有后面的 HTTP 请求。在正常的TCP/IP通信中,是可以伪造数据包来源 IP 的,但这会让发送出去的数据包返回到伪造的IP上,无法实现正常的通信。所以我们可以说Remote Address一定是真实的。

因此,我们可以将首层代理将握手 IP 设置为 HTTP 请求头的 X-Real-IP(个人更建议是一个更生僻的请求头) 中向后传递。后面的每一层原样传递下去(有则原样传递,无则设置为握手 IP )

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
flow是指从客户端服务器发起的会话过程。在计算机网络中,信息的流动通常是双向的,分为从客户端服务器请求流,以及从服务器客户端的响应流。而flow只针对从客户端服务器请求流有效。 在一个典型的会话中,客户端首先向服务器发送请求服务器接收并处理这个请求,并返回相应的响应给客户端。在这个过程中,请求流是从客户端发出,响应流是从服务器返回。在这个请求-响应过程中,flow起到了重要的作用。 通过flow,我们可以追踪和控制从客户端服务器的会话。它可以提供有关会话的各个方面的信息,例如请求的发送时间、请求的内容、请求到达服务器的时间、服务器的响应时间、响应的内容等。通过分析flow的数据,我们可以了解请求和响应的具体细节,可以用于性能优化、故障排查以及安全检测等。 然而,需要明确的是,flow只对从客户端服务器发起的会话有效。也就是说,它只能捕获和分析客户端发起的请求流,并记录相应的响应流。而对于从服务器客户端的响应流则无法进行同样的分析。这是因为flow是一种单向的概念,只针对特定方向的数据流动。 总而言之,flow是用于从客户端服务器发起的会话的分析工具。它提供了关于请求和响应的详细信息,用于追踪、分析和优化会话的过程。然而,需要注意的是,flow只对从客户端发出的请求流有效,无法对响应流进行同等的分析

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值