2012-06-10 3 views
19

나는 Go로 작성된 http 서버를 설치했으며 하루에 천 명이 넘는 방문자가 발생했습니다. 나는 누적되는 Goroutine 문제를 가지고있다. 하루 동안 나는 http 서버에서 천 개 이상의 새로운 Goroutines를 얻는 것처럼 보입니다.Golang : 오픈 goroutines를 남겨둔 http 서버

어떻게 처리기를 망칠 수 있는지 잘 모르겠습니다.

http.Handle("/", http.FileServer(http.Dir(config.htdocs_path))) 

다음은 연결이 읽기 상태에 갇혀지고 것 같다 스택

goroutine 1582 [chan receive]: 
net.(*pollServer).WaitRead(0xf84007f680, 0xf84066dea0, 0xf84007aa80, 0xb, 0x1, ...) 
     /home/ec2-user/go/src/pkg/net/fd.go:268 +0x73 
net.(*netFD).Read(0xf84066dea0, 0xf840ec1000, 0x100000001000, 0x7f7effffffff, 0xf84007c0f0, ...) 
     /home/ec2-user/go/src/pkg/net/fd.go:428 +0x1ec 
net.(*TCPConn).Read(0xf84068aff8, 0xf840ec1000, 0x100000001000, 0xf800000002, 0x0, ...) 
     /home/ec2-user/go/src/pkg/net/tcpsock_posix.go:87 +0xce 
io.(*LimitedReader).Read(0xf840d1bc20, 0xf840ec1000, 0x100000001000, 0xdcb00000000, 0x0, ...) 
     /home/ec2-user/go/src/pkg/io/io.go:394 +0xc1 
bufio.(*Reader).fill(0xf8405b0900, 0xdcb00000000) 
     /home/ec2-user/go/src/pkg/bufio/bufio.go:77 +0xf0 
bufio.(*Reader).ReadSlice(0xf8405b0900, 0xf840d1bc0a, 0x0, 0x0, 0x0, ...) 
     /home/ec2-user/go/src/pkg/bufio/bufio.go:257 +0x1b6 
bufio.(*Reader).ReadLine(0xf8405b0900, 0x0, 0x0, 0x0, 0x0, ...) 
     /home/ec2-user/go/src/pkg/bufio/bufio.go:283 +0x5b 
net/textproto.(*Reader).readLineSlice(0xf840730660, 0xc0, 0x100000000, 0x7f7e00000001) 
     /home/ec2-user/go/src/pkg/net/textproto/reader.go:55 +0x4f 
net/textproto.(*Reader).ReadLine(0xf840730660, 0xf84061f300, 0x0, 0x48411c) 
     /home/ec2-user/go/src/pkg/net/textproto/reader.go:36 +0x25 
net/http.ReadRequest(0xf8405b0900, 0xf84061f300, 0x0, 0x0, 0x100000400ccf60, ...) 
     /home/ec2-user/go/src/pkg/net/http/request.go:457 +0xb1 
net/http.(*conn).readRequest(0xf8402b2b40, 0xf8400e3fc0, 0x0, 0x0, 0xf8405b0a80, ...) 
     /home/ec2-user/go/src/pkg/net/http/server.go:240 +0xa8 
net/http.(*conn).serve(0xf8402b2b40, 0x0) 
     /home/ec2-user/go/src/pkg/net/http/server.go:594 +0x145 
created by net/http.(*Server).Serve 
     /home/ec2-user/go/src/pkg/net/http/server.go:1040 +0x430 

에서 goroutines 중 하나입니다. http 서버와 마찬가지로 시간을 정하지 않습니다. 기본 서버에 읽기 시간 초과가 있습니까? 모든 goroutines 읽고있는

이동 버전 go1

답변

54

이유는 연결 유지한다. 브라우저가 연결 유지 헤더를 보내면 서버는 더 많은 요청을 받아들이도록 연결을 유지합니다. 이것은 클라이언트가 많은 작은 파일을 요청하고 TCP 연결이 중요한 오버 헤드 일 때 좋은 일입니다. 읽기 시간 제한은 요청간에 일정 시간 이상 연결이 유지되지 않도록합니다. 이렇게하면 활성 연결을 유지할 수 있지만 누군가가 시간 초과보다 오랫동안 업로드하지 못하게됩니다. 불행하게도, keep-alive 특정 타임 아웃 옵션은 아직 없습니다.

기본적으로 시간 제한은 없습니다. 당신은 http://golang.org/pkg/net/http/#Server

srv := &http.Server{ 
    Handler: http.FileServer(http.Dir(config.htdocs_path)), 
    ReadTimeout: 30*time.Second, 
} 
srv.ListenAndServe() 
+0

감사합니다. 이번 주에 업데이트를 시도해 보겠습니다. :-) – Daniel

+1

그래, 고쳐 줬어. 감사! – Daniel

+0

답변으로 표시 할 수 있습니까? 감사합니다 –

0

는 HTTP 연결에 ReadTimeout 및 WriteTimeout 사용에 대한주의 서버 구조체에 시간 제한을 설정할 수 있습니다. 나는 그들이 당신이 기대하는대로한다고 생각하지 않습니다. 특히 연결을 닫지 않고 사용할 수없는 상태로 연결을 유지하는 경향이 있습니다. 자세한 내용은 https://groups.google.com/forum/#!topic/golang-nuts/oBIh_R7-pJQ을 참조하십시오. 특히 ReadTimeout이 연결을 사용할 수 없게 만들고 HTTP 처리기 시간이 시간 초과를 초과하면 응답을 바닥에 떨어 뜨리는 경우가 있습니다. 시간 제한을 어떤 핸들러의 응답 시간을 초과하는 큰 값으로 설정하면 OK 일 수 있습니다.

0

스티븐의 대답은 다음과 결합해서 만 저에게 효과적이었습니다. 서버는 고객에게 연결을 열어두기를 원하지 않는다고 말할 수 있다고 말합니다. 이렇게하려면 제공하기 전에 따라 플래그를 설정 :

server := &http.Server{ 
    // ... see Stephen's answer 
} 
server.SetKeepAlivesEnabled(false) 
server.ListenAndServe() 

이 그들의 편에서 연결을 종료합니다 응답 헤더 Connection: close가장 클라이언트를 설정합니다.