Я запускаю кластер Apache Ignite с различными узлами, которые предоставляют услуги. Каждому узлу назначается определенная группа услуг (настраиваемые атрибуты узла), описывающая услугу, предоставляемую этим узлом, например. Авторизация, Оплата, ...
Некоторые из этих сервисов используют Ignite Cache, но я хочу, чтобы эти специфичные для сервиса кэши были развернуты только на связанных сервисных узлах. Итак, я добавляю фильтр узла в свою конфигурацию кеша:
// configuration with custom attribute is provided at node start up
IgniteConfiguration nodeConfig = new IgniteConfiguration();
Map<String,String> nodeAttributes = Collections.singletonMap("role", "MyService");
nodeConfig.setUserAttributes(nodeAttributes);
CacheConfiguration cfg = new CacheConfiguration<>("MyServiceCache");
cfg.setNodeFilter((node) -> node.attribute("role") == nodeConfig .getUserAttributes().get("role"));
Развертывание кеша работает должным образом (по крайней мере, ошибки не отображаются). Однако, когда я добавляю 2-й узел, который предоставляет ту же услугу (по причинам масштабирования), отображается запись в журнале:
No server nodes found for cache client: MyServiceCache
Как только я останавливаю 2-й узел, появляется другое сообщение журнала:
[17:26:29] Topology snapshot [ver=9, servers=1, clients=0, CPUs=4, heap=1.7GB]
[17:26:29] All server nodes for the following caches have left the cluster: 'MyServiceCache'
[17:26:29] Must have server nodes for caches to operate.
Насколько я понимаю, 1-й узел все еще должен обслуживать службу и кеш. Так что эти сообщения не имеют для меня особого смысла. Может кто-нибудь уточнить, пожалуйста?
Вот конкретный пример:
- Запустите
MyService.java
дважды или более - Остановить 1-й узел
- Смотреть вывод журнала 2-го узла
NodeConfig.java
public class NodeConfig {
public static IgniteConfiguration myServiceNode()
{
IgniteConfiguration nodeConfig = new IgniteConfiguration();
Map<String,String> nodeAttributes = Collections.singletonMap("role", "myService");
nodeConfig.setUserAttributes(nodeAttributes);
return nodeConfig;
}
}
CacheConfig.java
public class CacheConfig {
public static CacheConfiguration<Long, String> myServiceCache() {
CacheConfiguration<Long, String> cfg = new CacheConfiguration<>("MyServiceCache");
cfg.setBackups(2);
cfg.setNodeFilter((node) -> node.attribute("role") == NodeConfig.myServiceNode().getUserAttributes().get("role"));
return cfg;
}
}
MyService.java
public class MyService implements Service {
@IgniteInstanceResource
private Ignite ignite;
private IgniteCache cache;
@Override
public void cancel(ServiceContext serviceContext) {
System.out.println("Service " + serviceContext.name() + " cancelled.");
}
@Override
public void init(ServiceContext serviceContext) throws Exception {
System.out.println("Service " + serviceContext.name() + " initialized.");
}
@Override
public void execute(ServiceContext serviceContext) throws Exception {
CacheConfiguration config = CacheConfig.myServiceCache();
cache = ignite.getOrCreateCache(config).withExpiryPolicy(new CreatedExpiryPolicy(Duration.ONE_MINUTE));
System.out.println("Service " + serviceContext.name() + " executing.");
}
public static void main(String[] args) {
Ignite ignite = Ignition.start(NodeConfig.myServiceNode());
IgniteServices svcs = ignite.services(ignite.cluster().forAttribute("role", NodeConfig.myServiceNode().getUserAttributes().get("role")));
svcs.deployNodeSingleton("MyService", new MyService());
}
}