一个支持微服务快速集群的 SDK。
项目描述
QC簇
Quick Cluster - 用于故障转移和复制的简单服务注册表。
背景和问题
在现代服务中,期望开箱即用地提供故障转移、复制或两者。特别是在分布式云架构中,节点可以按需启动,注册新服务是确保可扩展性和可靠性的重要部分。有几种强大的服务管理解决方案,包括 Apache Zookeeper、Istio Service Mesh 和 Linkerd。它们中的每一个要么实现流量代理,要么具有复杂的架构要求。有时,服务不需要全套功能,需要一种轻量级的方式来处理故障转移。
解决方案
QCluster 旨在成为一种轻量级服务,可为不需要与其他服务网格工具相关的繁重工作的服务启用故障转移和复制。这可以通过以下方式实现:
- 确保 QCluster 客户端可以在无主环境中运行
- 也允许主从模型,这可能有利于有状态的应用程序
- 鼓励自我注册
- 启用内置指标
- API 访问和客户端 SDK
贡献
QCluster 项目是使用 tox 构建的,它公开了一些开发工具。运行 tox 会自动运行 flake8 以检查代码样式以及运行单元测试套件并生成代码覆盖率报告。
要运行单元测试,只需在项目目录中运行 tox:
[Aarons-MacBook-Pro:qcluster] Aaron% tox
...
py38 run-test: commands[1] | coverage report
Name Stmts Miss Cover
-----------------------------------------------
qcluster/__init__.py 2 0 100%
qcluster/communication.py 147 0 100%
qcluster/consensus.py 134 3 98%
qcluster/qcluster.py 23 3 87%
qcluster/registry.py 41 9 78%
qcluster/utils.py 18 0 100%
-----------------------------------------------
TOTAL 365 15 96%
py38 run-test: commands[2] | coverage html
py38 run-test: commands[3] | flake8 qcluster
____________________________________________________ summary _____________________________________________________
py38: commands succeeded
congratulations :)
在为项目做贡献时,请牢记以下做法:
- 符合 flake8 样式指南以保持一致性
- 努力为添加的新代码添加单元测试
管道
我们使用 Github Actions 来处理这个包到 PyPI 的发布。从 Alpha -> Beta -> Production 升级后,我们将自动化构建,使其更具限制性和事件驱动。目前,构建和发布是通过手动工作流运行触发的。导航到 GitHub Actions 选项卡并运行工作流。工作流运行应该从master分支生成。
我们在 PyPI ( https://pypi.org/project/QCluster/ ) 上托管 QCluster,并在以下架构上运行测试:
- Ubuntu Linux(最新)
- 马科斯(最新)
- 窗户(最新)
可以通过 Github Actions 矩阵集成对其他操作系统或特定操作系统的支持。
Python 支持
目前仅支持 Python 3.8,但这可能会在更高版本的 Python 上运行。asyncio库严重依赖于哪个将是支持 Python 版本的主要驱动因素。
QCluster SDK
is_leader()
用于判断当前peer是否是集群的leader。
cluster = QCluster(**configuration)
if cluster.is_leader():
print("I am the leader")
else:
print("I am a follower")
get_leader_info()
Used to get more detailed information about the known elected leader. 如果没有选举出领导者(在不可能获得多数票的情况下),这将返回None。
领导者将在Peer具有以下属性的对象中返回:
- host: QCluster 通信可以到达的主机
- 端口:QCluster 通信可以到达此对等体的端口
- 标识符:此对等体的唯一字符串标识符
- metadata:由配置文件提供的元数据字典。
cluster = QCluster(**configuration)
leader = cluster.get_leader_info()
print("Leader communicates with QCluster on {}:{}".format(leader.host, leader.port))
print("Leader has an identifier of: {}".format(leader.identifier))
print("Leader has custom metadata of: {}".format(leader.metadata))
Leader communicates with QCluster on localhost:7001
Leader has an identifier of: server_a
Leader has custom metadata of: {"custom_field": 5"}
例子
下面使用以下配置文件显示了使用 QCluster 的一些示例(适用于更改了相应字段的各个对等方)。
{
"identifier": "server_a",
"listen_host": "localhost",
"listen_port": 7001,
"peers": [
{"host": "localhost", "port": 7002, "identifier": "server_b"},
{"host": "localhost", "port": 7003, "identifier": "server_c"}
]
}
此配置表示单个对等server_a点 ,它将接受 QCluster 上的数据localhost:7001。它有 2 个对等点,server_b可以server_c分别连接到 atlocalhost:7002和localhost:7003。
对等点的配置文件将采用类似的格式server_b,server_c但每个对等点都有适当的数据,以了解其他对等点。
自定义元数据
对等点可以在配置文件中具有与之关联的自定义元数据。将对等条目更改为:
{"host": "localhost", "port": 7002, "identifier": "server_b", "metadata": {"server_port": 8002}}
导致该对等点的数据{"server_port": 8002}可供metadata属性中的所有其他对等点访问。Therefore, follower peers can have access to more information about the elected leader to perform more complex tasks as a follower (such as redirecting one's traffic to the leader).
最低限度
from qcluster import QCluster
import asyncio
import sys
import json
async def main():
conf_file = sys.argv[1]
with open(conf_file) as f:
conf = json.load(f)
identifier = conf['identifier']
cluster = QCluster(**conf)
while True:
if cluster.is_leader():
logger.info("I am the leader!")
logger.info("{} is doing some work...".format(identifier))
else:
logger.info("I am not the leader :(")
logger.info("This is the leader: {}".format(cluster.get_leader_info()))
await asyncio.sleep(1)
if __name__ == "__main__":
asyncio.run(main())
使用 、和的 3 个版本的配置文件运行此程序server_a,将导致单个对等节点成为领导者。如果它是领导者,每个对等点的工作循环要么做“工作”,要么闲置直到它成为领导者。server_bserver_c
高级示例
请在示例目录中查找一些更深入和具体的示例。
项目详情
下载文件
下载适用于您平台的文件。如果您不确定要选择哪个,请了解有关安装包的更多信息。