Я пишу 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 из того, что япрочитал в Интернете.
- прослушивание пакетов
- сохранение данных пакета в буфере
- обработка каждого пакета с использованием отдельной процедуры Go.
Есть ли рекомендации по улучшению пропускной способности моего сервера, или сервер выглядит нормально, и просто частичная реализация DNS медленная?
Спасибо!