基于ATS7.0.0代码研究(与ATS6.1.1相差不大)
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< statuscode <600), 可以配多个值
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
//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
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
4. int ControlMatcher
5. int ControlMatcher
6. config_parse_error HostMatcher
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 中操作