有人有 ssl 使用 Python Cassandra 驱动程序和 eventlet 吗?

Does anybody have ssl working with the Python Cassandra driver and eventlet?

我无法让 ssl 与 Python Cassandra 驱动程序和 eventlet 一起工作。 我们正在使用 Python 3.4、eventlet 18.3 和 Cassandra 驱动程序 3.0.0。没有 ssl 的 Eventlet 和没有 eventlet 的 ssl 都有效。

有人知道 ssl、cassandra 和 eventlet 的组合可以与 Python 一起使用吗?如果有,是什么版本?

代码示例可能要求太多,但会很有帮助。

2016 年 2 月 18 日跟进:抱歉这么简洁。这是一些代码,全部带有 Python3:

首先,最简单的 Cassandra 客户端。没有 eventlet,没有 ssl。有效:

from cassandra.cluster import Cluster
cluster = Cluster(contact_points=['<ip>'],
                  connection_class=None)
session = cluster.connect('<keyspace>')
print("OK, session:", session)

接下来,eventlet。没有线程,所以 eventlet 在这里毫无意义。但它有效:

from cassandra.cluster import Cluster
from cassandra.io.eventletreactor import EventletConnection
cluster = Cluster(contact_points=['<ip>'],
                  connection_class=EventletConnection)
session = cluster.connect('<keyspace>')
print("OK, session:", session)

接下来,ssl,没有 eventlet。这也有效:

import ssl
from cassandra.cluster import Cluster
from cassandra.auth import PlainTextAuthProvider
cluster = Cluster(contact_points=['<ip>'],
                  connection_class=None,
                  ssl_options=dict(ca_certs='<certfile>',
                                   cert_reqs=ssl.CERT_REQUIRED,
                                   ssl_version=ssl.PROTOCOL_TLSv1),
                  auth_provider=PlainTextAuthProvider(username='<user>',
                                                      password='<pass>'))
session = cluster.connect('<keyspace>')
print("OK, session:", session)

最后是ssl和eventlet。这失败了:

import ssl
from cassandra.cluster import Cluster
from cassandra.auth import PlainTextAuthProvider
from cassandra.io.eventletreactor import EventletConnection
cluster = Cluster(contact_points=['<ip>'],
                  connection_class=EventletConnection,
                  ssl_options=dict(ca_certs='<certfile>',
                                   cert_reqs=ssl.CERT_REQUIRED,
                                   ssl_version=ssl.PROTOCOL_TLSv1),
                  auth_provider=PlainTextAuthProvider(username='<user>',
                                                      password='<pass>'))
session = cluster.connect('<keyspace>')
print("OK, session:", session)

回溯显示我们正在使用 eventlet.green.ssl:

Traceback (most recent call last):
  File "/home/jk/eventlet/venv3/lib/python3.5/site-packages/eventlet/hubs/poll.py", line 115, in wait
    listener.cb(fileno)
  File "/home/jk/eventlet/venv3/lib/python3.5/site-packages/eventlet/green/select.py", line 55, in on_read
    current.switch(([original], [], []))
  File "/home/jk/eventlet/venv3/lib/python3.5/site-packages/eventlet/greenthread.py", line 214, in main
    result = function(*args, **kwargs)
  File "/home/jk/eventlet/venv3/lib/python3.5/site-packages/cassandra/io/eventletreactor.py", line 98, in <lambda>
    self._read_watcher = eventlet.spawn(lambda: self.handle_read())
  File "/home/jk/eventlet/venv3/lib/python3.5/site-packages/cassandra/io/eventletreactor.py", line 153, in handle_read
    buf = self._socket.recv(self.in_buffer_size)
  File "/home/jk/eventlet/venv3/lib/python3.5/site-packages/eventlet/green/ssl.py", line 198, in recv
    read = self.read(buflen)
  File "/home/jk/eventlet/venv3/lib/python3.5/site-packages/eventlet/green/ssl.py", line 138, in read
    super(GreenSSLSocket, self).read, *args, **kwargs)
  File "/home/jk/eventlet/venv3/lib/python3.5/site-packages/eventlet/green/ssl.py", line 112, in _call_trampolining
    return func(*a, **kw)
  File "/home/jk/python-org/dst/python-3.5.1/lib/python3.5/ssl.py", line 786, in read
    return self._sslobj.read(len, buffer)
TypeError: must be read-write bytes-like object, not None
Removing descriptor: 5
Traceback (most recent call last):
  File "so4.py", line 13, in <module>
    session = cluster.connect('<keyspace>')
  File "cassandra/cluster.py", line 824, in cassandra.cluster.Cluster.connect (cassandra/cluster.c:11354)
  File "cassandra/cluster.py", line 850, in cassandra.cluster.Cluster.connect (cassandra/cluster.c:11176)
  File "cassandra/cluster.py", line 844, in cassandra.cluster.Cluster.connect (cassandra/cluster.c:11056)
  File "cassandra/cluster.py", line 2041, in cassandra.cluster.ControlConnection.connect (cassandra/cluster.c:36224)
  File "cassandra/cluster.py", line 2076, in cassandra.cluster.ControlConnection._reconnect_internal (cassandra/cluster.c:37080)
cassandra.cluster.NoHostAvailable: ('Unable to connect to any servers', {'<ip>': OperationTimedOut('errors=Timed out creating connection (5 seconds), last_host=None',)})

同样,没有实际线程。但是我们的真实系统确实使用了它们。

如果我在设置中包含 eventlet.monkey_patch(),我没有发现任何区别。 真实系统有。

这似乎是由 cassandra-drivers eventlet 代码在 ssl 套接字上使用 select.select() 引起的。这会导致此处所述的问题:select and ssl in python

此问题已在 https://github.com/datastax/python-driver/pull/485

中修复