原文连接html
订阅,取消订阅和发布实现了发布/订阅消息范式(引自wikipedia),发送者(发布者)不是计划发送消息给特定的接收者(订阅者)。而是发布的消息分到不一样的频道,不须要知道什么样的订阅者订阅。订阅者对一个或多个频道感兴趣,只需接收感兴趣的消息,不须要知道什么样的发布者发布的。这种发布者和订阅者的解耦合能够带来更大的扩展性和更加动态的网络拓扑。git
Redis 的 订阅(SUBSCRIBE) 可让客户端订阅任意数量的频道, 每当有新信息发送到被订阅的频道时, 信息就会被发送给全部订阅指定频道的客户端。github
如图例子golang
订阅:redis
举个例子,假设 客户端 A、B、C 订阅了一个 channel 通道。那么他讲阻塞 等待接收信息。等到有一个新的消息 往 channel 里面发送数据。那么通道将会 通知给客户端 A、B、C缓存
发布:网络
redis-client 实验订阅发布分布式
一、首先开启 Redis网站
二、打开三个 redis-cli 窗口spa
咱们能够看到当你订阅后,会阻塞在这里,等待新信息
三、在新的redis-cli 窗口 PUBLISH 一个新的信息 Channel 信息
四、切换窗口,咱们能够看到另外两个订阅的窗口接受到了一条 channel 信息
查看订阅者的总数
这里有两个窗口订阅了消息,因此就有 2
订阅发布的好处是,订阅接受的信息只会发送给订阅者。
假设我有一个系统,我有 a,b 两个订阅的通道。
我在某个服务中,只须要订阅 a 信息,那么用 Redis 的订阅 / 发布,订阅者只会接受到他须要接受的订阅信息。
简单的应用场景的话, 以门户网站为例, 当编辑更新了某推荐板块的内容后:
CMS发布清除缓存的消息到channel (推送者推送消息)
门户网站的缓存系统经过channel收到清除缓存的消息 (订阅者收到消息),更新了推荐板块的缓存。
下面我会用列子来解释,我如何在 Golang 中使用订阅发布来关闭某些服务
一、 下载 go redis 库
go get -u github.com/go-redis/redis
二、连接Redis 而且 订阅 wait-close服务
package main import ( "fmt" "log" "sync" example "github.com/yoloyi/redis-example" ) func main() { var wg sync.WaitGroup // 这里咱们用携程来模拟多个服务 for i := 0; i < 2; i++ { wg.Add(1) go func(i int) { client := example.InitRedis() pb := client.Subscribe("wait-close") fmt.Println("阻塞,等待读取 Channel 信息") for { select { case mg := <-pb.Channel(): // 等待从 channel 中发布 close 关闭服务 if mg.Payload == "close" { // 当 wg.Done() } else { log.Println("接channel信息", mg.Payload) } default: } } }(i) } wg.Wait() log.Println("结束 channel") }
三、打开服务
四、从 redis-cli 或者其余客户端发布信息
PUBLISH wait-close new_message
五、当咱们发布了 close 给某个通道,咱们能够看到 两个订阅都被关闭了。
PUBLISH wait-close close
这里的例子,用了两个协程来作两个服务,实际的应用场景中,咱们在分布式系统中,每个服务里面都会订阅这样一个相似的通道,好比更新 LocalCache。当用户在前台修改了某个值,咱们须要去更新你服务里面保存的一些值,就能够经过这种方式去触发到不一样的机器。来更新一些缓存啊,或者是一些其余信息。
有一些其余相似的队列,好比 ActiveMQ 也提供了相似的 发布 / 订阅 的功能,可是在 ActiveMQ 要远比 Redis更复杂,由于 Redis 是一个 Cache,毕竟Redis不是专门作发布订阅的。可是若是系统中已经有了Redis,而且须要基本的发布订阅功能,就没有必要再安装ActiveMQ了,
具体选型,看你领导。