我正在创建一个聊天应用程序后端,并希望考虑可扩展性。
我想创建一个负载均衡器,但不是在HTTP所在的L7层上,而是在IP网络所在的L3层上,以指示与特定服务器的连接,然后我可以TCP
。< / p>
net.ListenIP
是否正确用于侦听IP层上的数据包?
例如,它与较高的Listen("tcp")
相同吗?这是我实现负载均衡器所需的正确方法吗?
是否有关于数据包结构的参考,以便我可以从中获取源IP和目标IP以转发它们?
如果没有告诉我使用哪个功能来侦听L3网络层以平衡负载到其他服务器。
答案 0 :(得分:2)
在reading the Docs之后,是的,此功能将帮助您接收IP数据包。
ListenIP就像是用于IP网络的ListenPacket。
ListenIP
与ListenPacket("tcp")
类似,但对于IP数据包。
对于IP数据包的结构,并使用它们,net
包似乎没有。
还有另一个包gopacket
,看起来它可以帮助您从任何层读取和修改数据包。
在gopacket
中有Packet
类型,允许使用网络层。
Packet.NetworkLayer().LayerContent()
和Packet.NetworkLayer().LayerPayload()
将返回byte[]
,您可以按预期的structure of an IP packet解释。
注意:既然我已经写完了这一切,我必须想象有人在那里编写了一个很好的叠加/包装来使这更容易。这只是我谷歌搜索10分钟的结果。也许其他人会用更好的工具/方法回答
答案 1 :(得分:2)
就个人而言,我使用gopacket来捕获多个网络层,这个库非常令人印象深刻。
当您使用gopacket时,您可以通过指定它们来捕获多个网络图层,例如Ipv4
,TCP
,Ethernet
...
有关详细信息,请参阅layers packet。
然后,您将能够使用packet.Data()
分析您的图层,eth0
是构成整个数据包的一组字节,然后打开数据包类型以执行某些操作。
例如,在package main
import (
"fmt"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap"
"time"
)
//Layers we want to decode
var (
ip4 layers.IPv4
eth layers.Ethernet
tcp layers.TCP
)
func main() {
//Array to store decoded layers
decodedLayers := []gopacket.LayerType{}
//Create parser
parser := gopacket.NewDecodingLayerParser(layers.LayerTypeEthernet, ð, &ip4, &tcp)
//Here we use pcap to capture packet on eth0 interface, we can also use afpacket for example, which is more efficient
handle, err := pcap.OpenLive("eth0", 65536, true, pcap.BlockForever)
if err != nil {
panic("Error opening pcap: " + err.Error())
}
datasource := gopacket.NewPacketSource(handle, layers.LayerTypeEthernet)
//packets will be a channel of packets
packets := datasource.Packets()
for {
select {
case packet := <-packets:
//We are decoding layers, and switching on the layer type
err := parser.DecodeLayers(packet.Data(), &decodedLayers)
for _, typ := range decodedLayers {
switch typ {
case layers.LayerTypeIPv4:
fmt.Printf("Source ip = %s - Destination ip = %s \n", ip4.SrcIP.String(), ip4.DstIP.String())
case layers.LayerTypeTCP:
//Here, we can access tcp packet properties
fmt.Println("Capture tcp traffic")
}
//etc ....
}
if len(decodedLayers) == 0 {
fmt.Println("Packet truncated")
}
//If the DecodeLayers is unable to decode the next layer type
if err != nil {
//fmt.Printf("Layer not found : %s", err)
}
}
}
}
上捕获多个网络层:
$store_name = isset($_POST['store_name']) ? $_POST['store_name'] : null;
$sql = "insert into user_feedback (store_name,name,feedback) values ('$store_name','$name','$feedback')";