Golang在生产中崩溃

时间:2016-06-01 16:19:56

标签: linux go

我有一个go程序,它连接到tcp服务器并将该消息发布到Web服务。该应用程序在第一次运行时工作正常,并在一周左右后发生恐慌。我不知道为什么。堆栈跟踪也没有帮助。 (我从mac os交叉编译到linux; env GOOS = linux GOARCH = 386 go build) 可能会有人指出可能存在的问题吗?

tcp服务器连接可能偶尔会关闭;我已经手工构建了重新连接逻辑。 错误条件也适用于发布。互联网连接可能随时中断;所以“dns”解析器默认使用“cgo”是恐慌。我使用“netgo”重新编译以使用纯粹的网络实现。

堆栈跟踪

net.runtime_pollWait(0xf75c12d8, 0x72, 0x18690000)
    /usr/local/go/src/runtime/netpoll.go:157 +0x55 net.(*pollDesc).Wait(0x18a6bb38, 0x72, 0x0, 0x0)/usr/local/go/src/net/fd_poll_runtime.go:73 +0x35
    net.(*pollDesc).WaitRead(0x18a6bb38, 0x0, 0x0) _poll_runtime.go:78 +0x33
    net.(*netFD).Read(0x18a6bb00, 0x18cd6000, 0x1000, 0x1000, 0x0, 0xf75bc018, 0x18690000)/usr/local/go/src/net/fd_unix.go:232 +0x19anet.(*conn).Read(0x18cd4d78, 0x18cd6000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
    /usr/local/go/src/net/net.go:172 +0xb9
    net/http.noteEOFReader.Read(0xf75fc018, 0x18cd4d78, 0x1889770c, 0x18cd6000, 0x1000, 0x1000, 0x2c3620, 0x0, 0x0)
    /usr/local/go/src/net/http/transport.go:1370 +0x55
    net/http.(*noteEOFReader).Read(0x18cd29e0, 0x18cd6000, 0x1000, 0x1000, 0x8056f0c, 0x0, 0x0)
    <autogenerated>:126 +0xae
    bufio.(*Reader).fill(0x1881b7d0)
    /usr/local/go/src/bufio/bufio.go:97 +0x172
    bufio.(*Reader).Peek(0x1881b7d0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0)
    /usr/local/go/src/bufio/bufio.go:132 +0xad
    net/http.(*persistConn).readLoop(0x188976e0)
    /usr/local/go/src/net/http/transport.go:876 +0xe3
    created by net/http.(*Transport).dialConn
    /usr/local/go/src/net/http/transport.go:685 +0xabc

GO程序go program

  package main

 import (
  "bufio"
  "bytes"
  "encoding/json"
  "flag"
  "fmt"
  "net"
  "net/http"
  "time"
  )

  var (
    server             = flag.String("deamon", "127.0.0.1:7070", "AMQP URI")
    msgRoutingKey      = flag.String("routingKey", "routingKey", " routing key")
    msgexchange        = flag.String("exchange", "exchange", " excahnge ")
    mywebserviceServer = flag.String("mywebservice-server", "127.0.0.1:8080",      "mywebserviceServer:port ")
  )

   func init() {

     flag.Parse()
   }

   type TcpConnector struct {
    Outbound      chan string
    Inbound       chan string
    Addr          string
    ReconnectTime time.Duration
   }

type Message struct {
  RoutingKey string `json:"routingKey"`
  Exchange   string `json:"exchange"`
  Data       string `json:"data"`
}

func main() {
  start := time.Now()
  tcpClient := NewTcpConnector(*server)
  elapsed := time.Since(start)
  fmt.Println("the connecting params are  %s", *server, *msgexchange, *msgRoutingKey, *mywebserviceServer)
  fmt.Println("connecting to daemon took %s", elapsed)
   go func() {
    for msg := range tcpClient.Inbound {
        fmt.Println(msg)
        rabbitMessage := Message{
            RoutingKey: *msgRoutingKey,
            Exchange:   *msgexchange,
            Data:       msg,
        }
        mywebserviceMessageEndpoint :=    fmt.Sprintf("http://%s/v1/messages/publish", *mywebserviceServer)
        doPut(mywebserviceMessageEndpoint, &rabbitMessage)

      }
    }()

   select {}
 }

func doPut(url string, rabbitMessage *Message) {
 start := time.Now()
 b, err := json.Marshal(rabbitMessage)
 client := &http.Client{}
 request, err := http.NewRequest("PUT", url, bytes.NewBuffer(b))
 request.Header.Add("Content-Type", "application/json")
 request.Header.Add("accept", "application/json")
 response, err := client.Do(request)
 if err != nil {
    fmt.Println(err)
 } else {
    defer response.Body.Close()
    fmt.Println("   ", response.StatusCode)
    hdr := response.Header
    for key, value := range hdr {
        fmt.Println("   ", key, ":", value)
    }

 }

 elapsed := time.Since(start)
 fmt.Println("posting to mywebservice took %s", elapsed)

}

func NewTcpConnector(addr string) *TcpConnector {
 tcpConnector := &TcpConnector{
    Addr:          addr,
    Outbound:      make(chan string, 100),
    Inbound:       make(chan string, 100),
    ReconnectTime: 30 * time.Second,
 }
 tcpConnector.connect()
 return tcpConnector
}

//keep connect private, will be in trouble if got called twice
func (tcpConnector *TcpConnector) connect() {
 conn, err := net.Dial("tcp", tcpConnector.Addr)
 if err != nil {
    fmt.Println("Failed to make a connection", err)
    time.Sleep(tcpConnector.ReconnectTime)
    tcpConnector.connect()
    return
 }

go func() {
    for msg := range tcpConnector.Outbound {

        _, err = fmt.Fprintf(conn, msg+"\n")
        if err != nil {
            fmt.Println("Failed sending event", err)
            time.Sleep(tcpConnector.ReconnectTime)
            tcpConnector.connect()
            break
        }

    }
}()
go func() {
    reader := bufio.NewReaderSize(conn, 1024*1024)
    for {
        message, err := reader.ReadBytes('\n')
        if err != nil {
            break
        }
        fmt.Println("Message Received: %s", message)
        tcpConnector.Inbound <- string(message)
        fmt.Println("Message sent to chan")
    }

    fmt.Println("reconnecting...")
    tcpConnector.connect()
}()
fmt.Println("Connected tcp")
}

0 个答案:

没有答案