最近体验了一下微信小程序开发,做了一个简单的刷猫片的小玩具,效果大致如下: 开始是用 Laravel 写了 API,后来又用 Go 的 Iris 写了一套,压测了一下,Iris 的性能比 Laravel 的高了可不是一点点,后来就换 Iris 版本的 API 了。数据通过 Go 写了个简单的脚本抓取入库,附件上传到七牛。 本来这个小程序还有小论坛和复制淘宝链接功能的,但是上传到微信审核以后死活不能通过审核,就阉割掉了,暂时就先放几个刷猫片的小模块玩玩吧。 说下体验开发微信小程序的感受吧: 上手不难,尤其是熟悉 Vue.js 这样的前端框架的话刷下文档就直接上手做了 API 还算丰富,而且开放的 API 越来越多,脑洞大一点可以做一些有趣的小程序 从微信小程序后台统计来看,果然是用完即走,而且走了就不回来了 …… 微信小程序还是略封闭,比如我的社区板块一直审核不通过,关键也不告诉具体未通过的原因,就说未经微信授权巴拉巴拉的 源码请戳这里: https://github.com/yuansir/youmaolu-weixin-app-api https://github.com/yuansir/youmaolu-weixin-app 体验请微信扫描: 之前搭建的一个撸猫社区(有猫撸)一直放着没搞了,有空得把注册重新写一下,邮箱激活还不支持中文名这种注册方式确实太蛋疼了。。。。 转载请注明: 转载自Ryan 是菜鸟 | LNMP 技术栈笔记 如果觉得本篇文章对您十分有益,何不 打赏一下 本文链接地址: 微信小程序【有猫撸】开发体验 本作品采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可

阅读全文

Laravel 是我最喜欢的 PHP Web 开发框架,所以也希望可以在 Go 的 Web 框架中选择一个类似 Laravel 这样的好用又全栈的框架,刷了一下Beego, Echo , Gin, 以及Iris的文档,最终还是选择 Iris,当然我是没有从性能角度考虑,只是从可以快速开发,且支持的特性全还有就是看着顺眼的心理选择了 Iris,应该有不少 PHPer 像我一样使用 Laravel 同时在学习 Go,所以为了便于 Laravel 开发者可以快速的转到 Iris 开发,我准备写一系列这两者框架的比较文章。 基本路由 Iris 构建基本路由和 Laravel 的基本路由很像,都只需要一个 URI 与一个闭包: Laravel Route::get('foo', function () { return 'Hello World'; }); Iris app.Get("/foo", func(ctx iris.Context) { ctx.WriteString("Hello World") }) 可用的路由方法 Iris 和 Laravel 一样,能够响应任何的 HTTP 请求路由: Laravel Route::get($uri, $callback); Route::post($uri, $callback); Route::put($uri, $callback); Route::patch($uri, $callback); Route::delete($uri, $callback); Route::options($uri, $callback); Iris

阅读全文

看到Laravel-China 社区常有人问 Laravel Passport 用于密码验证方式来获取 Token 的问题,刚好我最近一个 API 项目使用 Laravel Dingo Api+Passport,也是使用 Oauth2 的'grant_type' => 'password'密码授权来做 Auth 验证,对于如何做登录登出,以及多账号系统的认证等常用场景做一下简单的使用小总结。 基本配置 基本安装配置主要参照官方文档,具体不详细说,列出关键代码段 config/auth.php 'guards' => [ 'api' => [ 'driver' => 'passport', 'provider' => 'users', ], ], 'providers' => [ 'users' => [ 'driver' => 'eloquent', 'model' => \App\Models\User::class ], ], Providers/AuthServiceProvider.php public function boot() { $this->registerPolicies(); //默认令牌发放的有效期是永久 //Passport::tokensExpireIn(Carbon::now()->addDays(2)); //Passport::refreshTokensExpireIn(Carbon::now()->addDays(4)); Passport::routes(function (RouteRegistrar $router) { //对于密码授权的方式只要这几个路由就可以了 config(['auth.guards.api.provider' => 'users']); $router->forAccessTokens(); }); } Middleware/AuthenticateApi.

阅读全文

译文 GitHub https://github.com/yuansir/diving-laravel-zh 原文链接 https://divinglaravel.com/queue-system/workers 现在,我们知道了 Laravel 如何将作业推到不同的队列中,让我们来深入了解 workers 如何运作你的作业。 首先,我将 workers 定义为一个在后台运行的简单 PHP 进程,目的是从存储空间中提取作业并针对多个配置选项运行它们。 php artisan queue:work 运行此命令将指示 Laravel 创建应用程序的一个实例并开始执行作业,这个实例将一直存活着,启动 Laravel 应用程序的操作只在运行命令时发生一次,同一个实例将被用于执行你的作业,这意味着: 避免在每个作业上启动整个应用程序来节省服务器资源。 在应用程序中所做的任何代码更改后必须手动重启 worker。 你也可以这样运行: php artisan queue:work --once 这将启动应用程序的一个实例,处理单个作业,然后干掉脚本。 php artisan queue:listen queue:listen 命令相当于无限循环地运行 queue:work --once 命令,这将导致以下问题: 每个循环都会启动一个应用程序实例。 分配的 worker 将选择一个工作并执行。 worker 进程将被干掉。 使用 queue:listen 确保为每个作业创建一个新的应用程序实例,这意味着代码更改以后不必手动重启 worker,同时也意味着将消耗更多的服务器资源。 queue:work 命令 我们来看看 Queue\Console\WorkCommand 类的 handle() 方法,这是当你运行 php artisan queue:work 时会执行的方法: public function handle() { if ($this->downForMaintenance() && $this->option('once')) { return $this->worker->sleep($this->option('sleep')); } $this->listenForEvents(); $connection = $this->argument('connection') ?

阅读全文

译文 GitHub https://github.com/yuansir/diving-laravel-zh 原文链接 https://divinglaravel.com/task-scheduling/preventing-overlapping 有时一个预定的工作需要比我们最初预期的更多的时间运行,这样会导致另外一个工作的实例开始,而第一个还没有完成,例如,我们运行一个每分钟生成报告的工作有时候当数据变大时,报表生成可能需要 1 分钟以上,这样就可以在第一个还在进行时启动该作业的另一个实例。 在大多数情况下,这是很好的,但有时候应该防止这种情况,以保证正确的数据或防止高的服务器资源消耗,所以让我们看看如何防止这种情况在 laravel 中发生: $schedule->command('mail:send')->withoutOverlapping(); Laravel 将检查 Console\Scheduling\Event::withoutOverlapping 类属性,如果设置为 true,它将尝试为作业创建互斥,并且只有在创建互斥的情况下才能运行该作业。 但是上面是互斥? 这是我可以在网上找到最有趣的解释: 当我在工作中进行热烈的讨论时,我使用一只橡胶鸡,我在这样的场合放在桌子上。 持有鸡的人是唯一被允许谈话的人。 如果你不握鸡,你不会说话。 你只能指示你想要鸡,等到你说话之前才能得到它。 一旦你完成演讲,你可以将鸡回到主持人,他将把它交给下一个人说话。 这样可以确保人们互不说话,也有自己的空间。 用线替换鸡与互斥和人,你基本上有一个互斥的概念。 – https://stackoverflow.com/questions/34524/what-is-a-mutex/34558#34558 所以当作业第一次启动时,Laravel 创建一个互斥,然后每次作业运行时,它检查互斥是否存在,只有在没有工作的情况下运行。 这里是 withoutOverlapping 方法中做的事 public function withoutOverlapping() { $this->withoutOverlapping = true; return $this->then(function () { $this->mutex->forget($this); })->skip(function () { return $this->mutex->exists($this); }); } 因此,Laravel 创建一个 filter-callback 方法,指示 Schedule Manager 忽略任务,如果互斥仍然存在,它还会创建一个在完成任务实例后清除互斥的回调。 在运行该作业之前,Laravel 会在Console\Scheduling\Event::run()方法中进行以下检查: if ($this->withoutOverlapping && ! $this->mutex->create($this)) { return; } 互斥体属性来自哪里? 当 Console\Scheduling\Schedule 的实例被实例化时,laravel 会检查 Console\Scheduling\Mutex 接口的实现是否绑定到容器,如果是,则使用该实例,如果不是,使用Console\Scheduling\CacheMutex实例:

阅读全文

译文 GitHub https://github.com/yuansir/diving-laravel-zh 原文链接 https://divinglaravel.com/task-scheduling/building-and-running-the-os-command 在启动计划任务的事件的时候,Laravel 的进度管理器在Illuminate\Console\Scheduling\Event对象上调用 run() 方法,表示该事件发生在 Illuminate\Console\Scheduling\ScheduleRunCommand 内。 这个 run() 方法构建命令语法,并使用 Symfony Process 组件在操作系统上运行它,但在构建命令之前,它首先检查该命令是否应该在后台运行,默认情况下所有命令都在前台运行 除非你使用以下方法来调度命令: ->runInBackground() 什么时候我需要在后台运行命令? 假设如果您有几个任务应该同时运行,比如每个小时,Laravel 默认设置会指示操作系统逐个运行命令: ~ php artisan update:coupons # Waiting for the command to finish # ... # Command finished, now we run the next one ~ php artisan send:mail 但是,你可以指示操作系统在后台运行命令,以便您可以继续推送更多命令,即使其他命令尚未完成: ~ php artisan update:coupons & ~ php artisan send:mail & 使用命令末尾的&符号可以继续推送命令,而无需等待初始化完成。 run() 方法检查 runInBackground 属性的值,并决定下一个调用哪个方法runCommandInForeground() 还是 runCommandInBackground()。

阅读全文

译文 GitHub https://github.com/yuansir/diving-laravel-zh 原文链接 https://divinglaravel.com/task-scheduling/properties-of-an-event 你添加的每个记录都将转换为 Illuminate\Console\Scheduling\Event 的实例,并存储在 Scheduler 的 $events 类属性中,Event 对象由以下内容组成: 命令运行 CRON 表达式 用于评估时间的时区 操作系统运行该命令的用户 命令应该运行的环境列表 维护模式配置 事件重叠配置 命令前台/后台运行配置 用于决定该命令是否运行的检查列表 如何处理输出的配置 命令运行后运行的回调 在命令运行前运行的回调 命令说明 命令的唯一 Mutex 命令可能像下面一种方式运行: 回调 在操作系统上运行的命令 artisan 命令 被调度的作业 使用回调 在回调的情况下,Container::call() 方法用于运行我们传递的值,这意味着我们可以传递一个可以调用或表示方法的字符串: protected function schedule(Schedule $schedule) { $schedule->call(function () { DB::table('recent_users')->delete(); })->daily(); } Or: protected function schedule(Schedule $schedule) { $schedule->call('MetricsRepository@cleanRecentUsers')->daily(); } 调用操作系统的命令 如果要运行操作系统的命令,可以使用 exec(): $schedule->exec('php /home/sendmail.php --user=10 --attachInvoice')->monthly(); 您还可以将数组作为参数:

阅读全文

译文 GitHub https://github.com/yuansir/diving-laravel-zh 原文链接 https://divinglaravel.com/task-scheduling/before-the-dive 想象这种情况,作为一个大型 SaaS 的开发者,您需要找到一种在周末每分钟选择 10 个随机客户的方式,并提供折扣升级,发送折扣的工作可能非常简单,但我们需要每分钟运行一次,为此我分享一些 CRON 的简要介绍给还不熟悉人。 CRON CRON 是一个守护进程,它驻留在你的 linux 服务器中,大部分时间都没有唤醒,但是每一分钟它都会睁开双眼,看看是否运行任何给定的任务,你使用 crontab 文件与该守护进程通信,在大多数常见的设置文件可以位于/etc/crontab,crontab 文件可能看起来像这样: 0 0 1 * * /home/full-backup 0 0 * * * /home/partial-backup 30 5 10 * * /home/check-subscriptions 在 crontab 文件中,每行表示一个计划任务作业,每个作业定义包含两部分: *部分代表该作业运行的计时器。 第二部分是应运行的命令 CRON 时序语法 5 个星号按顺序排列如下: 一小时内的分钟 一天内的小时 一个月内的日期 一年内的月份 一周的内的天 示例: 0 0 1 * * 在第一个例子中,表示该工作应在每月,每个月的第一个天,上午 12 点,每小时第一分钟运行。 或者简单地说,它应该在每月的第一天上午 12:00 运行。 0 * * * * 在第二个例子中,表示该工作应该每小时运行一次。 30 5 10 * * 表示该工作应该在每个月 10 日上午 5:30 运行 这里还有一些其他的示例:

阅读全文

译文 GitHub https://github.com/yuansir/diving-laravel-zh 原文链接https://divinglaravel.com/queue-system/pushing-jobs-to-queue 有几种方法可以将作业推送到队列中: Queue::push(new InvoiceEmail($order)); Bus::dispatch(new InvoiceEmail($order)); dispatch(new InvoiceEmail($order)); (new InvoiceEmail($order))->dispatch(); 调用Queue facade 是对应用程序使用的队列驱动的调用,如果你使用数据库队列驱动,调用push方法是调用Queue\DatabaseQueue类的push方法。 有几种有用的方法可以使用: // 将作业推送到特定的队列 Queue::pushOn('emails', new InvoiceEmail($order)); // 在给定的秒数之后推送作业 Queue::later(60, new InvoiceEmail($order)); // 延迟后将作业推送到特定的队列 Queue::laterOn('emails', 60, new InvoiceEmail($order)); // 推送多个作业 Queue::bulk([ new InvoiceEmail($order), new ThankYouEmail($order) ]); // 推送特定队列上的多个作业 Queue::bulk([ new InvoiceEmail($order), new ThankYouEmail($order) ], null, 'emails'); 调用这些方法之后,所选择的队列驱动会将给定的信息存储在存储空间中,供 workers 按需获取。 使用命令总线 使用命令总线调度作业进行排队可以给你额外控制权; 您可以从作业类中设置选定的connection, queue, and delay 来决定命令是否应该排队或立即运行,在运行之前通过管道发送作业,实际上你甚至可以从你的作业类中处理整个队列过程。 Bug facade 代理到Contracts\Bus\Dispatcher 容器别名,此别名解析为Bus\Dispatcher内的Bus\BusServiceProvider的一个实例: $this->app->singleton(Dispatcher::class, function ($app) { return new Dispatcher($app, function ($connection = null) use ($app) { return $app[QueueFactoryContract::class]->connection($connection); }); }); 所以Bus::dispatch() 调用的 dispatch() 方法是 Bus\Dispatcher 类的:

阅读全文

原文链接https://divinglaravel.com/queue-system/preparing-jobs-for-queue Every job we push to queue is stored in some storage space sorted by the order of execution, this storage place could be a MySQL database, Redis store, or a 3rd party service like Amazon SQS. 我们推送到队列的每个作业都存储在按执行顺序排序的某些存储空间中,该存储位置可以是 MySQL 数据库,Redis 存储或像 Amazon SQS 这样的第三方服务。 Later in this dive we’re going to explore how workers fetch these jobs and start executing them, but before that let’s see how we store our jobs, here are the attributes we keep for every job we store:

阅读全文

作者的图片

Ryan是菜鸟 | LNMP技术栈笔记

一步一个脚印,一直在路上!记录LNMP技术栈,Web架构,区块链等笔记

菜鸟码农

南京