ZeroMQ(java)之Router与Dealer运行原理

简介: 在开始这部分的内容之前,先来看看ZeroMQ中HWM概念---High-Water Marks当系统的数据量很大,而且发送频率很高的情况下,内存就很重要了,如果处理不好会出现很多问题,例如如下场景:A很快速的向B发送数据,但是B处理起来却很慢,这样子的话,数据就可能会在A的发送缓冲区,或者B的接收缓冲区累计起来.

在开始这部分的内容之前,先来看看ZeroMQ中HWM概念---High-Water Marks

当系统的数据量很大,而且发送频率很高的情况下,内存就很重要了,如果处理不好会出现很多问题,例如如下场景:

A很快速的向B发送数据,但是B处理起来却很慢,这样子的话,数据就可能会在A的发送缓冲区,或者B的接收缓冲区累计起来....如果双方速度差太多,就很容易出现问题.......

在ZeroMQ中,建立了pipe的概念(或者说数据缓冲),那么实际情况下就会如下图:


这个时候,HWM就是指这个缓冲区的容量大小....现在v3.x的版本,都是默认为1000.

而且不同类型的socket拥有的缓冲区类型也不一样,例如Publish与Push只有发送缓冲区,Subscribe与Pull什么的就只有接受缓冲区,Router,Dealer啥的就有两种类型的缓冲区....

这里不同类型的socket,当他们的缓冲区满了以后表现出来的行为也不一样,

例如Publish与Router会丢弃message,而其他的就表现为阻塞...

好了,打这里算是知道了在ZeroMQ中HWM这东西到底指的是神马意思了...

接下来来看另外一个概念:Envelope(信封,封皮)

说白了就是在不接触具体数据的情况下,在数据的外面套上一个外套,在ZeroMQ中主要是指在数据的外面加上一个Address,或者说标志位吧,其实到这里就基本上能够知道router以及dealer的运行原理了,其实就算不知道这个,猜也能猜到是router与dealer是怎么实现的....

好了,接下来具体来说明Request/Response的消息格式:

在Request/Response这种通信模式中,每一个request都会对应有一个response,我们知道ZeroMQ有自己定义的帧格式,拿Request发送hello字符串为例子,数据如下:

后面两个固定的帧是肯定有的,前面的address帧不一定会有(按照我们前面的用法,其实都没有的)。。。。那么当response端收到这个数据之后,它会将前面的数据都先去掉,只讲数据帧里面的数据提交给用户定义的代码(前面将hello数据封装,到后来response对数据进行处理都是由ZeroMQ来做的)。。。。

其实对于我们简单的Request/Response通信,发送和返回的数据都是又两个帧构成的,先是一个空帧,作为分隔符,然后就是数据帧。。。

但是当我们在通信中加入了Router和Dealer之后,就变了,他们会对我们发送的数据做一些手脚。。。。


整个通信结构变成了上图,先来说一下Router的比较特殊的行为,他将会跟踪每一个与其建立的链接,并且为每一个链接都分配一个标志,这个标志当然是唯一的咯,用于区分每一个建立的链接,所以我们通过Router发送数据到Request的时候,我们要发送的数据首先得要包含一个标志帧,这样Router才能知道应该发送给哪一个Request的连接,然后再将标志帧后面的数据发送出去(将前面的标志帧移除)。。。也就是说我们通过router发送数据的时候,数据应该是如下的格式:


这里知道了Router发送数据的一些行为,那么来看看Router接收数据的行为吧:

当router接收到数据之后,在将数据提交给用户代码之前,会在数据之前加上一个标志帧,用于指代这个数据是从哪一个链接接受过来的,也就是将数据变成上图的格式交给用户代码,而不是取出纯净的数据交给用户代码。。。

例如如下如下图的数据格式:


前面一个帧,存有标志,用于指代router从哪一个连接接收到的数据,接着是一个分割帧,然后才是数据帧。。

好了,讲完router的行为,下面接下来说Dealer的行为:

Dealer其实很简单,直接将前面的数据不做任何的改变,直接发送给Response端,当Response端接收到数据以后,会将前面的地址帧,还有分隔帧去掉,然后将纯净的数据提交给用户代码,这里就是提交Hello数据到用户代码。。。、

如果Response返回world字符串,那么Response会对这个数据包装,而且会将前面拆掉的标志帧又套上去,那么数据就变成了如下:


dealer收到了上图格式的数据,再通过router发送回request端,这个时候就可以通过前面的标志帧来知道究竟应该将数据发送给哪一个连接了。。。最后数据会变成如下的格式发送给request端:


这样request端就能够接收到正确的数据。。。、

接下来得出如下的结论:

(1)对于Request类型的socket,它是同步的,它一个时刻只能对一个连接进行操作,在一个连接上发送了数据之后,必须接着在这个连接上执行recv,也就是send与recv必须同时匹配出现。。。

(2)Response类型的socket也是同步的,与Request的意思差不多,不过顺序是先recv再send。。。

(3)Router类型的socket是异步的,他可以在随时执行recv与send,而不必在同一时刻必须要强制在某个连接上进行操作。。。它会根据标志帧来具体的区分应该在哪一个链接上进行操作

(5)Dealer类型的socket,这个更简单的,异步。。。它基本上就没做啥工作。。。。


到这里基本就已经清楚了Router以及Dealer的运行原理,其实跟自己以前猜的差不多。。。

若转载请注明出处!若有疑问,请回复交流!
目录
相关文章
|
12月前
|
存储 缓存 Java
我们来详细讲一讲 Java NIO 底层原理
我是小假 期待与你的下一次相遇 ~
379 2
|
11月前
|
监控 Java API
现代 Java IO 高性能实践从原理到落地的高效实现路径与实战指南
本文深入解析现代Java高性能IO实践,涵盖异步非阻塞IO、操作系统优化、大文件处理、响应式网络编程与数据库访问,结合Netty、Reactor等技术落地高并发应用,助力构建高效可扩展的IO系统。
314 0
|
前端开发 Java 关系型数据库
基于Java+Springboot+Vue开发的鲜花商城管理系统源码+运行
基于Java+Springboot+Vue开发的鲜花商城管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的鲜花商城管理系统项目,大学生可以在实践中学习和提升自己的能力,为以后的职业发展打下坚实基础。技术学习共同进步
805 7
|
存储 缓存 Java
【高薪程序员必看】万字长文拆解Java并发编程!(5):深入理解JMM:Java内存模型的三大特性与volatile底层原理
JMM,Java Memory Model,Java内存模型,定义了主内存,工作内存,确保Java在不同平台上的正确运行主内存Main Memory:所有线程共享的内存区域,所有的变量都存储在主存中工作内存Working Memory:每个线程拥有自己的工作内存,用于保存变量的副本.线程执行过程中先将主内存中的变量读到工作内存中,对变量进行操作之后再将变量写入主内存,jvm概念说明主内存所有线程共享的内存区域,存储原始变量(堆内存中的对象实例和静态变量)工作内存。
374 0
|
12月前
|
存储 算法 安全
Java中的对称加密算法的原理与实现
本文详细解析了Java中三种常用对称加密算法(AES、DES、3DES)的实现原理及应用。对称加密使用相同密钥进行加解密,适合数据安全传输与存储。AES作为现代标准,支持128/192/256位密钥,安全性高;DES采用56位密钥,现已不够安全;3DES通过三重加密增强安全性,但性能较低。文章提供了各算法的具体Java代码示例,便于快速上手实现加密解密操作,帮助用户根据需求选择合适的加密方案保护数据安全。
837 58
|
11月前
|
人工智能 安全 Java
Go与Java泛型原理简介
本文介绍了Go与Java泛型的实现原理。Go通过单态化为不同类型生成函数副本,提升运行效率;而Java则采用类型擦除,将泛型转为Object类型处理,保持兼容性但牺牲部分类型安全。两种机制各有优劣,适用于不同场景。
569 24
|
12月前
|
XML JSON Java
Java 反射:从原理到实战的全面解析与应用指南
本文深度解析Java反射机制,从原理到实战应用全覆盖。首先讲解反射的概念与核心原理,包括类加载过程和`Class`对象的作用;接着详细分析反射的核心API用法,如`Class`、`Constructor`、`Method`和`Field`的操作方法;最后通过动态代理和注解驱动配置解析等实战场景,帮助读者掌握反射技术的实际应用。内容翔实,适合希望深入理解Java反射机制的开发者。
947 13
|
12月前
|
算法 Java 索引
说一说 Java 并发队列原理剖析
我是小假 期待与你的下一次相遇 ~
128 1
|
12月前
|
安全 Java 编译器
JD-GUI,java反编译工具及原理: JavaDecompiler一个Java反编译器
Java Decompiler (JD-GUI) 是一款由 Pavel Kouznetsov 开发的图形化 Java 反编译工具,支持 Windows、Linux 和 Mac Os。它能将 `.class` 文件反编译为 Java 源代码,支持多文件标签浏览、高亮显示,并兼容 Java 5 及以上版本。JD-GUI 支持对整个 Jar 文件进行反编译,可跳转源码,适用于多种 JDK 和编译器。其原理基于将字节码转换为抽象语法树 (AST),再通过反编译生成代码。尽管程序可能带来安全风险,但可通过代码混淆降低可读性。最新版修复了多项识别错误并优化了内存管理。
10327 1