部署的Rasa开源虚拟助手无响应问题排查求助
Rasa虚拟助手部署无响应问题排查
环境与背景
- 部署环境:Google Cloud E2机器(Ubuntu 18.04),Docker容器集群
- 助手功能:旧金山探索馆虚拟讲解员,支持三类查询:
- 展品概念/现象解释
- 指定展品详情(描述、位置、创作者、年份)
- 展品推荐
- 问题现象:
- 对话中助手时常无响应
- 本地
rasa shell运行正常,但部署时COPY的模型被判无效,故在Dockerfile中加入RUN rasa train(训练数据/配置与本地一致) - M1芯片本地Docker测试时,助手几乎总是忽略第一个用户输入,日志显示
BotUttered已触发但Web服务器无响应 - 怀疑问题出在Nginx、Socket.io等网络组件,而非Rasa本身
配置详情
docker-compose.yml
version: '3' services: rasa_server: container_name: "rasa_server" build: context: backend user: root ports: - "5005:5005" expose: - 5005 action_server: container_name: "action_server" build: context: actions ports: - "5055:5055" expose: - 5055 web_server: container_name: "web_server" image: nginx depends_on: - "rasa_server" - "action_server" ports: - "80:80" - "443:443" restart: always volumes: - ./web/conf/default.conf:/etc/nginx/conf.d/default.conf - ./web/conf/explorer-ai.chat.conf:/etc/nginx/conf.d/explorer-ai.chat.conf - ./web/conf/nginx.conf:/etc/nginx/nginx.conf - ./web/html:/var/www/html - ./certbot/www:/var/www/certbot - ./certbot/conf:/etc/letsencrypt certbot: container_name: "certbot" image: certbot/certbot volumes: - ./certbot/www:/var/www/cerbot:rw - ./certbot/conf:/etc/letsencrypt:rw
backend Dockerfile
FROM rasa/rasa:3.3.1 WORKDIR /app USER root COPY ./models /app/models COPY ./data /app/data COPY . /app RUN rasa train ENTRYPOINT ["rasa", "run", "-m", "models", "--enable-api", "--cors", "*", "--debug"]
actions Dockerfile
FROM rasa/rasa-sdk:3.3.0 WORKDIR /app COPY ./requirements-actions.txt requirements.txt COPY . /app USER root RUN pip install --no-cache-dir -r requirements.txt USER 1001 EXPOSE 5055 ENTRYPOINT ["python", "-m", "rasa_sdk", "--actions", "actions"]
credentials.yml Socket.io配置
socketio: user_message_evt: user_uttered bot_message_evt: bot_uttered session_persistence: false
index.html Socket.io相关代码
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/3.1.2/socket.io.js" integrity="sha512-YybopSVjZU0fe8TY4YDuQbP5bhwpGBE/T6eBUEZ0usM72IWBfWrgVI13qfX4V2A/W7Hdqnm7PIOYOwP9YHnICw==" crossorigin="anonymous" referrerpolicy="no-referrer"> </script> <script> const socket = io("https://explorer-ai.chat"); const messages = document.getElementById('messages'); const form = document.getElementById('form'); const messageInput = document.getElementById('message-input'); function scrollToBottom() { window.scrollTo(0, document.body.scrollHeight); } function appendMessage(msg, type) { const item = document.createElement('div'); item.textContent = msg; item.classList.add("message"); item.classList.add(`message_${type}`); messages.appendChild(item); scrollToBottom(); } const welcome = "Hello! I'm Explorer AI, a virtual assistant for visitors to the " + "Exploratorium in San Francisco. I've been trained to answer questions about the " + "Exploratorium's exhibits and the concepts they illustrate."; const how_help = "How may I assist you?"; appendMessage(welcome, "received"); appendMessage(how_help, "received"); form.addEventListener('submit', function (e) { e.preventDefault(); const msg = messageInput.value; if (msg) { socket.emit('user_uttered', { "message": msg, }); messageInput.value = ''; appendMessage(msg, "sent"); } }); socket.on('connect', function () { console.log("Connected to Socket.io server"); }); socket.on('connect_error', (error) => { console.log("Connection to Socket.io FAILED"); console.error(error); }); socket.on('bot_uttered', function (response) { console.log("Bot uttered:", response); if (response.text) { appendMessage(response.text, "received"); } if (response.attachment) { appendImage(response.attachment.payload.src, "received"); } if (response.quick_replies) { appendQuickReplies(response.quick_replies); } }); </script>
Nginx配置
server { listen 80; listen [::]:80; server_name explorer-ai.chat www.explorer-ai.chat; location /.well-known/acme-challenge/ { root /var/www/certbot; } location / { return 301 https://explorer-ai.chat$request_uri; } } server { listen 443 ssl; listen [::]:443 ssl; server_name explorer-ai.chat www.explorer-ai.chat; ssl_certificate /etc/letsencrypt/live/explorer-ai.chat/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/explorer-ai.chat/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; root /var/www/html; index index.html; location /socket.io/ { proxy_pass http://rasa_server:5005; } }
排查建议
补全Nginx Socket.io代理配置
Socket.io依赖WebSocket协议,当前Nginx配置缺少必要的握手支持,在location /socket.io/块中添加:proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade;缺少这些配置会导致WebSocket连接失败,消息无法实时推送。
优化服务启动顺序
depends_on仅保证容器启动顺序,不保证服务就绪。给rasa_server添加健康检查,确保服务完全启动后再接收请求:
在docker-compose.yml的rasa_server服务中加入:healthcheck: test: ["CMD", "curl", "-f", "http://localhost:5005/health"] interval: 10s timeout: 5s retries: 5同时修改web_server的depends_on:
depends_on: rasa_server: condition: service_healthy action_server: condition: service_started避免前端连接时Rasa服务尚未初始化完成。
检查Socket.io版本兼容性
前端使用Socket.io 3.1.2,需确认Rasa容器中python-socketio版本与之兼容。在backend容器中执行pip list | grep python-socketio查看版本,若差异过大需调整前端或后端版本。保证会话ID一致性
前端发送user_uttered事件时未携带会话ID,可能导致会话不匹配。修改前端逻辑:// 生成或获取持久化的会话ID let sessionId = localStorage.getItem('rasa_session_id') || self.crypto.randomUUID(); localStorage.setItem('rasa_session_id', sessionId); // 发送消息时携带session_id socket.emit('user_uttered', { "message": msg, "session_id": sessionId });确保前后端会话关联正确。
日志排查
- 查看Rasa服务器日志:
docker logs rasa_server,确认BotUttered事件是否正确发送 - 查看Nginx日志:
docker logs web_server,检查Socket.io请求的状态码 - 查看浏览器控制台,确认Socket.io连接和消息发送是否有错误
- 查看Rasa服务器日志:
内容的提问来源于stack exchange,提问作者vonbecker
相关产品推荐
相关产品推荐

