如何手动获取 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

非常感谢!

日拱一卒
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
liyu001989
最佳答案

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

5年前 评论
讨论数量: 10
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

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

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

file

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

5年前 评论

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

5年前 评论

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