Лучшие сетевые практики для сервера UDP - PullRequest
0 голосов
/ 26 января 2019

Я пишу DNS-сервер на Go, чтобы узнать, как работает DNS и как написать настоящую, потенциально полезную программу на Go.

Одна из причин, по которой я выбрал Go, заключалась в его подпрограммах Go вместопотоки.

В настоящее время мой DNS-сервер на самом деле мало что делает, он отправляет один и тот же ответ на каждый полученный запрос.

Одна вещь, которая меня смущает, это то, что мой DNS-сервер, даже сего подпрограммы Go и даже несмотря на то, что он небольшой и мало что делает, в 10 раз медленнее, чем BIND.

Я запустил программу под названием dnsblast для одновременной отправки множества DNS-запросов, и вот мои результаты:

BIND
Sending 10,000 queries = 39,000 pps

My server
Sending 10,000 queries = 3,000 pps

Кроме того, когда я увеличиваю количество отправляемых пакетов в секунду, сервер отвечает на все меньше и меньше запросов.

Например: при отправке 1000 запросов сервер отвечает на100%, но при отправке 10 000 запросов сервер отвечает только на 66%.

Есть ли какое-либо отношение к работе в сети в Go, которое может ограничивать производительность моего DNS-сервера?Есть ли в Go параметры, которые я могу настроить?

В настоящее время основная программа выглядит следующим образом:

func main() {

    serv, err := net.ListenPacket("udp", ":53")

    if err != nil {
        panic(err)
    }

    defer serv.Close()

    for {
        tmp := make([]byte, 512)
        num_bytes, addr, _ := serv.ReadFrom(tmp)
        go handleQuery(serv, bytes.NewBuffer(tmp[:num_bytes]), addr)
    }

}

Это кажется довольно стандартным способом создания сервера в Go из того, что япрочитал в Интернете.

  1. прослушивание пакетов
  2. сохранение данных пакета в буфере
  3. обработка каждого пакета с использованием отдельной процедуры Go.

Есть ли рекомендации по улучшению пропускной способности моего сервера, или сервер выглядит нормально, и просто частичная реализация DNS медленная?

Спасибо!

1 Ответ

0 голосов
/ 27 января 2019

К сожалению, поддержка UDP в Go неоптимальна. Реализация выделяет память. Что помогает, так это запустить цикл параллельно. Увеличен размер буфера при потере пакета предельного уровня ОС.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...