如何实现 SQL 用户标签的查询?

1 Preface

在社交 APP 中,经常会看到用户标签功能,那么这个功能如何实现呢? 如微信的用户标签。

user-label

考虑两种情况:

  1. 标签的量级较大,我们需要基于 ES 来加速查询;
  2. 标签量级较小,可以使用数据库实现一个简易版的标签功能;

下面我们使用数据库,实现一个简易的标签功能;

……

阅读全文

Proto oneof schema 的使用

1 Preface protobuf 提供了 oneof 语义,表示任选其一;类似于C语言的 union 关键字。 于是想了解下 oneof 语义在 golang 中是如何实现的,下面我们来一探究竟。 具体的用法如下: 1 2 3 4 5 6 7 8 9 10 11 message WechatPay { int64 uuid = 1; } message HelloRequest { string msg = 1; oneof one_of_pay { string noop = 2; WechatPay wx = 3; } } 2 stub 代码分析 使用 protoc 工具会生成如下代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 // 定义一个接口,用于类型断言 type isHelloRequest_OneOfPay interface { isHelloRequest_OneOfPay() } type HelloRequest_Noop struct { Noop string `protobuf:"bytes,2,opt,name=noop,proto3,oneof"` } type HelloRequest_Wx struct { Wx *WechatPay `protobuf:"bytes,3,opt,name=wx,proto3,oneof"` } // 接口实现 empty // implements isHelloRequest_OneOfPay interface func (*HelloRequest_Noop) isHelloRequest_OneOfPay() {} // 接口实现 empty // implements isHelloRequest_OneOfPay interface func (*HelloRequest_Wx) isHelloRequest_OneOfPay() {} 3 总结 在 Golang 中, oneof 语义基于一个类型接口,oneof 的每个成员都实现这个接口,方便在Ge……

阅读全文

多个集合,取交集

1 Preface 最近在一直采用 go 语言进行项目开发,遇到一个比较有意思的问题: 多个集合,计算交集,哪种计算方法最高效? 假定集合采用 HashMap 来实现,那么每次查询的时间复杂度为 O(1) 考虑最简单的情况,假定有2个集合A和B,A 的元素个数为2, B 的元素个数为10。 计算A和B的交集有 2 个方案: 方案一:先遍历A,在B中查找是否存在,时间复杂度为 2*O(1) 方案二:时间复杂度为 10*O(1) 于是得出结论: 每次遍历最小的集合去计算交集,总的时间复杂度最小。 2 寻找已有的轮子 由于 go 标准库,并不提供 set 数据结构;先尝试用 google 搜索,fatih/set 出镜率比较高。 于是……

阅读全文

业务缓存之可行性?

1 Preface 在业务系统中,为了提高服务的性能,降低平均时延,一个常用的手段:增加cache。 鲁迅:-)人们发明一种方法解决一个问题,而几乎总是会引入另一个问题。 那么可能会问:Cache 要加在哪里,要缓存多久,才会更有效? 下面就拿一个例子,来展开看看。 2 分析 一般而言,需要对执行频率高,耗时占比大的逻辑,优先增加Cache。 但是要注意:增加 Cache 不能影响到业务的正确性。 适用场景:数据变化不频繁,因为一旦数据发生变化,Cache可能产生不一致。 对于不一致,还需要设计一个合理的失效时间,在业务可接受的误差之内增加c……

阅读全文

基于 go 的 wireshark 插件实现方案

1 背景 在业务服务重构过程中,发现后台一些RPC服务,使用的自定义的应用层协议(七层)。 为了方便验证重构逻辑,想在在海量的请求中,快速找到某一类业务请求包。 2 思考 一般来说简单的协议使用 lua 实现即可,但是遇到 pb/thrift 等 tlv 类型的协议就比较麻烦了; 比较友好的是,目前有 lua-protobuf 这样的库,可以在lua中解析PB协议, 只需要提供proto即可; 但是对于内部的 tlv 协议,由于本人不太会使用lua去封装c库; 突然萌生了一个想法,能不能用 golang 来开发 wireshark 插件? 是否可以让 lua5.2 直接调用cgo? 3 定制目标(okr) 定位: 本地的报文分析工具 1 当业务……

阅读全文

wireshark lua 插件tcp报文分段(desegment)?

缘起 我们知道 一般网路中 以太网的帧长度不超过 1500字节(MTU),所以单个 tcp segment 最大为1460; 如果我们业务报文超过 1420 字节(tcp payload),就会被分成多个 segment。 那么如何在 编写 wireshark 插件时,拿到一个完整的业务报文呢? 解决办法 通过goolge,发现解决办法非常简单,只需要为pinfo.desegment_len 还需要的字节长度即可。 1 2 3 4 5 6 7 8 9 10 11 -- 在入口处 function slicer.dissector(tvb, pinfo, tree) ... local pdu_length = get_pdu_length(...) if pdu_length > tvb:len() then pinfo.desegment_len = pdu_length - tvb:len() else do_dissection(tvb, pifo, tree) end return end 如果不知道明确的长度,那我们也可以: 1 pinfo.desegment_len = DESEGMENT_ONE_MORE_SEGMENT 总结 通过 wireshark lua 插件的编写,发现很……

阅读全文

wireshark lua 插件之 tvb():string()

缘起 最近在编写 lua 插件时,遇到一个问题:发现tvb中的字节码,传入 lua-protobuf 中,部分报文解码失败。 于是经过一顿debug,最后将字节码写入文件,对比 lua-protobuf 中的字节码和 tvb 中的字节码,发现不一致。 解决办法 通过 goolge 找到了如下一篇文章,wireshark-lua-stringbyte-error 不应该使用 tvb_range:string() 这个方法默认是带字符集转换的,要想将原始的bytes转为 lua string,需要使用raw方法。 1 2 -- local lua_str = tvb_range:string() local lua_str = tvb_range:raw(tvb_range:offset(), tvb_range:len()) 总结 这个问题,本质还是没有仔细阅读 wireshark lua 插件关于 tvb 的API文档导致的。 有时候遇到问题,我们可以先通过 google……

阅读全文

wireshark插件,如何关联请求应答(如ping协议)?

缘起 最近工作中,接触的内部协议比较多(项目历史原因),于是想编写 wireshark plugin,来辅助分析业务报文, 从中寻找包含特定请求的报文。 遇到一个问题,如何对请求和应答进行关联,我知道 wireshark 解析 ping 协议,是支持ping-pong相互跳转的。 于是想自己写的协议插件,也具有这种功能,于是开始google。 在 wireshark 社区找到了sindy大神的这段回答,很受启发。原文如下: The dissector code has no access to pinfo of any other packet than the one currently dissected. If some transaction ID exists in modbus which allows you to match requests and responses, you may use two global tables indexed by this transaction ID and store the frame.number of the currently dissected packet to the appropriate table (request{transactionId} or response{transactionId}) during the first pass of the dissector (after loading the file, all packets are dissected in sequence). Whenever……

阅读全文

Go 必须知道的 18 个Go开发库

包含各种使用场景的Go第三方列表。 随着时间的推移,Go语言爱好者已经创建并共享了许多Go框架和库。这些库有不同的功能,从微服务开发到构建web应用程序! 备注:在Go语言中我们都称第三方库为package(包)。 配置文件处理库 配置文件通常以各种格式编写,如JSON和YAML。Go有一个非常有用的包,它使读取和写入各种格式的配置文件成为小菜一碟。 1、Viper:这是一个关于Go应用程序配置处理的完整解决方案,包括12-Factor应用程序。它作用在应用程序中,可以处理所有类型的配置文件和格式。 可以读……

阅读全文

最近文章

分类

友情链接

标签

其它