`
kongshanxuelin
  • 浏览: 927138 次
  • 性别: Icon_minigender_1
  • 来自: 宁波
社区版块
存档分类
最新评论

高性能高可用的服务端研究之Req-Rep模式(附源码)

阅读更多

最近在思考高可用的高性能的服务端架构,面临的主要问题如下:

  1. 服务端组件怎么做到可插拔?
  2. 消息怎么智能路由?一个服务端挂了不会影响整个应用,避免单点故障?
  3. 如何设计一套高性能的Req-Rep,Pub-Sub,Push-Poll模型;
  4. 如何做到跨语言,让各语言各尽其用,比如编写业务代码可用Java,编写网络通信压缩,加密解密,数据序列化等用C++,而且尽可能减少性能损失?

看来这并不是一件简单的事情,我们这篇博客仅仅思考Req-Rep模式的搭建,我们这里使用开源项目ZeroMQ:

ZeroMQ以嵌入式网络编程库的形式实现了一个并行开发框架(concurrencyframework),能够提供进程内(inproc)、进程间(IPC)、网络(TCP)和广播方式的消息信道,并支持扇出(fan-out)、发布--订阅(pub-sub)、任务分发(taskdistribution)、请求/响应(request-reply)等通信模式。ZeroMQ的性能足以用来构建集群产品,其异步I/O模型能够为多核消息系统提供足够的扩展性。ZeroMQ支持30多种语言的API,可以用于绝大多数操作系统。在提供这些优秀特性的同时,ZeroMQ是开源的,遵循LGPLv3许可。
ZeroMQ的明确目标是“成为标准网络协议栈的一部分,之后进入Linux内核”。

 

我们的目标是:

  1. 业务程序的Req-Server集群部署,从网关发来的请求处理(是C/C++编写的网关),程序自动找一台空闲的Req-Server来处理这个请求,并将结果异步分发到服务单网关,从而Push给客户端;
  2. 一套Req-Server挂了不会影响整个服务端程序运行;
  3. 当Req过载时,即发送的大量请求在服务端堆积时,服务端“热部署”挂一个新的Req-Server,而不需要重新启动服务端程序;

这看起来的一个简单的任务其实并不简单!

 

幸好,ZeroMQ已经帮我们处理了大部分工作,考虑到这个网站大多数是Javaer,所以这篇博文我们以Java代码举例,实际上,我们服务端网关使用C编写的。

 

最简单的请求/应答模式如下:

客户端:

 

ZMQ.Context context = ZMQ.context(1);
ZMQ.Socket requester = context.socket(ZMQ.REQ);
requester.connect("tcp://localhost:5559");

for (int requestNbr = 0; requestNbr != 100000; requestNbr++) {
	String request = "Hello"+requestNbr;
	System.out.println("Sending Hello " + requestNbr);
	requester.send(request.getBytes(), 0);
	byte[] reply = requester.recv(0);
	System.out.println("Received " + new String(reply) + " " + requestNbr);
}
requester.close();
context.term();
 服务端:

 

 

ZMQ.Context context = ZMQ.context(1);
ZMQ.Socket responder = context.socket(ZMQ.REP);
responder.bind("tcp://*:5559");
while (!Thread.currentThread().isInterrupted()) {
	byte[] request = responder.recv(0);
	System.out.println("Received from client req:"+new String(request));
	Thread.sleep(100);
	String reply = "World";
	responder.send(reply.getBytes(), 0);
}
responder.close();
context.term();
 这里有几个不足:

 

  1. 当请求方并发数达到一定量时,由于请求在服务端不丢失,对导致大量的请求在服务端堆积,造成server端内存溢出;
  2. 存在单点故障,当部署的响应程序crash时,请求就无法处理了。

这里我们改善一下,引入请求/响应的Broker,所有的请求经由Broker代理中转,请求方不需要知道有多少server在后台服务,有Broker去决策一个请求交由那个处理请求的server去处理并负责负载均衡,代码如下:

Broker Server:

 

System.out.println("req Server Broker start....");
ZMQ.Context context = ZMQ.context(1);
ZMQ.Socket frontEnd = context.socket(ZMQ.ROUTER);
frontEnd.bind("tcp://*:5559");
ZMQ.Socket backEnd = context.socket(ZMQ.DEALER);       
backEnd.bind("tcp://*:5560");
ZMQQueue q = new ZMQQueue(context,frontEnd,backEnd);
q.run();
frontEnd.close();
backEnd.close();
context.term();
 处理请求的Server(可以部署N个,N个Server热插拔):

 

 

ZMQ.Context context = ZMQ.context(1);
ZMQ.Socket responder = context.socket(ZMQ.REP);
String brokerIP = prop.getProperty("server_req_broker");
System.out.println("serverName:" + brokerIP);
responder.connect("tcp://"+brokerIP);
while (!Thread.currentThread().isInterrupted()) {
	byte[] request = responder.recv(0);
	Thread.sleep(100);
	String reply = "World";
	responder.send(reply.getBytes(), 0);
}
responder.close();
context.term();
先在某一台机器上启动Broker Server(runReqServerBroker.bat),先在三台机器上部署3个Req Server,然后先启动一个,运行runReqClient.bat,然后再在别的机器上启动另外两个Req Server(runReqServer.bat),我们可以看到,Client发送的所有请求被自动负载均衡到3台请求处理服务器上,并且他们是平均分配的(当然,你可以改变均衡策略,比如使用LRU,但zeroMQ默认是采用平均分配的算法)。

 

想一下,这个模型有什么优缺点?
  1. 单点故障只在Broker Server出现,如果Broker Server不挂,那么Req Server可以任意增减,对clients来说是透明的;
  2. Req Server处理请求的策略完全可以由你自己来定义(比如采用LRU,权重分配等);
  3. 和业务无关的Broker Server可以完全由更高效的语言去实现,比如用C(也是官方所有Demo采用的默认语言),请求服务器则可以采用Java实现,比如处理业务查询,业务处理等;

这篇请求/响应模式的博文就介绍到这里,也给自己留个脚印,源码见附件,下篇我们会介绍pub/sub模式。

  • src.rar (6.9 KB)
  • 下载次数: 29
2
0
分享到:
评论
3 楼 ninyjun 2014-03-10  
楼主可能没有明白我的意思,或者可能我没有表达清楚。 我的意思是如果有个WORKER进程挂住了,可能影响导致BROKER阻塞,从而影响到其他的请求、相应进程。
至少我测试的结果是这样的。

感觉BROKER是单线程的(虽然文档上说是多路复用)
2 楼 kongshanxuelin 2014-03-04  
ninyjun 写道
不知道博主有没有实际测试过, 本人之前也做了一下REQ<-->BROKER<---> REP 模式,测试的结果是如果一个WORKER进程执行速度的快慢(比如其中的一个业务处理很慢挂住了)影响其他的进程。个人分析可能是BROKER的POLL模式问题,在官方网站提了一下问题。

因为Req/Rep是同步方式的,所以会有影响,最简单办法是直接设置requester.setReceiveTimeOut,或者采用官方文后给出的Simple Pirate queue,具体可参考http://zguide.zeromq.org/page:all那一章节(请求响应模式的可靠性设计)
1 楼 ninyjun 2014-03-04  
不知道博主有没有实际测试过, 本人之前也做了一下REQ<-->BROKER<---> REP 模式,测试的结果是如果一个WORKER进程执行速度的快慢(比如其中的一个业务处理很慢挂住了)影响其他的进程。个人分析可能是BROKER的POLL模式问题,在官方网站提了一下问题。

相关推荐

    nanomsg-req-rep流程源码分析.docx

    nanomsg是一个开源的实现了几种“可扩展协议”的高性能通信库,本文针对请求/回复模式进行了简单的源码分析,包括请求的时序图,socket消息槽等。 知识点1:nanomsg库简介 nanomsg是一个开源的高性能通信库,实现了...

    libzmq-master源码

    【标题】"libzmq-master源码" 是ZeroMQ库的一个源代码版本,ZeroMQ是一个高性能、轻量级的消息队列库,它提供了一种在分布式计算环境中进行进程间通信(IPC)的方式。ZeroMQ的核心功能是通过创建虚拟的网络连接来让...

    zero-mq源码 (xxxxxx)

    3. **高性能**:ZeroMQ的设计目标之一就是高效。它使用零拷贝技术减少内存操作,直接将数据从网络缓冲区传输到用户空间,从而提高了消息处理的速度。 4. **分布式**:ZeroMQ可以在多个进程中,甚至在不同的机器上...

    zeromq 源码 4.3.5

    ZeroMQ的核心概念是基于发布/订阅、请求/响应和推/拉模式的高性能消息队列。这些模式使得开发分布式系统变得更加简单,因为它抽象了网络通信的复杂性。下面,我们将深入探讨ZeroMQ 4.3.5版本的源码,了解其主要组件...

    jzmq源码.zip

    ZeroMQ,又称为ØMQ或0MQ,是一个轻量级的消息中间件,它提供了一种灵活的、高性能的通信模式,适用于分布式系统中的进程间通信。ZeroMQ通过抽象出多种消息模式(如PUB/SUB、REQ/REP、DEALER/ROUTER等),简化了跨...

    zeromq 代理模式的一些问题

    1. 请求-响应模式(Rep-Req): 在这个模式下,客户端发送请求到代理,代理接收到请求后将其转发到服务端,服务端处理完请求后通过代理将响应返回给客户端。常见的问题是代理可能会成为瓶颈,因为所有的请求都要...

    zmq源码学习,源码版本4.3.3

    zeromq,通常简称为ZMQ或0MQ,是一个开源的消息中间件库,它提供了高性能、轻量级的异步消息传递机制。ZMQ的核心设计理念是提供一个灵活、高效的网络抽象层,允许开发者构建分布式计算系统,而无需关心底层网络通信...

    zeromq+qt通信源码

    zeromQ,全称为“ZeroMQ”,是一个高性能的开源消息中间件,它提供了一种灵活的、点对点的通信模式,可以用于构建分布式应用。zeromQ的核心概念是消息队列,它允许进程之间异步通信,即使这些进程可能位于不同的网络...

    zmq编译库 ,源码4.3.2

    用户可以创建各种类型的套接字,如PUB(发布者)、SUB(订阅者)、REQ(请求者)、REP(响应者)等,这些模式对应于不同的消息传递模式,如发布/订阅、请求/响应和对等模式。 编译libzmq动态库的过程涉及以下几个...

    zeromq-4.0.3.tar

    3. **模式丰富**:支持多种通信模式,如PUB/SUB(发布/订阅)、REQ/REP(请求/响应)、PUSH/PULL(推送/拉取)等,适应不同应用场景。 4. **跨平台**:ZeroMQ可以在多种操作系统上运行,包括Linux、Windows、macOS等...

    zeromq-4.2.0.tar.gz源码包

    zeromq的设计基于发布/订阅(Pub/Sub)、请求/应答(Req/Rep)和推送/拉取(Push/Pull)等经典的消息模式。这些模式覆盖了各种常见的分布式系统通信场景,如服务间调用、事件驱动架构、工作队列等。通过这些模式,...

    nanomsg1.0.0,高效的通信中间件

    `nanomsg` 是一款开源的、轻量级的、高性能的通信中间件,它的设计目标是提供多种消息传递模式,使得分布式系统中的组件能够高效地进行通信。在`nanomsg1.0.0`版本中,它提供了丰富的协议栈,支持多种通信模式,如...

    zeromq手册源代码

    zeromq,又称为ZeroMQ或0MQ,是一个开源的消息中间件,它实现了高性能、分布式消息传递模型,支持多种编程语言,如C、C++、Python、Java等。zeromq的设计目标是提供一种轻量级、高效率的消息队列,以解决多进程间...

    zeromq网络开发库

    ZeroMQ,又称ØMQ或0MQ,是一款轻量级、高性能的开源消息中间件,它为应用程序提供了一种高效、灵活的异步消息传递机制。ZeroMQ的设计目标是简化分布式系统中的通信问题,使得开发者可以像在单机环境中一样简单地...

    libzmq-4.3.2.zip

    ZeroMQ,通常缩写为`libzmq`,是一个开源的消息中间件库,它提供了一种灵活、高性能的网络通信框架。ZeroMQ的核心概念是基于消息队列的模型,允许分布式系统中的进程间进行高效、可靠的异步通信。在本文中,我们将...

    libzmq-src-v4.3.4.zip

    0MQ(也称为 ZeroMQ 或 ØMQ)是一个开源的消息队列库,它为应用程序提供了一种灵活、高性能的异步消息传递机制。标题中的“libzmq-src-v4.3.4.zip”指的是0MQ库的源代码版本4.3.4,这个版本在2021年1月17日被标记为...

    zeromq-4.2.0.tar.zip

    总而言之,ZeroMQ 4.2.0是一个经过验证的、适用于Linux环境的高性能消息中间件,它的强大功能和灵活性使其成为开发分布式系统的首选工具之一。通过解压并编译zeromq-4.2.0.tar.gz,开发者可以深入理解其工作原理,并...

    jzmq源代码

    在ZeroMQ中,你可以创建各种模式的连接,比如点对点(P2P)、发布/订阅(Pub/Sub)和请求/响应(Req/Rep)。这些模式使得构建分布式系统变得简单且灵活。 jzmq库的实现主要基于JNI(Java Native Interface),允许...

    zeromq-4.0.3.tar.gz.zip

    3. **多种协议支持**:ZeroMQ 支持多种网络协议,如 TCP、IPC(进程间通信)、PUB/SUB、REQ/REP、DEALER/ROUTER 等,适应不同的通信模式。 4. **易用性**:ZeroMQ 提供了多种编程语言的绑定,包括 C、C++、Python、...

    zeromq-3.2.5.zip

    这使得开发人员可以快速地构建可靠和高性能的通信解决方案。 总的来说,zeromq-3.2.5版本是一个强大的工具,为开发者提供了构建复杂分布式系统的基础设施。它的高效性、灵活性和易用性使其在各种项目中得到广泛应用...

Global site tag (gtag.js) - Google Analytics