This article is to use the Linux crontab scheduled tasks to assist in achieving the task scheduling Laravel
First, create a project
1. Open a terminal, execute the command: laravel new crontab
including a database, to ensure that local normal operation. Subsequently deployed on the line. phpstrom
Connect to the server, ensure that the code can be properly submitted to the server.
2, create a task type, terminal execute the command: php artisan make:command SendEmail
3, modify the SendEmail.php
file
protected $signature = 'email:send';
protected $description = '定时发邮件测试';
4, the first e-mail do not panic, first to a timing of writing the test file, write the current time in the file, as follows
public function handle()
{
//写入文件
file_put_contents("/var/www/crontab/file.txt", date('Y-m-d H:i:s') . PHP_EOL, FILE_APPEND);
}
Note: where PHP_EOL
represents the time list wrap, the latter FILE_APPEND
refers back append a record.
5, modify the app/Console/Kernel.php
file:
protected $commands = [
Commands\SendEmail::class //注册任务类
];
protected function schedule(Schedule $schedule)
{
//每分钟执行一次文件的写入
$schedule->command('email:send')
->everyMinute();
}
6, on the server, into the project: cd /var/www/crontab
, first check the server PHP
installation path, execute the command: which php
my PHP
path /usr/bin/php
, and then save the copy down the path, and then execute the command: crontab -e
select Open, select the first four recommendations. In the last line add the following code:
* * * * * /usr/bin/php /var/www/crontab/artisan schedule:run >> /dev/null 2>&1
Note: Here the front part /usr/bin/php
on behalf of the server PHP
installation path, the rear portion of the representative project directory.
Also in front of the command above five asterisk * represent the minutes, hours, days, months, weeks.
Min: integer, default asterisk and the asterisk 0-59 / 1 for 1 minute.
Hours: integer of 0-23.
Day: Integer 1-31.
Month: Integer 1-12.
Week: integer of 0-7, 0 and 7 represent Sunday.
crontab -l to list the current scheduled task.
7, start the task sudo service cron restart
, open FZ
, on view at the root server project file.txt
if there is time to write files and execute every minute. After confirming the successful implementation of the command service cron stop
and exit
exits timed tasks.
Second, to achieve regular mail
The next step is to write the file into operation timed mail. In the .env
information about the files needed to configure the mail.
MAIL_DRIVER=smtp
MAIL_HOST=smtp.qq.com
MAIL_PORT=465
MAIL_USERNAME=244500972@qq.com
MAIL_PASSWORD=***** //填自己的邮箱密码
MAIL_ENCRYPTION=ssl
MAIL_FROM_ADDRESS=244500972@qq.com
MAIL_FROM_NAME=huangdj
1, open web.php
, add routes
$this->any('mail', 'HomeController@mail');//发邮件
2, Home
add the following code controller:
public function mail()
{
//第一种方法
\Mail::raw('定时发送邮件 测试', function ($message) {
$message->from('[email protected]', '长乐未央');
$message->subject('邮件主题 测试');
$message->to('[email protected]');
});
//第二种方法
// \Mail::send('admin.mail', ['name' => 'holy'], function ($message) {
// $message->to('[email protected]');
// });
}
Test: terminal print routing, routing address to get the browser to visit: http://你的二级域名/admin/mail
to see whether the mailbox to receive messages. If successful receipt of the message, continue down. .
3, open the task class SendEmail.php
file, modifying handle
the method, as follows:
public function handle()
{
//写入文件
// file_put_contents("/var/www/crontab/file.txt", date('Y-m-d H:i:s') . PHP_EOL, FILE_APPEND);
\Mail::raw('定时发送邮件 测试', function ($message) {
//查出要发邮件的所有用户的邮箱
$customers = Customer::where('email', '<>', null)->get();
foreach ($customers as $customer) {
$message->from('[email protected]', 'huangdj');
$message->subject('邮件主题 测试');
//执行发送
$message->bcc($customer->email);
}
});
}
Finally, the current project to the server, start the timer command service cron restart
, wait a minute to see if the mail message is received and executed once every minute.
Third, the increase Redis queue
When we want to send a large amount of e-mail, we will use the queue, the message is sent to all the stored queue, so that the back-end to complete the lengthy operation. Lot of information online are using a database queue, here I use redis
the queue.
1, modify .env file QUEUE_DRIVER=sync
is QUEUE_DRIVER=redis
2, launch queue, Terminal execute the command: redis-server
you will find predis
an extended not installed, execute the command: composer require predis/predis
install. After the installation is complete, restart redis.
3, create a task categories: php artisan make:job SendReminderEmail
After a successful run will app/Jobs
generate a directory SendReminderEmail.php
, we modify its contents as follows:
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use App\Customer;
use Illuminate\Contracts\Mail\Mailer;
class SendReminderEmail implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $customer;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct(Customer $customer)
{
$this->customer = $customer;
}
/**
* Execute the job.
*
* @return void
*/
public function handle(Mailer $mailer)
{
$customer = $this->customer;
$mailer->send('emails.reminder',['customer'=>$customer],function($message) use ($customer){
$message->to($customer->email)->subject('新功能发布');
});
}
}
4, create a mail partial viewresources/views/emails/reminder.blade.php
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div>
亲爱的{{$customer->nickname}},您好,长乐教育新发布了Laravel5.6使用redis实现群发邮件功能,立即去体验下吧:
<a href="https://www.whphp.com/">前往长乐教育</a>
</div>
</body>
</html>
Fourth, push queue tasks - manual distribution task
1, web.php
add the following route:
Route::get('mail/sendReminderEmail/{id}','MailController@sendReminderEmail');
2, create the controller: php artisan make:controller MailController
write controller the following code:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Customer;
use Mail;
use Storage;
use App\Jobs\SendReminderEmail;
class MailController extends Controller
{
//发送提醒邮件
public function sendReminderEmail(Request $request, $id)
{
$customer = Customer::findOrFail($id);
$this->dispatch(new SendReminderEmail($customer));
}
}
3, run queue listener. Access in the browser http://你的二级域名/mail/sendReminderEmail/63
, then pushed to the task Redis
queue. Run the following command at the command line: php artisan queue:work
and then go to see the mailbox will receive a reminder e-mail:
4, push task to a specified queue, modification App\Console\Commands\SendEmail
inside handle
method code as follows:
public function handle()
{
\Mail::queue('定时发送邮件 测试', function ($message) {
//查出要发邮件的所有用户的邮箱
$customers = Customer::where('email', '<>', null)->get();
foreach ($customers as $customer) {
$message->from('[email protected]', 'huangdj');
$message->subject('邮件主题 测试');
//执行发送
//$message->bcc($customer->email);
//将任务推送到指定队列并延迟一分钟执行
dispatch(new \App\Jobs\SendReminderEmail($customer->email))->onQueue('emails')->delay(60);
}
});
}
The ultimate test: to see if mail is received an e-mail every minute
start: redis-server
Start: php artisan queue:work
Start regular implementation:service cron restart
references:http://laravelacademy.org/post/2012.html
http://laravelacademy.org/post/222.html#ipt_kb_toc_222_14
Well Done !!!