한줄공지
  • 등록된 공지내용이 없습니다.

Ubuntu 20.04에서 PHP를 사용하여 Redis® Queue와 Worker를 구현하는 방법

2024년 7월 5일
조회수 52
코멘트 0

목차

소개

Redis® 대기열은 선입선출 개념에 따라 작업의 일련의 집합을 만들고 처리하는 라이브러리입니다. 웹 응용 프로그램에서 대기열을 항상 사용하여 비즈니스 로직이 오랜 시간이 걸릴 경우 사용자가 응답을 기다리지 않도록 해야합니다. 예를 들어, 바쁜 온라인 상점에서 대기열과 백그라운드 워커를 사용하여 결제 및 주소 확인과 같은 복잡한 프로세스를 수행할 수 있습니다. 즉, 웹 응용 프로그램이 사용자의 인내심에 맞지 못하는 순서대로 프로세스가 발생해야하는 유스 케이스가 있다면, 파일 변환 포털과 같은 Redis® 대기열을 사용하는 것을 고려해보십시오.

이 가이드에서는 Ubuntu 20.04 서버의 MySQL 데이터베이스에서 고객 등록을 처리하기 위해 Redis® 의 RPUSHLPOP 명령어를 사용하여 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 $100 크레딧 선물 받기

 

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
포스트 통계
지금 보고있는 포스트의 통계 데이터를 확인 해 보세요.
  • 총 조회수
    52
  • 최근 30일 조회수
    13
연관 포스트
코멘트 작성