1. Topic Based Messaging(基于主题的消息)
在集群间的节点之间交换自定义消息
1.1 概述
ignite分布式消息允许基于主题的集群范围内的所有节点间的通信.具有指定消息主题的消息可以分发给已订阅该主题的所有组或者是子组。
ignite消息传递是基于发布-订阅形式的,发布者和订阅者通过一个共同的主题连接在一起。当其中一个节点向主题T发送消息a时,它将在所有已订阅T的节点上发布。
PS:任何加入集群的新节点都会自动订阅集群中的其他节点(或集群组)所订阅的所有主题。
1.2 IgniteMessaging
通过IgniteMessaging接口提供了分布式消息传递功能。你可以得到一个IgniteMessaging的实例,就像这样:
Ignite ignite = Ignition.ignite();
IgniteMessaging msg = ignite.message();
IgniteMessaging rmtMsg = ignite.message(ignite.cluster().forRemotes());
1.3 Publish Messages(发布消息)
Send方法帮助将指定的消息主题发送/发布消息到所有节点。消息可以以有序或无序的方式发送。
1.3.1 Ordered Messages
如果您希望按照发送的顺序接收消息,则可以使用sendorder(…)方法。传递一个超时参数来指定消息将在队列中停留多长时间,等待在此消息之前发送的消息。如果超时过期,则所有尚未到达该节点的给定主题的消息将被忽略。
1.3.2 Unordered Messages
send(…)方法不保证消息的排序。这意味着,当您顺序发送消息A和消息B时,您不能保证目标节点首先接收到A,然后是B。
1.4 Subscribe for Messages
listen方法帮助收听/订阅消息。当调用这些方法时,具有指定消息主题的侦听器在所有(或子组)节点上注册,以侦听新消息。通过侦听方法,传递的谓词返回一个布尔值,该值告诉侦听器继续或停止监听新消息。
1.4.1 Local Listen
localListen(…)方法只在本地节点上注册一个带有指定主题的消息侦听器,并监听这个集群组中的任何节点的消息。
1.4.2 Remote Listen
remoteListen(…)方法向这个集群组中的所有节点注册一个指定主题的消息侦听器,并监听这个集群组中的任何节点的消息。
1.5 样例
下面的示例显示了远程节点之间的消息交换。
Ignite ignite = Ignition.ignite();
IgniteMessaging rmtMsg = ignite.message(ignite.cluster().forRemotes());
rmtMsg.remoteListen("MyOrderedTopic", (nodeId, msg) -> {
System.out.println("Received ordered message [msg=" + msg + ", from=" + nodeId + ']');
return true;
});
for (int i = 0; i < 10; i++)
rmtMsg.sendOrdered("MyOrderedTopic", Integer.toString(i));
Ignite ignite = Ignition.ignite();
IgniteMessaging rmtMsg = ignite.message(ignite.cluster().forRemotes());
rmtMsg.remoteListen("MyUnOrderedTopic", (nodeId, msg) -> {
System.out.println("Received unordered message [msg=" + msg + ", from=" + nodeId + ']');
return true;
});
for (int i = 0; i < 10; i++)
rmtMsg.send("MyUnOrderedTopic", Integer.toString(i));
Ignite ignite = Ignition.ignite();
ClusterGroup rmtPrj = ignite.cluster().forRemotes();
IgniteMessaging msg = ignite.message(rmtPrj);
msg.remoteListen("myOrderedTopic", new IgniteBiPredicate() {
@Override public boolean apply(UUID nodeId, String msg) {
System.out.println("Received ordered message [msg=" + msg + ", from=" + nodeId + ']');
return true;
}
});
for (int i = 0; i < 10; i++)
msg.sendOrdered("myOrderedTopic", Integer.toString(i), 0);
2.Local and Remote Events(本地和远程事件)
获得任何状态变化的通知或发生在集群范围内的事件。
2.1 概述
ignite的分布式的事件功能允许程序在分布式网格环境中发生各种事件时接收通知。你可以自动的获取发生在集群中的本地或者远程节点上的任务执行,读,写,或者查询操作的通知。
2.2 IgniteEvents
分布式事件功能通过IgniteEvents接口提供。你可以从ignite中得到一个igniteEvents的实例,就像下面这样:
Ignite ignite = ignition.ignite()
IgniteEvents events = ignite.events();
2.3 Subscribe for Events
侦听方法可用于接收在集群中发生的特定事件的通知。这些方法在本地或remotes节点上为指定的事件注册一个侦听器。每当事件发生在节点上时,侦听器就会被通知。
2.3.1 Local Events
localListen(...) 方法与本地节点只能上指定的事件注册事件监听器。
2.3.2 Remote Events
remoteListen(…)方法向集群或集群组中的所有节点注册事件侦听器。下面是每个方法的一个例子:
Ignite ignite = Ignition.ignite();
IgnitePredicate locLsnr = evt -> {
System.out.println("Received event [evt=" + evt.name() + ", key=" + evt.key() +
", oldVal=" + evt.oldValue() + ", newVal=" + evt.newValue());
return true;
};
ignite.events().localListen(locLsnr,
EventType.EVT_CACHE_OBJECT_PUT,
EventType.EVT_CACHE_OBJECT_READ,
EventType.EVT_CACHE_OBJECT_REMOVED);
final IgniteCache cache = ignite.cache("cacheName");
for (int i = 0; i < 20; i++)
cache.put(i, Integer.toString(i));
Ignite ignite = Ignition.ignite();
final IgniteCache cache = ignite.jcache("cacheName");
IgnitePredicate rmtLsnr = evt -> evt.key() >= 10;
ignite.events(ignite.cluster().forCacheNodes("cacheName")).remoteListen(null, rmtLsnr, EventType.EVT_CACHE_OBJECT_PUT,
EventType.EVT_CACHE_OBJECT_READ,
EventType.EVT_CACHE_OBJECT_REMOVED);
for (int i = 0; i < 20; i++)
cache.put(i, Integer.toString(i));
Ignite ignite = Ignition.ignite();
final IgniteCache cache = ignite.jcache("cacheName");
IgnitePredicate rmtLsnr = new IgnitePredicate() {
@Override public boolean apply(CacheEvent evt) {
System.out.println("Cache event: " + evt);
int key = evt.key();
return key >= 10;
}
};
ignite.events(ignite.cluster().forCacheNodes("cacheName")).remoteListen(null, rmtLsnr, EVT_CACHE_OBJECT_PUT, EVT_CACHE_OBJECT_READ, EVT_CACHE_OBJECT_REMOVED);
for (int i = 0; i < 20; i++)
cache.put(i, Integer.toString(i));
在上面的例子中,EVT_CACHE_OBJECT_PUT、EVT_CACHE_OBJECT_READ和EVT_CACHE_OBJECT_REMOVED 是在EventType接口中定义的预定义事件类型常量。
PS:EventType接口定义了可以使用监听方法的各种事件类型常量。有关这些事件类型的完整列表,请参考javadoc。
ps:作为参数传入localListen(…)和remoteListen(…)方法的事件类型也必须在IgniteConfiguration中配置。请参阅下面的配置示例。
2.4 Query for Events
系统中生成的所有事件都保存在本地节点上。igniteEvents API提供了查询这些事件的方法
2.4.1 Local Query
localQuery(…)方法查询本地节点上使用经过的谓词筛选器的事件。如果所有谓词都满足,则返回本地节点上发生的事件的集合。
2.4.2 Remote Query
remoteQuery(…)方法在这个投影中使用传递过来的谓词过滤器异步查询事件。这种操作是分布式的,因此在通信层上可能会失败,通常比本地事件通知要长得多。注意,这个方法不会阻塞,并且会立即返回。
2.5 Configuration
为了获得在集群中发生的任何任务或缓存事件的通知,必须启用IgniteConfiguration 的includeEventTypes 属性。
<bean class="org.apache.ignite.configuration.IgniteConfiguration">
...
<property name="includeEventTypes">
<util:constant static-field="org.apache.ignite.events.EventType.EVTS_CACHE"/>
property>
...
bean>
IgniteConfiguration cfg = new IgniteConfiguration();
cfg.setIncludeEventTypes(EVTS_CACHE);
Ignition.start(cfg);
默认情况下,由于性能原因关闭事件通知。
PS:由于每秒数千个事件被生成,因此它在系统上增加了额外的负载。这会导致显著的性能下降。因此,强烈建议只启用应用程序逻辑需要的那些事件。
3. Automatic Batching
批量通知,以帮助实现高速缓存性能和低延迟。
ignite自动分组或批量 那些由于在集群中发生缓存事件而生成的事件通知。
缓存中的每一个活动都可能导致生成和发送的事件通知。对于缓存活动高的系统,每个事件的通知都可能是网络密集的,可能导致在网格中缓存操作的性能下降。
在ignite中,事件通知可以分组,并分批或及时发送。这里有一个例子说明如何做到这一点:
Ignite ignite = Ignition.ignite();
final IgniteCache cache = ignite.jcache("cacheName");
IgnitePredicate rmtLsnr = new IgnitePredicate() {
@Override public boolean apply(CacheEvent evt) {
System.out.println("Cache event: " + evt);
int key = evt.key();
return key >= 10;
}
};
ignite.events(ignite.cluster().forCacheNodes("cacheName")).remoteListen(
10 , 0 , false, null, rmtLsnr, EVTS_CACHE);
for (int i = 0; i < 20; i++)
cache.put(i, Integer.toString(i));