Usage-Guide.md 18.2 KB

使用指南 - saas-search(运行与运维)

本文档聚焦运行与运维:服务启动/停止、日志查看、多环境切换、故障排查、Suggestion 索引运维。

开发与配置(环境入口、配置体系、Provider 架构、模块扩展规范)请优先阅读 docs/QUICKSTART.md

目录

  1. 环境准备
  2. 服务启动
  3. 服务管理总览
  4. 配置说明
  5. 查看日志
  6. 测试验证
  7. 常见问题

环境准备

系统要求

  • 操作系统: Linux (推荐 CentOS 7+ / Ubuntu 18.04+)
  • Python: 3.8+
  • 内存: 建议 8GB+
  • 磁盘: 10GB+ (包含模型文件)
  • Elasticsearch: 8.x (可通过Docker运行)

安装依赖

1. 安装 Python 依赖与激活环境

推荐:使用项目根目录的 activate.sh 激活环境(会加载 .env)。当前仅支持 venv(.venv),不存在 Conda 回退。系统要求、Python 环境、生产凭证与 .env 模板见 QUICKSTART.md §1.4–1.8。

cd /data/saas-search
./scripts/create_venv.sh   # 首次创建 venv(只需执行一次)
source activate.sh

模型服务采用独立环境(推荐):

cd /data/saas-search
./scripts/setup_embedding_venv.sh   # .venv-embedding
./scripts/setup_reranker_venv.sh    # .venv-reranker
./scripts/setup_cnclip_venv.sh      # .venv-cnclip

TEI 文本向量服务使用 Docker 容器:

# GPU(需 nvidia-container-toolkit)
TEI_DEVICE=cuda ./scripts/start_tei_service.sh

# CPU
TEI_DEVICE=cpu ./scripts/start_tei_service.sh

专项说明:

  • docs/TEI_SERVICE说明文档.md
  • docs/CNCLIP_SERVICE说明文档.md

2. 启动Elasticsearch

方式1: 使用Docker(推荐)

docker run -d \
  --name elasticsearch \
  -p 9200:9200 \
  -e "discovery.type=single-node" \
  -e "ES_JAVA_OPTS=-Xms2g -Xmx2g" \
  elasticsearch:8.11.0

方式2: 本地安装

参考 Elasticsearch官方文档

3. 配置环境变量(支持多环境)

创建 .env 文件(以本地 / prod 环境为例):

# MySQL配置
DB_HOST=120.79.247.228
DB_PORT=3316
DB_DATABASE=saas
DB_USERNAME=saas
DB_PASSWORD=your_password

# Elasticsearch配置
ES_HOST=http://localhost:9200
ES_USERNAME=essa
ES_PASSWORD=your_es_password

# Redis配置(可选,用于缓存)
REDIS_HOST=localhost
REDIS_PORT=6479
REDIS_PASSWORD=your_redis_password

# DeepL翻译API(可选)
DEEPL_AUTH_KEY=your_deepl_auth_key

# 运行环境(用于区分 prod / uat / test / dev)
RUNTIME_ENV=prod
# ES 索引命名空间前缀(用于按环境隔离索引,prod 通常留空)
ES_INDEX_NAMESPACE=

# API服务配置
API_HOST=0.0.0.0
API_PORT=6002

服务启动

方式1: 一键启动(推荐)

cd /data/saas-search
./run.sh all

这个脚本会自动:

  1. 创建日志目录
  2. 按目标启动服务(alltei cnclip embedding embedding-image translator reranker reranker-fine backend indexer frontend eval-web
  3. 写入 PID 到 logs/*.pid
  4. 执行健康检查
  5. 启动 monitor daemon(运行期连续失败自动重启)

启动完成后,访问:

仅启动部分服务示例:./run.sh backend indexer frontend

方式2: 统一控制脚本(推荐)

# 查看状态
./scripts/service_ctl.sh status

# 推荐:一键启动 + 监控守护
./scripts/service_ctl.sh up all

# 启动指定服务
./scripts/service_ctl.sh up backend indexer frontend

# 启动指定服务(不自动拉起 monitor daemon)
./scripts/service_ctl.sh start backend indexer frontend translator reranker tei cnclip

# 停止全部服务(含 monitor daemon)
./scripts/service_ctl.sh down all

# 重启全部服务
./scripts/service_ctl.sh restart all

补充说明:

  • ./scripts/service_ctl.sh 可以直接使用,不要求你手动先 source ./activate.sh;因为各个 start_*.sh 会自行加载项目虚拟环境。
  • 但如果你要运行 pytest、评估脚本或临时 Python 脚本,建议先执行 source ./activate.sh

方式3: 分步启动(单环境)

启动后端服务

./scripts/start_backend.sh

后端API会在 http://localhost:6002 启动(使用当前 .env 中的 ES_HOST / DB_HOST / RUNTIME_ENV / ES_INDEX_NAMESPACE)

等价的手动命令是:

cd /data/saas-search
source ./activate.sh
python main.py serve --host "${API_HOST:-0.0.0.0}" --port "${API_PORT:-6002}" --es-host "${ES_HOST:-http://localhost:9200}"

启动前端服务

./scripts/start_frontend.sh

前端界面会在 http://localhost:6003 启动

本地测试与检索效果评估

cd /data/saas-search
source ./activate.sh
python -m pytest -q tests/test_rerank_client.py tests/test_es_query_builder.py tests/test_search_rerank_window.py tests/test_query_parser_mixed_language.py
./scripts/service_ctl.sh restart backend
sleep 3
./scripts/service_ctl.sh status backend
./scripts/evaluation/quick_start_eval.sh batch

离线批量评估会把标注与报表写到 artifacts/search_evaluation/(SQLite、batch_reports/ 下的 JSON/Markdown 等)。说明与命令见 scripts/evaluation/README.md

方式4: 多环境示例(prod / uat)

假设有两套环境:

  • prod:正式环境,RUNTIME_ENV=prod,ES_INDEX_NAMESPACE 为空
  • uat:联调环境,RUNTIME_ENV=uat,ES_INDEX_NAMESPACE=uat_

可以在项目根目录准备两个配置文件:

  • .env.prod
RUNTIME_ENV=prod
ES_INDEX_NAMESPACE=
ES_HOST=http://prod-es:9200
DB_HOST=prod-mysql
...
  • .env.uat
RUNTIME_ENV=uat
ES_INDEX_NAMESPACE=uat_
ES_HOST=http://uat-es:9200
DB_HOST=uat-mysql
...

启动不同环境时:

# 启动 UAT 后端 + 索引服务
cp .env.uat .env
./scripts/start_backend.sh
./scripts/start_indexer.sh

# 启动 PROD 后端 + 索引服务
cp .env.prod .env
./scripts/start_backend.sh
./scripts/start_indexer.sh

方式5: 手动启动

启动后端API服务

python -m api.app \
  --host 0.0.0.0 \
  --port 6002 \
  --es-host http://localhost:9200 \
  --reload

启动前端服务(可选)

# 使用Python简单HTTP服务器
cd frontend
python -m http.server 6003

服务管理总览

1) 入口脚本职责

  • ./run.sh [all|service...]:薄封装,直接调用 ./scripts/service_ctl.sh up [all|service...]
  • ./restart.sh [all|service...]:薄封装,直接调用 ./scripts/service_ctl.sh restart [all|service...]
  • ./scripts/stop.sh [all|service...]:薄封装,直接调用 ./scripts/service_ctl.sh down [all|service...]
  • ./status.sh:薄封装,直接调用 ./scripts/service_ctl.sh status(包含进程/端口 + HTTP 健康检查结果)。
  • ./scripts/service_ctl.sh:统一控制器,支持 up/down/start/stop/restart/status/monitor*(带参数行为完全由此脚本定义)。

2) service_ctl.sh 的默认行为

  • up必须显式指定 服务或 all,并自动启动 monitor daemon。
  • down必须显式指定 服务或 all,并停止 monitor daemon。
  • start必须显式指定 服务或 all(不自动拉起 monitor daemon)。
  • stop必须显式指定 服务或 all;若 monitor daemon 运行会先停止它。
  • restart必须显式指定 服务或 all
  • status(不带服务名):显示全部已知服务状态 + monitor daemon 状态,并对支持的服务执行 HTTP/容器级健康检查。

3) 全量服务一键拉起

./scripts/service_ctl.sh up all

说明:

  • TEI_DEVICE / CNCLIP_DEVICE 统一使用 cuda|cpu
  • all 内部已按依赖顺序处理(先 tei/cnclipembedding)。

4) 常用运维命令

# 一键拉起完整栈(推荐)
./scripts/service_ctl.sh up all         # 或 ./run.sh all

# 查看全量状态 + 健康检查(进程/端口 + HTTP)
./scripts/service_ctl.sh status

# 仅重启某个服务
./scripts/service_ctl.sh restart embedding

# 停止全部
./scripts/service_ctl.sh down all       # 或 ./scripts/stop.sh all

停止服务

# 推荐:统一停止(示例:全部)
./scripts/stop.sh all

# 或使用统一控制脚本
./scripts/service_ctl.sh down all

服务端口

服务 端口 URL
Elasticsearch 9200 http://localhost:9200
Backend API 6002 http://localhost:6002
Indexer API 6004 http://localhost:6004
Frontend Web 6003 http://localhost:6003
Search eval web (eval-web) 6010 http://localhost:6010
Embedding Text (optional) 6005 http://localhost:6005
Embedding Image (optional) 6008 http://localhost:6008
TEI (optional) 8080 http://localhost:8080
Translation (optional) 6006 http://localhost:6006
Reranker (optional) 6007 http://localhost:6007
API Docs 6002 / 6004 http://localhost:6002/docs / http://localhost:6004/docs

配置说明

环境配置文件 (.env)

主要配置项说明:

# Elasticsearch配置
ES_HOST=http://localhost:9200
ES_USERNAME=essa
ES_PASSWORD=your_es_password

# MySQL配置
DB_HOST=120.79.247.228
DB_PORT=3316
DB_DATABASE=saas
DB_USERNAME=saas
DB_PASSWORD=your_password

# Redis配置(可选,用于缓存)
REDIS_HOST=localhost
REDIS_PORT=6479
REDIS_PASSWORD=your_redis_password

# DeepL翻译API
DEEPL_AUTH_KEY=your_deepl_auth_key

# API服务配置
API_HOST=0.0.0.0
API_PORT=6002

# Indexer服务配置
INDEXER_HOST=0.0.0.0
INDEXER_PORT=6004

# Optional service ports
FRONTEND_PORT=6003
EVAL_WEB_PORT=6010
EMBEDDING_TEXT_PORT=6005
EMBEDDING_IMAGE_PORT=6008
TEI_PORT=8080
CNCLIP_PORT=51000
TRANSLATION_PORT=6006
RERANKER_PORT=6007

修改配置

  1. 编辑 .env 文件
  2. 重启相关服务

查看日志

日志文件位置

日志文件存储在 logs/ 目录下:

  • logs/<service>-YYYY-MM-DD.log - service_ctl.sh 统一管理的按天日志文件(真实文件)
  • logs/<service>.log - 指向当天日志文件的软链(兼容原有命令)
  • logs/api.log - backend 进程内日志(按天轮转)
  • logs/backend_verbose.log - backend 详细大对象日志(按天轮转,含 Search response / ES query built 完整内容)
  • logs/indexer.log - 索引结构化日志(JSON,按天轮转)

查看实时日志

# 查看后端日志(建议 -F,跨天自动跟随新文件)
tail -F logs/backend.log

# 查看前端日志
tail -F logs/frontend.log

# 查看 backend 详细大对象日志
tail -F logs/backend_verbose.log

日志级别

日志级别可以通过环境变量 LOG_LEVEL 设置:

# 在 .env 文件中设置
LOG_LEVEL=DEBUG  # DEBUG, INFO, WARNING, ERROR, CRITICAL

日志轮转

日志文件按天自动轮转,默认保留 30 天历史日志(可通过 LOG_RETENTION_DAYS 调整 service_ctl.sh 管理日志的保留天数)。


测试验证

1. 健康检查

curl http://localhost:6002/admin/health

预期响应:

{
  "status": "healthy",
  "elasticsearch": "connected"
}

2. 索引统计

curl http://localhost:6002/admin/stats -H "X-Tenant-ID: 162"

3. 简单搜索测试

curl -X POST http://localhost:6002/search/ \
  -H "Content-Type: application/json" \
  -H "X-Tenant-ID: 162" \
  -d '{
    "query": "玩具",
    "size": 10
  }'

或者通过查询参数:

curl -X POST "http://localhost:6002/search/?tenant_id=2" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "玩具",
    "size": 10
  }'

4. 带过滤器的搜索

curl -X POST http://localhost:6002/search/ \
  -H "Content-Type: application/json" \
  -H "X-Tenant-ID: 162" \
  -d '{
    "query": "玩具",
    "size": 10,
    "filters": {
      "category.keyword": ["玩具", "益智玩具"]
    },
    "range_filters": {
      "price": {"gte": 50, "lte": 200}
    }
  }'

5. 分面搜索测试

curl -X POST http://localhost:6002/search/ \
  -H "Content-Type: application/json" \
  -H "X-Tenant-ID: 162" \
  -d '{
    "query": "玩具",
    "size": 10,
    "facets": [
      {"field": "category.keyword", "size": 15},
      {"field": "vendor.keyword", "size": 15}
    ]
  }'

6. 图片搜索测试

curl -X POST http://localhost:6002/search/image \
  -H "Content-Type: application/json" \
  -H "X-Tenant-ID: 162" \
  -d '{
    "image_url": "https://oss.essa.cn/example.jpg",
    "size": 10
  }'

7. 前端界面测试

访问 http://localhost:6003http://localhost:6002/ 进行可视化测试。

注意: 所有搜索接口都需要通过 X-Tenant-ID 请求头或 tenant_id 查询参数指定租户ID。


8. Suggestion 索引与接口使用

8.1 构建 Suggestion 索引(Phase 2:全量 + 增量)

Suggestion 索引会从:

  • ES 商品索引:title.{lang}, qanchors.{lang}
  • MySQL 日志表:shoplazza_search_log.query(含 languagerequest_params

聚合生成版本化索引并发布 alias:

  • 物理索引:{ES_INDEX_NAMESPACE}search_suggestions_tenant_{tenant_id}_v<timestamp>
  • 读别名:{ES_INDEX_NAMESPACE}search_suggestions_tenant_{tenant_id}_current

在项目根目录执行(以 tenant_id=162 为例):

# 1) 全量重建(版本化 + alias 发布)
./scripts/build_suggestions.sh 162 \
  --mode full \
  --days 30 \
  --publish-alias \
  --keep-versions 2

# 2) 增量更新(watermark + overlap)
./scripts/build_suggestions.sh 162 \
  --mode incremental \
  --overlap-minutes 30

可选参数:

  • --days:回溯日志天数(默认 30)
  • --batch-size:扫描商品索引的批大小(默认 500)
  • --min-query-len:参与 suggestion 的最小查询长度(默认 1)
  • --overlap-minutes:增量窗口重叠分钟数(默认 30)
  • --bootstrap-if-missing:增量模式下若缺少 active index 则自动全量初始化(默认 true)

建议在商品索引构建完成、日志正常写入一段时间后执行一次全量构建,然后按天/小时增加增量构建任务。

8.2 调用 Suggestion 接口

全量构建完成后,可直接通过 /search/suggestions 获取自动补全结果:

# UAT 环境(本地或 UAT 集群)
curl "http://localhost:6002/search/suggestions?q=iph&size=5&language=en" \
  -H "X-Tenant-ID: 162"

# PROD 环境(域名 / 端口按实际部署调整)
curl "https://api.yourdomain.com/search/suggestions?q=iph&size=5&language=en" \
  -H "X-Tenant-ID: 162"

8.3 商品索引构建(search_products,多环境例子)

以 tenant_id=162 为例,分别在 UAT / PROD 构建商品索引。

UAT 环境(索引前缀 uat_)

cd /data/saas-search

# 1. 切换到 UAT 环境配置
cp .env.uat .env

# 2. 启动 indexer 服务(如尚未启动)
./scripts/start_indexer.sh

# 3. 可选:重建索引结构(会删除旧索引)
./scripts/create_tenant_index.sh 162
# 实际创建的索引名为:uat_search_products_tenant_162

# 4. 导入商品数据(全量索引)
curl -X POST "http://localhost:6004/indexer/reindex" \
  -H "Content-Type: application/json" \
  -d '{
    "tenant_id": "162",
    "batch_size": 500
  }'

PROD 环境(无前缀)

cd /data/saas-search

# 1. 切换到 PROD 环境配置
cp .env.prod .env

# 2. 启动 indexer 服务
./scripts/start_indexer.sh

# 3. 可选:重建索引结构(search_products_tenant_162)
./scripts/create_tenant_index.sh 162

# 4. 导入商品数据
curl -X POST "http://localhost:6004/indexer/reindex" \
  -H "Content-Type: application/json" \
  -d '{
    "tenant_id": "162",
    "batch_size": 500
  }'

完成后:

  • UAT 环境商品索引:uat_search_products_tenant_162
  • PROD 环境商品索引:search_products_tenant_162

两套环境的搜索 / suggestion API 调用完全一致,只是连接到各自的后端 / ES。

接口返回结构详见 docs/搜索API对接指南.md 的“3.7 搜索建议接口”章节。


常见问题

Q1: MySQL连接失败

症状: Failed to connect to MySQL

解决方案:

# 检查MySQL服务状态
mysql -h 120.79.247.228 -P 3316 -u saas -p -e "SELECT 1"

# 检查配置
cat .env | grep DB_

Q2: Elasticsearch连接失败

症状: Failed to connect to Elasticsearch

解决方案:

# 检查ES服务状态
curl http://localhost:9200

# 检查ES版本
curl http://localhost:9200 | grep version

# 确认配置
cat .env | grep ES_

Q3: 服务启动失败

症状: Address already in use 或端口被占用

解决方案:

# 查看占用端口的进程
lsof -i :6002  # 后端
lsof -i :6003  # 前端
lsof -i :6010  # 搜索评估 UI(eval-web)
lsof -i :9200  # ES

# 杀掉进程
kill -9 <PID>

# 或修改端口配置

Q4: 搜索无结果

症状: 搜索返回空结果

解决方案:

# 检查ES中是否有数据
curl http://localhost:9200/search_products/_count

# 检查tenant_id过滤是否正确
curl -X POST http://localhost:6002/search/ \
  -H "Content-Type: application/json" \
  -H "X-Tenant-ID: 162" \
  -d '{"query": "*", "size": 10, "debug": true}'

Q5: 前端无法连接后端

症状: CORS错误

解决方案:

  • 确保后端在 http://localhost:6002 运行
  • 检查浏览器控制台错误信息
  • 检查后端日志中的CORS配置

Q6: 翻译不工作

症状: 翻译返回原文

解决方案:

  • 检查DEEPL_AUTH_KEY是否正确
  • 如果没有API key,系统会使用mock模式(返回原文)

相关文档

  • 测试数据构造文档: TEST_DATA_GUIDE.md - 如何构造和导入测试数据
  • API接口文档: API_INTEGRATION_GUIDE.md - 完整的API对接指南
  • 字段说明文档: INDEX_FIELDS_DOCUMENTATION.md - 索引字段详细说明
  • 设计文档: 设计文档.md - 系统架构和设计说明
  • README: README.md - 项目概述和快速开始

文档版本: v2.0
最后更新: 2024-12