热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

parentproxy源码学习

基于ATS7.0.0代码研究(与ATS6.1.1相差不大)UML图:notes:1.ParentRecord与pRecord:ParentRe

基于ATS7.0.0代码研究(与ATS6.1.1相差不大)

UML图:






notes:

1. ParentRecord 与 pRecord : ParentRecord 对应一条parent.config 记录, pRecord 对应一个回源IP或域名, 即 parent 或 secondary_parent 都可以配置多个下一跳的IP或域名,ParentRecord 中包含主(备)parent(secondary_parent)两个 pRecord 数组, 此时是 2:1 对应, 由于ParentRecord 里面包含多个 pRecord, 此时为 n:1 对应。

2. ParentRecord 与 ParentConfigParams :ParentConfigParams 通过 ParentTable 指针保存着所有的 parent.config 信息, 即 n:1 对应。

3. ParentRecord 与 ParentResult : 每个请求 request 都有一个ParentResult 对应着一个 ParentRecord 此时是 1:1 对应, 但是多个请求 req 的 ParentResult 可能共用一个ParentRecord 内存, 此时是 n:1 对应。


父代理的相关类介绍:

ParentSelectionStrategy 类, 基础工厂类

 虚函数成员方法:

  virtualvoid selectParent(const ParentSelectionPolicy *policy, bool firstCall,ParentResult *result, RequestData *rdata) = 0;

  virtual void markParentDown(constParentSelectionPolicy *policy, ParentResult *result) = 0;

  virtualuint32_t numParents(ParentResult *result) cOnst= 0;

  virtual voidmarkParentUp(ParentResult *result) = 0;

 

ParentConsistentHash 类, 内容哈希模块

  相关类介绍

 ATSConsistentHash 类: (一致性内容哈希 和 其哈希配置存储)

      将name域名结点node通过weight和自增变量值,计算出很多个离散的hash值出来,并存储到map中;

      name(域名)查找时,先计算其哈希值,再通过map的lower_bound 函数找出对应的node结点。

 

  成员变量:

 ATSHash64Sip24 hash[2];  //哈希算法的指定,对应 parent 和 secondary_parent

 ATSConsistentHash *chash[2]; 

//配置内容哈希值存储指针,对应 parent 和 secondary_parent, 对象实例化在ParentConsistentHash::ParentConsistentHash() 中

 

  pRecord*parents[2];  

//存储ParentRecord 的 parents 和 secondary_parents 指针, 值赋值可参考ParentConsistentHash::ParentConsistentHash()

 

  boolfoundParents[2][MAX_PARENTS];  //此值暂时未使用

  boolignore_query; //请求URL哈希时是否忽略URL的参数部分, 值赋值可参考ParentConsistentHash::ParentConsistentHash()

 

  staticconst int PRIMARY = 0;  //常变量

  staticconst int SECOnDARY= 1;  //常变量

 

  内容HASH分为PRIMARY(主) 和 SECONDARY(备) 两种选择

 

  成员方法:

  uint64_tgetPathHash(HttpRequestData *hrdata, ATSHash64 *h);  //通过请求 hrdata 获取次请求域名对应的哈希值

  voidselectParent(const ParentSelectionPolicy *policy, bool firstCall, ParentResult*result, RequestData *rdata); 

//用请求rdata 通过哈希的方式在 parents[2] 查找出合适的父IP(或域名)

 

  voidmarkParentDown(const ParentSelectionPolicy *policy, ParentResult *result);

//通过policy 和 result 中的信息,

         //来更新result 对应 ParentRecord 的parents 和 secondary_parents 中父IP(或域名)的不可用状态

 

  uint32_tnumParents(ParentResult *result) const;

//返回正在查询的parents[PRIMARY/SECONDARY] 在 parent.config 中配置父代理IP或域名的个数

 

  voidmarkParentUp(ParentResult *result); 

//通过result 中的信息, 来更新 result 对应ParentRecord 的 parents 和 secondary_parents 中父IP(或域名)的可用状态

 

ParentRoundRobin 类, 轮询模块

  成员变量:

  ParentRR_tround_robin_type; 

//枚举变量,对应 parent.config 中的 round_robin 参数,初始化可参考 ParentRecord::Init(), 值有: (具体示意参考parent.config 官方文档)

        //P_NO_ROUND_ROBIN: 即 false, Round robin selection does not occur.

        //P_STRICT_ROUND_ROBIN: 即 strict, Traffic Server machines serve requestsstrictly in turn.

        //P_HASH_ROUND_ROBIN: 即 true, Traffic Server determines the parent based onclient IP address.

        // 上面三个对应ParentRoundRobin

        //P_CONSISTENT_HASH: 即 consistent_hash, consistent hash of the url so thatone parent is chosen for a given url. (对应ParentConsistentHash )

 

  成员方法:

  voidselectParent(const ParentSelectionPolicy *policy, bool firstCall, ParentResult*result, RequestData *rdata);

               //通过请求rdata 在 result->rec->parents 按指定方式查找可用的父代理信息, 并用 result 的其他变量存储和返回

 

  voidmarkParentDown(const ParentSelectionPolicy *policy, ParentResult *result);

//通过policy 和 result 中的信息, 来更新result->rec->parents 中父IP(或域名)的不可用状态

 

  uint32_tnumParents(ParentResult *result) const; //返回 result->rec->parents 在parent.config 中配置父代理IP或域名的个数

  voidmarkParentUp(ParentResult *result);  //更新result->rec->parents 中父IP(或域名)的可用状态

 

ParentConsistentHash ParentRoundRobin 都继承于ParentSelectionStrategy,使用的是工厂方法设计模式。

 

ATSConsistentHashNode 结构体, 结点,就是个struct

    boolavailable;  //是否可用

    char*name;  //域名指针

 

pRecord 结构体,  继承于ATSConsistentHashNode ,主要是对ATSConsistentHashNode 其他属性的扩展

                存储 parent.config 中的parent 或 secondary_parent 的配置项

    成员变量配置属性:

    charhostname[MAXDNAME + 1];  //域名,可以是IP

    intport;  //端口值

    time_tfailedAt; //Mark the parent as down, 是原子操作

    intfailCount; //失败次数, 是原子操作

    int32_tupAt;  //此值未使用

    const char*scheme; //A request URL protocol: http or https.

    int idx; //表示parent 或 secondary_parent 的父代理的坐标索引

    floatweight;  //表示parent 或 secondary_parent 的多个父代理的权重值,只用于 consistent_hash, 默认值为 1.0

 

ParentRecord 类,一个对象对应一行 parent.config 配置

parent.config 的参数具体含义请参考官方文档

  成员变量:

  pRecord*parents;  //数组指针,用于存 parent.config 的 parent 配置项

  pRecord*secondary_parents;  //数组指针,用于存 parent.config 的 secondary_parent 配置项,只针对 consistent_hash 生效

  intnum_parents;   //与parents 对应, 保存 parent.config 的parent 配置父代理的总数

  int num_secondary_parents;//与 secondary_parents 对应, 保存parent.config 的 secondary_parent 配置父代理的总数

 

  const char*scheme;  //A request URL protocol: httpor https. 用于存 parent.config 的scheme 配置项

  boolignore_query;  //请求URL哈希时是否忽略URL的参数部分,只针对 consistent_hash 生效, 用于存 parent.config 的qstring 配置项

  volatileuint32_t rr_next; //强制轮询计数器, 只用于 ParentRoundRobin 的P_STRICT_ROUND_ROBIN 场景

  boolgo_direct; 

//对应parent.config 的 go_direct 参数,默认值为 true, parent_is_proxy 为 cache servers 时才会生效

         //true, 请求不走父直接回源站(PARENT_DIRECT), requests bypass parent hierarchiesand go directly to the origin server.

         //false, 请求走父, requests do not bypass parent hierarchies.

 

  boolparent_is_proxy;  //对应parent.config 的 parent_is_proxy 参数,默认值为 true

                         //true 表示此行配置的是cache servers

                         //false 表示此行配置的是origin servers ,此时的 go_direct 值是被忽略无效的

 ParentSelectionStrategy *selection_strategy;  //策略选择,在 ParentConsistentHash 和 ParentRoundRobin 两种中选择

 UnavailableServerResponseCodes *unavailable_server_retry_responses;

//对应parent.config 的 unavailable_server_retry_responses 参数,

                  //表示返回的状态码是否为不可用, 默认值为503, 配置值statuscode(500

 

  ParentRetry_tparent_retry;  //枚举类型,对应 parent.config 的 parent_retry 参数

                              //PARENT_RETRY_NONE: 初始值

                              //PARENT_RETRY_SIMPLE: 即 simple_retry

                              //PARENT_RETRY_UNAVAILABLE_SERVER: 即unavailable_server_retry

                              //PARENT_RETRY_BOTH: 即 both, 为simple_retry 和 unavailable_server_retry 都选择

  intmax_simple_retries;  //对应parent.config 的 max_simple_retries 参数,默认值为1, 与 parent_retry 一起使用

  intmax_unavailable_server_retries; 

//对应parent.config 的 max_unavailable_server_retries 参数,默认值为1, 与 parent_retry 一起使用

 

  成员方法:

 config_parse_error Init(matcher_line *line_info); //解析一行parent.config 配置

  boolDefaultInit(char *val);  //parent.config 默认配置的解析,ParentConfigParams 初始化时被 createDefaultParent() 调用

                                //默认值配置records.config, [default_var] proxy.config.http.parent_proxies

 

  voidUpdateMatch(ParentResult *result, RequestData *rdata); 

//根据result->line_number 和请求 rdata 来更新查找的ParentRecord 配置

 

  voidPrint();  //打印ParentRecord 的配置信息, 主要打印 hostname, port, go_direct,parent_is_proxy 参数

 

  boolbypass_ok() const;  //返回go_direct 的值

  const char*ProcessParents(char *val, bool isPrimary); //解析parent.config 中的 parent 和 secondary_parent 参数,

                                                        //并将值保存到 parents 和 secondary_parents 中

 

ParentResult 类,存储 ParentRecord 对象, 和一些其他的相关参数, 一个请求对应一个ParentResult

                ParentResult 与 ParentRecord 是多对一的关系

  成员变量:

 ParentResultType result;  //枚举变量,表示请求查找父代理的类型,值为:

                            // PARENT_UNDEFINED: 未指定父代理,初始化值

                            // PARENT_DIRECT : 直接回源

                            // PARENT_SPECIFIED: 指定了父代理包括api设置父代理

                            // PARENT_AGENT : 此值暂时未使用

                            // PARENT_FAIL : 指定父代理失败

  const char*hostname;  //匹配配置中的主机名

  int port;  //匹配配置中的端口

  boolretry;  //是否进行重试

 

  //private:

  intline_number;  //rec 配置在parent.config 中对应的行号

  ParentRecord*rec;  //parent.config 中的一项配置

  uint32_tlast_parent;  //最后一个父配置项

  uint32_tstart_parent;  //第一个父配置项,只在 ParentRoundRobin::selectParent() 中使用了

  boolwrap_around;  //没有实际意义

  // state forconsistent hash.

  intlast_lookup;  //表示查找的是PRIMARY 还是 SECONDARY, 只针对consistent hash 生效

  ATSConsistentHashIterchashIter[2];

//map的迭代器,定义为:typedef std::map::iteratorATSConsistentHashIter;

          //ATSConsistentHash 中 lookup_by_hashval 和lookup 查找 ATSConsistentHashNode 时的迭代器,不传此值也没问题

 

  成员方法:

  void reset();  //此ParentResult 对象初始化

  boolis_api_result() const;  //判断是否调用了api设置父代理

  bool is_some()const;  //判断rec 是否为空, 并进行了特需校验

  boolparent_is_proxy() const;  //先判断is_api_result(), 并返回是否为父代理

  unsignedretry_type() const;  //先判断is_api_result(), 并返回 parent_retry 值

  unsignedmax_retries(ParentRetry_t method) const; //先判断 is_api_result(), 并通过method 值返回最大重试次数

  boolresponse_is_retryable(HTTPStatus response_code) const;  //通过retry_type() 和 状态码 判断源站是否可用

  boolbypass_ok() const;  //先判断is_api_result(), 再返回 go_direct 的值

 

typedef ControlMatcher P_table;  //使用模板加载配置,配置模板可以参考 congestion 代码解析

 

ParentConfigParams 类,继承于ConfigInfo, 用于配置管理,其对象的使用和删除是通过计数器来控制的

  成员变量:

  P_table*parent_table;       

//保存parent.config 中的配置项,父配置文件 parent.config 指定参数为proxy.config.http.parent_proxy.file

  ParentRecord*DefaultParent;  //父的默认配置,可以通过 [default_var] proxy.config.http.parent_proxies 进行指定

                                //若default_var 参数未指定, 则无默认的父配置, 线上情况一般没有指定

 ParentSelectionPolicy policy; //是对records.config 中父配置的存储

                                //ParentRetryTime: [retry_var] proxy.config.http.parent_proxy.retry_time ,

                                //ParentEnable:[enable_var]proxy.config.http.parent_proxy_routing_enable ,

                               //FailThreshold: [threshold_var]proxy.config.http.parent_proxy.fail_threshold

 

  成员方法:

  boolapiParentExists(HttpRequestData *rdata); 

//判断此请求是否通过rdata->api_info (如: TSHttpTxnParentProxySet) 设置了父代理信息

 

  voidfindParent(HttpRequestData *rdata, ParentResult *result); 

//通过请求信息rdata 在 parent_table 中查找对应的父配置信息,

                 //调用 selectParent() 时firstCall 为 true 即第一次查找, 主策略中查找,并返回 result

 

  voidnextParent(HttpRequestData *rdata, ParentResult *result); 

//通过请求信息rdata 在对应的 result->rec 即ParentRecord 中选择备用父策略

                 //不需要通过 rdata 在 parent_table 中重新查找ParentRecord ,直接使用 result->rec

                 //调用 selectParent() 时firstCall 为 false 即第二次查找, 备用策略中查找,并返回 result

 

  boolparentExists(HttpRequestData *rdata);  //通过请求rdata 调用 findParent() 查找是否有可用的父策略

  voidselectParent(bool firstCall, ParentResult *result, RequestData *rdata);

//根据result 中 ParentRecord 配置信息调用selection_strategy->selectParent 去选择对应的父策略

                 //其实是对 ParentRecord 中的selection_strategy->selectParent 做了一次封装

 

  voidmarkParentDown(ParentResult *result); 

//根据result 中 ParentRecord 配置信息调用selection_strategy->markParentDown 去标记指定父配置不可用

                 //其实是对 ParentRecord 中的selection_strategy->markParentDown 做了一次封装

 

  uint32_tnumParents(ParentResult *result); 

//根据result 中 ParentRecord 配置信息调用selection_strategy->numParents 返回可用父配置数

                 //其实是对ParentRecord 中的 selection_strategy->numParents 做了一次封装

 

  voidmarkParentUp(ParentResult *result); 

//根据result 中 ParentRecord 配置信息调用selection_strategy->markParentUp 去标记指定父配置可用

                 //其实是对 ParentRecord 中的selection_strategy->markParentUp 做了一次封装

 

ParentConfig 类, 配置的读取类,包括热加载和配置内存管理和释放

  成员变量:

  static intm_id; //用于在 configProcessor 中查找ParentConfigParams 对象配置的标识

 

  成员方法:

  static voidstartup();   //配置读取入口,热加载的回调函数注册, 调用 reconfigure() 读取parent.config 配置

  static voidreconfigure();  //加载parent.config 的配置项,并用 ParentConfigParams *params 对象保存配置

                              //params 指向的内存使用配置处理器 configProcessor 保存并管理

  static voidprint();   //打印所有的父配置项,即 ParentConfigParams 对象里面的内容

  static voidset_parent_table(P_table *pTable, ParentRecord *rec, int num_elements);  //只有声明没有实现也没有使用。

                                                //测试了struct下面声明一个函数,没有实现且没有使用,gcc编译器是允许的。

 

  staticParentConfigParams *acquire(); //通过 m_id 在 configProcessor 中获取ParentConfigParams 对象配置

  staticvoid release(ParentConfigParams *strategy); //通过计数器释放 ParentConfigParams 对象内存

 

SocksServerConfig 类: socks代理,与 ParentConfig 类相似,配置存储都是用的ParentConfigParams 类,主要是用于网络层的 SocksProxy 代理模块。读取的配置文件为 socks.config, 参数指定[records.config]:proxy.config.socks.socks_config_file

 

配置读取和更新:

1. void ParentConfig::startup();  //parent.config 读取入口, 在 main() 函数中调用, 注册records.config 参数热加载的回调函数

   parent.config 的热加载可以参考 ConfigUpdateHandler 类, 具体如何热加载的待研究

2. void ParentConfig::reconfigure(); //配置读取

    P_table*pTable = new P_table(file_var, modulePrefix, &http_dest_tags);  //parent.config 配置的读取

    params =new ParentConfigParams(pTable); //默认配置的加载

3. ControlMatcher::ControlMatcher(const char *file_var, const char *name, constmatcher_tags *tags, int flags_in);

4. int ControlMatcher::BuildTable();

5. int ControlMatcher::BuildTableFromString(char *str);

6. config_parse_error HostMatcher::NewEntry(matcher_line *line_info);

7. config_parse_error ParentRecord::Init(matcher_line*line_info);

 

父代理处理流程:

1. find_server_and_update_current_info 函数先通过HTTP请求用ParentConfigParams::findParent 找出对应的 parent 配置,用 result 返回赋给 s->parent_result

2. 重试时查找父配置用ParentConfigParams::nextParent, 用 result 返回赋给s->parent_result

3. 标记此父配置不可用ParentConfigParams::markParentDown 在HttpTransact::handle_response_from_parent 和HttpTransact::PPDNSLookup 调用

4. 标记此父配置可用ParentConfigParams::markParentUp 在HttpTransact::handle_response_from_parent 调用

5. ATS查询和修改父配置对外的接口类为 ParentConfigParams, 所有的父配置状态信息修改和重新选择父配置都是在 s->parent_result 中操作





推荐阅读
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文详细介绍了在ASP.NET中获取插入记录的ID的几种方法,包括使用SCOPE_IDENTITY()和IDENT_CURRENT()函数,以及通过ExecuteReader方法执行SQL语句获取ID的步骤。同时,还提供了使用这些方法的示例代码和注意事项。对于需要获取表中最后一个插入操作所产生的ID或马上使用刚插入的新记录ID的开发者来说,本文提供了一些有用的技巧和建议。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • 本文介绍了在Linux下安装和配置Kafka的方法,包括安装JDK、下载和解压Kafka、配置Kafka的参数,以及配置Kafka的日志目录、服务器IP和日志存放路径等。同时还提供了单机配置部署的方法和zookeeper地址和端口的配置。通过实操成功的案例,帮助读者快速完成Kafka的安装和配置。 ... [详细]
  • Oracle seg,V$TEMPSEG_USAGE与Oracle排序的关系及使用方法
    本文介绍了Oracle seg,V$TEMPSEG_USAGE与Oracle排序之间的关系,V$TEMPSEG_USAGE是V_$SORT_USAGE的同义词,通过查询dba_objects和dba_synonyms视图可以了解到它们的详细信息。同时,还探讨了V$TEMPSEG_USAGE的使用方法。 ... [详细]
  • 本文讨论了在openwrt-17.01版本中,mt7628设备上初始化启动时eth0的mac地址总是随机生成的问题。每次随机生成的eth0的mac地址都会写到/sys/class/net/eth0/address目录下,而openwrt-17.01原版的SDK会根据随机生成的eth0的mac地址再生成eth0.1、eth0.2等,生成后的mac地址会保存在/etc/config/network下。 ... [详细]
  • 预备知识可参考我整理的博客Windows编程之线程:https:www.cnblogs.comZhuSenlinp16662075.htmlWindows编程之线程同步:https ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
author-avatar
小p揪脸包918
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有