Laravel Jobs and Queue 101,构建一个简单的分析应用程序

我使用Laravel的作业和队列已经有几年了。当我第一次开始使用它们时,我觉得非常困难,我无法理解这些概念,我们构建严重依赖它们的web应用程序的方式似乎有点奇怪,如果不是过于复杂的话。后来有一天,一切都变得清晰起来。希望同样的事情也会发生在你身上,你会开始怀疑这些年来你是如何不使用它们的。 p>据我所知,学习工作和排队(以Laravel为例)的主要问题并不是它的共谋性或新颖性,但事实上,我们在网上找到的大多数学习资源主要集中在理论上过于复杂的东西上,或者给出了在现实世界中找不到的非常简单的例子。 我写这篇教程是为了我过去的自己,这是我第一次开始学习这些概念时希望得到的教程。我喜欢用例子来解释任何复杂的想法。我们将一起构建一个简单的分析应用程序的各个部分,我们将从它的一个真正的基本版本开始,如果您是这个应用程序的唯一用户,那么您构建它的方式,然后我们将发现这种方法的缺点,以及一些作业和队列将帮助我们改进它并解决我们所面临的一些最大问题的方法我们的应用程序(命名为basic-analytics-v01)非常基本。这是一个应用程序,它允许我们跟踪我们的网站收到的流量。 让我们构建这个应用程序,同时记住我们可能也想向其他用户开放它,因此我们需要将用户数据分开,并且我们不应该需要太多的工作来将它集成到现有的网站中。 简而言之,每次用户访问某个网页时,网站都会向我们分析工具中的特定端点发送一个POST请求,然后我们将通过减去每两个连续POST请求的时间戳来计算每个网页上花费的时间。basic-analytics-v01 我们将保留此应用程序(或至少保留其第一个版本)它)非常简单。 让我们集中精力在数据库中存储这些点击,我们只需要一个端点和一个控制器(是的,我们现在将把所有的东西都放在一个控制器中)。 首先,让我们创建我们需要的两个主要模型和它们各自的迁移。 - Tracker:每个网站都有一个唯一的跟踪器,现在,我们只需要确保跟踪器的ID是一个有效的(它存在于数据库中)并且是唯一的。 - Hit:每个POST请求将被存储为一个\"命中\" 我们的控制器代码将如下所示: 1classTrackingControllerextendsController 2{ 3publicfunctiontrack($tracker_public_id, Request $request) 4{> 6if ($tracker) {> 8$hit =>>1011if ($previousHit) {13$previousHit->save();14return $previousHit->seconds;15}1617return0;18}1920return-1;21}22} 请记住,我们在这里过于简单化了许多事情,我们只是感兴趣在这个有助于阐明本文观点的用例中。 正如您所知,这段代码没有什么问题,特别是当您要处理的只是一个小型个人网站时。 但是让我们想象一下,在某些情况下,这段代码不够好,或者仅仅会中断。响应时间 让我们想象出于某种原因,发送这些请求的脚本需要等待并确认请求已被接收。 当我用Postman本地发送请求进行测试时,我得到的结果是: <100 ms是相当长的时间,尽管我们在控制器操作中没有做太多处理。假设我们所做的不仅仅是这个简单的处理,我们需要执行多个数据库查询,甚至与第三方API对话,我们将阻止发送请求的脚本(因此,我们可能会阻塞正在执行脚本的页面),直到完成处理。 并发请求数 无论您是在本地还是在生产服务器上运行Laravel应用程序,如果您使用本地开发服务器,并使用php artisan serve为您的Laravel应用程序提供服务,您会注意到服务器一次只能处理一个请求。 如果我们像在代码中一样同步执行代码,这意味着我们将更经常地达到这个限制,因为我们让Web服务器保持忙碌,我们会注意到太多的请求只是超时。这个问题的一个解决方案是尽快释放连接。数据丢失 读取当前代码时不容易想到的一个问题是,如果出现故障(例如,在尝试执行代码时,我们无法访问数据库,或者如果有一个bug抛出了一个异常)我们无法存储请求并重试。 现在让我们看看使用作业和队列将如何帮助我们解决所有这些问题:推送作业首先,让我们来讨论什么是队列和作业。 简而言之,作业是我们要执行的一段代码(例如方法)。我们把它放在一个队列中,以推迟它的执行,并将它委托给\"其他东西\"。 给你一个现实世界中的例子,当你去快餐连锁店吃饭时,接受你点菜的接待员不会是准备并送你的人,但是她会确保你的订单被正确地接受,然后把剩下的工作\"委托\"给其他人。 这背后的原因是接待员不需要让你排队等候,直到你拿到订单,而只需要做最少的和必要的工作,然后转到下一个订单(尽可能多的人同时服务)。我们希望在代码中实现同样的功能。 因此,在我们的代码中,我们只想确保接收到***9***请求,然后将剩余的作业委托给应用程序的另一部分。 一种方法是将要委托的代码放入一个闭包中,并将其分派到如下队列: ***10*** 但我建议您为代码创建一个专用的作业类,然后将其分派。 首先我们需要执行以下创建类的命令: ***11*** 此命令将生成以下类: ***12*** 现在让我们将代码从***14***中的***13***移动到新创建的***16***类中的***15***方法。***17***方法应该是这样的: ***18*** PS:不要忘记导入***19***和***20***模型以及请求类。 但是我们如何将参数(跟踪器公共ID以及请求本身)传递给跟踪代码?好吧,我们将它们传递给类的构造函数,然后handle方法可以像这样提取它们: ***21*** 现在每次我们收到新的命中,我们都需要分派一个新的作业。 我们可以按如下方式来做: ***22*** 看看我们的控制器有多干净和纤细。 如果您尝试发送一个***23***请求就像我们在一开始所做的那样,我们会注意到没有任何变化,我们仍然可以看到***24***表中的点击率,并且请求所用的时间仍然与上次相同(~100ms)。 那么,这里发生了什么?我们真的授权了吗?队列连接 如果您打开***25***文件,您会发现我们有一个名为***26***的变量设置为\"sync\",这意味着我们在调度任何作业后立即处理它们,并且我们是同步进行的。 因此,如果我们想从队列的强大功能中获益,我们需要将此队列连接更改为其他连接。换句话说,我们需要一个地方,在处理作业之前,我们可以\"排队\"/存储作业。 有多种选择。如果你看看***28***,你会注意到Laravel支持开箱即用的多个连接(\"sync\"、\"database\"、\"beanstalkd\"、\"sqs\"、\"redis\")。 由于我们刚刚开始使用队列和作业,现在让我们暂时避免任何需要第三方服务(beanstalkd和sqs)的队列连接,或者我们的开发机器(redis)中不一定有的应用程序。现在我们将继续使用***29***. 因此,每次我们收到新作业时,它都会存储在数据库中(在一个专用表中)。然后它将被提取和处理。 PS:如果您使用的是本地开发服务器,请不要忘记重新启动它,否则您对***30***文件所做的更改将不会被考虑。 ***31*** 在我们尝试发送***32***请求之前,我们需要创建一个存储这些作业的表。谢天谢地,Laravel为我们提供了一个命令,它将在执行这个命令(从而创建迁移)之后为我们生成这个表。 ***33*** ,我们需要运行迁移 ***34*** 现在如果我们再发送一次***35***请求,我们将注意到以下情况: - 响应时间稍短(因为我们不再同步处理请求)。 - 我们可以在***36***表中看到一个新条目 - ,但是没有***37***表中有新条目。

CSS无头WordPress到底有多合适?

我想知道无头WordPress会在哪里登陆。\"headless\"指的是只使用WordPress管理,通过WordPress restapi构建面向用户的站点,而不是传统的WordPress主题结构?WordPress的未来?还是相对利基?需求在哪里?当然,对它有需求。我知道很多人都这么做。例如,Gatsby有一个gatsby-source-wordpress插件,它允许您以使用wordpressrestapi的方式从WordPress站点获取内容,并将其缓存为GraphQL,以便在React-power...

日期:2021-06-24 01:15:34 浏览:625

CSS制作带有粘性页眉和页脚的表格变得更容易了

不久前,当我在博客中看到HTML中的粘性页眉和页脚时,一个表同时有粘性页眉和粘性第一列。在它里面,我从来没有在任何、或元素上使用position: sticky,因为即使Safari和Firefox可以做到这一点,Chrome也做不到。但是它可以做表格单元格,比如和,这是一个相当不错的解决办法。好吧,这已经改变了。我通过Twitter听说Chrome在v91中\"重写了表格\"。https://t.co/vTBplXWWtT我看到它掉了下来,升级了,然后做了一个快速测试。嘿,看看有粘性的表格页眉和页脚。@C...

日期:2021-06-24 02:00:01 浏览:939

CSS技巧编年史XXXX

只是我最近做的一些非现场工作的一个小链接汇总。就像我习惯的那样。DevJourney播客#151 Chris Coyier从陶瓷到CSS技巧和代码笔\"Chris带我们从玩他的第一个C64到他的陶瓷文学学士,再回到web开发。我们讨论了他在这一过程中的不同立场,以及他们是如何缓慢但肯定地引导他走向web开发的。我们浏览了CSS技巧的创造和娱乐,在开放中学习,以及美好的一天是什么样子。Podrocket Podcast火箭手术:Kaelan和Chris Coyier比较笔记我被要求删除这里嵌入的音频,如果你想...

日期:2021-06-24 02:00:03 浏览:865

CSS使用子资源完整性保护您的网站

当您从外部服务器加载文件时,您相信您请求的内容是您期望的内容。由于您不自己管理服务器,因此您依赖于另一个第三方的安全性,从而增加了攻击面。信任第三方并不是天生的坏事,但它肯定应该在网站安全的背景下加以考虑。一个真实的例子这不是纯粹的理论危险。忽视潜在的安全问题可能而且已经造成严重后果。2019年6月4日,Malwarebytes宣布他们在网站上发现了一个恶意的略读程序NBA.com. 由于Amazon S3存储桶受损,攻击者能够修改JavaScript库以窃取客户的信用卡信息。值得担心的不仅仅是JavaSc...

日期:2021-06-24 02:00:03 浏览:768

CSS联合的可能性

这是首字母缩略词RSS中不是形容词的一个词。非常简单联合更新:Lol这里有两个错误。RSS是首字母缩写而不是首字母缩写,\"Really\"是副词而不是形容词。RSS不仅仅是RSS阅读器。尽管如此,如果我不喜欢RSS阅读器。它是关于把内容放在一种设计成可移植的格式。内容的API并不是一个隐喻,这就是它的字面含义。RSS一直在我的脑海中,因为它就像我的日报,但我敢打赌它并不是人们关注的最高峰,甚至是开发者。尽管如此,它还是受到了一点关注,因为谷歌在androidchrome中引入了一个\"following\...

日期:2021-06-24 03:00:02 浏览:596

CSS在开放细节元素上添加背景

关于元素有一点奇怪,那就是,当它打开时,并不总是100%清楚该元素内部的内容和不内部的内容。我不是说总是重要,或者说它是一个特别难解决的问题,我只是注意到它最近出现在我身上。这里有一个直观的例子:这里的文本在里面,什么不是?这个解决方案是…CSS。把的样式设计得有点独特,这样问题就解决了。即使你希望排版是一样的,或者你不想任何独家风格,直到被打开,这仍然是可能的。使用alpha透明填充,您甚至可以确保更深的嵌套保持清晰。对于只插入内联内容的&lt;详细信息&gt;(如\"spoiler\"UI或其他内容),...

日期:2021-06-24 03:00:04 浏览:765

CSS容器查询的聚宝盆

我不知道是什么原因,但是我的feed在过去的几周里充斥着关于CSS容器查询的文章。有关集装箱查询的热议实际上始于去年12月,当时米丽亚姆•苏珊娜(Miriam Suzanne)发布了一份提案(采纳了大卫•巴隆的提案),但3月底,Una Kravets在推特上发布的一条消息称,他们在chrome://flags的#enable-container-queries旗后投放了Chrome Canary 91.0.4459.0在如此短的时间内,容器查询已经覆盖了如此多的地方,而且规范甚至还不是最终的!我很高兴看到C...

日期:2021-06-24 03:00:04 浏览:923

CSS target=blank

那会不会让你的眼睛有点抽搐?就像…是打字错误。值的开头应该是带有下划线的>。就像…Welp, that\"s correct syntax!In the case of the no-underscore>, the blank部分只是一个名称。可能是任何东西。它可以是>,或者,可能是为了预示这里的目的:>。是一个特殊的关键字,它将在新选项卡中打开链接,每次都打开一个新选项卡。>将在新选项卡中打开第一个单击的链接,但任何共享>的链接都将在新打开的选项卡中打开。我从来不知道这一点!我相信这条微博的解释。我创建...

日期:2021-06-24 04:00:02 浏览:1004

CSS查看WCAG 2.5.5以获得更好的目标尺寸

你有没有经历过这样的挫折:试图点击移动设备上的一个按钮却什么也不做,因为目标大小不够大,而且它在你的按键上不起作用?也许你有更大的手指,像我一样,也可能是由于灵活性有限。这是因为我们,即用户,必须与之交互的元素的目标区域越来越小,我们来谈谈如何使其足够大,以便用户能够轻松地与元素交互。如果用户在一个小型手持式触摸屏设备上访问内容,而这个设备的不动产要紧得多,那么这将是一个特别大的问题。成功标准重温我在上一篇涉及WCAG 2.1标准的文章中谈到了成功标准,Label in Name。简言之,WCAG标准是我们...

日期:2021-06-24 04:00:03 浏览:544

CSS Trickz:Netlify随需应变构建器的实验

默认情况下,WordPress站点有一个API。想看看这个网站的最新帖子吗,只是一组特定的数据…JSON格式?给你。Alex Riviere用它做了一个笑话站点。起初,当加载该API客户端时,该站点将fetch。很好,但是如果我们认真考虑一下,它对于访问站点的人来说是非常低效的(也就是说,比服务器呈现的HTML慢),对于API命中率也不是很高。所以,Alex用Netlify函数重新编写了它。然后Netlify函数将从API中fetch(在云中的节点中),并为预呈现的HTML提供服务。这可能更好一些,但正如亚...

日期:2021-06-24 04:00:04 浏览:593