Chinaunix首页 | 论坛 | 博客
  • 博客访问: 635257
  • 博文数量: 356
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 2287
  • 用 户 组: 普通用户
  • 注册时间: 2013-04-08 17:08
文章分类

全部博文(356)

文章存档

2023年(3)

2022年(7)

2021年(33)

2020年(47)

2019年(36)

2018年(221)

2017年(1)

2015年(1)

2013年(7)

我的朋友

分类: LINUX

2018-06-29 09:41:34

来源: https://blog.zymlinux.net/index.php/archives/1146

引子

Prefetch是一个ATS代码里有,管理文档里没有说,也没有其他任何官方说明的功能。当然,这是一个非常强大的隐藏的功能,不然我们也不去管它了。这里我将会介绍这个功能的主要设计思想,以及如何使用,并且介绍后续的开发与优化路线图,希望可以帮助大家理解ATS的强大与系统化设计思想,帮助大家掌握ATS的使用、二次开发,创造更大的价值。

背景

我们假设有这么个网络环境,这个网络环境的延迟很大很大,比如比中美之间的延迟还大,并且网络的效率也不高,还会有丢包,并且带宽成本还很高,你希望优化用户的感受,并且极致的压缩带宽开销,你可以用ATS做什么样的工作呢?

设计

ATS的开发者在这个场景下,首先想到了是如何改善网络延迟带来的不爽:

  • 首先,网络上的延迟在应用层面已经是无解的了,ATS并没有做到tcp协议优化层面来,而是独辟蹊径,在服务器端通过解析用户请求的html内容,提前预知用户可能请求的资源文件的方式,来预取后续用户端可能需要的资源,这样等用户端解析完html内容,对ATS发起请求的时候,ATS已经开始预取了很多内容,并且甚至已经递归到了后面好几层的网页资源了。用户端浏览器多数请求的资源都会已经缓存在cache里或者正在回源取的过程里了,如果正在回源的内容,又可以配合rww的回源合并功能避免重复回源,从而获得良好的用户端感受。

  • 然后,聪明的开发者又想到了如何压缩传输中的数据以减少数据传输量,提高传输效率。ATS在这种情况下,一般会在网络的两端分别部署,这样的话,中间网络就是一个管道,管道上传输的资源可以进一步压缩,甚至在进入管道前,可以对资源做更进一步的压缩,可能的方向包括但不限于:

    1. 压缩html内容,采用更高级的压缩比压缩
    2. 压缩jss css文件,采用minify这种类似的压缩技术
    3. 压缩图片文件,使用图片处理库做进一步的尺寸、压缩比例调整以减少图片字节大小

    是啊,我们的资源既然已经先于用户开始从源服务器下载了,抢先出来的时间,自然可以干点什么更有意义的事情啦,比如这里比较耗时的压缩、再压缩等。哎,你永远也不知道还有多少空间可以压榨的,干脆交给用户来搞吧,于是有了Prefetch相关的一堆API。

原理

Prefetch的原理很单纯,简单的原理就是,接收到了客户请求的返回html后,分析其中的页面元素、下层链接,提取出来后,逐个从本机发起一个对本机代理端口的一个请求,形成一个ATS抢跑客户端请求预先加载的结果,为了控制,这个功能里可以配置谁来触发这个功能、以及要分析提取的tag等等。

如何使用呢?

我们在前面已经把Prefetch的前因后果交代出来了,现在来看看如何启用Prefetch功能。

Prefetch可以说是一个实现在核心中的业务功能,是基于Scheduled Update功能核心模块做出来的,作为核心一部分就会使用核心的配置管理方法:

  • records.config:

    records.config中的配置项不多,关键的也就是前三个,其中需要改的,也就是第一个prefetch_enabled这个选项,buffer相关的就是得根据业务情况来调整了。

    proxy.config.prefetch.prefetch_enabled        控制是否启用Prefetch功能
    proxy.config.prefetch.child_port              指定Prefetch的发起端口用哪个
    proxy.config.prefetch.config_file
    proxy.config.prefetch.url_buffer_size
    proxy.config.prefetch.url_buffer_timeout
    proxy.config.prefetch.keepalive_timeout
    proxy.config.prefetch.push_cached_objects
    proxy.config.prefetch.default_url_proto
    proxy.config.prefetch.default_data_proto
    proxy.config.prefetch.max_object_size
    proxy.config.prefetch.max_recursion
    proxy.config.prefetch.redirection 
  • prefetch.config:

    Prefetch.config是一个简单的配置文件,主要控制对那些客户端启用Prefetch功能,对哪些html标签如何提取资源URL两个方面:

    1. 如何控制对哪些客户端启用Prefetch功能,目前采用的是一个简单模式,定一个IP地址段,如果客户端IP地址在这个范围内,我们就会对它启用Preftch功能:

      prefetch_children 10.0.0.0 - 10.255.255.255, 216.1.2.3 
    2. 对哪些html标签如何提取资源URL?这里的格式比较复杂,又分为简单格式和复杂格式

      简单格式为:

      html_tag tag attr,例子:html_tag img src定义了取<img height=10 width=10 src="http://www.example.com/images/1.gif"/>中的src里的URL为需要递归的资源。 

      复杂格式:

      html_tag tag attr filter_attr filter_value,例子:html_tag link href rel stylesheet定义了取<link rel="stylesheet" type="text/css" href="example.css"/>中的css属性的链接URL为需要递归的资源。 

      默认的配置中,已经包含了常用的html标签定义,如果你自己定义的话,就会覆盖掉这些默认的定义:

      html_tag img src
      html_tag body background
      html_tag frame src
      html_tag fig src
      html_tag applet code
      html_tag script src
      html_tag embed src
      html_tag td background
      html_tag base href 
      html_tag meta content
      html_tag input src
      html_tag link href rel stylesheet 

Prefetch实践效果

  • 实践用法之缓存灌数据

    大家都知道缓存的数据从0到满,需要很长时间,尤其是现在的大容量缓存,那都需要几周甚至月的。如果我们能够把数据从一个已在线的节点把数据复制到新节点,是不是会很高效?或者利用已在线的节点的访问纪录来主动跑一遍这些url?当然,如果你已经拿到这些url后,就可以用http_load等工具来对缓存做取的动作,然后就可以做到灌数据的效果了。

    如果我们使用Prefetch,只需要这样做:

    1. 把访问日志提取出来的经过去重的URL列表,按照固定个数分割为多个文件,并且使用如下格式存储各个URL:<img src="URL"/>
    2. 将生产的各个文件放在某个http服务器下,并让ATS可访问(配置remap啊),假设为:,如 1.html
    3. 配置records.config,启用Prefetch:traffic_line -s proxy.config.prefetch.prefetch_enabled -v 1
    4. 配置prefetch.config,对内网192.168.0.0/24客户端启用Prefetch功能,使用默认tag:prefetch_children 192.168.0.0 – 192.168.0.255
    5. 从内网,对ATS服务器,请求下的文件,将会起到相当帅的预加载效果

    本人实测,用这个模式刷缓存,加载速度远超对外服务能力,可能是由于ATS的顺序写磁盘优化在sata传统盘上的效果比较好的缘故吧。

  • 实践例子:

    测试代码里的那个test-hns-plugin.c的,极有可能是为 satellite company Hughes Network Systems做过啥特别的插件,请参考:
    ~bakos/classes/cdn.pdf 请有兴趣的同学自己挖掘吧。

问题以及后续

Prefetch也不是没有问题:

  1. 如果html内容是经过压缩的,目前的代码无法自解压
  2. 代码晦涩难懂,中间有很多什么UDP的东东,让人不懂
  3. API貌似问题比较多,社区的人多数不懂这个业务,甚至威胁要删掉

但是,基于移动互联网以及业务Edge化的考虑,类似Prefetch这种优化,将是非常非常有意思的一些领域,前途无量啊。

So,问题是你觉得呢?我觉得吧,好功能也得靠用户捧,玩社区就是要参与,要是你觉得好,去社区里voice出来啊,它的未来靠你了。


阅读(2085) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~