Laravel Queue xử lý công việc kiểu hàng đợi

Hàng đợi cho phép bạn trì hoãn một công việc mất nhiều thời gian đến một thời điểm nào nó mới xử lý. Laravel cung cấp một API thống nhất cho rất nhiều các hàng đợi ở backend khác nhau. Để hiểu nhanh các khái niệm mới chúng ta hãy bắt đầu bằng ví dụ: Bạn hãy tưởng tượng website của bạn có nhiều người vào xem và có thể đăng ký tài khoản, người đó đang ở trang đăng ký và nhập các thông tin vào form đăng ký. Khi đó chúng ta muốn thực hiện các công việc sau:

  • Kiểm tra thông tin nhập và lưu vào CSDL.
  • Gửi một email Chào mừng đến thành viên mới này.
  • Trả về trang Thankyou.

Sau khi kiểm tra và lưu thông tin vào CSDL, tiếp tục đến phần việc gửi email do mã PHP thực hiện tuần tự từ trên xuống. Người dùng sẽ thấy trang Thankyou nếu email đã được gửi đi, quá trình gửi email có thể nhanh nhưng cũng có thể mất thời gian, vậy tại sao phải bắt người dùng chờ? Laravel Queue sẽ là cứu cánh cho tình huống này.

Laravel Queue là gì?

Một hàng đợi (queue) là một danh sách những việc cần làm (job) được quản lý theo thứ tự. Khi chúng ta muốn thêm một công việc (job) vào hàng đợi, job phải implement interface Illuminate\Contracts\Queue\ShouldQueue.

Laravel Queue driver được sử dụng để quản lý các job như thêm job vào hàng đợi, lấy job ra khỏi hàng đợi. Laravel có thể làm việc với nhiều các driver khác nhau như database, Redis, Amazon SQS… và bạn có thể tự tạo riêng một driver nếu muốn. Trong bài viết này, chúng ta sẽ lưu trữ các job trong database, để thực hiện việc này, thực hiện các câu lệnh artisan để tạo ra các bảng lưu trữ trong database như sau:

c:\xampp\htdocs\laravel-test>php artisan queue:table
Migration created successfully!
c:\xampp\htdocs\laravel-test>php artisan queue:failed-table
Migration created successfully!
c:\xampp\htdocs\laravel-test>php artisan migrate
Migrated: 2017_04_03_144759_create_jobs_table
Migrated: 2017_04_03_150557_create_failed_jobs_table

Các câu lệnh này sẽ tạo ra bảng jobs và failed_jobs trong cơ sở dữ liệu. Ngoài ra, cần phải thiết lập

QUEUE_DRIVER=database

trong file cấu hình biến môi trường .env ở thư mục gốc project.

Tạo và thêm Job vào queue

Mặc định, các job được lưu trong app\Jobs, nếu thư mục app\Jobs không có trong project bạn cũng đừng lo, câu lệnh tạo job sẽ tự động tạo ra thư mục này nếu chưa có. Thực hiện tạo một job mới bằng câu lệnh:

php artisan make:job SendWelcomeEmail

Nó sẽ tự động sinh ra job SendWelcomeEmail được implement interface Illuminate\Contracts\Queue\ShouldQueue. Class này chứa phương thức handle() sẽ được gọi đến khi job được xử lý trong hàng đợi. Chúng ta hãy xem khung của một job:

<?php

namespace App\Jobs;

use App\User;
use App\AudioProcessor;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;

class SendWelcome Email implements ShouldQueue
{
    use InteractsWithQueue, Queueable, SerializesModels;

    protected $user;

    /**
     * Create a new job instance.
     *
     * @param  User  $user
     * @return void
     */
    public function __construct(User $user)
    {
        $this->user = $user;
    }

    /**
     * Execute the job.
     *
     * @param  AudioProcessor  $processor
     * @return void
     */
    public function handle(AudioProcessor $processor)
    {
        // Process uploaded user...
    }
}

Trong ví dụ trên chúng ta truyền một Eloquent Model User vào phương thức contruct của job. Để thêm job vào một queue, sử dụng phương thức dispatch():

<?php
namespace App\Http\Controllers\Auth;
use App\User;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Validator;
use Illuminate\Foundation\Auth\RegistersUsers;
use App\Jobs\SendWelcomeEmail;
class RegisterController extends Controller
{
    ...
    protected function create(array $data)
    {
        $user = User::create([
            'name' => $data['name'],
            'email' => $data['email'],
            'password' => bcrypt($data['password']),
        ]);
        $job = (new SendWelcomeEmail($user))->delay(Carbon::now()->addMinutes(10));
        dispatch($job);
        return $user;
    }
}

Phương thức delay() sẽ dừng lại trước khi thực hiện job trong queue.

Thực thi các jobs trong queue

Số lần thử thực hiện job

Mặc định job sẽ được thực hiện 1 lần, nếu lỗi sẽ được bỏ qua, để thiết lập số lần thử thực hiện lại một job chúng ta có hai cách: hoặc sử dụng câu lệnh artisan cho tất cả các job

php artisan queue:work --tries=3

hoặc đưa vào thuộc tính $tries của từng job

<?php
namespace App\Jobs;

class SendWelcome implements ShouldQueue
{
    /**
     * Số lần job sẽ thử thực hiện lại
     *
     * @var int
     */
    public $tries = 3;
}

Thiết lập thời gian timeout của job trong queue

Bạn có thể thiết lập thời gian timeout của các job bằng cách sử dụng câu lệnh artisan

php artisan queue:work --timeout=60

hoặc thiết lập trong thuộc tính $timeout của từng job

<?php
namespace App\Jobs;

class SendWelcome implements ShouldQueue
{
    /**
     * Số giây job có thể chạy trước khi timeout
     *
     * @var int
     */
    public $timeout = 60;
}

Queue worker, thực thi các job trong queue

Laravel có một queue worker để thực thi các job đang có trong hàng đợi, bạn có thể chạy worker này bằng câu lệnh artisan:

php artisan queue:work

Chú ý, câu lệnh này khi đã thực hiện sẽ chạy cho đến khi đóng cửa sổ dòng lệnh hoặc dừng nó bằng một câu lệnh. Queue worker là các tiến trình có thời gian sống dài do đó nó sẽ không cập nhật code khi có thay đổi, khi bạn thay đổi code chương trình, bạn cần khởi động lại queue worker bằng câu lệnh

php artisan queue:restart

Thiết lập thời gian nghỉ giữa các lần xử lý job

Các job trong hàng đợi được xử lý liên tục mà không có sự dừng lại nào, tùy chọn sleep sẽ xác định worker dừng lại sau bao lâu trước khi tiếp tục xử lý job tiếp theo:

php artisan queue:work --sleep=3

Sử dụng Supervisor giám sát xử lý hàng đợi trên Linux

Supervisor là một chương trình giám sát các xử lý trong hệ điều hành Linux, nó sẽ tự động khởi động lại xử lý queue:work nếu bị lỗi. Để cài đặt supervisor trên CentOS trước hết phải cài đặt python

$ yum install python-setuptools
$ easy_install supervisor

Cài đặt supervisor trên Ubuntu

#sudo apt-get install supervisor

Supervisor có file cấu hình nằm trong thư mục /etc/supervisor/conf.d, trong này bạn có thể tạo nhiều file để bắt supervisor giám sát các xử lý. Ví dụ tạo file laravelworker.conf để giám sát cho queue:worker với nội dung:

[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /home/forge/app.com/artisan queue:work sqs --sleep=3 --tries=3
autostart=true
autorestart=true
user=forge
numprocs=8
redirect_stderr=true
stdout_logfile=/home/forge/app.com/worker.log

numprocs = 8 tức là Supervisor sẽ chạy 8 xử lý queue:work cùng lúc và tự động khởi động lại queue:work khi gặp lỗi. Sau khi thiết lập cấu hình Supervisor xong, bạn phải cập nhật cấu hình và chạy các xử lý bằng các câu lệnh như sau:

$supervisorctl reread
$supervisorctl update
$supervisorctl start laravel-worker:*

Giám sát xử lý hàng đợi trên Windows

Công cụ supervisor chỉ hoạt động trong môi trường Linux, vậy trên Windows chúng ta sẽ xử lý như thế nào. Chúng ta sẽ sử dụng gói Forever, cài đặt Forever bằng npm. npm được tích hợp sẵn trong bộ cài Node.js, bạn tải về và cài đặt.

Sau đó cài đặt Forever:

npm install -g forever

Sau khi cài đặt Forever, chúng ta có thể dùng nó để giám sát các xử lý

forever -c php artisan --queue:work --tries=3 --timeout=60 --sleep=5

Laravel Queue trong bài toán xử lý song song

Trong lập trình, hàng đợi giúp cho việc thiết kế các ứng dụng tốt hơn trong hiệu năng xử lý. Chúng ta đến với ví dụ thực tế sau, trong hệ thống corebanking của ngân hàng, cuối ngày sẽ thực hiện chạy khóa ngày COB (Close Of Bussiness), quá trình này là một tập hợp (các batch) rất nhiều các tác vụ khác nhau như cập nhật thông tin hệ thống, tính toán lãi tiền gửi, tiền vay, chuyển trạng thái các hợp đồng, gửi tin nhắn đến khách hàng và cập nhật thông tin các bảng cần thiết cho ngày mới như bảng lãi suất, tỉ giá… Nếu tất cả các công việc này được thực hiện tuần tự, quá trình COB sẽ mất rất nhiều thời gian mà hệ thống corebanking chỉ được phép chạy trong khoảng 3-5 tiếng do cần phải có thời gian dự phòng. Vậy giải pháp nào cho những vấn đề tương tự như vậy?

Sử dụng hàng đợi sẽ giúp xử lý những vấn đề như trên. Chúng ta sẽ chia các công việc ra thành các Batch, trong mỗi Batch chứa các job khác nhau liên quan đến một bussiness logic nào đó. Khi đó, chúng ta thực hiện chạy nhiều queue:work sẽ giúp tăng tốc độ lên đáng kể. Trong ví dụ về sử dụng Supervisor, giả sử cấu hình máy chủ có thể chạy được 30 session một lúc, nếu chúng ta để

numprocs=30

tốc độ xử lý sẽ nhanh hơn rất nhiều lần. Laravel Queue rất thích hợp cho các bài toán xử lý nhiều việc song song. Do khuôn khổ bài viết, chúng tôi không đi sâu vào một ví dụ cụ thể, tuy nhiên sẽ có một bài viết riêng ở đó chúng ta sẽ quay lại việc kiểm tra xem giữa single queue và multiple queues khác biệt như thế nào nếu chúng ta thiết kế ứng dụng tốt.

Ví dụ gửi email khi đăng ký người dùng sử dụng Laravel Queue

Ok, chúng ta quay trở lại với ví dụ như ở đầu bài viết đã nêu, trong quá trình đăng ký thành viên, việc gửi mail chào mừng thành viên mới sẽ được tách ra thành một job để đưa vào hàng đợi, giúp cho người dùng không phải chờ đợi việc gửi email hoàn thành. Chúng ta cũng sẽ sử dụng sleep() để làm chậm quá trình gửi email cỡ 5 phút để giả lập trường hợp gửi email rất lâu. Trong ví dụ này, chúng ta thực hiện lại từng bước từ đầu, do đó nếu có bước nào các bạn đã thực hiện ở trên rồi không cần thực hiện lại.

Chú ý:

Bước 1: Thêm các bảng sử dụng cho Laravel Queue

c:\xampp\htdocs\laravel-test>php artisan queue:table
Migration created successfully!
c:\xampp\htdocs\laravel-test>php artisan queue:failed-table
Migration created successfully!
c:\xampp\htdocs\laravel-test>php artisan migrate
Migrated: 2017_04_03_144759_create_jobs_table
Migrated: 2017_04_03_150557_create_failed_jobs_table

Hai bảng được tạo ra là jobs và failed_jobs để quản lý các job trong hàng đợi.

Bước 2: Cập nhật cấu hình cho .env

Các cấu hình bao gồm, cấu hình cho queue và email.

QUEUE_DRIVER=database

MAIL_DRIVER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=allaravel.com@gmail.com
MAIL_PASSWORD=nexnaodkvvonmkod
MAIL_ENCRYPTION=tls

MAIL_PASSWORD của Gmail sử dụng là app password, để tạo app password cho tài khoản Google chúng ta vào My Account

Bước 1, vào My account trong Google

My Account chứa các thiết lập về tài khoản, trong đó có phần thiết lập bảo mật cho tài khoản

Bước 2 chọn sign in and security

Trước khi tạo app password chúng ta cần bật chế độ xác thực 2 bước trong Google.

Bước 3, chế độ xác thực 2 lần đang tắt

Click vào 2-Step Verification, cửa sổ giới thiệu xác thực 2 bước là gì xuất hiện.

Giới thiệu về xác thực 2 bước trong Google

Click vào Get Started để bắt đầu thiết lập xác thực 2 bước.

Nhập số điện thoại và sử dụng chế độ SMS để xác thực 2 bước

Một tin nhắn từ Google sẽ được gửi đến số điện thoại của bạn, lấy mã xác thực này nhập vào màn hình tiếp theo.

Nhận tin nhắn chứa verify code từ Google

Như vậy đã xong thiết lập xác thực 2 bước, click vào Turn On để xác nhận bật chế độ này.

Bật chế độ xác thực 2 bước

Ok, tiếp theo chúng ta quay lại Sign In and Security -> Signing in to Google để tạo app password

Chọn menu tạo app password

Chọn lại ứng dụng để tạo app password và click vào Generate.

Chọn loại ứng dụng để tạo app password

Phần mã trong khung màu vàng chính mà app password, bạn copy và đưa vào EMAIL_PASSWORD trong file .env, trong hình ảnh tôi đã cắt bớt các thông tin để đảm bảo tính bảo mật.

app password được tạo

Bước 3: Tạo mẫu email và các khởi tạo mail

Laravel hỗ trợ tạo email class bằng lệnh artisan

php artisan make:mail WelcomeEmail

Câu lệnh này sẽ tạo ra class WelcomeEmail trong app\Mail. Chúng ta sẽ thay đổi class này, thêm $user vào phương thức contruct() để truyền người dùng vừa đăng ký vào phần xây dựng nội dung email.

protected $user;
public function __construct($user){
    //
    $this->user = $user;
}

Tiếp theo sửa phương thức build() để gán giao diện email vào.

public function build()
{
    return $this->view('email.welcome')->with('user', $user);
}

Tiếp đến chúng ta tạo view cho email, tạo một thư mục trong resources/views là email chuyên lưu trữ các view về email. Tạo view welcome.blade.php trong thư mục vừa tạo (resources/views/email/welcome.blade.php) với nội dung như sau:

<!DOCTYPE html>
<html>
<head>
	<title>Welcome to All Laravel</title>
</head>
<body>
	<h1>Chào mừng {{ $user->name }} đến với Allaravel.com</h1>
	<p>All Laravel là website chứa đựng rất nhiều các kiến thức, tài nguyên liên quan đến framework PHP số 1 hiện nay - Laravel. Đến với All Laravel, bạn được tham gia nhiều khóa học miễn phí với rất nhiều các ví dụ thực tế, giúp bạn nhanh chóng nắm bắt được kiến thức.</p>
	<p>Link đăng nhập hệ thống: <a href="http://laravel.dev/login">Đăng nhập All Laravel</a></p>
</body>
</html>

Bước 4: Tạo job SendWelcomeEmail

php artisan make:job SendWelcomeEmail

Câu lệnh này sẽ tạo ra một job SendWelcomeEmail trong thư mục app\Jobs, điều chỉnh lại nội dung của class này như sau:

<?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 Mail;
use App\Mail\WelcomeEmail;

class SendWelcomeEmail implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $user;
    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct($user)
    {
        $this->user = $user;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        sleep(60);

        echo 'Start send email';
        $email = new WelcomeEmail($this->user);
        Mail::to($this->user->email)->send($email);

        echo 'End send email';
    }
}

Bước 5: Đưa job vào hàng đợi khi đăng ký thành viên

Controller RegisterController.php trong app\Http\Controllers\Auth xử lý việc đăng ký thành viên, thêm phương thức register() để ghi đè phương thức register() cha trong trail RegistersUser

   /**
    * Handle a registration request for the application.
    *
    * @param \Illuminate\Http\Request $request
    * @return \Illuminate\Http\Response
    */
    public function register(Request $request)
    {
        $this->validator($request->all())->validate();
        event(new Registered($user = $this->create($request->all())));
        $this->guard()->login($user);
        dispatch(new SendWelcomeEmail($user));

        //return $this->registered($request, $user)?: redirect($this->redirectPath());
        return view('auth.welcome');
    }

Tiếp theo chúng ta tạo view welcome.blade.php trong resources/views/auth

@extends('layouts.default')

@section('title', 'Welcome Allaravel.com')

@section('content')
    Chúc mừng bạn đã đăng ký thành công
@endsection

Bước 6: Chạy queue:work thực thi các job

Mỗi khi người dùng đăng ký mới, một job sẽ được đẩy vào hàng đợi, tiếp theo chúng ta chạy queue:work để lắng nghe nếu có job nào thì thực hiện luôn.

php artisan queue:work

Ok, vậy là chúng ta đã hoàn thành xong việc viết code cho ví dụ, bây giờ chúng ta sẽ kiểm thử xem ứng dụng chạy như thế nào:

Vào đường dẫn http://laravel.dev/register và nhập các thông tin đăng ký.

Màn hình đăng ký thành viên

Sau khi click vào Đăng ký, ngay lập tức tài khoản người dùng được tạo và người dùng được chuyển hướng đến view auth/welcome

Màn hình thông báo đăng ký thành công

Chúng ta thấy mặc dù trong job gửi email chúng ta đã delay 60 giây, nhưng khi đăng ký người dùng không phải chờ 60 giây này. Kiểm tra bảng jobs trong CSDL laravel-test chúng ta thấy xuất hiện bản ghi thông tin về job gửi email đang thực hiện.

Job gửi email xuất hiện trong bảng jobs

Quay lại màn hình queue:work chờ sau 60 giây, chúng ta thấy nó sẽ thực hiện job gửi email một cách tự động.

Màn hình queue:work tự động thực hiện job gửi email

Kiểm tra lại bảng jobs thì bản ghi job gửi email đã được delete sau khi thực hiện xong. Bây giờ chúng ta kiểm tra email dùng để đăng ký thành viên xem nhận được email không nhé.

Email nhận được từ hệ thống

Ok, vậy là chúng ta đã thực hành xong ví dụ của mình. Chúc các bạn thực hiện thành công, có bất kỳ câu hỏi nào, các bạn comment ở cuối bài nhé.

23 thoughts on “Laravel Queue xử lý công việc kiểu hàng đợi

    1. Ví dụ trong các bài viết là mình đã sắp xếp theo thứ tự, có thể bạn chưa thực hành phần Laravel Authentication, bạn có thể kiểm tra bằng cách xem route này đã có trong danh sách các route chưa bằng lệnh: php artisan routes (với laravel 4.x) hoặc php artisan route:list với Lararavel 5.x, nếu chưa có chắc chắn bạn chưa cài đặt phần xác thực trong Laravel.

  1. sau khi nhấn nút đăng ký em nhận đc lỗi
    ReflectionException
    Class App\Http\Controllers\Auth\Request does not exist
    in RouteSignatureParameters.php (line 25)
    ….

    1. Lỗi này có thể do bạn sử dụng namespace chưa đúng, thử khai báo namespace cho class Request như sau:
      use Illuminate\Http\Request;
      trong RegisterController. Nếu chưa hết lỗi, bạn paste đầy đủ code của app\Http\Controllers\Auth\RegisterController.php vào đây để mọi người cùng debug nhé.

    2. sau khi thêm use Illuminate\Http\Request; e nhận đc lỗi Class ‘App\Http\Controllers\Auth\Registered’ not found
      đây là file registercontroller của e
      middleware(‘guest’);
      }

      /**
      * Get a validator for an incoming registration request.
      *
      * @param array $data
      * @return \Illuminate\Contracts\Validation\Validator
      */
      protected function validator(array $data)
      {
      return Validator::make($data, [
      ‘name’ => ‘required|max:255′,
      ’email’ => ‘required|email|max:255|unique:users’,
      ‘password’ => ‘required|min:6|confirmed’,
      ]);
      }

      /**
      * Create a new user instance after a valid registration.
      *
      * @param array $data
      * @return User
      */
      protected function create(array $data)
      {
      return User::create([
      ‘name’ => $data[‘name’],
      ’email’ => $data[’email’],
      ‘password’ => bcrypt($data[‘password’]),
      ]);
      }

      /**
      * Handle a registration request for the application.
      *
      * @param \Illuminate\Http\Request $request
      * @return \Illuminate\Http\Response
      */
      public function register(Request $request)
      {
      $this->validator($request->all())->validate();
      event(new Registered($user = $this->create($request->all())));
      $this->guard()->login($user);
      dispatch(new SendWelcomeEmail($user));

      //return $this->registered($request, $user)?: redirect($this->redirectPath());
      return view(‘auth.welcome’);
      }
      }

  2. Chào anh,

    Em bị lỗi: nó vẫn gửi được email (vẫn chậm như khi không dùng queue).

    Và nó cũng ko hiện trên màn hình dòng: `Start send emailEnd send email[2017-08-27 15:33:48] Processed: App\Jobs\SendWelcomeEmail` khi đánh dòng `php artisan queue:work` trên console.

    Và cũng ko có dòng nào được add vào database `Jobs`.

    Của em khác là biến `$content` là get từ form.

    Anh có thể vào câu hỏi của em trên Stackoverflow được không ạ?

    Em định soạn lại nội dung tiếng việt nhưng blog ko highlight code nên khó đọc.

    Nếu anh ko hiểu ý em trên Stackoverflow thì comment lại, em gửi mail cho anh bản tiếng việt.

    Cảm ơn anh.

    https://stackoverflow.com/questions/45897650/getting-error-maximum-execution-time-when-send-mail-queue-in-laravel/45897948?noredirect=1#comment78755473_45897948

    1. Anh đọc có 1 bạn comment trên đó. Nói là tắt dòng `sleep(60)` đi.

      Em tắt đi thì nó chạy được nhưng tốc độ gửi mail vẫn chậm như hồi em gửi thường.

      Em có ghi rõ từng bước em làm dựa vào hướng dẫn của anh.

      1. Chào bạn, mình đưa sleep(60) mục đích để công việc này sẽ thực hiện rất chậm trong hơn 60s để demo thôi, ví dụ việc xử lý đơn hàng cho khách mất 60s chẳng hạn, trong thực tế bạn phải bỏ nó đi :). Về vụ lỗi chắc thời gian tới mình sẽ đưa source code và video hướng dẫn lên. Hiện team đang triển khai một số dự án khá bận, hẹn gặp lại trong đầu tháng 9.

    2. Bạn để ý phương thức dispatch trong bước 5 dùng để đăng ký sự kiện trong queue, có thể bạn đã điều chỉnh code?

      1. Chào anh,

        Em chỉ sửa lại theo ngữ cảnh của em là lấy dữ liệu từ form người dùng nhập vào.

        Anh có thể xem function `storeCustomer()` dùng để lưu thông tin người dùng nhập và gửi mail cho họ.

        public function storeCustomer(Request $request) {

        //Lưu thông tin form nhập vào database.
        Customer::create($request->all());

        $content = [
        ‘hoten’=> $request->input(‘hoten’),
        ‘tieude’=> $request->input(‘tieude’),
        ’email’=> $request->input(’email’),
        ‘sdt’ => $request->input(‘sdt’),
        ‘loinhan’ => $request->input(‘loinhan’)
        ];

        dispatch(new SendWelcomeEmail($content));

        return view(‘partials.success-mail’);
        }

        Anh vào link này cho dễ đọc, highlight code: https://pastebin.com/7XduBxfG

  3. Khi mình tạo 17 bảng migration, mình gõ lệnh cmd: php artisan migrate thì chỉ tạo được 14 bảng trên localhost. Lỗi: [Illuminate\Database\QueryException]
    SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that
    corresponds to your MySQL server version for the right syntax to use near ‘) default character set utf8mb4 collate
    utf8mb4_unicode_ci’ at line 1 (SQL: create table `CTHoaDon` () default character set utf8mb4 collate utf8mb4_unico
    de_ci)

    [PDOException]
    SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that
    corresponds to your MySQL server version for the right syntax to use near ‘) default character set utf8mb4 collate
    utf8mb4_unicode_ci’ at line 1

    Mình phải fix lỗi như thế nào ạ?

  4. Trương Chí Nhân

    - Edit

    Reply

    Chào bạn. Laravel có hỗ trợ dùng RabitMQ để dùng queue ko nhỉ. Bạn có bài hướng dẫn nào về laravel + rabitMQ ko nhỉ

    1. Your comment is awaiting moderation.

      bạn dùng package nhé. Laravel hỗ trợ bạn add một driver vào. Sử dụng rabbitmq nó tiện hơn. Nó chiếm 40% ram. Lên chay vù vù. Với lại khi bài toán nếu sử xử bắn data liên tục xong save tạm queue vào database. Nó tù cực luôn ý. Châm ơi là chậm. Ở đây mình đã dùng rabbitmq hoặc beanstalkd để hộ chờ multi thread. Nó tăng performance đáng kể luôn.
      http://kr.github.io/beanstalkd/download.html
      Dùng rabbitmq thì dùng em này nhé. https://github.com/vyuldashev/laravel-queue-rabbitmq Khá ổn
      =>> Theo dõi fanpage everyday coding: https://www.facebook.com/Everydaycoding24h/ để mình hỗ trơ nhiều hơn nhé

  5. Ad oi!
    Khi e chạy trên hosting, không sử dụng được lệnh php artisan queue:work bằng cmd.
    Vậy phải làm ntn để nó chạy queue:work ạ?
    Cảm ơn ad nhiều

Add Comment