학습
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!
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. 정리
다음에 학습하면 좋은 주제: