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

Python通过HTTPS子域名连接Cassandra时遭遇ProtocolError求助

解决Cassandra通过Nginx HTTPS映射后Python连接报错的问题

问题场景

我的Cassandra运行在虚拟机的9042端口,通过Nginx映射到HTTPS子域名mysub.original.com的443端口,使用以下Python代码尝试连接:

from cassandra.cluster import Cluster

CASSANDRA_DB_HOST="mysub.original.com"
CASSANDRA_DB_PORT = 443
CASSANDRA_DB_KEYSPACE = "test"
table_name = "test_tab"

def read_cassandra_table(host, port, keyspace, table):
    cluster = Cluster([host], port=port,protocol_version=4)
    session = cluster.connect(keyspace)

    session.shutdown()
    cluster.shutdown()

read_cassandra_table(CASSANDRA_DB_HOST, CASSANDRA_DB_PORT, CASSANDRA_DB_KEYSPACE, table_name)

无论更换cassandra-driver版本,还是添加/移除protocol_version=4参数,都会触发以下错误:

python test.py 
Traceback (most recent call last):
  File "/home/poc/latest_abc_backend/abc-backend/test.py", line 101, in <module>
    read_cassandra_table(CASSANDRA_DB_HOST, CASSANDRA_DB_PORT, CASSANDRA_DB_KEYSPACE, table_name)
  File "/home/poc/latest_abc_backend/abc-backend/test.py", line 87, in read_cassandra_table
    session = cluster.connect(keyspace)
              ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/poc/updated_venv/lib/python3.11/site-packages/cassandra/cluster.py", line 1690, in connect
    self.control_connection.connect()
  File "/home/poc/updated_venv/lib/python3.11/site-packages/cassandra/cluster.py", line 3488, in connect
    self._set_new_connection(self._reconnect_internal())
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/poc/updated_venv/lib/python3.11/site-packages/cassandra/cluster.py", line 3533, in _reconnect_internal
    raise NoHostAvailable("Unable to connect to any servers", errors)
cassandra.cluster.NoHostAvailable: ('Unable to connect to any servers', {'155.69.11.95:443': ProtocolError('This version of the driver does not support protocol version 72')})

错误原因

核心问题是协议不兼容:Cassandra使用专属的原生二进制协议,而你用Nginx配置的是HTTPS(HTTP over TLS)服务。当Python driver连接443端口时,Nginx会将请求识别为HTTP请求并返回HTTP响应,driver误将响应中的某个字段当成了Cassandra的协议版本号,才会出现“不支持协议版本72”的异常——Cassandra的合法协议版本最高仅到v5,72完全不属于它的版本体系。

解决方案

1. 调整Nginx配置为TCP转发

需要使用Nginx的stream模块处理TCP流量,而非HTTP/HTTPS的server块,因为Cassandra是基于TCP的服务。如果需要加密传输,可选择以下两种方案:

方案1:Nginx stream模块做TLS终止

在Nginx配置中添加stream块,将443端口的TLS流量转发到虚拟机内的Cassandra 9042端口:

stream {
    server {
        listen 443 ssl;
        proxy_pass 127.0.0.1:9042; # 替换为虚拟机内Cassandra的实际地址和端口

        # 配置SSL证书和密钥路径
        ssl_certificate /path/to/your/cert.pem;
        ssl_certificate_key /path/to/your/key.pem;
    }
}

注:大部分发行版的默认Nginx包已包含stream模块,若未包含需重新编译启用。

方案2:直接启用Cassandra自带SSL

若不想通过Nginx做TLS终止,可直接在Cassandra的cassandra.yaml配置文件中开启SSL,指定加密端口(默认9142),再让Nginx做纯TCP转发,或让driver直接连接Cassandra的SSL端口。

2. 修改Python连接代码

如果采用方案1的Nginx TLS终止配置,Python driver需要开启SSL连接,调整Cluster初始化参数:

import ssl
from cassandra.cluster import Cluster

def read_cassandra_table(host, port, keyspace, table):
    # 若使用自签名证书,需指定CA证书路径
    ssl_context = ssl.create_default_context(cafile="/path/to/your/ca.pem")
    cluster = Cluster(
        [host], 
        port=port,
        ssl=True,
        ssl_context=ssl_context
    )
    session = cluster.connect(keyspace)

    session.shutdown()
    cluster.shutdown()

若证书是权威机构签发的,可省略ssl_context参数,直接设置ssl=True即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 07:11:03