我正在Go中编写一个DNS服务器,以了解DNS的工作原理以及如何在Go中编写一个可能有用的真实程序。
我选择Go的原因之一是因为它的Go例程而不是线程。
当前,我的DNS服务器并没有做太多事情,它为收到的每个查询发送相同的响应。
让我感到困惑的是,即使使用Go例程,即使它很小并且不起作用,我的DNS服务器也比BIND慢10倍。
我运行了一个名为dnsblast
的程序来一次发送大量DNS查询,这是我的结果:
BIND
Sending 10,000 queries = 39,000 pps
My server
Sending 10,000 queries = 3,000 pps
另外,随着我每秒发送的数据包数量的增加,服务器对查询的响应也越来越少。
例如: 发送1,000个查询时,服务器响应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中创建服务器的一种非常标准的方法。
是否有最佳实践来提高服务器的吞吐量,或者服务器看起来还不错,只是我的部分DNS实施缓慢?
谢谢!
答案 0 :(得分:0)
不幸的是,Go的UDP支持不够理想。该实现分配内存。有点帮助的是并行运行循环。操作系统级别上增加的缓冲区大小限制了包丢失。