Câu hỏi Làm thế nào để giữ cho hệ thống xếp hàng Laravel chạy trên máy chủ


Gần đây tôi đã thiết lập một hệ thống xếp hàng Laravel. Những điều cơ bản là một cronjob gọi một lệnh thêm công việc vào hàng đợi và gọi lệnh thứ hai gửi một email.

Hệ thống hoạt động khi tôi ssh vào máy chủ của tôi và chạy hàng đợi php artisan: nghe, nhưng nếu tôi đóng terminal thì listener sẽ tắt và các job sẽ được xếp và đợi trong hàng đợi cho đến khi tôi quay trở lại và chạy lại.

Cách tốt nhất để giữ cho hệ thống xếp hàng của tôi chạy trong nền mà không cần phải giữ kết nối của tôi mở thông qua ssh là gì?

Tôi đã thử chạy php artisan queue:work --daemonvà nó đã hoàn thành các công việc trong hàng đợi, nhưng khi tôi đóng terminal, nó đóng kết nối và tiến trình nền.


19
2018-02-20 06:37


gốc




Các câu trả lời:


Đang chạy

nohup php artisan queue:work --daemon &

Sẽ ngăn lệnh thoát ra khi bạn đăng xuất.

Dấu và dấu (&) làm cho quá trình bắt đầu ở chế độ nền, vì vậy bạn có thể tiếp tục sử dụng trình bao và không phải đợi cho đến khi tập lệnh kết thúc.

Xem nohup 

nohup - chạy một lệnh miễn dịch với các lần gác máy, với đầu ra không phải là tty

Điều này sẽ xuất thông tin vào một tập tin có tên nohup.out trong thư mục nơi bạn chạy lệnh. Nếu bạn không quan tâm đến đầu ra, bạn có thể chuyển hướng stdout và stderr đến / dev / null, hoặc tương tự như vậy bạn có thể xuất nó vào nhật ký laravel bình thường của bạn. Ví dụ

nohup php artisan queue:work --daemon > /dev/null 2>&1 &

nohup php artisan queue:work --daemon > app/storage/logs/laravel.log &

Nhưng bạn cũng nên sử dụng một cái gì đó như Giám sát để đảm bảo rằng dịch vụ vẫn chạy và được khởi động lại sau khi sự cố / lỗi.


38
2018-02-20 09:44



Ahah tuyệt vời! Tôi nghĩ rằng đây sẽ là câu trả lời được chấp nhận! Tôi sẽ sớm có thể kiểm tra. Cảm ơn bạn. - zeros-and-ones
AWesome .. điều này đã làm cho ngày của tôi - sumit
Đầu tiên tôi cần: stackoverflow.com/a/29292637/470749 Sau đó nohup php artisan queue:work --daemon > storage/logs/laravel.log & đã làm cho tôi. Lưu ý: nếu bạn muốn tiêu diệt daemon nohup, trước tiên bạn cần khám phá PID của nó bằng cách chạy một cái gì đó như ps -ef |grep artisan. Sau đó, bạn có thể chạy kill [pid]  stackoverflow.com/q/17385794/470749 - Ryan
Đây là một giải pháp kém vì một khi bạn phát hành hàng đợi: reset nhân viên chết và bạn không có cơ chế khởi động lại, chỉ cần sử dụng supervisord, sinh ra 2 công nhân và bạn sẽ tốt như vàng khi bạn có khối lượng lớn. Là một lưu ý phụ, bạn sẽ cần phải hồi sinh nhân viên mới mỗi khi bạn thực hiện thay đổi mã. - z900collector
@ z900collector Câu trả lời một cách rõ ràng nói rằng bạn nên sử dụng một cái gì đó như Giám sát và luôn luôn đã làm. - Ben Swinburne


Bạn nên sử dụng linux người giám sát 

Cài đặt đơn giản và trên Ubuntu tôi có thể cài đặt nó bằng lệnh sau:

apt-get install supervisor

Các tệp cấu hình giám sát nằm trong thư mục /etc/supervisor/conf.d.

[program:email-queue]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/laravel-example/artisan queue:work redis --queue=emailqueue --sleep=3 --tries=3
autostart=true
autorestart=true
user=forge
numprocs=2
redirect_stderr=true
stdout_logfile=/var/www/laravel-example//storage/logs/supervisord.log

Đối với mỗi quá trình, bạn nên tạo một tệp cấu hình quy trình mới. Với cấu hình này, người nghe sẽ thử lại mỗi công việc 3 lần. Ngoài ra, Giám sát sẽ khởi động lại trình nghe nếu nó không thành công hoặc nếu hệ thống khởi động lại.


7
2018-06-12 14:15



có thêm hướng dẫn ở đây, digitalocean.com/community/tutorials/… - namal
Xin chào, bạn có thể giúp đỡ với vấn đề của tôi không? Tôi đang sử dụng giám sát và công việc đã được thực hiện, nhưng không thể tạo một tệp stackoverflow.com/questions/47715537/… - Irfandi D. Vendy
Đáng chú ý là câu trả lời này cũng là cách làm việc của Laravel: laravel.com/docs/5.6/queues#supervisor-configuration - Martin Joiner


Lệnh

nohup php artisan queue:work --daemon &

là chính xác, nó sẽ cho phép quá trình tiếp tục sau khi đóng kết nối SSH; tuy nhiên, đây chỉ là một phiên bản ngắn hạn. Khi máy chủ của bạn được khởi động lại hoặc bất kỳ vấn đề nào khiến quá trình dừng lại, bạn sẽ cần phải quay lại và chạy lại lệnh. Khi điều đó xảy ra, bạn không bao giờ biết. Nó có thể xảy ra vào tối thứ Sáu, vì vậy tốt hơn là nên thực hiện một giải pháp dài hạn.

Tôi đã chuyển sang giám sát, điều này có thể được cài đặt trên Ubuntu dễ dàng như

sudo apt-get install supervisor 

Đối với người dùng AWS-AMI hoặc RedHat, bạn có thể thực hiện theo các hướng dẫn mà tôi đã nêu trong câu hỏi này:

Thiết lập giám sát trên máy chủ AWS AMI Linux


5
2017-12-15 18:22



Xin chào, bạn có thể giúp đỡ với vấn đề của tôi không? Tôi đang sử dụng giám sát và công việc đã được thực hiện, nhưng không thể tạo một tệp stackoverflow.com/questions/47715537/… - Irfandi D. Vendy
Vậy tại sao bạn không chấp nhận câu trả lời mà người giám sát được đề xuất? - dewwwald
Câu trả lời đó chỉ áp dụng cho người dùng Ubuntu, câu trả lời của tôi liên kết đến một câu hỏi riêng biệt với cách thiết lập nó trên các bản phân phối dựa trên RedHat. Ngoài ra, tôi đã trả lời Dev 15 năm 2016, câu trả lời khác chỉ dành riêng cho người dùng Ubuntu vào tháng 6 năm 2017. - zeros-and-ones


Nếu bạn bắt đầu nghe trong màn hình thì sao? Xem ở đây: http://aperiodic.net/screen/quick_reference Sau đó, ngay cả khi bạn đăng xuất, màn hình sẽ vẫn hoạt động và đang chạy. Không chắc chắn tại sao các daemonization không hoạt động mặc dù.


2
2018-02-20 09:43





Đối với những người đang chạy NodeJS trên môi trường sản xuất của họ. Tôi sử dụng PM2 để quản lý quá trình ứng dụng.

# install
npm install -g pm2

# in project dir with your CI or dev setup tool 
# --name gives task a name so that you can later manage it
# -- delimits arguments that get passed to the script
pm2 start artisan --interpreter php --name queue-worker -- queue:work --daemon

Tôi sử dụng Vagrant trong việc phát triển và thiết lập NodeJS và quá trình này chỉ sử dụng các tập lệnh vagrant nội tuyến.

Khi bạn sử dụng PM2 trong phát triển, bạn có thể sử dụng một trong nhiều người theo dõi để quản lý việc khởi động lại. Chỉ cần chạy pm2 restart queue-worker khi bạn nhận một sự thay đổi. Trong sản xuất, tôi không khuyên bạn nên phương pháp này, thay vì lựa chọn không cho một công cụ xây dựng có thể làm theo quá trình này.

# 1. stop pm task to ensure that no unexpected behaviour occurs during build
pm2 stop queue-worker
# 2. do your build tasks
...
# 3. restart queue so that it loads the new code
pm2 restart queue-worker

2
2018-01-09 02:43





Từ https://gist.github.com/ivanvermeyen/b72061c5d70c61e86875

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

class EnsureQueueListenerIsRunning extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'queue:checkup';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Ensure that the queue listener is running.';

    /**
     * Create a new command instance.
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return void
     */
    public function handle()
    {
        if ( ! $this->isQueueListenerRunning()) {
            $this->comment('Queue listener is being started.');
            $pid = $this->startQueueListener();
            $this->saveQueueListenerPID($pid);
        }

        $this->comment('Queue listener is running.');
    }

    /**
     * Check if the queue listener is running.
     *
     * @return bool
     */
    private function isQueueListenerRunning()
    {
        if ( ! $pid = $this->getLastQueueListenerPID()) {
            return false;
        }

        $process = exec("ps -p $pid -opid=,cmd=");
        $processIsQueueListener = str_contains($process, 'queue:listen');

        return $processIsQueueListener;
    }

    /**
     * Get any existing queue listener PID.
     *
     * @return bool|string
     */
    private function getLastQueueListenerPID()
    {
        if ( ! file_exists(__DIR__ . '/queue.pid')) {
            return false;
        }

        return file_get_contents(__DIR__ . '/queue.pid');
    }

    /**
     * Save the queue listener PID to a file.
     *
     * @param $pid
     *
     * @return void
     */
    private function saveQueueListenerPID($pid)
    {
        file_put_contents(__DIR__ . '/queue.pid', $pid);
    }

    /**
     * Start the queue listener.
     *
     * @return int
     */
    private function startQueueListener()
    {
        $command = 'php-cli ' . base_path() . '/artisan queue:listen --timeout=60 --sleep=5 --tries=3 > /dev/null & echo $!';
        $pid = exec($command);

        return $pid;
    }
}

1
2017-08-09 05:43



Cảm ơn bạn đã chia sẻ, đó là cách duy nhất để đảm bảo hàng đợi đang chạy! Tốt đẹp bởi vì yêu cầu cài đặt không có phụ thuộc mới, chỉ cần một xử lý trên CRONTAB. Bất kỳ cài đặt quyền nào đều có? - zeros-and-ones
Không có vấn đề về quyền. Chỉ cần cẩn thận với các phiên bản và đường dẫn php, đôi khi chúng khác với trình bao. alse exec () thường bị tắt trên shared hosting .. - Harry Bosh


Vì đây là một câu hỏi cụ thể của Laravel, tôi nghĩ tôi sẽ gợi ý một câu trả lời cụ thể cho Lravel. Vì bạn đã sử dụng cronjobs trên máy chủ này, tôi khuyên bạn nên thiết lập lệnh shell làm cronjob định kỳ để luôn xác minh rằng nhân viên đang chạy. Bạn có thể thiết lập lệnh shell để chạy nguyên gốc thông qua cron trên máy chủ của bạn, hoặc bạn có thể sử dụng hạt nhân của giao diện điều khiển Laravel để quản lý lệnh và thêm logic, chẳng hạn như kiểm tra xem bạn đã có một nhân viên đang chạy hay chưa. và khởi động lại.

Tùy thuộc vào mức độ thường xuyên bạn cần để chạy lệnh của bạn, bạn có thể làm điều này không thường xuyên như một lần một tuần, hoặc thậm chí một lần một phút. Điều này sẽ cung cấp cho bạn khả năng đảm bảo rằng các nhân viên của bạn liên tục chạy, mà không phải thêm bất kỳ chi phí nào vào máy chủ của bạn, chẳng hạn như Giám sát viên. Việc cấp quyền cho gói bên thứ ba như người giám sát là ok nếu bạn tin tưởng, nhưng nếu bạn có thể tránh phải dựa vào nó, bạn có thể muốn xem xét phương pháp này thay thế.

Một ví dụ về việc sử dụng điều này để làm những gì bạn muốn sẽ có một cronjob chạy mỗi giờ. Nó sẽ thực hiện những điều sau theo thứ tự tuần tự từ bên trong một lệnh giao diện điều khiển Laravel tùy chỉnh:

\ Artisan :: call ('queue: restart');

\ Artisan :: call ('queue: work --daemon');

Lưu ý rằng điều này áp dụng cho các phiên bản cũ của Laravel (lên đến 5.3) nhưng tôi chưa thử nghiệm trên các phiên bản mới hơn.


1
2017-08-20 16:07



Mặc dù đây là một lựa chọn và sẽ làm việc, trong trường hợp xấu nhất này sẽ dẫn đến một giờ thời gian chết cho các nhiệm vụ xếp hàng đợi. Ngoài ra, điều này có vẻ như nó sẽ tạo ra một quá trình mới mỗi khi cron chạy, nếu như vậy cuối cùng bạn sẽ hết bộ nhớ. - zeros-and-ones
Một giờ của thời gian chết? Tôi chỉ có nghĩa là hai lệnh thủ công nên được chạy theo thứ tự tuần tự trong cronjob, không cách nhau một giờ. Tôi sẽ cập nhật câu trả lời gốc để phản ánh điều này. Điều này sẽ không gây ra một vấn đề bộ nhớ kể từ khi lệnh khởi động lại giết chết quá trình trước đó. - eresourcesfl
Về thời gian ngừng hoạt động tiềm năng, chúng tôi gặp sự cố trên máy chủ của chúng tôi, nơi nhân viên daemon thủ công sẽ bị giết vì lý do không xác định và sẽ không sống sót. Người giám sát là cách duy nhất để đảm bảo nó được hồi sinh khi chết. - zeros-and-ones
Đoạn mã trên cũng nên hoạt động. Bạn có thể gọi những lệnh này thường xuyên như bạn muốn, thường xuyên như mọi phút. Vì vậy, tôi không hiểu những bình luận về việc có một giờ của thời gian chết bằng cách sử dụng phương pháp này. Bạn có quyền kiểm soát tần suất bạn kiểm tra và khởi động lại trình nền. Toàn bộ vấn đề trong việc đăng bài này chỉ là để đưa ra một ví dụ về cách thực hiện nó bằng cách sử dụng Laravel. Có những cách khác để làm điều đó. Nhưng cách này không phụ thuộc vào gói bên ngoài được cài đặt. - eresourcesfl
Tôi nghĩ rằng hầu hết mọi người không nhớ cài đặt một màn hình quá trình, nhưng những người khác có thể không muốn cung cấp cho rằng mức độ truy cập vào một gói bên ngoài mà họ không kiểm soát. Đó là sở thích cá nhân. Trình giám sát dịch vụ có thể sạch hơn nếu bạn không bận tâm khi thực hiện cài đặt trên máy chủ, nhưng phương thức này đạt được như nhau mà không có bất kỳ phụ thuộc bên ngoài bổ sung nào và nên là nền tảng bất khả tri. Nhưng cả hai đều có plusses và minuses. - eresourcesfl


Bạn có thể dùng đơn độc dụng cụ. nó rất nhỏ và hữu ích cho bất kỳ loại quản lý và giám sát quy trình nào.

Sau khi tải xuống gói nhị phân từ liên kết này, bạn có thể giải nén nó vào một thư mục trên hệ thống của bạn và sau đó sao chép hai tệp từ gói vào hệ thống của bạn để cài đặt nó:

cd /path/to/monit/folder
cp ./bin/monit /usr/sbin/monit
cp ./conf/monitrc /etc/monitrc  

Bây giờ chỉnh sửa /etc/monitrc dựa trên nhu cầu của bạn (tài liệu tham khảo). sau đó tạo một tập tin điều khiển init để bật monit khi khởi động. bây giờ bắt đầu monit như thế này:

initctl reload-configuration
start monit

0
2017-10-17 17:57