You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Avatica-Go客户端连接Phoenix查询服务器负载均衡地址失败排查

问题排查:Go Avatica客户端连接Nginx负载均衡Phoenix Query Server时报错"driver: bad connection"

环境信息

  • 组件版本:Hbase 2.0.0、Phoenix 5.0.0、Avatica-go-client 5.2.0、带sticky模块的Nginx 1.8.1
  • 部署架构:3个Regionserver、3个Query Server,Nginx部署于192.168.3.236,配置sticky负载均衡,原配置如下:
upstream phoenix_balance {
        sticky expires=1m;
        server 192.168.3.190:8765;
        server 192.168.3.236:8765;
        server 192.168.3.165:8765;
    }

server {
        listen 8766;
        server_name localhost;
        location / {
                proxy_pass http://phoenix_balance/;
        }
    }

测试现象

  • Java客户端连接单个PQS或负载均衡地址均正常,代码示例:
Class.forName("org.apache.phoenix.queryserver.client.Driver");
String url = "jdbc:phoenix:thin:url=http://192.168.3.236:8766;serialization=PROTOBUF";
conn = DriverManager.getConnection(url, prop);
  • Go客户端连接单个PQS正常,但连接负载均衡地址http://192.168.3.236:8766时出现错误driver: bad connection,代码示例:
db, err := sql.Open("avatica", "http://192.168.3.236:8765") // 正常
db, err := sql.Open("avatica", "http://192.168.3.236:8766") // 失败,报错driver:bad connection
rows, err := db.Query("SELECT COUNT(*) FROM test.test1")

配置问题分析与调整建议

1. Nginx配置缺失关键转发参数

Java客户端能正常工作不代表Nginx配置无问题,Go的Avatica客户端对HTTP连接细节更敏感,原配置缺少以下关键设置:

(1)Host头传递

Phoenix Query Server可能依赖请求的Host头处理会话,原配置中server_name localhost会导致转发到后端的Host头被设置为localhost,而非客户端实际请求的192.168.3.236:8766,这会导致PQS无法正确识别请求来源。

(2)HTTP持久连接支持

Avatica客户端默认使用HTTP/1.1持久连接,Nginx默认配置未明确开启该支持,可能导致连接被提前关闭。

调整后的Nginx配置

upstream phoenix_balance {
        sticky expires=1m;
        server 192.168.3.190:8765;
        server 192.168.3.236:8765;
        server 192.168.3.165:8765;
    }

server {
        listen 8766;
        server_name 192.168.3.236 localhost; # 匹配实际请求IP和本地访问
        location / {
                proxy_http_version 1.1;          # 启用HTTP/1.1
                proxy_set_header Connection "";   # 清空Connection头,适配持久连接
                proxy_set_header Host $host:$server_port; # 传递客户端请求的Host信息
                proxy_set_header X-Real-IP $remote_addr; # 传递真实客户端IP
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_pass http://phoenix_balance/;
        }
    }

2. Sticky会话保持的Cookie兼容性问题

Nginx的sticky模块基于Cookie实现会话保持,但Avatica-Go客户端默认不自动处理Cookie,导致每次请求被分发到不同的PQS节点,而Avatica的连接会话是绑定到单个PQS实例的,跨节点请求会触发bad connection错误。

解决方式:

  • 临时测试:注释Nginx配置中的sticky expires=1m;,关闭会话保持后测试Go客户端是否能连接,验证是否为Cookie问题。
  • 代码调整:如果确实是Cookie问题,修改Go代码启用Cookie管理,示例如下:
import (
    "database/sql"
    "net/http"
    "net/http/cookiejar"

    _ "github.com/apache/calcite-avatica-go/v5"
)

func main() {
    // 创建Cookie Jar,用于存储会话Cookie
    jar, err := cookiejar.New(nil)
    if err != nil {
        panic(err)
    }
    // 配置带Cookie管理的HTTP客户端
    httpClient := &http.Client{Jar: jar}
    
    db, err := sql.Open("avatica", "http://192.168.3.236:8766")
    if err != nil {
        panic(err)
    }
    defer db.Close()

    // 将自定义HTTP客户端注入Avatica驱动
    if driver, ok := db.Driver().(*avatica.Driver); ok {
        driver.SetHTTPClient(httpClient)
    }

    rows, err := db.Query("SELECT COUNT(*) FROM test.test1")
    if err != nil {
        panic(err)
    }
    defer rows.Close()
    
    // 处理查询结果...
}

3. Nginx版本兼容性

Nginx 1.8.1版本较老,sticky模块可能存在兼容性问题,若上述调整无效,可尝试升级Nginx到较新版本(如1.20+)再测试。

内容的提问来源于stack exchange,提问作者kaber

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 03:24:58