Swift/Eventlet-removal
目录
从 Swift 中移除 eventlet
通用信息
https://governance.openstack.org/tc//goals/selected/remove-eventlet.html https://wiki.openstack.org/wiki/Eventlet-removal
Swift eventlet POC
目前这是一个 POC,用于讨论可行的移除 eventlet 的方法。撰写本文时,这使得在未安装 eventlet 的情况下运行 account-server 成为可能,使用 gunicorn 作为 wsgi 服务器。Gunicorn 目前看起来很有希望,并且已经包含在全局 openstack/requirements 中。Account server 的单元测试和功能测试(非进程内)也通过了。初步基准测试显示,与使用 eventlet.wsgi 相比,速度差异约为 +/- 15%,但尚未调整任何设置。
补丁已提交到 feature/threaded 分支:https://review.opendev.org/q/project:openstack/swift+branch:feature/threaded+(status:open+OR+status:merged)
POC 状态
模块导入
POC 替换了几个类(例如 GreenPool、Timeout 等)为虚拟类,以便在未安装 eventlet 的情况下导入 swift 模块。这可以通过设置环境变量 "DISABLE_EVENTLET=true" 来启用。理想情况下,我们希望在配置文件中进行此操作,但是 Swift 在我们甚至开始解析配置文件之前,会导入大量的 eventlet 模块(由于依赖关系)。
尽可能地,eventlet 导入已被替换为其原生对应项,例如 eventlet.green.socket -> socket。有些导入在不使用 eventlet 时暂时被禁用,以便使 POC 运行 account-server 正常工作。
测试
在安装 eventlet 的情况下,所有测试都应该仍然通过。在某些情况下,这需要一些变通方法,以避免目前对测试进行大量修改,例如在 https://review.opendev.org/c/openstack/swift/+/959193/6/swift/common/wsgi.py 中添加 shutdown_safe(),以确保在安装 eventlet 的情况下进行测试时仍然调用 greenio.shutdown_safe()。
入门
要开始使用,请签出最新的补丁(当前为 #960454)
git fetch ssh://cschwede@review.opendev.org:29418/openstack/swift refs/changes/54/960454/4 && git checkout FETCH_HEAD
建议使用一个没有安装 eventlet 的全新 virtualenv。
virtualenv ~/.venv3withouteventlet/ source ~/.venv3withouteventlet/bin/activate pip install setuptools python setup.py develop pip install -r test-requirements.txt pip uninstall eventlet
如果设置了环境变量 "DISABLE_EVENTLET=true",eventlet 导入(目前部分)将被替换,并且 account-server 和一些测试可以在不使用 eventlet 的情况下运行。例如
DISABLE_EVENTLET=true pytest test/unit/account/test_server.py DISABLE_EVENTLET=true swift-account-server etc/account-server.conf-sample -v # stays in foreground DISABLE_EVENTLET=true SWIFT_TEST_IN_PROCESS=false pytest test/functional/test_account.py
下一步短期计划
- 确保所有覆盖所有更改的测试在没有 eventlet 的情况下通过。这需要一些有效的替换,例如进程内 wsgi.server、可用的 Timeout() 类等。
- 使用配置文件设置而不是环境变量来禁用 eventlet。
想法
- 使用 asyncio 与 eventlet+gunicorn 结合起来,可能更有意义,以便更容易地迁移。请参阅 https://eventlet.readthedocs.io/en/latest/asyncio/migration.html#step-1-switch-to-the-asyncio-hub
- 对于不运行 wsgi 服务器的守护进程(replicators、auditors 等),使用原生线程和 ThreadPoolExecutor 可能是可行的方案。