# 使用指南 - 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 仅作为兼容回退(需要 `CONDA_ROOT`)。系统要求、Python 环境、生产凭证与 `.env` 模板见 [QUICKSTART.md](./QUICKSTART.md) §1.4–1.8。 ```bash cd /data/saas-search ./scripts/create_venv.sh # 首次创建 venv(只需执行一次) source activate.sh ``` 如果需要本地 embedding / 图像编码(会安装 torch/transformers 等较重依赖): ```bash cd /data/saas-search INSTALL_ML=1 ./scripts/create_venv.sh source activate.sh ``` 首次在新机器创建环境时,可任选其一: - `conda env create -f environment.yml`(推荐,与 environment.yml 一致) - 或创建 env 后 `pip install -r requirements.txt` #### 2. 启动Elasticsearch **方式1: 使用Docker(推荐)** ```bash 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官方文档](https://www.elastic.co/guide/en/elasticsearch/reference/8.11/install-elasticsearch.html) #### 3. 配置环境变量(支持多环境) 创建 `.env` 文件(以本地 / prod 环境为例): ```bash # 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: 一键启动(推荐) ```bash cd /data/saas-search ./run.sh ``` 这个脚本会自动: 1. 创建日志目录 2. 启动核心服务(backend/indexer/frontend) 3. 写入 PID 到 `logs/*.pid` 4. 执行健康检查 启动完成后,访问: - **前端界面**: http://localhost:6003 - **后端API**: http://localhost:6002 - **API文档**: http://localhost:6002/docs - **索引API**: http://localhost:6004/docs 可选:全功能模式(同时启动 embedding/translator/reranker): ```bash START_EMBEDDING=1 START_TRANSLATOR=1 START_RERANKER=1 ./run.sh ``` ### 方式2: 统一控制脚本(推荐) ```bash # 查看状态 ./scripts/service_ctl.sh status # 启动核心服务(默认) ./scripts/service_ctl.sh start # 启动指定服务 ./scripts/service_ctl.sh start backend indexer frontend translator reranker # 停止全部服务(含可选服务) ./scripts/service_ctl.sh stop # 重启 ./scripts/service_ctl.sh restart ``` ### 方式3: 分步启动(单环境) #### 启动后端服务 ```bash ./scripts/start_backend.sh ``` 后端API会在 http://localhost:6002 启动(使用当前 `.env` 中的 ES_HOST / DB_HOST / RUNTIME_ENV / ES_INDEX_NAMESPACE) #### 启动前端服务 ```bash ./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`: ```bash RUNTIME_ENV=prod ES_INDEX_NAMESPACE= ES_HOST=http://prod-es:9200 DB_HOST=prod-mysql ... ``` - `.env.uat`: ```bash RUNTIME_ENV=uat ES_INDEX_NAMESPACE=uat_ ES_HOST=http://uat-es:9200 DB_HOST=uat-mysql ... ``` 启动不同环境时: ```bash # 启动 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服务 ```bash python -m api.app \ --host 0.0.0.0 \ --port 6002 \ --es-host http://localhost:9200 \ --reload ``` #### 启动前端服务(可选) ```bash # 使用Python简单HTTP服务器 cd frontend python -m http.server 6003 ``` ### 停止服务 ```bash # 推荐:统一停止 ./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 | | 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) 主要配置项说明: ```bash # 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` - 错误日志(按天轮转) ### 查看实时日志 ```bash # 查看后端日志 tail -f logs/backend.log # 查看前端日志 tail -f logs/frontend.log # 查看应用主日志 tail -f logs/search_engine.log # 查看错误日志 tail -f logs/errors.log ``` ### 日志级别 日志级别可以通过环境变量 `LOG_LEVEL` 设置: ```bash # 在 .env 文件中设置 LOG_LEVEL=DEBUG # DEBUG, INFO, WARNING, ERROR, CRITICAL ``` ### 日志轮转 日志文件按天自动轮转,保留30天的历史日志。 --- ## 测试验证 ### 1. 健康检查 ```bash curl http://localhost:6002/admin/health ``` **预期响应**: ```json { "status": "healthy", "elasticsearch": "connected" } ``` ### 2. 索引统计 ```bash curl http://localhost:6002/admin/stats ``` ### 3. 简单搜索测试 ```bash curl -X POST http://localhost:6002/search/ \ -H "Content-Type: application/json" \ -H "X-Tenant-ID: 162" \ -d '{ "query": "玩具", "size": 10 }' ``` 或者通过查询参数: ```bash curl -X POST "http://localhost:6002/search/?tenant_id=2" \ -H "Content-Type: application/json" \ -d '{ "query": "玩具", "size": 10 }' ``` ### 4. 带过滤器的搜索 ```bash 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. 分面搜索测试 ```bash 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. 图片搜索测试 ```bash 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:6003 或 http://localhost:6002/ 进行可视化测试。 **注意**: 所有搜索接口都需要通过 `X-Tenant-ID` 请求头或 `tenant_id` 查询参数指定租户ID。 --- ## 8. Suggestion 索引与接口使用 ### 8.1 构建 Suggestion 索引(全量,多环境) Suggestion 索引会从: - ES 商品索引:`title.{lang}`, `qanchors.{lang}` - MySQL 日志表:`shoplazza_search_log.query`(含 `language`、`request_params`) 聚合生成 `{ES_INDEX_NAMESPACE}search_suggestions_tenant_{tenant_id}`。 在项目根目录执行(以 UAT 环境、tenant_id=162 为例): ```bash # 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` 获取自动补全结果: ```bash # 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_) ```bash 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 环境(无前缀) ```bash 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` **解决方案**: ```bash # 检查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` **解决方案**: ```bash # 检查ES服务状态 curl http://localhost:9200 # 检查ES版本 curl http://localhost:9200 | grep version # 确认配置 cat .env | grep ES_ ``` ### Q3: 服务启动失败 **症状**: `Address already in use` 或端口被占用 **解决方案**: ```bash # 查看占用端口的进程 lsof -i :6002 # 后端 lsof -i :6003 # 前端 lsof -i :9200 # ES # 杀掉进程 kill -9 # 或修改端口配置 ``` ### Q4: 搜索无结果 **症状**: 搜索返回空结果 **解决方案**: ```bash # 检查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