Клиент шардинга кластера не соединяется с хостом

После недавнего исследования и вопроса Stack over flow я понимаю, что сегментирование кластера является лучшим вариантом, чем кластер-согласованный хэш-маршрутизатор. Но у меня проблемы с запуском кластера из двух процессов.

Один процесс - это Семя, а другой - Клиент. Кажется, что узел Seed непрерывно выбрасывает сообщения мертвой буквы (см. Конец этого вопроса).

Это Семя HOCON следует:

akka {
loglevel = "INFO"                    

actor {
    provider = "Akka.Cluster.ClusterActorRefProvider, Akka.Cluster"
    serializers {
        wire = "Akka.Serialization.WireSerializer, Akka.Serialization.Wire"
    }
    serialization-bindings {
        "System.Object" = wire
    }
}                    

remote {
    dot-netty.tcp {
        hostname = "127.0.0.1"
        port = 5000
    }
}

persistence {
    journal {
        plugin = "akka.persistence.journal.sql-server"
        sql-server {
            class = "Akka.Persistence.SqlServer.Journal.SqlServerJournal, Akka.Persistence.SqlServer"
            schema-name = dbo
            auto-initialize = on
            connection-string = "Data Source=localhost;Integrated Security=True;MultipleActiveResultSets=True;Initial Catalog=ClusterExperiment01"
            plugin-dispatcher = "akka.actor.default- dispatcher"
            connection-timeout = 30s
            table-name = EventJournal
            timestamp-provider = "Akka.Persistence.Sql.Common.Journal.DefaultTimestampProvider, Akka.Persistence.Sql.Common"
            metadata-table-name = Metadata
        }
    }

    sharding {
        connection-string = "Data Source=localhost;Integrated Security=True;MultipleActiveResultSets=True;Initial Catalog=ClusterExperiment01"
        auto-initialize = on
        plugin-dispatcher = "akka.actor.default-dispatcher"
        class = "Akka.Persistence.SqlServer.Journal.SqlServerJournal, Akka.Persistence.SqlServer"
        connection-timeout = 30s
        schema-name = dbo
        table-name = ShardingJournal
        timestamp-provider = "Akka.Persistence.Sql.Common.Journal.DefaultTimestampProvider, Akka.Persistence.Sql.Common"
        metadata-table-name = ShardingMetadata
    }
}

snapshot-store {
    sharding {
        class = "Akka.Persistence.SqlServer.Snapshot.SqlServerSnapshotStore, Akka.Persistence.SqlServer"
        plugin-dispatcher = "akka.actor.default-dispatcher"
        connection-string = "Data Source=localhost;Integrated Security=True;MultipleActiveResultSets=True;Initial Catalog=ClusterExperiment01"
        connection-timeout = 30s
        schema-name = dbo
        table-name = ShardingSnapshotStore
        auto-initialize = on
    }
}

cluster {
    seed-nodes = ["akka.tcp://my-cluster-system@127.0.0.1:5000"]
    roles = ["Seed"]

    sharding {
        journal-plugin-id = "akka.persistence.sharding"
        snapshot-plugin-id = "akka.snapshot-store.sharding"
    }
}}

У меня есть метод, который по сути превращает вышеупомянутое в Config, например так:

var config = NodeConfig.Create(/* HOCON above */).WithFallback(ClusterSingletonManager.DefaultConfig());

Без "WithFallback" я получаю исключение нулевой ссылки из генерации конфигурации.

И затем генерирует систему примерно так:

var system = ActorSystem.Create("my-cluster-system", config);

Клиент создает свою систему таким же образом, и HOCON практически идентичен, за исключением:

{
remote {
    dot-netty.tcp {
        hostname = "127.0.0.1"
        port = 5001
    }
}
cluster {
    seed-nodes = ["akka.tcp://my-cluster-system@127.0.0.1:5000"]
    roles = ["Client"]
    role.["Seed"].min-nr-of-members = 1
    sharding {
        journal-plugin-id = "akka.persistence.sharding"
        snapshot-plugin-id = "akka.snapshot-store.sharding"
    }
}}

Узел Seed создает шардинг следующим образом:

ClusterSharding.Get(system).Start(
   typeName: "company-router",
   entityProps: Props.Create(() => new CompanyDeliveryActor()),                    
   settings: ClusterShardingSettings.Create(system),
   messageExtractor: new RouteExtractor(100)
);

И клиент создает прокси-прокси примерно так:

ClusterSharding.Get(system).StartProxy(
    typeName: "company-router",
    role: "Seed",
    messageExtractor: new RouteExtractor(100));

RouteExtractor это:

public class RouteExtractor : HashCodeMessageExtractor
{
    public RouteExtractor(int maxNumberOfShards) : base(maxNumberOfShards)
    {   
    }
    public override string EntityId(object message) => (message as IHasRouting)?.Company?.VolumeId.ToString();
    public override object EntityMessage(object message) => message;
}

В этом случае VolumeId всегда одинаков (только для эксперимента).

Оба процесса оживают, но Seed продолжает выдавать эту ошибку в журнал:

[INFO][05.07.2017, 9:00:58][Тема 0003][akka://my-cluster-system/user/sharding /company-routerCoordinator/singleton/ координатор] Регистрация сообщений от akka.tcp://my-cluster-system@127.0.0.1:5000/user/sharding/company-router to akka://my-cl uster-system/user/sharding/company-routerCoordinator/singleton/ координатор не был доставлен. 4 встреченных мертвых буквы.

Ps. Я не использую Маяк.

2 ответа

Спасибо Horusiath, это исправлено:

return sharding.Start(
   typeName: "company-router",
   entityProps: Props.Create(() => new CompanyDeliveryActor()),                    
   settings: ClusterShardingSettings.Create(system).WithRole("Seed"),
                messageExtractor: new RouteExtractor(100)                
            );

Кластерный осколок теперь связывается между двумя процессами. Большое спасибо за это.

Вкратце, вы запускаете прокси-сервер сегментирования кластера на своем клиентском узле и сообщаете ему, что сегментированные узлы - это те, которые используют начальную роль. Это не соответствует определению сегментирования кластера на начальном узле, если вы не указали никакой роли.

Поскольку нет никакой роли, чтобы ограничивать его, сегментирование кластера на начальном узле будет обрабатывать все узлы в кластере как полностью способные к размещению сегментированных участников, включая клиентский узел, для которого не создан экземпляр сегментирования (непрокси) кластера.

Возможно, это не единственная проблема, но вы можете разместить хост-кластер на всех ваших узлах или использовать ClusterShardingSettings.Create(system).WithRole("seed") ограничить свой осколок только определенным подмножеством узлов (имеющих начальную роль) в кластере.

Другие вопросы по тегам