英文:
Deployed application shuts itself down immediately
问题
我有一个Go的REST API应用程序。我将其Docker化并部署到Kubernetes上。
在我的本地环境中,它按预期工作。
但是在Kubernetes中,应用程序会自行关闭,并重新启动Pod。
它不会打印任何内容、日志或失败信息。
import (
"github.com/gorilla/mux"
"net/http"
"log"
)
func main() {
controller := controllers.Controllers{}
router := mux.NewRouter()
router.HandleFunc("/customer", controller.GetCustomer()).Methods("GET")
router.HandleFunc("/customer", controller.InsertCustomer()).Methods("POST")
router.HandleFunc("/healthcheck", controller.HealthCheck())
addr := ":" + os.Getenv("PORT")
srv := &http.Server{Addr: addr, Handler: router}
go func() {
if err := srv.ListenAndServe(); err != nil {
log.Fatalf("listenAndServe failed: %v", err)
}
}()
println("reached here")
}
令人惊讶的是,当我查看日志时,它会打印出"reached here"这一行。
我检查了env
变量,它也是正确的。
我怀疑调用listenAndServe
失败了,但我找不到一个合理的答案。
英文:
I have a Go rest API application. And I Dockerized it and deployed it to Kubernetes.
It is working as it should on my local.
But in Kubernetes, the application shuts down itself, and the pod is restarted.
It doesn't print anything, any log, or any fail.
import (
" github.com/gorilla/mux"
"net/http"
"log"
)
func main() {
controller := controllers.Controllers{}
router := mux.NewRouter()
router.HandleFunc("/customer", controller.GetCustomer()).Methods("GET")
router.HandleFunc("/customer", controller.InsertCustomer()).Methods("POST")
router.HandleFunc("/healthcheck", controller.HealthCheck())
addr := ":" + os.Getenv("PORT")
srv := &http.Server{Addr: addr, Handler: router}
go func() {
if err := srv.ListenAndServe(); err != nil {
log.Fatalf("listenAndServe failed: %v", err)
}
}()
println("reached here")
}
Surprisingly it prints the "reached here" line when I look at the logs.
I checked the env
variable, and it is also correct.
I suspect that the call to listenAndServe
fails, but I couldn't find a reasonable answer for that.
答案1
得分: 4
当main()
函数结束时,你的应用程序也会结束。它不会等待其他非main
的goroutine完成。参见规范:程序执行
程序的执行从初始化主包开始,然后调用函数
main
。当该函数调用返回时,程序退出。它不会等待其他(非main
)的goroutine完成。
由于你在一个新的goroutine中启动了监听器,所以没有什么阻塞main()
的东西,没有其他事情可做(在打印"reached here"
之后),所以你的应用程序结束了。请注意,内置的println()
函数打印到标准错误输出,这就是为什么你可能看不到任何日志(标准输出和标准错误输出可能保存/重定向到不同的位置)。
最简单的“修复”方法是在main()
函数中开始监听:
srv := &http.Server{Addr: addr, Handler: router}
if err := srv.ListenAndServe(); err != nil {
log.Fatalf("listenAndServe failed: %v", err)
}
英文:
When the main()
function ends, your app ends as well. It does not wait for other non-main goroutines to finish. See Spec: Program execution:
> Program execution begins by initializing the main package and then invoking the function main
. When that function invocation returns, the program exits. It does not wait for other (non-main
) goroutines to complete.
Since you start the listerer in a new goroutine, there's nothing "blocking" main()
, there's nothing left to do (after printing "reached here"
), so your app ends. Note that the builtin println()
prints to the standard error, that's why you may not see any logs (standard output and standard error may be saved / redirected to different places).
The easiest "fix" is to start listening in main()
:
srv := &http.Server{Addr: addr, Handler: router}
if err := srv.ListenAndServe(); err != nil {
log.Fatalf("listenAndServe failed: %v", err)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论