Muduo 网络编程示例(九)简单的消息广播服务

本文介绍用 muduo 实现一个简单的 topic-based 消息广播服务,这其实是“聊天室”的一个简单 扩展,不过聊天的不是人,而是分布式系统中的程序。

本文的代码见 http://code.google.com/p/muduo/source/browse/trunk/examples/hub

在分布式系统中,除了常用的 end-to-end 通信,还有一对多的广播通信。一提到“广播”,或许 会让人联想到 IP 多播或 IP 组播,这不是本文的主题。本文将要谈的是基于 TCP 协议的应用层广播 。示意图如下:

上图中圆角矩形代表程序,"Hub"是一个服务程序,不是网络集线器,它起到类似集线器 的作用,故而得名。Publisher 和 Subscriper 通过 TCP 协议与 Hub 程序通信。Publisher 把消息发 到某个 topic 上,Subscribers 订阅该 topic,然后就能收到消息。即 publisher 借助 hub 把消息 广播给了多个 subscribers。这种 pub/sub 结构的好处在于可以增加多个 Subscriber 而不用修改 Publisher,一定程度上实现了“解耦”(也可以看成分布式的 observer pattern)。 由于走的是 TCP 协议,广播是基本可靠的,这里的“可靠”指的是“比 UDP 可靠”,不是“完全可靠”。(思考 :如何避免 Hub 成为 single point of failure?)

为了避免串扰(cross-talk),每个 topic 在同一时间只应该有一个 publisher,hub 不提供 compare-and-swap 操作。

(“可靠 广播、原子广播”在分布式系统中有重大意义,是以 replicated state machine 方式实现可靠的分布 式服务的基础,“可靠广播”涉及 consensus 算法,超出了本文的范围。)

应用层广播在分布 式系统中用处很大,这里略举几例:

1. 体育比分转播。有 8 片比赛场地正在进行羽毛球比赛 ,每个场地的计分程序把当前比分发送到各自的 topic 上(第 1 号场地发送到 court1,第 2 号发送 到 court2,以此类推)。需要用到比分的程序(赛场的大屏幕显示,网上比分转播等等)自己订阅感 兴趣的 topic ,就能及时收到最新比分数据。由于本文实现的不是 100% 可靠广播,那么消息应该是 snapshot,而不是 incremental。(换句话说,消息的内容是“现在是几比几”,而不是“刚才谁得分 ”。)

2. 负载监控。每台机器上运行一个监控程序,周期性地把本机当前负载(CPU、网络、 磁盘、温度)publish 到以 hostname 命名的 topic 上,这样需要用到这些数据的程序只要在 hub 订 阅相应的 topic 就能获得数据,无需与多台机器直接打交道。(为了可靠起见,监控程序发送的消息 里边应该包含时间戳,这样能防止 stale 数据,甚至一定程度上起到心跳的作用。)沿着这个思路, 分布式系统中的服务程序也可以把自己的当前负载发布到 hub 上,供 load balancer 和 monitor 取 用。

协议

为了简单起见,muduo 的 hub 示例采用以 '/r/n' 分界的文本协议 ,这样用 telnet 就能测试 hub。协议只有三个命令:

时间: 2024-10-26 05:34:41

Muduo 网络编程示例(九)简单的消息广播服务的相关文章

Muduo 网络编程示例之零:前言

陈硕 (giantchen_AT_gmail)Blog.csdn.net/Solstice Muduo 全系列文章列表: http://blog.csdn.net/Solstice/category/779646.aspx我将会写一系列文章,介绍用 muduo 网络库完成常见的 TCP 网络编程任务.目前计划如下: UNP 中的简单协议,包括 echo.daytime.time.discard 等.  Boost.Asio 中的示例,包括 timer2~6.chat 等. Java Netty 

Muduo 网络编程示例(六)限制服务器的最大并发连接数

本文已以大家都熟悉的 EchoServer 介绍如何限制服务器的并发连接数. 本文的代码见 http://code.google.com/p/muduo/source/browse/trunk/examples/maxconnection/ <Muduo 网络 编程示例 系列>计划中的第六篇文章原本是"用于测试两台机器的带宽的 pingpong 程序", pingpong 协议的程序已经在<muduo 与 boost asio 吞吐量对比>和<muduo

Muduo 网络编程示例

我将会写一系列文章,介绍用 muduo 网络库完成常见的 TCP 网络编程任务.目前计划如下: UNP 中的简单协议,包括 echo.daytime.time.discard 等. Boost.Asio 中的示例, 包括 timer2~6.chat 等. Java Netty 中的示例,包括 discard.echo.uptime 等,其中的 discard 和 echo 带流量统计功能. Python twisted 中的示例,包括 finger01~07 用于测试两台机器的往返延迟的 rou

Muduo 网络编程示例(二) Boost.Asio 的聊天服务器

本文讲介绍一个与 Boost.Asio 的示例代码中的聊天服务器功能类似的网络服务程序,包括客户端 与服务端的 muduo 实现.这个例子的主要目的是介绍如何处理分包,并初步涉及 Muduo 的多线程功能 .Muduo 的下载地址: http://muduo.googlecode.com/files/muduo-0.1.7-alpha.tar.gz ,SHA1 873567e43b3c2cae592101ea809b30ba730f2ee6,本文的完整代码可在线阅读 http://code.go

Muduo 网络编程示例(四)Twisted Finger

Python Twisted 是一款非常好的网络库,它也采用 Reactor 作为网络编程的基本模型,所以从使 用上与 muduo 颇有相似之处.(当然,muduo 没有 deferreds)Finger 是 twisted 文档的一个经典 例子,本文展示如何用 muduo 来实现最简单的 finger 服务端.限于篇幅,只实现 finger01~07.代 码位于 examples/twisted/finger . 1 拒绝连接 什么都不做,程序空等. finger01.cc 1: #inclu

Muduo 网络编程示例(七)“串并转换”连接服务器及其自动化测试

本文介绍如何使用 test harness 来测试一个具有内部逻辑的网络服务程序. 本文的代码见 http://code.google.com/p/muduo/source/browse/trunk/examples/multiplexer 下载地址: http://muduo.googlecode.com/files/muduo-0.2.0-alpha.tar.gz SHA1 checksum: 75a09a82f96b583004876e95105c679e64c95715 云风在他的博客中

Muduo 网络编程示例(一) 五个简单TCP协议

本文将介绍第一个示例:五个简单 TCP 网络服务协议,包括 echo (RFC 862).discard (RFC 863) .chargen (RFC 864).daytime (RFC 867).time (RFC 868),以及 time 协议的客户端.各协议的功 能简介如下: * discard - 丢弃所有收到的数据: * daytime - 服务端 accept 连接之 后,以字符串形式发送当前时间,然后主动断开连接: * time - 服务端 accept 连接之后,以 二进制形式

Muduo 网络编程示例(五)测量两台机器的网络延迟

本文介绍一个简单的网络程序 roundtrip,用于测量两台机器之间的网络延迟,即"往返时间 / round trip time / RTT".这篇文章主要考察定长 TCP 消息的分包,TCP_NODELAY 的作用. 本文的代码见 http://code.google.com/p/muduo/source/browse/trunk/examples/roundtrip/roundtrip.cc 测量 RTT 的办法很简单: host A 发一条消息给 host B,其中包含 host

Muduo 网络编程示例(八)用 Timing wheel 踢掉空闲连接

本文介绍如何使用 timing wheel 来踢掉空闲的连接,一个连接如果若干秒没有收到数据,就认为 是空闲连接. 本文的代码见 http://code.google.com/p/muduo/source/browse/trunk/examples/idleconnection 在严肃的网络程序中,应用层的心跳协议是必不可少的.应该用心跳消息来判断对方进程是否能正 常工作,"踢掉空闲连接"只是一时权宜之计.我这里想顺便讲讲 shared_ptr 和 weak_ptr 的用法. 如果一个