216.73.216.25 TODAY : 2,828
์ž๋ฃŒ์‹ค ์„œ๋ธŒ ํƒ€์ดํ‹€ ์•„์ด์ฝ˜

์˜จ๋ผ์ธ ๊ฐ•์˜

 > 

PHP - ์ตœ์ƒ๊ธ‰

๐Ÿ“š PHP ์ตœ์ƒ๊ธ‰ - 2์ฃผ์ฐจ: ๋ฉ”์‹œ์ง€ ํ (Message Queue) ํ™œ์šฉ - 03 PHP์—์„œ ๋ฉ”์‹œ์ง€ ํ ์—ฐ๋™ ๋ฐ ํ™œ์šฉ (Laravel Queue ๋“ฑ)

๐Ÿ“š PHP ์ตœ์ƒ๊ธ‰ - 2์ฃผ์ฐจ: ๋ฉ”์‹œ์ง€ ํ (Message Queue) ํ™œ์šฉ - 03 PHP์—์„œ ๋ฉ”์‹œ์ง€ ํ ์—ฐ๋™ ๋ฐ ํ™œ์šฉ (Laravel Queue ๋“ฑ)

์ฃผ์š” ํ”„๋กœ๊ทธ๋žจ ์ŠคํŽ™

  • ํ‰์ : 10.0
  • ๋ผ์ด์„ ์Šค: free
  • ์šด์˜์ฒด์ œ:
  • ํŒŒ์ผ ํฌ๊ธฐ: 0

ํ”ผ๋“œ๋ฐฑ ๋ฐ ๋‹ค์šด๋กœ๋“œ

  • ์‚ฌ์šฉ์ž ํ‰์ : 10.0
  • ๋‹ค์šด๋กœ๋“œ ์ˆ˜: 1
  • ์กฐํšŒ์ˆ˜: 36

์ œ์กฐ์‚ฌ ๋ฐ ๋“ฑ๋ก ์ •๋ณด

  • ์ œ์ž‘์‚ฌ: LUZENSOFT
  • ๋“ฑ๋ก์ผ: 2025-10-07 09:01:37
  •  

- ์„ค๋ช…

์•ˆ๋…•ํ•˜์„ธ์š”. #PHP ์ตœ์ƒ๊ธ‰ ๊ณผ์ • 2์ฃผ์ฐจ์—์„œ๋Š” ๋ฉ”์‹œ์ง€ ํ๋ฅผ #PHP ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์‹ค์ œ ์—ฐ๋™ํ•˜๊ณ  ํ™œ์šฉํ•˜๋Š” ๊ตฌ์ฒด์ ์ธ ๋ฐฉ๋ฒ•์„ ๋‹ค๋ฃน๋‹ˆ๋‹ค. ํŠนํžˆ, #PHP ์ƒํƒœ๊ณ„์—์„œ ๊ฐ€์žฅ ๋„๋ฆฌ ์‚ฌ์šฉ๋˜๋Š” #Laravel ํ”„๋ ˆ์ž„์›Œํฌ์˜ #Queue ์‹œ์Šคํ…œ์„ ์ค‘์‹ฌ์œผ๋กœ ์‹ค์Šต์— ๊ฐ€๊นŒ์šด ๋‚ด์šฉ์„ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.





PHP ๋ฉ”์‹œ์ง€ ํ ์—ฐ๋™์˜ ์ดํ•ด

uploadImage

์ˆœ์ˆ˜ #PHP ํ™˜๊ฒฝ์—์„œ #๋ฉ”์‹œ์ง€ ํ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด, #RabbitMQ, #Redis, #Beanstalkd, #AWS SQS ๋“ฑ ์›ํ•˜๋Š” ๋ฉ”์‹œ์ง€ ๋ธŒ๋กœ์ปค์™€ ํ†ต์‹ ํ•˜๊ธฐ ์œ„ํ•œ ํด๋ผ์ด์–ธํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์„ค์น˜ํ•˜๊ณ  ์ง์ ‘ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.




๐Ÿ› ๏ธ ์ฃผ์š” ๋ฉ”์‹œ์ง€ ๋ธŒ๋กœ์ปค์™€ PHP ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ


  • RabbitMQ: #AMQP(Advanced Message Queuing Protocol) ๊ธฐ๋ฐ˜์˜ ๊ฐ•๋ ฅํ•œ ๋ฉ”์‹œ์ง€ ๋ธŒ๋กœ์ปค๋กœ, #php-amqplib ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ฃผ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

  • Redis: ์ธ๋ฉ”๋ชจ๋ฆฌ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ ์ €์žฅ์†Œ์ด์ง€๋งŒ, ๋ฆฌ์ŠคํŠธ(List) ์ž๋ฃŒ๊ตฌ์กฐ๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๊ฐ„๋‹จํ•œ #์ž‘์—… ํ๋กœ ๋งŽ์ด ํ™œ์šฉ๋ฉ๋‹ˆ๋‹ค. #Predis๋‚˜ #phpredis ํ™•์žฅ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

  • Beanstalkd: ๊ฐ€๋ณ๊ณ  ๋น ๋ฅด๋ฉฐ, ์ž‘์—…์„ 'Tube'์— ์ €์žฅํ•˜๊ณ  ์›Œ์ปค๊ฐ€ ๊ฐ€์ ธ๊ฐ€๋Š” ๋ฐฉ์‹์œผ๋กœ ์ž‘๋™ํ•˜๋Š” ์ „์šฉ ์ž‘์—… ํ์ž…๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ์ด๋Ÿฌํ•œ ๋กœ์šฐ๋ ˆ๋ฒจ(Low-Level) ์—ฐ๋™์€ ๋ณต์žกํ•˜๊ณ  ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ๊ฐ€ ๊นŒ๋‹ค๋กญ์Šต๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋งŽ์€ #PHP ํ”„๋ ˆ์ž„์›Œํฌ๋Š” #์ถ”์ƒํ™”๋œ #Queue ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.





Laravel Queue ์‹œ์Šคํ…œ: ์—ฐ๋™ ๋ฐ ์„ค์ •

uploadImage

#Laravel์˜ #Queue ์‹œ์Šคํ…œ์€ ๋‹ค์–‘ํ•œ ๋ฐฑ์—”๋“œ(๋ธŒ๋กœ์ปค)๋ฅผ ์ผ๊ด€๋œ #API๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ๊ฐ•๋ ฅํ•œ ์ถ”์ƒํ™” ๊ณ„์ธต์ž…๋‹ˆ๋‹ค.




โš™๏ธ ์„ค์ • (config/queue.php)


Laravel์˜ ํ ์„ค์ • ํŒŒ์ผ์—์„œ๋Š” ์—ฌ๋Ÿฌ #ํ ๋“œ๋ผ์ด๋ฒ„๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.



  • sync: ํ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ์ž‘์—…์„ ์ฆ‰์‹œ ์‹คํ–‰ (๊ฐœ๋ฐœ ๋ฐ ํ…Œ์ŠคํŠธ์šฉ).

  • database: ์ž‘์—…์„ DB ํ…Œ์ด๋ธ”์— ์ €์žฅํ•˜๊ณ , ์›Œ์ปค๊ฐ€ DB๋ฅผ ํด๋งํ•˜์—ฌ ๊ฐ€์ ธ๊ฐ (๊ฐ„๋‹จํ•œ ํ™˜๊ฒฝ์—์„œ ์œ ์šฉ).

  • redis: #Redis๋ฅผ ๋ฐฑ์—”๋“œ๋กœ ์‚ฌ์šฉ (๊ฐ€์žฅ ๋น ๋ฅด๊ณ  ๋„๋ฆฌ ์‚ฌ์šฉ๋˜๋Š” ์˜ต์…˜ ์ค‘ ํ•˜๋‚˜).

  • rabbitmq/sqs/beanstalkd: ์ „์šฉ ๋ธŒ๋กœ์ปค ๋“œ๋ผ์ด๋ฒ„ (์„ค์น˜ ๋ฐ ์„ค์ • ํ•„์š”).

์˜ˆ์‹œ (Redis ๋“œ๋ผ์ด๋ฒ„ ์„ค์ •):



PHP

'redis' => [
    'driver' => 'redis',
    'connection' => 'default', // Redis ์—ฐ๊ฒฐ ์„ค์ • ์ด๋ฆ„
    'queue' => 'default',      // ๊ธฐ๋ณธ ํ ์ด๋ฆ„
    'retry_after' => 90,       // ์žฌ์‹œ๋„๊นŒ์ง€ ๋Œ€๊ธฐ ์‹œ๊ฐ„ (์ดˆ)
    'block_for' => 5,          // ์ž‘์—…์ด ์—†์„ ๋•Œ ์ตœ๋Œ€ ๋Œ€๊ธฐ ์‹œ๊ฐ„ (์ดˆ)
],


๐Ÿง‘โ€๐Ÿ’ป ์ž‘์—… (Job) ์ƒ์„ฑ ๋ฐ ๋””์ŠคํŒจ์น˜


#ํ์— ๋„ฃ์„ ์ž‘์—…์€ Job ํด๋ž˜์Šค๋กœ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.



PHP

// app/Jobs/SendWelcomeEmail.php
namespace AppJobs;

use IlluminateBusQueueable;
use IlluminateContractsQueueShouldQueue;
use IlluminateFoundationBusDispatchable;

class SendWelcomeEmail implements ShouldQueue
{
    use Dispatchable, Queueable;

    protected $user;

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

    // ์‹ค์ œ ์ž‘์—… ๋กœ์ง์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฉ”์„œ๋“œ
    public function handle()
    {
        // ์ด๋ฉ”์ผ ๋ฐœ์†ก ๋กœ์ง
        Mail::to($this->user->email)->send(new WelcomeMail());
    }
}

์ž‘์—… ๋””์ŠคํŒจ์น˜: ์ปจํŠธ๋กค๋Ÿฌ๋‚˜ ์„œ๋น„์Šค์—์„œ ์ž‘์—…์„ ํ์— ๋„ฃ์Šต๋‹ˆ๋‹ค.



PHP

use AppJobsSendWelcomeEmail;

// ...
SendWelcomeEmail::dispatch($user); 
// ๋˜๋Š”
SendWelcomeEmail::dispatch($user)->onQueue('emails'); // ํŠน์ • ํ ์ง€์ •



์›Œ์ปค ํ”„๋กœ์„ธ์Šค ์‹คํ–‰ ๋ฐ ๊ด€๋ฆฌ

uploadImage

#Laravel์€ #์›Œ์ปค ํ”„๋กœ์„ธ์Šค๋ฅผ ๊ตฌ๋™ํ•˜์—ฌ ํ์— ์Œ“์ธ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.




๐Ÿƒ ์›Œ์ปค ๊ตฌ๋™


ํ„ฐ๋ฏธ๋„์—์„œ ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์›Œ์ปค๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.



Bash

php artisan queue:work --tries=3 --timeout=60

  • queue:work: ํ๋ฅผ ์ง€์†์ ์œผ๋กœ ๋ชจ๋‹ˆํ„ฐ๋งํ•˜๋ฉฐ, ๋ฉ”์‹œ์ง€๋ฅผ ๊ฐ€์ ธ์˜ค๋ฉด ์ฒ˜๋ฆฌํ•˜๊ณ  ์ข…๋ฃŒํ•˜์ง€ ์•Š๊ณ  ๋‹ค์Œ ๋ฉ”์‹œ์ง€๋ฅผ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค.

  • --tries=3: ์ž‘์—… ์‹คํŒจ ์‹œ ์ตœ๋Œ€ 3๋ฒˆ๊นŒ์ง€ ์žฌ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค.

  • --timeout=60: ์ž‘์—…์ด 60์ดˆ๋ฅผ ์ดˆ๊ณผํ•˜๋ฉด ํƒ€์ž„์•„์›ƒ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.


๐Ÿญ ์›Œ์ปค ํ”„๋กœ์„ธ์Šค ๊ด€๋ฆฌ


์‹ค์ œ ์šด์˜ ํ™˜๊ฒฝ์—์„œ๋Š” #PM2, #Supervisor ๋˜๋Š” #Laravel Horizon(Redis ๊ธฐ๋ฐ˜ ํ ๊ด€๋ฆฌ ๋„๊ตฌ)์™€ ๊ฐ™์€ ํ”„๋กœ์„ธ์Šค ๊ด€๋ฆฌ ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์›Œ์ปค ํ”„๋กœ์„ธ์Šค๋ฅผ ์•ˆ์ •์ ์œผ๋กœ ์‹คํ–‰ํ•˜๊ณ  ๋ชจ๋‹ˆํ„ฐ๋งํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.



  • Supervisor: ์›Œ์ปค ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ข…๋ฃŒ๋˜๊ฑฐ๋‚˜ ์‹คํŒจํ–ˆ์„ ๋•Œ ์ž๋™์œผ๋กœ ์žฌ์‹œ์ž‘ํ•˜์—ฌ ๊ณ ๊ฐ€์šฉ์„ฑ์„ ์œ ์ง€์‹œ์ผœ ์ค๋‹ˆ๋‹ค.

  • Laravel Horizon: #Redis ํ ์ „์šฉ ๋Œ€์‹œ๋ณด๋“œ๋กœ, #ํ์˜ ์ƒํƒœ, #์ž‘์—… ์ฒ˜๋ฆฌ๋Ÿ‰, #์‹คํŒจํ•œ ์ž‘์—… ๋“ฑ์„ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋ชจ๋‹ˆํ„ฐ๋งํ•˜๊ณ  ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.



์ž‘์—… ์‹คํŒจ ์ฒ˜๋ฆฌ์™€ ์žฌ์‹œ๋„ (Retries)


๋น„๋™๊ธฐ ์ž‘์—…์€ ๋„คํŠธ์›Œํฌ ์˜ค๋ฅ˜, ์™ธ๋ถ€ ์„œ๋น„์Šค ์žฅ์•  ๋“ฑ ๋‹ค์–‘ํ•œ ์ด์œ ๋กœ ์‹คํŒจํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ ์‹œ์Šคํ…œ์€ ์ด๋Ÿฌํ•œ ์‹คํŒจ์— ๋Œ€์‘ํ•˜๋Š” ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.




๐Ÿ—‘๏ธ ์‹คํŒจํ•œ ์ž‘์—… (Failed Jobs)


์ž‘์—…์ด ์ตœ๋Œ€ ์žฌ์‹œ๋„ ํšŸ์ˆ˜๋ฅผ ์ดˆ๊ณผํ•˜์—ฌ๋„ ์‹คํŒจํ•˜๋ฉด, ํ•ด๋‹น ์ž‘์—…์€ #์‹คํŒจํ•œ ์ž‘์—…(Failed Jobs) ํ…Œ์ด๋ธ”(๋˜๋Š” ๋ณ„๋„์˜ ์ €์žฅ์†Œ)๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.



Bash

// ์‹คํŒจํ•œ ์ž‘์—… ๋ชฉ๋ก ๋ณด๊ธฐ
php artisan queue:failed

// ์‹คํŒจํ•œ ํŠน์ • ์ž‘์—… ์žฌ์‹œ๋„
php artisan queue:retry 123


๐Ÿ’€ ๋ฐ๋“œ ๋ ˆํ„ฐ ํ (Dead Letter Queue, DLQ)


๋ณด๋‹ค ์ „๋ฌธ์ ์ธ ๋ฉ”์‹œ์ง€ ๋ธŒ๋กœ์ปค(์˜ˆ: RabbitMQ, AWS SQS)๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ, ์žฌ์‹œ๋„ ํ›„์—๋„ ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š์€ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณ„๋„๋กœ ๊ฒฉ๋ฆฌํ•˜๋Š” ๋ฐ๋“œ ๋ ˆํ„ฐ ํ (DLQ) ๊ธฐ๋Šฅ์„ ํ™œ์šฉํ•˜์—ฌ ๋‚˜์ค‘์— ์ˆ˜๋™์œผ๋กœ ๋ถ„์„ํ•˜๊ฑฐ๋‚˜ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.



Laravel์˜ Queue ์‹œ์Šคํ…œ์„ ์ˆ™๋‹ฌํ•˜๋Š” ๊ฒƒ์€ #๋Œ€๊ทœ๋ชจ #PHP ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์„ฑ๋Šฅ๊ณผ ์•ˆ์ •์„ฑ์„ ํ™•๋ณดํ•˜๋Š” ๋ฐ ํ•„์ˆ˜์ ์ธ ์ตœ์ƒ๊ธ‰ ๊ธฐ์ˆ ์ž…๋‹ˆ๋‹ค.



๋ฌด๋ฃŒ์ฒดํ—˜, ๋Š๊น€์—†์ด ๋น ๋ฅธVPN VPN, ๊ตญ๋‚ด ๋‹ค๋Ÿ‰IP, ๋ชจ๋ฐ”์ผ๊ฐ€๋Šฅ, ๋ณธ์‚ฌ ํ’ˆ์งˆ๊ด€๋ฆฌ ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๋Š” ๋ณด์•ˆ์„ฑ ๋†’์€ VPN ์„œ๋น„์Šค

https://vpn.luzensoft.com