使用ecpool构建MongoDB连接池时遇undef错误,求分析崩溃报告
问题描述
尝试使用ecpool库搭建MongoDB连接池,自定义mongo_client模块用于建立MongoDB实例连接,但无论输入参数如何,运行时都会触发undef错误,无法解读崩溃报告,寻求解决提示。
初始化代码
init([]) -> PoolSize = 10, Urls = ["localhost:27017"], Database = "test", Username = "test", Password = "test", Type = single, % Define the worker arguments WorkerArgs = [ {hosts, Urls}, {database, Database}, {login, Username}, {password, Password}, {type, Type} ], PoolOptions = [ {pool_size, PoolSize}, {auto_reconnect, 1}, {options, []}, {worker_options, WorkerArgs} ], PoolSpec = ecpool:pool_spec(?APP, ?APP, mongo_client, PoolOptions), {ok, {{one_for_all, 10, 100}, [PoolSpec]}}.
崩溃报告
Eshell V15.0.1 (press Ctrl+G to abort, type help(). for help) =CRASH REPORT==== 29-Aug-2024::16:19:21.153000 === crasher: initial call: ecpool_worker:init/1 pid: <0.253.0> registered_name: [] exception exit: undef in function gen_server:init_it/6 (gen_server.erl, line 2038) ancestors: [<0.252.0>,<0.250.0>,mongo_app_sup,<0.248.0>] message_queue_len: 0 messages: [] links: [<0.252.0>] dictionary: [] trap_exit: true status: running heap_size: 233 stack_size: 29 reductions: 103 neighbours: =SUPERVISOR REPORT==== 29-Aug-2024::16:19:21.158000 === supervisor: {<0.252.0>,ecpool_worker_sup} errorContext: start_error reason: undef offender: [{pid,undefined}, {id,{worker,1}}, {mfargs, {ecpool_worker,start_link, [mongo_app,1,mongo_client, [{pool_size,10}, {auto_reconnect,1}, {options,[]}, {worker_options, [{hosts,["localhost:27017"]}, {database,"test"}, {login,"test"}, {password,"test"}, {type,single}]}]]}}, {restart_type,transient}, {significant,false}, {shutdown,5000}, {child_type,worker}] =SUPERVISOR REPORT==== 29-Aug-2024::16:19:21.158000 === supervisor: {<0.250.0>,ecpool_pool_sup} errorContext: start_error reason: {shutdown,{failed_to_start_child,{worker,1},undef}} offender: [{pid,undefined}, {id,worker_sup}, {mfargs, {ecpool_worker_sup,start_link, [mongo_app,mongo_client, [{pool_size,10}, {auto_reconnect,1}, {options,[]}, {worker_options, [{hosts,["localhost:27017"]}, {database,"test"}, {login,"test"}, {password,"test"}, {type,single}]}]]}}, {restart_type,transient}, {significant,false}, {shutdown,infinity}, {child_type,supervisor}] =SUPERVISOR REPORT==== 29-Aug-2024::16:19:21.158000 === supervisor: {local,mongo_app_sup} errorContext: start_error reason: {shutdown, {failed_to_start_child,worker_sup, {shutdown,{failed_to_start_child,{worker,1},undef}}}} offender: [{pid,undefined}, {id,mongo_app}, {mfargs, {ecpool,start_pool, [mongo_app,mongo_client, [{pool_size,10}, {auto_reconnect,1}, {options,[]}, {worker_options, [{hosts,["localhost:27017"]}, {database,"test"}, {login,"test"}, {password,"test"}, {type,single}]}]]}}, {restart_type,permanent}, {significant,false}, {shutdown,5000}, {child_type,supervisor}] =INFO REPORT==== 29-Aug-2024::16:19:21.158000 === application: mongo_app exited: {{shutdown, {failed_to_start_child,mongo_app, {shutdown, {failed_to_start_child,worker_sup, {shutdown, {failed_to_start_child,{worker,1},undef}}}}}}, {mongo_app_app,start,[normal,[]]}} type: temporary =CRASH REPORT==== 29-Aug-2024::16:19:21.158000 === crasher: initial call: application_master:init/3 pid: <0.247.0> registered_name: [] exception exit: {{shutdown, {failed_to_start_child,mongo_app, {shutdown, {failed_to_start_child,worker_sup, {shutdown, {failed_to_start_child,{worker,1},undef}}}}}}, {mongo_app_app,start,[normal,[]]}} in function application_master:init/3 (application_master.erl, line 143) ancestors: [application_controller,<0.10.0>] message_queue_len: 1 messages: [{'EXIT',<0.248.0>,normal}] links: [<0.45.0>] dictionary: [] trap_exit: true status: running heap_size: 376 stack_size: 29 reductions: 70 neighbours: =INFO REPORT==== 29-Aug-2024::16:19:21.165000 === application: ecpool exited: stopped type: temporary =INFO REPORT==== 29-Aug-2024::16:19:21.171000 === application: gproc exited: stopped type: temporary =INFO REPORT==== 29-Aug-2024::16:19:21.176000 === application: mongodb exited: stopped type: temporary =INFO REPORT==== 29-Aug-2024::16:19:21.176000 === application: pbkdf2 exited: stopped type: temporary =INFO REPORT==== 29-Aug-2024::16:19:21.176000 === application: poolboy exited: stopped type: temporary =INFO REPORT==== 29-Aug-2024::16:19:21.176000 === application: bson exited: stopped type: temporary ===> Booted sasl ===> Failed to boot mongo_app for reason {{shutdown, {failed_to_start_child,mongo_app, {shutdown, {failed_to_start_child, worker_sup, {shutdown, {failed_to_start_child, {worker,1}, undef}}}}}}, {mongo_app_app,start,[normal,[]]}}
问题分析与解决提示
崩溃报告中的undef错误表明Erlang虚拟机找不到某个需要调用的函数,结合调用栈来看,问题出在ecpool_worker初始化时调用mongo_client模块的过程中,可能的原因及检查步骤如下:
- 检查
mongo_client模块是否正确加载:在Erlang shell中执行code:which(mongo_client).,如果返回undefined,说明模块未编译或不在代码路径中。需要确保.beam编译文件存在,且所在目录被添加到代码路径(可通过code:add_patha("/path/to/module").添加)。 - 确认
mongo_client实现了ecpool要求的回调函数:ecpool的worker模块必须实现init/1函数,ecpool_worker会调用该函数初始化worker进程,返回值需符合gen_server的init规范(如{ok, State})。如果该函数未定义,会直接触发undef错误。 - 核对参数匹配情况:ecpool会将
worker_options中的参数传递给mongo_client:init/1,确保函数参数结构与传入的WorkerArgs匹配,避免因参数不匹配导致的函数找不到问题。 - 匹配ecpool版本要求:不同版本的ecpool对worker模块的回调要求可能有差异,部分版本可能要求实现
start_link/1而非init/1,需对照使用的ecpool版本调整mongo_client的实现。
内容的提问来源于stack exchange,提问作者Marcel N.
相关产品推荐
相关产品推荐

