1、http协议基础及IO模型
Nginx (web server,web reverse proxy):
http协议:80/tcp,HyperText Transfer Procotol
http协议版本:
HTTP/0.9:原型版本,功能简陋
HTTP/1.0:第一个广泛使用的版本,支持MIME
HTTP/1.1: 增强了缓存功能
spdy
HTTP/2.0 下一次流行
MIME:Multipurpose Internet Mail Extesion 多用途互联网邮件扩展
major/minor:text/plain, text/html, image/jpeg
URI: Uniform Resource Identifier 同一资源标识符
URL: Uniform Resorce Locator(统一资源定位符),用于描述某服务器某特定资源的位置;
URL包括三部分:
URL方案:scheme//
服务器地址:ip:port
资源路径:
http://www.magedu.com:80/bbs/index.php,
https://就表示scheme,表示用什么协议进行交换
Scheme://Server:Port/path/to/resource
http://www.magedu.com/images/logo.jpg
URN: Uniform Resource Naming
http事务:httpd一次请求和响应的过程
请求:request //请求是由请求报文来请求
响应:response//响应是由响应报文来构建
报文语法格式:
request报文
<method> <request-URL> <version> //起始行
<headers> //有可能由众多的头部组成
<entity-body> //请求主体部分,有可能为空
Response响应报文
<version> <status> <reason-phrase>原因短语
<headers>
<entity-body>//响应实体
请求报文语法解析:
method:请求方法,标明客户端希望服务器对资源执行的动作
GET(表示客户端希望服务器把资源打包发给客户端)、HEAD、POST
version://请求报文和响应报文都一样
HTTP/<major>.<minor>//主版本号.次版本号
status:
三位数字,如200,301, 302, 404, 502; 标记请求处理过程中发生的情况;
reason-phrase:
status状态码所标记的状态的简要描述;
headers:首部
每个请求或响应报文可包含任意个首部;每个首部都有首部名称,后面跟一个冒号,而后跟上一个可选空格,接着是一个值;
entity-body:请求时附加的数据或响应时附加的数据;有用的数据块,请求报文entity-body可能为空
method(方法):
GET:从服务器获取一个资源;
HEAD:只从服务器获取文档的响应首部,而不是响应内容;
POST:向服务器发送要处理的数据,放在<entity-body>中;
PUT:将请求的主体部分存储在服务器上,上传数据到服务器;
DELETE:请求删除服务器上指定的文档;
TRACE:追踪请求到达服务器中间经过的代理服务器;
OPTIONS:请求服务器返回对指定资源支持使用的请求方法,如get等;
status(状态码):
1xx:100-101, 额外信息提示;
2xx:200-206, 成功类的响应;
3xx:300-305, 重定向类的状态;
4xx:400-415, 错误类信息,客户端错误(客户端请求根本不存在的资源)
5xx:500-505, 错误类信息,服务器端错误(服由于自己内部问题,导致运行不成功)
常用的状态码:
200: 成功,请求的所有数据通过响应报文的entity-body部分发送;OK
301: 请求的URL指向的资源已经被删除;但在响应报文中通过首部Location指明了资源现在所处的新位置;Moved Permanently,永久重定向
302: 与301相似,但在响应报文中通过Location指明资源现在所处临时新位置;Found,资源有,需要重新找
304: 客户端发出了条件式请求,但服务器上的资源未曾发生改变,则通过响应报文此响应状态码通知客户端;Not Modified
401: 需要输入账号和密码认证方能访问资源;Unauthorized未认证
403: 请求被禁止;Forbidden
404: 服务器无法找到客户端请求的资源;Not Found
500: 服务器内部错误,原因很多;Internal Server Error
502: 代理服务器从后端服务器收到了一条伪响应;
504 Gateway Timeout 是一种HTTP协议的服务器端错误状态代码,表示扮演网关或者代理的服务器无法在规定的时间内获得想要的响应。
Bad Gateway表示客户端向代理服务器发送请求,代理服务器应该给客返回结果,但是代理服务器本地没有缓存,就像上游代理服务器请求,上游服务器给所请求的下游服务器发送了一个错误的,因此下游服务器就没办法响应客户端。
协议查看或分析的工具:tcpdump, tshark, wireshark
方法是客户端告诉服务器端应该做什么,状态码是服务器端告诉客户端的请求发生的状态
headers:
格式: Name:Value
首部的分类:
通用首部、请求首部、响应首部、实体首部、扩展首部
通用首部:
Date: 报文的创建时间
Connection:连接状态,如keep-alive, close
Via:显示报文经过的中间节点
Cache-Control:控制缓存生效机制
Pragma:
请求首部:
Accept:通过服务器自己可接受的媒体类型;
Accept-Charset:
Accept-Encoding:接受编码格式,如gzip
Accept-Language:接受的语言
Client-IP:
Host: 请求的服务器名称和端口号
Referer:包含当前正在请求的资源的上一级资源;
User-Agent:客户端代理
条件式请求首部:
Expect:期望发什么信息
If-Modified-Since:自从指定时间之后,请求的资源是否发生过修改;
If-Unmodified-Since:自从指定时间之后,请求的资源没有发生修改;
If-None-Match:本地缓存中存储的文档的ETag(扩展标签)标签是否与服务器文档的Etag不匹配;是:表示不匹配,否:表示匹配
If-Match:和If-None-Match相对应
安全请求首部:
Authorization:向服务器发送认证信息,如账号和密码;
Cookie: 客户端向服务器发送cookie
Cookie2:
代理请求首部:
Proxy-Authorization: 向代理服务器认证
响应首部:
信息性:
Age:响应持续时长
Server:服务器程序软件名称和版本
协商首部:某资源有多种表示方法时使用
Accept-Ranges:服务器可接受的请求范围类型
Vary:服务器查看的其它首部列表;
安全响应首部:
Set-Cookie:向客户端设置cookie;
Set-Cookie2:
WWW-Authenticate:来自服务器的对客户端的质询认证表单
实体首部:
Allow: 列出对此实体可使用的请求方法
Location:告诉客户端真正的实体位于何处,在重定向时使用
Content-Encoding:内容编码格式
Content-Language:内容使用语言
Content-Length: 主体的长度
Content-Location: 实体真正所处位置;
Content-Type:主体的对象类型
缓存相关:
ETag:实体的扩展标签;
Expires:实体的过期时间;
Last-Modified:最后一次修改的时间
http协议是文本编码的是无状态的
web资源
静态资源:静态内容;客户端从服务器获得的资源的表现形式与原文件相同;
动态资源:通常是程序文件,需要在服务器执行之后,将执行的结果返回给客户端;客户端拿到的内容依然是静态的,认识纯文本,跟服务器端不一样 Web服务器和程序解释器之间是如何协调工作的?即web服务器如何把客户端请求的动态资源让解释器去磁盘调用并进行运行?他们之间遵循一种协议:CGI。
通俗的可以把服务器看作餐厅,用户请求看作来用餐的顾客,服务器处理请求看作解决顾客的就餐问题(响应输出一份饭)。
服务器上静态资源看作已做好的饭,只要放到餐盒里就可以返回给顾客,动态资源需要厨房大厨现成做份再放到餐盒里返回给顾客。
php_mod:这个大厨有个特点,看见有顾客进门就点火,不管顾客要不要现做的,有点浪费资源
php_fpm:这个大厨有好多小弟一直点着火(多个处理进程),等有顾客说要现做,大厨就安排小弟做份返回给客户
cgi:也是个大厨,不过他等到顾客要现做,他才点火,做饭,然后熄火。等待下一个要现做的到来
fastcgi:就是个大厨雇了一帮小弟,专门做需要现场做的饭,大厨只管分派任务,小弟真正操锅做饭
参考链接:https://www.zhihu.com/question/30672017/answer/53238751 程序=指令+数据 请求流程:Client --> (http) --> httpd服务 --> (cgi) --> application server (program file) --> (mysql驱动和协议) --> mariadb 1、首先客户端A通过http协议请求资源,web服务器端B接受协议之后,通过过滤器识别客户端请求的资源后缀,假如客户端请求的动态资源,发现是.php,那么就向后转发,通过CGI协议跟PHP解释器的应用程序C进行交互,这时web服务器是CGI的客户端,而php解释器的应用程序是CGI的服务器端。
2、CGI服务器C上面运行的程序发现代码中需要用到数据,服务器C会基于驱动D跟后面的数据存储打交道,这时假如后面的是mysql服务器(都是应用层协议),那么中间用到的协议就是mysql协议。这时候,应用程序C就MySQL协议的客户端,而MySQL服务器就成了MySQL协议的服务器端。
整个执行过程:客户端请求一个动态资源,请求先送到给web服务器,web服务器发现这是一个动态资源,那么web服务器就会转交给应用程序服务器-PHP程序,web服等待php程序响应,这个过程就被阻塞了,php程序就从磁盘上加载程序文件到php程序里面进行执行,在执行过程中,如果有结果就返回给web服务器,但是如果在执行过程中发现有数据,而数据在本地磁盘中并没有存放,需要到MySQL服务器中去调用,于是php程序就扮演成MySQL服务器的客户端发出请求,MySQL服务器经过对数据出来把结果返回给php应用程序,php程序对结果做进一步处理然后把结果返回给web服务器,web服务器把结果封装成http报文发送到客户端。
httpd的特性:
高度模块化:core + modules
DSO: Dynamic Shared Object
MPM:Multipath Processing Modules //多路处理模块
prefork:多进程模型,每个进程响应一个请求;
一个主进程:负责生成n个子进程,子进程也称为工作进程,每个子进程处理一个用户请求;即便没有用户请求,也会预先生成多个空闲进程,随时等待请求到达;最大不会超过1024个;
worker:多线程模型,每个线程响应一个请求;
一个主进程:生成多个子进程,每个子进程负责生成多个线程,每个线程响应一个请求;
m进程,n线程:m*n
event:事件驱动模型,每个进程响应n个请求;
一个主进程:生成m个子进程,每个进程直接n个请求;
m*n
httpd-2.2:event为测试使用
httpd-2.4:event可生产使用
pv:page view
uv: user view
独立IP
一个域名打开的线程数是有限的,所以有些网站为了提高用户体验就在一个网站页面上布置多个域名
I/O类型:
参考:马哥视频、https://www.jianshu.com/p/786d351e06d8、https://www.jianshu.com/p/486b0965c296
同步和异步:synchronous, asyncrhonous
关注的是消息通知机制(被调用者即服务器端如何把已经完成的结果通知给调用者); 即服务器端
同步:调用发出不会立即返回,但一旦返回就可以返回最终结果;
异步:调用发出之后,被调用方立即返回消息,但返回的非最终结果;被调用者通过状态、通知机制等来通知调用者,或通过回调函数来处理结果; 阻塞和非阻塞:block, nonblock
关注的是调用者等待被调用返回结果(消息、返回值)时的状态 即客户端
阻塞:调用结果返回之前,调用者(调用线程)会被挂起;调用者只有在得到结果之后才会返回;
非阻塞:调用结果返回之前,调用者不会阻塞当前线程;
5种I/O模型:prefork和worker都是复用型I/O,并发能力有限,最多1024;event是事件驱动型I/O;
blocking IO 阻塞式IO
nonblocking IO 非阻塞式IO
以上两种IO模型中第二阶段需要调用者即进程等待内存把数据从内核内存中复制给进程内存,这个过程调用者是阻塞的
IO multiplexing 复用型IO //把请求给内核代理,不是给内核,请求最多1024个,阻塞在select上,这样的好处调用者可以继续发送请求;
select(),poll()
signal driven IO 事件驱动式IO 当用户请求的数据准备好之后,内核会通知进程取数据,如果这时进程在第二阶段被阻塞时,如何?内核通知进程后,过了指定时间就会消失。
之所以叫事件驱式IO,是因为一旦数据从磁盘到内核内存即数据准备好了之后,内核会通知调用者即调用进程,让调用者就会使用回调函数进行处理。
(第二段阻塞:因为内核把数据准备好后,会通知进程数据已准备好,这是进程就要准备接受数据,然后内核会把数据从内核内存复制到进程内存)
通知机制:水平触发:通知一次没响应,再通知,直到你处理为止;
边缘触发:只通知一次,如果没有响应,就把通知事件通过回调函数让调用者自行来获取,即把通知信息放在某处;
复用IO和事件驱动IO模型第二阶段之所以阻塞是因为第一阶段:在内核从磁盘把数据处理好后放到内核内存后,第二阶段就需要调用者即进程调用回调函数来内核内存中取数据,所以也是阻塞。
asyncrhonous IO 异步IO 第二阶段即内存把数据准备好后,不需要调用者再利用回调函数去内核内存中取数据,而是内存直接把数据复制到进程内存中。
例:一个read操作:
(1) 等数据准备好,从磁盘到内核内存;
(2) 从内核内存复制到进程内存;
一个磁盘IO分两步:
1、用户空间的进程没有权限直接访问硬件的,用户空间的进程发起IO调用时,只能向内核请求,数据只能在硬盘上,内核先把数据加载至内存内存中,
2、内核再把数据从内核内存复制到进程内存
这两步真正执行IO的是数据从内核内存到进程内存 真正称为IO的步骤是数据从内核内存到进程内存
没有消息通知的是同步I/O:阻塞式I/O、非阻塞式I/O、复用型IO
有消息通知的是异步I/O: 事件驱动式IO、异步IO
nginx用的是事件驱动式IO,而且基于边缘触发通知机制来实现,同时也支持异步IO,而且还能够完成基于内存映射机制来完成数据的发放。
MMAP知识:https://www.cnblogs.com/huxiao-tee/p/4660352.html
一次完整的HTTP事务是怎样一个过程?
http://blog.51cto.com/linux5588/1351007
tcp三次握手
https://blog.csdn.net/geecky/article/details/56275032
1、http协议基础及IO模型的更多相关文章
- python基础(17)-IO模型&selector模块
先说一下IO发生时涉及的对象和步骤.对于一个network IO (这里我们以read举例),它会涉及到两个系统对象,一个是调用这个IO的process (or thread),另一个就是系统内核(k ...
- Python开发基础-Day33 IO模型
IO模型分类 五种IO Model blocking IO 阻塞IO nonblocking IO 非阻塞IO IO multiplexing IO多路复用 signal driven IO 信号驱动 ...
- python基础之IO模型
IO模型分类 五种IO Model blocking IO 阻塞IO nonblocking IO 非阻塞IO IO multiplexing IO多路复用 signal driven IO 信号驱动 ...
- linux基础之IO模型
一.IO模型 一次read操作: (1)等待数据准备好:从磁盘到内核内存 (2)从内核内存复制到进程内存 示意图如下: I/O类型: 同步和异步:synchronous,asynchronous 关注 ...
- Unix 网络IO模型介绍
带着问题阅读 1.什么是同步异步.阻塞非阻塞 2.有几种IO模型,不同模型之间有什么区别 3.不同IO模型的应用场景都是什么 同步和异步.阻塞和非阻塞 同步和异步 广义上讲同步异步描述的是事件中发送方 ...
- 图解四种 IO 模型
最近越来越认为,在讲解技术相关问题时,大白话固然很重要,通俗易懂,让人有想读下去的欲望.但几乎所有的事,都有两面性,在看到其带来好处时,不妨想想是否也引入了不好的地方. 例如在博客中,过于大白话的语言 ...
- linux基础编程:IO模型:阻塞/非阻塞/IO复用 同步/异步 Select/Epoll/AIO(转载)
IO概念 Linux的内核将所有外部设备都可以看做一个文件来操作.那么我们对与外部设备的操作都可以看做对文件进行操作.我们对一个文件的读写,都通过调用内核提供的系统调用:内核给我们返回一个file ...
- 进程池与线程池基本使用、协程理论与实操、IO模型、前端、BS架构、HTTP协议与HTML前戏
昨日内容回顾 GIL全局解释器锁 1.在python解释器中 才有GIL的存在(只与解释器有关) 2.GIL本质上其实也是一把互斥锁(并发变串行 牺牲效率保证安全) 3.GIL的存在 是由于Cpyth ...
- 协程 & IO模型 & HTTP协议
今日内容 进程池与线程池的基本使用 协程理论与实操 IO模型 前端简介 内容详细 一.进程池与线程池的基本使用 1.进程池与线程池的作用 为了保证计算机硬件安全的前提下,提升程序的运行效率 2.回调机 ...
随机推荐
- Django ORM 操作 必知必会13条 单表查询
ORM 操作 必知必会13条 import os # if __name__ == '__main__': # 当前文件下执行 os.environ.setdefault('DJANGO_SETTIN ...
- Oracle执行计划 explain plan
Rowid的概念:rowid是一个伪列,既然是伪列,那么这个列就不是用户定义,而是系统自己给加上的. 对每个表都有一个rowid的伪列,但是表中并不物理存储ROWID列的值.不过你可以像使用其它列那样 ...
- QT多线程简单例子
在Qt中实现多线程,除了使用全局变量.还可以使用信号/槽机制. 以下例子使用信号/槽机制. 功能: 在主线程A界面上点击按钮,然后对应开起一个线程B.线程B往线程A发送一个字符串,线程A打印出来. 1 ...
- scrapy instantiation
start from scrapy.cmdline import execute execute(['scrapy', 'crawl', 'jokespider']) items.py import ...
- linux装sqlite3
下载sqlite3源码包 tar xvfz sqlite-src-3.3.5 cd sqlite-3.3.5 ./configure –no-tcl make python继续一次. apt inst ...
- vi/vim 命令速查手册
vi 的基本概念 基本上vi可分为三种操作状态,分别是命令模式(Command mode).插入模式(Insert mode)和底线命令模式(Last line mode),各模式的功能区分如下: 1 ...
- DBeaver连接Oracle11g数据库
DBeaver连接Oracle11g数据库 一.准备 (1)dbeaver管理软件 (2)远程连接数据库地址.用户名秘密等 (3)Oracle驱动:ojdbc6.jar工具包 下载地址:https:/ ...
- 写给大忙人的CentOS 7下最新版(6.2.4)ELK+Filebeat+Log4j日志集成环境搭建完整指南
现在的公司由于绝大部分项目都采用分布式架构,很早就采用ELK了,只不过最近因为额外的工作需要,仔细的研究了分布式系统中,怎么样的日志规范和架构才是合理和能够有效提高问题排查效率的.经过仔细的分析和研究 ...
- jackson JsonPropertyOrder和@JsonIgnoreProperties注解
有些时候,我们在和外部系统交互的时候使用了json作为标准的数据交换格式,同时为了安全性考虑,增加了对报文的校验,因此我们需要确保序列化的时候参数有序且不多不少刚好,因为对外的API不像后台和前端交互 ...
- Android - Resource 之 Menu 小结
定义一个application的菜单,由MenuInflater召唤. 位置: res/menu/filename.xml 类型:指向Menu resource 文法: <?xml versio ...