专栏首页后台rpc基于Zmq的后台通信模型介绍
原创

基于Zmq的后台通信模型介绍

Zmq是一个简单好用的传输组建,使得socket变成更加简洁、高效、高性能。本文主要介绍后台服务实现、多线程任务实现、线程无锁计数实现。

1.Zmq通常通信模型

Zmq通信场景:

  • 线程之间(inproc)
  • 进程之间(ipc)
  • 机器之间(tcp)

Zmq通信模式:

  • 请求-回复(Request-reply)。分为ZMQ_REQ、ZMQ_REP、ZMQ_DEALER、ZMQ_ROUTER
  • 发布-订阅(Publish-subscribe)。分为ZMQ_PUB、ZMQ_SUB
  • 管道(Pipeline)。分为ZMQ_PUSH、ZMQ_PULL
  • 对立对(Exclusive pair)。分为ZMQ_PAIR

2.后台服务实现

多线程模式后台服务一般启动一线程接收外部请求,再派发给工作线程进行处理请求,工作线程完成后返回给派发线程,最终返回请求方。

使用zmq线程间,请求-回复,ROUTER-DEALER模式可以很方便的实现多线程后台服务。实现原理如图2-1。

图2-1 ROUTER-DEALER后台服务

1、Dispatcher线程通过tcp socket接收来自Client的请求。这里tcp socket可以是基于zmq的tcp,也可以是普通的tcp请求,只要与client统一通信协议即可,其中如果基于zmq则需要使用zmq的协议格式。

2、Dispatcher线程收到Client请求后采用zmq inproc socket派发给Worker线程。其中Dispatcher线程的zmq inproc socket采用DEALER模式。

3、Worker线程通过zmq inproc socket收到请求,进行处理,处理完后将结果返回给Dispatcher线程。Worker线程的zmq inproc socket采用ROUTER模式。

4、Dispatcher线程收到Worker线程的返回后将返回通过tcp返回给Client,完成一个完整的后台服务。

3 .多线程任务实现

很多后台任务并不是对外服务,仅仅是为了完成某项具体的任务,如数据处理、数据搬移、定时任务等。很多后台任务在多线程处理时,多任务需要在多线程完成,直接用锁、共享资源来分配任务实现比较复杂,且容易出错,如果采用zmq实现线程间通信,其中一线程来派发任务,多线程循环完成任务。这种场景实现原理如图3-1。

图3-1 纯后台多线程通信

1.启动一个Dispatcher线程进行任务派发;

2.Worker线程处理任务并返回处理结果;

3.Dispatcher线程统计结果,且继续派发任务,这里Dispatcher需要异步来接收任务返回。

4.多线程无锁计数实现

如果多个后台任务线程需要做一个互斥计数或取某一个数值,通常会想到直接用互斥锁来实现,这里基于zmq介绍一种通过线程间通信来实现的方式。通过启动一个Dispatcher来处理互斥资源操作,把操作结果返回给Worker线程,而这里由于只有一个Dispatcher线程,能够实现无锁互斥效果。实现原理如图4-1。

图4-1 多线程无锁实现

1.启动一个Dispatcher线程进行操作需要互斥的资源,如计数等;

2.Worker线程发送请求给Dispatcher线程;

3.Dispatcher线程进行处理,处理完后返回给Worker线程。

5 .总结

Zmq本身是一个应用非常广泛的通信组建,这里介绍的通信模式在生产环境得到了充分的验证,目前腾讯内部有基于zmq的成熟c++ rpc组件,本文主要讲线程间的通信,基于zmq多进程的模式实现后台框架,基本原理是一致的,可以进一步去研究。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • C# 基础知识系列- 12 任务和多线程

    照例一份前言,在介绍任务和多线程之前,先介绍一下异步和同步的概念。我们之间介绍的知识点都是在同步执行,所谓的同步就是一行代码一行代码的执行,就像是我们日常乘坐地...

    程序员小高
  • java基础题目总结

    有些基础题目由于工作中用的比较少但却又是不可少的,这样回答起来就会反应慢,不确定,不准确,特此开了文章记录遇到的不确定或者回答比较拗口的问题。 1.servle...

    Ryan-Miao
  • Java并发编程之线程封闭

    当访问共享变量时,往往需要加锁来保证数据同步。一种避免使用同步的方式就是不共享数据。如果仅在单线程中访问数据,就不需要同步了。这种技术称为线程封闭。在Java语...

    技术训练营
  • 线程池的作用和CLR线程池

    在程序的世界里,如果创建某种对象所需要的代价太高,同时这个对象又可以反复使用,那么我们往往就会准备一个容器,用来保存一批这样的对象。当我们要用这种对象时,就不需...

    小蜜蜂
  • 我会手动创建线程,为什么让我使用线程池?

    现陆续将Demo代码和技术文章整理在一起 Github实践精选 ,方便大家阅读查看,本文同样收录在此,觉得不错,还请Star

    用户1516716
  • 如何设置线程池参数大小?

    其实线程池的设置是有方法的,不是凭借简单的估算来决定的。今天我们就来看看究竟有哪些计算方法可以复用,线程池中各个参数之间又存在怎样的关系呢? 本文咱们来慢慢聊。

    用户4143945
  • 【万字图文-原创】 | 学会Java中的线程池,这一篇也许就够了!

    Java中的线程池已经不是什么神秘的技术了,相信在看的读者在项目中也都有使用过。关于线程池的文章也是数不胜数,我们站在巨人的肩膀上来再次梳理一下。

    一枝花算不算浪漫
  • Java中线程池的理解

    通过前面讲解,我们知道了Java中三种获取多线程的方法了。但是,在实际企业中,经常使用到的是第四种—使用线程池获取线程。在讲解这种获取方式之前,我们先来聊聊线程...

    凯哥Java
  • 不可不说的 Java “锁”事

    Java 提供了种类丰富的锁,每种锁因其特性的不同,在适当的场景下能够展现出非常高的效率。本文旨在对锁相关源码(本文中的源码来自 JDK 8 和 Netty 3...

    CG国斌
  • 线程的5种状态详解

    飞狗

扫码关注云+社区

领取腾讯云代金券