OpenEuler Rubik开发者手册:贡献代码前必须掌握的核心API解析
【免费下载链接】rubikrubik is a QoS manager agent for online/offline workload colocation项目地址: https://gitcode.com/openeuler/rubik
前往项目官网免费下载:https://ar.openeuler.org/ar/
作为openEuler生态中专注于工作负载协同的QoS管理工具,Rubik通过一系列设计精良的API接口实现对容器和Pod的资源调度与监控。本文将系统解析Rubik核心API的设计理念、关键接口及使用场景,帮助开发者快速掌握贡献代码所需的接口知识。
核心API架构概览
Rubik的API体系采用发布-订阅模式构建,主要定义在pkg/api/api.go文件中。该架构将系统功能抽象为四大核心接口:Viewer(数据查看)、Publisher(事件发布)、Subscriber(事件订阅)和Informer(外部数据同步),形成松耦合的组件通信机制。
图1:Rubik核心API交互流程(基于FSSR功能模块流程图)
数据查看接口:Viewer
Viewer接口提供Pod和容器信息的查询能力,是资源监控和决策的基础数据来源。其核心方法包括:
type Viewer interface { ListContainersWithOptions(options ...ListOption) map[string]*typedef.ContainerInfo ListPodsWithOptions(options ...ListOption) map[string]*typedef.PodInfo }使用场景:
- 资源调度模块查询当前节点Pod列表
- 监控组件获取容器实时状态
- 测试用例验证Pod信息正确性
关键特性:
- 支持自定义过滤条件(ListOption)
- 返回不可修改的容器/Pod信息快照
- 线程安全的并发访问设计
事件通信接口:Publisher与Subscriber
Rubik采用事件驱动架构,通过Publisher和Subscriber接口实现组件间的松耦合通信。
Publisher接口
type Publisher interface { Subscribe(s Subscriber) error Unsubscribe(s Subscriber) Publish(topic typedef.EventType, event typedef.Event) }Subscriber接口
type Subscriber interface { ID() string NotifyFunc(eventType typedef.EventType, event typedef.Event) TopicsFunc() []typedef.EventType }事件流处理流程:
- 订阅者通过
TopicsFunc()声明感兴趣的事件类型 - 发布者通过
Subscribe()注册订阅关系 - 事件发生时调用
Publish()广播事件 - 订阅者通过
NotifyFunc()处理事件
图2:Rubik事件发布-订阅时序流程
外部数据同步:Informer接口
Informer接口作为Rubik与外部数据源(如Kubernetes APIServer)的桥梁,继承Publisher能力实现数据变更事件的推送:
type Informer interface { Publisher Start(ctx context.Context) error }核心实现:
- pkg/informer/apiserverinformer.go:K8s API数据同步
- pkg/informer/nriinformer.go:NRI(Node Resource Interface)数据集成
启动流程:
- 调用
Start()方法建立外部连接 - 后台协程监听数据变更
- 通过
Publish()转换为Rubik内部事件
事件处理接口:EventHandler
EventHandler接口定义事件的具体处理逻辑,通常与Subscriber配合使用:
type EventHandler interface { HandleEvent(eventType typedef.EventType, event typedef.Event) EventTypes() []typedef.EventType }典型实现:
- 资源调整:pkg/services/quotaturbo/quotaturbo.go
- 驱逐策略:pkg/services/eviction/cpu/manager.go
- 动态缓存:pkg/services/dyncache/dyncache.go
API使用最佳实践
1. 事件订阅示例
// 实现Subscriber接口 type MySubscriber struct { id string } func (m *MySubscriber) ID() string { return m.id } func (m *MySubscriber) TopicsFunc() []typedef.EventType { return []typedef.EventType{typedef.PodAddEvent, typedef.PodUpdateEvent} } func (m *MySubscriber) NotifyFunc(eventType typedef.EventType, event typedef.Event) { // 事件处理逻辑 } // 注册订阅 publisher.Subscribe(&MySubscriber{id: "my-subscriber"})2. Pod信息查询示例
// 创建过滤条件:只查询在线Pod onlineFilter := func(pi *typedef.PodInfo) bool { return pi.QoSClass == "online" } // 获取符合条件的Pod列表 pods := viewer.ListPodsWithOptions(onlineFilter)3. Informer启动示例
ctx, cancel := context.WithCancel(context.Background()) defer cancel() informer := NewAPIServerInformer(config) if err := informer.Start(ctx); err != nil { log.Errorf("Failed to start informer: %v", err) }常见问题与调试技巧
事件订阅不生效
- 检查
TopicsFunc()是否返回正确的事件类型 - 确认订阅操作在Informer启动前完成
- 验证Subscriber的ID是否唯一
- 检查
Pod数据查询为空
- 检查Informer是否成功连接外部数据源
- 验证ListOption过滤条件是否正确
- 查看日志确认数据同步状态(pkg/common/log/log.go)
接口版本兼容性
- 遵循语义化版本控制(VERSION)
- 新增接口时保持向后兼容
- 接口变更需同步更新单元测试(如pkg/api/api_test.go)
总结
Rubik的API设计遵循接口隔离和依赖倒置原则,通过Viewer、Publisher、Subscriber和Informer四大核心接口构建了灵活可扩展的系统架构。掌握这些API的使用方法是参与Rubik开发的基础,建议开发者结合实际场景深入理解接口设计理念,并参考现有服务实现(如pkg/services/目录下的各类服务模块)进行实践。
完整的API文档可参考项目官方文档:docs/quotaturboAPI.md,更多使用示例请查看单元测试代码。
【免费下载链接】rubikrubik is a QoS manager agent for online/offline workload colocation项目地址: https://gitcode.com/openeuler/rubik
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考