Golang使用redis protocol实现pubsub通信

前言:

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


该文章后续会有更新, 原文地址http://xiaorui.cc/?p=4847


语言方面的选择?

我熟练的语言不多,最熟练的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.


大家觉得文章对你有些作用! 如果想赏钱,可以用微信扫描下面的二维码,感谢!
另外再次标注博客原地址  xiaorui.cc