2017-09-01 82 views
0

我正在創建一個聊天應用程序後端,並且要考慮可伸縮性。如何聽L3網絡層?

我想創建一個負載平衡器,但不是在HTTP所在的L7層,而是在IP網絡所在的L3層,以便將連接指向特定的服務器,然後我可以製作TCP

net.ListenIP正確的函數來偵聽IP層上的數據包?

是否與更高的Listen("tcp")相同?這是我需要實現負載平衡器的正確方法嗎?

是否有對數據包結構的引用,以便我能夠從中獲取源IP和目的IP來轉發它們?

如果不告訴我在L3網絡層偵聽哪個函數來平衡負載到其他服務器。

回答

2

reading the Docs之後,是的這個功能會幫你收到IP包。

ListenIP的行爲就像IP網絡的ListenPacket一樣。

ListenIPListenPacket("tcp")類似,但是對於IP數據包。

至於IP數據包的結構,並與他們合作,net包似乎沒有。

還有另一個包gopacket看起來它會幫助你讀取和修改任何層的數據包。

gopacket有一個Packet類型,它允許使用網絡層。

Packet.NetworkLayer().LayerContent()Packet.NetworkLayer().LayerPayload()將分別返回byte[],您可以通過預期的structure of an IP packet解釋。


注意現在,我已經寫了我有在那裏寫了一本很好的覆蓋/包裝,以使這更容易想象別人這件事。這只是我使用谷歌搜索10分鐘的結果。也許別人會用更好的工具/方法來回答

+0

我看了你的筆記,但你的回答一定是最好的,因爲我想實現負載均衡我自己 –

+0

,所以我看到和聽到了很多的數據包來了,我將它們轉發到我的服務器來處理它們並打開tcp的權利?平衡器是一個橋樑嗎? –

2

就我個人而言,我使用gopacket來捕獲多個網絡層,這個庫非常令人印象深刻。

當你使用gopacket,您可以通過指定他們捕捉到多個網絡層,例如Ipv4TCPEthernet ... 欲瞭解更多信息,請參閱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, &eth, &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) 
      } 
     } 
    } 

} 
+0

所以我看到和聽到很多數據包來了,我把它們轉發到我的服務器來處理它們並打開TCP對嗎?平衡器是一個橋樑嗎? –

+0

你的回答也很有幫助。謝謝 –