如何手动获取 RegistrationID(未解决) + horizon 队列处于暂停状态?(已解决)

请问老师,有两个问题请教下。

问题1

APP 获取 APNs 分配的 deviceToken,去 Jpush 注册并获取 RegistrationID

是APP自动将获取到的deviceToken发送到Jpush的服务器上,然后自动去注册并获取RegistrationID的吗?由于现在并没有APP,如果我想手动去得到一个可以使用的RegistrationID来测试Jpush的推送功能的话,应该怎么样去做呢?

问题2

当前的RegistrationID我们假设的是"test_registration_id",在修改了.env文件中的APP_ENV=testing后,根据\App\Notifications\TopicReplied\App\Listeners\PushNotification是否实现ShouldQueue,使用这个错误的RegistrationID会有不同的响应(有时会报错,有时不会,具体重现步骤见下)。

1. TopicReplied实现ShouldQueue,PushNotification不实现--不报错

app/Notifications/TopicReplied.php

class TopicReplied extends Notification implements ShouldQueue
//class TopicReplied extends Notification
...

app/Listeners/PushNotification.php

//class PushNotification implements ShouldQueue
class PushNotification

响应为:

  • postman不报错
    file
  • laravel.log内未见报错。
  • public/jpush.log内未见发送日志。

2. TopicReplied不实现ShouldQueue,PushNotification实现--不报错

app/Notifications/TopicReplied.php

//class TopicReplied extends Notification implements ShouldQueue
class TopicReplied extends Notification
...

app/Listeners/PushNotification.php

class PushNotification implements ShouldQueue
//class PushNotification

响应为:

  • postman不报错(时间明显更长,因为TopicReplied中有发送邮件)
    file
  • laravel.log内未见报错。
  • public/jpush.log内未见发送日志。
  • Laravel Horizon中有PushNotification的队列记录,但并没有失败?(从队列中取出job执行这个动作成功了,但即使这个job本身(推送)失败,但队列执行job还是成功了?)
    file

3. TopicReplied和PushNotification都实现ShouldQueue--不报错

app/Notifications/TopicReplied.php

class TopicReplied extends Notification implements ShouldQueue
//class TopicReplied extends Notification
...

app/Listeners/PushNotification.php

class PushNotification implements ShouldQueue
//class PushNotification

响应为:

  • postman不报错
  • laravel.log内未见报错。
  • public/jpush.log内未见发送日志。
  • Laravel Horizon中有TopicReplied的队列记录,而且是同一时间有两个同样的job
    file

4. TopicReplied和PushNotification都不实现ShouldQueue--报错

app/Notifications/TopicReplied.php

//class TopicReplied extends Notification implements ShouldQueue
class TopicReplied extends Notification
...

app/Listeners/PushNotification.php

//class PushNotification implements ShouldQueue
class PushNotification

响应为:

  • postman报错
    file
  • laravel.log内有报错记录:
    file
  • public/jpush.log内有发送日志:
    file

非常感谢!

日拱一卒
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
liyu001989
最佳答案

看看 status 还没执行啊,应该是 执行到 PushNotification 会尝试多次然后进入 failed,你的队列没有配置正确

5年前 评论
讨论数量: 10
liyu001989

看看 status 还没执行啊,应该是 执行到 PushNotification 会尝试多次然后进入 failed,你的队列没有配置正确

5年前 评论
liyu001989

file

为何要使用 testing ,testing 指的是单元测试

5年前 评论
liyu001989
  • 问题1,是的,app对注册,没有设备和 app 的配合貌似测试不了;
  • 问题2,TopicReplied 只是往数据库里面记录一条数据,怎么都不会报错啊,PushNotification 是真实的调用推送的逻辑,现在的情况就是报错啊。执行的顺序是 TopicReplied > PushNotification,执行到了 PushNotification 就会报错啊,同步的情况会返回响应,异步会显示在日志里面。你理解一下

这一节只是给一个真实场景的处理思路,遇到真实的场景可以参考一下,现在我没有想到好的测试方法

5年前 评论

@liyu001989 好的,谢谢老师。但是异步报错的并不会显示在日志中呀,我上面已经测试过了,还是说哪里没搞对?谢谢

5年前 评论
liyu001989
5年前 评论

@liyu001989 谢谢老师,这个我试过了,因为我手上的版本是5.7,configureMonologUsing这个方法已经没有了,参考了5.6的升级指南

The configureMonologUsing Method

If you were using the configureMonologUsing method to customize the Monolog instance for your application, you should now create a custom Log channel. For more information on how to create custom channels, check out the full logging documentation.

然后尝试创建自定义一个log channel

config/logging.php

  'channels' => [

        'custom' => [
            'driver' => 'custom',
            'via' => App\Logging\CreateCustomLogger::class,
        ],
        ...

app/Logging/CreateCustomLogger.php

<?php

namespace App\Logging;

use Monolog\Handler\RotatingFileHandler;
use Monolog\Logger;

class CreateCustomLogger
{
    /**
     * Create a custom Monolog instance.
     *
     * @param  array  $config
     * @return \Monolog\Logger
     */
    public function __invoke(array $config)
    {
        /**
         * Configure Monolog.
         */
        $processUser = posix_getpwuid(posix_geteuid());
        $processName = $processUser['name'];
        $filename = storage_path('logs/laravel-' . php_sapi_name() . '-'
            . $processName . '.log');
        $handler = new RotatingFileHandler($filename);
        $monolog = new Logger($config['driver']);
        $monolog->pushHandler($handler);
        return $monolog;
    }
}

修改.env

#LOG_CHANNEL=stack
LOG_CHANNEL=custom

然后清除配置缓存,重启queue

> php artisan config:clear
Configuration cache cleared!
> php artisan queue:restart
Broadcasting queue restart signal.
> sudo supervisorctl restart laravel_horizon
laravel_horizon: stopped
laravel_horizon: started

然后请求接口,正常返回结果,未报错。
file

查看日志文件夹,发现多了一个storage/logs/laravel-fpm-fcgi-vagrant-2018-11-27.log
file

内容如下:

[2018-11-27 10:25:56] custom.INFO: ============ URL: http://olarabbs.test/api/topics/68/replies =============== [] []
[2018-11-27 10:25:56] custom.DEBUG: [20.4ms] select * from `topics` where `id` = '68' limit 1 [] []
[2018-11-27 10:25:56] custom.DEBUG: [830μs] select * from `users` where `id` = '8' limit 1 [] []
[2018-11-27 10:25:56] custom.DEBUG: [7.22ms] insert into `replies` (`content`, `topic_id`, `user_id`, `updated_at`, `created_at`) values ('<p>有看看</p>', '68', '8', '2018-11-27 10:25:56', '2018-11-27 10:25:56') [] []
[2018-11-27 10:25:56] custom.DEBUG: [600μs] select * from `topics` where `topics`.`id` = '68' limit 1 [] []
[2018-11-27 10:25:56] custom.DEBUG: [2.31ms] update `topics` set `reply_count` = `reply_count` + 1, `updated_at` = '2018-11-27 10:25:56' where `id` = '68' [] []
[2018-11-27 10:25:56] custom.DEBUG: [390μs] select * from `users` where `users`.`id` = '1' limit 1 [] []
[2018-11-27 10:25:56] custom.DEBUG: [1.44ms] update `users` set `notification_count` = `notification_count` + 1, `updated_at` = '2018-11-27 10:25:56' where `id` = '1' [] []

这个还是没有报错记录啊。其他日志文件中也没有报错信息,试了好几次都是一样的。

5年前 评论
liyu001989

要不要试试 Horizon

5年前 评论

@liyu001989 已经用了Horizon了,但是没有报错。

file

5年前 评论

@liyu001989 老师正确,我的队列配置的确错了。。

原因在于我.env文件中写的APP_ENV=testing,但是由于安装了horizon,redis队列都是被horizon接管了,而我的config/horizon.php中,居然没有设置testing的配置。。

没有设置,就相当于没有连接上redis,所以会一直处于暂停状态,因此当然就不会报错了。。增加testing配置,然后再执行sudo supervisorctl restart laravel_horizon就OK了(教程中说要horizon:terminate,但我测试了这样也可以,方便记忆)

    'environments' => [
        ...
        'testing' => [
            'supervisor-1' => [
                'connection' => 'redis',
                'queue' => ['default'],
                'balance' => 'simple',
                'processes' => 3,
                'tries' => 3,
            ],
        ],
    ],

再来创建回复测试一下:
file

进入错误查看详情:
file

在自定义channel的日志中也可以看到报错了:
file

将channel改为默认的stack后,在默认的日志中也能看到报错了:
file

小结

  • 意外的学习了如何自定义log channel。
  • 对horizon配置文件理解更深入一层,明白了horizon运行的状态。
5年前 评论

@liyu001989 啊?不是测试服务器的意思么? 😅我以为.env文件中APP_ENV的值可以设置为production, local, testing...下次直接改为production😂

5年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!