2017-09-01 5 views
0

私はチャットアプリケーションバックエンドを作成しており、スケーラビリティを考慮したいと考えています。L3ネットワーク層で聞くには?

HTTPがあるL7レイヤではなく、TCPという特定のサーバーに接続するIPネットワークがあるL3レイヤで、ロードバランサを作成したいとしました。

net.ListenIPは、IPレイヤー上のパケットをリッスンするために使用する正しい機能ですか?

例えば、Listen("tcp")と同じですか?ロードバランサを実装するのに適切な方法ですか?

パケットがどのように構造化されているので、送信元IPと宛先IPからパケットを引き出すことができますか?

負荷を他のサーバと均衡させるためにL3ネットワーク層でリッスンする機能を教えてください。

答えて

2

reading the Docsの後、この機能はIPパケットの受信に役立ちます。

ListenIPはIPネットワークのListenPacketのように動作します。

は、IPパケットの場合と似ていますが、ListenPacket("tcp")です。

IPパケットの構造については、netパッケージには含まれていないようです。

他のパッケージgopacketは、どのレイヤーからのパケットの読み取りや変更にも役立つようです。

gopacketには、Packetタイプがあり、ネットワークレイヤーでの作業が可能です。

Packet.NetworkLayer().LayerContent()およびPacket.NetworkLayer().LayerPayload()はそれぞれbyte[]を返します。これは予想通りstructure of an IP packetで解釈できます。


今、私はこれを容易にするために素敵なオーバーレイ/ラッパーが書かれているから誰かを想像する必要があり、この全体のことを書いたこと。これは私の10分間のグーグルの結果です。他の人がより良いツール/方法で答えてくれるかもしれない

+0

ので、私は見ての多くに耳を傾ける私の自己 –

+0

をバランサ私はあなたのノートを読んで、私は負荷を実装したいので、あなたの答えは最高でなければなりませんパケットが来て、私はそれを私のサーバーに転送して、それらを処理し、tcpを開きますか?バランサーは橋の役目を果たしますか? –

2

個人的には、私はgopacketを使用して複数のネットワーク層をキャプチャしています。このライブラリは非常に印象的です。

あなたがgopacketを使用している場合は、あなたがたとえばIpv4のために、それらを指定することにより、複数のネットワーク層をキャプチャすることができ、TCPEthernet ...詳細については 、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

あなたの回答も役に立ちました。ありがとう –

関連する問題