{"componentChunkName":"component---src-templates-post-template-jsx","path":"/works/posts/2024-06-15--002","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":"d56ae60d-7c61-579d-af46-27d1703210ce","html":"<h2>1. 구조 파악</h2>\n<p>구조가 좀 복잡하다…</p>\n<ol>\n<li>모바일에서 요청시에 제일 먼저 webapp nginx 로 요청이 들어오고</li>\n<li>사용자 인증을 위해 에서 kakaotalk pilsner server 프록시 하고</li>\n<li>pilsner 서버에서 계정 인증 후 webapp server 로 또 프록시 된다.</li>\n<li>그리고 webapp으로 프록시된 요청은 실제 api 서버로 요청을 하게된다.</li>\n</ol>\n<h4>요청 흐름도)</h4>\n<p><strong>모바일</strong> → <strong>webapp server</strong> -(proxy)→ <strong>필스너 서버</strong> -(proxy)→ <strong>webapp server</strong> -(proxy)→ <strong>디지털카드 api server</strong></p>\n<h4>응답 흐름도)</h4>\n<p><strong>디지털카드 api server</strong> -(proxy res)→ <strong>webapp server</strong> -(proxy res)→ <strong>필스너서버</strong> -(proxy res)→ <strong>webapp serve</strong>r → <strong>모바일</strong></p>\n<p>\n  <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/devHistoryBlog/static/fa0dcf3ba63f020a113f88e65a7ffed5/8ce22/02-001.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: 685px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 72.5%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsTAAALEwEAmpwYAAACGUlEQVQ4y41UXW/aMBTNj+cH7H1PaC97qDRVfdg0iapQPtsMWggh6QYBCoSGlCTk2yac2qawbGsnrnRl5/r6+Prc40jb7RZZloGPv50e57vdTvg+h7IRbATCMEAURYjjWHgYhuJb4snvmbVawRiP8TidwnUdEcuIjYx68Dwfi8UCc+amacJxHAF6BNxXwsZthCydi9hwOEJLlqGNDJiWLWKB+RnErYj5XfceXUVBf6CB0P2tchW+AidDOMYH+H6E+14PjVodxm0TT5Meq2KN1coWTkiKH507dHsKVFVBEkeg9BVwuVyiVCpBlm+xfLJg2w5bpNBZZfpNC+WLS3S0GrI4EMdyPrkpfRUDBvbp6w1k1WC3o5D4vceMJ9d1oWma4OVghBAkSYzu1MSjE4Kk6ZEebimhiEMfZ9ca2vqc8wVpNptB13VsNhtUKhVBLHJVREEApVGFpQ9YcHck561m8gIkz/MwmUxQKBRQLBZzDdpv8J5tPD9oqJe/4fzqYn/YNjgeats21uu1aIgA5Bu5jvjCwfKAlPEi+DI0fLn+DuJrCOYfRayvqkJWI+Y8n/P+hw7zQHmu8rGVZcK2DKaCANV6A/VmC23W7Yefv7Dx/b91+P6cX+/Aa5JQ8SpqjSYur8pMj11W7UCI+x/AU/yQbzK5VapVyO2OkJDDlPLfp3eKBUwVrushYGpIkhTS2z+H05w3AbmCUqbTF91dLc2vUy38AAAAAElFTkSuQmCC'); 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=\"02 001\"\n        title=\"\"\n        src=\"/devHistoryBlog/static/fa0dcf3ba63f020a113f88e65a7ffed5/8ce22/02-001.png\"\n        srcset=\"/devHistoryBlog/static/fa0dcf3ba63f020a113f88e65a7ffed5/8ff5a/02-001.png 240w,\n/devHistoryBlog/static/fa0dcf3ba63f020a113f88e65a7ffed5/e85cb/02-001.png 480w,\n/devHistoryBlog/static/fa0dcf3ba63f020a113f88e65a7ffed5/8ce22/02-001.png 685w\"\n        sizes=\"(max-width: 685px) 100vw, 685px\"\n      />\n    </span>\n  </span>\n  \n  </a>\n    </p>\n<br/>\n<h2>2. 이슈 내용</h2>\n<ul>\n<li>간헐적으로 모바일에서만 정적파일(js, css, html) 서빙시에 타임아웃 발생 또는 css가 깨진 화면이 노출</li>\n</ul>\n<br/>\n<h2>3. 원인</h2>\n<ul>\n<li>talk-pilsner OS upgrade를 작업을 위해 gslb 내 vip 하나를 Down 하였고,</li>\n<li>webapp nginx 는 talk-pilsner dns의 변경사항을 감지하고 못하고 down 된 vip로 요청.</li>\n<li>nginx는 proxy pass 할 talk-pilsner <strong>도메인의 vip 목록을 서버 실행시 캐싱하여 계속 사용하기 때문에 down된 vip로 요청</strong></li>\n</ul>\n<p>\n  <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/devHistoryBlog/static/3456062b96d1a337bb8ad41bcb768d84/91e7e/02-002.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: 692px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 70.83333333333333%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsTAAALEwEAmpwYAAACNUlEQVQ4y62Uy5LSUBCGeRs3PowLXbi3XLjQKh9Ai4UbyzeY0hpduLCsccuMeBkgOCByDSQZAgG5FhASgUwIBH5PnyQYmFnaVc2pc7rznT/dHSKO48B1XazX653TfrvdgozWw3iQs9lseJxW8tVqhQgFD42Se70eup0uhoMBTwzggU2nUwyHQ3RZHq26rsOyLA8Y3BJ+oFgqQ5RkSPUGQsfcDMPAYrFAWRQhyTIu6ypse8mF7CkkIN1imiZ+ZLKoForQxF+Y/9EZxMRsNkOr3cLR6yO8fXeM2Nln1NUGFFlib+FwURECNRoNxGIxaJrGYfaVjVQmA/VrAl++f4MxlhjMguMsYVtLjNoTTLsmBOEC1VoVp6k8mr/7JAkR27ahKAp/jUqlslM7mUxgMlVCTcPcWmDJYGSXcxEP83fwqHgPCrvIMud4dZLDRbXlAam4pIzAyWRyByT5pmmgXi7CXVxh7Xql6VganmUeI5p9CsPV+ZmztHk+lS9CygRBQDQaRSKR8GpJI8CCvZoI+TyOj5+OMZ2Z/7qy8d2/ODAOpJ/xeAxVVf3OeEmu39kx6+bd5w9Qa0reQ0wpmwnPQ7O6B9wezgUFC08w/HAL+sltWKn7ezHKD8OuAcPSdaa20+mjnX+PWvwF1MRLtH6+Qb8/QLPZxGg0uhF6Dbj1a1dlnY6fnSKbLSJXkJGvqDgXckin0+wsi1KpxAc4DL0R+D+MA4M/h8DpkL7dNXO++vtVaB/ODzvF/wKVESHe245AUQAAAABJRU5ErkJggg=='); 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=\"02 002\"\n        title=\"\"\n        src=\"/devHistoryBlog/static/3456062b96d1a337bb8ad41bcb768d84/91e7e/02-002.png\"\n        srcset=\"/devHistoryBlog/static/3456062b96d1a337bb8ad41bcb768d84/8ff5a/02-002.png 240w,\n/devHistoryBlog/static/3456062b96d1a337bb8ad41bcb768d84/e85cb/02-002.png 480w,\n/devHistoryBlog/static/3456062b96d1a337bb8ad41bcb768d84/91e7e/02-002.png 692w\"\n        sizes=\"(max-width: 692px) 100vw, 692px\"\n      />\n    </span>\n  </span>\n  \n  </a>\n    </p>\n<br/>\n<h2>4. 조치 내용</h2>\n<ul>\n<li>dns resolve 설정을 추가하여 talk-pilsner 도메인의 ip를 주기적으로 가져오도록 설정</li>\n<li>인증이 불필요한 정적 파일은 talk-pilsner를 타지 않도록 수정.</li>\n</ul>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">resolver <span class=\"token number\">10.20</span>.30.40 <span class=\"token assign-left variable\">valid</span><span class=\"token operator\">=</span>10s<span class=\"token punctuation\">;</span>\n \nserver <span class=\"token punctuation\">{</span>\n    location / <span class=\"token punctuation\">{</span>\n        <span class=\"token builtin class-name\">set</span> <span class=\"token variable\">$talk_pilsner</span> <span class=\"token string\">\"talk-pilsner.kakao.com\"</span><span class=\"token punctuation\">;</span>\n        proxy_pass http://<span class=\"token variable\">$talk_pilsner</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<br/>\n<h2>5. 참고 내용 - nginx 에서 도메인명을 이용하여 서비스를 검색하는 방법</h2>\n<h3>5-1. proxy_pass 지시어에 도메인명 사용</h3>\n<p>가장 간단한 방법이지만 가장 유연성이 떨어지는 방법이며 다음과 같은 단점이 있다.</p>\n<ul>\n<li>도메인 이름을 확인할 수 없는 경우 서버가 실행되지 않는다.</li>\n<li>재시작 할때까지 DNS 레코드를 캐시하고 레코드의 TTL도 무시한다.</li>\n<li>로드 밸런싱 알고리즘을 지정할 수 없다.</li>\n</ul>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">server <span class=\"token punctuation\">{</span>\n    location / <span class=\"token punctuation\">{</span>\n        proxy_pass http://talk-pilsner.kakao.com<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<br/>\n<h3>5-2. Upstream Server Group에 도메인명 사용</h3>\n<p>로드 밸런싱 알고리즘을 지정할 수 있다. (ex> least_conn)</p>\n<p>max_fails 를 지정하여 연속 요청이 지정한 횟수에 다다르면 서버가 다운 된것으로 표시.</p>\n<p>다음과 같은 단점이 여전히 존재</p>\n<ul>\n<li>도메인 이름을 확인할 수 없는 경우 서버가 실행되지 않는다.</li>\n<li>재시작 할때까지 DNS 레코드를 캐시하고 레코드의 TTL도 무시한다.</li>\n</ul>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">upstream talk_pilsner <span class=\"token punctuation\">{</span>\n    least_conn<span class=\"token punctuation\">;</span>\n \n    server talk-pilsner.kakao.com <span class=\"token assign-left variable\">max_fails</span><span class=\"token operator\">=</span><span class=\"token number\">3</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n \nserver <span class=\"token punctuation\">{</span>\n    location / <span class=\"token punctuation\">{</span>\n        proxy_pass http://talk_pilsner<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<br/>\n<h3>5-3. 변수에 도메인 이름 지정</h3>\n<p>도메인 이름을 다시 확인하는 빈도를 제어할 수 있다.</p>\n<p>resolver valid 설정을 통해 지정된 시간마다 도메인 이름을 다시 확인 하도록 할수 있다.</p>\n<p>도메인 이름을 확인 할 수 없을때 nginx 재시작 없이 서비스 탐색을 재시도 하기때문에 첫번째 방법의 두가지 단점을 보완할수 있다.</p>\n<p>단, 로드 밸런싱 알고리즘을 지정 할 수 없다.</p>\n<p>nginx plus를 사용하지 않는다면 가장 유연성이 높은 방법이다.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">resolver <span class=\"token number\">10.20</span>.30.40 <span class=\"token assign-left variable\">valid</span><span class=\"token operator\">=</span>10s<span class=\"token punctuation\">;</span>\n \nserver <span class=\"token punctuation\">{</span>\n    location / <span class=\"token punctuation\">{</span>\n        <span class=\"token builtin class-name\">set</span> <span class=\"token variable\">$talk_pilsner</span> <span class=\"token string\">\"talk-pilsner.kakao.com\"</span><span class=\"token punctuation\">;</span>\n        proxy_pass http://<span class=\"token variable\">$talk_pilsner</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>","fields":{"tagSlugs":["/tags/nginx/"],"slug":"/works/posts/2024-06-15--002"},"frontmatter":{"title":"nginx proxy serving 이슈","tags":["nginx"],"date":"2024-06-15","description":""}}},"pageContext":{"slug":"/works/posts/2024-06-15--002"}},"staticQueryHashes":[]}