# ainews_server **Repository Path**: fourzkw/ainews_server ## Basic Information - **Project Name**: ainews_server - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-10-20 - **Last Updated**: 2026-10-21 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # ainews-api TrendRadar 的只读薄 API。Go、单二进制、无 CGO,只读 TrendRadar 产出的 SQLite 库, 给 Android App(以及任何 HTTP 客户端)提供 JSON。 ``` TrendRadar 容器 ──写──► /www/wwwroot/TrendRadar/output/news/YYYY-MM-DD.db │ 只读 ▼ ainews-api (127.0.0.1:8090) │ ▼ Nginx /api/ ──► App ``` ## 1. 本地开发 ```bash # 生成一天的假数据(11 个平台 × 8 条 × 9 个快照) go run ./cmd/mkdemo -out ../.tmp/demo-data -date 2026-10-20 # 起服务 go run . -addr 127.0.0.1:8090 -data ../.tmp/demo-data ``` 或编译成单文件: ```bash go build -o ../dist/ainews-api . ``` > 本机沙箱里 Go 的默认缓存在用户目录不可写,需要用工作区内的目录: > `GOPATH=D:\_Project\AInews\.gopath`、`GOCACHE=D:\_Project\AInews\.gocache`、 > `GOPROXY=https://goproxy.cn,direct`。 ## 2. 配置 全部走 flag / 环境变量,二选一(flag 优先): | flag | 环境变量 | 默认值 | 说明 | |---|---|---|---| | `-addr` | `ADDR` | `127.0.0.1:8090` | 监听地址,只绑本机,公网由 Nginx 代理 | | `-data` | `DATA_DIR` | `/www/wwwroot/TrendRadar/output` | TrendRadar 的 output 目录 | | `-key` | `API_KEY` | 空 | 非空时要求 `X-API-Key` 或 `?key=` | `-data` 指向的是 **容器挂载出来的宿主机目录**,不是容器内的 `/app/output`。 ## 3. 接口 统一响应体:`{"code":0,"message":"ok","data":...,"ts":"2026-10-20T22:31:31.646+08:00"}` | 方法 | 路径 | 参数 | 说明 | |---|---|---|---| | GET | `/api/health` | – | 存活 + 数据目录状态(免鉴权) | | GET | `/api/meta` | `date?` | 当天统计:总条数、最新抓取时间、平台条数、可用日期 | | GET | `/api/hotlist` | `date?` `platform?` `limit?` `offset?` | 榜单条目(`platform=all` 或留空=全部) | | GET | `/api/items/{id}` | `date?` | 单条详情:排名轨迹 `rankPoints` + 跨平台命中 `platformHits` | | GET | `/api/trends` | `date?` `limit?` | 涨幅榜(按 `rankDelta` 倒序) | | GET | `/api/search` | `q` `date?` `limit?` | 标题模糊搜索 | | GET | `/api/rss/meta` | `date?` | RSS 当天统计:条数、最新抓取时间、每个源条数、可用日期 | | GET | `/api/rss` | `date?` `feed?` `limit?` `offset?` | RSS 条目(`feed=all` 或留空=全部源,按发布时间倒序) | | GET | `/api/brief` | `date?` | 当天 AI 简报(从最新 HTML 报告解析五个板块;无分析时返回 `available:false` + `status`) | `date` 省略时取最新一天。时间字段统一返回 `"2026-10-20 17:00:00"`(本地时间,无时区后缀)。 新闻库在 `output/news/{date}.db`,RSS 库在 `output/rss/{date}.db`,接口会自动各取所需。 ```bash curl -s 'http://127.0.0.1:8090/api/hotlist?platform=zhihu&limit=3' | jq curl -s 'http://127.0.0.1:8090/api/items/2?date=2026-10-20' | jq '.data.rankPoints' curl -s 'http://127.0.0.1:8090/api/rss?feed=ruanyifeng&limit=2' | jq ``` ## 4. 部署到服务器(与 TrendRadar 同机) ```bash # 1) 二进制(本机交叉编译或服务器上 go build) GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -trimpath -ldflags '-s -w' -o ainews-api . # 2) 上传 scp ainews-api root@<服务器>:/opt/ainews-api/ainews-api scp deploy/ainews-api.service root@<服务器>:/etc/systemd/system/ # 3) 建运行用户 + 目录 useradd --system --no-create-home --shell /usr/sbin/nologin ainews mkdir -p /etc/ainews-api printf 'DATA_DIR=/www/wwwroot/TrendRadar/output\nADDR=127.0.0.1:8090\n' > /etc/ainews-api/env # 4) 起服务 chmod +x /opt/ainews-api/ainews-api systemctl daemon-reload systemctl enable --now ainews-api systemctl status ainews-api --no-pager # 5) 验收 curl -s http://127.0.0.1:8090/api/health | jq curl -s http://127.0.0.1:8090/api/meta | jq journalctl -u ainews-api -n 50 --no-pager ``` Nginx 前面挂一层(复用宝塔已建的站点即可): ```nginx location /api/ { proxy_pass http://127.0.0.1:8090; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } ``` ### 4.1 直接用仓库里的预编译二进制(推荐,服务器不编译) `prebuilt/` 目录里放了 linux/amd64 的成品二进制(Go 1.27 构建、无 CGO), 服务器只需要 `git pull` + 复制,**不装 Go、不编译、不会再卡死**: ```bash cd /www/wwwroot/ainews_server git pull --ff-only # 可选:校验完整性 (cd prebuilt && sha256sum -c SHA256SUMS) # 复制并重启 cp -f prebuilt/ainews-api-linux-amd64 /opt/ainews-api/ainews-api chmod +x /opt/ainews-api/ainews-api systemctl restart ainews-api curl -s http://127.0.0.1:8090/api/health ``` 也可以让 `update.sh` 走这条路(拉代码 + 复制,不编译): ```bash cd /www/wwwroot/ainews_server ./update.sh --prebuilt ``` 注意事项: - 二进制是 **linux/amd64**;服务器是 ARM(`aarch64`)时不能直接用,需要本机 `GOARCH=arm64` 重编后替换 `prebuilt/` 里的文件。 - `prebuilt/SHA256SUMS` 是校验清单,更新二进制时一起更新。 - Git 不适合频繁存二进制:每次替换约多 11MB 仓库体积,建议只在发布版本时更新,不要每次改代码都提交。 ### 4.2 直接在服务器上编译(备选;2C2G 容易内存打满卡死) 依赖全是纯 Go(`modernc.org/sqlite`,`CGO_ENABLED=0`),服务器装好 Go 就能直接编。 ```bash # 0) 先看架构和内存(amd64 / aarch64 决定下载哪个包) uname -m && cat /etc/os-release | head -2 && free -m # 1) 装 Go >= 1.27(go.mod 要求 1.27.0) cd /tmp curl -LO https://golang.google.cn/dl/go1.27.0.linux-amd64.tar.gz # 国内直连慢就用镜像:curl -LO https://mirrors.aliyun.com/golang/go1.27.0.linux-amd64.tar.gz # 服务器是 aarch64 时把文件名换成 go1.27.0.linux-arm64.tar.gz rm -rf /usr/local/go && tar -C /usr/local -xzf go1.27.0.linux-amd64.tar.gz cat >/etc/profile.d/go.sh <<'EOF' export PATH=$PATH:/usr/local/go/bin export GOPROXY=https://goproxy.cn,direct export GOSUMDB=sum.golang.google.cn EOF source /etc/profile.d/go.sh && go version # 2) 拉代码(Gitee 国内直连,不用翻墙) mkdir -p /opt/ainews-api && cd /opt/ainews-api git clone https://gitee.com/fourzkw/ainews_server.git repo cd repo # 3) 编译,产物直接放部署目录 CGO_ENABLED=0 go build -trimpath -ldflags '-s -w' -o /opt/ainews-api/ainews-api . ls -lh /opt/ainews-api/ainews-api ``` 2C2G 上的注意点: - 首次 `go build` 要下载依赖并编译 SQLite(大包),2 核 2G 无 swap 的机器峰值内存可达 1–2GB,**整机会被拖到卡死**;必须编译时加 `GOFLAGS=-p=1 nice -n 10 go build ...` 限制并行,并建议先加 2G swap。 - 被 OOM kill 时(`signal: killed`),改在本机交叉编译再上传;`prebuilt/` 里已有编好的 linux/amd64 二进制,优先走 4.1。 - 本机交叉编译命令:`GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -trimpath -ldflags '-s -w' -o prebuilt/ainews-api-linux-amd64 .` - 服务器是 ARM(`aarch64`)时,Go 用 `linux-arm64.tar.gz`,交叉编译加 `GOARCH=arm64`。 以后升级就三行: ```bash cd /opt/ainews-api/repo && git pull CGO_ENABLED=0 go build -trimpath -ldflags '-s -w' -o /opt/ainews-api/ainews-api . systemctl restart ainews-api ``` ## 5. 设计约束 - **只读**:`mode=ro` + `query_only`,绝不写 TrendRadar 的库;TrendRadar 删旧库(`retention_days`)时最多返回 404,不会互相加锁。 - **按天分库**:一次只开最近 3 个库(LRU),跨天查询请按日逐个查(Go 侧 `ATTACH` 上限 10,这里不用)。 - **schema 是契约**:TrendRadar 升级可能改列;镜像已 pin 到 `6.11.0`,升级时先跑 `--doctor` 并回归 `/api/meta`。 - **内存**:稳态 ~30–50MB,2C2G 上与 TrendRadar(512MB 上限)共存无压力。