1. 시작 계기

다시 취업을 준비하면서 이력서와 포트폴리오에 갱신이 필요함을 크게 느꼈다. 기존에 진행했던 프로젝트는 기술적으로 협업적으로 내가 봐도 크게 매력있다고 생각하지 않아서 프로젝트를 하나 더 해야겠다 싶었다.

 

가장 고민이 되었던 건 팀 프로젝트와 개인 프로젝트 중 어떤 방식으로 프로젝트를 진행할 것이었다. 팀 프로젝트에 합류해서 협업 능력과 체계적으로 개발을 할 수 있지만 지금까지 경험상 여럿이 같이 진행하는 만큼 일정이 빠그라지는 상황도 자주 발생하기도 하고, 회사에서 개발 업무를 하면서 아직 협업하기에는 개인 실력이 많이 부족하다고 생각해 개인 능력을 키우는 것이 더 필요하다고 생각했다. 그래서 삽질을 하더라도 혼자서 해보는 경험도 나쁘지 않을 것이라 생각해 개인 프로젝트를 진행해야겠다고 결정했다.

 

이전에 부트캠프에서 개인 프로젝트로 회원가입, 로그인, CRUD 같이 기본적인 서버 기능들은 구현해 놓은 프로젝트가 있어서 여기에 살을 더 붙이는 쪽으로 프로젝트 방향성을 잡았다. 프로젝트 테마는 가계부이다. 서버를 더 발전시킬 수 있으면 백엔드 개발자로서는 더 나을 수 있긴 하겠지만, 이력서와 포트폴리오를 면접관에게 어필하기 위해서는 일단 가시적인 결과물이 있으면 설득에 더 용이할 것이라 생각해 화면을 추가로 구현하기로 했다. html, css, 부트스트랩 정도는 조금은 알지만 javascript는 아예 몰랐기 때문에 막막하긴 했지만 일단 시작했다. 추가로 백엔드 개발자이지만, 프론트 관련해서 어느정도 숙지는 필요하다고 생각했기에 이 기회에 프론트 관련해서 뭔가를 만들어 보는 것도 괜찮겠다 싶었다.

 

2. 기획

2-1. 프로젝트 주제

사용자가 지출 내역을 직접 입력하고 1달/1년 단위로 카테고리별로 얼마를 썼는지 지출내역을 보여주는 가계부 프로젝트

 

2-2. 소프트웨어 구조

2-3. 기술스택

[FrontEnd]

HTML, CSS, BootStrap, Jquery, JavaScript

 

[BackEnd]

Java8, SpringBoot, Spring Data JPA, Spring Security, WebSocket, JWT, MySQL, Redis, Junit5, Mockito

 

[Tool]

Git/Github

 

2-4. 요구사항

[회원가입]

  • 입력 내용
    • 이메일
      • 이메일 형태의 값만 입력 가능
      • 한번 설정하면 수정 불가능
      • 이메일 중복 불가능
    • 이메일 인증
      • 인증키는 6자리의 임의의 숫자
      • 인증 이메일 전송 후 3분 이내로 인증키 입력
      • 이메일 인증 성공시 24시간 안에 회원가입 가능
    • 비밀번호
      • passwordEncoder로 암호화돼서 저장
    • 이름
      • 이름 중복 가능

[로그인]

  • 스프링 시큐리티와 JWT를 이용해서 구현
  • 입력 내용
    • 아이디
    • 비밀번호
  • Cookie에 access token 담아서 진행(유효시간은 30분)

 

[사용자]

  • 사용자 정보 조회
    • 사용자 본인만 가능
    • 이름
    • 이메일
    • 비밀번호 수정 가능한 버튼
    • 현재시점의 month와 설정한 예산
  • 사용자 정보 재설정
    • 이름 변경 가능
    • 비밀번호 변경 가능
      • 해당 기능은 별도의 기능으로 분리
    • 해당 month의 예산 변경 가능
      • 숫자 0이상이어야 함
    • 이메일 재설정 불가능
  • 회원 탈퇴
    • 본인만 탈퇴 가능
    • soft delete 형식으로 회원 삭제
      • 회원 테이블 role 컬럼의 값 DELETE로 변경 -> role != DELETE인 회원 체크 로직 필요

 

[예산]

  • 예산 저장
    • 사용자가 목표 예산 직접 설정
    • 매월 1일 이후 설정 가능
  • 예산 수정
    • 계정주만 변경 가능
    • 사용자 정보에서 예산 수정 가능
  • 예산 삭제
    • 예산은 해당 앱에서 필수인 필드이므로 삭제 하지않는 것으로 구현할 예정
  • 알림 전송 - 웹소켓
    • 달력에서 ‘예산 알림 받기’ 버튼 클릭시 요청한 월에 대한 예산 상태 알림
    • [추후 일정 시간에 자동 알림 구현 예정]

 

[매일 지출내역]

  • 지출 내역 입력 및 저장
    • 본인 페이지 외에 지출 내역 추가 불가능
    • 지출 금액을 입력한다
    • 결제 수단을 입력한다
    • 상점 이름 입력(ex. 스타벅스, 스타벅스 서판교점,,,)
    • 지출 카테고리는 1개 선택가능
    • 지출내역에 대한 메모 입력 가능
      • 일반 문장 형태(ex. ‘배고파서 편의점’)
    • 객체 생성 시간은 자동 입력
  • 지출 내역 조회
    • 날짜에 해당하는 지출내역 리스트 형태로 조회 가능
      • 조회 할때마다 DB쿼리 날리면 부하가 올 수 있으므로 캐시 이용
  • 지출 내역 수정
    • 본인 페이지 외에 지출 내역 수정 불가능
    • 지출 내역 선택 시 수정할 수 있다
      • 지출 금액, 결제 수단, 상점 이름, 카테고리 ,메모, 지출 날짜 수정 가능
  • 지출 내역 삭제
    • 본인 페이지 외에 지출 내역 삭제 불가능

 

[매일 지출내역 검색]

  • 키워드로 검색 가능
    • 거래처와 메모에 대응되는 매일 지출내역 리스트 조회
    • 해시태그로 구현은 지금 상황에서는 어려워 메모로 변경

 

[카테고리]

  • 카테고리 id로 식별하므로 카테고리명 중복 가능
  • 카테고리 추가
    • 한글/알파벳/숫자/특수기호 모두 사용 가능
  • 카테고리 수정
  • 카테고리 삭제
    • 사용자만 카테고리 삭제 가능
    • 카테고리명 삭제 시 관련된 지출내역의 카테고리명을 “미분류”으로 변경
  • 카테고리 조회
    • 전체 리스트만 조회
      • 리스트에는 각 카테고리의 이름이 나열되어있음

 

[Monthly 지출내역 통계]

  • 한달치 매달 지출 내역을 합산해 카테고리 별로 분류해서 조회
    • 이번달을 조회할 때와 지난달을 조회할 때 로직 구분해서 DB 부하가 좀 더 적은 방향으로 구현
    • 예) 12월 총 지출 : 50만원, [식비 : 18만원, 카페 : 8만원 ,,, ]
  • 매월 1일 0시 정각에 지난달 데이터 저장
    • 한달 총 지출 금액을 회원별로 나눠서 저장
    • 카테고리별 한당 총 지출 금액을 회원별로 나눠서 저장

 

[Yearly 지출내역 통계]

  • 한 해의 모든 카테고리 별 지출내역을 모두 합산해서 조회
    • 결과는 내림차순으로 출력
    • 예) 1위 식비(xxx만원), 2위 쇼핑(xxx만원),,

gRPC란?

구글에서 개발한 어느 환경에서도 실행할 수 있는 최신 오픈 소스 고성능 RPC 프레임워크 

 

 

RPC(Remote Procedure Call)

프로세스 간 통신 기술. 별도의 원격 제어를 위한 코딩 없이 다른 주소 공간에서 함수나 프로시저를 실행할 수 있게 해준다.

 

MSA 구조의 서비스에서 모듈 간의 언어에 구애받지 않고 원격에 있는 프로시저를 호출해 고유 프로그램의 개발에 집중할 수 있게 해주는 기술이다. (MSA의 각 모듈 간 통신을 원활하게 해주는 기술)

 

gRPC를 이용하면 원격에 있는 애플리케이션의 메서드를 로컬 메서드인 것처럼 직접 호출할 수 있기에 애플리케이션과 서비스를 보다 쉽게 만들 수 있다. 

 

gRPC 서버(Proto Response), gRPC 클라이언트(Proto Request 전송 부분)

 

Stub

서버와 클라이언트는 서로 다른 주소 공간을 사용하므로 함수 호출에 사용된 매개변수를 꼭 변환해줘야 한다. 그렇지 않으면 메모리 매개 변수에 대한 포인터가 다른 데이터를 가리키게 된다.

 

클라이언트 stub : 함수 파라미터 변환 -> 함수 실행 -> 서버 response 변환 담당

서버 stub : 클라이언트가 전달한 매개변수 역변환, 함수 실행 결과 변환 담당

 

 

 

Protocol Buffer

gRPC에서는 IDL(Interface Definition Language)로 protocol buffer를 사용한다. 

 

protocol buffer : 직렬화 데이터 구조. Json, XML

 

proto file : 직렬화하려는 데이터 구조 정의. 특정 언어에 대한 종속성이 없는 데이터 타입. 프로토 버퍼는 여러 프로그래밍 언어를 지원하기 때문.

프로토콜 버퍼 데이터는 ‘이름-값’의 쌍을 포함하는 작은 논리적 레코드인 메시지로 구성됨

 

proto file -> protoc 컴파일로 컴파일 -> 언어에 맞는 데이터 클래스 생성

만들어진 클래스는 각 필드를 위한 접근자 뿐 아니라 

전체 구조 -> 바이트 (직렬화)

바이트 -> 전체 구조 (파싱) 

메서드 제공

 

 

 

gRPC 특징

높은 생산성과 다양한 언어 및 플랫폼 지원

Protocol Buffer의 IDL만 정의하면 서비스와 메시지에 대한 소스코드가 자동으로 생성되고 데이터를 주고 받을 수 있따.

 

HTTP/2 기반 양방향 스트리밍

 

성능 이점

gRPC는 HTTP/2 레이어 위에서 Protocol Buffers를 이용해 직렬화된 바이트 스트림으로 통신해 JSON 기반 통신보다 더 가볍고 통신 속도가 빠르고, latency 감소, 더 많은 트래픽 처리 가능

 

 

-> 속도 빠르고, 많은 트래픽 처리 가능하며, 편리하다

서킷 브레이커란?

서킷 브레이커가 뭔가 하니 두꺼비 집에서 과부하, 단로, 누전으로부터 전기 회로를 보호하는 안전장치다.

 

서킷 브레이킹은 분산 시스템에서 서비스 간의 의존성가용성을 보장하기 위한 패턴 중 하나.

 

서킷 브레이킹 동작 방식

1. 장애 서비스 일시적으로 엔드포인트에서 제거

서비스 장애 상황 시 호출이 지연/실패할 경우, 서킷 브레이커는 장애 서비스를 일정 기간 동안 엔드포인트에서 제거하고 서비스의 상태가 정상으로 회복되기를 기다린다(모니터링). 

 

2. 장애 서비스로의 지연/장애 현상 전파 방지

장애 서비스에 대한 호출은 다른 서비스로 라우팅 되게 함으로써, 서비스 간의 지연 또는 장애 현상이 전파되는 것을 방지할 있게 해준다. 장애가 전체 시스템에 영향 최소화

 

서비스 메시

애플리케이션 서비스 간 모든 통신을 처리하는 소프트웨어 계층

애플리케이션이 확장되고, 마이크로서비스의 수가 증가함에 따른 성능 모니터링 문제 해결

서비스 간 연결을 관리하기 위해 모니터링, 로깅, 추적, 트래픽 제어와 같은 기능 제공

인프라 개발자, 서비스 개발자 -> 주로 인프라 개발자에게 서비스 메시는 이점을 준다

 

플랫폼 레이어(인프라 쪽)에 구성되는 네트워크 제어 방법

애플리케이션 트래픽을 관리, 추적 및 보안성을 강화하기 위해 사용

 

마이크로서비스 간 통신 문제 해결

 

대표 기능 -> 애플리케이션 트래픽 관리, 관찰 가능성, 보안

 

데이터 플레인, 컨트롤 플레인 두 개의 컴포넌트로 구성됨

데이터 플레인 : 애플리케이션 사이에 있는 프록시(envoy 서비스로 구성, 서비스와의 프록시 호출 담당) 네트워크로 구성됨, 서비스 메시의 모든 서비스에 대한 모든 인바운드 및 아웃바운드 트래픽 관장.

컨트롤 플레인 : 프록시에게 수행할 작업을 알려주고 메시를 작동하는 사람을 위한 인터페이스 제공, 서비스 검색(discovery), TLS 인증서 발급, 메트릭 집계 등 데이터 플레인이 작동하는데 필요한 컴포넌트 제공

컨트롤 플레인 <-> 프록시 <-> 애플리케이션

 

 

서비스 메시 툴

Istio

 

문제점

  • 프록시 자원은 인프라와 관련해 리소스를 소비하며 네트워크 지연을 발생시킴. 
  • 프록시 사용 서비스 개수 증가 -> 메모리, CPU 소비량 증가, 커넥션 풀 수 증가(point of failure도 증가)
  • 코드 수정 가능성(http 설정, 라이브러리 변경)
  • 트러블 슈팅이 어렵다

 

대안

서킷 브레이커(Spring Cloud for Kubernetes), Observability 대안(Jaeger, Zipkin 같은 분산 트레이싱 도구) 

 

Reference

https://aws.amazon.com/ko/what-is/service-mesh/

https://www.samsungsds.com/kr/insights/service_mesh.html

스로틀링(throtling)

 

스로틀링이란?

스로틀링은 전자 기기의 CPU, GPU 등이 지나치게 과열될 때 기기의 손상을 막고자 전압을 조절하는 것을 의미한다. 즉, 최악의 상황을 막기 위해 요청 개수나 속도를 조절하는 것을 의미한다. 

 

서버가 처리할 수 있는 요청보다 월등히 많은 요청을 받게되면 서버가 터질 수도 있기 때문에 서버로 가는 요청 수를 조절해 이를 방지하는 방법이다. 

 

너무 많은 요청으로 인해 API가 가득 차는 것을 방지하기 위함 -> API Gateway 레이어에서 API 요청 조절

서버 순간 처리 요청 수를 제한하고 바로 429 Too Many Requests 응답을 주면 클라이언트도 빠르게 파악 및 대응이 가능하고, 서버도 요청 수를 조절 할 수 있다. -> 요청 스레드가 밀려서 전체 사용자 응답 느려지는 것 방지 가능

 

 

API Gateway

MSA 패턴 중 하나로, API를 사용하는 클라이언트와 서버 사이에 위치해 다양한 목적으로 사용됨

  • 인증 및 권한 부여
  • 서비스 검색 통합
  • 속도 제한
  • 로깅을 반영 추적

 

대기열

서버가 처리 가능한 것을 넘은 요청이 올 때, 해결방법은 두 가지이다.

서버 자체의 크기 늘리기 or 서버의 처리량을 줄이는 것(대기열)

 

대량 접속이 동시다발적으로 요청될 경우 서버 및 시스템에 부하가 유발되어 사이트 단절 발생 가능.

대기열 시스템은 순차적 접속을 통해 부하가 유발되지 않도록 해 대규모 트래픽에도 흔들림 없이 사이트 운영을 도와주는 시스템이다.

 

 

활용 사례 

지마켓, 옥션은 Redis 이용해 RedCarpet이라는 대기열 아키텍처를 도입 -> 어렵다,,,

 

 

Reference

스로틀링

https://12bme.tistory.com/504

https://rene-or-irene.tistory.com/22

 

대기열

https://dev.gmarket.com/46

+ Recent posts