web应用程详解part1 - http协议详解

web应用层详解

如何看待一整套架构的上下游对接/通信?

  上下游不用管具体是什么软件,只要通信协议能对上就可以,即上游用什么协议封装,下游就英爱用什么协议解封。

1、web应用层各中程序的部署

协议:

  http协议

  cgi、fastcgi、php-fpm ---- >php语言体系

  wsgi、uwsgi、agi ---- >python语言体系

  http协议 ---->JAVA语言

  http协议 ---->go语言

不同语言程序的部署(服务部分和程序部分)

  部署php: nginx -------- php-fpm( php应用程序)-------- mysql

  部署Python:nginx -------- uwsgi( python应用程序)-------- mysql

  部署java应用:nginx -------- tomact( java应用程序)-------- mysql

  部署go应用:nginx -------- go二进制程序 -------- mysql

2、nginx详解(四层、七层负载均衡、web层当服务)

在复杂的软件架构中,上下游系统之间的对接与通信是关键环节。无需关注上下游具体使用的是何种软件,只要双方遵循相同的通信协议,即可实现无缝对接。换言之,上游系统使用某种协议进行数据封装,下游系统则需采用相同的协议进行解封,以确保信息的准确传递。

1. Web应用层的多元化程序部署
为了实现高效灵活的Web应用,部署过程中需要选择合适的通信协议,以匹配相应的编程语言体系:
  HTTP协议:作为Web应用的基础协议,负责客户端与服务器之间的通信。
  CGI、FastCGI、PHP-FPM:这些协议专门用于PHP语言体系,通过PHP-FPM管理PHP应用程序,实现动态内容生成。
  WSGI、uWSGI、AGI:针对Python语言体系,优化Python应用程序的性能与扩展性。
  Java语言:通过HTTP协议与Web服务器交互,利用Tomcat等应用服务器运行Java应用程序。
  Go语言:直接通过HTTP协议与Web服务器通信,执行Go编写的二进制程序。
在部署不同语言编写的应用程序时,服务器架构通常包括以下几个部分:
  部署PHP应用:Nginx作为Web服务器,通过PHP-FPM与PHP应用程序通信,同时连接MySQL数据库存储数据。
  部署Python应用:Nginx同样作为Web服务器,使用uWSGI与Python应用程序交互,连接MySQL数据库。
  部署Java应用:Nginx与Tomcat结合,运行Java应用程序,并与MySQL数据库进行数据交换。
  部署Go应用:Nginx直接与Go编写的二进制程序通信,访问MySQL数据库。
2. Nginx详解:四层与七层负载均衡及Web服务功能
Nginx作为一款高性能的Web服务器和反向代理服务器,广泛应用于现代Web架构中。它不仅支持四层(传输层)和七层(应用层)的负载均衡,还能在Web层充当重要服务角色:
  四层负载均衡:基于IP和端口进行负载分配,适用于TCP/UDP协议,适合处理大量并发连接。
  七层负载均衡:基于HTTP/HTTPS请求的URL、头部等信息进行负载分配,提供更智能的流量管理。
  Web服务功能:Nginx可作为静态内容服务器,处理高速的HTTP请求,同时通过代理功能,将动态请求转发给后端应用程序服务器。

 

1、为何要学http协议?


用户用浏览器访问网页,默认走的都是http协议,所以要深入研究web层,必须掌握http协议。

用户浏览器----------HTTP协议------------web应用程序

2、什么是http协议?


HTTP(HyperText Transfer Protocol,超文本传输协议)。

普通文本:文件内存放的是一些人类能认识的文字符号(汉字、英文、阿拉伯数字......)。

超级文本:除了普通文本内容之外,还有视频、图片、语音、超链接......

超文本包含:html文件、css文件、js文件、图片、视频......

http协议都能传输上述内容,所以说http协议是专用于传输超文本的协议。

http协议主要用于B/S架构的程序。

http协议是基于tcp协议的。

强调:基于http协议发包之前,必须建立tcp协议的双向通路

3、http协议的发展史(主要经历3个版本)


伴随着浏览器的诞生---->网景浏览器(万能客户端)----访问---->各种各样的服务端。

http0.9(基本不用了)

请求方法:只支持GET方法

请求头:不支持请求头。

响应信息:只支持纯文本,不支持图片。

    无连接:利用完tcp连接之后会立即回收。

http协议通信,先建立tcp连接,然后客户端发请求包,服务端收到后发送响应包,服务端一旦发送完响应包之后,服务端会立即主动断开tcp连接,下次http通信还需要重新建立tcp连接。所以我们称http协议是无连接的(持久连接/长连接)

无状态:(一个http协议的请求无法标识自己的身份)

http无法保存状态,比如登录状态

http1.0(还有再用)

请求方法:支持GET(查)、POST(改)、DELETE(删)、PUT(增)......

请求头:发送者在发的时候可以定制一些自己的请求参数

响应信息:更加丰富,支持超文本

支持缓存

无状态:解决方案:cookie、session、jwt

无连接:解决方案:支持持久连接/长连接 keep-alive

http1.1(主要在用)

在1.1的基础上又新增了一些功能:长连接(默认了所有请求都启用长连接)、pipeline(请求流水线/管道化)、分块传输编码chunked、

http2.0(未来版本)

持久连接和非持久连接

浏览器与web服务器建立tcp连接后,双方就可以通过发送请求信息和应答消息进行数据传输了。

问题:

同一个用户在短期内频繁的访问服务端,会造成大量的时间都消耗在重复建立tcp连接,在高并发场景下,对服务端是非常大的消耗,对客户端的访问速度也会很慢。

目标:

同一个用户在短期内访问多次服务端,不要重复建立tcp连接,而是能够共用一个tcp连接

解决方案:支持持久连接/长连接 keep-alive

前提:

发送完http响应包之后,服务端立即断tcp连接,这是服务端的默认行为。

要改变这种默认行为,要客户端通知服务端才行

实现:

客户端在发送http的请求时,需要在请求头里带上connection:keep-alive这个参数,服务端的keepalive_alive设置要大于0。

服务端收到这个参数之后,服务端会保持与这一个客户端tcp连接一段时间,响应时也会在响应头里放connection:keep-alive这个参数。

该tcp连接会保持一段时间直到达到服务端设置的keepalive_timeout时间。

补充:

在http1.0协议中还需要在发请求时自己加上connection:keep-alive参数

在http1.1协议中已经默认加上connection:keep-alive参数,也就是说客户端默认开启了长连接支持,配套的服务端也要开启keepalive_alive设置要大于0

 

http协议无状态

问题:

服务端无法标识一个http请求的唯一性(http协议本身就没有可以表示自身请求唯 一性的字段或机制),会导致用户登录状态无法保存,那么每次请求都需要重新输一遍账号密码

目标:

服务端要客户端有状态(让客户端每次发请求时都能标识自身的唯一性)

解决方案:

cookie、session、jwt

cookie机制:

流程:

1、首先第一次请求带着认证(账号、密码)到服务端通过认证后,服务端会生成一段独一无二的字符,生成响应信息把这一段字符带进去,响应头里会有set-cookie:字符(服务端会生成一段独一无二的字符)k1=v1;k2=v2;k3=v3

2、客户端(浏览器)收到服务端的响应信息后开始解析协议,响应头里有set-cookie立刻明白服务端让它保存cookie值,对应好对应的网站

3、下次再发请求的时候如果还是这个网站,浏览器会查找到本地的存放的该网站的这个cookie值,注入http协议的请求头里发送给服务端

特点:

1、cookie是浏览器的功能,是存放在客户端的;

2、cookie内存放的内容是可以被客户端篡改的;

cookie机制+session机制:

流程:

1、客户端访问一个站点,输入账号密码进行认证,服务端收到请求通过认证之后会产生一些标识用户身份的数据,这些数据(value)是放在服务端的,称之为session,针对这些数据会得到一个对应的key值。

2、服务端会把key放入set-cookie里,返回给客户端

3、客户端收到响应后,会把key存入到本地的浏览器cookie

4、下次请求该网站,会带着key去目标站点访问,目标站点收到后,会根据key取出value,value里放着本次请求的身份信息

特点:

1、把保密数据放在服务端,称之为session数据,然后对session数据生成一个key值存入客户端的cookie中,可以防止篡改

2、 在集群的场景下,需要做会话共享(session存入共享的地方,通常会将session数据存入Redis数据库缓存,Redis作为一个大家都依赖的共享点,会影响集群的扩展性)

 

总结:

单用cookie来存放状态信息:

优点:服务端不需要做会话共享

缺点:客户端可以篡改状态信息,不安全

cookie+session:

优点:状态信息即session数据是存放在服务端的,状态信息不会被篡改

缺点:服务端需要做会话共享,增加了集群的耦合性

jwt(json web token)机制:核心是即不需要做会话共享,又很安全。

服务端会将状态信息进行加密,然后把加密的数据放入客户的cookie中---->解决了篡改的问题;

下次请求会从cookie中取出token带上一切发送给服务端,服务端收到了会用加密算法解密---->不需要再做会话共享。

缺点:最大的缺点服务端无法做到废弃到某个cookie,一旦token下发以后,就只能等着该token过期;想要做到随时都能主动废弃掉某个token,就需要开发额外的代码。

 

 

4、http的通信过程


基于http协议完整的请求响应流程:

浏览器访问一个url地址

1、浏览器会先问本地dns把域名解析为ip地址

2、浏览器作为客户端会与目标ip:port建立tcp连接

3、浏览器会基于http协议封装请求包(osi七层的封包流程)

4、服务端收到包(osi七层的解包流程),拿到一个http协议的请求包,按照http协议解析请求(请求首行、请求头、空行和请求体数据),会拿到请求路径部分,服务端会打开该文件(对一个文件描述符)把文件内容从硬盘读入内存,然后服务端程序会基于http协议封装读入内存的数据,形成一个响应包发给客户端浏览器。

5、浏览器收到http协议的响应包之后,先解析响应首行,看到响应的状态码,知道本次访问是否成功;再解析响应头,可以拿到Content-Type:就知道该用什么方法来解析内容,如果值为text/html就会按照html代码的方式来解析返回的内容,再读取内容部分,当成html代码来解析。

6、在解析html代码的过程中,有可能遇到css、jss、图片、视频等资源,会发起多次的请求再往回拿数据,直到把整个页面都渲染完毕。

补充:http1.1默认是开启持久连接的(核心是请求与响应头里都带着connection:keep-alive)

 

5、URL地址详解


URI:统一资源标识符,是一种思想

URL:统一资源定位符,是uri的一种具体实现

URN:也是uri的一种具体实现

地址都是用来找东西,比如ip地址是用来找唯一的一台机器,如果再搭配上端口号就可以找到那台机器上的某个网络程序了,所以ip+port可以找到全世界范围内独一无二的程序(192.168.1.112:8080)。

发请求找到程序,程序还需要定位到具体的文件,在ip+port的基础之上再定位到文件那就是url地址,访问资源的西协议如果是http协议那完整的url地址就是http://192.168.1.112:8080/a/b/1.txt?a=1&b=2&age=10#name_lable5

url地址一般由三个关键部分组成:访问资源的命名机制,存放资源的主机名,资源本身的名称,由路径表示,着重强调于资源

http:// 协议部分

192.168.1.112:8080 ip+port(一般是域名,但是域名最终也是解析成ip+port)

/a/b/1.txt 路径部分

?a=1&b=2&age=10 请求参数部分,主要用于get方法

#name_lable5 锚,定位到某个页面的具体位置

http协议不写端口默认就是服务端端口80,路径可以不写,默认就是/结尾

 

 

6、http协议的格式


6.1、请求request

包含四部分:请求首行、请求头、空行、请求体数据

请求首行:由3部分组成(请求方法、URI和HTTP协议版本),它们之间用空格分隔。

请求方法 请求的路径部分及后续部分 使用的http协议版本

请求方法:

GET ---- 检索URI所标识的资源,请求的数据可以放在url地址的?后面。

POST ---- 请求服务器接受被写入客户端输出流中的数据,携带请求体数据。

DELETE ---- 请求服务器删除URI中命名的资源。

PUT ---- 服务器保存请求数据作为指定URI新内容的请求。

HEAD ---- 与GET方法相同,不同的是指挥获取响应头(包含状态码)而不会获取响应的数据。

OPTIONS ---- 请求得到服务器支持的请求方法。

 

请求头:都是key:value格式,用来定制一些参数

常见参数:

accept:代表能接收什么样的数据

accept-encoding:支持压缩算法

accept-language:能接收的语言

空行:隔开请求体数据

请求体数据:

如果是GET 方法是没有请求体数据的

 

6.2、响应response

包含四部分:响应首行、响应头、空行、响应体

响应首行:协议版本 状态码

常见状态码:

1xx:信息,请求收到,继续处理

2xx:成功

3xx:重定向,为了完成请求,必须进一步执行的动作。

4xx:客户端错误,请求包含语法错误或者请求无法实现。404表示客户端访问的资源不存在,403表示客户端没有对目标资源的访问权限,

5xx:服务端错误。503表示服务端故障

 

响应头:

常用字段:

set-cookie:要求浏览器把cookie信息存入到本地

cache-control:缓存控制手段

connection:连接状态

content-type:告诉浏览器本次返回内容的格式

空行:

响应体:

posted @ 2025-09-20 15:18  张仁国  阅读(5)  评论(0)    收藏  举报
目录代码