微信号:Golangweb

介绍:欢迎来到 Go语言社区 社区网址:www.golangweb.com APP网址:app.golangweb.com 社区非公司性质,完全个人爱好建立;做的不好的地方大家见谅.

Golang使用redis protocol实现pubsub通信

2017-12-02 22:28 峰云就她了

作者:峰云就她了
链接:http://xiaorui.cc/?p=4847
來源:个人博客

共 1918 字,阅读需 5 分钟

前言

闲来无事,加工作不饱和,饱思淫欲的状态下,用golang实现了一个基于redis通信协议的pubsub通信服务端. 这个轮子实现的还很粗暴,内部实现主要用的是golang channel ,不仅可以高效的控制并发读写,而且可以跟tcp连接关联做事件通知。 至于持久化部分还没写完,我现在选用的是第一个方案。 该代码实现上还是比较简单,还是需要大把时间去打磨。

语言方面的选择?

我熟练的语言不多,最熟练的Python实在是写腻味了,再说Python也不适合写这类带有存储性质的服务端。openresty lua 更适合写http相关的逻辑。 最后只有Golang了… 近一年来,我大多数时间都在写Golang,熟练程度不下于Python了,只是没有更多的涉及源码实现上。

协议方面的选择?

选择redis protocol 作为通信协议的原因很简单,redis通信协议本身很是简单高效,虽然比不上thrift、protocol buffer的性能和表现力,但好在方便调试。另外,我不需要开发各个语言的协议库包,直接使用各语言的redis sdk就可以了,还附赠一个redis-cli 及redis-benchmark工具。

持久化方面的几个选择?

第一种,像 redis 日志方式看似简单,但后面日志过大后肯定是需要rewrite。 那,这就有些棘手了,golang上层没有很好的fork机制,不能进行copy on write。 不能cow那就不能容易的保证状态的一致性。 那么我需要自己去compact 日志,进行合并收敛。

第二种,使用rocksdb来实现数据的存储,简单高效… 在golang channel内存只流传 数据id,这样不管有多少个queue,只会有一条数据在库中,极大的节省了空间。

第三种,像kafka那样,数据分区概念,逻辑分区是对应磁盘目录的,每个目录里都有的一堆的有序的segment数据和索引. 对于客户端来说,可以直接访问,也可以用逻辑id来访问。 这样的做法,不仅能方便的实现消息确认,而且可以做数据的历史回溯。 但是对于我来说,开发量有点大呀…

go_pubsub项目代码放到github上了,有兴趣的可以看看.
https://github.com/rfyiamcool/go_pubsub

下面来演示下go_pubsub服务:

启动 server 端:

go run cmd/main.go

client端我们可以直接用redis相关的客户端和库包。

[gopy@xiaorui ~ ]$ redis-cli -p 9999

# AUTH
127.0.0.1:9999> auth your_password

# 添加topic
127.0.0.1:9999> create topic xiaorui.cc

# 绑定topic和queue_name的关系
127.0.0.1:9999> bind xiaorui.cc queue1

# 给topic为xiaorui.cc发送 hello 信息
127.0.0.1:9999> PUBLISH xiaorui.cc hello
OK

# 接收信息
127.0.0.1:9999> SUBSCRIBE xiaorui.cc queue1
Reading messages... (press Ctrl-C to quit)
hello

END.

 
Golang语言社区 更多文章 Golang处理JSON(二)--- 解码 Golang处理JSON(一)--- 编码 go routine & channel 学习小结 Gost -- 一个极简且有用的GOPATH管理工具 Golang随机time.sleep的Duration问题
猜您喜欢 服务发现 [连载] 途客们的旅行梦 - 愿景和使命 程序员如果像夏洛一样穿越到1997,将会做什么呢? 结对编程:肩并肩还是面对面? 2015 Ctrip Tech Open House 金奖背后的故事