Ubuntu 20.04에서 PHP를 사용하여 Redis® Queue와 Worker를 구현하는 방법
목차
- 소개
- 전제 조건
-
php-redis
확장 설치 -
test_db
데이터베이스 생성 - Redis® 대기열 PHP 파일 설정
- 고객 데이터를 Redis® 대기열로 보내기
- Redis® 데이터를 MySQL에 영구적으로 저장하기
- Redis® 서버 작업자 테스트
- Redis® 작업자 자동 실행
- 결론
소개
Redis® 대기열은 선입선출 개념에 따라 작업의 일련의 집합을 만들고 처리하는 라이브러리입니다. 웹 응용 프로그램에서 대기열을 항상 사용하여 비즈니스 로직이 오랜 시간이 걸릴 경우 사용자가 응답을 기다리지 않도록 해야합니다. 예를 들어, 바쁜 온라인 상점에서 대기열과 백그라운드 워커를 사용하여 결제 및 주소 확인과 같은 복잡한 프로세스를 수행할 수 있습니다. 즉, 웹 응용 프로그램이 사용자의 인내심에 맞지 못하는 순서대로 프로세스가 발생해야하는 유스 케이스가 있다면, 파일 변환 포털과 같은 Redis® 대기열을 사용하는 것을 고려해보십시오.
이 가이드에서는 Ubuntu 20.04 서버의 MySQL 데이터베이스에서 고객 등록을 처리하기 위해 Redis® 의 RPUSH
와 LPOP
명령어를 사용하여 PHP를 사용합니다.
전제 조건
이 튜토리얼을 완료하려면 다음이 필요합니다:
- Ubuntu 20.04 서버
- sudo 사용자
- LAMP 스택
- Redis® 서버
php-redis
확장 설치
서버에 연결하고 패키지 정보 인덱스를 업데이트하고 php-redis
도우미 라이브러리를 설치하여 Redis® 서버의 기능을 PHP 코드 내에서 사용할 수있게 만듭니다.
$ sudo apt update
$ sudo apt install -y php-redis
변경 사항을 다시로드하기 위해 Apache 웹 서버를 재시작합니다.
$ sudo systemctl restart apache2
test_db
데이터베이스 생성
이 튜토리얼에서는 고객 등록 정보를 Redis® 서버에 대기열로 저장한 다음 데이터를 영구적으로 MySQL 데이터베이스에 저장합니다.
아래 명령을 실행하여 루트 사용자로 MySQL 서버에 로그인합니다.
$ sudo mysql -u root -p
입력하라는 메시지가 표시되면 MySQL 서버의 루트 암호를 입력하고 Enter
키를 눌러 계속합니다. 그런 다음 test_db
데이터베이스를 만듭니다.
mysql> CREATE DATABASE test_db;
test_db_user
사용자를 설정하고 EXAMPLE_PASSWORD
에 대한 강력한 값을 사용하십시오. 이러한 세부 정보를 사용하여 PHP 스크립트에서 MySQL에 연결합니다.
mysql> CREATE USER 'test_db_user'@'localhost' IDENTIFIED WITH mysql_native_password BY 'EXAMPLE_PASSWORD';
mysql> GRANT ALL PRIVILEGES ON test_db.* TO 'test_db_user'@'localhost';
mysql> FLUSH PRIVILEGES;
MariaDB 서버를 사용하는 경우 아래와 같이 CREATE USER
명령을 변경하십시오.
MariaDB> GRANT ALL PRIVILEGES on test_db.* TO 'test_db_user'@'localhost' identified by 'EXAMPLE_PASSWORD';
그런 다음 test_db
데이터베이스로 전환합니다.
mysql> USE test_db;
아래 명령을 실행하여 customers
테이블을 만듭니다.
mysql> CREATE TABLE customers (
customer_id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
first_name VARCHAR(50),
last_name VARCHAR(50),
email_address VARCHAR(255)
) ENGINE = InnoDB;
customers
테이블에 어떤 데이터도 입력하지 마십시오. 나중에 Redis® 서버에서 데이터를 가져와 테이블을 채우게 됩니다. mysql>
명령줄 인터페이스에서 종료합니다.
mysql> QUIT;
Redis® 대기열 PHP 파일 설정
웹 서버의 루트 디렉토리에 새로운 /var/www/html/redis_queue.php
를 nano를 사용하여 엽니다. 이 파일은 등록 목적으로 고객 세부 정보를 POST
매개 변수로 받습니다.
$ sudo nano /var/www/html/redis_queue.php
파일에 아래 정보를 추가합니다.
<?php
try {
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$data = [];
$data = [
'first_name' => $_POST['first_name'],
'last_name' => $_POST['last_name'],
'email_address' => $_POST['email_address']
];
$redis->rpush("customers_register", json_encode($data));
echo "고객 정보가 성공적으로 수락되었습니다.
";
} catch (Exception $e) {
echo $e->getMessage();
}
파일을 저장하고 닫습니다.
위의 파일에서는 로컬에 호스팅되고 포트 6379
에서 실행 중인 Redis® 서버에 연결합니다. 그런 다음, 글로벌 $_POST
매개 변수에서 받은 고객 데이터의 data
배열을 생성합니다. 그런 다음, redis->rpush
명령을 사용하여 데이터를 JSON으로 인코딩 된 문자열로 Redis® 서버에 전송합니다.
데이터가 Redis® 서버에 저장되면 성공 메시지를 출력합니다. 다음 단계에서는 샘플 데이터를 파일로 보내봅니다.
고객 데이터를 Redis® 대기열로 보내기
실제 환경에서는 고객이 HTML 양식을 사용하여 응용 프로그램에 가입할 수 있습니다. 이 튜토리얼을 위한 기초를 위해 명령 프롬프트에서 Linux curl
명령을 사용하여 http://localhost/queue_register.php
로 데이터를 보냅니다.
아래 명령을 실행하여 세 개의 고객 레코드를 전송합니다.
$ curl --data "first_name=JOHN&last_name=DOE&email_address=john_doe@example.com" http://localhost/redis_queue.php
$ curl --data "first_name=MARY&last_name=SMITH&email_address=mary_smith@example.com" http://localhost/redis_queue.php
$ curl --data "first_name=ROE&last_name=STEVE&email_address=roe_steve@example.com" http://localhost/redis_queue.php
각 명령을 실행한 후 다음 출력을 얻는지 확인하십시오.
...
고객 정보가 성공적으로 수락되었습니다.
위의 출력에서 Redis® 서버가 데이터를 성공적으로 대기열에 저장하는 것을 확인할 수 있습니다. 이제 대기열을 처리하기 위해 작업자를 만드는 단계로 넘어갑니다.
Redis® 데이터를 MySQL에 영구적으로 저장하기
이 단계에서는 Redis®의 LPOP
명령을 사용하여 Redis® 서버에서 고객 데이터를 대기열에서 처리하고 MySQL 데이터베이스에 영구적으로 데이터를 저장합니다.
nano를 사용하여 새로운 /var/www/html/redis_worker.php
파일을 연 다음 아래 정보를 파일에 추가합니다.
<?php
try {
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$data = $redis->lpop('customers_register');
$data = json_decode($data, true);
if (!empty($data)) {
$db_name = 'test_db';
$db_user = 'test_db_user';
$db_password = 'EXAMPLE_PASSWORD';
$db_host = 'localhost';
$pdo = new PDO('mysql:host=' . $db_host . '; dbname=' . $db_name, $db_user, $db_password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$sql = 'insert into customers
(
first_name,
last_name,
email_address
)
values
(
:first_name,
:last_name,
:email_address
)
';
$stmt = $pdo->prepare($sql);
$stmt->execute($data);
echo $data[first_name] . " " . $data[last_name] . "님의 세부 정보가 데이터베이스에 저장되었습니다.";
}
} catch (Exception $e) {
echo $e->getMessage();
}
파일을 저장하고 닫습니다.
위의 파일에서는 Redis® 서버에 연결하고 lpop
문을 사용하여 첫 번째로 도착한 데이터를 대기열에서 가져옵니다. 그런 다음 데이터를 JSON으로 디코딩하고 PHP 데이터 개체($pdo
)로 실행될 SQL 명령문 작성합니다. 마지막으로 데이터를 MySQL 서버에 영구적으로 저장하고 성공 메시지를 출력합니다.
주의: SQL 인젝션 공격을 방지하기 위해 바운드 매개 변수를 사용합니다. 이 가이드는 데모용이며 데이터 유효성 검사가 포함되어 있지 않습니다. 실제 환경에서는 데이터를 더욱 철저하게 검증하고 필터링하여 더 견고한 보안 계층을 구축해야합니다.
Redis® 서버 작업자 테스트
http://localhost/redis_worker.php
URL을 실행하여 redis_worker.php
파일이 예상대로 작동하는지 테스트합니다. 다음 명령을 세 번 실행하여 모든 항목을 처리합니다.
$ curl http://localhost/redis_worker.php
다음 출력에서 Redis® LPOP
명령이 Redis® 서버에 도착한 순서대로 고객을 데이터베이스에 등록하는 것을 확인할 수 있습니다.
JOHN DOE님의 세부 정보가 데이터베이스에 저장되었습니다.
MARY SMITH님의 세부 정보가 데이터베이스에 저장되었습니다.
ROE STEVE님의 세부 정보가 데이터베이스에 저장되었습니다.
Redis® 대기열과 작업자의 논리가 예상대로 작동하는지 확인하기 위해 데이터베이스에서 고객의 세부 정보를 확인하세요. 이를 위해 root로 다시 MySQL 서버에 로그인합니다.
$ sudo mysql -u root -p
암호를 입력하고 Enter
키를 누릅니다. 그런 다음 test_db
데이터베이스로 전환합니다.
mysql> USE test_db;
customers
테이블에 대해 SELECT
문을 실행합니다.
mysql> SELECT
customer_id,
first_name,
last_name,
email_address
FROM customers;
Redis® 큐와 작업자의 논리가 예상대로 작동하는지 확인하기 위해 아래와 같은 출력을 확인해야합니다.
+-------------+------------+-----------+------------------------+
| customer_id | first_name | last_name | email_address |
+-------------+------------+-----------+------------------------+
| 1 | JOHN | DOE | john_doe@example.com |
| 2 | MARY | SMITH | mary_smith@example.com |
| 3 | ROE | STEVE | roe_steve@example.com |
+-------------+------------+-----------+------------------------+
3 rows in set (0.00 sec)
MySQL 명령줄 인터페이스에서 나갑니다.
mysql> QUIT;
Redis® 작업자 자동 실행
이전 단계에서는 Linux curl
명령을 사용하여 http://localhost/redis_worker.php
스크립트를 수동으로 실행했습니다. 작업자를 자동으로 실행하려면 파일을 실행하도록 지정하는 크론 작업을 만들어야합니다.
crontab
파일을 엽니다.
$ sudo nano /etc/crontab
파일의 하단에 아래 내용을 추가하여 http://localhost/redis_worker.php
작업자를 매 분마다 실행하도록합니다.
...
* * * * * root /usr/bin/wget -O - http://localhost/redis_worker.php
파일을 저장하고 닫습니다. 이제 다른 고객 데이터를 http://localhost/redis_queue.php
엔드 포인트에 보내 봅니다.
$ curl --data "first_name=BABY&last_name=SMALL&email_address=baby_small@example.com" http://localhost/redis_queue.php
고객의 세부 정보가 큐에 들어 있는지 확인합니다.
고객 정보가 성공적으로 수락되었습니다.
1분 후 MySQL 서버로 다시 로그인합니다.
$ sudo mysql -u root -p
루트 암호를 입력하고 Enter
키를 눌러 계속합니다. 그런 다음 test_db
데이터베이스를 사용합니다.
mysql> USE test_db;
아래 SELECT
문을 한 번 더 실행하여 cron 작업이 작업자를 실행하는지 확인합니다.
mysql> SELECT
customer_id,
first_name,
last_name,
email_address
FROM customers;
cron 작업이 예상대로 작동하는지 확인하는 아래 출력을 얻어야합니다.
+-------------+------------+-----------+------------------------+
| customer_id | first_name | last_name | email_address |
+-------------+------------+-----------+------------------------+
| 1 | JOHN | DOE | john_doe@example.com |
| 2 | MARY | SMITH | mary_smith@example.com |
| 3 | ROE | STEVE | roe_steve@example.com |
| 4 | BABY | SMALL | baby_small@example.com |
+-------------+------------+-----------+------------------------+
4 rows in set (0.00 sec)
1분 동안의 시간 범위는 중요한 애플리케이션에는 너무 길 수 있으며, 이러한 경우 새로운 큐 항목에 대해 작업자 파일을 계속 폴링하는 PHP 루프 파일을 만들 수 있습니다.
결론
이 가이드에서는 Ubuntu 20.04 서버에서 Redis®를 사용하여 PHP로 작업 대기열을 만들고 처리하는 방법을 알아보았습니다. 이 가이드의 코드를 확장하여 필요에 맞게 사용할 수 있습니다.
출처: https://docs.vultr.com/implement-redis-queue-and-worker-with-php-on-ubuntu-20-04
안정적이고 저렴한 가상 서버(VPS) 안내
안정적인 서버 호스팅을 찾고 계신가요? 지금 Vultr 호스팅을 한번 이용 해 보세요. 지금 보고 계신 HaruLogs 사이트도 Vultr에서 VPS 호스팅 하고 있습니다. 한국, 일본, 미국등 다양한 국가에 클릭 몇번으로 안정적이고 저렴한 VPS를 운영 할 수 있습니다.
아래 배너를 통해 회원 가입을 하시면 100달러의 무료 크레딧을 받을 수 있습니다. 100달러의 무료 크레딧은 Vultr의 최소 사양 VPS를 20대 동시 운영가능한 크레딧입니다.
Vultr 서비스 요약
- VPS
- 인스턴스
- AMD 또는 Intel High Performance 인스턴스 최저 $6 - 1vCPU, 1GB Memory, 2TB Bandwidth, 25GB NVMe
- 엣지
- 인스턴스
- Block Storage
- Object Storage (AWS S3 호환)
- Firewall
- Network
- Load Balancers
- Kubernetes
- Databases