Usage-Guide.md 14.4 KB

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

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

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

目录

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

环境准备

系统要求

  • 操作系统: 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_USE_GPU=1 ./scripts/start_tei_service.sh

# CPU
TEI_USE_GPU=0 ./scripts/start_tei_service.sh

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

这个脚本会自动:

  1. 创建日志目录
  2. 启动核心服务(backend/indexer/frontend)
  3. 写入 PID 到 logs/*.pid
  4. 执行健康检查

启动完成后,访问:

可选:全功能模式(同时启动 embedding/translator/reranker/tei):

START_EMBEDDING=1 START_TRANSLATOR=1 START_RERANKER=1 START_TEI=1 ./run.sh

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

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

# 启动核心服务(默认)
./scripts/service_ctl.sh start

# 启动指定服务
./scripts/service_ctl.sh start backend indexer frontend translator reranker tei

# 停止全部服务(含可选服务)
./scripts/service_ctl.sh stop

# 重启
./scripts/service_ctl.sh restart

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

启动后端服务

./scripts/start_backend.sh

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

启动前端服务

./scripts/start_frontend.sh

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

方式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

停止服务

# 推荐:统一停止
./scripts/stop.sh

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

服务端口

服务 端口 URL
Elasticsearch 9200 http://localhost:9200
Backend API 6002 http://localhost:6002
Indexer API 6004 http://localhost:6004
Frontend Web 6003 http://localhost:6003
Embedding (optional) 6005 http://localhost:6005
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
EMBEDDING_PORT=6005
TRANSLATION_PORT=6006
RERANKER_PORT=6007

# Optional startup switches (for run.sh / service_ctl.sh)
START_EMBEDDING=0
START_TRANSLATOR=0
START_RERANKER=0

修改配置

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

查看日志

日志文件位置

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

  • logs/backend.log - 后端服务日志
  • logs/indexer.log - 索引服务日志
  • logs/frontend.log - 前端服务日志
  • logs/embedding.log - 向量服务日志(可选)
  • logs/translator.log - 翻译服务日志(可选)
  • logs/reranker.log - 重排服务日志(可选)
  • logs/search_engine.log - 应用主日志(按天轮转)
  • logs/errors.log - 错误日志(按天轮转)

查看实时日志

# 查看后端日志
tail -f logs/backend.log

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

# 查看应用主日志
tail -f logs/search_engine.log

# 查看错误日志
tail -f logs/errors.log

日志级别

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

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

日志轮转

日志文件按天自动轮转,保留30天的历史日志。


测试验证

1. 健康检查

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

预期响应:

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

2. 索引统计

curl http://localhost:6002/admin/stats

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 索引(全量,多环境)

Suggestion 索引会从:

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

聚合生成 {ES_INDEX_NAMESPACE}search_suggestions_tenant_{tenant_id}

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

# 1. 切换到 UAT 配置(包含 ES_INDEX_NAMESPACE=uat_)
cp .env.uat .env

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

# 3. 为指定租户全量重建 suggestion 索引(会删除旧索引)
python main.py build-suggestions \
  --tenant-id 162 \
  --es-host http://localhost:9200 \
  --days 30 \
  --recreate

UAT 环境下,索引名为:uat_search_suggestions_tenant_162
prod 环境下(ES_INDEX_NAMESPACE 为空),索引名为:search_suggestions_tenant_162

可选参数:

  • --days:回溯日志天数(默认 30)
  • --batch-size:扫描商品索引的批大小(默认 500)
  • --min-query-len:参与 suggestion 的最小查询长度(默认 1)

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

8.2 调用 Suggestion 接口

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

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

# PROD 环境(域名 / 端口按实际部署调整)
curl "https://api.yourdomain.com/search/suggestions?q=iph&size=5&language=en&with_results=true" \
  -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 :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