我是Go的新手,编写一个脚本来测试我的网络服务器是否正常运行,如果没有,则会测试mai。除了一个引起我疯狂的琐碎问题外,一切都在工作,尝试了其他地方发布的一些解决方案。
问题是当Web服务器完全关闭但没有回复时,Go正在崩溃:
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x1 addr=0x0 pc=0x40140e]
goroutine 16 [running]:
runtime.panic(0x68b1c0, 0x83bfe2)
c:/go/src/pkg/runtime/panic.c:279 +0x11f
main.httpGET(0x6f0530, 0x15)
httpcheck.go
:57 +0x32e
main.main()
httpcheck.go
:43 +0x3b
goroutine 19 [finalizer wait]:
runtime.park(0x415bb0, 0x840c38, 0x83eda9)
c:/go/src/pkg/runtime/proc.c:1369 +0xac
runtime.parkunlock(0x840c38, 0x83eda9)
c:/go/src/pkg/runtime/proc.c:1385 +0x42
runfinq()
c:/go/src/pkg/runtime/mgc0.c:2644 +0xdd
runtime.goexit()
c:/go/src/pkg/runtime/proc.c:1445
exit status 2
这是我在坠机前所拥有的......
import (
"fmt"
"io/ioutil"
"log"
"net/http"
"github.com/sendgrid/sendgrid-go"
"os"
"time"
"net"
)
var finishedWaiting bool
var timeout = time.Duration(2) * time.Second
var httpClient = http.DefaultClient
func main() {
const url = "http://doesnotexist.com"
httpGET(url)
log.Println("main is running")
}
func httpGET(url string) {
log.Println("httpGet is runnning")
resp, err := httpClient.Get(url)
if err != nil && !doesFileExist("down") {
}
if resp.StatusCode != 200 && !doesFileExist("down") {
isDown()
} else if resp.StatusCode == 200 && doesFileExist("down") {
log.Println("200 response")
sendmail("up")
removeDownFile()
}
}
func sendmail(status string) {
sg := sendgrid.NewSendGridClient("user", "pass")
message := sendgrid.NewMail()
message.AddTo("admin@website.com")
message.AddToName("WebBot")
if status == "down" {
message.SetSubject("Websites Down")
message.SetText("Sites may be down")
} else {
message.SetSubject("Website Up")
message.SetText("Sites are back Up")
}
message.SetFrom("admin@website.com")
if r := sg.Send(message); r == nil {
fmt.Println("Email sent!")
} else {
fmt.Println(r)
}
}
//checks if the file name is present
func doesFileExist(name string) bool {
if _, err := os.Stat(name); err != nil {
if os.IsNotExist(err) {
return false
}
}
return true
}
// write down file
func writeDownFile() {
contents, _ := ioutil.ReadFile("")
ioutil.WriteFile("down", contents, 0x777)
}
//remove down file if server is back up
func removeDownFile() {
os.Remove("down")
}
func sleepForTen() {
log.Println("sleeping for 10.....")
time.Sleep(10000 * time.Millisecond)
finishedWaiting = true
main()
}
func isDown() {
if finishedWaiting != true {
sleepForTen()
} else {
writeDownFile()
log.Println("200 response")
sendmail("down")
}
}
赞赏正确的方向,以帮助我优雅地确定连接是否无法建立。
感谢。
答案 0 :(得分:2)
问题在于您忽略了err
对象。由于此错误,resp
可能为零,当您尝试访问resp.StatusCode
时会导致恐慌。我不确定doesFileExist
的重点是什么,但试试这个:
func httpGET(url string) {
log.Println("httpGet is runnning")
resp, err := httpClient.Get(url)
if err != nil || resp.StatusCode != 200 && !doesFileExist("down") {
isDown()
} else if resp.StatusCode == 200 && doesFileExist("down") {
log.Println("200 response")
sendmail("up")
removeDownFile()
}
}
答案 1 :(得分:0)
即使Get返回错误,您也会尝试检查resp.StatusCode
。 http.Response
在这种情况下无效,可能为零,或者包含nil指针,因此您无法使用它。
答案 2 :(得分:-1)
如果get
发生错误,您只需继续执行该程序即可。难怪resp
将会迟到。
这只是猜测,因为我们只能猜测行数。