如何在VPS Windows Server上部署Golang

如何在VPS Windows Server上部署Golang 我使用Go运行一个Web应用程序,我的代码运行正常,但在CMD中运行2到3小时后,我收到这个错误并且服务器停止了。

操作系统:Windows Server 2012 R2 Standard

C:\Users\Administrator\Desktop\Go\vt>go run main.go Service is running 2020/04/06 23:17:59 write tcp (我的服务器IP):8080->(奇怪的IP): wsasend: 您主机中的软件中止了一个已建立的连接。 exit status 1

这是我的代码:

Go Playground - The Go Programming Language

我的 index.html:

Edit fiddle - JSFiddle - Code Playground


更多关于如何在VPS Windows Server上部署Golang的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

请使用以下行(作为第一行)来让日志记录器输出产生错误的行。

log.SetFlags(log.LstdFlags | log.Lshortfile)

更多关于如何在VPS Windows Server上部署Golang的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Newbei:

Edit fiddle - JSFiddle - Code Playground

缺少一个结束标签:</a>

Edit fiddle - JSFiddle - Code Playground

HTTP 错误可能导致关闭。

这个错误通常是由于客户端异常断开连接导致的,但服务器不应该因此崩溃。以下是几种解决方案:

1. 添加连接错误处理

修改你的HTTP服务器代码,添加连接状态的错误处理:

package main

import (
    "fmt"
    "log"
    "net/http"
    "time"
)

func main() {
    // 创建自定义的HTTP服务器,配置连接参数
    server := &http.Server{
        Addr: ":8080",
        Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            // 设置超时时间
            r.Context().Done()
            http.ServeFile(w, r, "index.html")
        }),
        ReadTimeout:    10 * time.Second,
        WriteTimeout:   10 * time.Second,
        IdleTimeout:    30 * time.Second,
        MaxHeaderBytes: 1 << 20,
    }

    fmt.Println("Service is running on port 8080")
    
    // 启动服务器并处理错误
    if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
        log.Printf("Server error: %v\n", err)
    }
}

2. 使用goroutine恢复panic

添加全局的panic恢复机制:

package main

import (
    "fmt"
    "log"
    "net/http"
    "runtime/debug"
)

func main() {
    // 创建带panic恢复的handler
    handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        defer func() {
            if err := recover(); err != nil {
                log.Printf("Recovered from panic: %v\n%s", err, debug.Stack())
                http.Error(w, "Internal Server Error", http.StatusInternalServerError)
            }
        }()
        
        http.ServeFile(w, r, "index.html")
    })

    fmt.Println("Service is running on port 8080")
    
    if err := http.ListenAndServe(":8080", handler); err != nil {
        log.Printf("Server failed: %v\n", err)
    }
}

3. 生产环境部署建议

对于Windows Server生产环境,建议:

package main

import (
    "context"
    "fmt"
    "log"
    "net/http"
    "os"
    "os/signal"
    "syscall"
    "time"
)

func main() {
    // 创建文件日志
    logFile, err := os.OpenFile("server.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0666)
    if err != nil {
        log.Fatal(err)
    }
    defer logFile.Close()
    
    log.SetOutput(logFile)
    
    server := &http.Server{
        Addr: ":8080",
        Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            http.ServeFile(w, r, "index.html")
        }),
        ReadTimeout:  15 * time.Second,
        WriteTimeout: 15 * time.Second,
        IdleTimeout:  60 * time.Second,
    }

    // 优雅关闭
    done := make(chan bool, 1)
    quit := make(chan os.Signal, 1)
    signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)

    go func() {
        <-quit
        log.Println("Server is shutting down...")
        
        ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
        defer cancel()
        
        if err := server.Shutdown(ctx); err != nil {
            log.Fatalf("Could not gracefully shutdown the server: %v\n", err)
        }
        close(done)
    }()

    fmt.Println("Service is running on port 8080")
    log.Println("Server started on port 8080")
    
    if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
        log.Fatalf("Could not listen on port 8080: %v\n", err)
    }
    
    <-done
    log.Println("Server stopped")
}

4. 编译为可执行文件运行

不要使用go run,而是编译后运行:

# 编译
go build -o myserver.exe main.go

# 运行
myserver.exe

5. 创建Windows服务

使用sc命令创建Windows服务:

# 安装为服务
sc create MyGoWebService binPath= "C:\path\to\myserver.exe" start= auto

# 启动服务
sc start MyGoWebService

主要问题是你的服务器没有正确处理客户端异常断开连接的情况。第一种方案添加了连接超时设置,第二种方案添加了panic恢复机制,第三种方案是完整的生产环境部署方案。建议使用第三种方案,并编译为可执行文件运行。

回到顶部