经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » Go语言 » 查看文章
记一个 aliyun tablestore go client 的大坑
来源:cnblogs  作者:alfred_zhong  时间:2021/3/1 9:16:47  对本文有异议

有个项目年前要做最后一次上线。项目中有用到 aliyun tablestore 的一个模块我做了一次重构。

这个模块的主要功能为从 Kafka 订阅消息,做一个的格式化处理之后存储到 aliyun 的 TableStore。并且提供接口根据查询参数从 aliyun tablestore 查询相关的数据。重构后查询接口的部分代码如下:

  1. func GetLimit(userID, deviceName string, messageID int64, limit int32) ([]*StoredMessage, error) {
  2. request := &tablestore.GetRangeRequest{}
  3. rangeRowQueryCriteria := &tablestore.RangeRowQueryCriteria{}
  4. rangeRowQueryCriteria.TableName = tableName
  5. startPK := new(tablestore.PrimaryKey)
  6. startPK.AddPrimaryKeyColumn(primaryUserID, userID)
  7. startPK.AddPrimaryKeyColumn(primaryDeviceName, deviceName)
  8. startPK.AddPrimaryKeyColumn(primaryMessageID, messageID)
  9. endPK := new(tablestore.PrimaryKey)
  10. endPK.AddPrimaryKeyColumn(primaryUserID, userID)
  11. endPK.AddPrimaryKeyColumn(primaryDeviceName, deviceName)
  12. endPK.AddPrimaryKeyColumn(primaryMessageID, math.MinInt64)
  13. rangeRowQueryCriteria.StartPrimaryKey = startPK
  14. rangeRowQueryCriteria.EndPrimaryKey = endPK
  15. rangeRowQueryCriteria.Direction = tablestore.BACKWARD
  16. rangeRowQueryCriteria.MaxVersion = 1
  17. rangeRowQueryCriteria.Limit = limit
  18. request.RangeRowQueryCriteria = rangeRowQueryCriteria
  19. response, err := client.GetRange(request)
  20. if err != nil {
  21. return nil, err
  22. }
  23. ...
  24. }

项目更新上线之后,查询接口失效了。从日志系统没有捞到错误日志。这么一想,可能是 panic 了,从 daoker 容器直接去捞日志。果然,发现了 panic 的信息。(由于这个模块的 panic 日志没有通过 syslog 发送出去,所以日志系统查不到。万恶的 panic)

好了,分析问题(panic 日志具体已经找不到了,我没存下来)。问题在 client.GetRange 这个方法上,根据源码进一步深入,会发现下面的代码:

  1. func NewPrimaryKeyColumn(name []byte, value interface{}, option PrimaryKeyOption) *PrimaryKeyColumnInner {
  2. if option == NONE {
  3. v := &PrimaryKeyColumnInner{}
  4. v.Name = name
  5. t := reflect.TypeOf(value)
  6. switch t.Kind() {
  7. case reflect.String:
  8. v.Type = otsprotocol.PrimaryKeyType_STRING
  9. case reflect.Int64:
  10. v.Type = otsprotocol.PrimaryKeyType_INTEGER
  11. case reflect.Slice:
  12. v.Type = otsprotocol.PrimaryKeyType_BINARY
  13. default:
  14. panic(errInvalidInput)
  15. }
  16. v.Value = value
  17. return v
  18. } else if option == AUTO_INCREMENT {
  19. return NewPrimaryKeyColumnAuto_Increment(name)
  20. } else if option == MIN {
  21. return NewPrimaryKeyColumnINF_MIN(name)
  22. } else {
  23. return NewPrimaryKeyColumnINF_MAX(name)
  24. }
  25. }

所以它的 PrimaryKeyColumn 的值类型只能是 string, int64 或者 slice 其中一种。而我传递的 math.MinInt64 是 untyped int。就直接 panic 了。

解决方法简单,转一下就行了。int64(math.MinInt64)

这个 sdk 的注释真的不多,GetRange 的方法上也没有注释,真是让人很容易用错。最根本问题是,这种直接 panic 的代码逻辑真的是害死人。所以啊 Don't use panic, use error!

使用的 aliyun tablestore go client sdk 版本为 v4.1.3。aliyun-tablestore-go-sdk@v4.1.3

原文链接:http://www.cnblogs.com/snowInPluto/p/14442110.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号