简介
对于一个大型网站来说需要流量控制的服务包括:RCP服务,Cache服务,数据库DAO服务,消息服务
对于该要求有两个基本概念:资源和策略,资源会被多个调用方请求,我们需要为不同的调用方制定不同的调用策略,以保证核心业务的稳定性。
限制方式:既可以限制别人调用我们的频率,也可以做到自己主动减少调用别人的次数。
实现如上功能的基本模型包括:
一次请求的上下文模型:Context
public class Context {
/**上下文的创建者*/
@Setter @Getter
private Object creator;
/**上下文的名字*/
@Setter @Getter
private String name;
/**入口节点*/
@Setter @Getter
private DefaultNode entranceNode;
/**限流的入口*/
@Getter @Setter
private Entry curEntry;
/**
* 请求来源的应用名
*/
@Setter @Getter
private String origin = "";
/**
* 请求的客户端IP
*/
@Setter @Getter
private String entryIp = "";
}
每个请求资源的节点模型:Node
具有统计职能以及分簇节点
public interface Node {
/******************** state ***********************/
long totalRequest();
long blockedRequest();
double passQps();
double blockedQps();
double totalQps();
double passReqQps();
double exceptionQps();
int avgRt();
int curThreadNum();
int currentUseTokens();
long tokenTimeRange();
/********************* * action **********************/
void increaseBlockedRequest();
void increasePassedRequest();
void increaseExceptionRequest();
void addPassRequest();
int rt(int rt);
void increaseBlockedQps();
void increassePassedQps();
void increaseThreadNum();
void decreaseThreadNum();
}
public class DefaultNode extends StatisticNode {
/**这条节点的上所有访问后继资源节点*/
private volatile HashSet<Node> childList = new HashSet<Node>();
/**对应的簇节点*/
private ClusterNode clusterNode;
}
监控点
如果一个线程中存在多个通过的监控点,每通过一个监控点,会为其生成一个这里CtEntry实例。由于这些监控点在同一根请求线程中被调用,因此它们共享同一个context,这意味着最后这些CtEntry实例会在context中构成一条调用链。context中的curEntry表示当前在哪一个监控点中(哪一级类或者方法的调用当中),CtEntry实例的parent属性指向的是上一个监控点或者为空(表明当前在EntranceNode),child属性则指向的是下一个监控点。
public abstract class Entry {
private long createTime;
private Node curNode;
private Node originNode;
private Throwable error;
}
public class CtEntry extends Entry{
protected Entry parent = null;
protected Entry child = null;
private Context context;
}