HttpClient 4.3教程 第六章 HTTP缓存

HttpClient 4.3教程 第六章 HTTP缓存

Posted on 2013 年 10 月 28 日

6.1.基本概念

HttpClient的缓存机制提供一个与HTTP/1.1标准兼容的缓存层 – 相当于Java的浏览器缓存。HttpClient缓存机制的实现遵循责任链(Chain of Responsibility)设计原则,默认的HttpClient是没有缓存的,有缓存机制的HttpClient可以用来临时替代默认的HttpClient,如果开启了缓存,我们的请求结果就会从缓存中获取,而不是从目标服务器中获取。如果在Get请求头中设置了If-Modified-Since或者If-None-Match参数,那么HttpClient会自动向服务器校验缓存是否过期。

HTTP/1.1版本的缓存是语义透明的,意思是无论怎样,缓存都不应该修改客户端与服务器之间传输的请求/响应数据包。因此,在existing compliant client-server relationship中使用带有缓存的HttpClient也应该是安全的。虽然缓存是客户端的一部分,但是从Http协议的角度来看,缓存机制是为了兼容透明的缓存代理。

最后,HttpClient缓存也支持RFC 5861规定的Cache-Control拓展(stale-if-error‘和stale-while-revalidate`)。

当开启缓存的HttpClient执行一个Http请求时,会经过下面的步骤:

  • 检查http请求是否符合HTTP 1.1的基本要求,如果不符合就尝试修正错误。
  • 刷新该请求无效的缓存项。(Flush any cache entries which would be invalidated by this request.)
  • 检测该请求是否可以从缓存中获取。如果不能,直接将请求发送给目标服务器,获取响应并加入缓存。
  • 如果该请求可以从缓存中获取,HttpClient就尝试读取缓存中的数据。如果读取失败,就会发送请求到目标服务器,如果可能的话,就把响应缓存起来。
  • 如果HttpClient缓存的响应可以直接返回给请求,HttpClient就会构建一个包含ByteArrayEntityBasicHttpResponse对象,并将它返回给http请求。否则,HttpClient会向服务器重新校验缓存。
  • 如果HttpClient缓存的响应,向服务器校验失败,就会向服务器重新请求数据,并将其缓存起来(如果合适的话)。
    当开启缓存的HttpClient收到服务器的响应时,会经过下面的步骤:
  • 检查收到的响应是否符合协议兼容性
  • 确定收到的响应是否可以缓存
  • 如果响应是可以缓存的,HttpClient就会尽量从响应消息中读取数据(大小可以在配置文件进行配置),并且缓存起来。
  • 如果响应数据太大,缓存或者重构消耗的响应空间不够,就会直接返回响应,不进行缓存。
    需要注意的是,带有缓存的HttpClient不是HttpClient的另一种实现,而是通过向http请求执行管道中插入附加处理组件来实现的。

6.2. RFC-2616 Compliance

HttpClient的缓存机制和RFC-2626文档规定是无条件兼容的。也就是说,只要指定了MUSTMUST NOTSHOULD或者SHOULD NOT这些Http缓存规范,HttpClient的缓存层就会按照指定的方式进行缓存。即当我们使用HttpClient的缓存机制时,HttpClient的缓存模块不会产生异常动作。

6.3. 使用范例

下面的例子讲述了如何创建一个基本的开启缓存的HttpClient。并且配置了最大缓存1000个Object对象,每个对象最大占用8192字节数据。代码中出现的数据,只是为了做演示,而过不是推荐使用的配置。

    CacheConfig cacheConfig = CacheConfig.custom()
            .setMaxCacheEntries(1000)
            .setMaxObjectSize(8192)
            .build();
    RequestConfig requestConfig = RequestConfig.custom()
            .setConnectTimeout(30000)
            .setSocketTimeout(30000)
            .build();
    CloseableHttpClient cachingClient = caching HttpClients.custom()
            .setCacheConfig(cacheConfig)
            .setDefaultRequestConfig(requestConfig)
            .build();

    HttpCacheContext context = HttpCacheContext.create();
    HttpGet httpget = new HttpGet("http://www.mydomain.com/content/");
    CloseableHttpResponse response = cachingClient.execute(httpget, context);
    try {
        CacheResponseStatus responseStatus = context.getCacheResponseStatus();
        switch (responseStatus) {
            case CACHE_HIT:
                System.out.println("A response was generated from the cache with " +
                        "no requests sent upstream");
                break;
            case CACHE_MODULE_RESPONSE:
                System.out.println("The response was generated directly by the " +
                "caching module");
                break;
            case CACHE_MISS:
                System.out.println("The response came from an upstream server");
                break;
            case VALIDATED:
                System.out.println("The response was generated from the cache " +
                "after validating the entry with the origin server");
                break;
        }
    } finally {
        response.close();
     }

6.4. 配置

有缓存的HttpClient继承了非缓存HttpClient的所有配置项和参数(包括超时时间,连接池大小等配置项)。如果需要对缓存进行具体配置,可以初始化一个CacheConfig对象来自定义下面的参数:

  • Cache size(缓存大小). 如果后台存储支持,我们可以指定缓存的最大条数,和每个缓存中存储的response的最大size。
  • Public/private cacheing(公用/私有 缓存). 默认情况下,缓存模块会把缓存当做公用的缓存,所以缓存机制不会缓存带有授权头消息或者指定Cache-Control:private的响应。但是如果缓存只会被一个逻辑上的用户使用(和浏览器饿缓存类似),我们可能希望关闭缓存共享机制。
  • Heuristic caching(启发式缓存)。即使服务器没有明确设置缓存控制headers信息,每个RFC2616缓存也会存储一定数目的缓存。这个特征在HttpClient中默认是关闭的,如果服务器不设置控制缓存的header信息,但是我们仍然希望对响应进行缓存,就需要在HttpClient中打开这个功能。激活启发式缓存,然后使用默认的刷新时间或者自定义刷新时间。更多启发式缓存的信息,可以参考Http/1.1 RFC文档的13.2.2小节,13.2.4小节。
  • Background validation(后台校验)。HttpClient的缓存机制支持RFC5861的stale-while-revalidate指令,它允许一定数目的缓存在后台校验是否过期。我们可能需要调整可以在后台工作的最大和最小的线程数,以及设置线程在回收前最大的空闲时间。当没有足够线程来校验缓存是否过期时,我们可以指定排队队列的大小。

6.4.存储介质

默认,HttpClient缓存机制将缓存条目和缓存的response放在本地程序的jvm内存中。这样虽然提供高性能,但是当我们的程序内存有大小限制的时候,这就会变得不太合理。因为缓存的生命中期很短,如果程序重启,缓存就会失效。当前版本的HttpClient使用EhCache和memchached来存储缓存,这样就支持将缓存放到本地磁盘或者其他存储介质上。如果内存、本地磁盘、外地磁盘,都不适合你的应用程序,HttpClient也支持自定义存储介质,只需要实现HttpCacheStorage接口,然后在创建HttpClient时,使用这个接口的配置。这种情况,缓存会存储在自定义的介质中,但是you will get to reuse all of the logic surrounding HTTP/1.1 compliance and cache handling. 一般来说,可以创建出支持任何键值对指定存储(类似Java Map接口)的HttpCacheStorage,用于进行原子更新。

最后,通过一些额外的工作,还可以建立起多层次的缓存结构;磁盘中的缓存,远程memcached中的缓存,虚拟内存中的缓存,L1/L2处理器中的缓存等。

易踪网:每天进步一点点

转载请保留链接地址: http://www.yeetrack.com/?p=844

时间: 2024-09-30 22:53:43

HttpClient 4.3教程 第六章 HTTP缓存的相关文章

C#图解教程 第六章 深入理解类

深入理解类 类成员成员修饰符的顺序实例类成员静态字段从类的外部访问静态成员 静态字段示例静态成员的生存期 静态函数成员其他静态类成员类型成员常量常量与静态量属性 属性声明和访问器属性示例使用属性属性和关联字段执行其他计算只读和只写属性属性与公共字段计算只读属性示例自动实现属性静态属性 实例构造函数 带参数的构造函数默认构造函数 静态构造函数对象初始化语句析构函数readonly修饰符this关键字索引器 什么是索引器索引器和属性声明索引器索引器的set访问器索引器的get访问器关于索引器的补充为

Python基础教程 第六章 学习笔记

收集函数 把实际参收集到元组和字典当中 1 def print_params(*params): 2 print(params) 3 """ 4 print_parasm(1,2,3) 5 output: (1,2,3) 6 """ 7 8 def print_params_2(**params): 9 print(params) 10 11 """ 12 print_params_2(x=1, y=2, z=3)

ArcGIS for Desktop入门教程_第六章_用ArcMap制作地图 - ArcGIS知乎-新一代ArcGIS问答社区

原文:ArcGIS for Desktop入门教程_第六章_用ArcMap制作地图 - ArcGIS知乎-新一代ArcGIS问答社区 1 用ArcMap制作地图 作为ArcGIS for Desktop的组成部分之一,ArcMap用于数据的浏览.编辑.显示.查询.地图排版等.ArcMap和ArcCatalog一起构成了完整的数据处理与管理分析的功能.在前一章中已经介绍了ArcCatalog的使用,本章中将介绍ArcMap的使用.本章的例子依然使用第4章里的小区平面图示例,但是将从原理的角度做更加

JAVA: httpclient 详解——第六章;

httpclient 详解--第一章: httpclient 详解--第二章: httpclient 详解--第三章: httpclient 详解--第四章: httpclient 详解--第五章: httpclient 详解--第六章: httpclient 详解--第七章: 相对于httpurlconnection ,httpclient更加丰富,也更加强大,其中apache有两个项目都是httpclient,一个是commonts包下的,这个是通用的,更专业的是org.apache.htt

HttpClient 4.3教程 第一章 基本概念

HttpClient 4.3教程 第一章 基本概念 Posted on 2013 年 10 月 9 日 1.1. 请求执行 HttpClient最基本的功能就是执行Http方法.一个Http方法的执行涉及到一个或者多个Http请求/Http响应的交互,通常这个过程都会自动被HttpClient处理,对用户透明.用户只需要提供Http请求对象,HttpClient就会将http请求发送给目标服务器,并且接收服务器的响应,如果http请求执行不成功,httpclient就会抛出异样. 下面是个很简单

Ajax本地跨域问题 Cross origin requests are only supported for HTTP(针对jQuery基础教程第四版第六章)

出现的问题: 解决的步骤: 谷歌浏览器出现的效果: 针对jQuery基础教程(第四版),第六章  成功: 原文地址:https://www.cnblogs.com/qinghui258/p/8432569.html

实战SpringCloud响应式微服务系列教程(第六章)

本章节介绍:Flux和Mono操作符 和其他主流的响应式编程一样,Reactor框架的设计目标也是为了简化相应式流的使用方法.为此Reactor框架提供了大量操作符用于操作Flux和Mono对象. 本节不打算全面详细介绍,我们的思路是将这些操作符分类,然后对每一类中具有代表性的操作符展开讨论. 对于其他没有介绍到的操作符可参考Reactor框架的官方文档. 在本节中我们把Flux和Mono操作符分为以下7大类. 转换 (Transforming)操作符负责对序列中的元素进行转变. 过滤 (Fil

【Java】《Java程序设计基础教程》第六章学习

第六章 常用的工具包 6.1 java.lang包 6.1.1 Object类 Object类是一个超级类,是所有类的直接或间接父类. public boolean equals(Object obj) 比较两个对象是否相同,相同就返回true,否则返回false public String toString() 返回对象的字符串表示 public final Class getClass() public int hashCode() protected Object clone() prot

Flask 教程 第十六章:全文搜索

本文翻译自The Flask Mega-Tutorial Part XVI: Full-Text Search 这是Flask Mega-Tutorial系列的第十六部分,我将在其中为Microblog添加全文搜索功能. 本章的目标是为Microblog实现搜索功能,以便用户可以使用自然语言查找有趣的用户动态内容.许多不同类型的网站,都可以使用Google,Bing等搜索引擎来索引所有内容,并通过其搜索API提供搜索结果. 这这方法适用于静态页面较多的的大部分网站,比如论坛. 但在我的应用中,基