为了账号安全,请及时绑定邮箱和手机立即绑定
2.2 HTTP 请求方法

面试官提问: HTTP 协议的请求方法有哪些,有啥区别?题目解析:序号方法说明 1GET 请求服务器上的资源,请求体不会包含请求数据,参数可以通过 URL 传输。2POST 用户传输信息到服务器,请求方式类似 GET 请求,比如提交表单。3PUT 用户传输信息到服务器,请求方式类似 POST 请求,比如提交文件。4DELETE 请求服务器删除某个资源,和 POST 请求作用相反。5OPTIONS 查询 URL 支持的 HTTP 方法。6HEAD 请求方式类似 GET 请求,但是服务器不会返回消息体,一般用于检查网页是否被修改、检查 URL 是否有效。除此之外,HTTP 协议还有 TRACE、CONNECT 等方法,但是在日常开发中基本不会用到,所以不用关注。面试官常常会将 POST 和 GET 方法进行对比,我们需要注意以下几个不同:(1)GET 请求主要是为了从服务器获取资源,POST 请求主要是为了向服务器发送资源。(2)GET 请求是通过 URL 传参,形式是 field = value,多个参数使用 & 进行分割,例如 http://127.0.0.1/login?username=xiaoming&password=123456。POST 请求是通过请求体传参,即信息存放到 Request Body 中。(3)GET 请求传输的信息量少,POST 请求能够传输的信息量多。(4)GET 请求参数在 URL 明文,容易被爬虫直接获取,POST 请求参数不直接可见,安全性更高,例如在表单提交密码时,必须使用 POST 请求。

1. HTTP 的历史背景

一个东西的产生可能有偶然因素,但是事物的兴盛就必然有他客观价值的存在。HTTP(hypertext transport protocol)超文本传输协议也是如此,下面我们来介绍它诞生的背景。

2.1 第一步:在 Node 环境中安装 Http 服务器

在 Node 环境中,提供了很多 http 服务器的支持,例如:Express 、 http server 等。针对 Swagger Editor 的特点和后台服务器的适用条件,这里我们采用 http server 来当做 Swagger Editor 的服务器支持。至于为什么选择 http server 来做后台服务器,这是不属于本节所介绍的内容,希望同学们可以在课下了解原因。我们使用一下命令来在 Node 环境中安装 Http Server 服务器: npm install ‐g http‐server-g 表示全局安装 http-server 服务器,这样我们就可以不用专门去 http-server 服务器目录下启动该服务了。我们看到如下提示信息就表明安装 http-server 服务器成功:

2.1 HTTP 服务器

Nginx 作为 Web 服务器能独立提供 Http 服务。另外,我们常常通过 Nginx 作为静态资源服务器来访问服务器上的静态资源,比如对于最新热门的前后端分离架构,前端打好包后直接放到某个地址,在 Nginx 配置后可以通过 Nginx 来访问主机上的前端页面。

HTTP 协议和 HTTPS 协议的对比

在前面的章节中我们对 Http 已经有了一个很全面的了解,Http 在满足通信的基本功能外,也提供了很多丰富的交互功能,但是在安全性方面,Http 还有很多不足的地方,Https 就是为了解决这个问题而诞生。目前 google / 苹果 / 腾讯的小程序接口都强制要求使用 Https 安全协议。以后的网站全面采用 Https 协议已经是一个可以遇见的趋势了。

俯视 HTTP 协议

生活中的各类电商系统,学校的教务系统,工作中的各种办公软件基本上都是 Web 网站。少部分的是桌面应用,而这一部分的桌面软件也都纷纷在往 Web 应用上面迁移。因为桌面软件还需要下载 APP 安装到本地电脑,而 Web 网站你只要打开浏览器就可以直接访问,在便利性方面 Web 网站是有巨大的优势。作为互联网的从业者,我们需要了解这个表现背后的原理,那就是 Http 协议,它帮助我们将远端服务器的数据信息传输到我们浏览器的客户端。本小节,将会从历史背景,实现原理,协议是什么,几个方面让你对 Http 有一个比较深刻的了解。

2.5 返回 HTTP 响应

服务器端处理业务结果之后,也要返回 HTTP 响应,HTTP 响应由状态行(Status Line)、响应头部(Response Headers)、空行(Blank Line)以及响应体(Response Body)构成,关于每个部分的细节也不再赘述。需要特别注意的是,响应体中的各种错误码定义:状态类型代表状态码和含义说明1xx100 Continue服务器收到了客户端的请求行和头部信息,告诉客户端继续发送数据部分。2xx200 OK请求成功3xx301 Moved Permanently资源被转移了,请求将被重定向4xx404 Not Found资源没找到5xx500 Internal Server Error服务器内部错误

2. HTTP 状态码

HTTP 状态码是用以表示网页服务器超文本传输协议响应状态的 3 位数字代码,下面列举出几种常见的 HTTP 状态码及含义:响应码含义描述100 Continue客户端应当继续发送请求,如果请求已经完成,忽略这个响应。服务器必须在请求完成后向客户端发送一个最终响应。200 OK请求已成功,请求所希望的响应头或数据体将随此响应返回,出现此状态码是表示正常状态。201 Created请求已经被实现,而且有一个新的资源已经依据请求的需要而建立。301 Moved Permanently被请求的资源已永久移动到新位置。404 Not Found请求失败,请求所希望得到的资源未被在服务器上发现。500 Internal Server Error服务器遇到了一个未曾预料的状况,服务器端的源代码出现错误时出现。502 Bad Gateway作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应。

3.2 运行程序 <a href="http://basis.py">basis.py</a>

1. 启动程序$ python basis.py2. 在浏览器中首次访问 http://localhost:50003. 观察控制台的输出before_first_requestbefore_requestexecute requestafter_request应用程序在第一个请求之前要运行一次 before_first_request,只会运行一次。4. 在浏览器中再次访问 http://localhost:50005. 观察控制台的输出before_requestexecute requestafter_request在程序整个生命周期内,before_first_request,只会运行一次,因此再次访问网站时,不会再执行 before_first_request。

1. HTTP 的基本概念

Http(超文本传输协议) 是一种客户端-服务端模型,使用超媒体文档进行传输的,简单的,无状态的,无连接的,可扩展的应用层协议。下面,我们一一来分析上述定义的几个概念。

Nginx 的 Http 模块介绍(下)

本小节,我们将主要介绍 Nginx 中 Http 请求 11 个阶段中的最后几个重要的阶段以及相关的模块,并演示其用法。

2. Http报文格式

Http 协议请求报文的本质就是一堆字符串,只是这堆字符是有格式的,发送方跟接收方都需要按照这个格式来拼接和拆解内容。我们要实现一个 Web 服务,了解这个是最基本的要素。以下截图的报文是通过 tcpflow(一款功能强大的、基于命令行的免费开源工具)在 Linux 系统抓包获取的。sudo tcpflow -c port 8080

1. http 请求 11 个处理阶段介绍

Nginx 将一个 Http 请求分成多个阶段,以模块为单位进行处理。其将 Http请求的处理过程分成了 11 个阶段,各个阶段可以包含任意多个 Http 的模块并以流水线的方式处理请求。这 11 个 Http 阶段如下所示:typedef enum { NGX_HTTP_POST_READ_PHASE = 0, NGX_HTTP_SERVER_REWRITE_PHASE, NGX_HTTP_FIND_CONFIG_PHASE, NGX_HTTP_REWRITE_PHASE, NGX_HTTP_POST_REWRITE_PHASE, NGX_HTTP_PREACCESS_PHASE, NGX_HTTP_ACCESS_PHASE, NGX_HTTP_POST_ACCESS_PHASE, NGX_HTTP_TRY_FILES_PHASE, NGX_HTTP_CONTENT_PHASE, NGX_HTTP_LOG_PHASE } ngx_http_phases;网上有人做了一个非常形象的图片,如下图所示。我们可以看到 11 个阶段的处理顺序,以及每个阶段中涉及到的相关模块以及模块之间的顺序。

5.2 运行程序 <a href="http://error.py">error.py</a>

1. 启动程序 error.py$ python error.py2. 在浏览器中访问 http://localhost:5000/non-exist-page3. 观察浏览器的显示404 Error访问一个不存在的页面 /non-exist-page,产生 HTTP 404 错误,Flask 框架执行使用 @errorhandler(404) 注册的函数 errorhandler,该函数返回字符串 ‘404 Error’ 给浏览器作为响应。5. 观察控制台的输出error_handler(404)404 Not Found: The requested URL was not found on the server. If URL manually please check your spelling and try again.执行 errorhandler 时,首先打印字符串 ‘error_handler(404)’,然后打印 Error 对象。

5.1 程序代码 <a href="http://error.py">error.py</a>

通过一个具体的例子讲解使用 errorhandler 处理 HTTP 错误,代码如下:from flask import Flask, render_templateapp = Flask(__name__)@app.route('/')def index(): print('execute request') return 'Hello World'@app.errorhandler(404)def errorhandler(e): print('error_handler(404)') print(e) return '404 Error'if __name__ == '__main__': app.run()在第 10 行,使用 @errorhandler(404) 注册一个钩子函数 errorhandler(e),当发生 HTTP 404 错误(页面不存在)时,调用钩子函数,该函数的第一个参数是错误对象。

4.2 Android Plugin for Gradle HTTP 代理设置

若从命令行或在未安装 Android Studio 的计算机上运行 Android 插件,则应在 Gradle 编译文件中设置 Android Plugin for Gradle 代理设置。对于特定于应用的 HTTP 代理设置,请根据各应用模块的要求在 build.gradle 文件中设置代理设置。apply plugin: 'com.android.application'android { ... defaultConfig { ... systemProp.http.proxyHost=proxy.company.com systemProp.http.proxyPort=443 systemProp.http.proxyUser=userid systemProp.http.proxyPassword=password systemProp.http.auth.ntlm.domain=domain } ...}对于整个项目的 HTTP 代理设置,请在 gradle/gradle.properties 文件中设置代理设置。Project-wide Gradle settings....systemProp.http.proxyHost=proxy.company.comsystemProp.http.proxyPort=443systemProp.http.proxyUser=usernamesystemProp.http.proxyPassword=passwordsystemProp.http.auth.ntlm.domain=domainsystemProp.https.proxyHost=proxy.company.comsystemProp.https.proxyPort=443systemProp.https.proxyUser=usernamesystemProp.https.proxyPassword=passwordsystemProp.https.auth.ntlm.domain=domain...```

<a href="http://www.imooc.com/wiki/djangolesson/webbasis2.html">5. HTTP 协议与网站基本开发流程</a>

这节课会介绍一下 Web 开发中常用的一些术语,让大家对 Web 开发有一个基本的认知,能够区分一些比较常见的概念。也会对 Web 开发必备基础知识 HTTP 协议进行详细讲解,如果你想要深入了解 HTTP 协议的话,可以学习这门《HTTP 教程》。通过这一小节的学习你会知道,当我们在浏览器中输入 https://www.imooc.com 这个地址按下回车之后到浏览器将慕课网的首页呈现给我们之间到底发生了什么?这个问题也是 Web 工程师面试中必问的一个问题。除了讲解这些概念之外,老师还会结合自身的经验给大家讲解在实际工作中一个公司想要开发一个网站的具体流程是什么,大致划分为几个阶段和步骤。好了,本章的介绍到这里就结束了,下面就开始正式的课程学习啦~

1.1 Http 请求

请求头的内容有很多,这里给大家做一个记录当做资料,不需要都记住,在实际使用中用到可以过来查阅即可。Header解释示例Accept指定客户端能够接收的内容类型Accept: text/plain, text/htmlAccept-Charset浏览器可以接受的字符编码集。Accept-Charset: iso-8859-5Accept-Encoding指定浏览器可以支持的web服务器返回内容压缩编码类型。Accept-Encoding: compress, gzipAccept-Language浏览器可接受的语言Accept-Language: en,zhAccept-Ranges可以请求网页实体的一个或者多个子范围字段Accept-Ranges: bytesAuthorizationHTTP授权的授权证书Authorization: Basic QWxhZIRpbjpvcGAuIHNlc2FtZQ==Cache-Control指定请求和响应遵循的缓存机制Cache-Control: no-cacheConnection表示是否需要持久连接。(HTTP 1.1默认进行持久连接)Connection: closeCookieHTTP请求发送时,会把保存在该请求域名下的所有cookie值一起发送给web服务器。Cookie: $Version=1; Skin=new;Content-Length请求的内容长度Content-Length: 348Content-Type请求的与实体对应的MIME信息Content-Type: application/x-www-form-urlencodedDate请求发送的日期和时间Date: Tue, 15 Nov 2010 08:12:31 GMTExpect请求的特定的服务器行为Expect: 100-continueFrom发出请求的用户的EmailFrom: user@email.comHost指定请求的服务器的域名和端口号Host: https://www.imooc.com/wiki/androidlesson/If-Match只有请求内容与实体相匹配才有效If-Match: “737060cd8c284d8af7ad3082f209582d”If-Modified-Since如果请求的部分在指定时间之后被修改则请求成功,未被修改则返回304代码If-Modified-Since: Sat, 29 Oct 2010 19:43:31 GMTIf-None-Match如果内容未改变返回304代码,参数为服务器先前发送的Etag,与服务器回应的Etag比较判断是否改变If-None-Match: “737060cd8c284d8af7ad3082f209582d”If-Range如果实体未改变,服务器发送客户端丢失的部分,否则发送整个实体。参数也为EtagIf-Range: “737060cd8c284d8af7ad3082f209582d”If-Unmodified-Since只在实体在指定时间之后未被修改才请求成功If-Unmodified-Since: Sat, 29 Oct 2010 19:43:31 GMTMax-Forwards限制信息通过代理和网关传送的时间Max-Forwards: 10Pragma用来包含实现特定的指令Pragma: no-cacheProxy-Authorization连接到代理的授权证书Proxy-Authorization: Basic QWxhZGbpbjpAcGVuIHNlc2FtZQ==Range只请求实体的一部分,指定范围Range: bytes=500-999Referer先前网页的地址,当前请求网页紧随其后,即来路https://www.imooc.com/wiki/androidlesson/TE客户端愿意接受的传输编码,并通知服务器接受接受尾加头信息TE: trailers,deflate;q=0.5Upgrade向服务器指定某种传输协议以便服务器进行转换(如果支持)Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11User-AgentUser-Agent的内容包含发出请求的用户信息User-Agent: Mozilla/5.0 (Linux; X11)Via通知中间网关或代理服务器地址,通信协议Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1)Warning关于消息实体的警告信息Warn: 199 Miscellaneous warning

4.2 运行程序 <a href="http://diff.py">diff.py</a>

1. 启动程序 diff.py$ python diff.py2. 在浏览器中访问 http://localhost:50003. 观察控制台的输出execute request without errorafter_requestteardown_request: None访问页面 / 时,执行处理函数 index,执行请求结束后,会调用 after_request 和 teardown_request。该函数执行期间没有发生异常,传递给 teardown_request 钩子函数的 exception 对象为 None。4. 在浏览器中访问 http://localhost:5000/error5. 观察控制台的输出execute request with errorTraceback (most recent call last): File "diff.py", line 14, in error 1 / 0ZeroDivisionError: division by zeroafter_requestteardown_request: division by zero访问页面 /error 时,执行处理函数 error,执行请求结束后,会调用 after_request 和 teardown_request。该函数执行期间发生异常,传递给 teardown_request 钩子函数的 exception 对象为 ZeroDivisionError。

2.2 第二步:在 http server 服务器中安装运行 Swagger Editor

要想在 http server 服务器中安装 Swagger Editor ,需要我们首先将 Swagger Editor 的压缩包下载下来,这就相当于在安装 Swagger Codegen 时的 Jar 包。出于方便考虑,我将 Swagger Editor 的资源压缩包放到了我的 Git 上面,同学们可以通过访问以下链接获取:https://github.com/SteafanMrZhou/MoocSwaggerWiki在安装好 http server 服务器之后,我们将下载好的压缩包进行解压,在解压完成后我们输入以下命令来启动 Swagger Editor 服务: http-server swagger-editor我们看到下图提示信息则表明 Swagger Editor 服务已经安装成功并成功运行:

HTTP 协议及其请求过程

TCP/IP 的网络模型有 7 层,Http 协议是位于最上层的应用层。应用层协议的意思是它是服务于我们能体验到的一些电脑软件,QQ/邮箱/浏览器这些。应用层下面还有好几层,他们主要保障的是网络传输中的一些安全性(会话加密),可靠性(字节冗余校验),字符转字节,字节转高低电平实现信号的传输等。

3.1.2 验证 HTTP Referer 字段

正常情况下,Referer 字段和请求的地址是位于同一域名下的。如果是 CSRF 攻击发起的请求,那么 Referer 字段和请求的地址就不是同一域名了,因此,服务器通过验证 HTTP Referer 字段就能识别出 CSRF 攻击。该方法的优点在于:只需要给所有安全敏感的请求统一增加一个拦截器来检查 Referer 的值就可以防御所有的 CSRF 攻击;特别是对于当前现有的系统,不需要改变当前系统的任何已有代码和逻辑,没有风险,非常便捷。该方法的缺点在于:攻击者能够篡改请求头的 Referer 字段内容,从而欺骗服务器;有可能无法获取 Referer 的值,因为 Referer 值会记录下用户的访问来源,有些用户认为这样会侵犯到他们自己的隐私权,因此,用户自己可以设置浏览器使其在发送请求时不再提供 Referer。

HTTP 协议与网站基本开发流程

上节课我们学习了 Web 开发中必备的一些 HTML/CSS/JS 这一节中我们会继续介绍下 Web 开发中的一些基础知识,包括常用术语、HTTP 协议、 URL 的组成部分,以及网站运行原理和开发的流程。只有理解了这些基础知识,才能继续后续的 Django 学习。

1.2 Http 响应

响应就是服务器收到我们的 request 之后给我们返回的数据,同样记录一下响应头:Header解释示例Accept-Ranges表明服务器是否支持指定范围请求及哪种类型的分段请求Accept-Ranges: bytesAge从原始服务器到代理缓存形成的估算时间(以秒计,非负)Age: 12Allow对某网络资源的有效的请求行为,不允许则返回405Allow: GET, HEADCache-Control告诉所有的缓存机制是否可以缓存及哪种类型Cache-Control: no-cacheContent-Encodingweb服务器支持的返回内容压缩编码类型Content-Encoding: gzipContent-Language响应体的语言Content-Language: en,zhContent-Length响应体的长度Content-Length: 348Content-Location请求资源可替代的备用的另一地址Content-Location: /index.htmContent-MD5返回资源的MD5校验值Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ==Content-Range在整个返回体中本部分的字节位置Content-Range: bytes 21010-47021/47022Content-Type返回内容的MIME类型Content-Type: text/html; charset=utf-8Date原始服务器消息发出的时间Date: Tue, 15 Nov 2010 08:12:31 GMTETag请求变量的实体标签的当前值ETag: “737060cd8c284d8af7ad3082f209582d”Expires响应过期的日期和时间Expires: Thu, 01 Dec 2010 16:00:00 GMTLast-Modified请求资源的最后修改时间Last-Modified: Tue, 15 Nov 2010 12:45:26 GMTLocation用来重定向接收方到非请求URL的位置来完成请求或标识新的资源Location: https://www.imooc.com/wiki/androidlesson/Pragma包括实现特定的指令,它可应用到响应链上的任何接收方Pragma: no-cacheProxy-Authenticate它指出认证方案和可应用到代理的该URL上的参数Proxy-Authenticate: Basic

3.2 访问资源的 API

客户端可以查看、新增、修改、删除主题,相应的 URI 如下:HTTP 方法行为URIGET获取所有的主题http://www.bbs.com/topicsGET获取特定的主题http://www.bbs.com/topics/123POST新建主题http://www.bbs.com/topicsPUT修改主题http://www.bbs.com/topics/123DELETE删除主题http://www.bbs.com/topics/123客户端可以查看、新增、修改、删除回复,相应的 URI 如下:HTTP 方法行为URIGET获取所有的回复http://www.bbs.com/answersGET获取特定的回复http://www.bbs.com/answers/456POST新建回复http://www.bbs.com/answersPUT修改回复http://www.bbs.com/answers/456DELETE删除回复http://www.bbs.com/answers/456

5.1. Netty 主启动类

public class MyWebSocketServer { public static void main(String[] args) throws Exception{ EventLoopGroup bossGroup = new NioEventLoopGroup(1); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap.group(bossGroup, workerGroup); serverBootstrap.channel(NioServerSocketChannel.class); serverBootstrap.childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); //因为基于http协议,使用http的编码和解码器 pipeline.addLast(new HttpServerCodec()); //是以块方式写,添加ChunkedWriteHandler处理器 pipeline.addLast(new ChunkedWriteHandler()); //http数据在传输过程中是分段, HttpObjectAggregator ,就是可以将多个段聚合 pipeline.addLast(new HttpObjectAggregator(8192)); //将 http协议升级为 ws协议 , 保持长连接 pipeline.addLast(new WebSocketServerProtocolHandler("/hello2")); //自定义的handler ,处理业务逻辑 pipeline.addLast(new MyWebSocketHandler()); } }); //启动服务器 ChannelFuture channelFuture = serverBootstrap.bind(7000).sync(); channelFuture.channel().closeFuture().sync(); }finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } }}代码说明:WebSocket 比 TCP 和 Http 协议都稍微复杂有点,它其实是 TCP 和 Http 协议的结合,首先是连接之前发送的是 Http 协议请求,但是新增 Http 所没有的附加头信息 Upgrade: WebSocket 表明是一个申请协议升级的 Http 请求。其次,真正建立连接之后,其实底层是 TCP 协议长连接;HttpServerCodec 将请求和应答消息解码为 HTTP 消息;ChunkedWriteHandler 向客户端发送 HTML5 文件;http 数据在传输过程中是分段,当浏览器发送大量数据时,就会发出多次 http 请求, HttpObjectAggregator 可以将 HTTP 消息的多个部分合成一条完整的 HTTP 消息;WebSocketServerProtocolHandler 定义了 WebSocket 的对外暴露地址。

3. 小结

这一小节,我们讲解了 HTTP 的基本概念,熟悉了 HTTP 简单的工作流程。其实 HTTP 协议比较复杂,感兴趣的读者可以更加深入的去学习 HTTP 底层的原理,对以后开发爬虫以及 WEB 应用都有很大的帮助。

4.2 proxy_cache 缓存实验

准备好 proxy_cache 缓存相关的配置,如下:...http { server { listen 8000; location / { default_type text/plain; return 200 '8000, server\n'; } } server { listen 8001; location / { default_type text/plain; return 200 '8001, server\n'; } } server { listen 8002; location / { default_type text/plain; return 200 '8002, server\n'; } } # 定义上游服务器 upstream backends { server 127.0.0.1:8000; server 127.0.0.1:8001; server 127.0.0.1:8002; } # proxy_cache_path 指令 proxy_cache_path /root/test/cache levels=1:2 keys_zone=nginx_cache:10m max_size=10g inactive=60m use_temp_path=off; server { listen 80; location / { proxy_pass http://backends; proxy_cache nginx_cache; # 状态码为200和301的缓存1分钟 proxy_cache_valid 200 301 1m; # 其余的缓存10分钟 proxy_cache_valid any 10m; # response响应的头信息中定义缓存的状态(有没有命中) proxy_cache_key "$host$uri$is_args$args"; expires 1d; proxy_no_cache $cookie_nocache $arg_nocache $arg_comment; proxy_no_cache $http_pragma $http_authorization; # add_header 响应添加缓冲命中结果 add_header Nginx-Cache "$upstream_cache_status"; } }...我们通过 curl 命令向 Nginx 所在主机的 80端 请求,第一次请求转发到8000端口,结果被缓存; 第2-3次请求时由缓存返回结果,所以仍然是8000端口的返回;等待超过1分钟后,缓存失效,请求被转发到8001端口进行处理,返回相应结果;最后再次请求80端口,依旧由缓存命中,返回8001端口的响应结果。参看日志记录的 http 请求。# 第一次请求,转到8000端口响应,然后缓存[shen@shen ~]$ curl http://180.76.152.1138000, server# 接下来请求全部由缓存命中[shen@shen ~]$ curl http://180.76.152.1138000, server[shen@shen ~]$ curl http://180.76.152.1138000, server[shen@shen ~]$ curl http://180.76.152.1138000, server# 缓存失效,转发到8001端口相应,并缓存结果[shen@shen ~]$ curl http://180.76.152.1138001, server# 继续命中缓存[shen@shen ~]$ curl http://180.76.152.1138001, server查看请求的响应结果:[root@server sbin]# tail -f ../logs/access.log127.0.0.1 - - [06/Feb/2020:20:14:15 +0800] "GET / HTTP/1.0" 200 13 "-" "curl/7.29.0" "-""-"103.46.244.69 - - [06/Feb/2020:20:14:15 +0800] "GET / HTTP/1.1" 200 13 "-" "curl/7.29.0" "-""MISS"103.46.244.69 - - [06/Feb/2020:20:14:23 +0800] "GET / HTTP/1.1" 200 13 "-" "curl/7.29.0" "-""HIT"103.46.244.69 - - [06/Feb/2020:20:14:26 +0800] "GET / HTTP/1.1" 200 13 "-" "curl/7.29.0" "-""HIT"127.0.0.1 - - [06/Feb/2020:20:16:10 +0800] "GET / HTTP/1.0" 200 13 "-" "curl/7.29.0" "-""-"103.46.244.69 - - [06/Feb/2020:20:16:10 +0800] "GET / HTTP/1.1" 200 13 "-" "curl/7.29.0" "-""EXPIRED"103.46.244.69 - - [06/Feb/2020:20:16:22 +0800] "GET / HTTP/1.1" 200 13 "-" "curl/7.29.0" "-""HIT"

直播
查看课程详情
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号