Golang站点维护通知:9月10日至12日停机公告
Golang站点维护通知:9月10日至12日停机公告 我将在接下来几天(9月10日、11日和12日)进行网站维护。
在这几天里,网站可能会随机不可用,因为我会对Discourse、数据库以及底层实例进行一系列升级和调整。
我会尽可能在维护时显示维护页面,但可能无法每次都做到。
谢谢。
3 回复
感谢您对网站的维护以及提前告知!
在此期间,我们只能暂时使用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

