Client Design
大约 7 分钟约 2215 字
背景
由于Influxdb 1.X的客户端已经基本处于维护状态,同时openGemini仍在不断发展中,为了能够更好地支持openGemini,如支持对接多个服务端地址、支持对接Apache Arrow Flight协议等,社区决定开发属于openGemini自己的客户端SDK。
客户端SDK规划功能
- 支持对接多个服务端地址
- 支持对接Apache Arrow Flight协议
- 支持Sql查询、结构化查询、写入、批量写入等,详见下文UML图
- 默认超时,连接超时10秒,读写超时30秒
本文的方法假定编程语言不支持重载,如编程语言支持重载,可以对方法名进行一些优化调整。
客户端构造参数设计
Database & RetentionPolicy管理设计
写入点位设计
Execute 接口设计
Execute 接口提供了一个统一的 SQL 执行接口,可以自动将不同类型的语句路由到相应的底层方法。该设计支持类 SQL 语句,包括 INSERT、SELECT、CREATE、DROP 和其他数据库操作,并提供参数支持和类型安全。
语句路由逻辑
参数支持
Execute 接口支持参数化语句并自动进行类型转换:
使用示例
基本用法
result, err := client.Execute(opengemini.Statement{
Database: "mydb",
Command: "SELECT * FROM weather LIMIT 10",
})
参数化查询
result, err := client.Execute(opengemini.Statement{
Database: "mydb",
Command: "SELECT * FROM weather WHERE location=$loc AND temp>$temp",
Params: map[string]any{
"loc": "beijing",
"temp": 25.0,
},
})
参数化插入
result, err := client.Execute(opengemini.Statement{
Database: "mydb",
Command: "INSERT weather,location=$location temperature=$temp,humidity=$hum",
Params: map[string]any{
"location": "shanghai",
"temp": 30.2,
"hum": 70,
},
})
查询设计
OpenTelemetry 集成设计
为增强 OpenGemini 客户端的可观测性,便于追踪与查询、写入操作相关的性能指标、错误及其他信息,本方案采用拦截器模式集成 OpenTelemetry,实现全链路追踪。该设计支持非侵入式扩展,允许与其他拦截器(如日志、认证拦截器)共存,同时最大限度减少对原有客户端的修改。
拦截器设计
拦截器模式定义了标准化接口,用于挂钩客户端操作(查询/写入)并注入遥测逻辑。
定义基础客户端类,关联拦截器接口
基础 Client 类管理一组拦截器,允许在客户端操作期间动态注册和执行拦截器逻辑。
定义集成 OpenTelemetry 的拦截器实现类,实现 Interceptor 接口
OtelClient 类实现 Interceptor 接口,嵌入 OpenTelemetry 逻辑以捕获客户端操作的跟踪、指标和日志。
追踪系统核心模块
使用示例(Go language examples)
func main() {
var ctx = context.Background()
shutdown, err := setupOtelSDK(ctx)
if err != nil {
return
}
defer func() {
err = errors.Join(err, shutdown(ctx))
}()
config := &opengemini.Config{
Addresses: []opengemini.Address{{
Host: "127.0.0.1",
Port: 8086,
}},
}
client, err := opengemini.NewClient(config)
if err != nil {
fmt.Println(err)
return
}
client.Interceptors(opengemini.NewOtelInterceptor())
err = client.CreateDatabase("db0")
if err != nil {
}
}
查询构造器设计
Ping 设计
Inner Http client 设计
使用类似InnerHttpClient的设计,将鉴权、负载均衡、重试等逻辑封装在内部,对client提供简单的接口。增强模块化和代码清晰度。
错误处理
错误信息
场景1 http请求失败
$operation request failed, error: $error_details
场景2 http响应码不符合预期
$operation error resp, code: $code, body: $body
场景3 其他异常
$operation failed, error: $error_details
# example:
writePoint failed, unmarshall response body error: json: cannot unmarshal number ...