扩展集群过滤器

发送反馈


利用 SuperMap iServer 提供的集群机制,不仅可以搭建普通的领域空间服务(DSS)集群,还可以搭建分布式 DSS 集群。分布式 DSS 集群,是指将提供不同服务能力的同类 DSS 进行集群,如在天气查询 DSS 里,不同的天气查询 DSS 可以提供不同城市的天气预报,可以对它们进行集群,共同提供所有城市的天气预报。

过滤器简介

为实现分布式 DSS 集群,SuperMap iServer 提供了过滤器机制,在集群服务器上,负载均衡前,先对 DSS 节点(包含集群服务器本身提供的 DSS)使用过滤器依次进行过滤,只保留能提供正确 DSS 的节点。

SuperMap iServer 提供了 com.supermap.services.cluster.client.spi.ClusterServiceFilter 接口,用户需要实现该接口对 DSS 节点进行过滤,ClusterServiceFilter 的主要方法如下:

boolean filter(ServiceInfo serviceInfo, HttpServletRequest request);

该方法用于根据客户端请求和 DSS 节点的信息对 DSS 节点进行过滤,其中,ServiceInfo.additions 属性为一个 String 数组,对应 DSS 的服务能力信息(由 NameMapping 提取),返回值为 true 表示过滤掉该 DSS 节点(不使用该节点),false 表示可以使用该节点提供的 DSS 服务(所有通过的节点,会在负载均衡后由其中一个提供服务)。

此外,实现 ClusterServiceFilter 时,需要添加@ClusterServiceFilterType 注记,@ClusterServiceFilterType 有两个必选元素:componentType 和 interfaceType,它们限定了过滤器可过滤的服务组件的类型和服务接口类型,即过滤器只对该种类型组合的服务实例起作用。

componentType 取值为:服务组件实现类的类名;

interfaceType 取值为:服务接口实现类的@protocol 注记的 name 字段值。

示例如下:

@ClusterServiceFilterType(componentType = "Temperature", interfaceType = "Jaxrs")
public class CityNameFilter implements ClusterServiceFilter{
        public boolean filter(ServiceInfo serviceInfo, HttpServletRequest request) {
                ...
        }
}

 

过滤器的配置

过滤器需要配置到集群服务器上,在系统配置文件 iserver-system.xml(位于%SuperMap iServer_HOME%/webapps/iserver/WEB-INF)中,<clusterService/>的<clusterServiceFilters/>子节点配置,向<clusterServiceFilters/>添加子节点如下:

<clustering>
        ...
        <clusterService>
                ...
                <clusterServiceFilters>
                        <ClusterServiceFilter name="cityNameFilter" class="com.supermap.sample.cluster.CityNameFilter">
                        </ClusterServiceFilter>
                </clusterServiceFilters>
        </clusterService>
</clustering>

注意:可以实现多个过滤器,同时配置在<clusterServiceFilters/>节点中,过滤器会按照 name 节点的值进行排序,然后依次执行。

<ClusterServiceFilter/>还可以有 componentName 和 interfaceName 两个可选属性,可以进一步指定过滤器起作用的范围。

 

构建分布式天气预报 DSS 集群

在天气查询 DSS 集群的示例中,com.supermap.sample.cluster.CityNameFilter 实现了 ClusterServiceFilter 接口,可以对提供天气预报 DSS 的节点进行过滤,代码如下:

package com.supermap.sample.cluster;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import javax.servlet.http.HttpServletRequest;
import com.supermap.services.cluster.ServiceInfo;
import com.supermap.services.cluster.client.spi.*;
import com.supermap.services.components.spi.ClusterServiceFilterType;
@ClusterServiceFilterType(componentType = "Temperature", interfaceType = "Jaxrs")
public class CityNameFilter implements ClusterServiceFilter{
        @Override
        public boolean filter(ServiceInfo serviceInfo, HttpServletRequest request) {
                boolean returnvalue=true;
                //子节点附加信息中标识的可提供天气预报的城市名称
                String[] cityNames=serviceInfo.additions;
                
                if(cityNames==null){
                        return true;
                }
                //请求信息中的城市名。
                String requestCityName;
                String requestURI=request.getRequestURI();
                int left=requestURI.lastIndexOf("/")+1;
                if(left>0&&requestURI.lastIndexOf(".")&gt;left){
                        int right=requestURI.lastIndexOf(".");
                        requestCityName=requestURI.substring(left, right);
                }else{
                        requestCityName=requestURI.substring(left);
                }
                try {
                        requestCityName = URLDecoder.decode(requestCityName, "utf-8");
                } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                }
                for(int i=0;i<cityNames.length;i++){
                        if(requestCityName.equalsIgnoreCase(cityNames[i])){
                                returnvalue=false;
                        }
                }
                return returnvalue;
        }
}

将天气查询 DSS 集群示例编译后的 jar 包部署到三个 SuperMap iServer 服务器——C1、S1、S2的%SuperMap iServer_HOME%/webapps/iserver/WEB-INF/lib 目录下,C1只提供“杭州”的天气预报,S1只提供“成都”的天气预报,S2只提供“北京”的天气预报。

在服务配置文件 iserver-services.xml(位于%SuperMap iServer_HOME%/webapps/iserver/WEB-INF)中的<providers/>节点中添加温度服务提供者的配置,即:

<providers>
<provider class="com.supermap.sample.temperature.TemperatureProvider" 
 name="tempratureProvider">
<config class="com.supermap.sample.temperature.FileSetting">
<filePath>F:\C1.txt</filePath>
</config>
</provider>
</providers>

注意:C1.txt 为 C1服务器使用的数据,需要手工 Copy 到对应目录。配置 S1、S2服务器的温度服务提供者同上,分别使用 S1.txt、S2.txt 即可。

配置 C1、S1、S2服务器的温度服务提供者,在服务配置文件 iserver-services.xml 中的<components/>节点中添加温度组件的配置如下,其中,温度组件使用到了 ugcMapProvider-China400和 tempratureProvider:

<components>
<component class="com.supermap.sample.temperature.Temperature" 
 interfaceNames="restjsr" name="temperature-China" 
 providers="ugcMapProvider-China400,tempratureProvider">
<config class="com.supermap.sample.temperature.TemperatureParam">
<mapName>China</mapName>
</config>
</component>
</components>

C1作为集群服务器,构建集群(参见搭建领域空间服务集群),需要在 C1上配置过滤器,即 com.supermap.sample.cluster.CityNameFilter。打开 C1的系统配置文件 iserver-system.xml(位于%SuperMap iServer_HOME%/webapps/iserver/WEB-INF),在<clusterServiceFilters/>节点中添加子节点如下:

<clustering>
        ...
        <clusterService>
                ...
                <clusterServiceFilters>
                        <ClusterServiceFilter name="cityNameFilter" class="com.supermap.sample.cluster.CityNameFilter">
                        </ClusterServiceFilter>
                </clusterServiceFilters>
        </clusterService>
</clustering>

S1、S2作为子节点,需要向 C1集群服务器报告,在 S1、S2的系统配置文件 iserver-system.xml 配置集群报告器如下:

<clustering>
<reporters>
<reporter>
  <enabled>true</enabled>
  <address>http://C1:8090/iserver/services/cluster</address>
</reporter>
</reporters>
</clustering>

搭建的集群结构如下:

访问 C1获取“北京”的天气预报,即访问“http://C1:8090/iserver/services/Temperature/restjsr/北京”,C1会对集群中所有 DSS 节点进行过滤,获取能提供“北京”天气预报服务的 DSS 节点,这里是 S2,由 S2响应客户端请求(获取“北京”天气预报的请求),结果如下:

由于进行了过滤,DSS 集群在响应获取“北京”天气预报的请求时,不会使用到 C1、S1的天气预报服务,从而保证了结果的正确性。