Golang API服务运行数小时后停止监听的解决方法
Golang API服务运行数小时后停止监听的解决方法 大家好,
我有一个为我的安卓应用提供服务的Golang API服务器,它运行在我们的AWS空间。 我启动应用后,服务器最多运行5到6小时就会自动停止。
有时我在终端中看到这条信息: Connection reset by 13.***.***.11 port 22。
有时终端中没有任何显示。
这个问题已经持续几周了,我虽然完成了API开发,但由于这个问题无法部署。
请提供解决方案。
连接被 13.**.**.11 端口 22 重置。
这条消息是来自你的程序、标准库还是 panic?同时在你的程序中记录操作日志,以找到程序挂起点的更多细节。
更多关于Golang API服务运行数小时后停止监听的解决方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
感谢您的帮助……我现在明白了应该使用服务在后台运行应用程序。
我对这种服务器端执行还比较陌生。我有使用 Node 的经验,通常使用框架来运行应用程序。Go 语言有类似的框架吗?
如果没有的话,我应该使用 Docker 吗?
由于您没有说明在 Node.js 中使用了哪个框架,我们无法告知 Go 语言中是否有类似的框架。但我可以告诉您,Go 语言确实有用于创建 Web 应用程序或 JSON API 的框架。
您需要自行搜索相关信息。
但即使使用了框架,您仍然需要正确部署应用程序。
在 Node.js 中情况也应该没什么不同,那里同样需要运行服务…
你在终端中看到这个吗?
你是怎么运行那个服务器的?
听起来好像你是通过 ssh 连接到服务器并在 ssh 会话中启动你的应用程序。如果你真的这样做,那么你的应用程序将作为你 ssh 会话中启动的 shell 的子进程运行,一旦会话结束,它的子进程也会随之终止。
请使用适当的 systemd 单元或其他系统服务描述来管理应用程序的启动和停止。
这是一个典型的连接资源泄漏问题,很可能是由于未正确管理HTTP连接或goroutine泄漏导致的。以下是几种可能的解决方案:
1. 配置HTTP服务器超时设置
package main
import (
"context"
"net/http"
"time"
)
func main() {
server := &http.Server{
Addr: ":8080",
ReadTimeout: 15 * time.Second,
WriteTimeout: 15 * time.Second,
IdleTimeout: 60 * time.Second,
MaxHeaderBytes: 1 << 20,
}
// 你的路由设置
http.HandleFunc("/api", yourAPIHandler)
if err := server.ListenAndServe(); err != nil {
panic(err)
}
}
2. 使用http.CloseNotifier检测断开连接
func yourAPIHandler(w http.ResponseWriter, r *http.Request) {
cn, ok := w.(http.CloseNotifier)
if !ok {
http.Error(w, "Cannot stream", http.StatusInternalServerError)
return
}
// 监听客户端断开连接
closeNotify := cn.CloseNotify()
go func() {
<-closeNotify
// 清理资源
fmt.Println("Client disconnected")
}()
// 你的业务逻辑
w.Write([]byte("Response"))
}
3. 实现连接池和连接复用
import (
"net"
"net/http"
"time"
)
func createHTTPClient() *http.Client {
return &http.Client{
Transport: &http.Transport{
MaxIdleConns: 100,
MaxIdleConnsPerHost: 100,
IdleConnTimeout: 90 * time.Second,
DialContext: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}).DialContext,
TLSHandshakeTimeout: 10 * time.Second,
},
Timeout: time.Second * 30,
}
}
4. 使用context管理请求生命周期
func yourAPIHandler(w http.ResponseWriter, r *http.Request) {
ctx, cancel := context.WithTimeout(r.Context(), 30*time.Second)
defer cancel()
// 在goroutine中使用context
done := make(chan bool)
go func() {
select {
case <-ctx.Done():
// 超时或取消
return
case <-done:
// 正常完成
}
}()
// 你的业务逻辑
// ...
close(done)
}
5. 添加健康检查和监控
func healthCheckHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
w.Write([]byte(`{"status": "healthy"}`))
}
func main() {
http.HandleFunc("/health", healthCheckHandler)
http.HandleFunc("/api", yourAPIHandler)
// 定期检查goroutine数量
go func() {
ticker := time.NewTicker(5 * time.Minute)
defer ticker.Stop()
for range ticker.C {
// 记录监控指标
fmt.Printf("Goroutines: %d\n", runtime.NumGoroutine())
}
}()
log.Fatal(http.ListenAndServe(":8080", nil))
}
6. 完整的服务器配置示例
package main
import (
"log"
"net/http"
"os"
"os/signal"
"syscall"
"time"
)
func main() {
server := &http.Server{
Addr: ":8080",
Handler: nil, // 设置你的路由
ReadTimeout: 15 * time.Second,
WriteTimeout: 15 * time.Second,
IdleTimeout: 60 * time.Second,
}
// 优雅关闭
stop := make(chan os.Signal, 1)
signal.Notify(stop, os.Interrupt, syscall.SIGTERM)
go func() {
log.Println("Server starting on :8080")
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("Server failed: %v", err)
}
}()
<-stop
log.Println("Shutting down server...")
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
if err := server.Shutdown(ctx); err != nil {
log.Printf("Server shutdown failed: %v", err)
}
log.Println("Server stopped")
}
主要关注点应该是HTTP服务器的超时配置和资源管理。Connection reset by port 22错误通常表示SSH连接问题,可能与你的服务器监控或部署流程有关,但核心问题很可能是应用程序层面的连接管理。

