【问题标题】:How do i effectively check a picture repository website for changes?我如何有效地检查图片存储库网站的更改?
【发布时间】:2017-06-21 09:30:20
【问题描述】:

我目前正在开发一种同步服务,该服务从交换服务器获取所有用户个人资料图片。 为了跟踪更改,我决定对响应正文进行 MD5 编码并将其与数据库中的实体一起保存,以便进一步比较它并查看图片是否已更改。而实际图片本身保存在磁盘上。

图片大小为 504x504 像素,因此重量约为 27 kb。 而且由于我正在获取字节码的哈希值,即使图片匹配,我仍然必须下载 27kb 数组,这几乎不会导致速度提高(除了我不必在磁盘上替换它)。将其乘以大量用户,即使所有图片都匹配,这项工作也需要 20 分钟。

有没有办法优化同步,所以如果图片相同,我就不会下载响应正文? 这里有一些代码可以帮助你更好地理解:

entity = restTemplate.getForEntity(
                Constant.EXCHANGE_URL_PREFIX + emailAddress + Constant.EXCHANGE_URL_SUFFIX, byte[].class);

这就是我调用 get 请求的方式。

if (entity.hasBody()) {
 String hexHash = Hex.encodeHexString(MessageDigest.getInstance("MD5").digest(bytes));
 if (!listofHashes.contains(hexHash)) {
    picture.remove();
 } else picture.save();
}

总结一下:有没有办法使用不下载整个页面的restTemplate检测网页更改?提前谢谢你。

编辑:对 ETag 标头以及 @Cacheable 注释的进一步研究并未成功。

【问题讨论】:

  • 可能是developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Last-Modified,但不能保证服务器会同时发送该信息
  • 不幸的是,我已经比较了多个请求标头,除了 request-id 之外,其他字段都相同
  • 您是否尝试发出HEAD 请求而不是GET 并检查响应标头?您是否尝试在请求中发送 If-Modified-Since 标头?
  • @yinon 我尝试发送 If-Modified-Since,但不是 HEAD 请求,将对其进行调查

标签: java resttemplate spring-web


【解决方案1】:

这实际上取决于您与之通信的服务器的功能。如果该服务器不支持任何standard mechanismsETagIf-Modified-Since 等,如 cmets 中所述)或发送任何其他自定义标头,那么您别无选择,只能执行您描述的操作 - 计算摘要客户端的响应正文(在您的应用程序中)。

【讨论】:

    【解决方案2】:

    您可以尝试使用 HTTP GET 但仅请求标头。

    然后,从回复中验证“content-length”和“last-modified”(如果它们与您已存储的图像不匹配,则必须重新下载)

    例如,对 Wikipedia 中的图像执行此操作时,我得到了这些:

    内容长度:314402

    最后修改时间:2013 年 10 月 31 日星期四 14:45:43 GMT

    注意,关于“内容长度”:

    Content-Length entity-header 字段指示发送给接收者的实体主体的大小,以十进制的八进制数表示,或者在 HEAD 方法的情况下,实体主体的大小将具有如果请求是 GET,则已发送。 (在此处查看更多信息:http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

    这是我使用的 curl 命令:

    $ curl -X HEAD -I "https://upload.wikimedia.org/wikipedia/commons/thumb/a/aa/            Lifeboat.17-31.underway.arp.jpg/1200px-Lifeboat.17-31.underway.arp.jpg"
    
    HTTP/2 200 
    date: Thu, 29 Jun 2017 08:30:29 GMT
    content-type: image/jpeg
    content-length: 314402
    x-object-meta-sha1base36: oboqyviefa9uqy9p7391dxgod784onh
    last-modified: Thu, 31 Oct 2013 14:45:43 GMT
    etag: 188492bd99a0032624df62205d156bb4
    x-timestamp: 1383230742.02258
    x-trans-id: tx73ff02723dc5476c92e0a-005953e448
    x-varnish: 894182014 897225224, 41759639 11075541, 415722130
    via: 1.1 varnish-v4, 1.1 varnish-v4, 1.1 varnish-v4
    accept-ranges: bytes
    age: 54876
    x-cache: cp1063 hit/1, cp3045 hit/72, cp3049 pass
    x-cache-status: hit
    strict-transport-security: max-age=31536000; includeSubDomains; preload
    x-analytics: https=1;nocookies=1
    x-client-ip: 82.181.132.52
    access-control-allow-origin: *
    access-control-expose-headers: Age, Date, Content-Length, Content-Range, X-Content-    Duration, X-Cache, X-Varnish
    timing-allow-origin: *
    

    【讨论】:

      【解决方案3】:

      条件获取

      如果你的服务器实现了standard of Http1.1,你可以使用以下任意一对来实现:

      • Last-Modified/If-Modified-Since
      • ETag/If-None-Match

      如果 etag 匹配或自上次获取日期以来未修改,服务器应返回 304(未修改)。

      示例:

      请求标头:

      If-Modified-Since:Sat, 06 Aug 2016 05:22:27 GMT
      If-None-Match:"02c7fd69fa875302f71b714fa2787cc95fa88245"
      

      响应标头:

      Last-modified:Sat, 04 Apr 2015 09:05:44 GMT
      Etag: "02c7fd69fa875302f71b714fa2787cc95fa88245"
      

      结论

      • 其实你做的应该是你的Exchange服务器做的,而不是客户端做的,这就是304的作用;
      • Last-Modified 方式会受到分布式系统中时间漂移的影响,而 Etag 不会;
      • 另一方面,Etag可能涉及文件系统的inode信息,因此移动文件也可能影响Etag值;

      参考

      【讨论】:

      • 谢谢,我会尝试发送条件标头
      猜你喜欢
      • 2018-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-25
      相关资源
      最近更新 更多