본문 바로가기

AI

# 24.10.16_ 아키텍처 설계 사례 분석 : Netfilx

728x90

아키텍처 설계 사례 분석 : Netflix

 

  • 넷플릭스 시스템 디자인 배너

Netflix 시스템

  • 기능적 요구 사항
    • 사용자는 계정을 만들고 로그인하고 로그아웃할 수 있어야 함
    • 사용자를 위한 구독 관리
    • 사용자가 비디오를 재생하고 일시 정지, 재생, 되감기, 빨리 감기 기능을 사용할 수 있도록 함
    • 오프라인에서 볼 수 있도록 콘텐츠를 다운로드할 수 있는 기능
    • 사용자 선호도와 시청 기록에 따른 개인화된 콘텐츠 추천
  • 비기능적 요구 사항
    • 콘텐츠 재생 중 지연 시간이 짧고 반응성이 높아야 함
    • 많은 수의 동시 사용자를 처리할 수 있는 확장성 요구
    • 최소한의 다운타임으로 높은 가용성을 보장해야 함
    • 안전한 사용자 인증 및 권한 부여
    • 쉬운 탐색을 위한 직관적인 사용자 인터페이스

Netflix 시스템 설계의 상위 수준 설계

  • [고수준 시스템 아키텍처]

기반 클라우드 시스템

  • AWS, Open Connect의 두 클라우드에서 작동함
  • 두 클라우드는 Netflix의 백본으로 함께 작동함
  • OC(Open Connect) 또는 Netflix CDN 사용
    • CDN: 다양한 지리적 위치에 분산된 서버 네트워크
    • Open Connect: Netflix만의 맞춤형 글로벌 CDN(콘텐츠 전송 네트워크)
  • 비디오 스트리밍과 관련된 모든 것을 처리함
  • 다양한 위치에 배포되어 있음
  • 디바이스에서 재생 버튼을 누르면
    • 이 구성 요소의 비디오 스트림이 장치에 표시됨
    • 예: 북미에 위치한 사용자가 비디오를 재생하려고 하는 경우,
      • 비디오는 원래 서버가 아닌 가장 가까운 오픈 커넥트(또는 서버)에서 제공됨
      • 가장 가까운 서버에서 더 빠른 응답을 받을 수 있음
  • 백엔드(데이터베이스)
    • 재생 버튼을 누르기 전까지 비디오 스트리밍과 관련되지 않은 모든 작업을 처리함
      • 새로운 콘텐츠의 온보딩
      • 비디오 처리
      • 전 세계 여러 지역에 있는 서버에 비디오 배포
      • 네트워크 트래픽 관리 등
  • 대부분의 프로세스는 Amazon Web Services가 처리함

마이크로서비스 아키텍처

  • Netflix의 아키텍처 스타일은 서비스의 모음으로 구축됨(마이크로서비스 아키텍처)
  • 애플리케이션과 웹 앱에 필요한 모든 API를 구동함
  • 요청이 엔드포인트에 도착하면
  • 필요한 데이터를 위해 다른 마이크로서비스를 호출하고
    • 이러한 마이크로서비스는 다른 마이크로서비스에서 데이터를 요청할 수도 있음
  • 그 후 API 요청에 대한 완전한 응답이 엔드포인트로 다시 전송됨
  • 마이크로서비스(Microservice) 아키텍처
  • 애플리케이션을 느슨하게 결합된 서비스의 모임으로 구조화하는 서비스 지향 아키텍처(SOA) 스타일의 일종인 소프트웨어 개발 기법
  • 마이크로서비스 아키텍처에서 서비스들은 섬세(fine-grained)하고 프로토콜은 가벼운 편
  • 애플리케이션을 작은 여러 서비스로 분해할 때의 장점
    • 모듈성의 개선
    • 애플리케이션의 이해, 개발, 테스트가 용이함
    • 애플리케이션 침식에 대하여 더욱 탄력적으로 대응할 수 있음
    • 규모가 작은 자율적인 팀들이 팀별 서비스를 독립적으로 개발, 전개, 규모 확장을 할 수 있게 함으로써 병렬 개발을 가능하게 함
    • 지속적인 리팩터링을 통해 개개의 서비스 아키텍처가 하나로 병합될 수 있게 허용
    • 지속적 배포와 전개(디플로이)를 가능하게 함
  • 마이크로서비스 아키텍처에서 서비스는 서로 독립적이어야 함
    • 예: 비디오 저장 서비스는 비디오 트랜스코딩을 담당하는 서비스에서 분리됨

  • [마이크로서비스 아키텍처]

마이크로서비스 아키텍처를 안정적으로 만드는 방법

  • Hystrix의 사용
  • 중요한 마이크로서비스 분리
    • 일부 중요한 서비스(또는 엔드포인트 또는 API)를 분리하여 다른 서비스에 대한 종속성이나 독립성을 낮출 수 있음
    • 또한 일부 중요한 서비스를 다른 안정적인 서비스에만 종속시킬 수도 있음
    • 중요한 마이크로서비스를 선택할 때 비디오 검색, 비디오 탐색, 비디오 클릭 및 재생 등 모든 기본 기능을 포함할 수 있음
    • 이렇게 하면 엔드포인트의 가용성을 높일 수 있으며 최악의 상황에서도 적어도 한 명의 사용자는 기본적인 작업을 수행할 수 있음
  • 서버를 무상태로 처리
    • 엔드포인트 중 하나에서 오류가 발생하거나 적절한 시기에 요청을 처리하지 못하는 경우 다른 서버로 전환하여 작업을 완료할 수 있도록 서비스를 설계하는 것이 아이디어
      • 예: 젖소 떼로부터 매일 얼마나 많은 갤런의 우유를 얻는지가 중요하다고 할 때,
        • 어느 날 젖소에서 우유가 줄었다는 것을 알게 되면
        • 그 젖소(우유 생산량 감소)를 다른 젖소로 교체하면 됨
        • 필요한 양의 우유를 얻기 위해 특정 소에 의존할 필요는 없음
        • 이 예시를 애플리케이션과 연관시킬 수 있음
Hystrix
  • 애플리케이션이 외부 시스템으로 인한 서비스의 지연과 장애에 대해 내성을 갖게 해주는 라이브러리
  • Netflix에서 개발했으며, 현재는 유지보수만 진행 중
  • 지원하는 기능
    • 빠른 실패(외부 시스템 혹은 서비스의 지연에 대한 빠른 실패처리)
    • 기본적으로 Thread Pool을 이용하여 포화 상태가 될 경우 앞으로의 요청은 실패 처리
    • 호출 실패에 대한 fallback 메소드 제공
    • 연쇄 장애 방지
    • Thread 혹은 Semaphore 전략에 따른 circuit breaker 기능
    • 실시간 모니터링
  • Hystrix의 기본 동작
    • HystrixCommand 혹은 HystrixObservableCommand 객체를 생성
    • Command 객체를 동작시킴(proxy의 역할)
    • Cache의 여부를 확인
    • Circuit breaker 확인(open[사용 불가 상태], close)
    • 세마포어 혹은 Thread pool의 Thread를 사용할 수 있는 상태인지를 체크
    • 실질적인 로직을 통작시킴(run() 메소드를 통해)
    • Circuit breaker를 open 상태로 돌려야할지의 여부 체크
    • 로직의 에러 혹은 circuit open 상태일 경우 빠른 실패 처리

  • [ Hystrix 기본 동작]

Netflix 시스템 설계의 저수준 설계

  • 영화/비디오 등록
    • Netflix는 제작사로부터 매우 고품질의 비디오와 콘텐츠를 수신하므로 비디오를 사용자에게 제공하기 전에 몇 가지 사전 처리 작업을 수행함
  • 2,200개 이상의 기기를 지원하며, 각 기기마다 다른 해상도와 형식이 필요함
    • 비디오를 다양한 기기에서 볼 수 있도록 변환이나 인코딩을 수행함
    • 이는 오류를 찾고 원본 비디오를 다른 형식과 해상도로 변환하는 과정

  • [ Netflix-트랜스코딩-1 ]
  • 다양한 네트워크 속도에 대한 파일 최적화를 생성함
    • 비디오를 높은 네트워크 속도로 시청할 때 비디오의 품질이 좋음
    • 각기 다른 해상도로 동일한 영화에 대한 여러 복제본(약 1100-1200개 복제본)을 생성함
    • 이러한 복제본에는 많은 트랜스코딩과 사전 처리가 필요함
      • 원본 비디오를 여러 개의 작은 청크로 나누고
      • AWS의 병렬 작업자를 사용하여 이러한 청크를 다양한 해상도(예: 4k, 1080p 등)에 걸쳐 다양한 형식(예: mp4, 3gp 등)으로 변환
      • 트랜스코딩 후 동일한 영화에 대한 파일의 여러 사본이 있으면 이러한 파일은 전 세계의 다른 위치에 있는 각각의 Open Connect 서버로 전송됨

  • [ Netflix-트랜스코딩-2 ]
  • 최적의 스트리밍 품질을 보장하는 단계별 프로세스
    • 사용자가 자신의 기기에 Netflix 앱을 로드하면 가장 먼저 AWS 인스턴스가 나타나 로그인, 추천, 검색, 사용자 기록, 홈페이지, 청구, 고객 지원 등 일부 작업을 처리함
    • 사용자가 비디오의 재생 버튼을 누르면 네트워크 속도나 연결 안정성을 분석한 후 사용자와 가장 가까운 최적의 Open Connect 서버를 검색함
    • 기기와 화면 크기에 따라 올바른 비디오 형식이 사용자의 기기로 스트리밍됨
      • 비디오를 보는 동안 비디오가 픽셀화되어 보이고 잠시 후 HD로 돌아가는 것을 알아차릴 수 있음
      • 이는 애플리케이션이 최상의 스트리밍 오픈 연결 서버를 계속 확인하고 필요할 때 최상의 시청 환경을 위해 형식을 전환하기 때문에 발생함
    • 검색, 시청, 위치, 기기, 리뷰, 좋아요 등의 사용자 데이터는 AWS에 저장되고, Netflix는 이를 사용하여 머신 러닝 모델이나 Hadoop을 사용하여 사용자를 위한 영화 추천을 구축함
트래픽 부하의 균형잡기
  • 탄력적 로드 밸런서(Elastic Load Balancer, ELB)
    • 트래픽을 프론트엔드 서비스로 라우팅하는 역할
    • 부하가 먼저 존에 분산되고 그다음 인스턴스(서버)에 분산되는 2계층 부하 분산 방식을 수행함
  • 1계층
    • 기본 DNS 기반 라운드 로빈 밸런싱으로 구성
    • 요청이 첫 번째 로드 밸런싱에 도달하면(그림 참조)
    • ELB가 사용하도록 구성된 영역 중 하나(라운드 로빈 사용)에서 밸런싱 수행
  • 2계층
    • 로드 밸런서 인스턴스의 배열
    • 라운드 로빈 밸런싱 기술을 수행하여 동일한 영역에 있는 인스턴스 전반에 요청을 분산

  • [탄력적 부하 분산 장치]
ZUUL
  • 동적 라우팅, 모니터링, 복원성 및 보안을 제공하는 게이트웨이 서비스
  • 쿼리 매개변수, URL 및 경로에 따라 쉬운 라우팅을 제공함
  • 각 부분의 작동 방식
    • Netty 서버
      • 네트워크 프로토콜, 웹 서버, 연결 관리 및 프록시 작업을 처리할 책임을 맡음
      • 요청이 Netty 서버에 도달하면 요청을 인바운드 필터로 프록시함
    • 인바운드 필터
      • 요청의 인증, 라우팅 또는 데코레이팅을 담당
      • 그런 다음 요청을 엔드포인트 필터로 전달함
    • 엔드포인트 필터
      • 정적 응답을 반환하거나 요청을 백엔드 서비스(또는 원점이라고 부름)로 전달
      • 백엔드 서비스로부터 응답을 받으면 해당 요청을 아웃바운드 필터로 전송함
    • 아웃바운드 필터
      • 콘텐츠 압축, 메트릭 계산, 사용자 지정 헤더의 추가/제거 등에 사용
      • 그 후, 응답은 Netty 서버로 다시 전송되고 클라이언트에서 수신됨
  • ZUUL 사용의 장점
  • 몇 가지 규칙을 만들고 트래픽의 각 부분을 여러 서버에 분산시켜 트래픽을 공유할 수 있음
  • 개발자는 일부 머신에서 새로 배포된 클러스터에 대한 부하 테스트를 수행할 수 있음
  • 이러한 클러스터에서 일부 기존 트래픽을 라우팅하고 특정 서버가 얼마나 많은 부하를 견딜 수 있는지 확인할 수 있음
  • 새로운 서비스를 테스트할 수 있음
  • 서비스를 업그레이드하고 실시간 API 요청에서 어떻게 동작하는지 확인하고 싶을 때, 특정 서비스를 한 서버에 배포하고 트래픽의 일부를 새 서비스로 리디렉션하여 서비스를 실시간으로 확인할 수 있음
  • 엔드포인트 필터나 방화벽에서 사용자 정의 규칙을 설정하여 잘못된 요청을 필터링할 수 있음

히스트릭스(Hystrix)

  • 복잡한 분산 시스템에서 서버는 다른 서버의 응답에 의존할 수 있음
  • 이러한 서버 간의 종속성은 지연을 생성할 수 있으며, 서버 중 하나가 불가피하게 어느 시점에서 실패하면 전체 시스템이 작동을 멈출 수 있음
  • 이 문제를 해결하기 위해 호스트 애플리케이션을 이러한 외부 실패로부터 격리할 수 있음
EV 캐시
  • 대부분의 애플리케이션에서는 일정량의 데이터가 자주 사용됨
  • 더 빠른 응답을 위해 이러한 데이터는 많은 엔드포인트에 캐시될 수 있으며, 원래 서버 대신 캐시에서 페치될 수 있음
  • 이렇게 하면 원래 서버의 부하가 줄어들지만
  • 노드가 다운되면 모든 캐시가 다운되고 이로 인해 애플리케이션의 성능이 저하될 수 있다는 문제가 있음
  • 문제 해결을 위해 EV 캐시라는 자체 커스텀 캐싱 계층 구축
    • EV 캐시: Memcached를 기반으로 하며 실제로 Memcached를 둘러싼 래퍼
    • Netflix는 다수의 AWS EC2 인스턴스에 많은 클러스터를 배포했으며 이러한 클러스터에는 많은 Memcached 노드가 있고 캐시 클라이언트도 존재
    • 데이터는 동일 영역 내의 클러스터 전체에서 공유되고, 캐시의 여러 사본이 분할된 노드에 저장됨
    • 클라이언트에 쓰기가 발생할 때마다 모든 클러스터의 모든 노드가 업데이트되지만
    • 캐시에 읽기가 발생하면 가장 가까운 클러스터(모든 클러스터와 노드가 아님)와 해당 노드로만 전송됨
    • 노드를 사용할 수 없는 경우 다른 사용 가능한 노드에서 읽음
    • 이러한 접근 방식은 성능, 가용성 및 안정성을 향상시킴

  • [ EV 캐시 ]
Kafka와 Chukwa를 사용한 데이터 처리
  • Netflix 에서 사용자가 비디오를 클릭하면 다양한 방식으로 데이터를 처리하기 시작하며, 이는 수 나노초도 걸리지 않음
  • 시스템의 다른 부분에서 생성된 데이터를 수집하기 위해 Kafka와 Apache Chukwe를 사용함
  • 하루에 1.3PB를 소비하는 거의 500B의 데이터 이벤트와 피크 타임에 초당 24GB를 소비하는 800만 개의 이벤트를 제공함
  • 이벤트에 포함되는 정보
    • 오류 로그
    • UI 활동
    • 공연 이벤트
    • 영상 시청 활동
    • 문제 해결 및 진단 이벤트 등
  • Apache Chukwa
    • 분산 시스템에서 로그나 이벤트를 수집하기 위한 오픈소스 데이터 수집 시스템
    • HDFS와 Map-reduce 프레임워크 위에 구축됨
    • Hadoop의 확장성과 견고성 기능이 함께 제공됨
      • 결과를 표시, 모니터링, 분석하기 위한 강력하고 유연한 툴킷을 많이 포함하고 있음
      • 시스템의 다양한 부분에서 이벤트를 수집하며, 모니터링과 분석을 수행할 수 있고 대시보드를 사용하여 이벤트를 볼 수 있음
      • Hadoop 파일 시퀀스 형식(S3)으로 이벤트를 작성하며, Big Data 팀은 이러한 S3 Hadoop 파일을 처리하고 Hive를 Parquet 데이터 형식으로 작성함
      • 이 과정을 일괄 처리라고 하며, 기본적으로 매시간이나 매일 간격으로 전체 데이터를 스캔함
    • Chukwa는 온라인 이벤트를 EMR/S3에 업로드하기 위해 Kafka(실시간 데이터 처리의 주요 게이트)에 트래픽을 제공함
  • Apache Kafka
    • 실시간 데이터 처리의 주요 게이트
    • 프런트 엔드 Kafka에서 S3, Elasticsearch, 보조 Kafka 등 다양한 싱크로 데이터를 이동하는 역할 수행
    • 이러한 메시지 라우팅은 Apache Samza 프레임워크를 사용하여 수행

탄력적 검색(Elastic Search)

  • Netflix는 약 150 개의 Elastic Search 클러스터와 인스턴스가 있는 3,500개의 호스트를 실행하고 있음
  • Netflix는 Elastic Search를 데이터 시각화, 고객 지원 및 시스템의 일부 오류 감지에 사용하고 있음
    • 고객이 비디오를 재생할 수 없는 경우
      • 고객 서비스 담당자가 Elastic Search를 사용하여 이 문제를 해결함
      • 재생 팀은 Elastic Search로 이동하여 사용자를 검색하여 사용자의 기기에서 비디오가 재생되지 않는 이유를 알아냄
        • Elastic Search를 통해 특정 사용자에게 발생하는 모든 정보와 이벤트를 알 수 있음
        • 그들은 비디오 스트림에서 오류가 발생한 원인을 알게 됨
  • Elastic Search는 관리자가 일부 정보를 추적하는 데 사용됨
  • 또한 리소스 사용량을 추적하고 가입 또는 로그인 문제를 감지하는 데 사용됨

영화 추천을 위한 Apache Spark

  • Netflix는 영화 추천을 위해 Apache Spark와 머신 러닝을 사용함
    • 첫 페이지를 로드하면 여러 행의 다양한 종류의 영화가 표시됨
      • 이 데이터를 개인화하고 특정 사용자에게 어떤 종류의 행 또는 어떤 종류의 영화를 표시해야 하는지 결정함
      • 이 데이터는 사용자의 과거 데이터와 선호도를 기반으로 함
    • 특정 사용자를 위해 영화를 정렬하고 플랫폼에서 제공되는 영화의 관련성 순위(추천에 대한)를 계산함
      • Netflix에서 Apache Spark는 콘텐츠 추천 및 개인화에 사용됨
      • 대부분의 머신 러닝 파이프라인은 이러한 대규모 스파크 클러스터에서 실행됨
      • 이러한 파이프라인을 사용하여 행 선택, 정렬, 제목 관련성 순위 지정, 아트워크 개인화 등을 수행함
  • 비디오 추천 시스템
    • 사용자가 Netflix에서 어떤 콘텐츠나 비디오를 찾고 싶어할 경우
    • Netflix의 추천 시스템은 사용자가 좋아하는 영화나 비디오를 찾는 데 도움을 줌
    • 추천 시스템을 구축하기 위해 사용자 관심사를 예측해야 하며
    • 다음과 같은 다양한 종류의 데이터를 사용자로부터 수집함
      • 서비스와 사용자 상호작용(시청 기록 및 사용자가 다른 제목을 평가한 방법)
      • 비슷한 취향과 선호도를 가진 다른 회원들
      • 사용자가 이전에 시청한 동영상의 메타데이터 정보(제목, 장르, 카테고리, 배우, 출시 연도 등)
      • 사용자의 기기, 사용자가 가장 활동적인 시간대, 사용자가 활동하는 시간
    • Netflix는 두 가지 다른 알고리즘을 사용하여 추천 시스템을 구축함
      • 협력적 필터링
        • 두 사용자가 비슷한 평가 기록을 가지고 있다면 미래에도 비슷한 행동을 할 것이라는 가정을 기반으로 영상을 필터링함
          • 예를 들어
            • 한 사람이 어떤 영화를 좋아했고 그 영화를 좋은 점수로 평가함
            • 비슷한 기록을 가진 다른 사람도 비슷한 패턴을 가지고 첫 번째 사람이 한 것과 똑같은 일을 할 가능성이 높음
      • 콘텐츠 기반 필터링
        • 사용자가 이전에 좋아했던 동영상과 비슷한 동영상을 필터링함
        • 콘텐츠 기반 필터링은 영화 제목, 개봉년도, 배우, 장르와 같은 제품 정보에 크게 의존
        • 따라서 이러한 필터링을 구현하려면 각 항목을 설명하는 정보를 아는 것이 중요함
        • 사용자가 좋아하는 것을 설명하는 일종의 사용자 프로필 활용도 바람직한 방법
Netflix 시스템 설계의 데이터베이스 설계
  • Netflix는 서로 다른 목적으로 두 가지 데이터베이스, MySQL(RDBMS)과 Cassandra(NoSQL)를 사용함
  • MySQL
  • EC2에 MySQL이 배포됨 - Netflix는 ACID 준수가 필요하기 때문에 청구 정보, 사용자 정보, 거래 정보와 같은 데이터를 MySQL에 저장함 - Netflix는 MySQL에 대한 마스터-마스터 설정을 가지고 있으며, InnoDB를 사용하여 Amazon의 대규모 EC2 인스턴스에 배포함
  • "동기 복제 프로토콜" 설정을 따름
    • 작성자가 기본 마스터 노드인 경우 다른 마스터 노드에도 복제됨
    • 커밋은 기본 및 원격 마스터 노드의 쓰기가 확인된 경우에만 전송 → 데이터의 고가용성 보장
    • 각 노드(로컬 및 크로스 리전)에 대한 읽기 복제본 설정 → 고가용성과 확장성 보장
  • 모든 읽기 쿼리는 읽기 복제본으로 리디렉션되고 쓰기 쿼리만 마스터 노드로 리디렉션
    • 기본 마스터 MySQL에 장애가 발생하는 경우
      • 보조 마스터 노드가 기본 역할을 넘겨받고
      • 데이터베이스의 route53(DNS 구성) 항목이 이 새로운 기본 노드로 변경됨
      • 이렇게 하면 쓰기 쿼리도 이 새로운 기본 마스터 노드로 리디렉션됨

  • [ MySQL ]
  • 카산드라(Cassandra)
    • 대량의 데이터를 처리할 수 있는 NoSQL 데이터베이스
      • 무거운 쓰기와 읽기도 처리할 수 있음
      • Netflix가 더 많은 사용자를 확보하기 시작했을 때
        • 각 멤버의 시청 기록 데이터도 증가하기 시작
        • 이로 인해 시청 기록 데이터의 총 수가 증가
        • Netflix가 이 방대한 양의 데이터를 처리하는 것이 어려워짐
      • Netflix는 시청 기록 데이터의 저장을 확장하면서 두 가지 주요 목표를 염두에 두고 설계를 개선
        • 작은 보관 공간
        • 멤버당 조회 수가 증가함에 따라 일관된 읽기/쓰기 성능이 유지됨
          • Cassandra에서 조회 기록 데이터 쓰기 대 읽기 비율은 약 9:1

  • [ Cassandra-서비스-패턴 ]
  • 전체 비정규화된 데이터 모델
    • 50개 이상의 Cassandra 클러스터
    • 500개 이상의 노드
    • 매일 30TB 이상의 백업
    • 가장 큰 클러스터에는 72개의 노드가 있음
    • 1개 클러스터, 250K 쓰기/초 이상
  • 처음에는 시청 기록이 Cassandra에 단일 행으로 저장됨
    • Netflix에서 사용자 수가 증가하기 시작하면서 행 크기와 전체 데이터 크기가 증가함 이로 인해
      • 스토리지는 많이 필요해지고
      • 운영 비용은 더 많이 들고
      • 애플리케이션 성능은 느려짐
      • 해결책은 이전 행을 압축하는 것
  • Netflix는 데이터를 두 부분으로 나눔
    • 라이브 시청 기록(LiveVH)
      • 이 섹션에는 자주 업데이트되는 사용자의 최근 조회 기록 데이터가 소수 포함됨
      • 이 데이터는 ETL 작업에 자주 사용되며 압축되지 않은 형태로 저장됨
    • 압축 시청 기록(CompressedVH)
      • 이 섹션에는 희귀한 업데이트가 있는 많은 양의 오래된 시청 기록이 분류됨
      • 데이터는 행 키당 단일 열에 저장되며
      • 저장 공간을 줄이기 위해 압축된 형태로도 저장됨
 
  • 내일부터는 마켓 컬리 클론 코딩 프로젝트를 추가로 진행할 예정(저번에 못했던 부분들, 수정할 것 개발 예정)

순서대로 차근차근 예정(포스트도 그에 맞춰서 진행)
- 개인 페이지에서 회원 정보 및 비밀번호 수정

- 추천인 코드 및 마일리지 기능

- 홈페이지 검색어 입력 기능 연동

- 선물특가 타이머 기능

- 시간 남으면 (메일로 회원 가입시 안내 메시지 보내기)

 

728x90