3.3. 监听器和通知
Data Grid 提供了一个监听器 API,客户端可以在事件发生时注册并获得通知。此注解驱动的 API 适用于 2 个不同的级别:缓存级别的事件和缓存管理器级别事件。
事件会触发分配给监听程序的通知。侦听器是简单的 POJO使用 @Listener 注解,并使用 Listenable 接口中定义的方法注册。
Cache 和 CacheManager 都实现了 Listenable,这意味着您可以将监听程序附加到缓存或缓存管理器,以接收缓存级别或缓存管理器级通知。
例如,以下类定义了一个监听程序,以非阻塞的方式每次添加新条目时打印一些信息:
有关更全面的示例,请参阅 @Listener 的 Java 文档。
3.3.1. 缓存级别通知 复制链接链接已复制到粘贴板!
缓存级别的事件以每个缓存为基础发生,默认情况下仅在发生事件的节点上引发。请注意,在分布式缓存中,这些事件只会在受影响的数据所有者上引发。正在添加、删除、修改等条目示例。这些事件会触发通知,以监听程序注册到特定缓存中。
有关所有缓存级别通知的完整列表 ,请参阅 org.infinispan.notifications.cachelistener.annotation 软件包中的 Javadocs,以及它们相应的方法级注解。
有关 Data Grid 中可用的缓存级别通知列表,请参阅 org.infinispan.notifications.cachelistener.annotation 软件包中的 Javadocs。
3.3.1.1. Cluster Listeners 复制链接链接已复制到粘贴板!
当需要侦听单个节点上的缓存事件时,应使用集群监听程序。
为此,需要把监听程序设置为将监听程序标注为集群。
@Listener (clustered = true)
public class MyClusterListener { .... }
@Listener (clustered = true)
public class MyClusterListener { .... }
在非集群的监听器中,集群监听程序有一些限制。
-
集群侦听器只能侦听
@CacheEntryModified、@CacheEntryCreated、@CacheEntryRemoved和@CacheEntryExpired事件。请注意,这意味着,对于这个监听器,任何其他类型的事件都不会侦听。 - 只有 post 事件发送到集群监听程序,才会忽略 pre 事件。
3.3.1.2. 事件过滤和转换 复制链接链接已复制到粘贴板!
安装监听器的节点上所有适用的事件都会被提高到监听器。可以使用 KeyFilter (仅允许对键进行过滤)或 CacheEventFilter (用于过滤键、旧值、旧值、新值、新值、新元数据、是否重试、事件在事件之前)以及命令类型之前,可以动态过滤哪些事件。
此处的示例显示了一个简单的 KeyFilter,它只允许仅在事件修改只为 Me 键的条目时引发事件。
当您想以更有效的方式限制收到的事件时,这非常有用。
另外,还提供了一个 CacheEventConverter,允许在发生事件前将值转换为另一个值。这可以提供模块化化值转换的任何代码。
在与 Cluster Listener 一起使用时,上述过滤器和转换器特别有用。这是因为在事件源自的节点上进行过滤和转换,而不是侦听事件的节点。这可提供不需要在集群中复制事件的好处(过滤),甚至会减少有效负载(转换器)。
3.3.1.3. 初始状态事件 复制链接链接已复制到粘贴板!
安装监听程序时,它仅在完全安装后收到事件的通知。
可能需要在第一次注册监听器时获取缓存内容的当前状态,方法是为缓存中的每个元素生成类型为 @CacheEntryCreated 的事件。在此初始阶段的任何额外生成的事件都将排队,直到引发适当的事件。
这目前仅适用于集群的监听程序。ISPN-4608 涵盖为非集群的监听程序添加此功能。
3.3.1.4. 重复事件 复制链接链接已复制到粘贴板!
在非事务缓存中可能会接收重复的事件。当试图执行写入操作(如 put )时,密钥的主所有者可能会停机。
数据中心内部将重新处理放置操作,方法是自动将其发送到给定密钥的新主所有者,但没有保证如果写入首次复制到备份,则无法保证。因此,以下写入事件(CacheEntryCreatedEvent、CacheEntryModifiedEvent 和 CacheEntryRemovedEvent)可以在单个操作上发送超过 1 个。
如果生成了多个事件,那么将标记重试命令生成的事件,以帮助用户知道何时发生此事件而无需注意查看更改。
另外,在使用 CacheEventFilter 或 CacheEventConverter 时,EventType 包含 isRetry 来指示事件因为重试而生成。https://access.redhat.com/webassets/avalon/d/red-hat-data-grid/8.3/api/org/infinispan/notifications/cachelistener/filter/EventType.html
3.3.2. 缓存管理器级通知 复制链接链接已复制到粘贴板!
缓存管理器级事件发生在缓存管理器上。这些也是全局和集群范围的,但涉及影响单个缓存管理器创建的所有缓存的事件。缓存管理器级别的事件示例是加入或离开集群,或缓存启动或停止。
如需了解所有缓存管理器级 通知及其相应的方法级别注解的完整列表,请参阅 org.infinispan.notifications.cachemanagerlistener.annotation 软件包。
3.3.3. 事件同步 复制链接链接已复制到粘贴板!
默认情况下,所有 async 通知都在通知线程池中分配。同步通知将延迟操作继续,直到监听程序方法完成或完成完成(以前导致线程被阻塞)。或者,您可以将监听程序标注为 异步,在这种情况下,操作会立即继续,而通知会在通知线程池上异步完成。要做到这一点,只需注解您的监听程序:
异步 Listener
@Listener (sync = false)
public class MyAsyncListener {
@CacheEntryCreated
void listen(CacheEntryCreatedEvent event) { }
}
@Listener (sync = false)
public class MyAsyncListener {
@CacheEntryCreated
void listen(CacheEntryCreatedEvent event) { }
}
阻塞同步 Listener
@Listener
public class MySyncListener {
@CacheEntryCreated
void listen(CacheEntryCreatedEvent event) { }
}
@Listener
public class MySyncListener {
@CacheEntryCreated
void listen(CacheEntryCreatedEvent event) { }
}
非阻塞 Listener
@Listener
public class MyNonBlockingListener {
@CacheEntryCreated
CompletionStage<Void> listen(CacheEntryCreatedEvent event) { }
}
@Listener
public class MyNonBlockingListener {
@CacheEntryCreated
CompletionStage<Void> listen(CacheEntryCreatedEvent event) { }
}
3.3.3.1. 异步线程池 复制链接链接已复制到粘贴板!
要调整用于分配此类异步通知的线程池,请在配置文件中使用 & lt;listener-executor /> XML 元素。