๋ชฉ๋ก๊ฐ๋ฐ์ผ์ง (21)
DevLog ๐ถ
๐ฑ ๋ค์ด๊ฐ๊ธฐ ์ ํตํฉ ํ ์คํธ๋ฅผ ํ๋ค ๋ณด๋ฉด, ์ค์ ๋น ์ค์ ์ผ๋ถ๋ง stubbing์ ํ๊ณ ์ถ์ ์ํฉ์ด ์๊ธด๋ค.์๋ฅผ ๋ค์ด, ์ธ๋ถ API๋ฅผ ํต์ ํ๊ฑฐ๋ ์ธ๋ถ ์์คํ ์ ํ์ฉํ๊ฒ ๋๋ฉด ํ ์คํธ์์ ๊ทธ๋๋ก ํ์ฉํ๊ธฐ ์ด๋ ค์ด๋ฐ, ํด๋น ๋ถ๋ถ์ ๋ํด์๋ง ์ฐ๋ฆฌ๊ฐ ์ํ๋ ์๋๋ฆฌ์ค๋ฅผ ์ ๊ณตํ์ฌ ์ฐ๋ฆฌ ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ ๋์ํ๋์ง ํ์ธํ๊ณ ์ถ์ ์ ์๋ค. ํ์ง๋ง, ๋ณดํต Spring Context์์๋ ๋์ผํ ์ด๋ฆ์ ๊ฐ์ง ๋น์ ๊ทธ๋๋ก ๋ฑ๋กํ๊ฒ ๋๋ฉด ์ค๋ฅ๊ฐ ๋ฐ์ํ๊ธฐ ๋๋ฌธ์, ๋ช ๊ฐ์ง ํน๋ณํ ์กฐ์น๋ฅผ ํด์ฃผ์ด์ผ ํ๋๋ฐ ํ ๋ฒ ์ดํด๋ณด์. โ๏ธ ํ ์คํธ ์๋๋ฆฌ์ค - ์ฌ์ฉ์๊ฐ ์ํ์ ๊ตฌ๋งคํ๊ฒ ๋๋ฉด, ์ธ๋ถ API๋ฅผ ํธ์ถํ์ฌ ์ฌ๊ณ ๊ฐ ์กด์ฌํ๋์ง ํ์ธํ๋ค. - ๋ง์ฝ ์ฌ๊ณ ๊ฐ ์กด์ฌํ๋ฉด ์ธ๋ถ API๋ ‘SUCCESS’๋ผ๋ ์๋ต์, ์ฌ๊ณ ๊ฐ ์กด์ฌํ์ง ์์ผ๋ฉด ‘FA..
๐ฑ ๋ค์ด๊ฐ๊ธฐ ์ ํ์ฌ ๋ค์ด๊ฐ๊ณ ๋ธ๋ก๊ทธ๊ฐ ๋๋ฌด ๋ธํด์ง ๊ฒ ๊ฐ์์, ์ด์ ์ ์ฐ๋ ค๋ค๊ฐ ๋ชป ์ด ๊ธ์ ์์ฑํ๊ณ ์ ํ๋ค ๐ฅน (๋ฌดํ์ ์์ ์ ์ฅ...) ์ฌ๋ด์์ Replication์ ํ์ฉํ๊ณ ์๋ค๋ ๊ฑด ์๊ณ ์๋๋ฐ, ๊ตฌ์ฒด์ ์ผ๋ก ์ด๋ค ์์ผ๋ก ๋์ํ๋์ง๋ ์ ๋๋ก ์ดํดํ์ง ๋ชปํ๊ณ ์์๋ ๊ฒ ๊ฐ์์ ๊ฐ๋จํ๊ฒ MySQL์ ํ์ฉํ์ฌ Replication์ด ์ด๋ค ์์ผ๋ก ๋์ํ๋์ง ๊ตฌ์ถํด๋ณด์๋ค. ๊ตฌ์ฒด์ ์ธ ๋ถ๋ถ์ ๋ ๊ณต๋ถํ๋ฉด ์ข๊ฒ ์ง๋ง, ํ์ต ์ฉ๋๋ก ์์ฑํ๋ ๊ธ! ๐ฑ ๋ณต์ ๋ ๋ฌด์์ผ๊น?๋ณต์ ๋ ๊ธฐ๋ณธ์ ์ผ๋ก master ๋ ธ๋์์ ๋ฐ์ดํฐ๊ฐ ๋ณ๊ฒฝ๋์์ ๋ slave ๋ ธ๋์๋ ๋ณ๊ฒฝ๋ ๋ด์ฉ์ ์ ์ฉ์ํค๋ ๊ฒ์ ์๋ฏธํ๋ฉฐ, MySQL์์๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋น๋๊ธฐ ๋ณต์ ๋ฐฉ์์ ํ์ฉํ์ฌ ๋ ์ฌ์ด์ ๋ฐ์ดํฐ ์ ํฉ์ฑ์ ๋ง์ถ๊ณ ์๋ค.์ฌ๊ธฐ์ ๋งํ๋ ๋น๋๊ธฐ ๋ณต์ ..
๐ฑ ๋ค์ด๊ฐ๊ธฐ ์ ๋๋ ํ์์ ๋ง์ฐ์ค๋ ์ฌ์ฉํ์ง ์์ง๋ง, ๋งฅ๋ถ ํฐ์นํจ๋๋ฅผ ์ ๋ง ๋ง์ด ์ฌ์ฉํ๋ ํธ์ด์์ด์ ๊ฐ๋ฐํ ๋ ๋จ์ถํค๋ฅผ๋ง์ด ์ฌ์ฉํ์ง ์๋ ํธ์ด์๋ค. ๊ทธ๋ฌ๋ค ๋ณด๋ ์๋์ผ๋ก ๊ฐ๋ฐํ ๋ ๋ฏธ๋ฌํ๊ฒ ์๋ ์ฐจ์ด๊ฐ ๋ฌ์๋๋ฐ, ์ด๋ฒ์ ๋จ์ถํค๋ ๊ณต๋ถํ ๊ฒธ, ๋ฆฌํฉํฐ๋ง ์ ์ด๋ป๊ฒ ํ๋ฉด Intellij ๋ฅผ ์ต๋ํ ํ์ฉํ ์ ์๋์ง ์คํฐ๋ ํ๋ ์๊ฐ์ ๊ฐ์ก๋ค. (๊ฐ๋๋๊ฐ๋ฐ์๋ ๋๋ถ์ ๋ง์ด ๋ฐฐ์ธ ์ ์๋ ์๊ฐ์ด์๋ค ใ _ใ ) ์ด๋ฒ ํฌ์คํ ์์ ์ฌ์ฉ๋ ์ํ ์ฝ๋๋ ๋ฐฑ๋ช ์ ๋์ ๊นํ๋ธ๋ฅผ ๊ฐ๋ฉด ํ์ธํ ์ ์๋๋ฐ, ๋๋ ์ฌ๋ด์์ ์ฝํ๋ฆฐ์ ์ฌ์ฉํ๊ณ ์๋ค ๋ณด๋๊น ํด๋น ์ฝ๋๋ฅผ ์ฝํ๋ฆฐ + Kotest๋ก ๋ณํํ์ฌ ์ฐ์ต์ ํด๋ณด์๋ค. ์ด๋ค ์์ผ๋ก ๋ฆฌํฉํฐ๋ง์ ํ๋์ง๋ ์๋์ ๋ ํ์งํ ๋ฆฌ์ ์ปค๋ฐ๋ณ๋ก ๋ํ๋ด์๋ค. GitHub - Cl8D/kotlin-exp..
๐ฑ ๋ค์ด๊ฐ๊ธฐ ์ ๋๋ฌด ์ค๋๋ง์ ์์ฑํ๋ ๋ธ๋ก๊ทธ ๊ธ...! ์ต๊ทผ์ ์ฌ๋ด์์ ๋งค์ฐ ๋ง์ด ์ฐ์ด๋ ๋๋ฉ์ธ์ ๋ํด์ ๋ฆฌํฉํฐ๋ง์ ์งํํ์๋๋ฐ, ๊ฑฐ๊ธฐ์ ๋ง๋ฌ๋ ์ด์๋ค๊ณผ ๊ฐ๋จํ ์๊ฐ ๊ธฐ๋ก์ ๋ธ๋ก๊ทธ์ ๋จ๊ธฐ๋ฉด ์ข์ ๊ฒ ๊ฐ์์ ์์ฑํ๊ณ ์ ํ๋ค. ์ด๋ฏธ ํ ๋ด์์ ๊ณต์ ๋ ํ์๊ณ , ๋๊ธฐ๋ค์๊ฒ๋ ๊ณต์ ํ ๋ด์ฉ์ด๊ธฐ๋ ํ๊ณ , ์ฌ์ค ๋ณ๊ฑฐ ์๋ ๊ฑฐ๋ผ ๊ทธ๋ฅ ๊ฐ๋จํ๊ฒ๋ง ์ ๋ฆฌํ ์์ ์ด๋ค. ๐ฑ ๋ฌธ์ ์ํฉ๋ฆฌํฉํฐ๋ง์ ์งํํ๊ณ ์ ํ ๋๋ฉ์ธ์ ์ฐ๋ฆฌ ํ์์ ๋งค์ฐ ์ค์ํ ๋น์ฆ๋์ค ๋๋ฉ์ธ ๊ฐ์ฒด ์ค ํ๋์๊ณ , ์ด๋ฏธ ์์ ์ ์ผ๋ก ์ ์ด์๋๊ณ ์์ง๋ง ๊ต์ฅํ ์๋ ๋ถํฐ ๋ ๊ฑฐ์๋ก ๋ด๋ ค์ค๊ณ ์๋ ๊ฐ์ฒด์๊ธฐ ๋๋ฌธ์ ์ ๊ท ์ ์ฌ์๊ฐ ๋ณด๊ธฐ์ ์ข์ ์ฝ๋๊ฐ ์๋๋ผ๋ ์๊ฐ์ด ๋ค์๋ค. ์ฌ๋ด ๋๋ฉ์ธ์ธ ๋งํผ ๊ทธ๋๋ก ๊ฐ์ ธ์ฌ ์๋ ์์ง๋ง, ๋น์ทํ ๋๋์ผ๋ก ์๋์ ๊ฐ์ด ์ธํ ์ ์งํํด๋ณด์๋ค.CREAT..
๐ฑ ๋ค์ด๊ฐ๊ธฐ ์ ์ง๋ ํฌ์คํ ์์๋ ๋ ๋์ค๋ฅผ ํ์ฉํด ๋ถ์ฐ๋ฝ์ ๊ตฌํํ๋ ๋ค์ํ ๋ฐฉ๋ฒ๋ค์ ์ดํด๋ณด์๋ค. ์ด๋ฒ ํฌ์คํ ์์๋ ์กฐ๊ธ ๋ ์๋ค๋ฅธ ๋ฐฉ๋ฒ์ผ๋ก ๋ ๋์ค๋ฅผ ํ์ฉํ์ฌ ๋ถ์ฐ๋ฝ์ ๊ตฌํํด๋ณด๊ณ ์ ํ๋ค. โ Case 4 - Lua Script ํ์ฉํ๊ธฐ Redis 2.6 ๋ฒ์ ์์ ๋ฃจ์ ์คํฌ๋ฆฝํธ ์์ง์ด ์ถ๊ฐ๋๋ฉด์, ๋ ๋์ค ์๋ฒ์์ ๋ฃจ์ ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ ์ ์๊ฒ ๋์๋ค. ๋ ๋์ค ๋ด๋ถ์์๋ EVAL (ํน์ EVALSHA)์ด๋ผ๋ ๋ช ๋ น์ด๋ฅผ ํตํด ์ฌ์ฉํ ์ ์๋ค. EVAL script numkeys [key [key ...]] [arg [arg ...]] ๋ง์ฝ ์คํฌ๋ฆฝํธ๊ฐ ๊ธธ์ด์ง๊ฒ ๋๋ค๋ฉด ์คํฌ๋ฆฝํธ ์ ์ฒด๋ฅผ EVAL๋ก ์ ์กํ๊ธฐ์๋ ๋คํธ์ํฌ ๋์ญ์ ๋น์ฉ์ด ๋ฐ์ํ ์ ์๊ธฐ ๋๋ฌธ์, ๋ ๋์ค์์๋ SCRIPT LOAD ๋ช ๋ น์ด๋ฅผ ํตํด ์คํฌ๋ฆฝํธ๋ฅผ ..
๐ฑ ๋ค์ด๊ฐ๊ธฐ ์ ์กฐ๊ธ ์ค๋๋๊ธด ํ์ง๋ง ์ด์ ํฌ์คํ ์์ ๋ค์๋๋ฝ์ ํตํ ๋ถ์ฐ๋ฝ ๊ตฌํ์ ์งํํ์๋ค. ๋ง์ง๋ง ํฌ์คํ ์์ ๋ ๋์ค๋ฅผ ํ์ฉํ๋ค๊ณ ๋งํ์๋๋ฐ, ๊ณ์ ๋ฏธ๋ฃจ๋ค๊ฐ ์ด๋ฒ์ ๋ ๋์ค ๊ณต๋ถ๋ฅผ ํ๋ฉด์ ๊ฐ๋จํ๊ฒ ๊ตฌํ์ ์งํํด๋ณด์๋ค. ๋ถ์ฐ๋ฝ์ ๋ํ ๊ฐ๋ ์ ์ด์ ํฌ์คํ ์์ ๋ค๋ฃจ์๊ธฐ ๋๋ฌธ์, ๋ ๋์ค๋ฅผ ์ด์ฉํด์ ๋ฐ๋ก ๋ถ์ฐ๋ฝ์ ๊ตฌํํด๋ณด์. ๋ํ, ์ง๋ ํฌ์คํ ์์๋ Jmeter๋ฅผ ํ์ฉํ์์ง๋ง, ์ด๋ฒ ํฌ์คํ ์์๋ E2E ํ ์คํธ๋ฅผ ํตํด ์ง์ ๊ตฌํ์ ํด๋ณด๊ณ ์ ํ๋ค. ๐ฑ ๊ตฌํ ์ํฉ ์ ๋ง ๊ฐ๋จํ๊ฒ ์์ก์ ์๋ฏธํ๋ 'Balance'๋ผ๋ ๊ฐ์, 2๊ฐ์ ์์ฒญ์ด ๋์์ ๋ค์ด์์ ๋ ๋ ๋์ค๋ฅผ ํตํ ๋ถ์ฐ๋ฝ์ ๊ตฌํํ์ฌ ์ ์ดํด๋ณด์. ์์ ๊ฒฐ๊ณผ์์ ์ต์ ์ ์ํฉ์ด๋ผ๋ฉด Request 1, 2๋ฒ ๋ชจ๋ 80์ด๋ผ๋ ๊ฐ์ ๋ฐํํ์ฌ ์ ์์ ์ผ๋ก ์์ก์ด ๊ฐฑ์ ๋์ง ์์..
๐ฑ ๋ฌธ์ ์ํฉ ํ๋ก์ ํธ๋ฅผ ์งํํ๋ฉด์ ๋์ ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ ์ผ์ด ๋ง์ QueryDSL์ ๋์ ํ๊ฒ ๋์๋๋ฐ, ์ด๋ฒ์ ์๋ค๋ฅธ ์ค๋ฅ๋ฅผ ๋ฐ๊ฒฌํ๊ฒ ๋์๋ค. java.lang.NullPointerException: Cannot read field "id" because "co.kirikiri.domain.goalroom.QGoalRoomMember.goalRoomMember.goalRoom.roadmapContent.roadmap" is null NPE๋ฅผ ๋ณธ ๊ฑด ์ค๋๋ง์ด์ด์ ์กฐ๊ธ ์ฝ์ง์ ์งํํ๋ค. ๐ฑ ๋๋ฉ์ธ ๊ตฌ์กฐ ์ง๋ ํฌ์คํ ๊ณผ ๊ฐ์ ํ๋ก์ ํธ์ด๊ธฐ ๋๋ฌธ์ ๋๋ฉ์ธ ๊ตฌ์กฐ๋ ๊ฑฐ์ ๋์ผํ๋ฐ, ์ ๋ฌธ์ ์ํฉ์ ์ดํดํ๊ธฐ ์ํ ์ถ๊ฐ์ ์ธ ๋๋ฉ์ธ ์ ๋ณด๊ฐ ํ์ํ๋ค. ํ๋์ ๋ก๋๋งต ๋ณธ๋ฌธ(RoadmapContent) ์ ๋ณด์ ๋ํด์ ์ฌ๋ฌ ๊ฐ์ ..
๐ฑ ๋ค์ด๊ฐ๊ธฐ ์ ์ฐ๋ฆฌ ํ์ ๊ฒฝ์ฐ E2E ํ ์คํธ ํ๊ฒฝ์ ๊ตฌ์ถํ๊ธฐ ์ํด์ @SpringBootTest๋ฅผ ํตํด ํ ์คํธ ์ฝ๋๋ฅผ ์์ฑํ๊ณ ์๋๋ฐ, ์ฐ๋ฆฌ ํ์ ํ์๋ถ์ด ์๋์ ๊ฐ์ ์ค๋ฅ๋ฅผ ๋ง๋๊ฒ ๋์๋ค. failed to lazily initialize a collection of role: co.kirikiri.domain.roadmap.RoadmapContent.nodes.values: could not initialize proxy - no Session ์ํฉ์ ์๋์ ๊ฐ๋ค. (์ถํ ์ฝ๋๋ก ๋ ์ ์ดํด๋ณผ ์์ ์ด๋ค.) A๋ผ๋ ์์ฑ API์ B๋ผ๋ ์กฐํ API๊ฐ ์์ ๋, ํ ๋ด์์ ๊ธฐ๋ฅ์ ์ธ๋ถํํ ๋ค์ ๊ฐ์ ๊ฐ๋ฐ์ ์งํํ๋ค ๋ณด๋ B๋ฅผ ๊ฐ๋ฐํ๋ ์์ ์ A๋ผ๋ API๊ฐ ์์ด, ํตํฉ ํ ์คํธ ๋ repository๋ฅผ ..
๐ฑ ๋ค์ด๊ฐ๊ธฐ ์ ์ฐ๋ฆฌ ํ์ CI ํ๋ก์ฐ ๊ณผ์ ์ค์์ Jacoco๋ฅผ ํ์ฉํ์ฌ ํ ์คํธ ๋ฆฌํฌํธ๋ฅผ ๋ฐํํ๊ณ , ์ปค๋ฒ๋ฆฌ์ง๋ฅผ ์ฒดํฌํ๊ณ ์๋ค. (ํ ์คํธ๋ฅผ ์ ๋ง ์ฒ ์ ํ๊ฒ ํ์๋ ์ทจ์ง์ธ๋ฐ, ํ์ ๋ชจ๋๊ฐ ํ ์คํธ๋ฅผ ์ ๋ง ๊ผผ๊ผผํ๊ฒ ์์ฑํด ์ฃผ์ ์ ์ข๋ค ๐) CI์ ๋ํ ๊ธ์ ๋ค์์ ์์ ํ๊ฒ ๊ตฌ์ถ๋ ์ดํ์ ์์ฑํ๋ ๊ฒ ์ข์ ๊ฒ ๊ฐ์์, ์ค๋์ Jacoco์ ๋ํด์๋ง ๊ฐ๋ณ๊ฒ ์ง๊ณ ๋์ด๊ฐ๊ณ ์ ํ๋ค. ๐ฑ Jacoco ์ค์ ํ๊ธฐ Jacoco๋, ํ ์คํธ ์ฝ๋ ์ปค๋ฒ๋ฆฌ์ง๋ฅผ ๋ถ์ํด์ฃผ๋ ์๋ฐ์ ๋ฌด๋ฃ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ด๋ค. Jacoco ํ๋ฌ๊ทธ์ธ์๋ JacocoTestReport์ JacocoTestCoverageVerification Task ๋ฑ์ด ์กด์ฌํ๋ค. (์ฌ๊ธฐ์๋ ์ด 2๊ฐ์ง๋ฅผ ์์ฃผ๋ก ์์๋ณด๋๋ก ํ์.) - JacocoTestReport: ์ปค๋ฒ๋ฆฌ์ง ๊ฒฐ๊ณผ..
๐ฑ ๋ค์ด๊ฐ๊ธฐ ์ DB ๊ณต๋ถํ๋ค๊ฐ '๋ค์๋๋ฝ'์ ๋ํด์ ์๊ฒ ๋์๋๋ฐ, ๋ค์๋๋ฝ์ ์ฌ์ฉํ๋ฉด ๋ถ์ฐ๋ฝ์ ๊ตฌํํ ์ ์๋ค๋ ๊ธ์ ๋ณด๊ณ ํ ๋ฒ ํ ์คํธํด๋ณด๊ณ ์ถ์ด์ ๊ธ์ ์์ฑํด๋ณด๊ณ ์ ํ๋ค. ์ ์ฒด ์์ค์ฝ๋๋ ์ฌ๊ธฐ์์ ํ์ธ ๊ฐ๋ฅํ๋ค. (๋ญ๊ฐ ํ ์คํธ์ฉ ๋ ํฌ ๋ง๋ค๊ธฐ ์ ๋งคํด์ ๊ทธ๋ฅ ์ ์ฐ๋ ๋ ํฌ์๋ค๊ฐ ํ๋ ค๋ค ๋ณด๋ ์ฝํ๋ฆฐ์ผ๋ก ์์ฑํ๊ฒ ๋์๋ค.) ๐ฑ ๋ถ์ฐ๋ฝ์ด๋? ๋ถ์ฐ๋ฝ์ด๋ ๋ฉํฐ ์ค๋ ๋ ํ๊ฒฝ์์ ๊ณต์ ์์์ ์ ๊ทผํ ๋, ๋ฐ์ดํฐ์ ์ ํฉ์ฑ์ ์งํค๊ธฐ ์ํด ์ฌ์ฉํ๋ ๊ธฐ์ ์ด๋ค. ์ฌ๊ธฐ์ ์ฌ๋ฌ ์ค๋ ๋๊ฐ ๊ณต์ ์์์ ์ ๊ทผํ๋ฉฐ ๊ฒฝ์ํ๋ ์ํฉ์ 'Race Condition (๊ฒฝ์ ์ํ)'๋ผ๊ณ ๋ ๋ถ๋ฅด๋ฉฐ, ์๋ฐ์์๋ 'synchronized'๋ผ๋ ํค์๋๋ฅผ ํตํด์ ํ๋์ ์ค๋ ๋๋ง ์ ๊ทผํ ์ ์๋๋ก ๋๊ธฐํ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค. ํ์ง๋ง, ์คํ๋ง ์น ์ ํ๋ฆฌ์ผ์ด..