- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 Laravel 5 构建一个 web 应用程序,该应用程序创建指向 web 应用程序的链接,当访问该链接时,会显示学生进度报告的表单。这些链接由 Web 应用程序发送到学生就读机构的联系人的电子邮件,以便收件人完成通过电子邮件中的链接访问的进度报告。
我面临的问题是创建和发送链接时。我有一些代码适用于几百名学生,但在现实世界中使用该应用程序可能一次创建和发送 3000 多个链接。我写的代码根本无法及时处理这么大的数字,应用程序崩溃了。奇怪的是,虽然我没有通过 laravel 收到任何超时错误(我需要仔细检查 php 日志)。
尽管我非常欢迎其他建议,但我相信问题的答案是利用队列。我在发送电子邮件时已经使用了队列(请参阅代码),但我想将代码的其他部分处理到队列中,但我有点不确定如何执行此操作!
简要数据库架构 Student
hasMany Link
Student
hasMany InstitutionContact
(根据我的申请限制为两个)Link
hasMany InstitutionContact
(根据我的申请限制为两个)Email
多对多 Link
我正在努力完成的工作
Student
需要一个新的 Link
Link
每个Student
Student
的当前 InstitutionContact
s 到 Link
的 InstitutionContact
(A Student
的机构联系方式可能会发生变化,因此如果需要重新发送,我会将 InstitutionContact
链接到该链接。Links
为了通过共享将它们组合在一起 InstitutionContact
s - 这是不是每个链接都发送一封电子邮件(因此可能会发送许多带有一个链接到同一地址的电子邮件),而是应该将链接按相同的电子邮件/联系人分组在一起,并在适用的情况下一起发送 Link
按电子邮件/联系人分组,以及:Link
的电子邮件的信息(网址、学生姓名等)到指定的 InstitutionContact
的电子邮件地址 Email
到数据库 Email
在前一步中创建的 Link
(s) 在其中发送的(因此该应用程序可用于搜索在哪个电子邮件中发送的链接)Link
通过队列一个接一个,但是这不允许我将所有
Link
分组通过联系方式/电子邮件联系在一起。由于该任务不会定期执行,我愿意考虑执行该任务,因为它会增加进程的内存和时间,但是我在尝试使用
set_time_limit(0);
时并没有取得太大的成功。和
ini_set('memory_limit','1056M');
在发送任何链接之前。
public function storeAndSendMass(Request $request)
{
$this->validate($request, [
'student_id' => 'required|array',
'subject' => 'required|max:255',
'body' => 'required|max:5000',
]);
$studentIds = $request->get('student_id');
$subject = $request->get('subject');
$body = $request->get('body');
$students = $this->student
->with('institutionContacts')
->whereIn('id', $studentIds)
->where('is_active', 1)
->get();
// create link, see Link.php below for method
$newLinks = $this->link->createActiveLink($students);
// send link to student's contact(s), see LinkEmailer.php below for method
$this->linkEmailer->send($newLinks, ['subject' => $subject, 'body' => $body], 'mass');
// return
return response()->json([
'message' => 'Creating and sending links'
]);
}
public function createActiveLink($students)
{
$links = [];
foreach ($students as $student) {
$newLink = $this->create([
'token' => $student->id, // automatically hashed
'status' => 'active',
'sacb_refno' => $student->sacb_refno,
'course_title' => $student->course_title,
'university_id' => $student->university_id,
'student_id' => $student->id,
'institution_id' => $student->institution_id,
'course_id' => $student->course_id,
]);
$studentContacts = $student->institutionContacts;
if ($studentContacts) {
foreach ($studentContacts as $studentContact) {
$newLink->contacts()->create([
'type' => $studentContact->pivot->type,
'institution_contact_id' => $studentContact->pivot->institution_contact_id
]);
$newLink->save();
}
}
$links[] = $newLink->load('student');
}
return $links;
}
namespace App\Emails;
use App\Emails\EmailComposer;
class LinkEmailer
{
protected $emailComposer;
public function __construct(EmailComposer $emailComposer)
{
$this->emailComposer = $emailComposer;
}
public function send($links, $emailDetails, $emailType)
{
$contactsAndLinks = $this->arrangeContactsToLinks($links);
foreach ($contactsAndLinks as $linksAndContact) {
$emailData = array_merge($linksAndContact, $emailDetails);
// send/queue email
\Mail::queue('emails/queued/reports', $emailData, function ($message) use ($emailData) {
$message
->to($emailData['email'], $emailData['formal_name'])
->subject($emailData['subject']);
});
// compose email message, returns text of the email
$emailMessage = $this->emailComposer->composeMessage($emailData);
// // create Email
$email = \App\Models\Email::create([
'to' => $emailData['email'],
'from' => 'report@domain.org',
'subject' => $emailData['subject'],
'body' => $emailMessage,
'type' => $emailType,
'user' => $_SERVER['REMOTE_USER']
]);
foreach ($linksAndContact['links'] as $link) {
$link->emails()->attach($email->id);
}
}
}
// group links by contact
public function arrangeContactsToLinks($links)
{
$contactsForLinks = [];
$assigned = false;
$match = false;
foreach ($links as $link) { // 1, n
if ($link->contacts) {
foreach ($link->contacts as $contact) { // 1, 2
if ($contactsForLinks) {
$assigned = false;
foreach ($contactsForLinks as $key => $contactLink) { // n
// assign links to existing email in array
if ($contactLink['email'] === $contact->institutionContact->email) {
$match = false;
// check link hasn't already been included
foreach ($contactsForLinks[$key]['links'] as $assignedLink) {
if ($assignedLink === $link) {
$match = true;
}
}
// if there was no match add to list of links
if (!$match) {
$contactsForLinks[$key]['links'][] = $link->load('student');
$assigned = true;
break;
}
}
}
if (!$assigned) {
$contactsForLinks[] = [
'email' => $contact->institutionContact->email,
'formal_name' => $contact->institutionContact->formal_name,
'requires_id' => $contact->institutionContact->institution->requires_id,
'requires_course_title' => $contact->institutionContact->institution->requires_course_title,
'links' => [$link->load('student')],
];
}
} else {
$contactsForLinks[] = [
'email' => $contact->institutionContact->email,
'formal_name' => $contact->institutionContact->formal_name,
'requires_id' => $contact->institutionContact->institution->requires_id,
'requires_course_title' => $contact->institutionContact->institution->requires_course_title,
'links' => [$link->load('student')],
];
}
}
}
}
return $contactsForLinks;
}
}
set_time_limit(0);
和
ini_set('memory_limit','1056M');
做 3000 名学生用了 8 分钟。
link
创建过程到一个队列中,该队列将在数据库中有一个相关实体,名为
Batch
当那个
Batch
链接已完成创建,然后将所有
Link
分组来自那个
Batch
并发送它们。
sent_at
Link
中的字段s 表并有一个预定的进程来检查
Link
s 尚未发送,然后发送它们。但是,使用上述方法我可以发送
Batch
的
Link
s 当它们都完成创建时,而使用
sent_at
使用预定进程寻找
Link
的方法尚未发送的 s 可能会在尚未创建所有链接时发送一些链接。
最佳答案
如果您使用少量数据测试了您的代码并且它成功而没有崩溃,那么很明显问题是(如您所说)您正在处理的记录数量非常多。为什么不使用 处理您的收藏?大块 方法?
根据 Laravel 文档:
If you need to process thousands of Eloquent records, use the chunk command. The chunk method will retrieve a "chunk" of Eloquent models, feeding them to a given Closure for processing. Using the chunk method will conserve memory when working with large result sets
关于php - Laravel:将大量任务放入队列中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35648386/
Task.WaitAll 方法等待所有任务,Task.WaitAny 方法等待一个任务。如何等待任意N个任务? 用例:下载搜索结果页面,每个结果都需要一个单独的任务来下载和处理。如果我使用 WaitA
我正在查看一些像这样的遗留 C# 代码: await Task.Run(() => { _logger.LogException(LogLevel.Error, mes
如何在 Linux 中运行 cron 任务? 关注此Q&A ,我有这个 cron 任务要运行 - 只是将一些信息写入 txt 文件, // /var/www/cron.php $myfile = fo
原谅我的新手问题,但我想按顺序执行三个任务并在剧本中使用两个角色: 任务 角色 任务 角色 任务 这是我到目前为止(任务,角色,任务): --- - name: Task Role Task ho
我有一个依赖于 installDist 的自定义任务 - 不仅用于执行,还依赖于 installDist 输出: project.task('run', type: JavaExec, depends
从使用 Wix 创建的 MSI 运行卸载时,我需要在尝试删除任何文件之前强行终止在后台运行的进程。主要应用程序由一个托盘图标组成,它反射(reflect)了 bg 进程监控本地 Windows 服务的
我想编写 Ant 任务来自动执行启动服务器的任务,然后使用我的应用程序的 URL 打开 Internet Explorer。 显然我必须执行 startServer先任务,然后 startApplic
使用 ASP.NET 4.5,我正在尝试使用新的 async/await 玩具。我有一个 IDataReader 实现类,它包装了一个特定于供应商的阅读器(如 SqlDatareader)。我有一个简
使用命令 gradle tasks可以得到一份所有可用任务的报告。有什么方法可以向此命令添加参数并按任务组过滤任务。 我想发出类似 gradle tasks group:Demo 的命令筛选所有任务并
除了sshexec,还有什么办法吗?任务要做到这一点?我知道您可以使用 scp 复制文件任务。但是,我需要执行其他操作,例如检查是否存在某些文件夹,然后将其删除。我想使用类似 condition 的东
假设我有字符串 - "D:\ApEx_Schema\Functions\new.sql@@\main\ONEVIEW_Integration\3" 我需要将以下内容提取到 diff 变量中 - 文档名
我需要编写一个 ant 任务来确定某个文件是否是只读的,如果是,则失败。我想避免使用自定义选择器来为我们的构建系统的性质做这件事。任何人都有任何想法如何去做?我正在使用 ant 1.8 + ant-c
这是一个相当普遍的计算机科学问题,并不特定于任何操作系统或框架。 因此,我对与在线程池上切换任务相关的开销感到有些困惑。在许多情况下,给每个作业分配自己的特定线程是没有意义的(我们不想创建太多硬件线程
我正在使用以下 Ansible playbook 一次性关闭远程 Ubuntu 主机列表: - hosts: my_hosts become: yes remote_user: my_user
如何更改 Ant 中的当前工作目录? Ant documentation没有 任务,在我看来,最好的做法是不要更改当前工作目录。 但让我们假设我们仍然想这样做——你会如何做到这一点?谢谢! 最佳答案
是否可以运行 cronjob每三天一次?或者也许每月 10 次。 最佳答案 每三天运行一次 - 或更短时间在月底运行一次。 (如果上个月有 31 天,它将连续运行 2 天。) 0 0 */3 * *
如何在 Gradle 任务中执行托管在存储库中的工具? 在我的具体情况下,我正在使用 Gradle 构建一个 Android 应用程序。我添加了一项任务,将一些 protobuf 数据从文本编码为二进
我的项目有下一个结构: Root |- A |- C (depends on A) \- B (depends on A) 对于所有子项目,我们使用自己的插件生成资源:https://githu
我设置了一个具有4个节点的Hadoop群集,其中一个充当HDFS的NameNode以及Yarn主节点。该节点也是最强大的。 现在,我分发了2个文本文件,一个在node01(名称节点)上,一个在node
在 TFS 2010 中为多个用户存储任务的最佳方式是什么?我只能为一项任务分配一个。 (例如:当我计划向所有开发人员演示时) (这是一个 Scrum Msf 敏捷项目,其中任务是用户故事的一部分)
我是一名优秀的程序员,十分优秀!