HOME
home
Team
home

J4JG

ย ๋‚ด๊ฐ€ ๊ธฐ์—ฌํ•œ ๋ถ€๋ถ„

โ€ข
API Gateway๋ฅผ ํ†ตํ•ด WebFlux ๋ฐฉ์‹์œผ๋กœ ๋กœ๊ทธ์ธ ์š”์ฒญ ์ฒ˜๋ฆฌํ•˜์—ฌ ์„œ๋น„์Šค ํ™•์žฅ์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜์„ฑ ํ–ฅ์ƒ
โ€ข
Google๊ณผ Kakao ์†Œ์…œ ๋กœ๊ทธ์ธ ์—ฐ๋™์œผ๋กœ ๊ฐ„ํŽธ ๋กœ๊ทธ์ธ ๊ธฐ๋Šฅ ์ œ๊ณต
โ€ข
CI/CD ํŒŒ์ดํ”„๋ผ์ธ ๊ตฌ์ถ•์œผ๋กœ ์ž๋™ํ™”๋œ ๋นŒ๋“œ, ํ…Œ์ŠคํŠธ, ๋ฐฐํฌ ํ”„๋กœ์„ธ์Šค๋ฅผ ๋„์ž…ํ•˜์—ฌ ๊ฐœ๋ฐœ ํšจ์œจ์„ฑ ๊ทน๋Œ€ํ™”
โ€ข
MultiModule ์„ค๊ณ„๋ฅผ ํ†ตํ•ด ์ฝ”๋“œ ์žฌ์‚ฌ์šฉ์„ฑ ๋ฐ ํ”„๋กœ์ ํŠธ ๊ด€๋ฆฌ ํšจ์œจ์„ฑ ๊ฐœ์„ 
โ€ข
AWS ์ธํ”„๋ผ ์„ค์ • ๋ฐ ๋ฐฐํฌ ์ž๋™ํ™”๋ฅผ ํ†ตํ•ด ์•ˆ์ •์ ์ธ ์„œ๋น„์Šค ์šด์˜ ํ™˜๊ฒฝ ๊ตฌ์ถ•
โ€ข
Prometheus์™€ Grafana๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ JVM ๋ฐ Nginx ๋ชจ๋‹ˆํ„ฐ๋ง ์‹œ์Šคํ…œ์„ ๊ตฌ์ถ•ํ•˜์—ฌ ์„œ๋ฒ„ ์„ฑ๋Šฅ์„ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋ถ„์„

ย ์‚ฌ์šฉ ๊ธฐ์ˆ 

โ€ข
DataBase
โ—ฆ
MySQL / Redis / ElasticSearch
โ€ข
BackEnd
โ—ฆ
Java / Spring Boot / Spring Data JPA / Spring Security / Spring Cloud
โ€ข
API
โ—ฆ
Kakao Login / Google Login / Wanted / Swagger
โ€ข
Monitoring
โ—ฆ
LogStash / Prometheus & Grafana
โ€ข
Software Architecture Pattern
โ—ฆ
Hexagonal Architecture
โ€ข
FrontEnd
โ—ฆ
HTML / CSS / JavaScript / Vue.js
โ€ข
DevOps
โ—ฆ
GitHub Actions / AWS(Elastic Beanstalk, EC2, RDS, S3, Route53)
โ€ข
Collaboration
โ—ฆ
GitHub / Slack / Notion / Figma / Miro / Jira

System Architecture

J4JG System Architecture

ํŠธ๋Ÿฌ๋ธ” ์ŠˆํŒ… 1

๋ฌธ์ œ ๋ฐฐ๊ฒฝ

Spring WebFlux ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ OAuth2 ์ธ์ฆ์„ ์„ค์ •ํ•˜๋Š” ๊ณผ์ • ์ค‘, ์„œ๋ธ”๋ฆฟ ๊ธฐ๋ฐ˜์˜ HttpSecurity ์„ค์ •์„ ์‚ฌ์šฉํ•˜์—ฌ ClientRegistrationRepository ๋นˆ์„ ์ฐพ์„ ์ˆ˜ ์—†๋‹ค๋Š” ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

๋ฆฌ์•กํ‹ฐ๋ธŒ ํ™˜๊ฒฝ์— ๋งž๊ฒŒ ์„ค์ •์„ ๋ณ€๊ฒฝํ•˜๊ธฐ ์œ„ํ•ด SecurityWebFilterChain์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฆฌ์•กํ‹ฐ๋ธŒ ๋ณด์•ˆ ์„ค์ •์„ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ์กด์˜ ์„œ๋ธ”๋ฆฟ ๊ธฐ๋ฐ˜ ๋ณด์•ˆ ์„ค์ •์ธ HttpSecurity๋ฅผ ์ œ๊ฑฐํ•˜๊ณ , ServerHttpSecurity๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฆฌ์•กํ‹ฐ๋ธŒ ๊ทœ์น™์„ ์ •์˜ํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ฐœ์„  ๊ฒฐ๊ณผ

๋ฆฌ์•กํ‹ฐ๋ธŒ ๋ณด์•ˆ ์„ค์ •์œผ๋กœ ๋ณ€๊ฒฝํ•œ ํ›„, ClientRegistrationRepository์™€ ๊ด€๋ จ๋œ ์˜ค๋ฅ˜๊ฐ€ ํ•ด๊ฒฐ๋˜์—ˆ์œผ๋ฉฐ, OAuth2 ๋กœ๊ทธ์ธ ๋ฐ JWT ํ•„ํ„ฐ ์ ์šฉ์ด ์ •์ƒ์ ์œผ๋กœ ์ž‘๋™ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

ํ•ด๋‹น ๊ฒฝํ—˜์„ ํ†ตํ•ด ์•Œ๊ฒŒ ๋œ ์ 

๋ฆฌ์•กํ‹ฐ๋ธŒ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ๋Š” ์„œ๋ธ”๋ฆฟ ๊ธฐ๋ฐ˜์˜ ๋ณด์•ˆ ์„ค์ •์„ ์‚ฌ์šฉํ•˜์ง€ ๋ง์•„์•ผ ํ•˜๋ฉฐ, SecurityWebFilterChain์„ ํ†ตํ•ด ๋ฆฌ์•กํ‹ฐ๋ธŒ ๋ณด์•ˆ์„ ๊ตฌ์„ฑํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ๋ฐฐ์› ์Šต๋‹ˆ๋‹ค.
๋ฆฌ์•กํ‹ฐ๋ธŒ ์„ค์ •์„ ์œ„ํ•œ SecurityConfig ํด๋ž˜์Šค
HttpSecurity๋ฅผ ์ œ๊ฑฐํ•˜๊ณ , ServerHttpSecurity๋ฅผ ์‚ฌ์šฉ

ํŠธ๋Ÿฌ๋ธ” ์ŠˆํŒ… 2

๋ฌธ์ œ ๋ฐฐ๊ฒฝ

๋กœ๊ทธ์•„์›ƒ ์‹œ Redis์— ์ €์žฅ๋œ RefreshToken์ด ์‚ญ์ œ๋˜์ง€ ์•Š๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.
๋ฌธ์ œ์˜ ์›์ธ์€ CustomLogoutSuccessHandler์—์„œ RefreshToken์„ Redis์—์„œ ์‚ญ์ œํ•˜๋Š” ๋กœ์ง์ด ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š์•„์„œ์˜€์Šต๋‹ˆ๋‹ค. ๋กœ๊ทธ์•„์›ƒ ์‹œ RefreshToken์˜ providerId๋ฅผ ํ™œ์šฉํ•ด Redis์—์„œ ํ•ด๋‹น ํ† ํฐ์„ ์‚ญ์ œํ•˜๋Š” ๋ถ€๋ถ„์ด ์ œ๋Œ€๋กœ ํ˜ธ์ถœ๋˜์ง€ ์•Š๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

๋กœ๊ทธ์•„์›ƒ ์ฒ˜๋ฆฌ ์‹œ ๋ฆฌํ”„๋ ˆ์‹œ ํ† ํฐ์„ ์‚ญ์ œํ•˜๋Š” CustomLogoutSuccessHandler์—์„œ Redis์— ์ €์žฅ๋œ ํ† ํฐ์„ ์‚ญ์ œํ•˜๋Š” ๋ฐฉ์‹์— ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ฟ ํ‚ค์—์„œ ๋ฆฌํ”„๋ ˆ์‹œ ํ† ํฐ ๊ฐ’์„ ์ถ”์ถœํ•œ ๋’ค, ํ•ด๋‹น ๊ฐ’์„ ์ด์šฉํ•˜์—ฌ Redis์—์„œ ์‚ญ์ œํ•˜๋„๋ก deleteByProviderId ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ providerId๋ฅผ ์ง์ ‘ ์‚ญ์ œํ•˜์ง€ ์•Š๊ณ , ํ† ํฐ ๊ฐ’์„ ์ œ๋Œ€๋กœ ๋งค์นญํ•ด Redis์—์„œ ์ •ํ™•ํžˆ ์‚ญ์ œํ•˜๋Š” ๋กœ์ง์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ฐœ์„  ๊ฒฐ๊ณผ

๋กœ๊ทธ์•„์›ƒ ์‹œ Redis์—์„œ ๋ฆฌํ”„๋ ˆ์‹œ ํ† ํฐ์ด ์ •์ƒ์ ์œผ๋กœ ์‚ญ์ œ๋˜์—ˆ์œผ๋ฉฐ, ๋งŒ๋ฃŒ๋œ ํ† ํฐ๋„ Redis์—์„œ ์ž๋™์œผ๋กœ ์ œ๊ฑฐ๋  ์ˆ˜ ์žˆ๋„๋ก ๊ธฐ๋Šฅ์ด ์ ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

ํ•ด๋‹น ๊ฒฝํ—˜์„ ํ†ตํ•ด ์•Œ๊ฒŒ ๋œ ์ 

Redis์—์„œ ํ‚ค ๊ธฐ๋ฐ˜ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ญ์ œํ•  ๋•Œ, ์ •ํ™•ํ•œ ํ‚ค๋ฅผ ํ™œ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
CustomLogoutSuccessHandler์—์„œ Redis์— ์ €์žฅ๋œ ํ† ํฐ์„ ์‚ญ์ œ

๐Ÿซก ํšŒ๊ณ 

โ€œ๊ธฐ์ˆ ์  ๋„์ „๊ณผ ์ง€์†์ ์ธ ์„ฑ์žฅ ๊ทธ๋ฆฌ๊ณ โ€ฆ ์ •๋ฆฌ์˜ ์Šต๊ด€ํ™”โ€
J4JG(์žกํฌ์ž๊ธฐ): Follow Your Dream ํ”„๋กœ์ ํŠธ๋Š” ๊ธฐ์ˆ ์  ๋„์ „๊ณผ ํŒ€์›Œํฌ๋ฅผ ํ†ตํ•ด ํฐ ์„ฑ๊ณผ๋ฅผ ๋‚ผ ์ˆ˜ ์žˆ์—ˆ๋˜ ์ค‘์š”ํ•œ ๊ฒฝํ—˜์ด์—ˆ์Šต๋‹ˆ๋‹ค. API Gateway๋ฅผ ํ™œ์šฉํ•œ WebFlux ๋ฐฉ์‹์œผ๋กœ ๋กœ๊ทธ์ธ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๊ณ , Google๊ณผ Kakao ์†Œ์…œ ๋กœ๊ทธ์ธ ์—ฐ๋™์„ ํ†ตํ•ด ๊ฐ„ํŽธํ•œ ์‚ฌ์šฉ์ž ์ ‘๊ทผ์„ ์ œ๊ณตํ–ˆ์œผ๋ฉฐ, CI/CD ํŒŒ์ดํ”„๋ผ์ธ์„ ๊ตฌ์ถ•ํ•˜์—ฌ ์ž๋™ํ™”๋œ ๋นŒ๋“œ ๋ฐ ๋ฐฐํฌ ํ”„๋กœ์„ธ์Šค๋ฅผ ๋„์ž…ํ•จ์œผ๋กœ์จ ๊ฐœ๋ฐœ ํšจ์œจ์„ฑ์„ ๊ทน๋Œ€ํ™”ํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ, Prometheus์™€ Grafana๋ฅผ ์‚ฌ์šฉํ•ด JVM ๋ฐ Nginx ๋ชจ๋‹ˆํ„ฐ๋ง ์‹œ์Šคํ…œ์„ ๊ตฌ์ถ•ํ•˜์—ฌ ์„œ๋ฒ„ ์„ฑ๋Šฅ์„ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋ถ„์„ํ•˜๊ณ  ์•ˆ์ •์„ฑ์„ ๋†’์˜€์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด ํ”„๋กœ์ ํŠธ์—์„œ ๊นจ๋‹ฌ์€ ๋˜ ๋‹ค๋ฅธ ์ค‘์š”ํ•œ ์ ์€ ๋ฌธ์„œํ™”์™€ ๊ธฐ๋ก์˜ ์ค‘์š”์„ฑ์ž…๋‹ˆ๋‹ค. ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๋Š” ๋™์•ˆ ๋ชฉํ‘œ๋ฅผ ๋‹ฌ์„ฑํ•˜๋Š” ๋ฐ ์ง‘์ค‘ํ•˜๋Š๋ผ ๋งค ์ˆœ๊ฐ„ ๊ธฐ๋กํ•˜๊ณ  ์ •๋ฆฌํ•˜๋Š” ์Šต๊ด€์„ ๋“ค์ด์ง€ ๋ชปํ–ˆ๋˜ ๊ฒƒ์ด ์•„์‰ฌ์› ์Šต๋‹ˆ๋‹ค. ํ”„๋กœ์ ํŠธ์˜ ํ๋ฆ„๊ณผ ๊ธฐ์ˆ ์  ์„ ํƒ์„ ์ฒด๊ณ„์ ์œผ๋กœ ๊ธฐ๋กํ•˜๋Š” ์Šต๊ด€์ด ์žˆ์—ˆ๋”๋ผ๋ฉด, ์ถ”ํ›„ ์œ ์ง€๋ณด์ˆ˜๋‚˜ ์ง€์‹ ๊ณต์œ ์—์„œ ๋”์šฑ ํšจ์œจ์ ์ด์—ˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์•ž์œผ๋กœ๋Š” ์ด๋Ÿฌํ•œ ์Šต๊ด€์„ ๊ธธ๋Ÿฌ์„œ ๋”์šฑ ์ •๋ฆฌ๋œ ๋ฐฉ์‹์œผ๋กœ ํ”„๋กœ์ ํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.