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