도커 실습 7 - 역방향 프록시를 이용한 마이크로 서비스의 세션 처리 > 클라우드네이티브

본문 바로가기

[실습] 도커 실습 7 - 역방향 프록시를 이용한 마이크로 서비스의 세션 처리

필기자
2025-10-29 12:30 876 0

본문

목차
  • Redis 개요
  • Redis Session
  • Redis 컨테이너 설치 및 세션 테스트

Redis 개요
Redis(Remote Dictionary Server)는 고성능 키-값 저장소로, 데이터베이스, 캐시, 메시지 브로커 등 다양한 용도로 사용됨. Redis는 메모리 기반으로 동작하기 때문에 디스크 기반의 데이터베이스보다 훨씬 빠른 속도를 자랑함. 다양한 데이터 타입을 지원하며, 단순한 문자열뿐만 아니라 리스트, 셋, 해시 등도 저장할 수 있음.
 
3529946166_gLiyoakK_356efef6379056fe7ed70a1a295e5e69cf96d3fc.png
특징
항목 설명
메모리 기반 (In-memory) 모든 데이터를 RAM에 저장하므로 읽기/쓰기 속도가 매우 빠름.
지속성 (Persistence) 메모리 데이터가 손실되지 않도록 주기적으로 디스크(RDB, AOF)에 백업 가능.
공유 저장소 (Shared Storage) 여러 웹 서버가 하나의 Redis를 공동 사용하여 세션·캐시 데이터를 공유할 수 있음.
레플리케이션 (Replication) 하나의 Redis(Master) 데이터를 다른 Redis(Slave) 서버에 실시간 복제하여 고가용성(HA) 확보.
트랜잭션 (Transaction) 여러 명령을 하나의 묶음으로 처리하여 중간에 실패 없이 원자적으로 실행.
Pub/Sub (Publish/Subscribe) 메시지 브로커처럼 실시간으로 데이터를 발행(Publish)하고 구독(Subscribe)하는 구조.

Redis Session
웹 애플리케이션은 사용자의 상태를 유지하기 위해 세션을 사용함. 그러나 세션 데이터를 애플리케이션 서버에 저장하면 서버가 여러 대일 경우 세션 공유에 대한 문제가 있음. 이런 문제를 해결하기 위해 Redis 같은 메모리 저장소를 사용하여 세션 정보를 중앙에서 관리함.

3529946166_HMCv308c_f95109978044ea4b06d75fcac07afaf8386faa60.png

장점
  • 빠른 접근: 메모리 기반으로 빠르게 세션 데이터에 접근 가능
  • 확장성: 여러 서버 간의 세션 공유가 쉬움
  • 지속성: 필요에 따라 세션 데이터를 디스크에 저장하여 안정성 확보
Redis는 빠른 속도와 다양한 용도로 인해 많이 사용되고 있으며, 특히 세션 관리에 유용함.

Redis 컨테이너 설치 및 세션 테스트

redis 도커 허브
역방향 프록시를 이용한 마이크로 서비스의 세션 처리 구성도

3529946166_azKDelwC_a134fe1b29532f9e9c08f85f4b7b5d20c7304bde.png
redis 컨테이너 설치 명령어

docker run -d --name myredis --net php-mysql -p 6379:6379 redis


3529946166_QoJWmL3x_e767eea199f5ae5d18642257a0aa5273d076a73b.png

redis session store 사용을 위한 각 컨테이너(mytaskapi, myuserapi) 모듈 설치

docker exec -it mytaskapi /bin/bash
pecl install redis
docker-php-ext-enable redis
exit
docker exec -it myuserapi /bin/bash
pecl install redis
docker-php-ext-enable redis
exit


redis_session.php 설정 파일 생성
  • /home/kky/php/task/redis_session.php
  • /home/kky/php/user/redis_session.php

// Redis에 연결
$redis = new Redis();               // Redis 클라이언트 객체 생성
$redis->connect('myredis', 6379);   // Redis 서버(myredis:6379)에 연결
                                    // 'myredis'는 Docker 네트워크 컨테이너명일 수 있음

// 세션 핸들러 설정
session_set_save_handler(
    // open($save_path, $session_name)
    // 세션이 처음 시작될 때 호출됨 (session_start() 시점)
    // 파일 기반 세션이라면 세션 저장 경로를 열지만, Redis는 이미 연결되어 있으므로 특별한 작업 필요 없음
    function ($save_path, $session_name) use ($redis) {
        // $save_path : 세션 파일 저장 경로 (Redis에서는 무시)
        // $session_name : 세션 이름 (보통 PHPSESSID)
        return true; // 정상적으로 열렸음을 반환
    },

    // close()
    // 세션 처리가 끝날 때 (스크립트 종료 시) 호출됨
    // Redis 연결 종료나 정리 작업을 수행할 수 있으나, 여기서는 생략
    function () use ($redis) {
        return true; // 특별한 종료 작업 없음
    },

    // read($session_id)
    // 세션 시작 시, 기존 세션 데이터를 읽기 위해 호출됨
    // Redis에 저장된 "session:<세션ID>" 키에서 세션 데이터를 가져옴
    function ($session_id) use ($redis) {
        // $session_id : 현재 세션을 식별하는 고유 ID
        $data = $redis->get("session:$session_id"); // Redis에서 세션 데이터 읽기
        error_log("Read session data: $data");      // 디버깅용 로그 출력
        return $data ? $data : '';                  // 데이터가 없으면 빈 문자열 반환
    },

    // write($session_id, $session_data)
    // 스크립트 종료 시 세션이 변경되었다면 호출됨
    // 세션 데이터를 Redis에 저장함 (유효기간 3600초 = 1시간)
    function ($session_id, $session_data) use ($redis) {
        // setex(key, TTL, value) : TTL(초) 동안 유효한 키 저장
        return $redis->setex("session:$session_id", 3600, $session_data);
    },

    // destroy($session_id)
    // session_destroy()가 호출될 때 실행됨
    // Redis에서 해당 세션 키를 삭제
    function ($session_id) use ($redis) {
        return $redis->del("session:$session_id");
    },

    // gc($maxlifetime)
    // 오래된 세션 데이터를 정리하는 가비지 컬렉션 단계
    // Redis는 TTL(유효기간)로 자동 만료되므로 별도 처리 불필요
    function ($maxlifetime) use ($redis) {
        return true;
    }
);

// 등록된 핸들러를 활성화하려면 session_start() 호출 필요
// 이후 $_SESSION에 저장되는 값은 Redis를 통해 관리됨


redis 세션 설정 및 확인 테스트 파일 생성
  • home/kky/php/user/redis_session_set.php


// redis_session.php 안에는 session_set_save_handler() 설정 코드가 있음
include_once("./redis_session.php"); // 세션을 Redis로 저장하도록 핸들러 등록

// -----------------------------------------------------------
// ① session_start()
// -----------------------------------------------------------
// 1) PHP가 클라이언트의 쿠키에서 PHPSESSID 값을 읽음
//    - 없으면 새로 생성 (예: "8f94e2b78e3d1e1a2c4f7b99c8a5e6f2")
// 2) 등록된 핸들러의 open($save_path, $session_name) 자동 호출
// 3) 이어서 read($session_id) 호출 → Redis에서 "session:<세션ID>" 데이터 조회
//    - 이전 세션 데이터가 있으면 읽고, 없으면 빈 세션으로 시작
session_start();

// -----------------------------------------------------------
// ② $_SESSION 배열에 데이터 저장
// -----------------------------------------------------------
// PHP 내부 메모리상의 세션 배열에 값만 기록됨
// 이 시점에는 아직 Redis에 반영되지 않음
$_SESSION['username'] = "홍길동";
$_SESSION['userid'] = "kky";

// -----------------------------------------------------------
// ③ 세션 데이터 사용
// -----------------------------------------------------------
// 현재 메모리에 로드된 $_SESSION 값을 바로 출력 가능
// 브라우저 출력 시 PHPSESSID 쿠키도 함께 전송되어
// 다음 요청에서 동일한 세션을 복원할 수 있음
echo "사용자 이름 : {$_SESSION['username']}<br>";
echo "사용자 아이디 : {$_SESSION['userid']}<br>";

// -----------------------------------------------------------
// ④ 스크립트 종료 시 자동 호출 (핸들러 내부 동작)
// -----------------------------------------------------------
// - write($session_id, $session_data) 호출
//   → PHP가 $_SESSION 배열을 직렬화하여 Redis에 저장
//   → 예: setex("session:8f94e2b78e3d1e1a2c4f7b99c8a5e6f2", 3600, 'username|s:9:"홍길동";userid|s:3:"kky";')
// - close() 호출
//   → 세션 저장 완료 후 종료 처리

  • home/kky/php/task/redis_session_get.php


// Redis 세션 핸들러 등록 파일 불러오기
// (이 파일에는 session_set_save_handler() 설정이 들어 있음)
include_once("./redis_session.php");

// -----------------------------------------------------------
// ① session_start()
// -----------------------------------------------------------
// - 클라이언트의 쿠키에서 PHPSESSID를 확인함
//   (예: PHPSESSID=8f94e2b78e3d1e1a2c4f7b99c8a5e6f2)
// - 쿠키가 없으면 PHP가 새 세션 ID를 생성함
//
// - 이후 PHP 내부적으로 다음 호출 순서가 자동으로 진행됨:
//     1) open($save_path, $session_name)   → 세션 핸들러 초기화
//     2) read($session_id)                 → Redis에서 세션 데이터 조회
//
//   read($session_id)는 예를 들어 다음과 같은 Redis 키를 조회함:
//       get("session:8f94e2b78e3d1e1a2c4f7b99c8a5e6f2")
//
//   Redis에 저장된 데이터 예시:
//       username|s:9:"홍길동";userid|s:3:"kky";
//
//   PHP 엔진은 이 문자열을 자동으로 "역직렬화(unserialize)" 하여
//   $_SESSION 배열에 다음과 같이 복원함:
//       $_SESSION['username'] = "홍길동";
//       $_SESSION['userid']   = "kky";
//
//   즉, read()는 데이터를 Redis에서 가져오고
//   PHP가 $_SESSION 전역 배열에 자동으로 채워 넣는 단계이다.
session_start();

// -----------------------------------------------------------
// ② $_SESSION 데이터 접근
// -----------------------------------------------------------
// 위 단계에서 Redis → PHP 메모리로 이미 복원된 데이터이므로,
// 직접 할당 없이 곧바로 $_SESSION 값 사용 가능
echo "사용자 이름 : {$_SESSION['username']}<br>";
echo "사용자 아이디 : {$_SESSION['userid']}<br>";

// -----------------------------------------------------------
// ③ 스크립트 종료 시 자동 호출
// -----------------------------------------------------------
// - 세션 데이터가 변경되지 않았더라도 write($session_id, $session_data)가 호출됨
//   → PHP가 현재 $_SESSION 배열을 다시 직렬화하여 Redis에 setex()로 저장
// - close() 호출로 세션 처리가 완료됨



역방향 프록시 설정 확인
3529946166_N5bRCrQL_7cd5ac638563ecf8d9ccd29829f2457aec1f2445.png

redis 세션 테스트 3529946166_Q6hlsLWk_6e9bf334ec16710786168eaef8a65a2a9d3ec3e8.png 3529946166_8hMciqFA_f51cd20dbae14e6e33aa8c9daa671fb82ff142a5.png 3529946166_I6psgOFY_7864af97d1d926e3849a51d2df139acd59a1485e.png
 

댓글목록0

등록된 댓글이 없습니다.
게시판 전체검색