Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何通过.Net客户端在Eventstore群集上写入和读取事件_.net_Docker_Cluster Computing_Eventstoredb - Fatal编程技术网

如何通过.Net客户端在Eventstore群集上写入和读取事件

如何通过.Net客户端在Eventstore群集上写入和读取事件,.net,docker,cluster-computing,eventstoredb,.net,Docker,Cluster Computing,Eventstoredb,我尝试使用.Net客户端在eventstore集群上写入和读取事件。 因此,我设置了3个本地docker容器来测试对集群的写入和读取。我已经设置了集群,它说它是活动的(1个主集群和2个从集群) 不幸的是,当我尝试在eventstore上从.Net客户端写入或读取时,连接总是自动打开和关闭,并且没有任何调用到达存储。如何连接到群集以写入和读取事件? 如果我在没有集群的情况下使用eventstore,那么这些方法可以正常工作,并且我可以创建和使用事件。对于群集,我只接收以下日志消息: Start c

我尝试使用.Net客户端在eventstore集群上写入和读取事件。 因此,我设置了3个本地docker容器来测试对集群的写入和读取。我已经设置了集群,它说它是活动的(1个主集群和2个从集群)

不幸的是,当我尝试在eventstore上从.Net客户端写入或读取时,连接总是自动打开和关闭,并且没有任何调用到达存储。如何连接到群集以写入和读取事件?

如果我在没有集群的情况下使用eventstore,那么这些方法可以正常工作,并且我可以创建和使用事件。对于群集,我只接收以下日志消息:

Start connecting to Eventstore
Start reading events:
[04,06:49:19.771,INFO] Discovering: found best choice [172.16.1.103:1112,n/a] (Master).
[04,06:49:19.771,INFO] Discovering attempt 1/10 successful: best candidate is [172.16.1.103:1112, n/a].
[10,06:49:20.396,INFO] ClientAPI TcpConnection closed [06:49:20.396: N172.16.1.103:1112, L, {220a086e-3394-49c3-affa-b3d6fc385ea2}]:
[10,06:49:20.396,INFO] Received bytes: 0, Sent bytes: 0
[10,06:49:20.396,INFO] Send calls: 0, callbacks: 0
[10,06:49:20.396,INFO] Receive calls: 0, callbacks: 0
[10,06:49:20.396,INFO] Close reason: [Success] Connection establishment timeout.
[10,06:49:20.397,DEBUG] TcpPackageConnection: connection [172.16.1.103:1112, L, {220a086e-3394-49c3-affa-b3d6fc385ea2}] was closed cleanly.
[10,06:49:22.564,INFO] Discovering attempt 1/10 failed: no candidate found.
[10,06:49:23.068,INFO] Discovering: found best choice [172.16.1.103:1112,n/a] (Master).
[10,06:49:23.068,INFO] Discovering attempt 2/10 successful: best candidate is [172.16.1.103:1112, n/a].
如果我使用WebUI将事件写入集群eventstore,它将接受该事件,然后可以在eventstore的WebUI中找到该事件


以下是我的设置,以防您需要详细信息:

eventstore群集的设置如中所述。 通过设置
discover via dns=false
,集群被设置为不使用dns。这是我的
.yaml
文件,用于docker设置:

version: '3'
services:
  eventstore1:
    image: "eventstore/eventstore:latest"
    environment:
      EVENTSTORE_DISABLE_HTTP_CACHING: "True"
      EVENTSTORE_RUN_PROJECTIONS: ALL
      EVENTSTORE_CLUSTER_SIZE: 3
      EVENTSTORE_INT_IP: 172.16.1.101
      EVENTSTORE_EXT_IP: 172.16.1.101
      EVENTSTORE_INT_TCP_PORT: 1111
      EVENTSTORE_EXT_TCP_PORT: 1112
      EVENTSTORE_INT_HTTP_PORT: 2113
      EVENTSTORE_EXT_HTTP_PORT: 2114
      EVENTSTORE_DISCOVER_VIA_DNS: "False"
      EVENTSTORE_GOSSIP_SEED: 172.16.1.102:2113,172.16.1.103:2113
      EVENTSTORE_INT_HTTP_PREFIXES: "http://*:2113/"
      EVENTSTORE_EXT_HTTP_PREFIXES: "http://*:2114/"
    ports:
      - 1111:1111
      - 1112:1112
      - 2113:2113
      - 2114:2114
    networks:
      app_net:
        ipv4_address: 172.16.1.101
  eventstore2:
    image: "eventstore/eventstore:latest"
    environment:
      EVENTSTORE_DISABLE_HTTP_CACHING: "True"
      EVENTSTORE_RUN_PROJECTIONS: ALL
      EVENTSTORE_CLUSTER_SIZE: 3
      EVENTSTORE_INT_IP: 172.16.1.102
      EVENTSTORE_EXT_IP: 172.16.1.102
      EVENTSTORE_INT_TCP_PORT: 1111
      EVENTSTORE_EXT_TCP_PORT: 1112
      EVENTSTORE_INT_HTTP_PORT: 2113
      EVENTSTORE_EXT_HTTP_PORT: 2114
      EVENTSTORE_DISCOVER_VIA_DNS: "False"
      EVENTSTORE_GOSSIP_SEED: 172.16.1.101:2113,172.16.1.103:2113
      EVENTSTORE_INT_HTTP_PREFIXES: "http://*:2113/"
      EVENTSTORE_EXT_HTTP_PREFIXES: "http://*:4114/"
    ports:
      - 3111:1111
      - 3112:1112
      - 4113:2113
      - 4114:2114
    networks:
      app_net:
        ipv4_address: 172.16.1.102
  eventstore3:
    image: "eventstore/eventstore:latest"
    environment:
      EVENTSTORE_DISABLE_HTTP_CACHING: "True"
      EVENTSTORE_RUN_PROJECTIONS: ALL
      EVENTSTORE_CLUSTER_SIZE: 3
      EVENTSTORE_INT_IP: 172.16.1.103
      EVENTSTORE_EXT_IP: 172.16.1.103
      EVENTSTORE_INT_TCP_PORT: 1111
      EVENTSTORE_EXT_TCP_PORT: 1112
      EVENTSTORE_INT_HTTP_PORT: 2113
      EVENTSTORE_EXT_HTTP_PORT: 2114
      EVENTSTORE_DISCOVER_VIA_DNS: "False"
      EVENTSTORE_GOSSIP_SEED: 172.16.1.101:2113,172.16.1.102:2113
      EVENTSTORE_INT_HTTP_PREFIXES: "http://*:2113/"
      EVENTSTORE_EXT_HTTP_PREFIXES: "http://*:2114/"
    ports:
      - 5111:1111
      - 5112:1112
      - 6113:2113
      - 6114:2114
    networks:
      app_net:
        ipv4_address: 172.16.1.103
networks:
  app_net:
    external: true
为了测试连接,以及是否可以在eventstore群集上写入和读取,我创建了以下小型应用程序:

主程序:

class Program
{
    const string STREAM = "MyTestStream";
    private static ConnectionFactory _connectionFactory = new ConnectionFactory();

    static void Main(string[] args)
    {
        var useCluster = true;
        Console.WriteLine("Start connecting to Eventstore");
        var writeEvents = new WriteEvents(_connectionFactory);
        writeEvents.Write(useCluster, STREAM).Wait();
        Console.WriteLine("Start reading events:");
        var readEvents = new ReadEvents(_connectionFactory);
        readEvents.Read(useCluster, STREAM).Wait();
        Console.WriteLine("Check if events are written and press key to exit");
        Console.ReadKey();
    }
}
连接工厂:

public class ConnectionFactory
{
    public IEventStoreConnection SingleConnection()
    {
        return EventStoreConnection.Create(ConnectionSettings.Create(),
            new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1113));
    }

    public IEventStoreConnection ClusterConnection()
    {
        return EventStoreConnection.Create(
            ConnectionSettings.Create().KeepReconnecting().UseConsoleLogger()
                .SetGossipSeedEndPoints(
                    new IPEndPoint(IPAddress.Parse("127.0.0.1"), 2113),
                    new IPEndPoint(IPAddress.Parse("127.0.0.1"), 4113),
                    new IPEndPoint(IPAddress.Parse("127.0.0.1"), 6113))
                .WithConnectionTimeoutOf(TimeSpan.FromMilliseconds(500))
                );
    }

    public IEventStoreConnection CreateConnection(bool useCluster)
    {
        if (useCluster)
        {
            return ClusterConnection();
        }

        return SingleConnection();
    }
}
集群的连接是按照中所述创建的,但是,文档与我使用的最新nuget版本并非100%一致

nuget版本:

<PackageReference Include="EventStore.ClientAPI.NetCore" Version="4.1.0.23" />

这不是与客户端类型相关的问题。对于非NetCore,您也将获得相同的行为。 当客户端尝试连接到群集中的一个节点时,EventStore会使用无法访问的ip进行响应。 在某些情况下,例如当您使用Kubernetes或swarm等软件编排器时,您的客户端需要托管在同一覆盖网络中,以便能够使用Tcp客户端连接到集群。 在开发应用程序/微服务时,您可以使用连接字符串连接到Kubernetes、swarm或本地Docker引擎中未托管的单节点EventStore。在Kubernetes、swarm或Docker Compose环境中部署应用程序时,您可以使用八卦种子设置应用程序的连接字符串,并使用群集主机的IP

使用群集连接的C#客户端

namespace TestClusterConnection
{
    class Program
    {
        private const string Stream = "MyTestStream";

        static void Main(string[] args)
        {
            try
            {
                var useCluster = true;
                Console.WriteLine("Start connecting to Eventstore");
                Write(useCluster, Stream).Wait();
                Console.WriteLine("Start reading events:");
                Read(useCluster, Stream).Wait();
                Console.WriteLine("Check if events are written and press key to exit");
            }
            catch (Exception e)
            {
                Console.WriteLine(e.GetBaseException().Message);
            }
            Console.ReadKey();
        }

        public static async Task Read(bool useCluster, string streamName)
        {
            using (var conn = CreateConnection(useCluster))
            {
                await conn.ConnectAsync();
                var slice = await conn.ReadStreamEventsForwardAsync(streamName, 0, 100, false);
                foreach (var evt in slice.Events)
                    Console.WriteLine($"Received event. Type: '{evt.Event.EventType}', Data: '{Encoding.UTF8.GetString(evt.Event.Data)}'");
            }
        }

        private static async Task Write(bool useCluster, string streamName)
        {
            using (var conn = CreateConnection(useCluster))
            {
                await conn.ConnectAsync();
                for (var x = 0; x < 100; x++)
                {
                    await conn.AppendToStreamAsync(streamName,
                        ExpectedVersion.Any,
                        GetEventDataFor(x));
                    Console.WriteLine("event " + x + " written.");
                }
            }
        }

        private static IEnumerable<EventData> GetEventDataFor(int i)
        {
            yield return new EventData(
                Guid.NewGuid(),
                "MyTestEvent",
                true,
                Encoding.ASCII.GetBytes("{'somedata' : " + i + "}"),
                Encoding.ASCII.GetBytes("{'metadata' : " + i + "}")
            );
        }


        private static IEventStoreConnection SingleConnection()
        {
            return EventStoreConnection.Create(ConnectionSettings.Create(),
                new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1113));
        }

        private static IEventStoreConnection ClusterConnection()
        {
            return EventStoreConnection.Create(
                ConnectionSettings.Create().KeepRetrying().KeepReconnecting().UseConsoleLogger()
                    .SetGossipSeedEndPoints(
                        new IPEndPoint(IPAddress.Parse("172.19.0.2"), 2112),
                        new IPEndPoint(IPAddress.Parse("172.19.0.3"), 2112),
                        new IPEndPoint(IPAddress.Parse("172.19.0.4"), 2112))
                    .SetHeartbeatInterval(TimeSpan.FromSeconds(3))
                    .SetHeartbeatTimeout(TimeSpan.FromSeconds(6))
                    .WithConnectionTimeoutOf(TimeSpan.FromSeconds(10))
            );
        }

        private static IEventStoreConnection CreateConnection(bool useCluster)
        {
            return useCluster ? ClusterConnection() : SingleConnection();
        }
    }
}
docker-compose.yaml

version: '3.4'

services:
  esclienttest:
    image: testclient
    build:
      context: .
      dockerfile: Dockerfile
    depends_on:
    - eventstore1
    - eventstore2
    - eventstore3

  eventstore1:
    image: eventstore/eventstore:release-4.1.0
    hostname: eventstore1    
    ports:    
    - 1113:1113
    - 2112:2112     
    environment:
      EVENTSTORE_CLUSTER_DNS: eventstore1
      EVENTSTORE_CLUSTER_SIZE: 3      
      EVENTSTORE_CLUSTER_GOSSIP_PORT: 2112   
      EVENTSTORE_EXT_IP_ADVERTISE_AS: 172.19.0.2 

  eventstore2:
    image: eventstore/eventstore:release-4.1.0
    hostname: eventstore2
    environment:
      EVENTSTORE_CLUSTER_DNS: eventstore1
      EVENTSTORE_CLUSTER_SIZE: 3      
      EVENTSTORE_CLUSTER_GOSSIP_PORT: 2112      
      EVENTSTORE_EXT_IP_ADVERTISE_AS: 172.19.0.3  

  eventstore3:
    image: eventstore/eventstore:release-4.1.0
    hostname: eventstore3
    environment:
      EVENTSTORE_CLUSTER_DNS: eventstore1
      EVENTSTORE_CLUSTER_SIZE: 3      
      EVENTSTORE_CLUSTER_GOSSIP_PORT: 2112      
      EVENTSTORE_EXT_IP_ADVERTISE_AS: 172.19.0.4
这仅用于测试,可能需要进一步的网络设置

希望这有帮助


Riccardo

我建议排除一些不一致的地方,就是在测试中使用非NetCore客户端-其中有3到4个修复程序可能会导致这种情况。如果您在中尝试我的设置并将单节点八卦群集作为起点
和$env:ProgramData\chocolate\bin\EventStore.ClusterNode.exe--单节点八卦--通过dns 0发现--ext http port=30778
。(对于商业集群,流言发生在
30778
上,此配置允许OSS版本模拟这种情况)。首先在本地运行,然后转到dockerx1,然后是x3
namespace TestClusterConnection
{
    class Program
    {
        private const string Stream = "MyTestStream";

        static void Main(string[] args)
        {
            try
            {
                var useCluster = true;
                Console.WriteLine("Start connecting to Eventstore");
                Write(useCluster, Stream).Wait();
                Console.WriteLine("Start reading events:");
                Read(useCluster, Stream).Wait();
                Console.WriteLine("Check if events are written and press key to exit");
            }
            catch (Exception e)
            {
                Console.WriteLine(e.GetBaseException().Message);
            }
            Console.ReadKey();
        }

        public static async Task Read(bool useCluster, string streamName)
        {
            using (var conn = CreateConnection(useCluster))
            {
                await conn.ConnectAsync();
                var slice = await conn.ReadStreamEventsForwardAsync(streamName, 0, 100, false);
                foreach (var evt in slice.Events)
                    Console.WriteLine($"Received event. Type: '{evt.Event.EventType}', Data: '{Encoding.UTF8.GetString(evt.Event.Data)}'");
            }
        }

        private static async Task Write(bool useCluster, string streamName)
        {
            using (var conn = CreateConnection(useCluster))
            {
                await conn.ConnectAsync();
                for (var x = 0; x < 100; x++)
                {
                    await conn.AppendToStreamAsync(streamName,
                        ExpectedVersion.Any,
                        GetEventDataFor(x));
                    Console.WriteLine("event " + x + " written.");
                }
            }
        }

        private static IEnumerable<EventData> GetEventDataFor(int i)
        {
            yield return new EventData(
                Guid.NewGuid(),
                "MyTestEvent",
                true,
                Encoding.ASCII.GetBytes("{'somedata' : " + i + "}"),
                Encoding.ASCII.GetBytes("{'metadata' : " + i + "}")
            );
        }


        private static IEventStoreConnection SingleConnection()
        {
            return EventStoreConnection.Create(ConnectionSettings.Create(),
                new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1113));
        }

        private static IEventStoreConnection ClusterConnection()
        {
            return EventStoreConnection.Create(
                ConnectionSettings.Create().KeepRetrying().KeepReconnecting().UseConsoleLogger()
                    .SetGossipSeedEndPoints(
                        new IPEndPoint(IPAddress.Parse("172.19.0.2"), 2112),
                        new IPEndPoint(IPAddress.Parse("172.19.0.3"), 2112),
                        new IPEndPoint(IPAddress.Parse("172.19.0.4"), 2112))
                    .SetHeartbeatInterval(TimeSpan.FromSeconds(3))
                    .SetHeartbeatTimeout(TimeSpan.FromSeconds(6))
                    .WithConnectionTimeoutOf(TimeSpan.FromSeconds(10))
            );
        }

        private static IEventStoreConnection CreateConnection(bool useCluster)
        {
            return useCluster ? ClusterConnection() : SingleConnection();
        }
    }
}
FROM mono:4.6.2.16
ADD . /home/TestClusterConnection
CMD [ "mono",  "home/TestClusterConnection/TestClusterConnection.exe" ]
version: '3.4'

services:
  esclienttest:
    image: testclient
    build:
      context: .
      dockerfile: Dockerfile
    depends_on:
    - eventstore1
    - eventstore2
    - eventstore3

  eventstore1:
    image: eventstore/eventstore:release-4.1.0
    hostname: eventstore1    
    ports:    
    - 1113:1113
    - 2112:2112     
    environment:
      EVENTSTORE_CLUSTER_DNS: eventstore1
      EVENTSTORE_CLUSTER_SIZE: 3      
      EVENTSTORE_CLUSTER_GOSSIP_PORT: 2112   
      EVENTSTORE_EXT_IP_ADVERTISE_AS: 172.19.0.2 

  eventstore2:
    image: eventstore/eventstore:release-4.1.0
    hostname: eventstore2
    environment:
      EVENTSTORE_CLUSTER_DNS: eventstore1
      EVENTSTORE_CLUSTER_SIZE: 3      
      EVENTSTORE_CLUSTER_GOSSIP_PORT: 2112      
      EVENTSTORE_EXT_IP_ADVERTISE_AS: 172.19.0.3  

  eventstore3:
    image: eventstore/eventstore:release-4.1.0
    hostname: eventstore3
    environment:
      EVENTSTORE_CLUSTER_DNS: eventstore1
      EVENTSTORE_CLUSTER_SIZE: 3      
      EVENTSTORE_CLUSTER_GOSSIP_PORT: 2112      
      EVENTSTORE_EXT_IP_ADVERTISE_AS: 172.19.0.4