feat: 添加监控仪表盘
- 新增 Lit.js 组件化 UI (ui/ 目录) - tasks-chart: 带十字准星和拖拽选择的图表 - queue-table: 队列列表,支持暂停/恢复 - queue-modal: 队列详情弹窗,支持任务重试 - time-range-picker: Prometheus 风格时间选择器 - help-tooltip: 可复用的提示组件 - HTTPHandler 功能 - SSE 实时推送 (stats + queues) - 队列暂停/恢复 API - 任务重试 API - 时间范围查询 API - Inspector 改进 - Prometheus 风格单表存储 - 集成到 Start/Stop 生命周期 - 新增 PauseQueue/UnpauseQueue/RunTask 方法 - 代码重构 - Start 函数拆分为小函数 - 优雅关闭流程优化 - 其他 - 忽略 SQLite 数据库文件 - example 添加延迟/定点任务示例
This commit is contained in:
@@ -5,6 +5,9 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"code.tczkiot.com/wlw/taskq"
|
||||
@@ -75,8 +78,8 @@ func main() {
|
||||
log.Fatal("注册图片任务失败:", err)
|
||||
}
|
||||
|
||||
// 创建监控处理器
|
||||
handler, err := taskq.NewInspectHandler(taskq.InspectOptions{
|
||||
// 创建监控 HTTP 处理器
|
||||
handler, err := taskq.NewHTTPHandler(taskq.HTTPHandlerOptions{
|
||||
RootPath: "/monitor",
|
||||
ReadOnly: false,
|
||||
})
|
||||
@@ -84,10 +87,16 @@ func main() {
|
||||
log.Fatal("创建监控处理器失败:", err)
|
||||
}
|
||||
|
||||
// 启动 taskq 服务器
|
||||
ctx := context.Background()
|
||||
// 创建可取消的 context
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
// 启动 taskq 服务器(包含统计采集器)
|
||||
go func() {
|
||||
err := taskq.Start(ctx)
|
||||
err := taskq.Start(ctx, taskq.StartOptions{
|
||||
StatsInterval: 2 * time.Second,
|
||||
StatsDBPath: "./taskq_stats.db",
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatal("启动 taskq 服务器失败:", err)
|
||||
}
|
||||
@@ -107,7 +116,7 @@ func main() {
|
||||
case <-ticker.C:
|
||||
taskCounter++
|
||||
|
||||
// 发布邮件任务
|
||||
// 发布即时邮件任务
|
||||
err := emailTask.Publish(ctx, EmailTask{
|
||||
UserID: taskCounter,
|
||||
TemplateID: "welcome",
|
||||
@@ -118,7 +127,29 @@ func main() {
|
||||
log.Printf("发布邮件任务成功: 用户ID=%d", taskCounter)
|
||||
}
|
||||
|
||||
// 发布图片调整任务
|
||||
// 发布延迟任务(30秒后执行)
|
||||
err = emailTask.Publish(ctx, EmailTask{
|
||||
UserID: taskCounter + 1000,
|
||||
TemplateID: "reminder",
|
||||
}, taskq.Delay(30*time.Second))
|
||||
if err != nil {
|
||||
log.Printf("发布延迟邮件任务失败: %v", err)
|
||||
} else {
|
||||
log.Printf("发布延迟邮件任务成功: 用户ID=%d (30秒后执行)", taskCounter+1000)
|
||||
}
|
||||
|
||||
// 发布定点任务(1分钟后的整点执行)
|
||||
scheduledTime := time.Now().Add(1 * time.Minute).Truncate(time.Minute)
|
||||
err = imageTask.Publish(ctx, ImageResizeTask{
|
||||
SourceURL: fmt.Sprintf("https://example.com/scheduled%d.jpg", taskCounter),
|
||||
}, taskq.DelayUntil(scheduledTime))
|
||||
if err != nil {
|
||||
log.Printf("发布定点图片任务失败: %v", err)
|
||||
} else {
|
||||
log.Printf("发布定点图片任务成功: 任务ID=%d (在 %s 执行)", taskCounter, scheduledTime.Format("15:04:05"))
|
||||
}
|
||||
|
||||
// 发布即时图片任务
|
||||
err = imageTask.Publish(ctx, ImageResizeTask{
|
||||
SourceURL: fmt.Sprintf("https://example.com/image%d.jpg", taskCounter),
|
||||
})
|
||||
@@ -131,7 +162,44 @@ func main() {
|
||||
}
|
||||
}()
|
||||
|
||||
// 启动 HTTP 服务器提供监控界面
|
||||
log.Printf("启动监控服务器在 http://localhost:8080")
|
||||
log.Fatal(http.ListenAndServe(":8080", handler))
|
||||
// 创建 HTTP 服务器
|
||||
server := &http.Server{
|
||||
Addr: ":8081",
|
||||
Handler: handler,
|
||||
}
|
||||
|
||||
// 启动 HTTP 服务器(非阻塞)
|
||||
go func() {
|
||||
log.Printf("启动监控服务器在 http://localhost:8081")
|
||||
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||
log.Fatal("HTTP 服务器错误:", err)
|
||||
}
|
||||
}()
|
||||
|
||||
// 等待中断信号
|
||||
quit := make(chan os.Signal, 1)
|
||||
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
|
||||
<-quit
|
||||
|
||||
log.Println("收到关闭信号,正在优雅关停...")
|
||||
|
||||
// 1. 取消 context,停止任务发布
|
||||
cancel()
|
||||
|
||||
// 2. 关闭监控 HTTP 处理器(会断开 SSE 连接)
|
||||
handler.Close()
|
||||
|
||||
// 3. 关闭 HTTP 服务器(设置 5 秒超时)
|
||||
shutdownCtx, shutdownCancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer shutdownCancel()
|
||||
|
||||
if err := server.Shutdown(shutdownCtx); err != nil {
|
||||
log.Printf("HTTP 服务器关闭错误: %v", err)
|
||||
}
|
||||
|
||||
// 4. 停止 taskq 服务器(会等待完全关闭)
|
||||
taskq.Stop()
|
||||
|
||||
log.Println("服务已安全关闭")
|
||||
// rdb.Close() 由 defer 执行
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user