欢迎使用普元产品知识库,本知识库包含普元应用开发平台EOSPlatform,流程平台BPS,企业服务总线ESB,微服务平台Microservice,运维管理平台Devops,数据集成平台DI

页面树结构

欢迎使用普元文档库

Skip to end of metadata
Go to start of metadata

ESB_SAM_频度控制_实施中的经验积累
最近又在实施ESB的项目了,有一些小体会,总结一下。
今天主要说说【频度控制】这里。

实施中,客户提出一个问题,访问次数的控制是多server累加还是单server计算?另外如何实时同步设置,通过数据库还是文件?是否需要重启server等。这在之前我没有考虑过,所以我打算先从帮助文档下手,经查询

帮助文档:"针对每个服务配置单位时间访问次数的上限,对访问次数已达到上限之后的服务,在统计时间段内的请求都予以拒绝,直至本统计时间段结束;服务访问频度达到阈值时会进行告警,显示出现服务访问流量异常的服务的基本信息、异常信息等。"


帮助文档不够细致,所以就动手验证一下。变有了下文。
为了验证这个问题,本地搭建了两个server分别在两台虚拟机上。
简单说一下环境,两个server分别是10.0.2.20和10.0.2.15,其中SAM在10.0.2.20上面。拦截器以及数据库策略都已经配置OK,并将server加入到Console中。
配置了频度控制规则,时长10s,访问次数3次。

相同10s内,在20的server上调用第4次结果:

相同10s内在15server上调用第4次结果:

觉得奇怪,20上没问题,15上有问题。随即重启2个server后发现,15上规则生效。
此时可以确定的是,在相同的10秒钟内,每个server可以单独调用3次。不会多server累加。
但是为什么20没问题,15有问题?我只能想到的是,20的server和sam在一起,肯定有关联,并且ip地址可能是127.0.0.1的类似设置。检查_srv下的xml等都无果。然后就跟了一下代码,从FrequencyControlInterceptor拦截器开始断
 

在SAM一次新的设置后,15的配置这里取的还是本次server启动后的数据,而20却是SAM设置后的新数据。
于是继续跟踪代码,原来是从AccessFrequencyControlPolicyData类中的
private Map<String, FrequencyDefinition> map = new HashMap();
获取的访问频度信息。
 

于是,在setFrequencyDefinition这里断。


后发现是原来是每次在设置SAM的频度控制之后都会调用IPolicyDataHandler的notifyPolicyUpdate来通知server进行更新。

关键代码,类DefaultPolicyDataHandler继承自IPolicyDataHandler

public void loadAccessAuthorityControlPolicyData(){
//省略部分代码
Map<String, FrequencyDefinition> map = PolicyManageFactory.getInstance().getAccessFrequencyControlPolicyData().get();
conn = DBConnectionManager.getInstance().getConnetion();
String sql = "select a.operation_code,a.period,a.threshold from sam_frequency_control a ";
stmt = conn.prepareStatement(sql);
rs = stmt.executeQuery();
Map<String, FrequencyDefinition> tmpMap = new HashMap();
while (rs.next()) {
FrequencyDefinition frequencyDefinition = new FrequencyDefinition(rs.getString(1), rs.getLong(2), rs.getLong(3));
tmpMap.put(frequencyDefinition.getOperationCode(), frequencyDefinition);
}
synchronized (map) {
map.clear();
map.putAll(tmpMap);
}
}

然后就去查询是谁调用的notify接口?
通过搜索得知PublishService有去调用,然后发现是读取的jmx-config.properties

在sam中搜索jmx-config.properties,得知sam\apache-tomcat-5.5.20\webapps\sam\config,jmx-config.properties,发现的确有配置如下:

ip=127.0.0.1
port=9876


这里配置的读取方法代码如下,IP地址是以逗号分隔


public List<JMXServer> getJMXServerInstance()
{
String ipaddress = this.properties.getProperty("ip");
String port = this.properties.getProperty("port");
String[] ips = null;
if (ipaddress.indexOf(",") > 0) {
ips = ipaddress.split(",");
} else {
ips = new String[] { ipaddress };
}
List<JMXServer> jmxServers = new ArrayList();
if ((null != ips) && (ips.length > 0)) {
for (String ip : ips)
{
jmxServer = new JMXServer(ip, port);
jmxServers.add(jmxServer);
}
}
return jmxServers;
}


将其修改为

ip=10.0.2.15,10.0.2.20
port=9876

重启server后,这样以后每次对SAM设置频度控制,多server就可以马上同步了。
其他白名单,流量控制从代码上看都是同理。


  • 无标签