IMCAT.DEV
로그인 가입
PHP 고급 네트워크

PHP PHP와 메시지 큐

PHP PHP와 메시지 큐 — 고급

PHP와 메시지 큐

1. 도입 (왜 배워야 하는가)

메시지 큐는 시스템 간의 비동기적 통신을 가능하게 해주는 강력한 도구입니다. 실무에서는 대규모 아키텍처를 설계할 때, 서로 다른 서비스가 안정적으로 데이터를 주고받을 수 있어야 합니다. 예를 들어, 웹 애플리케이션에서 사용자가 주문을 하면 결제 서비스, 재고 관리 서비스, 배송 서비스 등 여러 서비스가 동시에 작동해야 할 때, 메시지 큐를 사용하면 각 서비스가 독립적으로 작업을 수행할 수 있도록 도와줍니다.

메시지 큐를 도입하지 않으면, 서비스 간의 직접적인 의존성이 생겨 시스템이 복잡해지고, 오류가 발생할 확률이 높아지며, 성능이 저하될 수 있습니다. 또한, 서비스가 중단될 경우, 다른 서비스도 영향을 받을 위험이 커집니다. 따라서, 메시지 큐를 이해하고 활용하는 것은 현대의 소프트웨어 개발에서 매우 중요합니다.

2. 핵심 개념 설명

메시지 큐 (Message Queue)

메시지 큐는 비동기적으로 메시지를 전송하고 수신하는 시스템입니다. 메시지를 보내는 "제작자(producer)"와 메시지를 받는 "소비자(consumer)" 간의 중재자 역할을 합니다.

비유

메시지 큐를 우편 시스템에 비유할 수 있습니다. 편지를 보내는 사람(제작자)은 우편함에 편지를 넣고, 우편 서비스가 그것을 배달합니다. 받는 사람(소비자)은 우편 서비스가 배달해준 편지를 확인합니다. 이 과정에서 발신자와 수신자는 서로 직접적으로 연결되지 않기 때문에 독립적으로 작업할 수 있습니다.

관련 용어 정리

용어설명
Producer메시지를 생성하는 애플리케이션 또는 시스템
Consumer메시지를 소비하는 애플리케이션 또는 시스템
Queue메시지를 저장하는 공간
Broker메시지를 라우팅하고 관리하는 중재 시스템

3. 기본 코드 예제

다음은 PHP와 RabbitMQ를 사용하여 메시지를 큐에 보내고 받는 간단한 예제입니다.

Producer 예제

<?php
require_once __DIR__ . '/vendor/autoload.php'; // Composer로 설치한 라이브러리 로드

use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;

$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
$channel = $connection->channel();

$channel->queue_declare('test_queue', false, true, false, false, false, []); // 큐 선언

$data = 'Hello, World!'; // 보낼 메시지
$message = new AMQPMessage($data);
$channel->basic_publish($message, '', 'test_queue'); // 메시지 큐에 발행

echo " [x] Sent '$data'\n";

$channel->close();
$connection->close();
?>

실행 결과

 [x] Sent 'Hello, World!'
  • require_once를 사용해 필요한 라이브러리를 로드합니다.
  • AMQPStreamConnection을 통해 RabbitMQ 서버에 연결합니다.
  • queue_declare로 큐를 선언합니다.
  • 메시지를 생성하고 basic_publish로 큐에 발행합니다.
  • Consumer 예제

    <?php
    require_once __DIR__ . '/vendor/autoload.php';
    
    use PhpAmqpLib\Connection\AMQPStreamConnection;
    use PhpAmqpLib\Message\AMQPMessage;
    
    $connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
    $channel = $connection->channel();
    
    $channel->queue_declare('test_queue', false, true, false, false, false, []); // 큐 선언
    
    $callback = function($msg) {
        echo " [x] Received ", $msg->body, "\n"; // 메시지 수신
    };
    
    $channel->basic_consume('test_queue', '', false, true, false, false, $callback); // 메시지 소비
    
    while ($channel->is_consuming()) {
        $channel->wait(); // 메시지를 대기
    }
    
    $channel->close();
    $connection->close();
    ?>

    실행 결과

     [x] Received Hello, World!
  • Producer와 마찬가지로 RabbitMQ에 연결합니다.
  • queue_declare로 큐를 선언합니다.
  • 메시지를 받을 때 실행할 콜백 함수를 정의합니다.
  • basic_consume로 메시지를 소비합니다.
  • while 루프를 통해 메시지를 계속 대기합니다.
  • 4. 실전 활용 예제

    예제 1: 쇼핑몰에서 장바구니 구현

    쇼핑몰 시스템에서 사용자가 장바구니에 상품을 추가할 때마다, 이 정보를 메시지 큐에 보내고, 재고 관리 서비스가 이를 소비하여 재고를 업데이트할 수 있습니다.

    예제 2: 이메일 발송 서비스

    사용자가 회원가입할 때, 가입 확인 이메일을 발송하기 위해 메시지 큐를 사용할 수 있습니다. 사용자가 가입 요청을 보내면, 이메일 발송 서비스가 이를 소비하여 비동기적으로 이메일을 발송합니다.

    5. 흔한 실수와 주의사항

    실수 1: 큐를 선언하지 않음

    // 잘못된 예
    $channel->basic_publish($message, '', 'non_existent_queue'); // 존재하지 않는 큐에 메시지를 발행
  • 주의: 큐를 미리 선언해야 합니다. 존재하지 않는 큐에 메시지를 보내면 오류가 발생합니다.
  • 실수 2: 메시지 소비 후 acknowledgment 처리 생략

    // 잘못된 예
    $channel->basic_consume('test_queue', '', false, false, false, false, $callback); // ack 생략
  • 주의: 메시지를 소비할 때 ack를 설정하지 않으면, 메시지가 큐에서 제거되지 않습니다. 이는 동일한 메시지가 계속 소비될 수 있다는 뜻입니다.
  • 6. 정리

  • 메시지 큐는 비동기적 통신을 가능하게 하여 시스템 간의 독립성을 높입니다.
  • Producer와 Consumer 개념을 이해하는 것이 중요합니다.
  • 실무에서는 메시지 큐를 통해 다양한 서비스 간의 데이터 전송을 효율적으로 처리할 수 있습니다.
  • 다음에 학습하면 좋은 주제:

  • RabbitMQ의 고급 기능 (예: 라우팅, 교환기)
  • 다른 메시지 큐 시스템 (예: Kafka, ActiveMQ) 비교
  • 비동기 프로그래밍 패턴 (예: 이벤트 기반 아키텍처)