728x90
1. 단순한 Static Page 서비스
단순 Static Page 서비스의 경우 대부분 대량의 트래픽을 감당해야하는 경우가 많은 상황이 많기 때문에, 성능에 대해 충분한 고려가 필요하다. ex) 프로모션 홍보 페이지, 랜딩 페이지 등등
예를들어 이모티콘을 발급받는 페이지라고 한다면, 사용자는 내용을 보기보다 어떤 이모티콘인지 어떻게 받을 수 있는지만 확인한다.
즉, 사용자는 페이지가 어떻게 구성되어있는지를 보기보다 중요한 것만 본다. 단일 페이지에서 머무는 시간이 길지 않기 때문에 한사람이 많은 트래픽을 발생시키지 않는다. (=TPS가 짧아질 수 있다.)
TPS(Transactions per Second): 초당 발생하는 트랜잭션 수. TPS 숫자는 높으면 높을 수록 좋지만, TPS가 높아질수록 비용이 비례하게 증가한다. [TPS = 총 Business Transaction 처리건수 / 단위시간 (sec)]
- Web Server + VIP + DNS
Web Service를 구축 한 다음 VIP 를 생성하고, DNS 연결한다.
- Web Service는 nginx를 통해 구축
- nginx로 구축시 불필요한 resource가 노출되지 않도록 주의 해야함(nginx는 웹서비스 구축하기 위해 필요한 SW)
VIP(Virtual IP): 가상 IP. IP를 실제 존재하는 서버로 분산시켜주는 기능을 한다.
DNS (Domain Name System): 도메인 이름 시스템. 사용자에게 친숙한 도메인 이름을 컴퓨터가 네트워크에서 서로를 식별하는 데 사용하는 인터넷 프로토콜(IP) 주소로 변환하는 인터넷 표준 프로토콜의 구성 요소. (도메인 → IP주소)
ex) 사람이 읽을 수 있는 도메인 이름(www.amazon.com)을 머신이 읽을 수 있는 IP 주소(192.0.2.44)로 변환
- Web Server + CDN + VIP + DNS
- 실제 노출될 resource 파일을 CDN 서비스를 통해 관리하도록 하는 방법
- Web Service를 구축하기 위해 nginx를 띄울 때, 특정 경로로 진입시 CDN 서비스의 특정 링크 경로로 연결할 수 있도록 Proxy Pass 처리
CDN (Content Delivery Network): 서버를 분산시켜 캐싱해두고 사용자의 컨텐츠 요청이 들어오면 사용자와 가장 가까운 위치에 존재하는 서버로 매핑시켜 요청된 콘텐츠의 캐싱된 내용을 내어주는 방식으로 빠르게 데이터를 전송하는 방법. 즉, 사용자가 Request하는 위치와 가까운 프록시 서버에 콘텐츠를 요청하고 받아오는 방법
만약 CDN을 사용하지 않는 경우, 사용자가 웹페이지 하나를 열면 총 2개의 요청이 내 서버로 들어온다.
- HTML 문서를 요청 → 1개의 HTTP 리퀘스트
- HTML 안에 <img src="내 서버/image.jpg"> 이런 이미지가 있다면 → 이미지도 같은 서버에 요청함 → 또 1개의 리퀘스트
CDN 사용하는 경우, 내 서버 입장에서는 리퀘스트가 1개만 들어온다. (HTML 요청만)
- HTML은 여전히 내 서버에서 받음 → 1개의 리퀘스트
- 이미지 주소가 <img src="http://cdn.example.com/image.jpg"> 처럼 CDN 서버로 연결됨 → 이미지는 CDN 서버가 처리
- Web Application Server( Front Server - CSR ) + VIP + DNS
- Front Platform을 이용한 서비스 구성(Backend 없이 구성 가능)
- 링크의 구조화가 필요하고 배포이력 관리가 필수일 때 사용할 수 있는 방법
- CSR 방식은 클라이언트에서 렌더링을 처리하기 때문에, 서버의 부담이 덜하고 반응 속도가 빠름
CSR(Client Side Rendering): 클라이언트 랜더링
사용자가 페이지에 접속하면 서버는 빈 HTML + JavaScript를 내려주고, 브라우저가 자바스크립트를 실행해서 페이지 내용을 그리는 구조
- SEO에 대한 고려 필요(HTML에 콘텐츠가 없고, JS 실행 후 내용이 렌더링되기 때문에 검색엔진이 콘텐츠를 인식 못할 수 있음)
SEO(Search Engine Optimization): 웹사이트가 검색 결과에 더 잘 보이도록 최적화하는 과정
검색 순위 개선할 땐 og 태그(메타 태그)를 사용해서 검색창에 데이터 뜰 수 있게 제공하는 경우가 많음
→ 하지만, 동일한 것밖에 제공할 수 없음(= 샤용자에게 제공할 수 있는 데이터가 디테일하지 못하다)
- 서버 구축에 사용할 수 있는 자원에 한계가 있고, 빠른 구축이 필요할 때 사용
- Web Application Service( Front Service ) 를 구축 한 다음 VIP 를 생성하고, DNS 연결
- Web Application Server( Front Server - SSR ) + VIP + DNS
- Front Platform을 이용한 서비스 구성(Backend 없이 구성 가능)
- 링크의 구조화가 필요하고 배포이력 관리가 필수일 때 사용할 수 있는 방법
- SSR 방식은 렌더링을 서버에서 처리하기 때문에, 서버의 부담이 있고 반응 속도가 떨어짐
SSR(Server Side Rendering) : 서버 랜더링
→ 그만큼 트래픽을 적게 받을 수 있고, 리퀘스트가 들어왔을 때 서버에 머무르는 시간이 적다.
→ 서버가 처리할 수 있는 TPS가 증가한다. 즉,
적은 돈으로 처리할 수 있어서 SSR 선호
- 렌더링 결과물을 Redis에 저장시키는 캐싱 처리를 통해 해결
- 캐싱 처리를하기 위해 고려되어야하는 요소가 존재 함
- SEO 이슈에 대해 케어 가능
2. 단순 데이터 운영 서비스
Database인 mysql에 데이터를 운영해서, 다른 서비스에게 API 나 DB 데이터를 제공하는 기능을 위한 서비스.
- Web Application Server(Backend Server) + Redis + Mysql + VIP + DNS
- 실서비스의 경우 가능한 Backend Server 의 Instance를 최소 2개 이상 사용
- 인증기능 구현시 세션 클러스터링에 대해 고려해야 됨
- 주로 Redis를 이용하여 세션 클러스터링을 구현
WAS서버가 2개 이상일 때, 하나가 죽으면 죽어있는 서버에 트래픽을 전달하지 않아 사용자로 하여금 장애를 느끼지 못하게 함
- Redis 를 이용해서 조회되는 데이터의 캐싱처리를 수행
- 캐싱 된 데이터의 Expire 정책을 잘 정리해서 구현이 필요
백엔드는 인증과 관련한 부분을 잘 구현해야한다.
쿠키에 저장한 토큰을 활용해서 인증처리를 구현할 경우, A서버에서 인증 토큰을 받은 뒤 B서버에 갔을 땐 인증이 되지 않는 경우가 많다. (토큰 발급 방식은 같지만, 내용이 다르기 때문에 인증이 되지 않음)
즉, 세션 클러스터링은 동일한 세션으로 여러 곳에서 사용할 수 있게 관리하는 것을 말한다.
3. 운영 데이터를 이용한 사용자 서비스
CMS를 구성하여 운영한 데이터를 바탕으로 사용자에게 컨텐츠를 제공하는 서비스
CMS(Customer Management System): 온라인 콘텐츠 제작, 편집 및 관리를 위한 플랫폼을 제공하는 소프트웨어
- Web Application Server( Backend Server ) + Mysql + Redis + VIP + DNS
일반적인 관리자 시스템은 소수가 이용하기 때문에 백엔드에서 뷰를 띄워서 구현하기도 한다. 다만, 쇼핑몰과 같이 다수의 관리자가 이용하는 경우 UI를 따로 띄우는 경우가 많음.
- 하나의 프로젝트로 구현하는 경우
- View와 운영 기능을 한 코드베이스에 구현
- 단, View 서비스 도메인에서는 운영 기능(추가/수정/삭제 등)에 접근 못하도록 제어 필요
- 각각 분리된 프로젝트로 구현하는 경우
- View 서비스와 운영 서비스를 따로 개발
- 공통 비즈니스 로직이 중복되지 않도록 구조화 필요
- 일정 수준 이상의 개발 숙련도와 중심 역할을 맡을 리더가 필요
- 캐싱 정책 필요
- View 서비스에서 데이터를 캐싱하여 성능 향상
- 운영 서비스에서 데이터가 변경되면, 관련된 View의 캐시를 삭제(Expire)
- 하나의 데이터 변경이 여러 조회 쿼리에 영향을 준다면, 해당 모든 캐시를 함께 삭제
- Web Application Server( Front Server ) + Web Application Server( Backend Server ) + Mysql + Redis + VIP + DNS
- 데이터 운영 서비스 구성에서 API를 제공하고, Front Server를 연동하는 방식
- API와 운영 기능을 하나의 프로젝트로 구성할 경우
- API와 운영 기능을 같은 코드베이스에 구현
- 외부에 제공되는 API 도메인에서는 운영 기능에 접근하지 못하도록 접근 제어 필요
- API와 운영 기능을 각각 다른 프로젝트로 구성할 경우
- 분리 구현 시, 인증 체계 필요 (예: OAuth2 등으로 접근 제어)
- 공통 로직 중복을 피하기 위한 구조 설계 필요
- 구현을 효율적으로 진행하려면 숙련된 담당자가 필요
토큰을 저장할 때 쿠키에 저장하는데, 탈취 가능성이 있음 탈취하는데 드는 시간동안 토큰이 만료되어 사용할 수 없게 되는 경우 있음 Refresh 토큰 발급받아서 인증받게 해야하는 방식이 OAuth2
토큰을 헤더에 심어서 보내고 백엔드에서 토큰 정보를 헤더에 담겨있는 것에서 빼서 인증/인가를 처리
- 캐싱 정책 필요
- API에서 데이터를 빠르게 제공하기 위해 캐싱 도입 필요
- 운영 기능에서 데이터가 변경되면 해당 API의 캐시도 삭제(Expire)
- 하나의 데이터 변경이 여러 API 응답에 영향을 주면, 그 모든 캐시를 함께 삭제해야 함
4. Service To Service Message 전달 서비스
- Web Application Server(Backend Server) + Kafka
카프카(Kafka): 파이프라인, 스트리밍 분석, 데이터 통합 및 미션 크리티컬 애플리케이션을 위해 설계된 고성능 분산 이벤트 스트리밍 플랫폼. Pub-Sub 모델의 메시지 큐 형태로 동작하며 분산환경에 특화
- 특정 서비스에서 메시지 발생시켜서 해당 메시지 처리할 수 있는 임의의 서버 중 한개의 서버에서 처리하도록 구현
- 즉, 비동기로 처리하기 위해 사용된다.
동기로 처리:
1. 이모티콘 발급 버튼
2. API 호출
3. 사용자의 정보 가지고 있는 인증 서버에 토큰 전달
4. 응답 받음 (내부에서는 이미 API 한번 호출)
5. 전달받은 데이터를 사용해서 이모티콘 발급 서버에 다시 이모티콘 발급 API 호출
6. “발급되었습니다.”
API 호출하는데 0.25초씩 걸린다면 벌써 0.5초가 소요된다.
동기방식으로 운영하게 되면 사용자가 기다리게되고, 이탈 가능성 높아짐 → 해결하기 위해 비동기 도입
비동기로 처리:
1. 이모티콘 발급 버튼
2. API 호출
3. 사용자의 정보 전달받을 수 있는 토큰을 Kafka나 DB에 저장시킨 다음 사용자에게 응답을 바로 전달
4. “발급요청이 되었습니다”
카프카에 새롭게 저장되는 정보가 있는 지 조회하고, 정보가 있다면 그 정보를 가져다가 별도의 배치서버에서 관리
→ 사용자의 요청은 대기하지 않고 처리가 된다.
배치를 통해 이모티콘 발급시켜주는 프로세스 진행하기 때문에 비동기형태로 처리된다.
→ 트래픽이 아무리 많아도, TPS 성능 높아진다.
- kafka의 경우 데이터를 파티션 단위로 분산 저장한다. 이상적인 개수는 Partition 개수 == Consumer 개수일때 가장 효율적인 병렬 처리 구조라고 할 수 있다. Consumer의 개수는 유동적으로 변경 가능하지만, Partition의 개수는 다시 줄일 수 없기 때문에 주의해야 한다.
- kafka가 수신한 메시지는 kafka서버 설정에 정의된 시간만큼 보관하는 형태이기 때문에 해당 메시지를 Consumer가 수신했다고 해서 사라지지 않는다.
- kafka에서 데이터를 가져오게 되면, 데이터를 바라보는 offset 정보가 업데이트된다. (job처리 중에 장애 발생하면 해당 job이 있던 offset 스킵하게 되는 문제 발생)
- consumer에서 처리중인 offset의 정보와 처리 완료 여부의 값을 관리해야 장애 발생시 이슈 대응 가능
- offset 정보를 과거의 offset으로 이동이 가능하며 특정시기로 이동도 가능
- ex) 1~20까지의 offset에 담긴 정보 처리하는 중에 10~17까지의 내용이 장애로 인해 처리되지 못했다면, offset을 10으로 이동시켜서 다시 순차적으로 처리를 진행. 단, 18~20의 경우 이미 기처리된 내용이기 때문에 중복처리될 수 있어서 처리를 어떻게 할지는 고민이 필요
- Web Application Server(Backend Server) + Redis
- 특정 서비스에서 메시지를 Brodcast하여 처리할 수 있는 임의의 서비스 모두가 동일한 처리를 수행하도록 구현(Redis의 Pub/Sub 기능을 통해 처리하는 방식)
이전까지의 Redis는 캐싱을 하기 위해 사용, 여기서 말하는 Redis는 Brodcast해서 처리할 수 있는 임의의 서비스 모두가 동일한 처리 수행하도록 구현하는 것을 말함.
브로드캐스팅(Broadcasting): 브로드캐스팅 서버에 데이터가 변경되면 메세지가 웹 소캣 연결로 보내져 클라이언트에 의해 처리될 수 있도록 하는것
Publish / Subscribe: 특정한 주제(topic)에 대하여 해당 topic을 구독한 모두에게 메시지를 발행하는 통신 방법으로 채널을 구독한 수신자(클라이언트) 모두에게 메세지를 전송 하는것을 의미
ex) Redis 서버가 “126이라는 숫자를 456으로 바꿔야함.” 이라는 Publishing 받은 뒤
구독하고 있던 여러개의 서버에 동시에 요청을 보내면 다수의 서버에 있는 데이터가 동시에 갱신될 수 있다.
또한 동시에 조회했는데, 첫번째 서버는 123 출력하고 두번째 서버는 456 출력할 수 있음. (타이밍의 문제)
→ 타이밍을 해결하기 위해 가장 편리하게 사용할 수 있는 방법이 Redis의 Publishing 방식.
- Redis는 Publish된 메시지의 내용을 별도로 보관하지 않기 때문에 처리되지 않는 메시지에 대한 대응 취약(서버 재부팅, 장애발생시의 메시지 수신 못한 경우에 대한 대응 방법 고려 필요)
5. 배치 서비스
- Web Application Server( Backend Server ) + Mysql
- 배치 Job 처리 기능과 Job 분산을 위한 처리를 백엔드에서 자체적으로 구현
- Job 처리에 들어가는 Instance에 어떻게 분산해서 Job을 전달해 줄 것인지 고민이 필요
- Mysql의 특정 Table을 Queue형태로 사용하는 방법
- Job List의 index 숫자 값을 instance 개수만큼 나누어 나머지값에 매칭되는 instance 에서 처리하도록 하는 방법(나머지연산(mod)을 통해 여러 인스턴스가 Job을 나눠 처리하는 방식)
- 실행되는 instance에 번호가 매칭될 수 있도록 하는 방법이 필요
- Job 처리 instance 마다 일일이 번호를 환경변수로 부여하는 방법은 instance 개수가 적을 때는 괜찮음
- Job 처리 instance 의 개수가 많거나, 유동적으로 조절해야하는 경우 이슈가 있음
- 실행되는 instance에 번호가 매칭될 수 있도록 하는 방법이 필요
Redis에 비해 속도는 낮지만, 안정성이 높아서 Mysql 자주 사용한다. 또한, 비용을 아낄 수 있다.
- Web Application Server( Backend Server ) + kafka
- 처리할 작업(Job)을 Kafka에 메시지 형태로 쌓아두고, 여러 인스턴스(consumer)가 이를 나눠서 처리하는 구조 - Job 분산처리
- Job을 Topic으로 구분하고, Job처리를 수행하는 Instance에서 kafka에 처리해야하는 내용에 대해 가져와서 수행
ex) 인스턴스A: 이미지 처리 Job → image-processing 토픽 → 메시지를 읽고 이미지 리사이징 수행
인스턴스B: 이메일 발송 Job → email-sending 토픽 → 메시지를 읽고 이메일 전송
6. 검색 기능 제공 서비스
- Web Application Server( Backend Server ) + Mysql
- 저장된 테이블 컬럼 기반으로 SQL 쿼리의 조건절(where)통해 특정 데이터의 검색기능 구성(일반적인, 단순한 검색 기능 구현 방법)
- 데이터의 인덱싱 설정에 따라 검색의 성능이 달라질 수 있음
- Like검색: 사용방법에 따라서 index 사용하지 않고 검색하기 때문에 성능 이슈(Like절로 부분매칭 or Equals로 완전매칭)
- Like를 앞뒤에 붙이면 인덱싱이 동작하지 못해서 Full Scan으로 동작.
- 신문기사정도의 컨텐츠가 저장되어있는 서비스의 경우 Mysql로 처리하려면 Full Scan이 동작해 오랜시간 기다려야한다.
- 이정도 되는 수준에서 부분매칭할 필요 없으면, 그냥 Mysql사용해도 무관
- Like검색: 사용방법에 따라서 index 사용하지 않고 검색하기 때문에 성능 이슈(Like절로 부분매칭 or Equals로 완전매칭)
1. 대부분 단어를 검색하는 경우가 많음
2. 형태소 분석기를 사용해서 컨텐츠 저장 당시 분석 시행
3. 단어가 매칭되면 Mysql에 저장될 때, 기사 원문과 키워드들 별도로 저장시켜 놓는다.
→ 키워드와 매칭만 시킬 수 있으면 완전매칭으로 적용 가능
형태소 분석기는 사용하기 까다롭지만, Mysql로 처리할 수 있는 방법
- Web Application Server( Backend Server ) + Mysql + ElasticSearch
- 데이터는 MySQL로 관리, 화면별로 보여지는 내용을 기반으로 검색기능 제공할 때 활용하는 방법
- 컨텐츠는 여러 table 조합해서 보여지는 경우가 대부분이라 검색 쿼리 수행 후 데이터 재구성 작업 필요(JOIN 등을 통해 검색하기엔 속도 문제)
- ElasticSearch에 저장시키는 방법과 구조에 따라 Index 혹은 Type을 기준으로 서비스에서 보여지는 컨텐츠 결과물 데이터를 저장
- ElaticSearch에서 제공하는 검색기능 이용해 다양한 형태의 검색기능 구현
- Elasticsearch는 텍스트를 파싱해서 검색어 사전을 만든 다음에 inverted index 방식으로 텍스트를 저장.
"Lorem Ipsum is simply dummy text of the printing and typesetting industry"
예를 들어, 이 문장을 모두 파싱해서 각 단어들( Lorem, Ipsum, is, simply .... )을 저장하고, 대문자는 소문자 처리하고, 유사어도 체크하고... 등의 작업을 통해 텍스트를 저장한다. 때문에 RDBMS보다 전문검색( Full Text Search )에 빠른 성능을 보인다.
- 컨텐츠 중심의 검색 기능 구현 가능, 저장방식(ex. 시계열 데이터 저장방식)에 따라 다양한 검색 결과물 만들어낼 수 있음
문자열 매칭, 검색 알고리즘
Rabin-Karp Algorithm, KMP(Knuth-Morris-Pratt) Algorithm, Boyer-Moore-Horspool Algorithm
velog.io
- Web Application Server( Backend Server ) + Logstash + ElasticSearch
LogStash (로그스태시): LogStash는 실시간 파이프라인 기능을 갖춘 오픈 소스 데이터 수집 엔진. 다양한 범위의 input, output, filter를 통해 많은 유형의 이벤트를 변환 할 수 있으며, 데이터 수집 프로세스를 단순화
즉, LogStash는 별도의 조회 시스템이라고 생각하면 된다
- WAS(BE server)에서 직접 ElasticSearch에 저장하는 것이 아니라 Logstash를 통해 MySQL의 데이터를 ElasticSearch로 동기화 수행(ElasticSearch에는 컨텐츠 중심 데이터를 저장)
- ElasticSearch에 존재하지 않는 신규 데이터를 조회한 다음에 ElasticSearch에 저장시켜줌
- ElasticSearch 서비스 장애가 발생해 데이터 누락, 혹은 손실이 발생하더라도 MySQL에 저장된 데이터 기반으로 복구 가능
- 사용자는 ElasticSearch에 저장하는 시간 동안 Mysql에 있는 데이터를 조회할 수 없음 (절대 실시간이 될 수 없다.)
- 실시간으로 조회해야하는 경우에는 WAS(BACKEND) + Mysql + ElasticSearch를 사용해야 한다. 혹은 Logstash의 주기 설정을 짧게 가져가면 실시간에 근접하게 동작시킬 수 있음.
7. 파일 저장 기능 제공 서비스
- Web Application Server( Backend Server )
- 구동되는 서버 자체에 파일 저장하는 방식. 해당 서버의 저장소에 문제 생기면 파일 유실 가능
- 서버 뻑나면 이제 데이터 다 날라감 데이터 어떻게 관리할건지 꼭 규칙이 있어야함
- 언제든 원본 파일을 다른 저장소에서 복구할 수 있을 때 사용
- 서버에서 파일 Load해서 임의의 비즈니스 로직 처리할 때 빠른 처리를 위해 사용
- Web Application Server( Backend Server ) + CDN
- 컨텐츠 관리하는 네트워크 공간인 CDN서버에 파일을 업로드(수동 업로드)하고 링크를 전달받아 활용
- 파일을 저장하면 내가 언제든지 접속해서 사용할 수 있는 링크
- 별도 시스템을 통해 올려진 파일의 링크만 관리해주면 되기 때문에, 비교적 짧은 시간에 구현 가능
- Web Application Server( Backend Server ) + NFS(NAS, glusterFS, ...)
- WAS가 구동되는 서버에 별도의 저장소서버(NAS, glusterFS..) 공간 네트워크 통해 마운트 시켜 해당 경로에 파일 저장시키는 방식
- 서버 자체에 파일을 저장하는 방식이지만, 실제 저장은 네트워크를 통해 마운트되어 있는 저장소 서버에 저장
- 물리/논리적으로 분리된 WAS(BACKEND) 여러대가 하나의 저장소와 마운트되도록 구성이 가능하기 때문에 파일 동기화 이슈가 자연스럽게 해결 가능
728x90