#http #go #concurrency
#http #Вперед #параллелизм
Вопрос:
func serveApp() {
mux := http.NewServeMux()
mux.HandleFunc("/", func(resp http.ResponseWriter, req *http.Request) {
fmt.Fprintln(resp, "Hello, QCon!")
})
http.ListenAndServe("0.0.0.0:8080", mux)
}
func serveDebug() {
http.ListenAndServe("127.0.0.1:8001", http.DefaultServeMux)
}
func main() {
go serveDebug()
serveApp()
}
Однако serveDebug запускается в отдельной подпрограмме, и если она возвращает
только эта подпрограмма завершится, пока остальная часть программы будет продолжаться
вкл. Ваш операционный персонал не будет рад обнаружить, что они не могут
извлекайте статистику из своего приложения, когда они этого хотят, потому что
обработчик /debug перестал работать давным-давно.
Я новичок в Golang и кодировании в целом. Я наткнулся на статью в Интернете и нашел этот код. Я копирую и вставляю его в свой редактор и набираю go run main.go. Программа работает вечно без каких-либо ошибок. Я могу свернуть его без проблем. Почему это плохой код? Я новичок, и я пытаюсь лучше понять это, если бы это можно было объяснить простыми словами, это было бы здорово.
Ответ №1:
Программа создает два HTTP-сервера для ответа на трафик, полученный на разные порты. Сервер отладки запускается в отдельной подпрограмме, и нет способа определить, произошел ли сбой на этом сервере. Программа может продолжать работать с сервером приложений.
Лучшей реализацией было бы остановить оба сервера, если один из них вышел из строя:
stop:=make(chan struct{},2)
go func() {
defer func() {
stop<-struct{}{}
}()
serveDebug()
}()
go func() {
defer func() {
stop <-struct{}{}
}{}
serveApp()
}()
<-stop
Выше программа создаст две подпрограммы и заблокирует <-stop
до тех пор, пока кто-нибудь не запишет в канал. Если какой-либо из серверов выйдет из строя, подпрограмма запишет на канал, который разблокируется <-stop
, поэтому программа завершит работу.
Комментарии:
1. Это приводит к панике с «закрытием закрытого канала», если оба сервера выходят из строя (или остановлены), особенно если оператор receive не является концом main (но даже тогда это гонка). Я бы использовал
make(chan error, 2)
и отправил ошибку, возвращенную ListenAndServe, вместо закрытия канала.2. @Peter как это гонка? Я немного сбит с толку.
3. @user2648117, если оба сервера выходят из строя в течение достаточно короткого времени друг от друга (например, из-за того, что пользователю не разрешено запускать серверы на привилегированных портах), два оператора close могут выполняться до завершения работы приложения, и это вызывает панику.