RabbitMQ 消费者
RabbitMQ的消费模式分两种:推模式和拉模式,推模式采用Basic.Consume进行消费,拉模式则是调用Basic.Get进行消费。
消费者通过订阅队列从RabbitMQ中获取消息进行消费,为避免消息丢失可采用消费确认机制
消费者
- 拉模式
- 拉模式的实现
- 推模式
- 消费确认与拒绝
- 消息确认的实现
- 消息拒绝的实现
- basicRecover
- basicQos 限制消费
- 总结
拉模式
顾名思义,拉模式就是消费者主动的从RabbitMQ中获取数据,通过拉模式每次获取数据只能获取一条。拉模式的时序图如下图所示。
RabbitMQ每次接收到Get请求后会将队列中即将被消费的消息发送给消费者,消费者接收处理消息后向RabbitMQ发送消费应答,然后该消息将从队列中移除。
需要注意的是拉模式普遍仅适用用从RabbitMQ中获取一条数据的场景,如果以循环的方式获取批量数据将影响RabbitMQ的性能。
拉模式的实现
拉模式通过以下方法实现:
/**
* queue 队列名称
* autoAck 是否开启自动应答
*/
GetResponse basicGet(String queue,boolean autoAck)
如上述代码所示channel.basicGet方法返回的是一个GetResponse,在GetResponse对象中包含了一条消息内容,消费者可以获取该消息并进行处理。
推模式
推模式是指RabbitMQ将消息主动推送给订阅监听队列的消费者。在RabbitMQ推送消息的过程中其并不关心该消费者是否完成上一条消息的消费,只要队列中存在消息则向消费者推送,当然推送消息的个数会受Basic.Qos的限制。Basic.Qos指定了某个消费者可以保持的未应答的消息数量。
/*** Start a consumer. Calls the consumer's {@link Consumer#handleConsumeOk}* method.* Provide access to <code>basic.deliver(Broker推送消息)</code>, <code>basic.cancel</code>* and shutdown signal callbacks (which is sufficient* for most cases). See methods with a {@link Consumer} argument* to have access to all the application callbacks.* @param queue 队列名称* @param autoAck 是否自动确认* @param consumerTag 消费者标签,消费者的唯一标识符* @param noLocal 是否可以接收同Connection中生产者的消息(true不能接收)* @param exclusive 是否设置排他* @param arguments 其他参数* @param deliverCallback 消息接收回调* @param cancelCallback 消费取消回调* @param shutdownSignalCallback 连接或者信道关闭回调* @return the consumerTag associated with the new consumer*/String basicConsume(String queue, boolean autoAck, String consumerTag, boolean noLocal, boolean exclusive, Map<String, Object> arguments, DeliverCallback deliverCallback, CancelCallback cancelCallback, ConsumerShutdownSignalCallback shutdownSignalCallback) throws IOException;String basicConsume(String queue, boolean autoAck, String consumerTag, boolean noLocal, boolean exclusive, Map<String, Object> arguments, Consumer callback) throws IOException;
可以通过上述两种方法(设置参数最多的)实现声明消费者。其中Consumer的定义如下:
public interface Consumer {/*** 消费者通过basicConsume被注册后调用*/void handleConsumeOk(String consumerTag);/*** 消费者通过basicCancel取消时调用*/void handleCancelOk(String consumerTag);/*** 消费者不通过basicCancel取消时调用*/void handleCancel(String consumerTag) throws IOException;/*** 通道或者连接关闭时调用*/void handleShutdownSignal(String consumerTag, ShutdownSignalException sig);/*** 接收重新发送的未被确认的消息时调用*/void handleRecoverOk(String consumerTag);/*** 接收消息时调用* @param consumerTag 消费者标签* @param envelope 打包消息的数据* @param properties 消息的内容标头数据* @param body 消息内容*/void handleDelivery(String consumerTag,Envelope envelope,AMQP.BasicProperties properties,byte[] body)throws IOException;
}
消费确认与拒绝
为了保障消息从队列可靠地到达消费者,RabbitMQ提供了消息确认机制。消费者在订阅队列时,可以指定autoAck参数,当autoAck为true时RabbitMQ会自动的把发送出去的消息设置为确认,然后从队列中删除;当autoACK为false时RabbitMQ会等待消费者显式回复确认信号后才从内存中移去消息(先标记再删除)。
autoAck参数意为自动应答,但是如果该参数为true时则rabbitMQ将自动将发送的消息标记确认,无需消费者进行应答。
当autoAck参数为false时,对于RabbitMQ服务器而言,队列中的消息分成两部分:一部分时等待投递给消费者的消息;一部分时已经投递给消费者,但是还未收到消费者确认消息的消息
RabbitMQ不会为未确认的消息设置过期时间,如果一个消息一直未被消费者确认,那么这个消息再RabbitMQ中将一直保存为投递未确认状态,指导消费者确认或者消费者断开连接,如果消费者断开连接,则该消费者接收但未确认的消息将重新入队。
消息确认的实现
消息的显式确认需要消费者再声明的过程中设置autoAck=false。然后该消费者消费的消息可以显式的进行确认应答。确认应答方法如下:
/*** @param 消息的标签,可通过Delivery.getEnvelope().getDeliveryTag()获取* @param 如果为true则将发送给该消费者的该消息之前的所有未应答的消息进行应答,如果为false则仅应答一条消息*/void basicAck(long deliveryTag, boolean multiple) throws IOException;
当进行消息的批量确认时,将所有发送给该消费者未确认的消息进行确认,而针对监听同一队列的其他消费者的未确认消息并不进行处理。
消息拒绝的实现
RabbitMQ提供了两种消息拒绝的方法:Basic.Reject和Basic.Nack命令;其两者的区别时Nack可以进行批量拒绝。
/*** @param deliveryTag 消息标签* @param requeue 为true时被拒绝的消息重新入队,否则将成为死信* @throws java.io.IOException if an error is encountered*/void basicReject(long deliveryTag, boolean requeue) throws IOException;/*** @param deliveryTag 消息标签* @param multiple 如果为true则批量拒绝自该消息之前所有未确认的发送给该消费者的消息* @param requeue 为true时被拒绝的消息重新入队,否则将成为死信* @throws java.io.IOException if an error is encountered*/void basicNack(long deliveryTag, boolean multiple, boolean requeue)throws IOException;
basicRecover
该方法可以将某个消费者未应答(确认或者拒绝)的消息重新入队,该方法会导致:
- 投递而未被应答的消息可以重新发送给消费者进行处理
- 消费者的消息队列被清空,可以重新接收到其他消息
/*** <p>* Ask the broker to resend unacknowledged messages. In 0-8* basic.recover is asynchronous; in 0-9-1 it is synchronous, and* the new, deprecated method basic.recover_async is asynchronous.* </p>* Equivalent to calling <code>basicRecover(true)</code>, messages* will be requeued and possibly delivered to a different consumer.* @see #basicRecover(boolean)*/Basic.RecoverOk basicRecover() throws IOException;/*** Ask the broker to resend unacknowledged messages. In 0-8* basic.recover is asynchronous; in 0-9-1 it is synchronous, and* the new, deprecated method basic.recover_async is asynchronous.* @param requeue If true, messages will be requeued and possibly* delivered to a different consumer. If false, messages will be* redelivered to the same consumer.*/Basic.RecoverOk basicRecover(boolean requeue) throws IOException;
basicQos 限制消费
默认情况下,消费者对于接收的消息数量并未限制,也就是说,一旦RabbitMQ中接收到消息并且存在消费者,则RabbitMQ将把消息发送到相关的消费者中,并不关心消费者是否消息完信息。
轮询的默认消息分发机制会导致消费者资源不能合理利用、消费者消息积压导致内存溢出等问题。为解决上述问题可以使用basicQos方法实现限制信道上消费者所能保持的最大未确认消息数量。该方法如下:
/*** @param prefetchSize 消息大小* @param prefetchCount 消息数量* @param global 是否全局* @throws java.io.IOException if an error is encountered*/void basicQos(int prefetchSize, int prefetchCount, boolean global) throws IOException;
针对global参数需要注意一下内容:
- 当global=true时信道上所有的消费者都需要遵从消息数量限定值(某个信道上所有消费者未确认消息数量<=prefetchCount)
- 等global=false时新的消费者需要遵从消息数量的限定值。
- 可以调用两次basicQos方法,并使用不同的global参数,这种情况下两次配置都可以生效。
总结
消费者就是针对某个队列进行消息监听和消息消费的。消费者消费消息存在拉模式和推模式,推模式的是使用场景相对比较多。
为确保消息被合法的消费,RabbitMQ提供了消费确认机制,投递的消息并不能被理解完成了消费,仅消费者确认消费该消息才会被移除队列。
默认的消息投递机制时轮询,轮询的消息分发并会关系消费者的性能以及消息积压的问题,因此需要限制每个消费者所能保持的最大未确认的消息数量。
相关文章:
RabbitMQ 消费者
RabbitMQ的消费模式分两种:推模式和拉模式,推模式采用Basic.Consume进行消费,拉模式则是调用Basic.Get进行消费。 消费者通过订阅队列从RabbitMQ中获取消息进行消费,为避免消息丢失可采用消费确认机制 消费者 拉模式拉模式的实…...
软件测试面试真题 | 什么是PO设计模式?
面试官问:UI自动化测试中有使用过设计模式吗?了解什么是PO设计模式吗? 考察点 《page object 设计模式》:PageObject设计模式的设计思想、设计原则 《web自动化测试实战》:结合PageObject在真实项目中的实践与应用情…...
GB2312转UTF-8部分中文乱码
现象 最近写了个txt导入,客户反馈有时候导入的数据,会出现个别中文乱码的现象,但是我之前已经做过编码转换处理了,统一转成了UTF-8。 比如“鞠婧祎”,导入进来是这样: 排查思路 首先看了一下这个文本的编码格式&am…...
项目——电子词典(客户端、服务器交互,字典导入,单词查询)
一、项目要求 登录注册功能,不能重复登录,重复注册单词查询功能历史记录功能,存储单词,意思,以及查询时间基于TCP,支持多客户端连接采用数据库保存用户信息与历史记录将dict.txt的数据导入到数据库中保存。…...
jenkins 是什么?
一、jenkins 是什么? Jenkins是一个开源的、提供友好操作界面的持续集成(CI)工具,起源于Hudson,主要用于持续、自动的构建/测试软件项目、监控外部任务的运行。Jenkins用Java语言编写,可在Tomcat等流行的servlet容器中运行&#…...
无涯教程-PHP - sql_regcase()函数
sql_regcase() - 语法 string sql_regcase (string string) 可以将sql_regcase()函数视为实用程序函数,它将输入参数字符串中的每个字符转换为包含两个字符的带括号的表达式。 sql_regcase() - 返回值 返回带括号的表达式字符串以及转换后的字符。 sql_regcase…...
cesium 实现鼠标中键拖动地图
cesium默认左键拖动地图,中键旋转,再绘图时带来诸多不便。所以改成鼠标中键按下拖动地图,鼠标左键选点。代码如下:【感谢chatGPT】 //改为中建拖动// 假设 viewer 是你的 Cesium Viewer 实例const cameraController viewer.scene…...
低压风机单片机方案
低压风机通常由电机、转子、机壳、进气管、出气管、齿轮和减速机等组成。电机带动转子旋转,旋转的转子带动齿轮和减速机转动,进而形成空气被吸入转子内部,通过旋转而产生的离心力把气体压缩,并将气体排出。 低压风机方案的主控型…...
R语言06-R语言的基本运算
概念 R语言支持多种基本运算,包括算术运算、逻辑运算、比较运算和向量化运算等。 代码示意 逻辑运算 a <- TRUE b <- FALSElogical_and <- a & b # 逻辑与 logical_or <- a | b # 逻辑或 logical_not <- !a # 逻辑非比较运算 x <…...
Docker容器:docker-compose管理创建LNMP服务并运行Wordpress网站平台
文章目录 一.项目环境1. 环境描述2.项目需求 二.部署过程1.安装Docker2.安装Docker加速器3.Docker-Compose安装部署4.准备依赖文件、配置nginx5.配置mysql6.配置php7.编写docker-compose.yml8.验证 三.容器快照,然后将Docker镜像打包成tar包备…...
实业兴国 守护种源 —— 白露木實®农业的活力之风
高科技领域,芯片是生命线;而在农业领域,种源与芯片在高科技领域的重要性是相同的。保护、发展、培育我国的种质资源,是中国农业发展至为关键的一环。但是,因为思想、观念、认识、技术等方面的原因,让我们错…...
Web3.0
一、Web3.0是什么 Web3.0(有时称为“分布式Web”或“去中心化Web”)是对互联网的下一代演进的概念。它代表了一种更加分散、去中心化和用户掌控的互联网模式,与传统的Web2.0模型有很大不同。 以下是Web3.0的一些关键特征和概念:…...
精密图纸被窃,知名手表品牌Seiko遭BlackCat勒索软件攻击
据BleepingComputer消息,日本著名手表制造商Seiko在7月末遭到了网络攻击,8月21日,BlackCat(又名ALPHV)勒索软件组织在其网站上宣布对这起攻击事件负责。 8 月 10 日,Seiko发布了一份数据泄露通知࿰…...
K8S如何部署Redis(单机、集群)
在今天的讨论中,我们将深入研究如何将Redis数据库迁移到云端,以便更好地利用云计算的优势提高数据管理的灵活性。 Redis(Remote Dictionary Server)是一个开源的、基于内存的数据结构存储系统,它可以用作数据库、缓存和消息代理。Redis支持多…...
Flask狼书笔记 | 03_模板
文章目录 3 模板3.1 模板基本使用3.2 模板结构组织3.3 模板进阶 3 模板 模板(template):包含固定内容和动态部分的可重用文件。Jinja2模板引擎可用于任何纯文本文件。 3.1 模板基本使用 HTML实体:https://dev.w3.org/html5/htm…...
MySQL 数据备份和数据恢复
目录 一、数据备份 1、概述 2、MySQLdump命令备份 1)备份单个数据库中的所有表 2) 备份数据中某个或多个表 3) 备份所有数据库 4)备份多个库 5) 只备份一个表或多个表结构 二、数据恢复 三、数据备份与恢复应用 一、数据备份 1、概述 数据备…...
软考高级系统架构设计师系列论文八十二:论软件的可维护性设计
软考高级系统架构设计师系列论文八十二:论软件的可维护性设计 一、摘要二、正文三、总结一、摘要 随着软件大型化,复杂化的发展,软件维护所耗费的资源越来越多,软件可维护性设计日益得到重视。我单位近几年开发综合业务 ATM交换机,用户对交换机的可维护性要求很高。我参加…...
Ompl初探
在/ompl-1.x.0/build/Release/bin下有很多生成的demo可执行文件 在终端执行 ./demo_Point2DPlanning 测试程序 #include <ompl/base/SpaceInformation.h> #include <ompl/base/spaces/SE3StateSpace.h> #include <ompl/base/StateSpace.h> #include <o…...
android sdk打包aar方案步骤
1.使用fat-aar库https://github.com/kezong/fat-aar-android/blob/master/README_CN.md 第一步:添加以下代码到你工程根目录下的build.gradle文件中: For Maven Central (The lastest release is available on Maven Central): buildscript {repositories {maven…...
Redis之bitmap类型解读
目录 基本介绍 基本命令 Setbit Getbit BITCOUNT 应用场景 统计当日活跃用户 用户签到 bitmap - Redis布隆过滤器 (应对缓存穿透问题) 基本介绍 Redis 的位图(bitmap)是由多个二进制位组成的数组,只有两…...
stm32之10.系统定时器
delay_s()延时秒 delay_ms()毫秒*1000 delay_us()微秒*1000000 微秒定时器代码 void delay_us(uint32_t n) { SysTick->CTRL 0; // Disable SysTick,关闭系统定时器 SysTick->LOAD SystemCoreClock/1000000*n-1; // 就是nus SysTick->LOAD Sys…...
PyTorch安装教程:从头开始配置PyTorch环境
PyTorch是一个开源的机器学习框架,广泛用于深度学习任务。要开始使用PyTorch,您需要在计算机上正确配置PyTorch环境。本文将为您提供一步步的指南,帮助您成功安装和配置PyTorch。 第一部分:安装Python和相关工具 第一步…...
Docker拉取并配置Grafana
Linux下安装Docker请参考:Linux安装Docker 安装准备 新建挂载目录 /opt/grafana/data目录,准备用来挂载放置grafana的数据 /opt/grafana/plugins目录,准备用来放置grafana的插件 /opt/grafana/config目录,准备用来挂载放置graf…...
Vue+Axios搭建二次元动态登录页面(mp4视频格式)
最近想做一个前端登录页面,背景好看的,格式中规中矩的,这么难?我自己创一个吧! 效果图如下: 源码可以参考我的github,复制源码即可用:gym02/loginPage_Vue: 使用VueAxios搭建的动态…...
【Kubernetes】K8S到底是什么,最近怎么这么火
前言 kubernetes,简称K8s,是用8代替名字中间的8个字符“ubernete”而成的缩写。是一个开源的,用于管理云平台中多个主机上的容器化的应用,Kubernetes的目标是让部署容器化的应用简单并且高效(powerful),Kub…...
Java爬虫下载网页图片
在Java中,可以使用HttpURLConnection,Jsoup等库来实现网页爬取和图片下载。下面是一个基本的例子: 首先,需要添加Jsoup库到你的项目中。如果你使用Maven,可以在你的pom.xml文件中添加以下依赖: xml <…...
C语言之扫雷游戏实现篇
目录 主函数test.c 菜单函数 选择循环 扫雷游戏实现分析 整体思路 问题1 问题2 问题3 问题4 游戏函数(函数调用) 创建游戏盘数组mine 创建游戏盘数组show 初始化游戏盘数组InitBoard 展示游戏盘DisplayBoard 游戏盘置雷SetMine 游戏…...
Python面向对象中super用法与MRO机制
Python面向对象中super用法与MRO机制 最近再看trackformer,里面用到了super的用法,记录一下super的用法 class A(object):def __init__(self):print(init A)def fun(self):print(A.fun)print(self)super(A, self).fun()class B(object):def __init__(s…...
高性能网络模式-Reactor
事实上,Reactor 模式也叫Dispatcher模式,即I/O 多路复⽤监听事件,收到事件后,根据事件类型分配(Dispatch)给某个进程/线程。Reactor 模式也是一种非阻塞同步网络模式。 Reactor 模式主要由 Reactor部分和处…...
gRpc的四种通信方式详细介绍
🌷🍁 博主猫头虎 带您 Go to New World.✨🍁 🦄 博客首页——猫头虎的博客🎐 🐳《面试题大全专栏》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 &a…...
JWT令牌的介绍
目录 一、什么是JWT 二、JWT令牌和Cookie客户端、Session服务端对比 三、特点与注意事项 四、使用场景 优点: 五、结构组成 一、什么是JWT JWT(JSON Web Token)是一种用于在网络应用间传递信息的开放标准(RFC 7519&#x…...
C语言入门 Day_9 条件判断
目录 前言: 1.if判断 2.else判断 3.易错点 4.思维导图 前言: 我们知道比较运算和逻辑运算都会得到一个布尔型的数据,要么为真(true),要么为假(false)。 今天我们来学习真和假在…...
Nodejs-nrm:快速切换npm源 / npm官方源和其他自定义源之间切换
一、理解 Nodejs nrm Nodejs nrm 是一个管理 npm 源的工具。由于 npm 在国内的速度较慢,很多开发者会使用淘宝的 npm 镜像源,但是也会遇到一些问题,例如某些包在淘宝镜像源中不存在,或者淘宝镜像源本身也会有问题。 Nodejs nrm …...
数据驱动洞察:各种词频分析技术挖掘热点数据
一、引言 随着信息时代的发展,人们的关注点日益复杂多样。社交媒体、新闻网站和论坛等平台上涌现了大量的信息,这使得热点分析成为了解社会热点话题和舆情动向的重要手段。词频统计是热点分析的基础,本文将分别介绍基于ElasticSearch、基于S…...
ES6-简介、语法
ES6 ES6简介 ECMAScript 6(简称ES6)是于2015年6月正式发布的JavaScript语言的标准,正式名为ECMAScript 2015(ES2015)。它的目标是使得JavaScript语言可以用来编写复杂的大型应用程序,成为企业级开发语…...
诚迈科技子公司智达诚远与Unity中国达成合作,打造智能座舱新时代
2023 年 8 月 23 日,全球领先的实时 3D 引擎 Unity 在华合资公司 Unity 中国举办发布会,正式对外发布 Unity 引擎中国版——团结引擎,并带来专为次世代汽车智能座舱打造的团结引擎车机版。发布会上,诚迈科技副总裁、诚迈科技子公司…...
算法与数据结构(十)--图的入门
一.图的定义和分类 定义:图是由一组顶点和一组能够将两个顶点连接的边组成的。 特殊的图: 1.自环:即一条连接一个顶点和其自身的边; 2.平行边:连接同一对顶点的两条边; 图的分类: 按照连接两个顶点的边的…...
【Go 基础篇】Go语言 init函数详解:包的初始化与应用
介绍 在Go语言中,init() 函数是一种特殊的函数,用于在包被导入时执行一次性的初始化操作。init() 函数不需要手动调用,而是在包被导入时自动执行。这使得我们可以在包导入时完成一些必要的初始化工作,确保包的使用具有正确的环境…...
wazuh环境配置及漏洞复现
目录 一、wazuh配置 1进入官网下载OVA启动软件 2.虚拟机OVA安装 二、wazuh案例复现 1.wazuh初体验 2.这里我们以SQL注入为例,在我们的代理服务器上进行SQL注入,看wazuh如何检测和响应 一、wazuh配置 1进入官网下载OVA启动软件 Virtual Machine (O…...
Java接收前端请求体方式
💗wei_shuo的个人主页 💫wei_shuo的学习社区 🌐Hello World ! 文章目录 RequestBodyPathVariableRequestParamValidated方法参数校验方法返回值校验 RequestHeaderHttpServletRequest ## Java接收前端请求体的方式 请求体…...
私有化部署即时通讯平台,30分钟替换钉钉和企业微信
随着企业对即时通讯和协作工具的需求不断增长,私有化部署的即时通讯平台成为企业的首选。WorkPlus作为有10余年行业深耕经验与技术沉淀品牌,以其安全高效的私有化部署即时通讯解决方案,帮助企业在30分钟内替换钉钉和企业微信。本文将深入探讨…...
如何深入理解 Node.js 中的流(Streams)
Node.js是一个强大的允许开发人员构建可扩展和高效的应用程序。Node.js的一个关键特性是其内置对流的支持。流是Node.js中的一个基本概念,它能够实现高效的数据处理,特别是在处理大量信息或实时处理数据时。 在本文中,我们将探讨Node.js中的流…...
MSP430FR2xxx开发(一)添加driverlib
一、新建工程 根据自己手上的硬件型号新建工程,文中已MSP430FR2355为例。 二、添加driverlib 首先去官方下载driverlib. https://www.ti.com.cn/tool/cn/MSPDRIVERLIB?keyMatchMSP430%20DRIVERLIB#downloads 下载后的内容如下: 我这里就选择MSP430…...
【C++】做一个飞机空战小游戏(九)——发射子弹的编程技巧
[导读]本系列博文内容链接如下: 【C】做一个飞机空战小游戏(一)——使用getch()函数获得键盘码值 【C】做一个飞机空战小游戏(二)——利用getch()函数实现键盘控制单个字符移动【C】做一个飞机空战小游戏(三)——getch()函数控制任意造型飞机图标移动 【C】做一个飞…...
34.SpringMVC获取请求参数
SpringMVC获取请求参数 通过ServletAPI获取 将HttpServletRequest作为控制器方法的形参,此时HttpServletRequest类型的参数表示封装了当前请求的请求报文的对象 index.html <form th:action"{/test/param}" method"post">用户名&#…...
TC1016-同星4路CAN(FD),2路LIN转USB接口卡
TC1016是同星智能推出的一款多通道CAN(FD)和LIN总线接口设备,CANFD总线速率最高支持8M bps,LIN支持速率0~20K bps,产品采用高速USB2.0接口与PC连接,Windows系统免驱设计使得设备具备极佳的系统兼容性。 支…...
Android源码——从Looper看ThreadLocal
1 概述 ThreadLocal用于在当前线程中存储数据,由于存储的数据只能在当前线程内使用,所以自然是线程安全的。 Handler体系中,Looper只会存在一个实例,且只在当前线程使用,所以使用ThreadLocal进行存储。 2 存储原理 …...
16、Flink 的table api与sql之连接外部系统: 读写外部系统的连接器和格式以及JDBC示例(4)
Flink 系列文章 1、Flink 部署、概念介绍、source、transformation、sink使用示例、四大基石介绍和示例等系列综合文章链接 13、Flink 的table api与sql的基本概念、通用api介绍及入门示例 14、Flink 的table api与sql之数据类型: 内置数据类型以及它们的属性 15、Flink 的ta…...
MySQL 自定义 split 存储过程
MySQL 没有提供 split 函数,但可以自己建立一个存储过程,将具有固定分隔符的字符串转成多行。之所以不能使用自定义函数实现此功能,是因为 MySQL 的自定义函数自能返回标量值,不能返回多行结果集。 MySQL 8: drop pr…...
专题-【十字链表】
有向图的十字链表表示法:...