实战Alibaba Sentinel:深度解析微服务高并发流量治理
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

2.3.2 Entry

在调用链上,一个资源对应一个Entry实例。可以从Context中获取调用链上当前访问到的资源的DefaultNode实例,而DefaultNode实例实际是从Context实例的curEntry字段中获取的。Context实例的curEntry字段引用当前资源的DefaultNode实例,以及资源相对当前调用来源的StatisticNode实例。

Entry抽象类定义了如下字段。

• curNode:当前资源的DefaultNode实例。

• originNode:资源相对当前调用来源的StatisticNode实例。

• resourceWrapper:资源ID。

CtEntry是Entry的直接子类,CtEntry用于维护父子Entry关系,每一次调用SphU类的entry方法都会创建一个CtEntry实例。

CtEntry类中声明的字段信息如下述代码所示。

• parent:当前Entry实例指向的父Entry。

• child:当前Entry实例指向的下一个Entry实例。

• chain:当前资源的ProcessorSlotChain实例,Sentinel会为每个资源创建且仅创建一个ProcessorSlotChain实例。

• context:调用链上的Context实例。

如果调用链上多次调用SphU类的entry方法(调用链上有多个资源),那么调用链上这些资源的CtEntry实例会构成一个双向链表。每次创建CtEntry实例都会将Context实例的curEntry字段设置为这个新的CtEntry实例。双向链表的作用就是在调用CtEntry类的exit方法时,能够将Context实例的curEntry字段还原为引用调用链上前一个CtEntry实例。

类似于Java虚拟机上栈桢的入栈和出栈。

以2.3.1节的天气预报例子进行说明,在服务B收到服务A的请求时,Sentinel在拦截器中会调用SphU类的entry方法创建一个CtEntry实例,取名为ctEntry1,此时的ctEntry1的父节点为空。当服务B向服务C发起调用时,Sentinel会拦截请求的发起,调用SphU类的entry方法创建一个CtEntry实例,取名为ctEntry2,此时ctEntry2的父节点指向ctEntry1,ctEntry1的子节点指向ctEntry2,如图2.7所示。

图2.7 CtEntry双向链表