Golang站点维护通知:9月10日至12日停机公告

Golang站点维护通知:9月10日至12日停机公告 我将在接下来几天(9月10日、11日和12日)进行网站维护。

在这几天里,网站可能会随机不可用,因为我会对Discourse、数据库以及底层实例进行一系列升级和调整。

我会尽可能在维护时显示维护页面,但可能无法每次都做到。

谢谢。

3 回复

维护已完成

更多关于Golang站点维护通知:9月10日至12日停机公告的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


感谢您对网站的维护以及提前告知!

在此期间,我们只能暂时使用Reddit了!

这是一个标准的维护通知,直接使用Go的net/http包即可实现维护页面的显示。以下是一个简单的示例,它会在维护期间拦截所有请求并返回503状态码和维护信息。

package main

import (
    "net/http"
    "time"
)

// 维护时间段定义
var maintenanceStart = time.Date(2024, 9, 10, 0, 0, 0, 0, time.UTC)
var maintenanceEnd = time.Date(2024, 9, 13, 0, 0, 0, 0, time.UTC)

// 维护中间件
func maintenanceMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        now := time.Now().UTC()
        
        // 检查当前是否在维护时间段内
        if now.After(maintenanceStart) && now.Before(maintenanceEnd) {
            w.Header().Set("Retry-After", "3600") // 建议1小时后重试
            w.WriteHeader(http.StatusServiceUnavailable)
            w.Write([]byte(`
                <!DOCTYPE html>
                <html>
                <head>
                    <title>系统维护中</title>
                    <style>
                        body { 
                            font-family: Arial, sans-serif; 
                            text-align: center; 
                            padding: 50px; 
                        }
                        .container { 
                            max-width: 600px; 
                            margin: 0 auto; 
                        }
                    </style>
                </head>
                <body>
                    <div class="container">
                        <h1>🚧 系统维护中</h1>
                        <p>网站正在进行计划性维护(9月10日至12日)</p>
                        <p>预计完成时间:9月13日 00:00 UTC</p>
                        <p>给您带来的不便,敬请谅解。</p>
                    </div>
                </body>
                </html>
            `))
            return
        }
        
        // 非维护时间,正常处理请求
        next.ServeHTTP(w, r)
    })
}

func mainHandler(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("网站正常运行中"))
}

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/", mainHandler)
    
    // 应用维护中间件
    handler := maintenanceMiddleware(mux)
    
    http.ListenAndServe(":8080", handler)
}

对于数据库升级操作,这里有一个简单的数据库迁移示例:

package main

import (
    "database/sql"
    "fmt"
    "log"
    _ "github.com/lib/pq"
)

func performDatabaseMigration(db *sql.DB) error {
    // 示例:添加新表
    _, err := db.Exec(`
        CREATE TABLE IF NOT EXISTS maintenance_logs (
            id SERIAL PRIMARY KEY,
            maintenance_date TIMESTAMP NOT NULL,
            description TEXT,
            duration_minutes INT
        )
    `)
    if err != nil {
        return fmt.Errorf("创建表失败: %v", err)
    }

    // 示例:修改现有表结构
    _, err = db.Exec(`
        ALTER TABLE users 
        ADD COLUMN IF NOT EXISTS last_maintenance_notice TIMESTAMP
    `)
    if err != nil {
        return fmt.Errorf("修改表结构失败: %v", err)
    }

    return nil
}

func main() {
    // 数据库连接
    connStr := "user=postgres dbname=mydb sslmode=disable"
    db, err := sql.Open("postgres", connStr)
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()

    // 执行迁移
    if err := performDatabaseMigration(db); err != nil {
        log.Fatalf("数据库迁移失败: %v", err)
    }
    
    fmt.Println("数据库迁移完成")
}

如果需要更精确的控制,可以结合配置文件和命令行参数来动态控制维护模式:

package main

import (
    "flag"
    "net/http"
    "os"
)

var maintenanceMode = flag.Bool("maintenance", false, "启用维护模式")

func main() {
    flag.Parse()
    
    mux := http.NewServeMux()
    
    if *maintenanceMode {
        mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
            w.WriteHeader(http.StatusServiceUnavailable)
            w.Write([]byte("系统维护中,请稍后再访问"))
        })
    } else {
        mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
            w.Write([]byte("欢迎访问网站"))
        })
    }
    
    port := os.Getenv("PORT")
    if port == "" {
        port = "8080"
    }
    
    http.ListenAndServe(":"+port, mux)
}

运行方式:

# 正常模式
go run main.go

# 维护模式
go run main.go --maintenance=true
回到顶部