消息队列初始

  1. JMS简介

全称:Java Message Service
中文:Java消息服务
JMS是Java的一套API标准,最初的目的是为了使应用程序能够访问现有的MOM系统(MOM是Message Oriented Middleware的英文缩写,指的是利用高效可靠的消息传递机制进行平台无关的数据交流,并基于数据通信来进行分布式系统的集成。);后来被许多现有的MOM供应商采用,并实现为MOM系统。
常见MOM系统包括Apache的ActiveMQ、阿里巴巴的RocketMQ、IBM的MQSeries、Microsoft的MSMQ、BEA的RabbitMQ等。(并非全部的MOM系统都遵循JMS规范)
基于JMS实现的MOM,又被称为JMS Provider

  1. 消息

“消息”是在两台计算机间传送的数据单位。消息可以非常简单,例如只包含文本字符串;也可以更复杂,可能包含嵌入对象。
消息被发送到队列中。“消息队列”是在消息的传输过程中保存消息的容器。消息队列的主要目的是提供路由并保证消息的传递;如果发送消息时接收者不可用,消息队列会保留消息,直到可以成功地传递它。

  1. 消息队列的主要功能

a. 削峰

在秒杀或抢够活动中使用广泛使用。这种活动一般会因为流量过大,应用系统配置承载不了这股瞬间流量,导致系统直接挂掉,即传说中的“宕机”现象。为解决这个问题,我们会将那股巨大的流量拒在系统的上层,即将其转移至 MQ 而不直接涌入我们的接口,此时MQ起到了缓冲作用。、
在这里插入图片描述

b. 应用解耦

场景说明:后台发货系统,发货后快递发货系统需要通知订单系统,该订单已发货。如果我们用传统的做法是,快递发货系统调用订单系统的接口,更新订单为已发货。
传统模式的缺点:
1) 假如订单系统无法访问,则订单更新为已发货失败,从而导致发货失败;
2) 发货系统与订单系统耦合;
如何解决:
在这里插入图片描述
发货系统:发货后,发货系统完成持久化处理,将消息写入消息队列,返回发货成功。
订单系统:订阅发货的消息,获取发货信息,订单系统根据信息,进行更新操作。
如上,发货系统在发货的时候不用关心后续操作了,如果订单系统不能正常使用。也不影响正常发货,实现订单系统与发货系统的应用解耦。

c. 异步处理

场景说明:用户注册后,需要发注册邮件和注册短信。传统的做法有两种1.串行的方式;2.并行方式
(1)串行方式:将注册信息持久化后,发送注册邮件,再发送注册短信。三个业务全部完成后,返回给客户端。

并行方式:将注册信息持久化后,发送注册邮件的同时,发送注册短信。三个业务全部完成后,返回给客户端。与串行的差别是,并行的方式可以提高处理的时间。
在这里插入图片描述
假设三个业务节点每个使用100毫秒钟,不考虑其他开销,则串行方式的时间是300ms,并行的时间可能是200毫秒。则串行的方式1秒内可处理3次请求,并行方式1秒内可处理5次请求,综上所述,传统的方式系统的性能(并发量,吞吐量,响应时间)会有瓶颈。如何解决这个问题呢?
引入消息队列,将不是必须的业务逻辑,异步处理。如下图所示
在这里插入图片描述
按照上图,用户的响应时间相当于是注册信息写入数据库的时间和将消息插入消息队列,也就是105毫秒。注册邮件,发送短信消息写入队列后,直接返回。如此消息队列异步处理后,1秒内可处理9次请求。大大提高了系统的性能

d. 消息通讯

消息通讯是指,消息队列一般都内置了高效的通信机制,因此也可以用在实现消息通讯。如点对点消息队列,或者聊天室等。
点对点通讯:客户端A和客户端B使用同一队列,进行消息通讯。
聊天室通讯:客户端A,客户端B 订阅同一主题,进行消息发布和接收。
以上实际是消息队列的两种消息模式,点对点或发布订阅模式。

<think>嗯,用户让我用C语言写一个消息队列初始化函数,如果消息队列存在的话就清空它。首先,我需要理解消息队列在C语言中的实现方式。消息队列通常可以通过System V或者POSIX两种方式实现。用户没有具体说明,可能需要我选择一个常见的实现方式。System V的消息队列比较传统,可能更适合这个例子。 接下来,我需要考虑如何初始化消息队列初始化函数需要做两件事:如果消息队列不存在,就创建它;如果已经存在,就清空里面的消息。这里可能需要用到msgget函数来获取消息队列的标识符。使用IPC_CREAT和IPC_EXCL标志可以判断消息队列是否存在。如果创建失败并且错误是EEXIST,说明队列已经存在,这时候需要用msgctl函数来清空它。 然后,如何处理清空消息队列呢?msgctl函数配合IPC_RMID命令可以删除消息队列,但删除后可能需要重新创建。不过,直接删除再创建可能更有效,因为这样可以确保队列被彻底清空。不过,可能有些系统在删除后立即重新创建会有问题,需要处理可能的竞态条件。 还需要考虑权限的问题。在创建消息队列时,需要设置合适的权限,比如0666,允许用户、组和其他人读写。另外,函数的参数可能需要包括一个key_t类型的键值,以及消息队列的标识符。 可能还需要处理错误情况,比如msgget或msgctl失败时,应该返回错误码或者进行错误处理。用户可能希望函数返回一个整数,0表示成功,非零表示错误。或者返回消息队列的ID,并在出错时返回-1。 然后,编写函数的大致步骤应该是这样的:首先尝试创建消息队列,如果创建失败并且是因为已经存在,则获取现有的队列,然后删除它,再重新创建。或者,直接打开现有的队列,然后使用IPC_RMID删除,再创建新的。不过,删除后是否需要立即创建?或者用户希望函数返回一个可用的消息队列,无论之前是否存在。 另外,清空消息队列和删除再创建的区别是什么?如果队列中有消息,直接删除再创建会更彻底,而清空可能需要循环读取所有消息直到队列为空,这可能效率较低,尤其是当队列中有大量消息时。所以,可能更高效的方式是删除现有的队列,然后重新创建。 不过,如果其他进程正在使用该消息队列,删除可能会导致问题。所以,这个函数可能应该在确定没有其他进程使用该队列时调用,比如在初始化阶段。或者,用户可能有其他机制确保独占访问。 综上所述,函数的实现步骤可能是: 1. 使用msgget尝试创建消息队列,带有IPC_CREAT | IPC_EXCL标志。 2. 如果创建失败且错误是EEXIST,则用msgget不带IPC_EXCL打开现有队列。 3. 使用msgctl与IPC_RMID删除现有队列。 4. 再次调用msgget创建新的队列。 5. 处理可能的错误,如权限不足等。 但是,删除队列后,其他进程可能已经创建了新的队列,所以需要考虑竞态条件。或者,可能需要使用ftok生成唯一的键值,确保队列的唯一性。 另外,可能需要提供一个示例代码,展示如何调用这个函数,并处理错误情况。 最后,测试这个函数的时候需要注意权限问题,可能需要使用ipcs和ipcrm命令来查看和删除残留的消息队列,避免调试时的干扰。</think>以下是用C语言实现的消息队列初始化函数示例,包含存在时清空队列的功能。这里以System V消息队列为例: ```c #include <stdio.h> #include <stdlib.h> #include <sys/msg.h> #include <sys/ipc.h> #include <
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值