【问题标题】:Database threads per request using Ecto使用 Ecto 的每个请求的数据库线程
【发布时间】:2017-10-03 11:48:50
【问题描述】:

典型的 Elixir Web 应用程序通常有一个 postgresql 后端,带有 Ecto 查询以及 API 逻辑。

但是,由于cowboy 为每个请求创建了一个子GenServer 进程(包含应用程序逻辑),这是否会产生为 n 生成 n 个 psql 线程的效果并发请求,即使 cowboy/poolboy 提供池化?

然后,转移到存在多个应用程序实例的场景(例如 docker 容器集群),这不会增加现有数据库线程总数的额外因素吗?

【问题讨论】:

    标签: json architecture elixir psql ecto


    【解决方案1】:

    Cowboy 确实为每个请求创建一个新的 Erlang 进程,但从该进程执行 Ecto 查询将不会导致新的数据库连接。 Ecto 保持与数据库的连接池(使用 db_connection/poolboy)。此池的大小是使用回购配置中的pool_size 选项设置的。当您启动查询时,会借用此池中的连接并用于执行查询。执行完成后,连接将返回到池中。 Ecto 永远不会为每个查询创建新连接。如果池中没有可用的连接,它将等待一个可用的连接,或者如果在配置的超时(默认为 30 秒)中没有签入连接,则最终超时。

    【讨论】:

    • 谢谢 - 计算跨 n 个应用程序实例的最大应用程序数据库线程数应该是 n * pool_size
    • 是的,没错。应用程序的每个实例都将打开pool_size 连接。
    • 这不是问题吗?我的意思是,如果实例数量无法控制地增长,那么 n*pool_size 线程可能会在重负载下杀死数据库,在这种情况下,你在 Elixir 世界中会做什么?
    • 我知道如果你控制连接 pool_size 集群的值与数据库服务器可以处理的值成正比,它可以解决这样的问题。 Ecto 有这样的东西吗?
    • 请注意,:pool_timeout 已被删除,并已替换为更智能的队列:hexdocs.pm/db_connection/DBConnection.html#start_link/…
    猜你喜欢
    • 2020-10-06
    • 1970-01-01
    • 2010-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多