Link
기간 | 2024.11 ~ 2024.12 |
구성원 | BE 1명 | FE 1명 | ML 1명 |
담당 역할 | PM / BE / DESIGN |
BE 기술 스택 | Spring Boot, Spring Security, JPA, Fast API, AWS EKS, Helm, Github Actions, Docker, Helm, FluxCD, Kakao API, MySQL, Redis, Kafka, Zookeeper, Netty, Spring MVC, WebFlux, gRPC, GraphQL |
팀원 평가 | 스케줄링, 마스터키 |
프로젝트
Plant(환경/사회) + Amplify(통합)
=> 가치있는 결제의 시작, 플랜티파이(PlantiFy)
기능
•
Pay - 페이 결제 시스템
◦
PlantiPay: 나만의 페이, 피피 / 한 번의 터치로 한 번의 결제
•
Funding - 온라인 펀딩 참여 / 내 참여 내역
◦
PlantiFunding: 손쉬운 기분 펀딩, 피프 / 쌓여있는 포인트로 언제 어디서나
•
Forest - 캐시로 나만의 숲 꾸미기
◦
PlantiForest: 나만의 숲 꾸미기, 피포 / 자유롭게 꾸미는 내 손 안의 숲
•
Card - 카드 추천 서비스 / 더 큰 혜택 찾기
◦
PlantiFit: 다양한 혜택 한 번에, 피핏 / 숨겨진 카드 혜택까지 모두 모아
•
Chat - 사용자 맞춤 기부 펀딩 추천
◦
PlantiPick: 기부 도우미, 피픽 / 나눔의 길을 안내하는 길잡이
구현
문서
1. 기능명세서
2. API 명세서
3. User Flow
4. ERD
5. Sequence Diagram - 결제 로직
6. 개발 아키텍처
개발(MSA) - Spring Security, Jasypt
플랜티파이 서비스
1.
auth service(카카오 로그인, JWT): 로그인, 유저 검증
2.
admin service: 관리자 페이지
3.
item service: 숲 꾸미기에 사용되는 아이템
•
Item을 구매하면 MyItem, 내 아이템 중 사용하면 UsingItem(GraphQL)
4.
cash service: 아이템을 결제할 수 있는 캐시로 기부 펀딩에 참여하면 캐시를 지급받음
5.
funding service: 현재 진행 중인 기부 펀딩을 크롤링하고 펀딩
6.
chat service(gRPC, WebFlux + Netty)
: 채팅 AI 모델 ←gRPC→ SpringBoot 서버 ←WebSocket→ 클라이언트
7.
apiUser service: 결제 API를 사용 중인 유저(정산 받을 API 유저) 서비스
8.
notification service(SSE): 결제 완료 시 유저에게 보내는 알람
9.
card service(FastAPI): 유저의 카드를 추가, 삭제하고 혜택을 보여줌
결제 서비스 - 2PC, 분산락(Redis)
1.
pay service: Account, Pay, Point 관련 서비스
a.
Account: Pay에 연결하는 계좌로 10,000원 단위로 돈 충전할 수 있음
b.
Pay
•
한 사람 당 하나의 Pay만 가질 수 있으며 한 개 이상의 계좌가 존재해야 함
•
Pay 생성 시 랜덤으로 Pay 번호 부여하고 5년 기간 동안 사용 가능
•
결제, 취소, 환불 구현
•
transaction ID 기반으로 결제 관련 검증용 JWT 보안 토큰 발급
c.
Point
•
결제 완료 시 포인트 0.05% 적립
•
포인트 사용 시 실 결제에서 포인트 사용 금액 제외하고 결제
2.
transaction service
•
결제 요청 시 transaction에 pending, 실 결제 완료 시 success로 업데이트
•
5분 동안 pending이면 failed로 업데이트
•
결제 취소 요청 시 cancel로 업데이트
•
결제 관련 작업 후 Kafka 활용해 notification service, pay service로 보내 알림과 포인트 적립
3.
payment service: 실제 결제가 완료되는 서비스
•
최종적으로 잔액 확인 후 실제 결제 진행
CI/CD 파이프라인 구축 및 배포
Github Actions, Docker, Helm, FluxCD, AWS EKS
회고
문제 상황 및 해결
•
결제 시스템(Pay-Transaction-Payment)
◦
결합도
◦
외부 클라이언트
◦
실제 결제할 때 한 번 더 확인?
◦
포인트 및 실결제
◦
계좌 예외 처리
◦
취소 및 환불
•
Acitivity History
•
관리자
•
코드 분리
•
아이템(GraphQL)
•
채팅방(gRPC, WebFlux + Netty)
신경 쓴 부분
커스텀 예외처리를 활용하여 클라이언트에 정확한 에러 메시지 전달
외부 프로젝트에 결제 API 제공
외부 프로젝트에도 결제 API를 제공하여 실제 페이 서비스를 이용하는 것처럼 결제하고 결제 내역에서 확인할 수 있도록 함
기술 사용 이유
GraphQL
•
REST보다 네트워크 트래픽이 감소하고 단일 mutation으로 아이템 생성, 업데이트, 삭제를 한 번에 처리
•
subscription 기능으로 실시간으로 ui에 반영할 수 있음
2PC
•
조정자가 모든 참여 노드 제어 → 전체 트랜잭션 로직 중앙에서 관리(트랜잭션 상태 지속적 관리)
트랜잭션 원자적 처리 → 전체 성공/실패
⇒ 결제는 데이터의 정확성과 일관성이 중요
•
결제 시스템: Pay, Transaction, Payment 서버로 구성되고 MySQL, Pay 서버가 Coordinator 역할
Redis 분산락
여러 서버가 자원에 동시에 접근하게 되면 데이터가 불일치하거나 동일 사용자에 대한 중복 결제 요청이 있을 수 있는데 이를 방지하기 위해 사용
•
Redis의 싱글 스레드 활용락
◦
기본 명령어(SET NX, PX, DEL)를 활용해 구현
Kafka
•
이벤트 기반 메시징 시스템으로 결제 완료 이벤트를 비동기적으로 처리할 수 있음
•
3개의 서비스가 이를 구독해 하나의 이벤트를 여러 서비스가 독립적으로 처리할 수 있어 확장성 높음
◦
결제 관련 작업 후 notification, pay, cash 서버로 보내 알림, 포인트 적립, 캐시 지급
gRPC
•
언어에 독립적이고 protocol buffers로 직렬화하여 데이터 전송 속도가 빠름
•
AI 모델과의 스트리밍 통신을 비동기로 처리하고, 응답을 실시간으로 전송
WebFlux + Netty
•
논블로킹과 병렬 처리 지원
•
비동기 처리해서 사용자가 여러 개의 요청을 보냈을 때 병렬로 처리해서 처리 속도를 높임
SSE(Server-Send Event)
•
결제 완료 알람은 서버에서 클라이언트로 단방향 데이터 전송하는 통신이므로 양방향 통신 기능이 필요 없다고 생각