{"componentChunkName":"component---src-templates-post-template-jsx","path":"/works/posts/2023-07-10--001","result":{"data":{"site":{"siteMetadata":{"title":"Blog by Eunyoung","subtitle":"작업 기록 블로그","copyright":"© All rights reserved.","author":{"name":"EunYoung","twitter":"#"},"disqusShortname":"","url":"https://ssongey.github.io"}},"markdownRemark":{"id":"3aecf5b1-10cc-5d36-b55a-1292251e11c6","html":"<p>SpringBoot/Java + K8S 환경 기반에서 어떤 방식으로 웜업을 수행해야 좋을지 고민을 한 내용을 정리한다.</p>\n<br/>\n<h2>1. 스프링부트 애플리케이션 시작 시점에 웜업 수행</h2>\n<h3>✔️ 방법</h3>\n<ul>\n<li><code class=\"language-text\">CommandLineRunner</code> 또는 <code class=\"language-text\">ApplicationRunner</code> 인터페이스를 구현한 클래스에 <code class=\"language-text\">@Component</code> 를 선언하면, 컴포넌트 스캔 후에 override 된 run 메소드 로직이 수행된다.</li>\n<li>여기서 웜업 로직을 넣어 애플리케이션 시작시에 웜업 코드가 돌도록 한다.</li>\n</ul>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token annotation punctuation\">@Component</span>\n<span class=\"token keyword\">public</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">BeforeStartRunner</span> <span class=\"token keyword\">implements</span> <span class=\"token class-name\">CommandLineRunner</span> <span class=\"token punctuation\">{</span>\n\t<span class=\"token annotation punctuation\">@Override</span>\n\t<span class=\"token keyword\">public</span> <span class=\"token keyword\">void</span> <span class=\"token function\">run</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">String</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span> args<span class=\"token punctuation\">)</span> <span class=\"token keyword\">throws</span> <span class=\"token class-name\">Exception</span> <span class=\"token punctuation\">{</span>\n\t\t<span class=\"token comment\">// 웜업 로직</span>\n\t<span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\n또는\n\n<span class=\"token annotation punctuation\">@Component</span>\n<span class=\"token keyword\">public</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">BeforeStartRunner</span> <span class=\"token keyword\">implements</span> <span class=\"token class-name\">ApplicationRunner</span> <span class=\"token punctuation\">{</span>\n\t<span class=\"token annotation punctuation\">@Override</span>\n\t<span class=\"token keyword\">public</span> <span class=\"token keyword\">void</span> <span class=\"token function\">run</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">ApplicationArguments</span> args<span class=\"token punctuation\">)</span> <span class=\"token keyword\">throws</span> <span class=\"token class-name\">Exception</span> <span class=\"token punctuation\">{</span>\n\t\t<span class=\"token comment\">// 웜업 로직</span>\n\t<span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<h3>✔️ 장점</h3>\n<ul>\n<li>애플리케이션 시작 시 무조껀 수행이 보장된다.</li>\n</ul>\n<h3>✔️ 단점</h3>\n<ul>\n<li>로컬, 개발 페이즈 등, 웜업이 불필요한 페이즈에 대해 예외처리를 해줘야 한다.</li>\n<li>웜업이 끝나기 전까지 트래픽을 받을 수 없도록 조치가 필요하다. (ex. 로컬 메모리에 웜업 종료에 대한 플래그 저장 등)</li>\n<li>liveness probe에서 지정한 timeoutSeconds값 보다 웜업 수행 시간이 길어질 경우, liveness probe 실패로 파드 무한 재시작이 될 수 있다.</li>\n<li>그렇다고 timeoutSeconds 값을 크게주면, liveness probe 주기가 길어지게 되므로 적절하지 않다.</li>\n</ul>\n<br/>\n<h2>2. K8S Startup Probe 사용하여 웜업 수행</h2>\n<ul>\n<li>Pod Probe 중 <code class=\"language-text\">startupProbe</code> 는 아래 그림과 같이 성공이 될때까지 다른 probe를 활성화하지 않기 때문에, 웜업을 수행하기 적절하다.</li>\n<li>만약 <code class=\"language-text\">startupProbe</code> 가 실패하면, kubelet이 컨테이너를 죽이고, 컨테이너는 재시작 정책에 따라 처리된다.</li>\n<li>실제, k8s 매뉴얼에도 서비스를 시작하는 데 오랜 시간이 걸리는 컨테이너가 있는 파드에 유용하다고 가이드가 되어있다.</li>\n</ul>\n<p>\n  <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/devHistoryBlog/static/e71b16a7ec85bc1a46b34407e281e179/af777/01.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n  \n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 50.416666666666664%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABYlAAAWJQFJUiTwAAABcklEQVQoz31SaVPCMBDt//9hooNfVFCoFoQBaq/0SNokTdPnNtCR4XCnmW02e7236+GO9H3vtLEG22SDVRhA6gZKKrRtOzigt9b5jb6D9v5N6L4eUjVgeYZGNojiGEKIo8+NBrzxcl7l/AyiWwteK/efJQxa6THL0W9MOia8rHIpb0GK11UKXgl8TAMkYQ7JMuwnDwifp7Ba/0HuRy5OfCil0DQSXdfBGANLmlUSERNoKTDeE3QhUQuOKk3REvxjrL3NIeccURTB2g5lWRJfHLKp0dQCNZ3hPoBLKFnJ+RUaj4cHsE8f+SogbiTypEK4jmmSBotNhqRQrtOODuOabMy9RZsU2U9BXSsU6zUy34ehwp7Y7ZC+z8GWS2gyhNsEwWxDsBVevmLs0xpFnoMxhjCryZbQtBVW8y0O3zE0TZ75S8TzGQwhuLs2bronsjnBLMrCQR1t9+RqKP3ZKnSmQ14xTP0nPC4mYGXmbP3lep3F/wJ2+AkYEM7hUAAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n    >\n      <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n        alt=\"01\"\n        title=\"\"\n        src=\"/devHistoryBlog/static/e71b16a7ec85bc1a46b34407e281e179/d9199/01.png\"\n        srcset=\"/devHistoryBlog/static/e71b16a7ec85bc1a46b34407e281e179/8ff5a/01.png 240w,\n/devHistoryBlog/static/e71b16a7ec85bc1a46b34407e281e179/e85cb/01.png 480w,\n/devHistoryBlog/static/e71b16a7ec85bc1a46b34407e281e179/d9199/01.png 960w,\n/devHistoryBlog/static/e71b16a7ec85bc1a46b34407e281e179/07a9c/01.png 1440w,\n/devHistoryBlog/static/e71b16a7ec85bc1a46b34407e281e179/29114/01.png 1920w,\n/devHistoryBlog/static/e71b16a7ec85bc1a46b34407e281e179/af777/01.png 3474w\"\n        sizes=\"(max-width: 960px) 100vw, 960px\"\n      />\n    </span>\n  </span>\n  \n  </a>\n    </p>\n<h3>✔️ 장점</h3>\n<ul>\n<li>필요한 페이즈의 매니페스트에 startupProbe를 등록하면 된다.</li>\n<li>웜업이 끝나기 전까지 다른 probe가 활성화 되지 않으므로 트래픽을 받지 않는다.</li>\n<li>웜업 수행시간이 길어지게 되면, startupProbe의 timeoutSeconds 값만 수정하면 된다.</li>\n</ul>\n<h3>✔️ 단점</h3>\n<ul>\n<li>startupProbe 를 위한 api 가 필요하다.</li>\n</ul>\n<br/>\n<h2>3. 결론</h2>\n<ul>\n<li>웜업 수행 시간이 짧다면 1번째 방법이 나쁘지 않다.</li>\n<li>하지만 트래픽이 많은 컴포넌트의 경우, 배포 실패 및 파드 무한 재시작이 일어날 수 있다.</li>\n<li>따라서 좀 더 안정적인 배포가 가능한 2번째 방법으로 선택하자.</li>\n</ul>\n<br/>\n<p>참고)<br>\n<a href=\"https://nearhome.tistory.com/89\">https://nearhome.tistory.com/89</a><br>\n<a href=\"https://kubernetes.io/ko/docs/concepts/workloads/pods/pod-lifecycle/\">https://kubernetes.io/ko/docs/concepts/workloads/pods/pod-lifecycle/</a></p>","fields":{"tagSlugs":["/tags/warmup/"],"slug":"/works/posts/2023-07-10--001"},"frontmatter":{"title":"warm up 은 어떻게 수행을 하는게 가장 좋을까?","tags":["warmup"],"date":"2023-07-10","description":""}}},"pageContext":{"slug":"/works/posts/2023-07-10--001"}},"staticQueryHashes":[]}