์ ์ฒด ๊ธ (64) ์ธ๋ค์ผํ ๋ฆฌ์คํธํ Spring Boot์ Graceful Shutdown ์ด๋๊น์ง ์๊ณ ์๋์? (SmartLifeCycle, Phased ์ ํจ๊ป timeout-per-shutdown-phase ์คํด ๋ฐ๋ก์ก๊ธฐ) ์ด ๊ธ์์๋ Graceful Shutdown์ "์ฐ์ํ ์ข ๋ฃ"๋ก ์ธ๊ธํฉ๋๋ค. 1. ์ฐ์ํ ์ข ๋ฃ ํ ์คํธ ํ๊ฒฝ ์ค์ ์ฐ์ํ ์ข ๋ฃ ํ ์คํธ๋ IDE์์ ์คํ ์ ์ํํ๊ฒ ๋์ํ์ง ์๋๋ค๊ณ ์ค๋ช ๋์ด ์์ด, Linux ์๋ฒ์์ jar๋ฅผ ์๋์ผ๋ก ์ข ๋ฃํ๋ฉฐ ํ ์คํธ๋ฅผ ์งํํ์ต๋๋ค.Using graceful shutdown with your IDE may not work properly if it does not send a proper SIGTERM signal. See the documentation of your IDE for more details. 1.1 application.yml ์ค์ application.yml์ ์ฐ์ํ ์ข ๋ฃ๋ฅผ ์ค์ ํ์์ต๋๋ค. ์คํ๋ง ๋ถํธ 3.4๋ถํฐ๋ ์ฐ์ํ ์ข ๋ฃ๊ฐ ๊ธฐ๋ณธ์ผ๋ก ์ค์ ๋๋ฉฐ, .. Disk I/O ๋ฐ์ด๋ ์๋ฒ๋ฅผ ์ํ ํ์ด์ง ์บ์(Page Cache) "์น ๊ฐ๋ฐ์๋ฅผ ์ํ ๋๊ท๋ชจ ์๋น์ค๋ฅผ ์งํฑํ๋ ๊ธฐ์ "์ ๋ด์ฉ์ ์ฌ๊ตฌ์ฑํ์ต๋๋ค. ํ์ด์ง ์บ์๋?OS๋ ๋์คํฌ ์ก์ธ์ค๋ฅผ ์ค์ด๊ธฐ ์ํด ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ์ฉํฉ๋๋ค.ํ๋ก์ธ์ค A๊ฐ ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ณ ๋ ํ, ๋ ์ด์ ๊ทธ ๋ฐ์ดํฐ๊ฐ ํ์ ์์ด์ก๋ค๊ณ ํด์ OS๋ ๋ฉ๋ชจ๋ฆฌ์์ ๋ฐ๋ก ํด์ ํ์ง ์์ต๋๋ค.๋ฉ๋ชจ๋ฆฌ์ ๋ฐ์ดํฐ๋ฅผ ๊ทธ๋๋ก ๋จ๊ฒจ๋๋๋ฐ, ์ด๊ฒ์ด ๋ฐ๋ก ํ์ด์ง ์บ์์ ๋๋ค. ์ด ๋๋ถ์ ํ๋ก์ธ์ค B๊ฐ ๋ฐ์ดํฐ๋ฅผ ํ์ํ ๋ ๋์คํฌ๋ฅผ ๋ค์ ์ฝ์ง ์๊ณ ๋ฉ๋ชจ๋ฆฌ์์ ๋ฐ๋ก ๊ฐ์ ธ์ฌ ์ ์๊ฒ ๋ฉ๋๋ค. * OS์ ํ์ผ ์์คํ ๋ง๋ค ๋์คํฌ ์ฝ๋ ๋ฐฉ๋ฒ์ด ๋ค๋ฅผํ ๋ฐ?๋ฆฌ๋ ์ค์๋ ext3, ext2 ๊ฐ์ ์ฌ๋ฌ ํ์ผ ์์คํ ์ด ์๊ณ ๊ฐ๊ฐ ๋์คํฌ๋ฅผ ์ฝ๋ ๋ฐฉ๋ฒ์ด ๋ค๋ฅด์ง๋ง, VFS(Virtual File System)๊ฐ ์ด๋ค ํ์ผ ์์คํ ์ ์ฌ์ฉํ๋ ํ์ด์ง ์บ์๋ฅผ ๋์ผํ๊ฒ ์ ๊ณตํด์ค๋ค๊ณ .. search_after API ๋ก OpenSearch์์ 10,000๊ฑด ์ด์ Pagination ์๋๋ ๋ฌธ์ ํด๊ฒฐํ๊ธฐ best practice ๊ฐ ์๋ ์ ์์ต๋๋ค. ์ฐธ๊ณ ํด์ฃผ์๋ฉด ๊ฐ์ฌํ๊ฒ ์ต๋๋ค.๋ฌธ์ ์ํฉOpenSearch์์ from๊ณผ size๋ฅผ ํ์ฉํด ํ์ด์ง ์ฟผ๋ฆฌ๋ฅผ ์์ฒญํ๋ ์ค, ๋ฐ์ดํฐ๊ฐ 10,000๊ฑด์ ๋์ด๊ฐ๋ฉด์ ๋ค์๊ณผ ๊ฐ์ ์๋ฌ๊ฐ ๋ฐ์ํ์ต๋๋ค."Result window is too large, from + size must be less than or equal to: [10000] but was [10008]. See the scroll api for a more efficient way to request large data sets. This limit can be set by changing the [index.max_result_window] index level setting."OpenSearch(El.. Cloud OpenFeign ์ ์ฌ์๋๋ ์ธ์ ๋์ํ ๊น? Retryer.Default ๋์ ์๋ฆฌ์ ํ ์คํธ README WireMock์ ๋ํ ์ค๋ช ์ด ๋ถ์กฑํ๋ฉฐ, WireMock์ ์๊ณ ์๋ ๊ฐ์ ํ์ ์งํ๋ฉ๋๋ค. WireMock์ ๋ํ ์ค๋ช ์ ์๋๋ฅผ ์ฐธ๊ณ ํด์ฃผ์ธ์. - Spring Cloud Contract WireMock Docs- Baeldung ์ Introduction WireMock- ์ฐ์ํ๊ธฐ์ ๋ธ๋ก๊ทธ : ์ผ, ๋๋ WireMock ์ผ๋ก ํ ์คํธํ ์ ์์ด Cloud OpenFeign ์ ์ฌ์๋๋ฅผ ์ํด Retryer.Default ๋ฅผ ๋น์ผ๋ก ๋ฑ๋กํ์ ๋ ์๋ 2๊ฐ์ง ๊ฒฝ์ฐ ์ ์ฌ์๋๋ฅผ ํ๋ ๊ฒ์ ํ์ธํ๊ณ ํ ์คํธ ํ๋ ๊ณผ์ ์ ์๊ฐํฉ๋๋ค.1. IOException ๋ฐ์ ์, ์ฌ์๋2. ์๋ต์ Retry-After ํค๋๊ฐ ์์ด์ RetryableException์ด ๋ฐ์ํ ๋, ์ฌ์๋ ์๋ก : Feig.. ์๊ด ์๋ธ์ฟผ๋ฆฌ๋ฅผ ๊ฐ์ ํ์ฌ API ์๋ต 2.5์ด์์ 0.2์ด๋ก ๊ฐ์ ํ๊ธฐ ์๋ก ์ฝ 2.5์ด๊ฐ ๊ฑธ๋ฆฌ๋ ๋ํ ๋ชฉ๋ก ์กฐํ API์ ์๋ต ์๊ฐ์ 0.2์ด๋ก ๊ฐ์ ํ๋ฉฐ ๋ฐฐ์ด ์๊ด ์๋ธ์ฟผ๋ฆฌ์ Hash Join, Nested Loop Join ์ ํน์ง์ ๊ณต์ ํฉ๋๋ค.๋ฌธ์ ๋ํ ๋ชฉ๋ก ์กฐํ API๋ฅผ Postman์ผ๋ก ํ ์คํธํ ๊ฒฐ๊ณผ, ์๋ต ์๊ฐ์ด ์ฝ 2.5์ด๋ ๊ฑธ๋ ธ์ต๋๋ค. ์์ธ ํ์ ํด๋น API๋ DB ์ ๊ทผ์ ์ด 3๋ฒ ํ๋ ๊ตฌ์กฐ์๊ธฐ์ ๋ณ๋ชฉ ์ง์ ์ ๋น ๋ฅด๊ฒ ํ์ ํ๊ธฐ ์ํด IntelliJ Profiler๋ก ๊ฐ ์ฟผ๋ฆฌ์ ์คํ ์๊ฐ์ ์ธก์ ํ์ต๋๋ค.์ธก์ ๊ฒฐ๊ณผ์ฒซ ๋ฒ์งธ ์ฟผ๋ฆฌ๋ ์๋ ์ฌ์ง์ ์กฐํ ์กฐ๊ฑด 5๊ฐ์ง(๊ฒ์์ด, ์๋น์ค, ์นดํ ๊ณ ๋ฆฌ ๋ช , ์ฌ์ฉ์ ๋ฐ์, ๋ํ์ผ์)๋ฅผ ํํฐ๋งํด์ ํ์ด์ง ๋น ๋ณด์ฌ์ค ๋ํ UUID 10๊ฐ๋ฅผ ์ถ์ถํ๋ ์ฟผ๋ฆฌ๋ก, 102ms ๊ฐ ๊ฑธ๋ ธ์ต๋๋ค. ๋ ๋ฒ์งธ ์ฟผ๋ฆฌ๋ ์๋ ์ฌ์ง์ ๋ํ UUID ๋ง๋ค ์ฌ์ฉ์ .. ๋ณต์กํจ ๋์ ๋จ์ํจ ์ถ๊ตฌํ๊ธฐ - RestTemplate ํ์ฅ ๋๋๋ฆฌ๊ธฐ ๊ธฐ๋ฅ ๊ตฌํ ์ค, RestTemplate์ผ๋ก OpenSearch์ GET _search API๋ฅผ ํธ์ถํ๊ณ , ์๋ต์ ๋ฐ์์ผ ํ์ต๋๋ค. OpenSearch์ Search API๋ ์ฟผ๋ฆฌ๊ฐ ๊ธธ์ด์ง ์ ์์ด, HTTP ๊ท์ฝ์ ์ด๊ธ๋๋๋ผ๋ GET ์์ฒญ์ Body๋ฅผ ํ์ฉํฉ๋๋ค. ์ ๋ ์ฒ์์ _search API ๋ช ์ธ๋๋ก GET + body์์ฒญ์ ์ฌ์ฉํ์ง๋ง, RestTemplate์ด GET์ Body๋ฅผ ๋ด์์ฃผ์ง ์๋๋ค๋ ์ฌ์ค์ ๊นจ๋ซ๊ณ GET + body ์์ฒญ์ ์ํ RestTemplate ํ์ฅ ์์ ์ ์งํํ์ต๋๋ค. ๊ทธ๋ฌ๋, OpenSearch ๋ HTTP ๊ท์ฝ์ ์ํด _search API ๋ฅผ GET ๋ฟ๋ง ์๋๋ผ POST ๋ ์ง์ํ๋ ๊ฒ์ ์๊ฒ ๋์์ต๋๋ค.๊ทธ ๊ณผ์ ์์ ๋ฐฐ์ด "๋ณต์กํจ ๋ณด๋ค๋ ๋จ์ํจ"์, ๊ทธ๋ฆฌ๊ณ RestTem.. Spring AOP ๋ก ์ฌ์ฉ์๊ฐ ๊ฐ์ง ๊ถํ์ ๋ฐ๋ผ ํน์ ๋ฉ๋ด(๊ธฐ๋ฅ) ์ ์ ์ ํํ๊ธฐ ์ฌ๋ด ์ด๋๋ฏผ์ ๊ฐ๋ฐํ๋ ์ค, ๋ค์๊ณผ ๊ฐ์ ์๊ตฌ์ฌํญ์ด ์๊ฒผ์ต๋๋ค."์ฌ์ฉ์๊ฐ ๊ฐ์ง๊ณ ์๋ ๊ถํ ์ธ์ ๋ฉ๋ด(๊ธฐ๋ฅ)์ ์ ๊ทผํ ์ ์๋๋ก ์ ํํด๋ฌ๋ผ." ์ด ์๊ตฌ์ฌํญ์ AWS์ IAM ๊ธฐ๋ฅ๋งํผ ๋ณต์กํ์ง ์์ง๋ง, ๋งฅ๋ฝ์ ๋น์ทํด์ IAM ๊ฐ๋ ์ ๋น๋ ค ์๊ตฌ์ฌํญ์ ์ค๋ช ๋๋ฆฌ๊ณ ์ ํฉ๋๋ค. IAM์ ๊ตฌ์ฑ์์์ ์ ๊ทผ ์ ์ด ๋ฐฉ์IAM์ ๊ตฌ์ฑ ์์ ์ค ๊ธ์ ์ค๋ช ํ๋๋ฐ ํ์ํ ๊ฐ๋ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. ์ฌ์ฉ์ (User)AWS ๋ฆฌ์์ค์ ๋ก๊ทธ์ธํ๊ฑฐ๋ API๋ฅผ ํธ์ถํ๋ ์ฃผ์ฒด๋ก, ์ค์ ์ฌ๋๊ณผ 1:1 ๋งคํ๋ฉ๋๋ค.์ญํ (Role)AWS์ IAM์ ์ญํ ์ ์ผ์์ ์ธ ๊ถํ ์์์ ์ํด ์กด์ฌํ๋ ์๊ฒฉ์ ๋๋ค. ์ฆ, "์ฌ์ฉ์๊ฐ ์ญํ ์ ๊ฐ๋ ๊ฒ"์ด ์๋๋ผ, ์ฌ์ฉ์๋ AWS ์๋น์ค๊ฐ ํ์ํ ๋ ์ญํ ์ ๋งก์์(๊ฐ์ ํด์, Assume), ์ญํ ์ ์ฐ๊ฒฐ๋ ์ ์ฑ ๊ถ.. MultipartFile ์ transferTo ์ดํ getBytes ํธ์ถ ์ NoSuchFileException ๋ฐ์ ์์ธ ์๊ฐ ์๋ก MultipartFile ๊ฐ์ฒด๋ฅผ ๋์คํฌ์ ์ ์ฅํ๊ณ , ํด๋น ํ์ผ์ ์๋ฒ ๋ฉํ๊ธฐ ์ํด FastAPI๋ก ๋ฐ์ด๋๋ฆฌ ๋ฐ์ดํฐ๋ฅผ ์ ์กํด์ผ ํ๋ ์๊ตฌ์ฌํญ์ ๊ตฌํ ์ค์ด์์ต๋๋ค.ํ์ผ์ ๋์คํฌ์ ์ ์ฅํ๊ธฐ ์ํด transferTo() ๋ฅผ ์ฌ์ฉํ๊ณ , getBytes() ๋ฅผ ํตํด ๋ฐ์ด๋๋ฆฌ ๋ฐ์ดํฐ๋ฅผ ์ป์ผ๋ ค ํ์ง๋ง, ํ์ผ์ ์ฐพ์ ์ ์๋ค๋ NoSuchFileException ์ด ๋ฐ์ํ์ต๋๋ค.Caused by: java.nio.file.NoSuchFileException: C:\Users\...\Local\Temp\tomcat.28080.5183490430648900766 ๊ฐ์ MultipartFile ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ์ง๋ง ํ์ผ์ ์ฐพ์ ์ ์๋ค๋ ๊ฒ์ด ์ดํด๊ฐ ๊ฐ์ง ์์์ต๋๋ค.๊ฒฐ๋ก MultipartFile์ spring.servlet.mu.. ์ด์ 1 2 3 4 ยทยทยท 8 ๋ค์