对话机器人 Rasa(二十六):生产环境支持多并发的配置

发布时间: 2023-09-30 15:41:38 作者: 大象笔记

默认,Rasa 服务器只使用 1 个 worker。

对于生产环境,这肯定是不能接受的。

rasa 多并发

单机高并发设置

为何直接增加 worker 数量行不通

因为每一次请求的回复都需要基于对话的历史,而同一个用户的多个请求分散到多个 worker 上时, 就需要一个中心化的存储。

这里的 Rasa 名词为:

tracker store 及 lock store 的选型

Rasa 内置了多种 tracker store 方案:

内置的 Lock Store 方案

所以,看起来 Redis 是最简洁的配置方案。

redis docker

redis 最新的版本,2023-09-30 星期六, 从官网看最新版本是 7.2.1.

但是,我看到版本说明中说 7 版本包含了不向后兼容的变更。所以,谨慎起见,我选择了 6.2.13 版本。

docker-compose.yml 中增加

redis:
  image: redis:6.2.13-alpine
  restart: on-failure
  ports:
    - 6379
  command: redis-server --maxmemory 200M --maxmemory-policy allkeys-lru
  volumes:
    - /some/path/redis_data:/data

endpoints.yml

注意,tracker store 与 lock store 使用不同的 redis database。例如一个使用 0,一个使用 1。

启动命令增加环境变量

worker 数量设置为多少合适?等同于 CPU 的核数。例如双核就设置为 2.

例如 action_server ACTION_SERVER_SANIC_WORKERS 的配置:

action_server:
  image: rasa/rasa:3.4.6-full
  ports:
    - 5055:5055
  environment:
    - ACTION_SERVER_SANIC_WORKERS=2
  volumes:
    - ./:/app
  command:
    - run
    - actions

SANIC_WORKERS 的配置相同。

Redis 限制最大内存使用量

防止内存不足

command: redis-server --maxmemory 200M --maxmemory-policy allkeys-lru

重启 docker compose 以生效

docker-compose up -d

这个命令除了会执行 redis 容器的创建,还会同时重启其他已存在的服务。

无法访问 docker 中的 redis

  File "/opt/venv/lib/python3.10/site-packages/rasa/core/agent.py", line 419, in handle_message
    async with self.lock_store.lock(message.sender_id):
  File "/usr/lib/python3.10/contextlib.py", line 199, in __aenter__
    return await anext(self.gen)
  File "/opt/venv/lib/python3.10/site-packages/rasa/core/lock_store.py", line 101, in lock
    ticket = self.issue_ticket(conversation_id, lock_lifetime)
  File "/opt/venv/lib/python3.10/site-packages/rasa/core/lock_store.py", line 87, in issue_ticket
    raise LockError(f"Error while acquiring lock. Error:\n{e}")
rasa.core.lock_store.LockError: Error while acquiring lock. Error:
Error 99 connecting to localhost:6379. Cannot assign requested address.

将 endpoints.yml 中的配置 localhost 改成对应的 docker-compose.yml 中的 redis 服务名即可。

最好是备份一个线上的 endpoints.yml 文件。

custom action aiohttp

https://forum.rasa.com/t/need-details-on-multi-thread-architecture-of-rasa-server/41385/7

A common root cause of poor performance is when the action server is using a synchronous method to call external services, for example with the requests package.

These type of calls block the asyncio logic and all other calls will wait.

Make sure to use async logic everwhere in your custom actions, for example, replace the requests package with the aiohttp package.

lock store 为空的原因

https://forum.rasa.com/t/redis-lock-store-do-not-save-conversations/59410

通过 redis monitor 能看到实时的 set get del 操作。确实有用到,用完就删除了。

例如:

1696837537.683873 [1 172.18.0.4:43904] "GET" "lock:test_user"
1696837537.684096 [1 172.18.0.4:43904] "SET" "lock:test_user" "{\"conversation_id\": \"test_user\", \"tickets\": []}"
1696837537.684218 [1 172.18.0.4:43904] "GET" "lock:test_user"
1696837537.684326 [1 172.18.0.4:43904] "DEL" "lock:test_user"

查看合集

📖 对话机器人 Rasa 中文系列教程

我是一名山东烟台的开发者,联系作者