无法在Cassandra 3下运行Xandra,调用prepare触发FunctionClauseError
排查Xandra Cluster连接时的FunctionClauseError问题
你遇到的FunctionClauseError本质是Cassandra集群连接未成功建立——从错误日志能看到pools: %{}(空连接池)和node_refs: [{..., nil}, {..., nil}](节点引用全为空),说明Xandra没能成功连接到你的Cassandra节点,导致后续调用Xandra.prepare/3时触发了不匹配的函数子句。
核心问题:自定义认证器实现不符合协议要求
你的MyApp.CassandraAuth没有正确实现Xandra.Authenticator行为的规范。Cassandra的PasswordAuthenticator协议要求认证响应是<<0>> <> 用户名 <> <<0>> <> 密码的字节序列,而你返回的是字符串列表,这会直接导致认证失败,节点连接不上。
解决方法
方法1:使用Xandra内置密码认证器(推荐)
无需自定义认证器,直接用Xandra官方提供的Xandra.PasswordAuthenticator,配置简单且不易出错:
{:ok, conn} = Xandra.start_link( nodes: ["127.0.0.1:9042", "127.0.0.1:9043"], authentication: Xandra.PasswordAuthenticator, username: "cassandra", password: "cassandra", name: :xandra_pool, pool: Xandra.Cluster, after_connect: fn(conn) -> Xandra.execute(conn, "USE ks_test") end )
方法2:修复自定义认证器的实现
如果必须自定义认证器,确保response_body/1返回符合Cassandra协议的字节序列:
defmodule MyApp.CassandraAuth do @behaviour Xandra.Authenticator def response_body(options) do username = Keyword.fetch!(options, :user) password = Keyword.fetch!(options, :password) # 严格按照Cassandra PasswordAuthenticator协议构造响应 <<0>> <> username <> <<0>> <> password end end
额外检查项
- 确认Cassandra节点确实在
127.0.0.1:9042和127.0.0.1:9043端口运行,且网络可达 - 确认
ks_test键空间已存在,否则after_connect中的USE ks_test会抛出错误,影响连接池初始化 - 检查Cassandra配置是否开启了
PasswordAuthenticator(默认开启,若修改过需确认)
修复认证问题后,Xandra就能成功连接到Cassandra节点并初始化集群连接池,后续的Xandra.prepare/3调用即可正常工作。
内容的提问来源于stack exchange,提问作者Stoecki
相关产品推荐
相关产品推荐

