注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

itoedr的it学苑

记录从IT文盲学到专家的历程

 
 
 

日志

 
 

ATS插件开发基础(阿里永明讲义)  

2014-03-19 15:56:45|  分类: trafficserver编 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

编者注:随对ATS的使用加深,有些东西就需要自己手了,收集了本部分资源.

ATS插件开发需要提前了解ATS的插件的一些设计思想,以及系统提供的一些不同方向。我们将会介绍ATS的基础开发知识,以利于后续的插件开发课程讲解。

ATS的SDK文档,是了解ATS的核心设计、接口设计的很重要资料,甚至是老的PDF版本文档,都是非常非常有用的资料。以至于我经常建议完全不 了解ATS核心代码的初学者也好好看看SDK文档,这里讲的很多基础知识,有利于对核心的深入理解。ATS的API以及核心插件接口设计是一个很庞大的工 程,其设计思想我们很难一下消化掉,这里点出一些知识点供大家参考。如有纰漏、谬误之处,以SDK文档、代码注释、代码为准。

官方SDK文档

历史的SDK PDF文件

下一篇:手把手教你写plugin

ATS开发环境

名词解释

  • HTTP Transaction

    HTTP Transaction 是ATS特指http的处理流程,在ATS中,一个HTTP的请求的处理过程,叫做一个HTTP Transaction。ATS的很多API是以Transaction为核心的函数处理过程,也就赋予了这个过程以特殊的意义。在相关的API函数 中,TSHttpTxn数据结构,以及以TSHttpTxn开头的API函数都是围绕这个处理流程来的。

  • HTTP SM

    HTTP SM 是一般是指ATS的主流程状态机,在ATS中,处理的流程是通过HTTP Transaction中的函数处理的,而状态数据是存储在HTTP SM中的。ATS核心主流程就是HTTP Transaction和HTTP SM的交互过程。

  • HTTP session

    HTTP session是指http会话,一般指一个请求交互过程,特指如客户端的一个请求,回源的一个请求,分别对应客户端和服务器端HTTP session。对照HTTP Transaction,我们对应的ATS一个用户请求引起的ATS HTTP Transaction,可以包含一个客户端 HTTP Session,0个或1个甚至多个回源 HTTP Session。

  • remap

    remap是ATS做URL rewrite的方式,也是ATS在配置文件设计方面的特殊部分。从功能上来讲,ATS的remap更像一个精简版本的Apache Httpd的rewrite模块。remap之所以重要,是因为它定义了一个很方便的API入口,我们可以通过remap系统,编写remap插件。

基础知识:

  • Continuation

    Continuation,从学术上应该是叫做Continuation的编程模型(方法),这个技术相当古老,后来微软围绕这个方案,改进出了 coroutine的编程模型(方法),一定程度上来讲Continuation是整个异步回调机制的多线程事件编程基础。对应ATS 中,Continuation是一个最最基础的抽象结构,后续的所有高级结构,如Action Event VC等都封装Continuation数据结构,我们先看Continuation结构的实际代码:

    class Continuation: private force_VFPT_to_top
    {
    public:
        ContinuationHandler handler;
        Ptr<proxymutex> mutex;
        LINK(Continuation, link);
    
        int handleEvent(int event = CONTINUATION_EVENT_NONE, void *data = 0) {
        return (this->*handler) (event, data);
        }
    
        Continuation(ProxyMutex * amutex = NULL);
    };
    

    Continuation主要包含:

    • handler:当前的Continuation处理函数。
    • mutex:Continuation的锁。
    • link:链接到其他Continuation的双链表。
    • handleEvent:接收event的代码和数据,并交给当前的处理函数处理。

    结构非常精炼,并不代表特殊含义。

    Continuation在API中的结构叫TSCont,是插件开发中最常用到的抽象之一,是多数API要求的参数结构。在插件编程中的主要用到的如blacklit-0中的代码:

    TSHttpHookAdd(TS_HTTP_OS_DNS_HOOK, TSContCreate(blacklist_plugin, NULL));
    

    这是一个hook函数,在TS_HTTP_OS_DNS_HOOK阶段,hook进去了blacklist_plugin(见下面代码),而blacklist_plugin 函数事实上只是一个事件处理的handler而以,这里通过TSContCreate转化为TSCont结构。通过这些API,插件开发者可以更关注业务流程实现,甚至都可以不用去理解ATS核心的复杂异步事件化机制,只需要照着例子来堆代码就好啦。

    static int
    blacklist_plugin(TSCont contp, TSEvent event, void *edata)
    {
      TSHttpTxn txnp = (TSHttpTxn) edata;
    
      switch (event) {
      case TS_EVENT_HTTP_OS_DNS:
        handle_dns(txnp, contp);
        return 0;
      case TS_EVENT_HTTP_SEND_RESPONSE_HDR:
        handle_response(txnp);
        return 0;
      default:
        break;
      }
      return 0;
    }
    
  • Action

    Action是一个抽象出来的,由处理机处理的异步任务模型。这个任务是可以在异步处理环境中允许撤销的。简单的以为可以说是一个可以撤销的函数机制?

    这个结构的主要用处是用来构建统一的Event系统,用在底层的iocore/中的网络以及磁盘IO等方面。当然,ATS的上层建筑更是依赖于它了。

    class Action
    {
    public:
        Continuation * continuation;
        Ptr</proxymutex><proxymutex> mutex;
        volatile int cancelled;
    
        virtual void cancel(Continuation * c = NULL) {
        if (!cancelled)
            cancelled = true;
        }
    
        void cancel_action(Continuation * c = NULL) {
        if (!cancelled)
            cancelled = true;
        }
    
        Continuation *operator =(Continuation * acont)
        {
        continuation = acont;
        if (acont)
            mutex = acont->mutex;
        else
            mutex = 0;
        return acont;
        }
    
        Action():continuation(NULL), cancelled(false) {
        }
    
        virtual ~ Action() {
        }
    };
    

    关于Action,有几个需要注意的地方:

    • Action是可以再入的
    • 撤销必须是由任务的callback处理机来做
    • 要撤销必须先拿到锁
    • Action是由处理机创建的,在完成或撤销的时候,也是由处理机负责的。状态机不能在Action完成或撤销后再访问它
  • Event

    Event是由Event处理机返回的一种Action。是可以用来调度出去从而异步处理的任务(Action)。event是不可再入的。由于它继承自Action,因此也具有可以撤销的机制,同时更可以在收到Event后处理或不处理而再调度出去,这个很乱啊:D

    Event的调度分为4种:

    • _imm:立即执行,这个模式讲会直接让Event进入待执行队列
    • _at:在未来某个具体时间,指定具体事件执行
    • _in:在未来某段时间后,指定具体多久之后执行
    • _every:每隔多长事件,让事件循环执行,类似cron等定时任务

      class Event:public Action { public: void schedule_imm(int callback_event = EVENT_IMMEDIATE); void schedule_at(ink_hrtime atimeout_at, int callback_event = EVENT_INTERVAL); void schedule_in(ink_hrtime atimeout_in, int callback_event = EVENT_INTERVAL); void schedule_every(ink_hrtime aperiod, int callback_event = EVENT_INTERVAL); void free();

      EThread *ethread;

      unsigned int in_the_prot_queue:1; unsigned int in_the_priority_queue:1; unsigned int immediate:1; unsigned int globally_allocated:1; unsigned int in_heap:4; int callback_event;

      ink_hrtime timeout_at; ink_hrtime period;

      void *cookie;

      Event(); Event *init(Continuation * c, ink_hrtime atimeout_at = 0, ink_hrtime aperiod = 0); private: void *operator new(size_t size); Event(const Event &); Event & operator =(const Event &);

      public: LINK(Event, link); };

    关于Event结构,有如下几点需要注意:

    • 状态机只能在那个call-back线程中,发起调度,并且需要拿到continuation的锁。
    • 撤销机制与Action类似,也需要在call-back状态机拿到锁的情况下做。
    • 状态机中,Event事件的代码是需要全局统一的
  • VC

    VConnection是ATS核心、插件都常用的一种面向stream的数据抽象结构。主要可以理解为一个数据读写管道,在某些场景下,有点类似 FD的效果。VConnection继承自continuation,也是会call-back到处理机处理的。这个基类是封装上层通信管道的基础。

    VConnection提供关键的几个接口:

    • do_io_read
    • do_io_write
    • do_io_close
    • do_io_shutdown
    • reenable 用来通知另一端可以实施下一步动作
    • set_continuation

      class VConnection:public Continuation { public:

      virtual ~ VConnection();

      virtual VIO *do_io_read(Continuation *c = NULL, int64_t nbytes = INT64_MAX, MIOBuffer *buf = 0) = 0; virtual VIO *do_io_write(Continuation *c = NULL, int64_t nbytes = INT64_MAX, IOBufferReader *buf = 0, bool owner = false) = 0; virtual void do_io_close(int lerrno = -1) = 0; virtual void do_io_shutdown(ShutdownHowTo_t howto) = 0;

      VConnection(ProxyMutex *aMutex); virtual void set_continuation(VIO *vio, Continuation *cont); virtual void reenable(VIO *vi

  评论这张
 
阅读(198)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017