更新内容

本次更新主要新增了 秒级定时任务 hyper/crontab 组件,以及修复了一些其它组件的 Bug

Added

  • #185 响应(Response) 增加 xml 格式支持;
  • #202 在协程内抛出未捕获的异常时,默认输出异常的 trace 信息;
  • #138 #197 增加秒级定时任务组件;

Changed

  • #195 变更 retry() 函数的 $times 参数的行为意义, 表示重试的次数而不是执行的次数;
  • #198 优化 Hyperf\Di\Containerhas() 方法, 当传递一个不可实例化的示例(如接口)至 $container->has($interface) 方法时,会返回 false
  • #199 当生产 AMQP 消息失败时,会自动重试一次;
  • #200 通过 Git 打包项目的部署包时,不再包含 tests 文件夹;

Fixed

  • #176 修复 LengthAwarePaginator::nextPageUrl() 方法返回值的类型约束;
  • #188 修复 Guzzle Client 的代理设置不生效的问题;
  • #211 修复 RPC Client 存在多个时会被最后一个覆盖的问题;
  • #212 修复 Guzzle Client 的 ssl_keycert 配置项不能正常工作的问题;

定时任务

通常来说,执行定时任务会通过 Linux 的 crontab 命令来实现,但现实情况下,并不是所有开发人员都能够拥有生产环境的服务器去设置定时任务的,这里 hyperf/crontab 组件为您提供了一个 秒级 定时任务功能,只需通过简单的定义即可完成一个定时任务的定义。

安装

composer require hyperf/crontab

使用

启动任务调度器进程

在使用定时任务组件之前,需要先在 config/autoload/processes.php 内注册一下 Hyperf\Crontab\Process\CrontabDispatcherProcess 自定义进程,如下:

<?php
// config/autoload/processes.php
return [
    Hyperf\Crontab\Process\CrontabDispatcherProcess::class,
];

这样服务启动时会启动一个自定义进程,用于对定时任务的解析和调度分发。如果您没有注册该进程,亦可理解为您关闭了定时任务功能。

定义定时任务

通过配置文件定义

您可于 config/autoload/crontab.php 的配置文件内配置您所有的定时任务,文件返回一个 Hyperf\Crontab\Crontab[] 结构的数组,如配置文件不存在可自行创建:

<?php
// config/autoload/crontab.php
use Hyperf\Crontab\Crontab;
return [
    (new Crontab())->setName('Foo')->setRule('* * * * *')->setCallback([App\Task\FooTask::class, 'execute'])->setMemo('这是一个示例的定时任务'),
];

通过注解定义

通过 @Crontab 注解可以快速完成对一个任务的定义,以下的定义示例与配置文件定义所达到的目的都是一样的。定义一个名为 Foo 每分钟执行一次 App\Task\FooTask::execute() 的定时任务。

<?php
namespace App\Task;

use Hyperf\Contract\StdoutLoggerInterface;
use Hyperf\Crontab\Annotation\Crontab;

/**
 * @Crontab(name="Foo", rule="* * * * *", callback="execute", memo="这是一个示例的定时任务")
 */
class FooTask
{

    /**
     * @Inject()
     * @var \Hyperf\Contract\StdoutLoggerInterface
     */
    private $logger;

    public function execute()
    {
        $this->logger->info(date('Y-m-d H:i:s', time()));
    }
}

任务属性

name

定时任务的名称,可以为任意字符串,各个定时任务之间的名称要唯一。

rule

定时任务的执行规则,在分钟级的定义时,与 Linux 的 crontab 命令的规则一致,在秒级的定义时,规则长度从 5 位变成 6 位,在规则的前面增加了对应秒级的节点,如 */5 * * * * * 则代表每 5 秒执行一次。注意在注解定义时,规则存在 \ 符号时,需要进行转义处理,即填写 *\/5 * * * * *

callback

定时任务的执行回调,即计划任务实际执行的代码,在通过配置文件定义时,这里需要传递一个 [$class, $method] 的数组,$class 为一个类的全称,$method$class 内的一个 public 方法。当通过注解定义时,只需要提供一个当前类内的 public 方法的方法名即可,如果当前类只有一个 public 方法,您甚至可以不提供该属性。

memo

定时任务的备注,该属性为可选属性,没有任何逻辑上的意义,仅供开发人员查阅帮助对该计划任务的理解。

调度分发策略

定时任务在设计上允许通过不同的策略来调度分发执行任务,目前仅提供了 多进程执行策略协程执行策略 两种策略,默认为 多进程执行策略,后面的迭代会增加更多更强的策略。

更改调度分发策略

通过在 config/dependencies.php 更改 Hyperf\Crontab\Strategy\StrategyInterface 接口类所对应的实例来更改目前所使用的策略,默认情况下使用 多进程执行策略,对应的类为 Hyperf\Crontab\Strategy\ProcessStrategy,如我们希望更改策略为一个新的策略,比如为 App\Crontab\Strategy\FooStrategy,那么如下:

<?php
return [
    'dependencies' => [
        \Hyperf\Crontab\Strategy\StrategyInterface::class => \App\Crontab\Strategy\FooStrategy::class,
    ],
];

多进程执行策略

策略类:Hyperf\Crontab\Strategy\ProcessStrategy

默认情况下使用此策略,即为 CrontabDispatcherProcess 进程解析定时任务,并通过进程间通讯轮训传递执行任务到各个 Worker 进程中,由各个 Worker 进程以协程来实际运行执行任务。

协程执行策略

策略类:Hyperf\Crontab\Strategy\CoroutineStrategy

默认情况下使用此策略,即为 CrontabDispatcherProcess 进程解析定时任务,并在进程内为每个执行任务创建一个协程来运行。

关于 Hyperf

Hyperf 是基于 Swoole 4.3+ 实现的高性能、高灵活性的 PHP 协程框架,内置协程服务器及大量常用的组件,性能较传统基于 PHP-FPM 的框架有质的提升,提供超高性能的同时,也保持着极其灵活的可扩展性,标准组件均均基于 PSR 标准 实现,基于强大的依赖注入设计,保证了绝大部分组件或类都是 可替换可复用 的。     框架组件库除了常见的协程版的 MySQL 客户端Redis 客户端,还为您准备了协程版的 Eloquent ORMWebSocket 服务端及客户端JSON RPC 服务端及客户端GRPC 服务端及客户端Zipkin (OpenTracing) 客户端Guzzle HTTP 客户端Elasticsearch 客户端Consul 客户端ETCD 客户端AMQP 组件Apollo 配置中心阿里云 ACM 应用配置管理基于令牌桶算法的限流器通用连接池熔断器Swagger 文档生成 等组件,省去了自己实现对应协程版本的麻烦,Hyperf 还提供了 基于 PSR-11 的依赖注入容器注解AOP 面向切面编程基于 PSR-15 的中间件自定义进程基于 PSR-14 的事件管理器Redis/RabbitMQ 消息队列自动模型缓存基于 PSR-16 的缓存 等非常便捷的功能,满足丰富的技术场景和业务场景,开箱即用。

框架初衷

尽管现在基于 PHP 语言开发的框架处于一个百花争鸣的时代,但仍旧未能看到一个优雅的设计与超高性能的共存的完美框架,亦没有看到一个真正为 PHP 微服务铺路的框架,此为 Hyperf 及其团队成员的初衷,我们将持续投入并为此付出努力,也欢迎你加入我们参与开源建设。

设计理念

Hyperspeed + Flexibility = Hyperf,从名字上我们就将 超高速灵活性 作为 Hyperf 的基因。

  • 对于超高速,我们基于 Swoole 协程并在框架设计上进行大量的优化以确保超高性能的输出。
  • 对于灵活性,我们基于 Hyperf 强大的依赖注入组件,组件均基于 PSR 标准 的契约和由 Hyperf 定义的契约实现,达到框架内的绝大部分的组件或类都是可替换的。

基于以上的特点,Hyperf 将存在丰富的可能性,如实现 Web 服务,网关服务,分布式中间件,微服务架构,游戏服务器,物联网(IOT)等。

文档齐全

我们投入了大量的时间用于文档的建设,以解决各种因为文档缺失所带来的问题,文档上也提供了大量的示例,对新手同样友好。

生产可用

我们为组件进行了大量的单元测试以保证逻辑的正确,同时维护了高质量的文档,在 Hyperf 正式对外开放(2019年6月20日)之前,便已在一家 C轮 和一家 B轮 互联网公司上线了多个服务并以稳定的姿态完美的运行了超过半年时间,经过了严酷的生产环境的考验,我们才正式的对外开放该项目。

Hyperf 官网