问题
我想运行负载测试,每秒请求数量很高。我在Go中写了一个套接字发送者和一个接收者。发送方向端口7357发送大量数据包,每个数据包包含当前时间(以纳秒为单位)。接收机在端口7357进行侦听并分析每条消息,计算延迟。如何在Go中为每个连接写入单独的数据包?
问题是,当阅读我在一个conn.Read()
得到多个数据包。我知道这意味着我实际上每个数据包都发送多条消息:每个conn.Write()
都不会发送套接字数据包,但会等待一段时间,然后在发送之前与下一个(或接下来的几个)进行合并。
问题
我怎样才能确保每个conn.Write()
通过插座单独发送作为一个单独的数据包? 注意:我不想重新创建TCP,我只是想模拟从每个发送消息的外部实体的负载。
所采取的步骤
我已经搜索的文档,但似乎没有conn.Flush()
或相似。我曾尝试使用缓冲写入器:
writer := bufio.NewWriter(conn)
...
bytes, err := writer.Write(message)
err = writer.Flush()
没有错误,但仍然在接收端得到混合数据包。我也尝试在每conn.Write()
之后做0个字节的假conn.Read()
,但它也没有工作。发送消息终止符如\r\n
似乎没有任何区别。最后,Nagle算法在默认情况下是禁用的,但我已经调用tcp.SetNoDelay(true)
进行了很好的测量。
在Node.js中,我设法在每个socket.write()
:setImmediate()
等待所有I/O完成之前完成setImmediate()
的技巧。我如何在Go中执行相同的操作,以便获得单独的数据包?
代码段
发送:
func main() {
conn, _ := net.Dial("tcp", ":7357")
defer conn.Close()
for {
timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
conn.Write([]byte(timestamp))
conn.Read(buff)
}
}
接收:
func main() {
listen, _ := net.Listen("tcp4", ":7357")
defer listen.Close()
for {
conn, _ := listen.Accept()
go handler(conn)
}
}
func handler(conn net.Conn) {
defer conn.Close()
var buf = make([]byte, 1024)
for {
conn.Read(buf)
data := string(buf[:n])
timestamp, _ := strconv.ParseInt(data, 10, 64)
elapsed := timestamp - time.Now().UnixNano()
log.Printf("Elapsed %v", elapsed)
}
}
错误处理的可读性被删除,但在实际的代码彻底检查。它第一次运行strconv.ParseInt()
时崩溃,value out of range
错误,因为它收到了很多时间戳合并。
TCPConn中的SetWriteBuffer,IPConn ...在净包文档(https://golang.org/pkg/net)不起作用,我已经试过了。但这个参考似乎有一个解决方案https://groups.google.com/forum/#!topic/golang-nuts/0FQ8duKRB4U我还没有尝试过,但你可能想要退房。 – Ravi
“*我只是想模拟来自大量发送消息的外部实体的负载。*”您能否详细说明这一点? “一条消息”究竟是什么意思?为什么多个外部实体使用单个TCP连接?这听起来像你想/需要一个消息协议,为什么不设计/实现一个? –
几个客户端连接到一台服务器并使用TCP发送消息。每条消息都包含在一个TCP数据包中。服务器分别处理每条消息。这个测试的连接数量并不重要;客户可能会使用几个或只有一个。我想我可以打开几个连接并使用循环法通过每个连接发送一条消息,但我正在寻找一种更简单的方法。 – alexfernandez