PHP使用RabbitMQ(正常连接与开启SSL验证后的连接)
代码中包含了PHP在一般情况下使用方法和RabbitMQ开启了SSL验证后的使用方法(我这边消费队列是使用接口请求的方式,每次只从中取出一条)
安装amqp扩展
PHP使用RabbitMQ前,需要安装amqp扩展,之前文章中介绍了Windows环境PHP安装amqp扩展的方法:windows环境PHP使用RabbitMq安装amqp扩展_windows mq扩展安装-CSDN博客
Linux中安装amqp扩展:
### 先进入/usr/local目录下,下载两个文件到此目录(我的PHP版本是7.2):wget -c https://github.com/alanxz/rabbitmq-c/releases/download/v0.8.0/rabbitmq-c-0.8.0.tar.gzwget -c http://pecl.php.net/get/amqp-1.9.3.tgz### 若使用的docker,将上面下载的两个包 拷贝到容器内【 docker cp ./文件 dockerID:/usr/local】,然后执行下面命令即可### 解压rabbitmq-c-0.8.0.tar.gztar zxf rabbitmq-c-0.8.0.tar.gzcd /usr/local/rabbitmq-c-0.8.0./configure --prefix=/usr/local/rabbitmq-c-0.8.0make && make install### 然后解压 amqp-1.9.3.tgz 解压后amqp-1.9.3文件下内还有个amqp-1.9.3文件夹,将内部的amqp-1.9.3目录拷贝到/usr/local/下,执行下列命令:cd /usr/local/amqp-1.9.3/usr/local/bin/phpize./configure --with-php-config=/usr/local/bin/php-config --with-amqp --with-librabbitmq-dir=/usr/local/rabbitmq-c-0.8.0cp /usr/local/rabbitmq-c-0.8.0/librabbitmq/amqp_ssl_socket.h /usr/local/amqp-1.9.3/make && make install### 最后修改php.ini 加上配置:extension = amqp.so
安装后,执行php -m 显示amqp
即表明扩展安装成功!
加载PHP代码的扩展包
然后需要加载代码的扩展包,比较方便快捷的方法是使用composer 加载扩展包
composer require php-amqplib/php-amqplib若想指定版本:composer require php-amqplib/php-amqplib:版本
具体使用哪个版本可以在此链接内查询:https://packagist.org/packages/php-amqplib/php-amqplib
示例代码(包含开启了SSL的连接方式)
<?phpnamespace common\helpers;use models\setting\Log;
use PhpAmqpLib\Connection\AMQPSSLConnection;
use PhpAmqpLib\Exception\AMQPTimeoutException;
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;class AmqpHelper
{/*** rabbitMq 未开启ssl验证 消费者* @return false|string|void* @throws \AMQPChannelException* @throws \AMQPConnectionException* @throws \AMQPQueueException* @time 2024/12/2 13:43* @author zsh*/public static function consumerResult(){//队列配置信息$configParams = array('host' => \Yii::$app->params['cotaTct']['queueHost'],'port' => \Yii::$app->params['cotaTct']['queuePort'],'login' => \Yii::$app->params['cotaTct']['queueLogin'],'password' => \Yii::$app->params['cotaTct']['queuePassword'],'vhost' => \Yii::$app->params['cotaTct']['queueVhost']);$conn = new \AMQPConnection($configParams);if (!$conn->connect()) {die("连接rabbitmq失败!\n");}//建立信道$channel = new \AMQPChannel($conn);// 创建队列$q = new \AMQPQueue($channel);$queueName = \Yii::$app->params['cotaTct']['queueName']; //队列名$q->setName($queueName);$q->setFlags(AMQP_DURABLE); // 持久化// 绑定交换机与队列,并指定路由键$q->bind(\Yii::$app->params['cotaTct']['exchange'], \Yii::$app->params['cotaTct']['routingKey']);// 消息获取$ret = $q->get(AMQP_AUTOACK);if ($ret) {
// echo "\nget data:\n";
// var_dump($ret->getBody());
// var_dump(json_decode($ret->getBody(), true));$conn->disconnect();return $ret->getBody();}else{$conn->disconnect();return false;}}/*** rabbitMq 开启ssl了验证 消费者* @return mixed|string|void* @throws \ErrorException* @time 2024/12/2 13:44* @author zsh*/public static function sslConsumerResult(){$configParams = array('host' => \Yii::$app->params['cotaTct']['prodQueueHost'],'port' => \Yii::$app->params['cotaTct']['prodQueuePort'],'login' => \Yii::$app->params['cotaTct']['prodQueueLogin'],'password' => \Yii::$app->params['cotaTct']['prodQueuePassword'],'vhost' => \Yii::$app->params['cotaTct']['queueVhost']);// 创建SSL连接时忽略证书验证$ssl_options = array('verify_peer' => false,'verify_peer_name' => false,);$connection = new AMQPSSLConnection($configParams['host'],$configParams['port'],$configParams['login'],$configParams['password'],$configParams['vhost'],$ssl_options);if (!$connection->isConnected()) {die("连接rabbitmq失败!\n");}
// echo '链接成功...';$queueName = \Yii::$app->params['cotaTct']['queueName']; //队列名$exchange = \Yii::$app->params['cotaTct']['exchange'];$routingKey = \Yii::$app->params['cotaTct']['routingKey'];$channel = $connection->channel();// 声明交换器$channel->exchange_declare($exchange, 'topic', false, true, false);// 获取系统生成的消息队列名称,这里也可以指定一个队列名称$channel->queue_declare($queueName, false, true, false, false);// 将队列名与交换器名进行绑定,并指定routing_key(路由键值)$channel->queue_bind($queueName,$exchange,$routingKey);$message = '';// 定义收到消息回调函数$callback = function ($msg) use (&$message) {
// echo 'Message:'.$msg->body;$message = $msg->body;// 手动确认消息是否正常消费$msg->delivery_info['channel']->basic_Ack($msg->delivery_info['delivery_tag']);};// 设置消费成功后才能继续进行下一个消费$channel->basic_qos(null, 1, null);// 开启消费no_ack=false,设置为手动应答$channel->basic_consume($queueName, '', false, false, false, false, $callback);// 循环进行消费
// while ($channel->is_consuming()) {
// try {
// $channel->wait(null, false, $timeout = 10);
// }catch (AMQPTimeoutException $ex){
// // 没有消息可处理,退出循环
// echo $ex->getMessage();
// break;
// }
// }if ($channel->is_consuming()) {try {$channel->wait(null, false, $timeout = 5);}catch (AMQPTimeoutException $ex){// 没有消息可处理,退出循环echo $ex->getMessage();}}//关闭连接$channel->close();$connection->close();$return = $message;unset($message);$message = null;return $return;}/*** rabbitMq 未开启ssl验证 生产者* @return mixed|string|void* @throws \ErrorException* @time 2024/12/2 13:44* @author zsh*/public static function producer($message){$configParams = array('host' => \Yii::$app->params['cotaTct']['queueHost'],'port' => \Yii::$app->params['cotaTct']['queuePort'],'login' => \Yii::$app->params['cotaTct']['queueLogin'],'password' => \Yii::$app->params['cotaTct']['queuePassword'],'vhost' => \Yii::$app->params['cotaTct']['queueVhost']);$exchangeName = \Yii::$app->params['cotaTct']['producerExchange'];try {$conn = new AMQPStreamConnection($configParams['host'], $configParams['port'], $configParams['login'], $configParams['password']);//创建channel$channel = $conn->channel();$channel->exchange_declare($exchangeName,'fanout',false,true,false);$messageData = new AMQPMessage($message);$channel->basic_publish($messageData, $exchangeName);$channel->close();$conn->close();return true;}catch (\Exception $e){Log::error('AMQP队列错误:'.$e,'AMQP');return false;}}/*** rabbitMq 开启了ssl验证 生产者* @return mixed|string|void* @throws \ErrorException* @time 2024/12/2 13:44* @author zsh*/public static function sslProducer($message){$configParams = array('host' => \Yii::$app->params['cotaTct']['prodQueueHost'],'port' => \Yii::$app->params['cotaTct']['prodQueuePort'],'login' => \Yii::$app->params['cotaTct']['prodQueueLogin'],'password' => \Yii::$app->params['cotaTct']['prodQueuePassword'],'vhost' => \Yii::$app->params['cotaTct']['queueVhost']);$exchangeName = \Yii::$app->params['cotaTct']['producerExchange'];// 创建SSL连接时忽略证书验证$ssl_options = array('verify_peer' => false,'verify_peer_name' => false,);try {$conn = new AMQPSSLConnection($configParams['host'],$configParams['port'],$configParams['login'],$configParams['password'],$configParams['vhost'],$ssl_options);if (!$conn->isConnected()) {die("连接rabbitmq失败!\n");}//创建channel$channel = $conn->channel();$channel->exchange_declare($exchangeName,'fanout',false,true,false);$messageData = new AMQPMessage($message);$channel->basic_publish($messageData, $exchangeName);$channel->close();$conn->close();return true;}catch (\Exception $e){Log::error('AMQP队列错误:'.$e,'AMQP');return false;}}
}
相关文章:
PHP使用RabbitMQ(正常连接与开启SSL验证后的连接)
代码中包含了PHP在一般情况下使用方法和RabbitMQ开启了SSL验证后的使用方法(我这边消费队列是使用接口请求的方式,每次只从中取出一条) 安装amqp扩展 PHP使用RabbitMQ前,需要安装amqp扩展,之前文章中介绍了Windows环…...
轻量级视觉骨干网络 MobileMamba: Lightweight Multi-Receptive Visual Mamba Network
MobileMamba 快速链接解决问题:视觉模型在移动设备端性能和效果的平衡性解决方法:改进网络结构训练和测试策略网络结构改进训练和测试策略 实验支撑:图像分类、分割,目标检测等图像分类结果对比目标检测和实例分割结果对比语义分割…...
科技云报到:数智化转型风高浪急,天翼云如何助力产业踏浪而行?
科技云报到原创。 捷径消亡,破旧立新,是今年千行百业的共同底色。 穿越产业周期,用数字化的力量重塑企业经营与增长的逻辑,再次成为数字化技术应用的主旋律,也是下一阶段产业投资的重点。 随着数字化转型行至“深水区…...
dockerfile部署前后端(vue+springboot)
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言0.环境说明和准备1.前端多环境打包1.1前端多环境设置1.2打包 2.后端项目多环境配置以及打包2.1后端多环境配置2.2项目打包 3.文件上传4.后端镜像制作4.1dockerf…...
c语言的思维导图
之前已经全部学完c语言了,所以为了更好的复习回顾,我做了一份c语言超详细的思维导图,帮助实现一张图就可以复习,避免盲目, 由于平台不支持直接发上图,有想要的小伙伴,可以私信找我要原件...
Android 拍照(有无存储权限两种方案,兼容Q及以上版本)
在某些行业,APP可能被禁止使用存储权限,或公司在写SDK功能,不方便获取权限 所以需要有 无存储权限拍照方案。这里两种方案都列出里。 对于写入权限,在高版本中,已经废弃, 不可用文件写入读取权限…...
MongoDB在自动化设备上的应用示例
发现MongoDB特别适合自动化检测数据的存储。。。 例如一个晶圆检测项目,定义其数据结构如下 #pragma once #include <vector> #include <QString> #include <QRectF> #include <string> #include <memory>class tpoWafer; class tp…...
draggable插件——实现元素的拖动排序——拖动和不可拖动的两种情况处理
最近在写后台管理系统的时候,遇到一个需求,就是关于拖动排序的功能。 我之前是写过一个关于拖动表格的功能,此功能可以实现表格中的每一行数据上下拖动实现排序的效果。 vue——实现表格的拖拽排序功能——技能提升 但是目前我这边的需求是…...
Redux的使用
到如今redux的已经不是react程序中必须的一部分内容了, 我们应该在本地需要大量更新全局变量时才使用它! redux vs reducer reducer的工作机制: 手动构造action对象传入dispatch函数中 dispatch函数将 action传入reducer当中 reducer结合当前state与a…...
【JAVA】Java高级:多数据源管理与Sharding:数据分片(Sharding)技术的实现与实践
大规模分布式系统,数据存储和管理变得越来越复杂。随着用户数量和数据量的急剧增加,单一数据库往往难以承载如此庞大的负载。这时,数据分片(Sharding)技术应运而生。数据分片是一种将数据水平切分到多个数据库实例的技…...
ASP.NET Core 9.0 静态资产传递优化 (MapStaticAssets )
一、结论 💢先看结论吧, MapStaticAssets 在大多数情况下可以替换 UseStaticFiles,它已针对为应用在生成和发布时了解的资产提供服务进行了优化。 如果应用服务来自其他位置(如磁盘或嵌入资源)的资产,则应…...
LeetCode刷题day18——贪心
LeetCode刷题day18——贪心 135. 分发糖果分析: 406. 根据身高重建队列分析:for (auto& p : people) 昨天写了一道,今天写了一道,都有思路,却不能全整对。昨天和小伙伴聊天,说是因为最近作业多…...
MATLAB Simulink® - 智能分拣系统
系列文章目录 前言 本示例展示了如何在虚幻引擎 环境中对四种不同形状的标准 PVC 管件实施半结构化智能分拣。本示例使用 Universal Robots UR5e cobot 执行垃圾箱拣选任务,从而成功检测并分类物体。cobot 的末端执行器是一个吸力抓手,它使 cobot 能够拾…...
linuxCNC(五)HAL驱动的指令介绍
HAL驱动的构成 指令举例详解 从终端进入到HAL命令行,执行halrun,即可进入halcmd命令行 # halrun指令描述oadrt加载comoonent,loadrt threads name1 period1创建新线程loadusr halmeter加载万用表UI界面loadusr halscope加载示波器UI界面sho…...
STM32 进阶 定时器3 通用定时器 案例2:测量PWM的频率/周期
需求分析 上一个案例我们输出了PWM波,这个案例我们使用输入捕获功能,来测试PWM波的频率/周期。 把测到的结果通过串口发送到电脑,检查测试的结果。 如何测量 1、输入捕获功能主要是:测量输入通道的上升沿和下降沿 2、让第一个…...
第一节、电路连接【51单片机-TB6600驱动器-步进电机教程】
摘要:本节介绍如何搭建一个51单片机TB6600驱动器步进电机控制电路,所用材料均为常见的模块,简单高效的方式搭建起硬件环境 一、硬件清单 ①51单片机最小控制系统 ②USB转TTL模块 ③开关电源 ④TB6600步进电机驱动器 ⑤二相四线步进电机 ⑥电…...
【通俗理解】Koopman算符与非线性动力系统分析
【通俗理解】Koopman算符与非线性动力系统分析 关键词: #Koopman算符 Koopman Operator #非线性动力系统 Nonlinear Dynamical System #无穷维线性算子 Infinite-Dimensional Linear Operator #演化分析 Evolution Analysis #Bernard Koopman Bernard Koopman 第…...
mybatis plus打印sql日志
1、官方文档 使用配置 | MyBatis-Plus 2、日志实现 MyBatis-Plus 提供了多种日志实现(log-impl),用于记录 SQL 语句和相关操作,帮助开发者进行调试和监控数据库操作。以下是一些可用的日志实现及其说明: StdOutImpl…...
ObjectMapper
ObjectMapper 是 Jackson 库中非常重要的一个类,它是 JSON 和 Java 对象之间进行序列化与反序列化的核心工具。ObjectMapper 的底层实现是基于 Jackson 的数据绑定模型,它将 Java 对象与 JSON 数据转换为互通格式。 1. ObjectMapper 的设计与核心功能 O…...
新增白名单赋予应用安装权限
目录 相关问题 具体实现 相关问题 安装app到/data/分区时,如何在安装阶段就赋予权限,无需请求权限 具体实现 frameworks/base/core/res/res/values/config.xml <!-- For whitelis apk --><string-array translatable"false" nam…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...
C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...
【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解
JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用,结合SQLite数据库实现联系人管理功能,并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能,同时可以最小化到系统…...
libfmt: 现代C++的格式化工具库介绍与酷炫功能
libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库,提供了高效、安全的文本格式化功能,是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全:…...
保姆级【快数学会Android端“动画“】+ 实现补间动画和逐帧动画!!!
目录 补间动画 1.创建资源文件夹 2.设置文件夹类型 3.创建.xml文件 4.样式设计 5.动画设置 6.动画的实现 内容拓展 7.在原基础上继续添加.xml文件 8.xml代码编写 (1)rotate_anim (2)scale_anim (3)translate_anim 9.MainActivity.java代码汇总 10.效果展示 逐帧…...
Kubernetes 节点自动伸缩(Cluster Autoscaler)原理与实践
在 Kubernetes 集群中,如何在保障应用高可用的同时有效地管理资源,一直是运维人员和开发者关注的重点。随着微服务架构的普及,集群内各个服务的负载波动日趋明显,传统的手动扩缩容方式已无法满足实时性和弹性需求。 Cluster Auto…...
Linux安全加固:从攻防视角构建系统免疫
Linux安全加固:从攻防视角构建系统免疫 构建坚不可摧的数字堡垒 引言:攻防对抗的新纪元 在日益复杂的网络威胁环境中,Linux系统安全已从被动防御转向主动免疫。2023年全球网络安全报告显示,高级持续性威胁(APT)攻击同比增长65%,平均入侵停留时间缩短至48小时。本章将从…...
基于单片机的宠物屋智能系统设计与实现(论文+源码)
本设计基于单片机的宠物屋智能系统核心是实现对宠物生活环境及状态的智能管理。系统以单片机为中枢,连接红外测温传感器,可实时精准捕捉宠物体温变化,以便及时发现健康异常;水位检测传感器时刻监测饮用水余量,防止宠物…...
对象回调初步研究
_OBJECT_TYPE结构分析 在介绍什么是对象回调前,首先要熟悉下结构 以我们上篇线程回调介绍过的导出的PsProcessType 结构为例,用_OBJECT_TYPE这个结构来解析它,0x80处就是今天要介绍的回调链表,但是先不着急,先把目光…...
