DND 7๊ธฐ ํ๋ก์ ํธ (2022.08~)
- ํ์
- ํ๋กํ ์กฐํ ๋ฐ ์์
- ๋ง์ด ํ์ด์ง ์กฐํ (์ด๋ ๊ธฐ๋ก ์ ๋ณด, ํ์ ์ ๋ณด ๋ฑ)
- ์ด๋ ๊ธฐ๋ก ํํฐ ๊ด๋ฆฌ (๋ด ๊ธฐ๋ก ๋ณด๊ธฐ, ์น๊ตฌ ๊ธฐ๋ก ๋ณด๊ธฐ ๋ฑ)
- ์ด๋ ๊ธฐ๋ก ๋ฉ์์ง ์์
- ๋ฉ์ธ ํ๋ฉด ์กฐํ (๋ด ์์ญ, ์ด๋ฒ ์ฃผ ์์ญ, ์น๊ตฌ ์์ญ, ์ฑ๋ฆฐ์ง ์ ๋ณด, ์ฑ๋ฆฐ์ง ๋ฉค๋ฒ ์์ญ ๋ฑ)
- ์ฑ๋ฆฐ์ง (์ง์ธ๊ณผ ํจ๊ป ์ผ์ ๊ธฐ๊ฐ๋์ ์ด๋ ๊ธฐ๋ก์ ๊ณต์ ํ๋ฉฐ ๊ฒฝ์ํ๋ ๊ธฐ๋ฅ)
- ์ฑ๋ฆฐ์ง ์์ฑ ๋ฐ ์ด๋
- ์ฑ๋ฆฐ์ง ์๋ฝ, ๊ฑฐ์
- ์ฑ๋ฆฐ์ง ์ํ ๊ด๋ฆฌ
- ์ฑ๋ฆฐ์ง ์์๋ ์ง์ ๋ง์ถฐ ์งํ
- ์์์ผ 00์ ์ฑ๋ฆฐ์ง ์ข ๋ฃ
- ์ฑ๋ฆฐ์ง ์ฐธ์ฌํ๋ ์ฌ๋(์ฑ๋ฆฐ์ง ๋ฉค๋ฒ)์ ๋ํ ์ํ ๊ด๋ฆฌ ๋ฐ ์ฃผ์ต์ ๊ด๋ฆฌ
- ์ฑ๋ฆฐ์ง ์๊น ๊ณ์ฐ
- ์ํ ๋ณ ์ฑ๋ฆฐ์ง ๋ชฉ๋ก ์กฐํ
- ์ํ ๋ณ ์ฑ๋ฆฐ์ง ์์ธ ๋ชฉ๋ก ์กฐํ
- ์ฑ๋ฆฐ์ง ์งํ ๊ธฐ๊ฐ๋์ ๊ธฐ๋ก๋ ์์ญ ์กฐํ
- ์ฑ๋ฆฐ์ง ์ญ์
- ์ด๋ ๊ธฐ๋ก
- ์ด๋ ๊ธฐ๋ก ์์ฑ
- ์ด๋ ๊ธฐ๋ก ์กฐํ
- ๋ญํน
- ์ญ๋ ๋์ ์นธ ์ ๋ญํน ๊ณ์ฐ
- ์ด๋ฒ ์ฃผ ์์ญ ์ ๋ญํน ๊ณ์ฐ
- ๊ฑธ์ ์ ๋ญํน ๊ณ์ฐ
- ์น๊ตฌ
- ์น๊ตฌ ์ ์ฒญ ๋ฐ ์๋ต
- ์นด์นด์ค ์น๊ตฌ ๋ชฉ๋ก ์กฐํ
- ์นด์นด์ค ์น๊ตฌ ์ด๋ ๋ฉ์์ง ์ ์ก
- ์น๊ตฌ ์ญ์
- ์์น ๊ธฐ๋ฐ ์น๊ตฌ ์ถ์ฒ
- ํ์๊ฐ์
/๋ก๊ทธ์ธ
- ์นด์นด์ค, ์ ํ ์์ ๋ก๊ทธ์ธ ์ง์
- JWT ๊ธฐ๋ฐ ํ ํฐ ์ธ์ฆ
- ์นด์นด์ค ํ์ ์ ๋ณด ์กฐํ
- ๋ก๊ทธ์์
- ํ์ ํํด
- ํธ์ ์๋
- FCM ํ ํฐ ๊ด๋ฆฌ
- ํน์ ์ํฉ์์ ํธ์ ์๋ ์์ฒญ ๋ฐ ์๋ ๊ด๋ฆฌ
- HTTPS ์ง์
- Java 11 (OpenJDK 11)
- Spring boot 2.7.1
- ์์กด์ฑ ๊ด๋ฆฌ
- Auto Configuration
- Spring Security
- JWT ๊ธฐ๋ฐ ํ ํฐ์ ํ์ฉํ ์ธ์ฆ
- ExceptionEntryPoint๋ฅผ ํ์ฉํ ์์ธ ์ฒ๋ฆฌ
- Spring Data JPA
- ๊ฐ์ฒด ์ค์ฌ์ ORM ์ฟผ๋ฆฌ ํ์ฉ
- QueryDSL
- ์ปดํ์ผ ๋จ๊ฒ์์ ์ฟผ๋ฆฌ ์๋ฌ ๊ฒ์ถ
- ์ค๋ณต ์ฟผ๋ฆฌ ์ฌํ์ฉ์ ํตํด ์ ์ง๋ณด์์ ์ฉ์ดํ๋๋ก ํจ
- ๋์ ์ฟผ๋ฆฌ๋ฅผ ํจ์จ์ ์ผ๋ก ์์ฑ
- No Offset์ ํ์ฉํ ํ์ด์ง ์ฟผ๋ฆฌ ๊ฐ์
- Spring Batch
- ์ฒด๊ณ์ ์ธ ๋ฐฐ์น ์์ : Chunk ๋จ์๋ก ํธ๋์ญ์ ์ ๊ด๋ฆฌํด ๋ฉ๋ชจ๋ฆฌ์ ํ ๋ฒ์ ์ ์ฌํ์ง ์๋๋ก ํด ์๋ฒ์ ๋ถ๋ด ์ต์ํ
- Challenge์ ์ํ ๋ณ๊ฒฝ ์ ๋ฐฐํ ๋ฝ ์ค์ -> Chunk ๋จ์ ์์ ํ์
- AbstractPagingItemReader, JpaItemWriter๋ฅผ ์์๋ฐ์ ๋ค๋ชจ๋์ ์ํฐํฐ ๊ตฌ์ฑ์ ๋ง๊ฒ ๊ตฌ์ฑ
- MySQL 8.0.30
- ํ ์ด๋ธ์ ์ฑ๊ฒฉ์ ๊ณ ๋ คํ ๊ฐ์ฒด ์ค์ฌ์ ์ํฐํฐ ์ค๊ณ
- N:M ๊ด๊ณ๋ฅผ ์กฐ์ธ ํ ์ด๋ธ์ ํ์ฉํด 1:N, M:1๋ก ํ์ด๋ด ๊ฐ๋ฐ ๋ณต์ก๋ ์ ํ
- N-gram Parser๋ฅผ ํ์ฉํ ๋ถ๋ถ ๋ฌธ์์ด ๊ฒ์ (FullText-index)
- Nginx
- SSL ์ธ์ฆ์๋ฅผ ํ์ฉํ ์ํธํ/๋ณตํธํ
- ๋ฐ๊ธ๋ฐ์ ๋๋ฉ์ธ(nemodu.site)์ ๋ํ ํ๋ก์ ์ญํ
- AWS EC2
- ํ์ํ ๋งํผ ์ปดํจํ ์์ ์ฌ์ฉ(์จ๋๋งจ๋)
- ์ธ์คํด์ค ๋ชจ๋ํฐ๋ง
- AWS RDS
- ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ชจ๋ํฐ๋ง ๋ฐ ๊ด๋ฆฌ
- AWS S3
- ํ์ ํ๋กํ ์ฌ์ง์ ๋น๋กฏํ ํ์ผ ์ ์ฅ
- ์ ์ ํ์ด์ง ์ ์ฅ ๋ฐ ์ ๋ฌ (์ฝ๊ด ํ์ด์ง)
- AWS ElastiCache
- Redis๋ฅผ ํ์ฉํด ๋ฐ์ดํฐ ์บ์ฑ
- ๋น ๋ฅธ ์กฐํ ๋ฐ ์๋ฒ ๋ถํ ๊ฐ์
- Expire Event ๊ตฌ๋ : ์ด๋ฒคํธ๊ฐ ๋ฐํ๋๋ ๊ฒฝ์ฐ ๋ฐ์ดํฐ ์ฒ๋ฆฌ (FCM ํ ํฐ ์ฌ๋ฐ๊ธ ์์ฒญ)
์ถํ ๋ฐ์ํ ๋ค์ํ ์์ธ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํด ์ ์ฐํ ๊ตฌ์กฐ ํ์
- ๋ฐ์ํ ์ ์๋ ์์ธ์ ๋ํ ์ฝ๋ ์ ์ (ExceptionCodeSet.java)
- ์ธํฐํ์ด์ค๋ฅผ ํตํด ์์ธ ํด๋์ค์ ์ญํ ์ ์ (BaseException.java)
- ์ถ์ ํด๋์ค๋ฅผ ํ์ฉํด ์์ธ ํด๋์ค์ ์ค๋ณต ์ฝ๋ ์ต์ํ (BaseExceptionAbs.java)
- @RestControllerAdvice๋ฅผ ํ์ฉํด ์ปจํธ๋กค๋ฌ ๋ ๋ฒจ์์ ๋ฐ์ํ๋ ์์ธ ๊ณตํต ์ฒ๋ฆฌ
- ํํฐ ๋ ๋ฒจ์์ ๋ฐ์ํ๋ ์์ธ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํด, AuthenticationException์ ์์ ๋ฐ์ ์์ธ ํด๋์ค ์์ฑ
- ๊ธฐ์กด์ ์ ์ํ ์์ธ ์ฝ๋๋ฅผ ํ์ฉํด AuthenticationEntryPoint๋ฅผ ์์๋ฐ์ ํธ๋ค๋ฌ์์ ์์ธ ์ฒ๋ฆฌ
- ์ผ์ด์ค๋ณ ์์ธ ํด๋์ค ์์ฑ ๋ฐ ๊ฐ ์์ธ์ ๋ํ ๊ฐ๋ณ ์ฒ๋ฆฌ
(Ex:FilterException.java, ํํฐ ๋ ๋ฒจ์์ ๋ฐ์ํ ์์ธ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํด AuthenticationException ์์)
์นด์นด์ค, ์ ํ 2๊ฐ์ง ์์ ๋ก๊ทธ์ธ์ ์ง์. ๋์ค์ ์ถ๊ฐ๋ ์ ์๋ ๋ค์ํ ํ์๊ฐ์ ํํ์ ๋ํ ๋๋น
- Resource Server(ํ ์์ ์์ ์นด์นด์ค, ์ ํ)์ ๋ง์ถฐ ๊ฐ๋ฐํด ๊ตฌ์กฐ ๋ณ๊ฒฝ์ด ํ๋ค๋ค๊ณ ํ๋จ -> Resource Server ์์กด์ฑ ์ต์ํ
- ๋ก๊ทธ์ธ ํ Redirect ๋ฐ๋ ํํ๊ฐ ์๋, ํด๋ผ์ด์ธํธ๊ฐ ๋ก๊ทธ์ธ ํ ํ ํฐ๊น์ง ๋ฐ๊ธํ๋ ๊ฒ์ผ๋ก ์ญํ ๋ถ๋ฆฌ.
- ์์ ๋ก๊ทธ์ธ์ ๋ํ ๊ณตํต API๋ฅผ ์ ๊ณตํด ์๋ฒ์์ ํ์ํ ์ ๋ณด๋ฅผ ๋ฐ์ ํ์ ์ ๋ณด ๊ด๋ฆฌ
๋ฐ์ดํฐ๊ฐ ๋ง์์ง์๋ก ๋ฉ์ธ ํ๋ฉด API ์ฑ๋ฅ์ด ๊ธ๊ฒฉํ ์ ํ๋จ
- 1:N ํํ๋ก ์ค๊ณ๋ '์ด๋ ๊ธฐ๋ก<->์์ญ'์ ์กฐํํ ๋, 2๋ฒ์ ๊ฑธ์ณ ์กฐํํ๋ ๊ฒ์ Join์ ํ์ฉํด ํ ๋ฒ์ผ๋ก ์ค์ (DB I/O ์ต์ํ)
- ํ์ ์ค์ฌ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์กฐํํ๋ ๋ก์ง -> ์์ญ์ ์ค์ฌ์ผ๋ก ๋ฐ์ดํฐ ์กฐํ. ์ฆ, ํ ๋ฒ์ ๋ฐ์ดํฐ๋ฅผ ์กฐํํ๋๋ก ๋ก์ง ๊ฐ์
- ์ฌ๋ฐ๋ฅธ ์ธ๋ฑ์ค ์ค๊ณ๋ฅผ ํตํด ์ฟผ๋ฆฌ ์ฑ๋ฅ ๊ฐ์
- ํ ์คํธ ๊ฒฐ๊ณผ: ์คํ ์๋ 81.95% ํฅ์
- ํด๋ผ์ด์ธํธ์ ์ง๋ ์ถ์ฒ ์ ๋ณด๋ฅผ ํ์ฉํด MBR(Minimum Bounding Rectangle) ๊ณ์ฐ -> ๋ถํ์ํ ๋ฐ์ดํฐ ์ต์ํ
- MySQL์ MBR_CONTAINS() ํจ์๋ฅผ ํ์ฉํด MBR ๋ด ์์ญ๋ง ์กฐํํ๋๋ก ๊ฐ์
- ํ ์คํธ ๊ฒฐ๊ณผ: ์คํ ์๋ 42.86% ํฅ์
๋ญํน ๊ณ์ฐ์ ํ์ฉ๋๋ QueryDSL์ Tupleํด๋์ค์ ์์กด์ฑ์ด ์ ์ญ์ ํผ์ ธ์์.
- ๋ญํน ๊ณ์ฐ์ ํ์ํ ๊ณตํต DTO ์์ฑ
- DTO๋ฅผ ํ์ฉํด ์กฐํํจ์ผ๋ก์จ, Tuple์ ๋ํ ์์กด์ฑ ์ ๊ฑฐ
- ์๋ชป๋ Join ์ฌ์ฉ์ผ๋ก ์ธํด ๋ถํ์ํ๊ฒ ๋ณต์กํด์ง ๋ญํน ๊ณ์ฐ ๋ก์ง์ Outer Join์ ํ์ฉํด ๊ฐ์ํ
- ๋ญํน ๊ณ์ฐ์ ๊ณตํต ๋ชจ๋๋ก์ ํ์ฉํด ์ถํ ๋ค์ํ ๊ณณ์์ ์ฌ์ฉํ๊ธฐ ์ฝ๋๋ก ํจ
์ฌ์ฉ์๊ฐ ๋ง์์ก์ ๋, ๋ง์ ๋ฐ์ดํฐ๋ฅผ ํ ๋ฒ์ ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฌํ๋ ๊ฒ์ ๋ถ๋ด
- ์ผ์ ๋จ์๋งํผ ๋ฐ์ดํฐ๋ฅผ ์กฐํํด ์ฒ๋ฆฌํ๋๋ก ํจ -> ์ฝ๋๊ฐ ๋ณต์กํด ์ ์ง๋ณด์๊ฐ ํ๋ค ๊ฒ์ผ๋ก ์์
- ํนํ, ์ฑ๋ฆฐ์ง ์ํ ๋ณ๊ฒฝ ๋ฐฐ์น์ ๊ฒฝ์ฐ, ๋ณ๊ฒฝ ์ ๋ฐ์ดํฐ๋ฅผ ์กฐํํ ์ ์๋๋ก ๋ฐฐํ ๋ฝ์ ์ ์ฉํจ -> ๋น ๋ฅด๊ฒ ์ฒ๋ฆฌํด์ผ ํจ.
- Spring Batch๋ฅผ ๋์ ํด Job, Step ๊ฐ ๋จ๊ณ ๋ณ ์์ ์ Chunk๋ก ๋จ์๋ก ์ํ
- Postman์ผ๋ก ์ง์ ํ ์คํธํ๊ธฐ ํ๋ค๊ธฐ ๋๋ฌธ์, ํ ์คํธ ์ฝ๋ ์์ฑ
๊ฐ ์ฌ์ฉ์์ FCM ํ ํฐ์ด 2๋ฌ์ด ๊ฒฝ๊ณผํ ๊ฒฝ์ฐ, ํด๋ผ์ด์ธํธ์๊ฒ ์ฌ๋ฐ๊ธ์ ์์ฒญํด์ผ ํจ.
- ์ฌ์ฉ์๋ง๋ค ๋ง๋ฃ ์๊ฐ์ด ๋ค๋ฅด๊ธฐ ๋๋ฌธ์, ์ค์ผ์ค๋ฌ๋ฅผ ํตํด ์ง์ ํ์ธํ๋ ๊ฒ์ ๋นํจ์จ์
- FCM ํ ํฐ์ Redis์ ์ ์ฅํ๊ณ , TTL์ 2๋ฌ(60์ผ)๋ก ์ค์
- ํ ํฐ์ด ๋ง๋ฃ๋๋ ๊ฒฝ์ฐ Expire Event๋ฅผ ๋ฐํํด ์๋ฒ๋ก ์ ๋ฌ -> ์ด๋ฒคํธ๋ฅผ ๊ฐ์งํ๋ฉด key ์ ๋ณด์ ๋ง์ถฐ ํ ํฐ ์ฌ๋ฐ๊ธ ์์ฒญ
- Apns(iOS์ ํธ์ ์๋ ์๋น์ค)์ Silent Message๋ฅผ ํ์ฉํด ์ฌ๋ฐ๊ธ ์์ฒญ
์๋ฒ ๋ชจ๋ํฐ๋ง ๋ฐ ๋น ๋ฅธ ํธ๋ฌ๋ธ ์ํ ์ ์ํ ๋ก๊ทธ ์ ๋ต ๊ฐ์ ํ์
- ํธ์ ์๋, ๋ฐฐ์น ๋ฑ ํน์ ์๋น์ค์ ๋ฐ๋ฅธ Logger ๋ถ๋ฆฌ
- ๋ก๊ทธ ๋ ๋ฒจ์ ๋ฐ๋ฅธ ๋ก๊ทธ ์์ง
- ์๊ฐ, ์ฉ๋ ๋ณ Rolling ์ ๋ต ์๋ฆฝ
- Logger ํด๋์ค๋ฅผ Request Scope Bean์ผ๋ก ์์ฑํด ์ฝ๊ฒ ๋ก๊ทธ๋ฅผ ํ์ธํ ์ ์๋๋ก ๊ฐ์
-> @Qualifer๋ฅผ ํตํด ํน์ Logger๋ฅผ ์ฃผ์ ํด์ผ ํ๋ ๋ถ๋ถ์ ๊ฐ์ ํ์
์ด์์ ์ํด JVM ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ ๋ฐ GC ๋ชจ๋ํฐ๋ง์ด ํ์ํ๋ค๊ณ ํ๋จ