eftec/usagimq

单文件版的Laravel Blade模板引擎

1.4 2018-08-06 15:14 UTC

This package is auto-updated.

Last update: 2024-09-07 07:05:25 UTC


README

logo

UsagiMQ

使用Redis和PHP在单个盒子(一个类)中实现的简约消息队列(少于500行代码)

为什么我应该使用消息队列(MQ)?

让我们来看一个例子,一个系统将信息发送到另一个系统,例如一个Web客户端和一个Web服务。

如果Web服务正在执行一个 慢操作 并且同时接收来自许多客户端的信息,那么,迟早,系统可能会崩溃或出现瓶颈。

例如,如果每个客户端完成操作(接收信息并存储在数据库中)需要0.1秒,而我们有1000名客户,那么每个操作可能需要1.6分钟。

Web Service

解决方案是在系统中添加一个消息队列。消息队列只是一个存储由发布者接收的消息/操作的服务器,之后订阅者可以执行。

对于同样的例子,发布者(以前的客户端)可以以0.001秒的速度调用MQ。然后订阅者可以执行所有操作,例如每小时或夜间,不必担心所有操作需要几分钟或几小时。

MQ

MQ应该尽可能快,能够监听和存储每个发布者的请求(信封)。然而,MQ并不执行最终操作,它类似于电子邮件服务器。稍后,订阅者可以读取这些信息并相应处理。

这种方法的一个缺点是它增加了延迟,处理过程不是同步执行的,而是异步执行的,发布者不知道信息是否被订阅者正确处理。

注意事项

这个库使用Redis。Redis是一个开源(BSD许可)的内存数据结构存储,用作数据库、缓存和消息代理。

为什么选择UsagiMQ?

虽然市场上有很多消息队列(包括开源、免费软件和商业),但它们大多数都是重量级的。UsagiMQ是轻量级的,它是在考虑定制的情况下开发的。你可以优化和定制它以满足你的需求,例如,改变信封的结构。

这是一个基于软件的解决方案,可以根据你的需求进行 重新编程。而大多数MQ都是基于 配置的

例如,你可以轻松地通过软件创建一个 ORCHESTRATION、CHOREOGRAPHY 或 CLUSTER。

UsagiMQ轻量级

  • 一个类,它需要Redis,不需要更多。
  • < 500行代码。
  • 易于定制。
  • 它只需要一个文件(UsagiMQ.php)

它是可扩展的吗?

是的,但它需要一个负载均衡器,你可以编程或使用软件或硬件解决方案。由你决定。

信封结构

  • id = 信封的标识(必需)。
  • from = 发送信封的人(可选)
  • body = 信封的内容(必需)。
  • date = 收到信封的日期。(必需,自动生成)
  • try = 尝试次数。(必需,用于将来,自动生成)

MQ服务器

谁在监听和存储信封(请求)。它应该尽可能快。

示例

include "UsagiMQ.php";
$usa=new UsagiMQ("127.0.0.1",6379,1);
if ($usa->connected) {
    $info=$usa->receive();
    if ($info=='NO INFO') {
        $usa->webUI(); // if not information is send, then it opens the UI.  It is optional
    } else {
        echo $info; // show the result.
    }
} else {
echo "not connected";
}

示例MQ服务器调用工作者(订阅者)。请参阅示例:mqwithworker.php

发布者(谁发送请求/信封)

发布者需要向页面发送POST请求。因此可以是CURL、JavaScript、PHP、Java、C#等。

URL应该是这样的:mq.php?id=ID&op=OP&from=FROM

而信封(内容)应以POST方式发送。

  • ID是消息的标识(必需,但不一定是唯一的)
  • OP是要执行的操作。它类似于文件夹或分类。
  • FROM是发送消息的人。它可以用于身份验证。
<?php
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL,            "http://localhost/UsagiMQ/mq.php?id=200&op=INSERTCUSTOMER&from=SALESSYSTEM" );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt($ch, CURLOPT_POST,           1 );
curl_setopt($ch, CURLOPT_POSTFIELDS,     "** IT IS WHAT WE WANT TO SEND**" );
curl_setopt($ch, CURLOPT_HTTPHEADER,     array('Content-Type: text/plain'));

$result=curl_exec ($ch);

echo $result; // if returns OKI then the operation was successful. Otherwise, it an error.

订阅者(本地)

这是一个本地订阅者(可以访问Redis)。然而,它可以用于创建远程订阅者。

可能它可以作为一个守护进程/在计划任务中/或根据请求运行。

示例

<?php
// its a local subscriber
include "UsagiMQ.php";

$usa=new UsagiMQ("127.0.0.1",6379,1);
if (!$usa->connected) {
    echo "not connected";
    die(1);
}

$listEnveloper=$usa->listPending("insert");

foreach($listEnveloper as $id) {
    $env=$usa->readItem($id);
    var_dump($env);
    // todo: code goes here

    // $correct indicates if the operation was successful or not. For example, if the operation was to insert and the operation failed.
    // We also could decide to delete it for any case. Its up to us.
    if ($correct) {
        $usa->deleteItem($id); // YAY!
    } else {
        $usa->failedItem($id,$env); // booh hiss!.
    }
}

命令

构造函数

$usa=new UsagiMQ($IPREDIS,$PORT,$DATABASE);

$IPREDIS表示Redis服务器所在的IP。$PORT(可选)表示Redis端口号(默认值6379)$DATABASE(可选),表示Redis的数据库(默认值为0)

receive()

从发布者接收信息。

listPending($op)

列出每个操作待处理封装器的所有键。

示例

$array=$usa->listPending('insert');

$array=$usa->listPending('update');

readItem($key)

读取一个项目。当读取一个项目时,它不会被删除。一旦处理完毕,应该删除它。键可以通过listPending命令获得。

示例

$usa->readItem('UsagiMQ_insert:2');

deleteItem($key)

删除一个项目。
键可以通过listPending命令获得。
示例

$usa->deleteItem('UsagiMQ_insert:2');

failedItem($key,$arr)

我们将项目标记为失败。失败的项目是我们将再次尝试的项目(直到达到限制)。如果我们尝试失败,那么我们将删除该项目。

  • 键可以通过listPending命令获得。
  • $arr是包含封装器的数组[id,from,body,date,try]
    示例

$usa->failedItem('UsagiMQ_insert:2',array('id'=>2,'from'=>'system','body'=>'xxx','date'=>'2000-01-01','try'=>0));

deleteAll()

删除所有项目和重置计数器。

close()

关闭Redis。这不是必需的。

showUI()

可选。它显示具有统计信息的UI。默认用户名和密码是admin,你应该更改它。

logo

版本

  • 2017-11-12 1.0 第一个版本
  • 2017-11-14 1.1 添加新成员并修复了listPending操作。现在它是排序的。
  • 2017-11-19 1.2 添加UI
  • 2017-11-21 1.3 为UI添加新功能。代码仍然少于500行。
  • 2018-08-06 1.4 一些修复

待办事项

  • 错误控制/日志
  • 自述文件中缺少命令
  • 自述文件中缺少发布者。