Files
sese-engine-go/main.go
T

109 lines
3.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// sese-engine — Go rewrite
// Go 版 sese-engine:个人搜索引擎的主入口文件。
//
// 所有模块(爬虫、收获服务器、搜索服务器、反向链接计算)均作为 goroutine 在同一进程中启动。
// 主线程阻塞等待系统信号(Ctrl-C / SIGTERM),收到后优雅退出。
//
// 运行方式:
//
// cd golang && go run . [--storage ./savedata] [--entry https://zh.wikipedia.org/]
package main
import (
"flag" // 命令行参数解析
"fmt" // 格式化(搜索服务端口)
"log" // 日志输出
"os" // 操作系统信号
"os/signal" // 信号捕获
"syscall" // 系统调用(SIGTERM
"time" // 定期刷盘定时器
"sese-engine/analyzer" // 文本分析和关键词提取
"sese-engine/backlink" // 反向链接(繁荣值)计算
"sese-engine/config" // 全局配置
"sese-engine/crawler" // BFS 爬虫
"sese-engine/harvester" // 收获服务器(索引写入)
"sese-engine/info" // info 服务(繁荣表、调整表、屏蔽词)
"sese-engine/search" // 搜索服务器
"sese-engine/storage" // 持久化存储
)
func main() {
// ---- 命令行参数 ----
// --storage:存储根目录路径,默认使用 config.StoragePath
storageDir := flag.String("storage", config.StoragePath, "path to savedata directory")
// --entryBFS 爬取的起始 URL,默认使用 config.EntryURL(维基百科中文首页)
entryURL := flag.String("entry", config.EntryURL, "BFS crawl entry URL")
// --stopwords:屏蔽词 JSON 文件路径
stopWords := flag.String("stopwords", "../data/标点符号.json", "path to stop-words JSON")
flag.Parse()
// 设置日志格式:时间戳 + 短文件名
log.SetFlags(log.LstdFlags | log.Lshortfile)
log.Printf("sese-engine starting storage=%s entry=%s", *storageDir, *entryURL)
// ---- 1. 存储层:打开 bbolt 数据库 ----
db, err := storage.Open(*storageDir)
if err != nil {
log.Fatalf("failed to open storage: %v", err)
}
defer db.Close()
// ---- 2. Info 服务:加载繁荣表、调整表和屏蔽词 ----
infoSvc := info.New(*storageDir)
// ---- 3. Analyzer:初始化分词器和语言检测器 ----
// modelPath 参数已废弃(lingua-go 使用内置模型,无需外部文件)
anal, err := analyzer.New("", *stopWords)
if err != nil {
log.Fatalf("failed to init analyzer: %v", err)
}
defer anal.Close()
// ---- 4. 收获服务器(:5000):接收爬虫发来的索引数据 ----
harvSrv := harvester.New(db, infoSvc)
go func() {
if err := harvSrv.ListenAndServe(":5000"); err != nil {
log.Fatalf("[harvester] fatal: %v", err)
}
}()
// ---- 4b. 定期刷盘:每 60 秒强制将内存索引写入磁盘,确保搜索实时可用 ----
go func() {
ticker := time.NewTicker(60 * time.Second)
defer ticker.Stop()
for range ticker.C {
harvSrv.Flush()
}
}()
// ---- 5. 搜索服务器(默认 :80):对外提供搜索 API ----
searchSrv := search.New(db, infoSvc, anal, "http://localhost:5000")
go func() {
addr := fmt.Sprintf(":%d", config.SearchServerPort)
if err := searchSrv.ListenAndServe(addr); err != nil {
log.Fatalf("[search] fatal: %v", err)
}
}()
// ---- 6. 反向链接计算器:每 48 小时运行一次 ----
bl := backlink.New(db, *storageDir)
go bl.Run()
// ---- 7. 爬虫:从入口 URL 开始 BFS 爬取 ----
// 从 info 服务获取繁荣表快照,用于调度优先级决策
prosperMap := infoSvc.ProsperMap()
crawl := crawler.New(db, anal, prosperMap)
go crawl.Run(*entryURL, config.MaxEpoch)
log.Println("all modules started — press Ctrl-C to stop")
// ---- 优雅退出 ----
// 阻塞等待 SIGINTCtrl-C)或 SIGTERM 信号
quit := make(chan os.Signal, 1)
signal.Notify(quit, os.Interrupt, syscall.SIGTERM)
<-quit
log.Println("shutdown signal received, flushing index...")
harvSrv.Flush() // 退出前刷盘,不丢数据
}