7.11. 查询拦截器和守卫

GeoMesa提供了在执行查询之前将自定义逻辑应用于查询的机会。查询拦截器必须通过简单要素类型中的用户数据指定,并且可以在调用之前设置 createSchema ,或通过调用 updateSchema 。要指示查询拦截器,请使用键 geomesa.query.interceptors

sft.getUserData().put("geomesa.query.interceptors", "com.example.MyQueryInterceptor");

该值必须是由实现特征的一个或多个类的名称组成的逗号分隔的字符串 org.locationtech.geomesa.index.planning.QueryInterceptor

/**
  * Provides a hook to modify a query before executing it
  */
trait QueryInterceptor extends Closeable {

  /**
    * Called exactly once after the interceptor is instantiated
    *
    * @param ds data store
    * @param sft simple feature type
    */
  def init(ds: DataStore, sft: SimpleFeatureType): Unit

  /**
    * Modifies the query in place
    *
    * @param query query
    */
  def rewrite(query: Query): Unit

  /**
   * Hook to allow interception of a query after extracting the query values
   *
   * @param strategy query strategy
   * @return an exception if the query should be stopped
   */
  def guard(strategy: QueryStrategy): Option[IllegalArgumentException] = None
}

拦截器必须有一个默认的无参数构造函数。拦截器生命周期包括:

  1. 该实例使用其默认构造函数通过反射进行实例化

  2. 该实例是通过 init 方法,传入包含简单要素类型的数据存储

  3. rewriteguard 为每个查询调用一次(这两个方法必须是线程安全的)

  4. 当释放数据存储区时,实例将通过 close 方法

拦截器将按照它们在用户数据中声明的顺序被调用。要查看有关查询拦截器结果的详细信息,您可以启用 TRACE -类上的级别日志 org.locationtech.geomesa.index.planning.QueryRunner$

7.11.1. 提供的查询保护

GeoMesa提供了一些基本的查询保护,可以阻止过宽的查询(这可能会使系统不堪重负)。有关其他控件,请参见 geomesa.query.timeoutgeomesa.scan.block-full-table 在……里面 运行时配置

7.11.1.1. 全表扫描查询保护

全表扫描查询保护将阻止导致执行全表扫描的查询。将在所有环境中加载查询保护。或者,可以使用 geomesa.scan.block-full-table 系统属性来禁用每个环境的全表扫描(请参见 运行时配置 )。

就像 geomesa.scan.block-full-table 属性时,此警卫会尊重 geomesa.scan.block-full-table.threshold 系统属性。这允许预览查询,这有助于显示系统正在工作。

要启用保护,请添加 org.locationtech.geomesa.index.planning.guard.FullTableScanQueryGuardgeomesa.query.interceptors 如上所述。

sft.getUserData().put("geomesa.query.interceptors",
  "org.locationtech.geomesa.index.planning.guard.FullTableScanQueryGuard");

要针对每个环境禁用保护,请设置系统属性 geomesa.scan.<typeName>.block-full-tablefalse ,在哪里 <typeName> 是要素类型的名称。

7.11.1.2. 时态查询保护

时态查询保护将阻止超过最大时态持续时间的查询。任何试图返回更长时间段的查询都将停止。时态查询保护不会影响对没有时态组件的索引的查询(例如,要素ID和属性查询)。

要启用保护,请添加 org.locationtech.geomesa.index.planning.guard.TemporalQueryGuardgeomesa.query.interceptors ,并使用以下命令设置持续时间 geomesa.guard.temporal.max.duration

sft.getUserData().put("geomesa.query.interceptors",
  "org.locationtech.geomesa.index.planning.guard.TemporalQueryGuard");
sft.getUserData().put("geomesa.guard.temporal.max.duration", "28 days");

要针对每个环境禁用保护,请设置系统属性 geomesa.guard.temporal.<typeName>.disabletrue ,在哪里 <typeName> 是要素类型的名称。

7.11.1.3. 分级查询卫士

分级查询警卫基于查询的空间范围应用不同的持续时间限制。随着查询在空间上变得更大,它可以被限制在越来越短的时间范围内。一系列规则限制了查询的持续时间,查询的大小最多为平方度。此保护也适用于全表扫描保护。

要启用保护,请添加 org.locationtech.geomesa.index.planning.guard.GraduatedQueryGuardgeomesa.query.interceptors 如上所述。配置通过以下方式进行管理 TypeSafe Config 它将查找名为 reference.conf 和/或 application.conf 在类路径上。在Geoserver中使用的文件名 reference.conf 可以添加到 WEB-INF/classes 。配置在密钥下 geomesa.guard.graduated

配置必须满足以下几个条件:

  • 对无界查询必须有限制,

  • 随着大小的增加,持续时间必须减少,

  • 并且给定的大小限制不能重复。

如果未提供大小,则等效于无限大小。持续时间可以以天、小时或分钟为单位。例如:

geomesa {
  guard {
    graduated {
      "sftName" = [
        { size = 1,  duration = "60 days" }
        { size = 10, duration = "3 days"  }
        { duration = "1 day" }
      ]
    }
  }
}

要针对每个环境禁用保护,请设置系统属性 geomesa.guard.graduated.<typeName>.disabletrue ,在哪里 <typeName> 是要素类型的名称。