一个http请求的“奇妙”之旅

272 阅读7分钟

前言

我们或许经常会有这样的疑问,当我们在浏览器中输入一个http请求后,我们的请求会去哪里,经历哪些过程,获取我们请求的资源然后返回给我们。 接下来跟着晴天一起来探索一个http请求获取资源的全过程吧。


http请求

首先先来看一下一个http请求长什么样子

image.png

:这里直接把一个URL地址说成是http请求,方便读者理解,因为更详细的http请求还分为更具体的请求行,消息头和消息体。


http全链路图

介绍完了http请求长什么样子,让我们再来看看具体的请求过程

请求全链路图.png

以下是上图过程讲解

  1. 客户端在浏览器中输入一个URL地址,被浏览器完整封装成一个http请求,发送出去
  2. 为了更快地对用户请求进行响应,http请求首先会经过一个全站加速网络(业内领先的全站加速有阿里云和腾讯云的DCDN)
  3. 经过加速网络后,该http请求想要获取的静态资源会被获取到,而剩下的动态资源(如果需要请求的话)则会进行接下来的回源操作
  4. 回源首先会经过流量网关(目前常用阿里云网关或世纪互联网关),在流量网关层进行限流,防止瞬时请求量过大导致后端服务超负载
  5. 一般情况下流量网关后还会跟有一个业务网关(也是我们常说的API网关),在微服务成为主流服务架构的今天,往往一个请求会涉及多个微服务,这时候就需要一个业务网关帮助我们统一收集响应信息并返回
  6. 微服务目前可以采用KVM部署,容器化部署(K8S),KVM+容器化的组合部署方式
  7. 采用KVM部署方式,需要在流量网关中配置upstream进行导流,多台KVM,则需要在upstream上配置SLB的地址,将所有流量转发到SLB,再由SLB进行选择,将流量转发到哪台KVM上进行响应处理
  8. 采用容器化部署方式,需要在流量网关中配置upstream,此时upstream中配置的地址就是ingress(类似于NGINX)的地址,ingress通过location,将不同的URL路径转发到不同的service(服务)集群上,一个service集群包含多个pod,service自己就可以实现负载均衡,自行选择将该请求转发到哪个pod上进行处理响应
  9. 采用KVM+容器化部署的组合方式,需要在流量网关中配置upstream,此时需要配置两个甚至多个地址(SLB地址和ingress地址),并配置权重比例,来决定总流量在这两种部署方式上的转发比例

补充相关名词的介绍

upstream 负载均衡模块

upstream test {
    ip_hash;// 调度算法
    // 负载均衡
    server 192.168.0.1 weight=3; //权重轮询
    server 192.168.0.2 weight=7; 
}

ingress 一种集群维度暴露服务的方式,ingress可以简单理解为service的service,通过独立的ingress对象来制定请求转发的规则,把请求路由到一个或多个service中,由service决定将请求转给哪个pod处理 image.png

加速网络 对于加速网络不了解的话,可以参考这两篇文章来了解一下 你管这玩意儿叫CDN?你管这玩意儿叫全站加速?


Web防火墙(WAF)

加速网络和流量网关之间的“门神”

++或许你有这样的疑问,网络中全量的http请求都通过加速网络进行加速吗?如果是恶意请求(黑客攻击请求),也需要通过加速网络进行加速吗?这样会不会浪费资源并且使后端服务器瞬时压力过载并宕机?++

让我们带着问题看下面这张图

在http全链路图中,加速网络和流量网关之间还有一位“门神”,就是WAF。WAF可以有效识别Web业务流量的恶意特征,在对流量清洗和过滤后,将正常、安全的流量返回给服务器,避免网站服务器被恶意入侵导致性能异常等问题,从而保障网站的业务安全和数据安全 image.png


容器化部署下请求的过程

采用KVM方式部署请求过程比较简单,这里不做介绍。那么接下来说一下采用容器化部署,请求在容器中处理的过程

  1. 客户端发送HTTP请求,请求将到达Kubernetes集群的入口,通常是Ingress Controller。Ingress Controller是一个负载均衡器,它将根据Ingress资源中定义的规则来路由请求。Ingress资源定义了服务的入口点和路由规则。
  2. Ingress Controller将请求路由到相应的Service。Service是一组Pod的抽象,它们共享同一个网络地址和端口,提供相同的服务。Service可以通过标签选择器来选择Pod,这使得Service能够发现并管理多个Pod,提供负载均衡和故障转移。
  3. Service将请求路由到后端Pod。它使用Selector来选择符合标准的Pod。如果有多个Pod符合选择器的标准,则Service使用一种负载均衡算法来选择要发送请求的Pod。
  4. kube-proxy是Kubernetes集群中的一个网络代理,它会监视Service和Pod的状态,并根据需要更新iptables规则以确保流量正确地路由到后端Pod。
  5. 当Pod中的容器接收到请求时,它会执行相应的处理逻辑,并生成HTTP响应。Pod中的容器可能是单个容器,也可能是多个容器,它们共享同一个Pod的网络和存储资源。
  6. Pod将响应返回给Service。Service将汇总来自多个Pod的响应,并将其返回给Ingress Controller。
  7. Ingress Controller将响应发送回客户端。Ingress Controller可能会执行其他功能,如SSL终止、请求路由、负载均衡等。

写在最后

至此,我们就看完了一个http请求在网络中是进行转发和获取资源的了。如果还有什么疑问,欢迎留言,晴天后续会继续补充说明。

欢迎关注公众号 晴天码字 晴天会持续努力,输出更多有趣且实用的主题。


基础知识补充

NGINX基础介绍

NGINX是一款高性能、开源的Web服务器和反向代理软件。它旨在处理大量流量、提供快速可靠的性能,并提供灵活的配置选项。 NGINX支持广泛的协议,包括HTTP、HTTPS、TCP和UDP。它还包括一系列高级功能,如缓存、SSL/TLS加密、gzip压缩和访问控制。它被各种规模的组织广泛使用,包括一些世界上最大的网站和在线服务

NGINX常用的几大模块及功能

  • ngx_http_core_module:这是NGINX的核心HTTP模块,它处理HTTP请求和响应,并提供了基本的HTTP功能,如请求分发、缓存、日志记录和错误处理。
  • ngx_http_ssl_module:这个模块提供了SSL/TLS加密功能,使得NGINX可以通过HTTPS协议安全地传输数据。
  • ngx_http_gzip_module:这个模块提供了Gzip压缩功能,可以减少HTTP响应的大小,从而提高性能。
  • ngx_http_proxy_module:这个模块提供了反向代理功能,它允许NGINX作为代理服务器,将客户端请求转发到后端服务器。
  • ngx_http_upstream_module:这个模块提供了负载均衡功能,可以将客户端请求分发到多个后端服务器,从而提高系统的可用性和性能。
  • ngx_http_fastcgi_module:这个模块提供了与FastCGI服务器通信的功能,使得NGINX可以将客户端请求转发给FastCGI进程,从而实现动态内容的生成。
  • ngx_http_rewrite_module:这个模块提供了URL重写功能,允许NGINX根据规则修改URL,从而改变请求的处理方式。
  • ngx_http_access_module:这个模块提供了访问控制功能,可以限制某些客户端或IP地址的访问。
  • ngx_http_limit_req_module:这个模块提供了请求速率限制功能,可以限制某些客户端的请求速率,防止过度消耗服务器资源。