Использование ZeroMQ Golang в Fargate - PullRequest
0 голосов
/ 03 мая 2020

Я пытаюсь использовать ZeroMQ в ECS, работающем на Fargate в режиме awsvp c. У меня есть 2 разные службы, каждая из которых выполняет свою задачу с включенным обнаружением служб.

Я создаю свой маршрутизатор и дилер в микросервисе с именем broker.

front, _ := zmq.NewSocket(zmq.ROUTER)
defer front.Close()
front.Bind("tcp://*:4070")

back, _ := zmq.NewSocket(zmq.DEALER)
defer back.Close()
back.Bind("tcp://*:4080")

Затем я добавляю эти 2 сокета в Poller и есть для l oop, который ждет сообщений.

У меня есть отдельный микросервис, который подключается к сокету и пытается отправить сообщение дилеру. Я установил обнаружение службы, поэтому я предполагаю, что адрес, к которому я подключаюсь, будет:

"tcp: // broker: 4070"

Ниже приведен код от 'serviceA '

func New(ZMQ models.ZMQ) *Requester {
    s, err := zmq.NewSocket(zmq.REQ)
    if err != nil {
        log.Fatalln("shareholder/requester zmq.NewSocket", err)
    }
    p := zmq.NewPoller()
    p.Add(s, zmq.POLLIN)

    log.Println("Requester", ZMQ.Req)
    err = s.Connect("tcp://broker:4070")
    if err != nil {
        log.Print(fmt.Errorf("err is %w", err))
    }

    req := &Requester{
        Poller:  p,
        Retries: 2,
        Socket:  s,
        Timeout: time.Duration(time.Minute),
    }
    runtime.SetFinalizer(req, (*Requester).Close)
    return req
}

Затем я использую указанный выше код для отправки сообщения с моим сокет-соединением

_, err := r.Socket.SendMessage(req)

Однако мое сообщение никогда не принимается в моей брокерской службе. Я могу подключиться к своим REST API в сети по именам их хостов, которые я регистрирую при обнаружении службы. Есть ли что-то, чего мне здесь не хватает в Fargate / ECS / ZeroMQ ???

Ответы [ 2 ]

1 голос
/ 04 мая 2020

Q : "есть что-то Мне не хватает здесь с Fargate / ECS / ZeroMQ ???"

Может быть, да, может быть, нет.


Добро пожаловать в искусство дзен-ноль:


В случае, если никто никогда не работал с ZeroMQ ,
здесь можно в первый раз взглянуть на "ZeroMQ Принципы менее чем за Пять секунд "
перед погружением в дальнейшие детали



Давайте начнем структурированным образом, чтобы перейти к root -причины:

Шаг 0: a Брокер Сервисный узел

Был упомянут ZeroMQ, поэтому мы начнем с этого момента. Учитывая ваш выбор, вы должны использовать AccessPoint для DEALER по адресу ( *:4070 ) и AccessPoint для ROUTER по адресу ( *:4080 ), и оба использовать .bind() -метод для активации tcp:// -Транспортный класс внутри Брокерского -Микросервисного узла, наш следующий шаг - проверить, действительно ли этот Узел видим для остального мира.

Итак, дайте ему поработать.

Шаг 1: Тест прямой видимости

Это первый шаг для проверки - это Брокер - Узел, какой бы его реализация на самом деле не была видна «целевой аудитории»? Если нет, то в ZeroMQ или других инфраструктурах ничего не поделаешь, но ваша задача - получить адреса, L1-сигнальное соединение, L2-arp / rarp MA C -детектирование / отображение, L3-разрешения на маршрутизацию / access-lists / filters / xlations / et c, (dynamici c) Обновлены DNS-обновления и все другие конфигурации, так что вы можете (выборочная часть) остальной мир увидеть и приблизиться на один шаг ближе к выполнить успешно .connect()

$ #                                 is it L3-(in)-visible # a [ PASS ] | [ FAIL ]
$ ping <_a_Broker_Node_Assumed_TCP/IP_Address>            # a [ PASS ] | [ FAIL ]

Шаг 2: RTO-тест номера порта

$ #                                                  4070 # a [ PASS ] | [ FAIL ]
$ netcat -vz <_a_Broker_Node_visible_TCP/IP_Address> 4070 # a [ PASS ] | [ FAIL ]
$ ######
$ # OR :
$ ######
$ telnet     <_a_Broker_Node_visible_TCP/IP_Address> 4070 # a [ PASS ] | [ FAIL ]
Trying 
Connected to 
Escape character is '^]'.
https://<_a_Broker_Node_visible_TCP/IP_Address>:4070
HTTP/1.1 400 Bad Request
Server: nginx
Date: Mon, 03 May 2020 18:14:54 GMT
Content-Type: text/html
Content-Length: 150
Connection: close

<html>
<head><title>400 Bad Request</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx</center>
</body>
</html>
Connection closed by foreign host.
$
$ //                                             4080 // a [ PASS ] | [ FAIL ]
$ telnet <_a_Broker_Node_visible_TCP/IP_Address> 4080 // a [ PASS ] | [ FAIL ]

Шаг 3: RTO-тест локальной отправки сообщения

Замените довольно сложную область REQ/ROUTER -Scalable Formal Pattern Archetype Pattern, и давайте проверим с помощью простого теста доставки PUSH/PULL -message, который (по очевидным причинам) соответствует предполагаемому использованию для отправка сообщения:

package main

import (
    zmq "github.com/pebbe/zmq4"
    "log"
    "fmt"
    "time"
    ...
)

func PushTASK() {

    aCtx, err    := zmq.NewContext()
    if err != nil {
        log.Fatalln( "__NACK: aCtx instantiation failed in zmq.NewContext()",
                      err )
    }

    aPusher, err := aCtx.NewSocket( zmq.PUSH )
    if err != nil {
        log.Fatalln( "__NACK: aPusher instantiation failed in aCtxNewSocket()",
                      err )
    }

    err = aPusher.SetLinger( 0 )
    if err != nil {
        log.Fatalln( "__NACK: aPusher instance failed to .SetLinger()",
                      err  )
    }

    err = aPusher.SetConflate( true )
    if err != nil {
        log.Fatalln( "__NACK: aPusher instance failed to .SetConflate()",
                      err  )
    }

    log.Println( "POSACK: aPusher instantiated and about to .connect( tcp://addr:port#)" )

    err = aPusher.Connect( "tcp://broker:4070" )
    if err != nil {
        log.Print( fmt.Errorf( "__NACK: aPusher failed to .connect(): %w",
                                err )
                   )
    }

    log.Println( "POSACK: aPusher RTO and about to .SendMessage*()-loop" )

    for aPush_NUMBER := 1; aPush_NUMBER < 10000; aPush_NUMBER++ {

        err = aPusher.SendMessageDontwait( aPush_NUMBER )
        if err != nil {
              log.Print( fmt.Errorf( "__NACK: aPusher failed to .SendMessageDontwait()[%d]: %w",
                                      aPush_NUMBER,
                                      err )
                         )
        }

        time.Sleep( 0.1 * time.Second )
    }
 // ---------------------------------------------------BE NICE TO RESOURCES USED
    err = aPusher.Disconnect( "tcp://broker:4070" )
    if err != nil {
        log.Print( fmt.Errorf( "__NACK: aPusher failed to .Disconnect( tcp://addr:port ): %w",
                                err )
                   )
    }
 // ---------------------------------------------------BE NICE TO RESOURCES USED
    err = aPusher.Close()
    if err != nil {
        log.Print( fmt.Errorf( "__NACK: aPusher failed to .Close(): %w",
                                err )
                   )
    }
 // ---------------------------------------------------BE NICE TO RESOURCES USED
    err = aCtx.Term()
    if err != nil {
        log.Print( fmt.Errorf( "__NACK: aCtx failed to .Term(): %w",
                                err )
                   )
    }
 // ---------------------------------------------------WE ARE CLEAR TO TERMINATE
}

Шаг 4: RTO-тест удаленного получения сообщения

Если ни один из тестов [ PASS ] | [ FAIL ] не потерпел крах, следующий шаг должен отразить PUSH сторона концепции "Ремо te " Broker , да, переписать его, используя сторону PULL, и развернуть его, чтобы увидеть, нет ли сбоев и поступают ли сообщения так, как они должны в все еще работает или перезапустите Шаг 3.

Шаг 5. Оцените возможности ZeroMQ

Как только все приведенные выше тесты действительно сделают [ PASS ], вы не только уверены, что ZeroMQ был не ограничитель показа, но также может усовершенствовать развернутые принципы в любом последующем сценарии использования ios, учитывая, что L1- / L2- / L3- / ZeroMQ-сервисы были установлены корректным и проверяемым образом.

0 голосов
/ 03 мая 2020

Я бы описал свое мышление как ответ, и я уверен, что мы можем выяснить вашу проблему.

Так что я думаю, что это ваша установка.

Setup services

Сервис A

  • nginx звонки backend через backend:9000
  • backend звонки nginx через nginx:80

Служба от A до B

  • nginx не может вызвать брокера1 через broker1:4070
  • Ни nginx, ни backend не может позвонить broker1 или broker2, просто указав имя: порт .

Если контейнер работает в разных службах и каждая служба имеет свой собственный awsvpc, который нельзя вызвать, просто указав имя: порт .

Вам необходимо установить соединение между службами , от A до B, что означает, что вам нужно правильное обнаружение службы.

...