前期准备工作,开启SMTP服务并获取授权码,以qq邮箱为例
1、登录邮箱,设置-》账户
2开启SMTP服务,获取授权码
配置使用,laravel自带有邮件插件,所以直接配置使用即可
1 .env文件进行如下配置mail_username是邮箱号,maill_password是刚才的授权码
2 config文件夹下的mail.php进行设置,如下图,address和上边的mail_username需要一致
3 编写路由
4 控制器中的使用,引入邮件类,编写方法,如下
use Illuminate\Mail\Mailer;
use Illuminate\Support\Facades\Mail;
class IndexController extends Controller
{
private $mailer;
public function __construct(Mailer $mailer)
{
$this->mailer = $mailer;
}
public function index(Request $request)
{
$email = '1058424094@qq.com';
$title = '测试邮件001';
$content = '测试邮件001';//内容
$tag = $this->mailer->raw($content, function ($message)use($title,$email){
$message->subject($title);
$message->to($email);
});
}
public function sendHtml(){
$data = ['title' => '你若盛开,清风自来','author' => '木心'];
$tag = $this->mailer->send('mail',$data,function ($message){
$message->subject('Hello My Dear,let`s go');
$message->to('244250933@qq.com');
});
return $tag;
}
}
直接访问就可以发送邮件了
遇到的问题,我配置好了却总是不生效,最后发现是配置文件有缓存的原因,于是清理了所有的缓存,就好了,命令如下:
php artisan cache:clear
php artisan view:clear
php artisan config:cache
第二个问题就是有时候邮件发送太慢,会影响网站的体验性,查了下可以用laravel的邮件队列功能避免,如下(下边的都是copy的,理解就好):
邮件队列
队列允许我们延迟耗时任务的处理,例如邮件发送,从而使得 web 请求响应更快。
如何工作
队列实际上很容易理解:
整个过程应该是这样:Web 请求到达处理该请求的控制器,在处理过程中,某些任务被推送到队列(比如邮件发送),然后返回响应。队列会在后台异步执行。
队列驱动
Laravel 为队列提供了的不同实现驱动:
sync
- 当任务被推送到sync队列后会立即执行database
- 数据库队列会将任务存放到数据表中,该表默认是jobs
beanstalkd
- 要实现beanstalkd队列需要先配置并运行beanstalkd,而且还要使用Composer安装依赖包:composer require "pda/pheanstalk=~3.0"
sqs
- 该驱动会将任务推送到Amazon SQS队列,同样需要先使用Composer安装依赖包:composer require aws/aws-sdk-php
iron
- 该驱动会将任务推送到IronMQ,使用前需要安装依赖:composer required "iron-io/iron_mq=~1.5"
redis
- Redis队列会将任务推送到Redis数据库,使用前需要安装redis依赖:composer require "presdis/presis=~1.0"
使用数据库驱动
这里我们使用数据库驱动实现队列。
登录到 Homestead 虚拟机,运行如下迁移命令创建存放队列任务的 jobs
表:
php artisan queue:table
php artisan migrate
然后编辑 .env
文件并修改 QUEUE_DRIVER
的配置值为 database
。
现在队列已经设置好了,接下来我们将邮件发送推送到队列中而不是等待邮件发送完成再返回响应给用户。
修改控制器
要将邮件发送任务推送到队列,只需要在控制器 ContactController
中做如下改动即可:
// 找到这一行
Mail::send('emails.contact', $data, function ($message) use ($data) {
// 然后将其修改为:
Mail::queue('emails.contact', $data, function ($message) use ($data) {
就是这么简单!
邮件在哪
再次测试联系我们表单,点击“Send"之后没有任何延迟就会跳转到成功页面。
但是,如果仅仅这样你就以为完事的话那就错了,你将永远无法接收到邮件。
为什么?
因为后台没有运行对队列进行处理的轮询命令,接下来我们就要来做这件事。
运行 queue:work
要处理队列中的任务,需要手动运行 Artisan 命令:queue:work
。
如果队列为空,这个命令什么也不会做。一旦有任务推送到队列中,该命令会捕获任务并执行它。
queue:work
命令有个缺陷,就是每次有新任务推送到队列后需要手动登录到服务器并运行该命令,任务才会被执行,这显然是不合理的,对此我们可以使用一些自动化解决方案。
一种方式是将 artisan queue:listen
命令加入到服务器启动脚本中,该命令会在新任务推送到队列时自动调用 artisan queue:work
。这种方案的问题是 queue:listen
命令会一直挂在那里,消耗 CPU 资源,而且一旦命令挂掉,新的任务还是无法执行,更好的解决方案是使用 Supervisor 来运行 queue:listen
。
使用 Supervisor 运行 queue:listen
Supervisor 是 *nix 系统上用于监控和管理进程的工具,我们这里不深入探究如何安装这个工具,如果你使用 Homestead 作为本地开发环境,则该工具已经为我们安装好了。
以 Homestead 上预装的 Supervisor 为例,在 /etc/supervisor/conf.d
目录下创建 blog.conf
,并编辑该文件内容如下:
[program:blog-queue-listen]
command=php /home/vagrant/Code/blog/artisan queue:listen
user=vagrant
process_name=%(program_name)s_%(process_num)d
directory=/home/vagrant/Code/blog
stdout_logfile=/home/vagrant/Code/blog/storage/logs/supervisord.log
redirect_stderr=true
numprocs=1
保存该文件后关闭在正在运行的 Supervisor 服务,然后使用如下命令重新启动 Supervisor:
sudo supervisord -c /etc/supervisor/supervisord.conf
使用如下命令可以查看所有正在监听的队列:
sudo supervisorctl status
这样,推送到队列的任务就可以正常被执行了。
使用调度命令
对小的站点而言还有一种方式是使用调度任务每分钟运行一次 queue:work
,或者每五分钟,这可以通过使用 Laravel 5.1 的命令行调度器来完成。
编辑 app/Console/Kernel.php
文件如下:
/ 修改如下这个方法
/**
* Define the application's command schedule.
*
* @param Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
// Run once a minute
$schedule->command('queue:work')->cron('* * * * * *');
}
这将会每分钟运行一次 queue:work
,你还可以通过如下方式修改运行频率:
// 每5分钟运行一次
$schedule->command('queue:work')->everyFiveMinutes();
// 一天运行一次
$schedule->command('queue:work')->daily();
// 每个星期一早上8:15运行
$schedule->command('queue:work')->weeklyOn(1, '8:15');
要查看更多配置详情可查看Laravel任务调度文档。
下一步需要编辑服务器的 crontab
设置调度命令。编辑 crontab
并添加如下这行调度任务:
* * * * * php /path/to/artisan schedule:run 1>> /dev/null 2>&1
注:需要将 /path/to 修改成项目根目录,比如在Homestead上是
/home/vagrant/Code/blog
。
这将会调用 Artisan 运行任何当前调度任务,并将输出发送到空设备。
队列任务
队列的另一个使用场景是异步任务。我们在控制器中使用 $this->dispatch(new JobName)
分发任务,但是这些任务只是被推送到队列,只有当运行 queue:work
或者其它处理队列任务 的操作执行时这些队列任务才会执行。
更多关于队列任务的详情请查看Laravel队列文档。
本地测试邮件可以发送成功,但是部署在阿里云服务器上之后,并且在安全组中配置了25端口的出入后还是不行。
原因是:
阿里云服务器封禁了25
解决办法
端口号port 改成 465
加密方式 encryption 改用 ssl
也就是加入了SSL验证
问题解决