<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Jay's Code Factory</title>
    <link>https://jay-ji.tistory.com/</link>
    <description>안녕하세요! 운동하는 개발자 Fitware Jay 입니다. ️&amp;zwj;♀️
함께자라기를 추구합니다  </description>
    <language>ko</language>
    <pubDate>Wed, 29 Jul 2026 09:40:54 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>피트웨어 제이 (FitwareJay)</managingEditor>
    <image>
      <title>Jay's Code Factory</title>
      <url>https://tistory1.daumcdn.net/tistory/2811652/attach/01aecb8d6f084d78a1a127f1b5915429</url>
      <link>https://jay-ji.tistory.com</link>
    </image>
    <item>
      <title>백엔드 개발자가 만들어 본 App 테스트 자동화 (feat. Appium, Jenkins, AWS DeviceFarm)</title>
      <link>https://jay-ji.tistory.com/122</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;225&quot; data-origin-height=&quot;225&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bSdrDb/btsC8YwEJMJ/Wo05guE77UVBApkfOfYqE1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bSdrDb/btsC8YwEJMJ/Wo05guE77UVBApkfOfYqE1/img.png&quot; data-alt=&quot;제가 만든 프로젝트 로고 QA(QuokkA)ㅋㅋ&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bSdrDb/btsC8YwEJMJ/Wo05guE77UVBApkfOfYqE1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbSdrDb%2FbtsC8YwEJMJ%2FWo05guE77UVBApkfOfYqE1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;278&quot; height=&quot;278&quot; data-origin-width=&quot;225&quot; data-origin-height=&quot;225&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;제가 만든 프로젝트 로고 QA(QuokkA)ㅋㅋ&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요! QA엔지니어(?) Jay입니다 ㅋㅋㅋㅋ ~는 아니고 저는 백엔드 개발자입니다. 오늘 이렇게 시작을 한 이유는 최근 회사에서 했던 과제 중 하나가 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;앱로그 QA 자동화&lt;/b&gt;&lt;/span&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&quot;갑자기 왠 QA?&quot;&lt;/b&gt;라고 하신다면...ㅋㅋ 해당 과제가 중요하기도 했고 저희팀이 플랫폼 전반적인 과제들을 하고 있기 때문에 저희팀에서 과제를 가져와서 진행하게 되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;게다가 단순히 앱 UI 테스트 자동화는 아니고, 앱에서 어떤 액션을 할때마다 정상적으로 로그가 남는지까지 확인하는 &lt;b&gt;End-To-End 테스트&lt;/b&gt;라서 백엔드 영역의 핸들링도 필요하기 때문에 저희 쪽에서 진행하게 된 이유도 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런저런 이유로 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;제가 진행했던 과제에서 App 테스트 자동화를 어떤 식으로 했고 어떤 기술들을 이용했는지 정리 및 소개&lt;/b&gt;&lt;/span&gt;를 하려고 합니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. 어떤 기술을 사용했나?!&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1006&quot; data-origin-height=&quot;216&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c7jGdx/btsC8WldMO3/mCMz8eRFRgpVfDjA12cRW0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c7jGdx/btsC8WldMO3/mCMz8eRFRgpVfDjA12cRW0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c7jGdx/btsC8WldMO3/mCMz8eRFRgpVfDjA12cRW0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc7jGdx%2FbtsC8WldMO3%2FmCMz8eRFRgpVfDjA12cRW0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;363&quot; height=&quot;78&quot; data-origin-width=&quot;1006&quot; data-origin-height=&quot;216&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://appium.io/docs/en/2.4/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Appium&lt;/a&gt;&lt;/span&gt;이란  오픈소스 서비스를 사용했습니다~ 특별히 다른 서비스를 찾아보진 않았고 Appium이 가장 많이 쓰이는 것 같아 Appium을 선택했습니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;Appium은 모바일(iOS, Android, Tizen), 브라우저(Chrome, Firefox, Safari), 데스크톱(macOS, Windows), TV를 포함한 많은 앱 플랫폼의 UI 자동화를 용이하게 하도록 설계된 오픈 소스 프로젝트이자 관련 소프트웨어의 생태계입니다. (Roku, tvOS, Android TV, Samsung)&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;네 그렇다고 합니다ㅋㅋ Appium을 사용하는 방법은 대략적으로 아래와 같습니다.&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal; background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Appium 설치&lt;/li&gt;
&lt;li&gt;Appium 드라이버 및 해당 종속성을 설치. (ios = xcuitest, android =uiautomator2)&lt;/li&gt;
&lt;li&gt;선택한 언어로 Appium 클라이언트 라이브러리를 설치합니다(JavaScript, Python, Java, Ruby 및 .NET를 지원하는 Appium 라이브러리가 있습니다. 사용하시는 언어에 맞게 설치하시면 됩니다.)&lt;/li&gt;
&lt;li&gt;샘플 애플리케이션을 사용하여 간단한 Appium 자동화 스크립트 작성 및 실행&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 포스팅에서는 전체적인 설치에 대한 가이드는 이야기하지 않겠습니다. (Appium 설치 가이드는 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://appium.io/docs/en/2.4/quickstart/install/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;여기&lt;/a&gt;&lt;/span&gt;를 확인해 주세요!)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1160&quot; data-origin-height=&quot;550&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MXghD/btsC6R5ROxx/D6kVupOpXJvWlxfz8KK68k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MXghD/btsC6R5ROxx/D6kVupOpXJvWlxfz8KK68k/img.png&quot; data-alt=&quot;Appium을 정상적으로 설치하고 실행시키면 요런 모습들을 볼 수 있습니다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MXghD/btsC6R5ROxx/D6kVupOpXJvWlxfz8KK68k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMXghD%2FbtsC6R5ROxx%2FD6kVupOpXJvWlxfz8KK68k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;641&quot; height=&quot;304&quot; data-origin-width=&quot;1160&quot; data-origin-height=&quot;550&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Appium을 정상적으로 설치하고 실행시키면 요런 모습들을 볼 수 있습니다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. 테스트 디바이스 실행 및 연결&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 테스트를 실행하기 위해서는 디바이스가 있어야 합니다. 하지만 우리는 모든 디바이스를 가지고 있지 않기 때문에 가상 디바이스를 활용합니다! (다만 여기서 함정이 있습니다. 함정은 잠시 후 공개....)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 Android의 경우 Android Studio Emulator를 사용할 수 있습니다. ios도 마찬가지로 Xcode Simulator를 사용할 수 있는데... 여기서 함정이 있습니다. &lt;b&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;ios Simulator 같은 경우에는 ipa파일이 설치가 안되더라고요... 직접 만든 앱을 Simulator에 빌드(Build)해서 실행시키는 건 됩니다&lt;/span&gt;&lt;/b&gt;. 그래서 ios 같은 경우에는 부득이하게 실제 Device를 연결해서 테스트를 진행했습니다. (혹시 방법을 아신다면 댓글로...)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 이번 포스팅에서는 Android 기준으로 설명해보려고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://developer.android.com/studio/install?hl=ko&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Android Studio 설치 링크&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://developer.android.com/studio/run/emulator?hl=ko&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Android Emulator 실행 방법 링크&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1308&quot; data-origin-height=&quot;1482&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cwk1mE/btsC1nky5gO/KMZEXm3FTzl6KdgWbzlQuK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cwk1mE/btsC1nky5gO/KMZEXm3FTzl6KdgWbzlQuK/img.png&quot; data-alt=&quot;Android Emulator 실행 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cwk1mE/btsC1nky5gO/KMZEXm3FTzl6KdgWbzlQuK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcwk1mE%2FbtsC1nky5gO%2FKMZEXm3FTzl6KdgWbzlQuK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;399&quot; height=&quot;452&quot; data-origin-width=&quot;1308&quot; data-origin-height=&quot;1482&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Android Emulator 실행 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. 테스트를 위한 사전 작업&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 테스트를 진행하려면 테스트할 apk가 있어야 합니다.&amp;nbsp; 아래 블로그에서 sample apk를 제공해 주셔서 요걸 사용해 보겠습니다. 감사합니다!!&lt;/p&gt;
&lt;figure id=&quot;og_1704547513831&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;App 테스트 자동화를 위한 Sample Test App 공유 (APK)&quot; data-og-description=&quot;2023년 목표 중 하나는 바로 QA Engineer 강의를 만드는 것이였습니다. 그래서 마이크도 구매하고 실제로 동영상을 촬영하기도 하였지만 상업용으로 사용할 수 있는 어플이 없어서 강의 영상촬영을 &quot; data-og-host=&quot;goddessbest-qa.tistory.com&quot; data-og-source-url=&quot;https://goddessbest-qa.tistory.com/263&quot; data-og-url=&quot;https://goddessbest-qa.tistory.com/263&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/xKqbb/hyU2pQaQ01/cVjXRyoB2UYbwFdHX5J7H0/img.jpg?width=800&amp;amp;height=1777&amp;amp;face=0_0_800_1777,https://scrap.kakaocdn.net/dn/r3T2T/hyU2p3GOtE/oPdXYlJtzwr6qvghVC1fVk/img.jpg?width=800&amp;amp;height=1777&amp;amp;face=0_0_800_1777,https://scrap.kakaocdn.net/dn/fL3DD/hyU2e8WgSx/ntsjgZnioBn7j6ohXhl4Qk/img.jpg?width=1080&amp;amp;height=2400&amp;amp;face=0_0_1080_2400&quot;&gt;&lt;a href=&quot;https://goddessbest-qa.tistory.com/263&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://goddessbest-qa.tistory.com/263&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/xKqbb/hyU2pQaQ01/cVjXRyoB2UYbwFdHX5J7H0/img.jpg?width=800&amp;amp;height=1777&amp;amp;face=0_0_800_1777,https://scrap.kakaocdn.net/dn/r3T2T/hyU2p3GOtE/oPdXYlJtzwr6qvghVC1fVk/img.jpg?width=800&amp;amp;height=1777&amp;amp;face=0_0_800_1777,https://scrap.kakaocdn.net/dn/fL3DD/hyU2e8WgSx/ntsjgZnioBn7j6ohXhl4Qk/img.jpg?width=1080&amp;amp;height=2400&amp;amp;face=0_0_1080_2400');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;App 테스트 자동화를 위한 Sample Test App 공유 (APK)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;2023년 목표 중 하나는 바로 QA Engineer 강의를 만드는 것이였습니다. 그래서 마이크도 구매하고 실제로 동영상을 촬영하기도 하였지만 상업용으로 사용할 수 있는 어플이 없어서 강의 영상촬영을&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;goddessbest-qa.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트할 apk도 생겼으니 이제 테스트 스크립트를 작성해 볼까요?!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그전에 먼저 테스트를 하려면 UI Element들을 제어하기 위해 어떤 값들을 가졌는지 알아야 하는데요. 이걸 가능하게 하는 게 바로 &lt;b&gt;Appium inscpector&lt;/b&gt;라는 툴입니다. 릴리즈 파일들은 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://github.com/appium/appium-inspector/releases&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;여기&lt;/a&gt;&lt;/span&gt;에서 확인할 수 있으니 os 맞게 설치해 주시면 됩니다!&lt;/p&gt;
&lt;figure id=&quot;og_1704547958045&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - appium/appium-inspector: A GUI inspector for mobile apps and more, powered by a (separately installed) Appium server&quot; data-og-description=&quot;A GUI inspector for mobile apps and more, powered by a (separately installed) Appium server - GitHub - appium/appium-inspector: A GUI inspector for mobile apps and more, powered by a (separately in...&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/appium/appium-inspector&quot; data-og-url=&quot;https://github.com/appium/appium-inspector&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/jLgi1/hyUXRguyLD/pnK2uGwcGpopM4fqzj97S0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/appium/appium-inspector&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/appium/appium-inspector&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/jLgi1/hyUXRguyLD/pnK2uGwcGpopM4fqzj97S0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - appium/appium-inspector: A GUI inspector for mobile apps and more, powered by a (separately installed) Appium server&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;A GUI inspector for mobile apps and more, powered by a (separately installed) Appium server - GitHub - appium/appium-inspector: A GUI inspector for mobile apps and more, powered by a (separately in...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Appium Inspector를 실행하면 이런 창을 확인할 수 있습니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1422&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8igqc/btsC4HbwYFi/K2NutXODqrVBuVxakLjYBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8igqc/btsC4HbwYFi/K2NutXODqrVBuVxakLjYBk/img.png&quot; data-alt=&quot;Appium-Inspector 실행 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8igqc/btsC4HbwYFi/K2NutXODqrVBuVxakLjYBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8igqc%2FbtsC4HbwYFi%2FK2NutXODqrVBuVxakLjYBk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;560&quot; height=&quot;350&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1422&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Appium-Inspector 실행 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Appium Inspector를 통해 앱에 접근하기 위해서는 당연히 Appium Server가 실행되어 있어야 하고 몇 가지 값들을 Capability에 정의해줘야 합니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;- Android Emulator&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1704548192120&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  &quot;platformName&quot;: &quot;Android&quot;, 
  &quot;appium:automationName&quot;: &quot;uiautomator2&quot;, // 안드로이드 전용 드라이버
  &quot;appium:deviceName&quot;: &quot;emulator-5554&quot;, // 안드로이드 에뮬레이터는 이 이름으로 고정
  &quot;appium:app&quot;: &quot;.../app.apk&quot; // apk 경로
}&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;- ios Device&amp;nbsp;&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1704605572586&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  &quot;platformName&quot;: &quot;ios&quot;,
  &quot;appium:automationName&quot;: &quot;XCUITest&quot;,  // ios driver
  &quot;appium:platformVersion&quot;: &quot;17.2&quot;,
  &quot;appium:deviceName&quot;: &quot;iPhone12&quot;,
  &quot;appium:app&quot;: &quot;../app.ipa&quot;, // 앱 경로
  &quot;appium:wdaBaseUrl&quot;: &quot;http://xxx.xxx.xxx.xxx:8100&quot;, // wda 로컬 네트워크
  &quot;appium:xcodeSigningId&quot;: &quot;iPhone Developer&quot;,
  &quot;appium:xcodeOrgId&quot;: &quot;&quot;,   // xcode org id
  &quot;appium:udid&quot;: &quot;&quot;  // device UDID
}&lt;/code&gt;&lt;/pre&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;- ios Simulator&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1704606994622&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  &quot;platformName&quot;: &quot;ios&quot;,
  &quot;appium:automationName&quot;: &quot;XCUITest&quot;,
  &quot;appium:platformVersion&quot;: &quot;17.2&quot;,
  &quot;appium:udid&quot;: &quot;&quot;,
  &quot;appium:deviceName&quot;: &quot;simulator&quot;,
  &quot;appium:bundleId&quot;: &quot;&quot; # 앱 번들 ID
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저의 경우 위에 서서도 말했지만 Simulator에 ipa 파일 설치하는 게 안 됐어서 Device로 테스트를 진행했습니다. 상황에 맞게 선택해 주시면 될 것 같아요!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 ios의 경우 실 디바이스, Simulator에서 Appium을 사용하려면 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://github.com/appium/WebDriverAgent&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;WebDriverAgent&lt;/a&gt;&lt;/span&gt;라는 앱이 필요합니다. WebDriverAgent 설치 관련 내용은 아래 블로그를 참고해 주세요!&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1704606887569&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Appium - iOS 환경 셋팅&quot; data-og-description=&quot;Appium에서 iOS를 실행할 수 있도록 환경 셋팅하기&quot; data-og-host=&quot;velog.io&quot; data-og-source-url=&quot;https://velog.io/@tkjung/Appium-iOS-%ED%99%98%EA%B2%BD-%EC%85%8B%ED%8C%85&quot; data-og-url=&quot;https://velog.io/@tkjung/Appium-iOS-환경-셋팅&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/DNWFz/hyUXWa6wxR/1sczKSdV0nZQt3ooKV2KGk/img.png?width=689&amp;amp;height=523&amp;amp;face=0_0_689_523,https://scrap.kakaocdn.net/dn/czr6gb/hyU2rAwiJJ/mQgY0oeU31P7kefVpTiSX1/img.png?width=689&amp;amp;height=523&amp;amp;face=0_0_689_523,https://scrap.kakaocdn.net/dn/bJShWd/hyU2ujIElx/jxKu0CnsoNoFbZJLnT5EBk/img.png?width=1536&amp;amp;height=401&amp;amp;face=0_0_1536_401&quot;&gt;&lt;a href=&quot;https://velog.io/@tkjung/Appium-iOS-%ED%99%98%EA%B2%BD-%EC%85%8B%ED%8C%85&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://velog.io/@tkjung/Appium-iOS-%ED%99%98%EA%B2%BD-%EC%85%8B%ED%8C%85&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/DNWFz/hyUXWa6wxR/1sczKSdV0nZQt3ooKV2KGk/img.png?width=689&amp;amp;height=523&amp;amp;face=0_0_689_523,https://scrap.kakaocdn.net/dn/czr6gb/hyU2rAwiJJ/mQgY0oeU31P7kefVpTiSX1/img.png?width=689&amp;amp;height=523&amp;amp;face=0_0_689_523,https://scrap.kakaocdn.net/dn/bJShWd/hyU2ujIElx/jxKu0CnsoNoFbZJLnT5EBk/img.png?width=1536&amp;amp;height=401&amp;amp;face=0_0_1536_401');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Appium - iOS 환경 셋팅&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Appium에서 iOS를 실행할 수 있도록 환경 셋팅하기&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;velog.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2276&quot; data-origin-height=&quot;1412&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bsabbm/btsC6RY0akc/PqrJXHmFFDecjKAYZ26pE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bsabbm/btsC6RY0akc/PqrJXHmFFDecjKAYZ26pE0/img.png&quot; data-alt=&quot;capability가 입려된 Appium-Inspector&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bsabbm/btsC6RY0akc/PqrJXHmFFDecjKAYZ26pE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbsabbm%2FbtsC6RY0akc%2FPqrJXHmFFDecjKAYZ26pE0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;566&quot; height=&quot;351&quot; data-origin-width=&quot;2276&quot; data-origin-height=&quot;1412&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;capability가 입려된 Appium-Inspector&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Capability에 대한 자세한 내용은 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://github.com/appium/appium-xcuitest-driver/blob/master/docs/capabilities.md&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;capabilites.md&lt;/a&gt;&lt;/span&gt;를 참고해 주세요!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Start Session 버튼을 클릭하면 Emulator에 앱이 설치되면서 Appium Inspector에서 앱의 화면을 캡처한 형태로 보이게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2268&quot; data-origin-height=&quot;1412&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vhyFC/btsC4civ8bi/I2EC9IBOlYDlKg4kq5l79k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vhyFC/btsC4civ8bi/I2EC9IBOlYDlKg4kq5l79k/img.png&quot; data-alt=&quot;앱 실행과 함께 화면이 캡처된다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vhyFC/btsC4civ8bi/I2EC9IBOlYDlKg4kq5l79k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvhyFC%2FbtsC4civ8bi%2FI2EC9IBOlYDlKg4kq5l79k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;654&quot; height=&quot;407&quot; data-origin-width=&quot;2268&quot; data-origin-height=&quot;1412&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;앱 실행과 함께 화면이 캡처된다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1420&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dxjXSw/btsC6zD5rDW/0HNXYwMd06HOh8O1xyp3K1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dxjXSw/btsC6zD5rDW/0HNXYwMd06HOh8O1xyp3K1/img.png&quot; data-alt=&quot;화면의 UI Element를 클릭하면 선택한 Element의 속성들이 보입니다&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dxjXSw/btsC6zD5rDW/0HNXYwMd06HOh8O1xyp3K1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdxjXSw%2FbtsC6zD5rDW%2F0HNXYwMd06HOh8O1xyp3K1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;656&quot; height=&quot;410&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1420&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;화면의 UI Element를 클릭하면 선택한 Element의 속성들이 보입니다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 이미지처럼 &lt;b&gt;UI Element를 클릭하면 속성들을 확인할 수 있고 이 속성값들을 이용해서 앱을 제어할 수 있습니다!&lt;/b&gt; 참고로 이 화면은 앱 화면에 따라 자동으로 변경되진 않고 상단의 돋보기 버튼 왼쪽에 있는 새로고침 버튼을 클릭해야지 현재 화면 기준으로 캡처가 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자 이제 본격적으로 테스트 스크립트를 작성해 보겠습니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;4. 테스트 스크립트 작성&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Appium에 접근해서 앱을 제어하기 위한 라이브러리들을 Appium에서 제공을 하는데요. 다양한 언어로 된 라이브러리를 제공합니다. 저는 python이 주 언어이이기 때문에 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://github.com/appium/python-client&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Appium-Python-Client&lt;/a&gt;&lt;/span&gt;를 사용했습니다!&amp;nbsp; 본인에게 맞는 언어로 사용하시면 될 것 같고 저는 python 기준으로 테스트 코드를 작성해 보겠습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트 코드는 깃헙에 업로드해놨으니 참고해 주세요!&lt;/p&gt;
&lt;figure id=&quot;og_1704616292056&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - JAY-Chan9yu/appium-python-example&quot; data-og-description=&quot;Contribute to JAY-Chan9yu/appium-python-example development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/JAY-Chan9yu/appium-python-example&quot; data-og-url=&quot;https://github.com/JAY-Chan9yu/appium-python-example&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dvYY3i/hyUXYz2tpJ/b18boEIiKjzjwDozsJkEW1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/JAY-Chan9yu/appium-python-example&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/JAY-Chan9yu/appium-python-example&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dvYY3i/hyUXYz2tpJ/b18boEIiKjzjwDozsJkEW1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - JAY-Chan9yu/appium-python-example&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Contribute to JAY-Chan9yu/appium-python-example development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;python을 사용해 보신 분들이라면 unnittest, pytest에 대해서 한 번쯤 들어 보셨을 텐데요. Appium 테스트도 똑같습니다! 일단은 Appium Driver를 연결을 위한 BaseTest 클래스를 만듭니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1872&quot; data-origin-height=&quot;1914&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Clknj/btsC30CyRb2/8teknhJkrIWWCHM4omkdG0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Clknj/btsC30CyRb2/8teknhJkrIWWCHM4omkdG0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Clknj/btsC30CyRb2/8teknhJkrIWWCHM4omkdG0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FClknj%2FbtsC30CyRb2%2F8teknhJkrIWWCHM4omkdG0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1872&quot; height=&quot;1914&quot; data-origin-width=&quot;1872&quot; data-origin-height=&quot;1914&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;BaseTest 클래스에서는 Driver를 통해 Appium Server와 session을 맺고 끊는 역할을 제공합니다. 이 클래스를 상속해서 Test Class를 구현하면 됩니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트 코드를 짤 때 보통 page단위로 Element와 Action들을 정리를 하더라고요! 그래서 이 page들에 공통으로 기능을 제공해 주는 BasePage 클래스를 만들고 이 클래스를 상속해서 테스트할 페이지를 구현해 보겠습니다. 저희는 샘플 앱의 home page를 테스트할 예정입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1872&quot; data-origin-height=&quot;1750&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7ZA4R/btsC5ZC69nO/4TdQtTLK3c0e8HCziwuDlk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7ZA4R/btsC5ZC69nO/4TdQtTLK3c0e8HCziwuDlk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7ZA4R/btsC5ZC69nO/4TdQtTLK3c0e8HCziwuDlk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7ZA4R%2FbtsC5ZC69nO%2F4TdQtTLK3c0e8HCziwuDlk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1872&quot; height=&quot;1750&quot; data-origin-width=&quot;1872&quot; data-origin-height=&quot;1750&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;BasePage에서는 click, get_element, send_keys와 같은 공통 동작들을 구현해 놓았습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1872&quot; data-origin-height=&quot;1380&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BYQYn/btsC31uFYFz/Kf0gkYKLREPjNsOlL0PmHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BYQYn/btsC31uFYFz/Kf0gkYKLREPjNsOlL0PmHk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BYQYn/btsC31uFYFz/Kf0gkYKLREPjNsOlL0PmHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBYQYn%2FbtsC31uFYFz%2FKf0gkYKLREPjNsOlL0PmHk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1872&quot; height=&quot;1380&quot; data-origin-width=&quot;1872&quot; data-origin-height=&quot;1380&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HomePage에는 홈화면의 버튼들과 그 버튼들에 대한 액션을 정의했습니다. 각 element들의 속성은 Appium Inspector를 통해서 추출하면 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1872&quot; data-origin-height=&quot;1174&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sVQYs/btsDbc8YTZT/1GKoKFZL7A2lDH0K11csh1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sVQYs/btsDbc8YTZT/1GKoKFZL7A2lDH0K11csh1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sVQYs/btsDbc8YTZT/1GKoKFZL7A2lDH0K11csh1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsVQYs%2FbtsDbc8YTZT%2F1GKoKFZL7A2lDH0K11csh1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1872&quot; height=&quot;1174&quot; data-origin-width=&quot;1872&quot; data-origin-height=&quot;1174&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 정의한 BaseTest, BasePage, HomePage 클래스들을 사용해서 테스트 케이스를 작성해 봤습니다. 코드는 특별히 설명이 없어서 보시면 어떤 액션들을 할지 알아보실 거 같아서 따로 설명은 드리지 않고 동작이 어떻게 되는지 영상으로 공유드리겠습니다.&lt;/p&gt;

            &lt;figure class=&quot;unsupported component-kakaotv&quot; contenteditable=&quot;false&quot; style=&quot;background:#000;margin:16px 0;min-height:72px;padding:10px 16px;display:flex;align-items:center;justify-content:center;text-align:center;box-sizing:border-box;width:100%;max-width:100%;&quot;&gt;
                &lt;p contenteditable=&quot;false&quot; style=&quot;margin:0;color:#8a8a8a;font-size:13px;line-height:1.6;user-select:none;pointer-events:none;&quot;&gt;동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.&lt;/p&gt;
            &lt;/figure&gt;
        
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아주 잘 동작하는 걸 볼 수 있습니다! 여기까지가 이제 로컬에서 테스트하는 방법이었고 테스트 자동화라고 하기엔 뭔가 부족하죠?!ㅎㅎ 그래서 좀 더 자동화에 가깝게 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;Jenkins + DeviceFarm을 연동하는 방법&lt;/b&gt;&lt;/span&gt;에 대해 간단하게 설명드리겠습니다. (깊게 설명하자면 글이 너무 길어져서 어떤 식으로 연동했는지 정도만 말씀드릴게요)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;5. Jenkins + DeviceFarm 연동 테스트 자동화&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Jenkins 같은 경우 CI/CD 파이프라인으로 많이들 사용하고 있습니다. 그럼 DeviceFarm은 무엇인가?! 두둔!&lt;/p&gt;
&lt;figure id=&quot;og_1704612090832&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;company&quot; data-og-title=&quot;AWS Device Farm | 모바일 및 웹 앱 테스트 | Amazon Web Services&quot; data-og-description=&quot;수동으로 문제를 재현하고, 병렬로 자동 테스트를 실행합니다. AWS에서는 동영상, 로그 및 성능 데이터를 수집하므로, 이를 분석하여 문제를 신속하게 해결할 수 있습니다. 자동화된 테스트의 경&quot; data-og-host=&quot;aws.amazon.com&quot; data-og-source-url=&quot;https://aws.amazon.com/ko/device-farm/&quot; data-og-url=&quot;https://aws.amazon.com/ko/device-farm/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bvCPP2/hyU2hq9ZxK/IEK77UMDbE9bKlG5dq15Xk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/xvOh6/hyU2kOXehf/HZPbk03Aa1XaZdjikb2oY1/img.png?width=179&amp;amp;height=109&amp;amp;face=0_0_179_109,https://scrap.kakaocdn.net/dn/QguCW/hyU2rHiHiE/ysfBbQUWwF4XbM45ALDUnK/img.png?width=1876&amp;amp;height=626&amp;amp;face=0_0_1876_626&quot;&gt;&lt;a href=&quot;https://aws.amazon.com/ko/device-farm/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://aws.amazon.com/ko/device-farm/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bvCPP2/hyU2hq9ZxK/IEK77UMDbE9bKlG5dq15Xk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/xvOh6/hyU2kOXehf/HZPbk03Aa1XaZdjikb2oY1/img.png?width=179&amp;amp;height=109&amp;amp;face=0_0_179_109,https://scrap.kakaocdn.net/dn/QguCW/hyU2rHiHiE/ysfBbQUWwF4XbM45ALDUnK/img.png?width=1876&amp;amp;height=626&amp;amp;face=0_0_1876_626');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;AWS Device Farm | 모바일 및 웹 앱 테스트 | Amazon Web Services&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;수동으로 문제를 재현하고, 병렬로 자동 테스트를 실행합니다. AWS에서는 동영상, 로그 및 성능 데이터를 수집하므로, 이를 분석하여 문제를 신속하게 해결할 수 있습니다. 자동화된 테스트의 경&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;aws.amazon.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;AWS DeviceFarm은 테스트 인프라를 프로비저닝하고 관리하지 않아도 다양한 데스크톱 브라우저 및 실제 모바일 디바이스에서 테스트를 진행하여 웹 및 모바일 앱 품질을 향상시키는 애플리케이션 테스트 서비스입니다. 테스트를 통해 여러 데스크톱 브라우저나 실제 디바이스에서 동시에 테스트를 실행함으로써 테스트 도구 실행 속도를 높이고 비디오 및 로그를 생성하여 앱과 관련된 문제를 빠르게 식별할 수 있습니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;말 그대로 저희가 &lt;b&gt;테스트를 위해 여러 디바이스를 구비하지 않아도 AWS를 통해서 테스트할 수 있는 디바이스들을 빌려서 사용&lt;/b&gt;한다고 생각하시면 됩니다. 디바이스를 대여하는 것, 사용한 만큼 지불하는 것 등 여러 옵션이 있습니다. 기본적으로 1000분의 Free Trial을 제공해 주기 때문에 테스트하시는데 큰 어려움은 없으실 겁니다! (&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://aws.amazon.com/ko/device-farm/pricing/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;요금정책&lt;/a&gt;&lt;/span&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 Jenkins에는 DeviceFarm과 연동할 수 있는 플러그인(Plugin)을 제공하기 때문에 쉽게 연동할 수 있습니다. 처음에는 요걸 몰라서 직접 DeviceFarm API를 호출해서 파이썬 스크립트로 자동화를 구현하다가 뒤늦게 해당 플러그인을 발견했네요 ㅋㅋㅋ 그래도 boto3로 DeviceFarm API호출하는 것도 나름 재밌습니다. (&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://plugins.jenkins.io/aws-device-farm/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;jenkins-aws-device-farm plugin&lt;/a&gt;&lt;/span&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS 공식문서에 가보시면 jenkins와 연동하는 방법에 대해 나와있으니 구현하실 때 참고 하시면 될 것 같습니다. 저 같은 경우 Jenkins를 도커로 설치한 뒤 진행했습니다.&lt;/p&gt;
&lt;figure id=&quot;og_1704612494178&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;AWS Device Farm integration with Jenkins CI plugin - AWS Device Farm&quot; data-og-description=&quot;Thanks for letting us know this page needs work. We're sorry we let you down. If you've got a moment, please tell us how we can make the documentation better.&quot; data-og-host=&quot;docs.aws.amazon.com&quot; data-og-source-url=&quot;https://docs.aws.amazon.com/devicefarm/latest/developerguide/continuous-integration-jenkins-plugin.html&quot; data-og-url=&quot;https://docs.aws.amazon.com/devicefarm/latest/developerguide/continuous-integration-jenkins-plugin.html&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/kIREX/hyU2iKnKeP/BCI2D8qtitYNgWsVK8ek10/img.png?width=741&amp;amp;height=728&amp;amp;face=0_0_741_728,https://scrap.kakaocdn.net/dn/Tk6XO/hyUXXHUYDm/rQ7GZ6NKPOHuakNtzT0tkK/img.png?width=854&amp;amp;height=360&amp;amp;face=0_0_854_360&quot;&gt;&lt;a href=&quot;https://docs.aws.amazon.com/devicefarm/latest/developerguide/continuous-integration-jenkins-plugin.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.aws.amazon.com/devicefarm/latest/developerguide/continuous-integration-jenkins-plugin.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/kIREX/hyU2iKnKeP/BCI2D8qtitYNgWsVK8ek10/img.png?width=741&amp;amp;height=728&amp;amp;face=0_0_741_728,https://scrap.kakaocdn.net/dn/Tk6XO/hyUXXHUYDm/rQ7GZ6NKPOHuakNtzT0tkK/img.png?width=854&amp;amp;height=360&amp;amp;face=0_0_854_360');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;AWS Device Farm integration with Jenkins CI plugin - AWS Device Farm&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Thanks for letting us know this page needs work. We're sorry we let you down. If you've got a moment, please tell us how we can make the documentation better.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.aws.amazon.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;figure id=&quot;og_1704612820477&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;What is AWS Device Farm? - AWS Device Farm&quot; data-og-description=&quot;What is AWS Device Farm? Device Farm is an app testing service that you can use to test and interact with your Android, iOS, and web apps on real, physical phones and tablets that are hosted by Amazon Web Services (AWS). There are two main ways to use Devi&quot; data-og-host=&quot;docs.aws.amazon.com&quot; data-og-source-url=&quot;https://docs.aws.amazon.com/devicefarm/latest/developerguide/welcome.html&quot; data-og-url=&quot;https://docs.aws.amazon.com/devicefarm/latest/developerguide/welcome.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://docs.aws.amazon.com/devicefarm/latest/developerguide/welcome.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.aws.amazon.com/devicefarm/latest/developerguide/welcome.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;What is AWS Device Farm? - AWS Device Farm&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;What is AWS Device Farm? Device Farm is an app testing service that you can use to test and interact with your Android, iOS, and web apps on real, physical phones and tablets that are hosted by Amazon Web Services (AWS). There are two main ways to use Devi&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.aws.amazon.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3374&quot; data-origin-height=&quot;1078&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/U1mxy/btsC4pa20Gu/iUqRZlTq0KzLN7pWnU6Wn1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/U1mxy/btsC4pa20Gu/iUqRZlTq0KzLN7pWnU6Wn1/img.png&quot; data-alt=&quot;테스트 자동화 파이프라인 설명&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/U1mxy/btsC4pa20Gu/iUqRZlTq0KzLN7pWnU6Wn1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FU1mxy%2FbtsC4pa20Gu%2FiUqRZlTq0KzLN7pWnU6Wn1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3374&quot; height=&quot;1078&quot; data-origin-width=&quot;3374&quot; data-origin-height=&quot;1078&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;테스트 자동화 파이프라인 설명&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjVsxA/btsC33MMoPW/USdjZkeECIXxpreuIJCfw1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjVsxA/btsC33MMoPW/USdjZkeECIXxpreuIJCfw1/img.png&quot; data-origin-width=&quot;2318&quot; data-origin-height=&quot;2278&quot; data-is-animation=&quot;false&quot; style=&quot;width: 27.9015%; margin-right: 10px;&quot; data-widthpercent=&quot;28.57&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjVsxA/btsC33MMoPW/USdjZkeECIXxpreuIJCfw1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjVsxA%2FbtsC33MMoPW%2FUSdjZkeECIXxpreuIJCfw1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2318&quot; height=&quot;2278&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sslm3/btsDbeZ2mr4/FTGG6FxAx5P8gputETE8ik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sslm3/btsDbeZ2mr4/FTGG6FxAx5P8gputETE8ik/img.png&quot; style=&quot;width: 43.2602%; margin-right: 10px;&quot; data-origin-width=&quot;3168&quot; data-origin-height=&quot;2008&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;44.29&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sslm3/btsDbeZ2mr4/FTGG6FxAx5P8gputETE8ik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fsslm3%2FbtsDbeZ2mr4%2FFTGG6FxAx5P8gputETE8ik%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3168&quot; height=&quot;2008&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nooIl/btsC53Fuc95/DlFvkBlyp8Iht4dVwTSY8K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nooIl/btsC53Fuc95/DlFvkBlyp8Iht4dVwTSY8K/img.png&quot; style=&quot;width: 26.5127%;&quot; width=&quot;516&quot; height=&quot;534&quot; data-origin-width=&quot;2104&quot; data-origin-height=&quot;2176&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;27.14&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nooIl/btsC53Fuc95/DlFvkBlyp8Iht4dVwTSY8K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnooIl%2FbtsC53Fuc95%2FDlFvkBlyp8Iht4dVwTSY8K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2104&quot; height=&quot;2176&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;jenkins에서 테스트할 apk를 업로드하고 github branch를 선택해서 build하게 되면 AWS DeviceFarm에서 테스트가 실행하고 결과를 알려준다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최종적으로 제가 구현한 형태는 위 이미지처럼 동작합니다. 필요에 따라서 apk 빌드부터 업로드하는 부분까지 자동화할 수 있을 것 같습니다. 위 내용도 자세하게 설명하면 좋겠지만 이번 포스팅에서는 다루지 않고 따로 글을 쓰도록 하겠습니다 &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;6. 정리&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Appium을 사용해서 앱 테스트 자동화 코드를 만들고 Jenkins + DeviceFarm 연동까지 정리해 봤습니다. 마지막에 Jenkins + DeviceFarm 연동에 대해 자세히 다루지 못해서 아쉽지만... 이런 식으로 테스트 자동화를 해봤다 정도로 참고해 주시면 좋을 것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개인적으로 회사에서 이번 과제를 진행하면서 몇 가지 느낀 점이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;525&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgiFiU/btsC5YYvQGA/kElcJ15SnGi6b5QKwtWSP0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgiFiU/btsC5YYvQGA/kElcJ15SnGi6b5QKwtWSP0/img.jpg&quot; data-alt=&quot;힘든 QA&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgiFiU/btsC5YYvQGA/kElcJ15SnGi6b5QKwtWSP0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgiFiU%2FbtsC5YYvQGA%2FkElcJ15SnGi6b5QKwtWSP0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;373&quot; height=&quot;392&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;525&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;힘든 QA&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 내 업무와 직접적인 관계는 아니지만 간접적인 업무였을 때 내가 할 수 있는 일이 있다면 적극적으로 해보기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 잠시 QA 엔지니어의 삶을 느껴봤는데 생각보다 재밌었고 어쨌든 개발과 관련된 부분이다 보니 커리어에 도움이 될 것 같다&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. 앱테스트 자동화다 보니 혼자 하는데 한계가 있다. (못하는 건 아님) &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 시나리오 작성을 하려면 UI Element를 찾아야 하는데 고유의 ID가 없거나 움직이는 배너이라던가 (속도가 빠르면 클릭 잘 못 할 수 있음) 하는 일들 때문에 앱개발자들도 함께 자동화 환경을 만들어 가야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. 앱이 어떻게 빌드되고 설치되는지에 대한 이해도가 없어서 초반에 삽질 많이 했다. &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 ios는 &lt;s&gt;지랄맞게&lt;/s&gt; 추가적인 작업들 (WebDriverAgent 설치 등)과 개발자 등록이 안되면 일주일에 열 번 빌드인가? 암튼 제한이 있어서 삽질하다가 빌드를 못해서 Apple 계정을 새로 만들기도 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;5. 잘 만들면 QA 하기 편할 것 같다. (하지만 그 과정이 빡셀&amp;nbsp;것 같긴 하다 ㅋㅋ)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;암튼 재밌었던 과제였고 아직 마무리된 건 아니지만, 마무리가 되고 잘 사용이 되면 기분이 좋을 것 같습니다. (poc까지 끝낸 상황)&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;긴 글 읽어주셔서 감사드리며 오늘도 좋은 하루 보내시길 바랍니다!&lt;/p&gt;</description>
      <category>  프로그래밍/Python</category>
      <category>Appium</category>
      <category>DeviceFarm</category>
      <category>QA 자동화</category>
      <category>앱 테스트 자동화</category>
      <author>피트웨어 제이 (FitwareJay)</author>
      <guid isPermaLink="true">https://jay-ji.tistory.com/122</guid>
      <comments>https://jay-ji.tistory.com/122#entry122comment</comments>
      <pubDate>Sun, 7 Jan 2024 17:39:35 +0900</pubDate>
    </item>
    <item>
      <title>유부월드 합류한 5년차 개발자의 2023년 회고</title>
      <link>https://jay-ji.tistory.com/121</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요! Jay입니다! 글을 쓰는 지금은 23년도 12월 31일 오후 5시경입니다. 회고를 쓸 때면 늘 생각나는 이야기지만... 시간이 참 빠르게 흘러가는 것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어느 순간부터 회고를 작성하면서 한해를 마무리하는 게 루틴이 되었네요. 올 한 해도 정말 다양한 일이 있었고 또 많은 고민과 해결의 반복들이 있던 것 같습니다. 개발자로서 그리고 개인적인 삶에서의 생각들을 정리해보려고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. 올 한해 나는 성장하였는가?&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;408&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bH3v7U/btsCX6A03lS/Wguy07LdIqJvUZeLZWIp8K/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bH3v7U/btsCX6A03lS/Wguy07LdIqJvUZeLZWIp8K/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bH3v7U/btsCX6A03lS/Wguy07LdIqJvUZeLZWIp8K/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbH3v7U%2FbtsCX6A03lS%2FWguy07LdIqJvUZeLZWIp8K%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;228&quot; height=&quot;233&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;408&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이건 진짜 끝이 없는 고민인 것 같습니다ㅋㅋ 아마 이 글을 보시는 다른 분들도 같은 고민을 많이 하실 것 같습니다. 어렵습니다... 성장의 기준은 어떻게 잡아야 하고 &quot;지금 나의 성장은 또 다른 사람보다 적었던 건 아닐까?&quot;라는 생각도 들고... 그러다 보면 가면증후군에 빠지는 적도 있던 것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작년 10월에 화해(버드뷰)에 입사하고 백엔드센터라는 조직에서 1년이라는 시간이 지났습니다. 저희팀에서는 플랫폼 전반적으로 필요한 공통모듈, 정책, 기술들에 대한 정리와 개발을 하고 있습니다. 대부분 서비스와 직접적으로 관련 있는 업무보다는 간접적인 업무들을 많이 해왔습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러다 보니 내가 하고있는 일들이 서비스에 기여도가 적은 것 같다는 생각이 들었습니다. &lt;b&gt;다른 분들은 회사에 기여를 많이 하는거 같은데 나는 이 문제들을 해결하기 위해 너무 많은 시간만 쏟고 있는 건 아닌지? 도움이 되는 건지? 이게 맞나?&lt;/b&gt;라는 생각을 상반기 까지는 많이 했던 것 같습니다. (+ 서비스 개발을 안 하다 보니 나만 백엔드 개발자로서 뒤쳐지는 기분이 들기도 했습니다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시간이 좀 더 지나고... 지금와서 생각해 보면 저희 팀에서만 할 수 있는 일들을 해왔던 것 같습니다. 플랫폼 정책들을 통일하고 정리하는 과정들, 플랫폼 개발자들의 생산성을 높여줄 수 있는 기능 개발 등, 이 모든 것들이 결국 플랫폼에 필요한 일들이었고 누군가는 해줬으면 하는 일들이었습니다. 서비스에 직접적이진 않지만 간접적인 형태로 회사에 기여를 했다고 생각하고 그 과정에서 저는 이런 것들을 배웠고 성장했다고 생각합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;- 우리팀, 내가 하고 있는 업무에 대한 자부심&lt;/b&gt;&lt;br /&gt;&lt;b&gt;- 우리팀만이 할 수 있는 일이라 생각하고 도전하는 마음가짐&lt;/b&gt;&lt;br /&gt;&lt;b&gt;- 업무가 진행되게 하기 위한 과정과 노력, 역할&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시 &quot;올 한해 나는 성장하였는가?&quot;에 대한 스스로의 답변은 이렇습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;'개인(개발자)' 성장보다는 ' 팀'으로서의 성장이 있었다!&lt;/span&gt; &lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다가오는 2024년도에도 &lt;b&gt;우리팀만이 할 수 있는 일, 우리 팀이 잘하는 일들을 하면서 회사에 기여하고 개인의 성장도 가져가려고 합니다.&lt;/b&gt; 위에서 제가 팀으로서의 성장을 이야기했지만 그 속에서 개발자로서 성장하는 챌린지도 많았습니다 ㅋㅋㅋ 팀 특성상 다양한 업무들을 하긴 했지만 재밌는 과제들도 많이 했습니다ㅋㅋ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. 개발은 삶을 살아가는 수단 중 하나&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;불과 몇달 전까지만 해도 저는 '개발자'로서의 삶에 높은 비중을 두고 살았었습니다. 사실 지금도 개발에 쏟는 시간이 일주일 중 제일 많은 것 같긴 합니다ㅋㅋ 다만 약간 생각하는 자세(?), 태도(?)가 조금 바뀌긴 했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1510&quot; data-origin-height=&quot;1248&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RQQAP/btsCSaki61J/M96uEeiGnJ7Jw0pxKyHiY1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RQQAP/btsCSaki61J/M96uEeiGnJ7Jw0pxKyHiY1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RQQAP/btsCSaki61J/M96uEeiGnJ7Jw0pxKyHiY1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRQQAP%2FbtsCSaki61J%2FM96uEeiGnJ7Jw0pxKyHiY1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;342&quot; height=&quot;283&quot; data-origin-width=&quot;1510&quot; data-origin-height=&quot;1248&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;올 10월에 제가 결혼을 했습니다! (축하 부탁드립니다 ㅋㅋ) 아주 좋습니다 여러분! 결혼하세요~ㅋㅋㅋ  결혼을 하면서 여러가지 생각이 바뀐 것도 있지만, 팀장님께 들었던 말이 굉장히 인상 깊었던 것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; &quot;삶에 있어서 개발이 전부가 아니고 개발은 삶을 살아가는 수단 중 하나다&quot;&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 이야기를 듣고 많은 생각을 하게 되었던 것 같습니다. &lt;b&gt;이전까지는 개발자로서의 성장이 약간 삶의 전부처럼(물론 이정도는 아니지만) 생각했고 그에 따른 가면증후군, 압박감도 되게 심했었습니다. (연차가 쌓일수록 더 심해졌던 것 같습니다)&lt;/b&gt;&amp;nbsp;하지만 이제는 개발은 삶을 살아가는 수단 중 하나로 생각하고 삶을 어떻게 잘 살아갈지를 더 고민하게 되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러다 보니 회사생활이나 삶을 바라보는 시야가 넓어진 것 같습니다. 예컨대 모든 걸 잘해야 한다는 오만에서 조금 벗어난 것 같습니다. 모두가 개발천재일 필요는 없고 각자 잘할 수 있는 일을 하고 부족한 부분은 서로 보완하면 된다고 생각합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;735&quot; data-origin-height=&quot;460&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rIue9/btsCSDGDyHN/q66sJIOvc9h8hVIEuxWat0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rIue9/btsCSDGDyHN/q66sJIOvc9h8hVIEuxWat0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rIue9/btsCSDGDyHN/q66sJIOvc9h8hVIEuxWat0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrIue9%2FbtsCSDGDyHN%2Fq66sJIOvc9h8hVIEuxWat0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;326&quot; height=&quot;204&quot; data-origin-width=&quot;735&quot; data-origin-height=&quot;460&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 이제 가정을 꾸리다보니 삶의 중요도가 가족, 가정에 더 집중을 하게 된 것도 있는 것 같습니다. 개발에 온 신경을 쏟고 시간을 보내는 게 내 삶에 최선은 아닌 걸 느꼈습니다. (이렇게 살면 집에서 쫓겨납니다... 여보 사랑해)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발은 제가 추구하는 행복과 삶을 살기위한 수단일 뿐입니다. 제가 추구하는 행복과 삶을 위해 뭐가 됐던 최선을 다할 거고 열심히 살려고 합니다!  여러분들도 여러분이 추구하는 행복과 삶을 최선을 다해 사시길 바라며...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;538&quot; data-origin-height=&quot;322&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPsoCf/btsCQ27N6yC/u8kWUXiIvxe8JMfNbZyvn1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPsoCf/btsCQ27N6yC/u8kWUXiIvxe8JMfNbZyvn1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPsoCf/btsCQ27N6yC/u8kWUXiIvxe8JMfNbZyvn1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbPsoCf%2FbtsCQ27N6yC%2Fu8kWUXiIvxe8JMfNbZyvn1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;423&quot; height=&quot;253&quot; data-origin-width=&quot;538&quot; data-origin-height=&quot;322&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 style=&quot;text-align: center;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;23년도 올한해 모두 고생 많으셨고 24년도에는 좋은 일만 가득하길 기원하겠습니다!! &lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category> &amp;zwj;  개발자 제이의 이야기</category>
      <author>피트웨어 제이 (FitwareJay)</author>
      <guid isPermaLink="true">https://jay-ji.tistory.com/121</guid>
      <comments>https://jay-ji.tistory.com/121#entry121comment</comments>
      <pubDate>Sun, 31 Dec 2023 22:49:59 +0900</pubDate>
    </item>
    <item>
      <title>AWS Secret Manager그리고 Lambda Extension</title>
      <link>https://jay-ji.tistory.com/120</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;630&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/k7PSd/btsBfzL8Bha/VzKOYem3YBrdAqmSZmiBL1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/k7PSd/btsBfzL8Bha/VzKOYem3YBrdAqmSZmiBL1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/k7PSd/btsBfzL8Bha/VzKOYem3YBrdAqmSZmiBL1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fk7PSd%2FbtsBfzL8Bha%2FVzKOYem3YBrdAqmSZmiBL1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;427&quot; height=&quot;224&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;630&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요! 이번 포스팅에서는 &lt;b&gt;AWS Secret Manger&lt;/b&gt; 그리고 &lt;b&gt;Lambda extension&lt;/b&gt; 사용에 대해서 정리해보려고 합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;회사에서 사용 중인 Lambda 서비스에서 하드코딩으로 관리되고 있던 값들을 정리하기 위해 AWS Secret Manager를 사용하기로 논의가 되었습니다. 해당 서비스가 자주 업데이트 되는 서비스가 아니었어서 유지보수 하기 어려운 형태였는데요. 시간이 지나고 보니 생각보다 중요한 레거시(?)가 돼서 지금이라도 유지보수를 위해 정비를 하게 되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 하드코딩 된 값들을 제거함으로써 dev, stg, prd 환경에서 동일한 코드로 관리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 이런 값들을 Secret으로 빼서 보안성 높이기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;크게 위 두가지 목표를 가지고 작업을 시작했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. AWS Secret Manager란?&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;715&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sUais/btsBfv31Db0/q62A2tDuDF5SJaGHS52Jhk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sUais/btsBfv31Db0/q62A2tDuDF5SJaGHS52Jhk/img.png&quot; data-alt=&quot;출처:&amp;amp;amp;nbsp;https://aws.amazon.com/ko/secrets-manager/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sUais/btsBfv31Db0/q62A2tDuDF5SJaGHS52Jhk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsUais%2FbtsBfv31Db0%2Fq62A2tDuDF5SJaGHS52Jhk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;715&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;715&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처:&amp;amp;nbsp;https://aws.amazon.com/ko/secrets-manager/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS Secret Manager는 데이터베이스 보안 인증정보 혹은 api key와 같은 정보들을 안전하게 암호화하고 중앙집중식으로 관리할 수 있는 서비스입니다. 말 그대로 시크릿 매니저입니다ㅋㅋ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbhwOo/btsBeUC0UcF/ZOhCt3hPOULR8xzKbv1JVk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbhwOo/btsBeUC0UcF/ZOhCt3hPOULR8xzKbv1JVk/img.png&quot; data-origin-width=&quot;2266&quot; data-origin-height=&quot;1856&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;51.38&quot; style=&quot;width: 50.7861%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbhwOo/btsBeUC0UcF/ZOhCt3hPOULR8xzKbv1JVk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbhwOo%2FbtsBeUC0UcF%2FZOhCt3hPOULR8xzKbv1JVk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2266&quot; height=&quot;1856&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c7InWv/btsBcSr8hlk/9nBXUKbWzOmW276CGpslQ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c7InWv/btsBcSr8hlk/9nBXUKbWzOmW276CGpslQ0/img.png&quot; data-origin-width=&quot;2308&quot; data-origin-height=&quot;1998&quot; data-is-animation=&quot;false&quot; style=&quot;width: 48.0511%;&quot; data-widthpercent=&quot;48.62&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c7InWv/btsBcSr8hlk/9nBXUKbWzOmW276CGpslQ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc7InWv%2FbtsBcSr8hlk%2F9nBXUKbWzOmW276CGpslQ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2308&quot; height=&quot;1998&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;콘솔에서 AWS Secret Manager를 추가하는 과정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Secret Manager 사용하는 방법도 크게 어렵진 않은데요. 콘솔로 Secret Manager를 생성하고 키/값을 추가하면 끝입니다. 이후 Secret Manger 이름을 정의하고 생성하면 끝! 저는 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;test/lambda/jay&lt;/b&gt;&lt;/span&gt;로 이름을 지정했습니다~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2026&quot; data-origin-height=&quot;1760&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7mH0L/btsBbJWyipj/W0miCCzidstATBJKgezySk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7mH0L/btsBbJWyipj/W0miCCzidstATBJKgezySk/img.png&quot; data-alt=&quot;샘플코드까지 줘서 개꿀&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7mH0L/btsBbJWyipj/W0miCCzidstATBJKgezySk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7mH0L%2FbtsBbJWyipj%2FW0miCCzidstATBJKgezySk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;479&quot; height=&quot;416&quot; data-origin-width=&quot;2026&quot; data-origin-height=&quot;1760&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;샘플코드까지 줘서 개꿀&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Secret Manager를 생성하면 여러 언어로 샘플코드까지 줘서 테스트하는데 크게 어렵지 않습니다. 해당 코드를 복사하고 Lambda에 추가해서 배포해보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1701348678819&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import {
  SecretsManagerClient,
  GetSecretValueCommand,
} from &quot;@aws-sdk/client-secrets-manager&quot;;

export const handler = async (event) =&amp;gt; {
  const secretName = &quot;test/lambda/jay&quot;; // 시크릿 매니저 이름
  const client = new SecretsManagerClient({
    region: &quot;ap-northeast-2&quot;,
  });
  let result;
  
  try {
    result = await client.send(
      new GetSecretValueCommand({
        SecretId: secretName,
        VersionStage: &quot;AWSCURRENT&quot;, // VersionStage defaults to AWSCURRENT if unspecified
      })
    );
  } catch (error) {
    throw error;
  }
  
  const secret = result.SecretString;
  const response = {
    statusCode: 200,
    body: JSON.stringify(secret),
  };
  return response;
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드는 샘플코드 그대로 가져왔으며 Secret Manager에 접근해서 secret들을 가져온 뒤 response로 전달하고 있습니다. 실제로 그렇게 동작할까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1064&quot; data-origin-height=&quot;578&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kVdXS/btsBb9AVvuU/KUpWlWyqXQxSeKIzEoEFP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kVdXS/btsBb9AVvuU/KUpWlWyqXQxSeKIzEoEFP1/img.png&quot; data-alt=&quot;Exception 발생&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kVdXS/btsBb9AVvuU/KUpWlWyqXQxSeKIzEoEFP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkVdXS%2FbtsBb9AVvuU%2FKUpWlWyqXQxSeKIzEoEFP1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;579&quot; height=&quot;315&quot; data-origin-width=&quot;1064&quot; data-origin-height=&quot;578&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Exception 발생&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;익셉션(Exception)이 발생했네요 ㅋㅋㅋ 내용을 확인해 보면...&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;jayLambdaTest&amp;nbsp;is&amp;nbsp;not&amp;nbsp;authorized&amp;nbsp;to&amp;nbsp;perform:&amp;nbsp;secretsmanager:GetSecretValue&amp;nbsp;on&amp;nbsp;resource:&amp;nbsp;test/lambda/jay&amp;nbsp;because&amp;nbsp;no&amp;nbsp;identity-based&amp;nbsp;policy&amp;nbsp;allows&amp;nbsp;the&amp;nbsp;secretsmanager:GetSecretValue&amp;nbsp;action&quot;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;역시 엄격한 AWS! 위 내용은 &lt;b&gt;Lambda에서 test/lambda/jay 라는 Secret Manager의 GetSecretValue 액션을 허용하는 정책이 없기 때문에 접근이 불가&lt;/b&gt;하다는 말입니다. 당연하죠~?! 저희는 서비스 별로 권한을 분리하고 특정 서비스에서는 특정 리소스만 사용하게 해야 보안도 높일 수 있고 관리도 편합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1494&quot; data-origin-height=&quot;1374&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b7bkim/btsBfKs88I2/8qfkE0eyZqhxrIk1PjsbTK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b7bkim/btsBfKs88I2/8qfkE0eyZqhxrIk1PjsbTK/img.png&quot; data-alt=&quot;IAM role에서 Lambda의 역할을 확인&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b7bkim/btsBfKs88I2/8qfkE0eyZqhxrIk1PjsbTK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb7bkim%2FbtsBfKs88I2%2F8qfkE0eyZqhxrIk1PjsbTK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;420&quot; height=&quot;386&quot; data-origin-width=&quot;1494&quot; data-origin-height=&quot;1374&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;IAM role에서 Lambda의 역할을 확인&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재는 기본 권한 정책만 존재하기 때문에 &lt;b&gt;test/lambda/jay lambda&lt;/b&gt;에 접근할 수 있는 권한정책을 추가해 보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2140&quot; data-origin-height=&quot;1884&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bP0Sz1/btsBfb5Nj4d/7MNNuqzfUpcqce6F0kv4B1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bP0Sz1/btsBfb5Nj4d/7MNNuqzfUpcqce6F0kv4B1/img.png&quot; data-alt=&quot;권한 추가 버튼을 클릭후 Secret Manager를 선택&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bP0Sz1/btsBfb5Nj4d/7MNNuqzfUpcqce6F0kv4B1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbP0Sz1%2FbtsBfb5Nj4d%2F7MNNuqzfUpcqce6F0kv4B1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;604&quot; height=&quot;532&quot; data-origin-width=&quot;2140&quot; data-origin-height=&quot;1884&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;권한 추가 버튼을 클릭후 Secret Manager를 선택&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저희는 &lt;b&gt;GetSecretValue&lt;/b&gt; 액션만 필요하기 때문에 해당 옵션만 선택하고 리소스를 특정합니다. 여기서 특정 리소스는 접근하고자 하는 Secret Manager의 ARN을 말합니다. 내용을 모두 입력 후 저장한 후 다시 Lambda를 호출해 보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1766&quot; data-origin-height=&quot;632&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c7IlSY/btsBb6jHdYK/rpvPPCFueMTufdqgWcKQYK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c7IlSY/btsBb6jHdYK/rpvPPCFueMTufdqgWcKQYK/img.png&quot; data-alt=&quot;정상적으로 Secret 값 들을 반환!!&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c7IlSY/btsBb6jHdYK/rpvPPCFueMTufdqgWcKQYK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc7IlSY%2FbtsBb6jHdYK%2FrpvPPCFueMTufdqgWcKQYK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;589&quot; height=&quot;211&quot; data-origin-width=&quot;1766&quot; data-origin-height=&quot;632&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;정상적으로 Secret 값 들을 반환!!&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;호출 결과를 보시면 정상적으로 Secret Manager의 값들을 가져온 것을 확인할 수 있습니다!! 오예!!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. SecretManager를 그대로 쓰면 안 되는 이유!&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;474&quot; data-origin-height=&quot;266&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bD83Qk/btsBbEgETe2/MiGd1z8EkA62xKY6h9dJG0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bD83Qk/btsBbEgETe2/MiGd1z8EkA62xKY6h9dJG0/img.jpg&quot; data-alt=&quot;소중한 회삿돈...&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bD83Qk/btsBbEgETe2/MiGd1z8EkA62xKY6h9dJG0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbD83Qk%2FbtsBbEgETe2%2FMiGd1z8EkA62xKY6h9dJG0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;474&quot; height=&quot;266&quot; data-origin-width=&quot;474&quot; data-origin-height=&quot;266&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;소중한 회삿돈...&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 내용에서 끝난 줄 알았지만 사실 끝이 아닙니다! Secret Manager 호출하는 것도 모두 &lt;b&gt;'돈'입니다&lt;/b&gt; ㅋㅋㅋ 저희는 회사에 소속되어 있기 때문에 AWS 리소스를 최적화해서 사용할 의무가 있습니다~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2776&quot; data-origin-height=&quot;2218&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvaMKc/btsBbE11XrG/7ZxSmaDVKuxERtSn81jAhK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvaMKc/btsBbE11XrG/7ZxSmaDVKuxERtSn81jAhK/img.png&quot; data-alt=&quot;AWS 요금 계산기로 계산해본 예상 비용&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvaMKc/btsBbE11XrG/7ZxSmaDVKuxERtSn81jAhK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbvaMKc%2FbtsBbE11XrG%2F7ZxSmaDVKuxERtSn81jAhK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;577&quot; height=&quot;461&quot; data-origin-width=&quot;2776&quot; data-origin-height=&quot;2218&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;AWS 요금 계산기로 계산해본 예상 비용&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;엇... 이렇게 보니까 생각보다 안 비싸네... 여하튼 트래픽이 늘어나고 사용하는 보안암호(Secret)들이 많아질수록 요금은 올라가겠죠? 그리고 매번 Lambda에서 Secret Manager를 호출하는 것 자체가 응답속도에 영향을 주는 행위입니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 왜 이렇게 말이 길었느냐?! 위 문제들을 어느 정도 해소해 줄 수 있는 방법이 있습니다! 바로 Lambda Extension 중 하나인 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;AWS-Parameters-and-Secrets-Lambda-Extension&lt;/b&gt;&lt;/span&gt; 입니다!!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;624&quot; data-origin-height=&quot;661&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dzvLbh/btsBgxmMYtR/9OryoelWgNc7v3K87eLUmK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dzvLbh/btsBgxmMYtR/9OryoelWgNc7v3K87eLUmK/img.png&quot; data-alt=&quot;출처:&amp;amp;amp;nbsp;https://aws.amazon.com/ko/blogs/compute/using-the-aws-parameter-and-secrets-lambda-extension-to-cache-parameters-and-secrets/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dzvLbh/btsBgxmMYtR/9OryoelWgNc7v3K87eLUmK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdzvLbh%2FbtsBgxmMYtR%2F9OryoelWgNc7v3K87eLUmK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;563&quot; height=&quot;596&quot; data-origin-width=&quot;624&quot; data-origin-height=&quot;661&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처:&amp;amp;nbsp;https://aws.amazon.com/ko/blogs/compute/using-the-aws-parameter-and-secrets-lambda-extension-to-cache-parameters-and-secrets/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;AWS-Parameters-and-Secrets-Lambda-Extension&lt;/b&gt;을 사용하면 시크릿&lt;span style=&quot;background-color: #ffffff; color: #16191f; text-align: start;&quot;&gt;을 검색한 후 로컬 캐시에 저장합니다. 그런 다음 캐시 된 값은 만료될 때까지 이후 호출에 사용됩니다. 캐시된 값은 TTL(time-to-live)이 경과한 이후에 만료되며 &lt;span style=&quot;background-color: #f2f3f3; color: #16191f; text-align: start;&quot;&gt;&lt;b&gt;SECRETS_MANAGER_TTL&lt;/b&gt;&lt;span style=&quot;background-color: #ffffff; color: #16191f; text-align: start;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #16191f; text-align: start;&quot;&gt;환경변수로 TTL 시간을 조절할 수 있습니다. (default 300초)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #16191f; text-align: start;&quot;&gt;&lt;span style=&quot;background-color: #f2f3f3; color: #16191f; text-align: start;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #16191f; text-align: start;&quot;&gt;익스텐션 이름 그대로 AWS Parameter Store도 동일하게 사용할 수 있습니다. 이렇게 캐시를 사용하게 되면 Secret Manager API를 계속 호출하지 않으니 비용도 감소되고 Lambda의 응답시간도 빨라질 것입니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #16191f; text-align: start;&quot;&gt;&lt;span style=&quot;background-color: #f2f3f3; color: #16191f; text-align: start;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #16191f; text-align: start;&quot;&gt;자! 그럼 &lt;b&gt;AWS-Parameters-and-Secrets-Lambda-Extension&lt;/b&gt;을 추가해 보도록 하겠습니다&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;806&quot; data-origin-height=&quot;354&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cK554F/btsBfJgIAEw/xSUlepLmAmafV30gzLBSrk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cK554F/btsBfJgIAEw/xSUlepLmAmafV30gzLBSrk/img.png&quot; data-alt=&quot;처음엔 Layers에 아무것도 추가가 안되어 있습니다&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cK554F/btsBfJgIAEw/xSUlepLmAmafV30gzLBSrk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcK554F%2FbtsBfJgIAEw%2FxSUlepLmAmafV30gzLBSrk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;397&quot; height=&quot;174&quot; data-origin-width=&quot;806&quot; data-origin-height=&quot;354&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;처음엔 Layers에 아무것도 추가가 안되어 있습니다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1714&quot; data-origin-height=&quot;2022&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dTynhU/btsBgdB3Bf2/qd0hxKBAhLQl8ph4il9SCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dTynhU/btsBgdB3Bf2/qd0hxKBAhLQl8ph4il9SCK/img.png&quot; data-alt=&quot;Layer 추가를 하게되면 위 내용처럼 Extension을 선택할 수 있습니다&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dTynhU/btsBgdB3Bf2/qd0hxKBAhLQl8ph4il9SCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdTynhU%2FbtsBgdB3Bf2%2Fqd0hxKBAhLQl8ph4il9SCK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;692&quot; height=&quot;816&quot; data-origin-width=&quot;1714&quot; data-origin-height=&quot;2022&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Layer 추가를 하게되면 위 내용처럼 Extension을 선택할 수 있습니다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1548&quot; data-origin-height=&quot;1006&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c7t3SB/btsBaZTcb1v/4QybHmQ5Kx4WL3tXg3QAKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c7t3SB/btsBaZTcb1v/4QybHmQ5Kx4WL3tXg3QAKk/img.png&quot; data-alt=&quot;Layer가 한개 추가된 걸 확인할 수 있습니다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c7t3SB/btsBaZTcb1v/4QybHmQ5Kx4WL3tXg3QAKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc7t3SB%2FbtsBaZTcb1v%2F4QybHmQ5Kx4WL3tXg3QAKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;479&quot; height=&quot;311&quot; data-origin-width=&quot;1548&quot; data-origin-height=&quot;1006&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Layer가 한개 추가된 걸 확인할 수 있습니다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 코드를 수정해 보겠습니다. Lambda에서는 더 이상 직접적으로 Secret Manager를 호출하는 게 아니라 Extension을 통해서 호출하게 됩니다. (캐싱된 값이 없을 때만)&lt;/p&gt;
&lt;pre id=&quot;code_1701354770464&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;export const handler = async (event) =&amp;gt; {
  const secretName = &quot;test/lambda/jay&quot;; // 시크릿 매니저 이름
  const url = `http://localhost:${process.env.PARAMETERS_SECRETS_EXTENSION_HTTP_PORT}/secretsmanager/get?secretId=${secretName}`;
  const options = {
    headers: { 'X-Aws-Parameters-Secrets-Token': process.env.AWS_SESSION_TOKEN },
    method: 'GET',
  };
  let result;
  
  try {
    const response = await fetch(url, options);
    if (!response.ok) {
      const json = await response.json().catch((err) =&amp;gt; err.message);
      console.error('Invalid response :', json);
      throw new Error(`Invalid ${response.status} response`);
    }
    result = await response.json();

  } catch (error) {
    console.error('Error:', error);
    throw error;
  }
  
  return {
    statusCode: 200,
    body: JSON.parse(result.SecretString)
  };
};&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3026&quot; data-origin-height=&quot;474&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oPi4P/btsBc2BlGPB/IcFi0Nm3c3zKGTUjJqpNA1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oPi4P/btsBc2BlGPB/IcFi0Nm3c3zKGTUjJqpNA1/img.png&quot; data-alt=&quot;Extension port를 환경변수로 지정해줘야 합니다. (default: 2773)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oPi4P/btsBc2BlGPB/IcFi0Nm3c3zKGTUjJqpNA1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoPi4P%2FbtsBc2BlGPB%2FIcFi0Nm3c3zKGTUjJqpNA1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3026&quot; height=&quot;474&quot; data-origin-width=&quot;3026&quot; data-origin-height=&quot;474&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Extension port를 환경변수로 지정해줘야 합니다. (default: 2773)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1068&quot; data-origin-height=&quot;642&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dvMzC3/btsBccj7Qet/GhiBbc9iFvYknaPkzLkXzK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dvMzC3/btsBccj7Qet/GhiBbc9iFvYknaPkzLkXzK/img.png&quot; data-alt=&quot; 응답 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dvMzC3/btsBccj7Qet/GhiBbc9iFvYknaPkzLkXzK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdvMzC3%2FbtsBccj7Qet%2FGhiBbc9iFvYknaPkzLkXzK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;472&quot; height=&quot;284&quot; data-origin-width=&quot;1068&quot; data-origin-height=&quot;642&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt; 응답 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Lambda Extension 호출은 localhost를 호출하게 되며 Secret Manager, Parameter Store 별 API endpoint가 존재합니다. 자세한 내용은 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://docs.aws.amazon.com/ko_kr/secretsmanager/latest/userguide/retrieving-secrets_lambda.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;여기&lt;/a&gt;&lt;/span&gt;서 확인 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. 참고&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;figure id=&quot;og_1701355364074&quot; style=&quot;color: #333333; text-align: start;&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/FNf1c/hyUE6qFW0U/qzCGzuu11RRvCMTkJdmjU0/img.png?width=2000&amp;amp;height=1340&amp;amp;face=0_0_2000_1340,https://scrap.kakaocdn.net/dn/AqMAk/hyUE31NkKf/87jFATd70HGrg6UO78pJxK/img.png?width=1720&amp;amp;height=1300&amp;amp;face=0_0_1720_1300,https://scrap.kakaocdn.net/dn/CBoFo/hyUE2u1vks/guFLJ95BLWDEZMFz5tpVZ1/img.png?width=1440&amp;amp;height=950&amp;amp;face=0_0_1440_950&quot; data-og-url=&quot;https://docs.aws.amazon.com/lambda/latest/dg/runtimes-extensions-api.html&quot; data-og-source-url=&quot;https://docs.aws.amazon.com/lambda/latest/dg/runtimes-extensions-api.html&quot; data-og-host=&quot;docs.aws.amazon.com&quot; data-og-description=&quot;Lambda Extensions API Lambda function authors use extensions to integrate Lambda with their preferred tools for monitoring, observability, security, and governance. Function authors can use extensions from AWS, AWS Partners, and open-source projects. For m&quot; data-og-title=&quot;Lambda Extensions API - AWS Lambda&quot; data-og-type=&quot;website&quot; data-ke-align=&quot;alignCenter&quot; data-ke-type=&quot;opengraph&quot;&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://docs.aws.amazon.com/lambda/latest/dg/runtimes-extensions-api.html&quot; data-source-url=&quot;https://docs.aws.amazon.com/lambda/latest/dg/runtimes-extensions-api.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/FNf1c/hyUE6qFW0U/qzCGzuu11RRvCMTkJdmjU0/img.png?width=2000&amp;amp;height=1340&amp;amp;face=0_0_2000_1340,https://scrap.kakaocdn.net/dn/AqMAk/hyUE31NkKf/87jFATd70HGrg6UO78pJxK/img.png?width=1720&amp;amp;height=1300&amp;amp;face=0_0_1720_1300,https://scrap.kakaocdn.net/dn/CBoFo/hyUE2u1vks/guFLJ95BLWDEZMFz5tpVZ1/img.png?width=1440&amp;amp;height=950&amp;amp;face=0_0_1440_950');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; style=&quot;color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;Lambda Extensions API - AWS Lambda&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; style=&quot;color: #909090;&quot; data-ke-size=&quot;size16&quot;&gt;Lambda Extensions API Lambda function authors use extensions to integrate Lambda with their preferred tools for monitoring, observability, security, and governance. Function authors can use extensions from AWS, AWS Partners, and open-source projects. For m&lt;/p&gt;
&lt;p class=&quot;og-host&quot; style=&quot;color: #909090;&quot; data-ke-size=&quot;size16&quot;&gt;docs.aws.amazon.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;figure id=&quot;og_1701355272218&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Using the AWS Parameter and Secrets Lambda extension to cache parameters and secrets | Amazon Web Services&quot; data-og-description=&quot;Caching data retrieved from external services is an effective way to improve the performance of your Lambda function and reduce costs. Implementing a caching layer has been made simpler with this AWS-managed Lambda extension.&amp;nbsp;&quot; data-og-host=&quot;aws.amazon.com&quot; data-og-source-url=&quot;https://aws.amazon.com/ko/blogs/compute/using-the-aws-parameter-and-secrets-lambda-extension-to-cache-parameters-and-secrets/&quot; data-og-url=&quot;https://aws.amazon.com/blogs/compute/using-the-aws-parameter-and-secrets-lambda-extension-to-cache-parameters-and-secrets/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/QiDsY/hyUE38xNhc/357ZDlVpOA8Z9NWjQV5Ij1/img.png?width=595&amp;amp;height=630&amp;amp;face=0_0_595_630,https://scrap.kakaocdn.net/dn/h3hUv/hyUE6c8ObP/bR7AIQ1bu9u2VsMbK8jU31/img.png?width=595&amp;amp;height=630&amp;amp;face=0_0_595_630,https://scrap.kakaocdn.net/dn/CrKE2/hyUFdchVLe/Kx1P0XnJxAggJ0fKzTkjv0/img.png?width=624&amp;amp;height=661&amp;amp;face=0_0_624_661&quot;&gt;&lt;a href=&quot;https://aws.amazon.com/ko/blogs/compute/using-the-aws-parameter-and-secrets-lambda-extension-to-cache-parameters-and-secrets/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://aws.amazon.com/ko/blogs/compute/using-the-aws-parameter-and-secrets-lambda-extension-to-cache-parameters-and-secrets/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/QiDsY/hyUE38xNhc/357ZDlVpOA8Z9NWjQV5Ij1/img.png?width=595&amp;amp;height=630&amp;amp;face=0_0_595_630,https://scrap.kakaocdn.net/dn/h3hUv/hyUE6c8ObP/bR7AIQ1bu9u2VsMbK8jU31/img.png?width=595&amp;amp;height=630&amp;amp;face=0_0_595_630,https://scrap.kakaocdn.net/dn/CrKE2/hyUFdchVLe/Kx1P0XnJxAggJ0fKzTkjv0/img.png?width=624&amp;amp;height=661&amp;amp;face=0_0_624_661');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Using the AWS Parameter and Secrets Lambda extension to cache parameters and secrets | Amazon Web Services&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Caching data retrieved from external services is an effective way to improve the performance of your Lambda function and reduce costs. Implementing a caching layer has been made simpler with this AWS-managed Lambda extension.&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;aws.amazon.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;figure id=&quot;og_1701355308468&quot; style=&quot;color: #333333; text-align: start;&quot; data-og-image=&quot;&quot; data-og-url=&quot;https://docs.aws.amazon.com/secretsmanager/latest/userguide/auth-and-access_resource-policies.html?icmpid=docs_asm_help_panel&quot; data-og-source-url=&quot;https://docs.aws.amazon.com/secretsmanager/latest/userguide/auth-and-access_resource-policies.html?icmpid=docs_asm_help_panel&quot; data-og-host=&quot;docs.aws.amazon.com&quot; data-og-description=&quot;The following put-resource-policy example adds a permissions policy to a secret, checking first that the policy does not provide broad access to the secret. The policy is read from a file. For more information, see Loading AWS CLI parameters from a file in&quot; data-og-title=&quot;Attach a permissions policy to an AWS Secrets Manager secret - AWS Secrets Manager&quot; data-og-type=&quot;website&quot; data-ke-align=&quot;alignCenter&quot; data-ke-type=&quot;opengraph&quot;&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://docs.aws.amazon.com/secretsmanager/latest/userguide/auth-and-access_resource-policies.html?icmpid=docs_asm_help_panel&quot; data-source-url=&quot;https://docs.aws.amazon.com/secretsmanager/latest/userguide/auth-and-access_resource-policies.html?icmpid=docs_asm_help_panel&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('&amp;quot;&amp;quot;');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; style=&quot;color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;Attach a permissions policy to an AWS Secrets Manager secret - AWS Secrets Manager&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; style=&quot;color: #909090;&quot; data-ke-size=&quot;size16&quot;&gt;The following put-resource-policy example adds a permissions policy to a secret, checking first that the policy does not provide broad access to the secret. The policy is read from a file. For more information, see Loading AWS CLI parameters from a file in&lt;/p&gt;
&lt;p class=&quot;og-host&quot; style=&quot;color: #909090;&quot; data-ke-size=&quot;size16&quot;&gt;docs.aws.amazon.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;figure id=&quot;og_1701355258537&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;How To Cache Secrets Using AWS Lambda Extensions | HackerNoon&quot; data-og-description=&quot;Build a cache layer for secrets stored in AWS Secrets manager using AWS Lambda extension&quot; data-og-host=&quot;hackernoon.com&quot; data-og-source-url=&quot;https://hackernoon.com/how-to-cache-secrets-using-aws-lambda-extensions-ji1531jx&quot; data-og-url=&quot;https://hackernoon.com/how-to-cache-secrets-using-aws-lambda-extensions-ji1531jx&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://hackernoon.com/how-to-cache-secrets-using-aws-lambda-extensions-ji1531jx&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://hackernoon.com/how-to-cache-secrets-using-aws-lambda-extensions-ji1531jx&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;How To Cache Secrets Using AWS Lambda Extensions | HackerNoon&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Build a cache layer for secrets stored in AWS Secrets manager using AWS Lambda extension&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;hackernoon.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;figure id=&quot;og_1701355240092&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;AWS Lambda 함수에서 AWS Secrets Manager 보안 암호 사용 - AWS Secrets Manager&quot; data-og-description=&quot;이 페이지에 작업이 필요하다는 점을 알려 주셔서 감사합니다. 실망시켜 드려 죄송합니다. 잠깐 시간을 내어 설명서를 향상시킬 수 있는 방법에 대해 말씀해 주십시오.&quot; data-og-host=&quot;docs.aws.amazon.com&quot; data-og-source-url=&quot;https://docs.aws.amazon.com/ko_kr/secretsmanager/latest/userguide/retrieving-secrets_lambda.html&quot; data-og-url=&quot;https://docs.aws.amazon.com/ko_kr/secretsmanager/latest/userguide/retrieving-secrets_lambda.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/secretsmanager/latest/userguide/retrieving-secrets_lambda.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.aws.amazon.com/ko_kr/secretsmanager/latest/userguide/retrieving-secrets_lambda.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;AWS Lambda 함수에서 AWS Secrets Manager 보안 암호 사용 - AWS Secrets Manager&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;이 페이지에 작업이 필요하다는 점을 알려 주셔서 감사합니다. 실망시켜 드려 죄송합니다. 잠깐 시간을 내어 설명서를 향상시킬 수 있는 방법에 대해 말씀해 주십시오.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.aws.amazon.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;figure id=&quot;og_1701355343724&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;AWS Lambda 함수에서 Parameter Store 파라미터 사용 - AWS Systems Manager&quot; data-og-description=&quot;AWS Lambda 함수에서 Parameter Store 파라미터 사용 AWS Systems Manager의 기능인 Parameter Store는 구성 데이터 관리 및 암호 관리를 위한 안전한 계층적 스토리지를 제공합니다. 암호, 데이터베이스 문자열, A&quot; data-og-host=&quot;docs.aws.amazon.com&quot; data-og-source-url=&quot;https://docs.aws.amazon.com/ko_kr/systems-manager/latest/userguide/ps-integration-lambda-extensions.html&quot; data-og-url=&quot;https://docs.aws.amazon.com/ko_kr/systems-manager/latest/userguide/ps-integration-lambda-extensions.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/systems-manager/latest/userguide/ps-integration-lambda-extensions.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.aws.amazon.com/ko_kr/systems-manager/latest/userguide/ps-integration-lambda-extensions.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;AWS Lambda 함수에서 Parameter Store 파라미터 사용 - AWS Systems Manager&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;AWS Lambda 함수에서 Parameter Store 파라미터 사용 AWS Systems Manager의 기능인 Parameter Store는 구성 데이터 관리 및 암호 관리를 위한 안전한 계층적 스토리지를 제공합니다. 암호, 데이터베이스 문자열, A&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.aws.amazon.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>  프로그래밍/AWS</category>
      <category>AWS</category>
      <category>lambda</category>
      <category>Lambda Extension</category>
      <category>Secret Manager</category>
      <author>피트웨어 제이 (FitwareJay)</author>
      <guid isPermaLink="true">https://jay-ji.tistory.com/120</guid>
      <comments>https://jay-ji.tistory.com/120#entry120comment</comments>
      <pubDate>Thu, 30 Nov 2023 23:47:27 +0900</pubDate>
    </item>
    <item>
      <title>[AWS Lambda] Nodejs 16.x 지원종료, 18.x 버전업 대응 요약(feat.s3)</title>
      <link>https://jay-ji.tistory.com/119</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요! 제이입니다! 오늘은 사내에서 사용 중인 AWS Lambda의 Nodejs runtime 버전을 변경하면서 그 과정에 대한 요약과 어떤 점을 수정했는지 일부 요약 해보려고 합니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 버전관리&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적으로 우리가 사용하고 있는 언어, 라이브러리, 프레임워크에 대한 지원종료에 대해서 인지하고 있어야 합니다. 저는 백엔드 센터 소속으로서 최근 백엔드에서 사용 중인 기술들에 대한 버전관리 및 업데이트를 진행(중)했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 번째로 저희가 사용 중인 AWS Lambda의 node버전을 체크했습니다. 버전 지원 종료에 대한 내용은 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://endoflife.date/nodejs&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://endoflife.date/nodejs&lt;/a&gt;&lt;/span&gt; 에서 쉽게 확인할 수 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(참고: &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://endoflife.date/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://endoflife.date/&lt;/a&gt;&lt;/span&gt; 에는 다양한 언어, 제품에 대한 수명주기를 명시하고 있기 때문에 즐겨찾기 해놓으시면 많은 도움이 되실 거예요!)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2236&quot; data-origin-height=&quot;1448&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqUBxl/btswwSKxYvT/AddloQQc7mFdmLNqwqKGEk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqUBxl/btswwSKxYvT/AddloQQc7mFdmLNqwqKGEk/img.png&quot; data-alt=&quot; nodejs 지원에 대한 내용&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqUBxl/btswwSKxYvT/AddloQQc7mFdmLNqwqKGEk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqUBxl%2FbtswwSKxYvT%2FAddloQQc7mFdmLNqwqKGEk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;558&quot; height=&quot;361&quot; data-origin-width=&quot;2236&quot; data-origin-height=&quot;1448&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt; nodejs 지원에 대한 내용&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저희는 16.x를 사용 중이었는데 표를 보시다시피 23년도 9월 11일에 보안 지원까지 종료가 되었습니다. 좀 더 일찍 대응을 했으면 좋았을 텐데 그래도 당장 뭐 이슈가 있는 건 아니니 ㅎㅎ (늦었다 생각했을 때가 늦었다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여하튼 현재 올릴 수 있는 안정된 버전은 18(LTS) 버전입니다. 25년 4월 30일까지 지원기간도 넉넉합니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2844&quot; data-origin-height=&quot;974&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IgX7v/btsw6Z9fFaV/Sc17kJjkyVAP43VkNbIGNk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IgX7v/btsw6Z9fFaV/Sc17kJjkyVAP43VkNbIGNk/img.png&quot; data-alt=&quot;https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IgX7v/btsw6Z9fFaV/Sc17kJjkyVAP43VkNbIGNk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIgX7v%2Fbtsw6Z9fFaV%2FSc17kJjkyVAP43VkNbIGNk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2844&quot; height=&quot;974&quot; data-origin-width=&quot;2844&quot; data-origin-height=&quot;974&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;혹시 모르니 Lambda에서 nodejs18.x를 지원하는지도 체크해 줍니다! 확인해 보니 아주 다행히도 지원을 해주고 있었습니다. 다만 변경된 점은 nodejs18.x부터 AWS SDK V3를 사용합니다. (역시 쉬운 게 없습니다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저희는 AWS SDK의 S3 관련 모듈을 사용하고 있었기 때문에 이 부분에 대한 변경점이 있을 거라 예상하며 적용을 진행했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 적용&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저희는 serverless framework라는 툴을 사용하여 lambda 배포를 진행하고 있습니다. 로컬에서는 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://www.npmjs.com/package/serverless-offline&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;serverless offline&lt;/a&gt;&lt;/span&gt;이라는 라이브러리를 통해서 테스트를 하고 있고요! (진짜 좋습니다!)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에 사용하던 AWS SDK V2(&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://www.npmjs.com/package/aws-sdk&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;aws-sdk&lt;/a&gt;&lt;/span&gt;)에서 V3로 변경되면서 패키지 구조와 사용되는 모듈들의 변화가 조금씩 있는 것 같습니다. aws 공식문서에서 V3(js) &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/javascript_code_examples.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;code 예제&lt;/a&gt;&lt;/span&gt;들을 제공하고 있습니다. (참고: &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/introduction/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;AWSJavascriptSDK V3&lt;/a&gt;&lt;/span&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3878&quot; data-origin-height=&quot;886&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BiV8M/btsw6C0Czx3/Kbl20cHifCysb80onLjRAk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BiV8M/btsw6C0Czx3/Kbl20cHifCysb80onLjRAk/img.png&quot; data-alt=&quot;https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/introduction/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BiV8M/btsw6C0Czx3/Kbl20cHifCysb80onLjRAk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBiV8M%2Fbtsw6C0Czx3%2FKbl20cHifCysb80onLjRAk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3878&quot; height=&quot;886&quot; data-origin-width=&quot;3878&quot; data-origin-height=&quot;886&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/introduction/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;yarn add @aws-sdk/client-s3&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SDK v3부터는 각 모듈별로 따로 설치를 하는 것 같습니다. 공식문서에 되게 친절하게 나와있어서 이해하시기 어려운 부분은 없을 거예요! 이런 방식으로 변경된 이유는 패키지 전체 리소스보다 필요한 것만 사용하는게 적기때문이기도 한 것 같습니다. 자세한 내용은 아래 문서를 확인해보시면 좋을 것 같습니다!&lt;/p&gt;
&lt;figure id=&quot;og_1696425727460&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Modular packages in AWS SDK for JavaScript | Amazon Web Services&quot; data-og-description=&quot;As of December 15th, 2020, the&amp;nbsp;AWS SDK for JavaScript, version 3 (v3) is generally available. On October 19th, 2020, we published the Release Candidate (RC) of the AWS SDK for JavaScript, version 3 (v3). One of the major changes in the JavaScript SDK v3 i&quot; data-og-host=&quot;aws.amazon.com&quot; data-og-source-url=&quot;https://aws.amazon.com/ko/blogs/developer/modular-packages-in-aws-sdk-for-javascript/&quot; data-og-url=&quot;https://aws.amazon.com/blogs/developer/modular-packages-in-aws-sdk-for-javascript/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/90j0L/hyT54txOeC/XxtwmFkMVsET68IheboED1/img.jpg?width=1260&amp;amp;height=630&amp;amp;face=0_0_1260_630,https://scrap.kakaocdn.net/dn/d3zmaR/hyT5UEp51B/5T9Zw4QHm6hEWWbWjHq4v0/img.jpg?width=1260&amp;amp;height=630&amp;amp;face=0_0_1260_630,https://scrap.kakaocdn.net/dn/etU3NV/hyT53aiFPe/g14tGreNkjNmCqTXw3XdW1/img.png?width=1024&amp;amp;height=433&amp;amp;face=0_0_1024_433&quot;&gt;&lt;a href=&quot;https://aws.amazon.com/ko/blogs/developer/modular-packages-in-aws-sdk-for-javascript/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://aws.amazon.com/ko/blogs/developer/modular-packages-in-aws-sdk-for-javascript/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/90j0L/hyT54txOeC/XxtwmFkMVsET68IheboED1/img.jpg?width=1260&amp;amp;height=630&amp;amp;face=0_0_1260_630,https://scrap.kakaocdn.net/dn/d3zmaR/hyT5UEp51B/5T9Zw4QHm6hEWWbWjHq4v0/img.jpg?width=1260&amp;amp;height=630&amp;amp;face=0_0_1260_630,https://scrap.kakaocdn.net/dn/etU3NV/hyT53aiFPe/g14tGreNkjNmCqTXw3XdW1/img.png?width=1024&amp;amp;height=433&amp;amp;face=0_0_1024_433');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Modular packages in AWS SDK for JavaScript | Amazon Web Services&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;As of December 15th, 2020, the&amp;nbsp;AWS SDK for JavaScript, version 3 (v3) is generally available. On October 19th, 2020, we published the Release Candidate (RC) of the AWS SDK for JavaScript, version 3 (v3). One of the major changes in the JavaScript SDK v3 i&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;aws.amazon.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;v2에서는 getObject, putObject와 같은 형태로 메서드를 제공했었는데 v3부터는 &lt;span style=&quot;color: #16191f; text-align: left;&quot;&gt;GetObjectCommand,&amp;nbsp; PutObjectCommand와 같은 형태로 메서드를 제공합니다. 단순히 메서드의 형태만 바뀐 게 아니라 데이터를 가져오고 전송하는 형태도 달라졌습니다.&lt;/span&gt;&lt;span style=&quot;color: #16191f; text-align: left;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1696425133186&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;S3.GetObject no longer returns the result as a string &amp;middot; Issue #1877 &amp;middot; aws/aws-sdk-js-v3&quot; data-og-description=&quot;Describe the bug I'm using the GetObjectCommand with an S3Client to pull a file down from S3. In v2 of the SDK I can write response.Body.toString('utf-8') to turn the response into a string. In v3 ...&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/aws/aws-sdk-js-v3/issues/1877#issuecomment-755387549&quot; data-og-url=&quot;https://github.com/aws/aws-sdk-js-v3/issues/1877&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/UQccx/hyT5UEpOOP/g6cN1MU3gVJWva83mj9szk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/aws/aws-sdk-js-v3/issues/1877#issuecomment-755387549&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/aws/aws-sdk-js-v3/issues/1877#issuecomment-755387549&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/UQccx/hyT5UEpOOP/g6cN1MU3gVJWva83mj9szk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;S3.GetObject no longer returns the result as a string &amp;middot; Issue #1877 &amp;middot; aws/aws-sdk-js-v3&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Describe the bug I'm using the GetObjectCommand with an S3Client to pull a file down from S3. In v2 of the SDK I can write response.Body.toString('utf-8') to turn the response into a string. In v3 ...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #16191f; text-align: left;&quot;&gt;v3에서부터는 buffer를 스트리밍 형태로 주고받습니다. 대표로 &lt;span style=&quot;color: #16191f; text-align: left;&quot;&gt;&lt;b&gt;GetObjectCommand&lt;/b&gt;의 사용형태를 확인해 보겠습니다.&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #16191f; text-align: left;&quot;&gt;&lt;span style=&quot;color: #16191f; text-align: left;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2252&quot; data-origin-height=&quot;1624&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/m742o/btsw0hbrpjy/mrxCKt0GyIRKFWlvr5jVk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/m742o/btsw0hbrpjy/mrxCKt0GyIRKFWlvr5jVk1/img.png&quot; data-alt=&quot;https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/with-s3-tutorial.html&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/m742o/btsw0hbrpjy/mrxCKt0GyIRKFWlvr5jVk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fm742o%2Fbtsw0hbrpjy%2FmrxCKt0GyIRKFWlvr5jVk1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;622&quot; height=&quot;449&quot; data-origin-width=&quot;2252&quot; data-origin-height=&quot;1624&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/with-s3-tutorial.html&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드를 보시다시피 &lt;span style=&quot;color: #16191f; text-align: left;&quot;&gt;&lt;b&gt;GetObjectCommand&lt;/b&gt;의 결과로 가져온 데이터의 Body의 타입은 &lt;b&gt;StreamingBlobPayloadOutputTypes&lt;/b&gt; 입니다. &lt;b&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;v2에서 getObject로 가져온 값의 body는 buffer였으나 v3부터는&amp;nbsp;&lt;span style=&quot;color: #16191f; text-align: left;&quot;&gt;buffer가 아니라 stereaming 형태의 타입이며&amp;nbsp; buffer 형태로 가져오기 위해서는 stream을 buffer로 변환해야 합니다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #16191f; text-align: left;&quot;&gt;에피소드&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #16191f; text-align: left;&quot;&gt;로컬에서 테스를 하면서 약간의 에피소드가 있었는데 nvm으로 node버전을 변경해 가면서 테스트하다 보니 e2e테스트를 위해 띄우는 로컬 서버는 18.x로 띄우고 테스트 실행하는 node 버전은 16.x로 실행하다 보니 자꾸 127.0.0.1:4569 (serverless-offline 주소)를 연결할 수 없다고 뜨는 것이었습니다.ㅎㅎ &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #16191f; text-align: left;&quot;&gt;결론적으로는 node버전이 달랐기도 했고 &lt;b&gt;v17.x 부터는 기본적으로 IPv6를 사용&lt;/b&gt;하기 때문에 서버가 떠있는데도 연결이 불가능했던 것입니다. 약간 바보 같은 실수이긴 하지만 그래도 나름 얻은 건 있던 것 같습니다 ㅋㅋ&lt;/span&gt;&lt;span style=&quot;color: #16191f; text-align: left;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1696424187421&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[NodeJs] localhost가 실행되었는데 127.0.0.1 에 접속되지 않는 경우&quot; data-og-description=&quot;해결 방법 (결론) 결론부터 말하자면 NodeJs 버전 17 이상부터 서버 실행시 ipv6 프로토콜을 우선적으로 사용하기 때문에 ipv4 프로토콜의 루프백 주소인 127.0.0.1 은 연결이 되지 않는 것이다. 그래서 &quot; data-og-host=&quot;stirringdev.tistory.com&quot; data-og-source-url=&quot;https://stirringdev.tistory.com/102&quot; data-og-url=&quot;https://stirringdev.tistory.com/102&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b9cmrN/hyT5W95yvr/7wMm1JLOOlKPyzrqeiiqTK/img.png?width=800&amp;amp;height=471&amp;amp;face=0_0_800_471,https://scrap.kakaocdn.net/dn/1btbt/hyT5T6zK0g/8ReMTCU74Nt5y04vUu7Enk/img.png?width=800&amp;amp;height=471&amp;amp;face=0_0_800_471,https://scrap.kakaocdn.net/dn/rD9Wa/hyT5UdlzQU/kNA0vVXYkXoB9sVB0Gq3rk/img.png?width=1563&amp;amp;height=921&amp;amp;face=0_0_1563_921&quot;&gt;&lt;a href=&quot;https://stirringdev.tistory.com/102&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://stirringdev.tistory.com/102&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b9cmrN/hyT5W95yvr/7wMm1JLOOlKPyzrqeiiqTK/img.png?width=800&amp;amp;height=471&amp;amp;face=0_0_800_471,https://scrap.kakaocdn.net/dn/1btbt/hyT5T6zK0g/8ReMTCU74Nt5y04vUu7Enk/img.png?width=800&amp;amp;height=471&amp;amp;face=0_0_800_471,https://scrap.kakaocdn.net/dn/rD9Wa/hyT5UdlzQU/kNA0vVXYkXoB9sVB0Gq3rk/img.png?width=1563&amp;amp;height=921&amp;amp;face=0_0_1563_921');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[NodeJs] localhost가 실행되었는데 127.0.0.1 에 접속되지 않는 경우&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;해결 방법 (결론) 결론부터 말하자면 NodeJs 버전 17 이상부터 서버 실행시 ipv6 프로토콜을 우선적으로 사용하기 때문에 ipv4 프로토콜의 루프백 주소인 127.0.0.1 은 연결이 되지 않는 것이다. 그래서&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;stirringdev.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #16191f; text-align: left;&quot;&gt;&lt;span style=&quot;color: #16191f; text-align: left;&quot;&gt;3. 결론&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #16191f; text-align: left;&quot;&gt;저희는 테스트 케이스를 작성하고 있어서 버전업에 대한 대응이나 리팩토링에 대해 덜 부담스럽게 작업할 수 있었던 것 같습니다. 비즈니스 로직을 작성하는 것도 중요하지만 적절한 시기에 맞추어 유지보수를 위한 버전관리도 정말 중요합니다. 이럴 때 특히 테스트 케이스의 필요성이 더 강조되는 것 같습니다!&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #16191f; text-align: left;&quot;&gt;아직 버전 관리에 대응해야 하는 프로젝트들이 많지만... 연말인 만큼 이런 것들 후다닥 해치우고 서비스 성장을 위해 달려가야 할 것 같습니다!&amp;nbsp;&lt;/span&gt;&lt;/p&gt;</description>
      <category>  프로그래밍/node</category>
      <category>aws-sdk</category>
      <category>lambda</category>
      <category>nodejs18</category>
      <author>피트웨어 제이 (FitwareJay)</author>
      <guid isPermaLink="true">https://jay-ji.tistory.com/119</guid>
      <comments>https://jay-ji.tistory.com/119#entry119comment</comments>
      <pubDate>Wed, 4 Oct 2023 22:16:05 +0900</pubDate>
    </item>
    <item>
      <title>Serverless Framework로 AWS Lambada 배포하기</title>
      <link>https://jay-ji.tistory.com/118</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요! 오랜만에 돌아온 개발자 JAY입니다! 요즘 좀 업무에 집중하고 이것저것 하다 보니 글을 진짜 오랜만에 쓰네요 ㅋㅋ 오늘은 신규업무를 하면서 알게 된 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;Serverles Framework&lt;/b&gt;&lt;/span&gt;에 대해서 설명해보려고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. What is Serverless Framework&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2072&quot; data-origin-height=&quot;1476&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bfLTZt/btr7gSgZvWK/6a9GkiJSoLPgkkKo8AGQR0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bfLTZt/btr7gSgZvWK/6a9GkiJSoLPgkkKo8AGQR0/img.png&quot; data-alt=&quot;serverless freamwork 홈페이지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bfLTZt/btr7gSgZvWK/6a9GkiJSoLPgkkKo8AGQR0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbfLTZt%2Fbtr7gSgZvWK%2F6a9GkiJSoLPgkkKo8AGQR0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;572&quot; height=&quot;407&quot; data-origin-width=&quot;2072&quot; data-origin-height=&quot;1476&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;serverless freamwork 홈페이지&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Severless Framework &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://www.serverless.com/framework&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;홈페이지&lt;/a&gt;&lt;/span&gt;에 들어가게되면 대문짝만 하게 위와 같은 설명이 나옵니다. &lt;i&gt;&lt;b&gt;AWS 람다 앱 auto-scaling을 위한 all-in-one 개발 솔루션이라고&lt;/b&gt;&lt;/i&gt; 하네요 ㅋㅋ&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;serverless framework는 람다 배포를 야믈(yaml) 파일 형태로 배포할 수 있게 해주는 솔루션 입니다. 보통 람다는 AWS 콘솔에 들어가서 직접 수정할 수도 있지만 serverless framework를 이용하면 배포와 인프라 세팅을 손쉽게 할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. AWS Lambda 배포하기&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자, 이제 serverless framwork를 통해 간단한 람다 api를 만들어 보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;  첫 번째로 serverless framework를 설치합니다.&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;npm&amp;nbsp;install&amp;nbsp;-g&amp;nbsp;serverless&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치가 완료되면 제대로 설치되었는지 버전확인을 한번 해봅니다&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;serverless --version 혹은 sls --version&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;724&quot; data-origin-height=&quot;414&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/czoQES/btr7iM8qVV6/RfnlqpzsE5Ky7B7cAbKJT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/czoQES/btr7iM8qVV6/RfnlqpzsE5Ky7B7cAbKJT1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/czoQES/btr7iM8qVV6/RfnlqpzsE5Ky7B7cAbKJT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FczoQES%2Fbtr7iM8qVV6%2FRfnlqpzsE5Ky7B7cAbKJT1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;326&quot; height=&quot;186&quot; data-origin-width=&quot;724&quot; data-origin-height=&quot;414&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;  두 번째로는 프로젝트를 생성합니다.&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;serverless 혹은 sls&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bsM3d3/btr7hTtlb2g/ro68DyVF34ed6BKxBlfx00/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bsM3d3/btr7hTtlb2g/ro68DyVF34ed6BKxBlfx00/img.png&quot; data-origin-width=&quot;558&quot; data-origin-height=&quot;534&quot; data-is-animation=&quot;false&quot; style=&quot;width: 43.1359%; margin-right: 10px;&quot; data-widthpercent=&quot;43.64&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bsM3d3/btr7hTtlb2g/ro68DyVF34ed6BKxBlfx00/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbsM3d3%2Fbtr7hTtlb2g%2Fro68DyVF34ed6BKxBlfx00%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;558&quot; height=&quot;534&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPaN8t/btr7s39toEh/Ea6Em5aAaPcA3fxjRmrYxK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPaN8t/btr7s39toEh/Ea6Em5aAaPcA3fxjRmrYxK/img.png&quot; data-origin-width=&quot;1012&quot; data-origin-height=&quot;750&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;56.36&quot; style=&quot;width: 55.7013%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPaN8t/btr7s39toEh/Ea6Em5aAaPcA3fxjRmrYxK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbPaN8t%2Fbtr7s39toEh%2FEa6Em5aAaPcA3fxjRmrYxK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1012&quot; height=&quot;750&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;명령어를 실행하면 어떤 형태의 프로젝트를 만들것인지 선택할 수 있습니다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 node.js 프로젝트를 생성했습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2484&quot; data-origin-height=&quot;708&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4d8Yx/btr7flR0UiZ/T0YOYpXEfdZAHlOBUBojFk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4d8Yx/btr7flR0UiZ/T0YOYpXEfdZAHlOBUBojFk/img.png&quot; data-alt=&quot;이렇게 기본적으로 생성된 파일들을 확인 할 수 있습니다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4d8Yx/btr7flR0UiZ/T0YOYpXEfdZAHlOBUBojFk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4d8Yx%2Fbtr7flR0UiZ%2FT0YOYpXEfdZAHlOBUBojFk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2484&quot; height=&quot;708&quot; data-origin-width=&quot;2484&quot; data-origin-height=&quot;708&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이렇게 기본적으로 생성된 파일들을 확인 할 수 있습니다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;  세 번째로 생성된 프로젝트 경로에 가서 로컬환경에서 람다함수를 실행합니다.&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;sls&amp;nbsp;invoke&amp;nbsp;local&amp;nbsp;--function&amp;nbsp;helloWorld&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;882&quot; data-origin-height=&quot;194&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KhS9c/btr7n1jT1Wg/TApd4gQ696l11swMkWDQb0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KhS9c/btr7n1jT1Wg/TApd4gQ696l11swMkWDQb0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KhS9c/btr7n1jT1Wg/TApd4gQ696l11swMkWDQb0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKhS9c%2Fbtr7n1jT1Wg%2FTApd4gQ696l11swMkWDQb0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;564&quot; height=&quot;124&quot; data-origin-width=&quot;882&quot; data-origin-height=&quot;194&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;  네 번째로 배포를 위해 AWS 계정 세팅을 합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배포 시 AWS계정을 사용하는 방법은&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://www.serverless.com/framework/docs/providers/aws/guide/credentials&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt; 여러 가지&lt;/a&gt;&lt;/span&gt;가 있는데 저는 aws profile을 세팅해서 진행했습니다. 몇 가지 이유가 있는데 default로 회사계정을 사용하고 있어서 제 개인계정으로 쉽게 사용하기 위해서 aws profile 방식을 선택했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;~/.aws/credentilas&lt;/span&gt;&lt;/b&gt;파일에서 아래와 같이 프로필을 세팅합니다. AWS IAM 계정을 생성하는 방법은 별도로 다루지 않겠습니다. AWS IAM 계정 생성 시 인프라 세팅을 위한 권한이 필요합니다. 저는 테스트를 위해 adminisrator 권한이 있는 IAM 계정을 사용했습니다&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;[profileName1]&lt;br /&gt;aws_access_key_id=***************&lt;br /&gt;aws_secret_access_key=***************&lt;br /&gt;&amp;nbsp;&lt;br /&gt;[profileName2]&lt;br /&gt;aws_access_key_id=***************&lt;br /&gt;aws_secret_access_key=***************&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배포 명령어는 아래와 같습니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;serverless&amp;nbsp;deploy&amp;nbsp;--aws-profile&amp;nbsp;devProfile&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배포전 yaml파일을 살짝 수정하겠습니다. 저는 HTTP GET 호출을 사용하기 위해서 다음과 같이 events를 추가했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;804&quot; data-origin-height=&quot;824&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b5zQiJ/btr7mtOrDt4/UqiFDFQY4Z4qUy5f44jkM0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b5zQiJ/btr7mtOrDt4/UqiFDFQY4Z4qUy5f44jkM0/img.png&quot; data-alt=&quot;http get 요청을 받는 이벤트를 추가&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b5zQiJ/btr7mtOrDt4/UqiFDFQY4Z4qUy5f44jkM0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb5zQiJ%2Fbtr7mtOrDt4%2FUqiFDFQY4Z4qUy5f44jkM0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;497&quot; height=&quot;509&quot; data-origin-width=&quot;804&quot; data-origin-height=&quot;824&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;http get 요청을 받는 이벤트를 추가&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자 이제 배포를 해보겠습니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1760&quot; data-origin-height=&quot;418&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OGcXY/btr7hxXZcfL/JsvLKkrhFkKNdc2AjygN8k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OGcXY/btr7hxXZcfL/JsvLKkrhFkKNdc2AjygN8k/img.png&quot; data-alt=&quot;배포가 잘 되었다고 한다~&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OGcXY/btr7hxXZcfL/JsvLKkrhFkKNdc2AjygN8k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOGcXY%2Fbtr7hxXZcfL%2FJsvLKkrhFkKNdc2AjygN8k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1760&quot; height=&quot;418&quot; data-origin-width=&quot;1760&quot; data-origin-height=&quot;418&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;배포가 잘 되었다고 한다~&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배포가 잘 되었고 api endpoint까지 공유를 해주네요!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1336&quot; data-origin-height=&quot;348&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cfY1rg/btr7ggJd8hM/ESMhEX9uSTHPPlE5AAZvk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cfY1rg/btr7ggJd8hM/ESMhEX9uSTHPPlE5AAZvk0/img.png&quot; data-alt=&quot;endpoint에 접근하면 람다가 잘 응답을 주는걸 확인할 수 있습니다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cfY1rg/btr7ggJd8hM/ESMhEX9uSTHPPlE5AAZvk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcfY1rg%2Fbtr7ggJd8hM%2FESMhEX9uSTHPPlE5AAZvk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1336&quot; height=&quot;348&quot; data-origin-width=&quot;1336&quot; data-origin-height=&quot;348&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;endpoint에 접근하면 람다가 잘 응답을 주는걸 확인할 수 있습니다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. serverless framework 이거 무슨 magic이야?&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단한 serverless framwork 프로젝트 생성부터 배포까지 해봤는데요. 처음 보면 되게 마법 같다고 생각하시겠지만 알고 보면 그렇지 않습니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;549&quot; data-origin-height=&quot;245&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cefwOU/btr7iLPd5GM/KSVZqyHbmx9fwoheLtyI30/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cefwOU/btr7iLPd5GM/KSVZqyHbmx9fwoheLtyI30/img.png&quot; data-alt=&quot;CloudFormation 작동 방식&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cefwOU/btr7iLPd5GM/KSVZqyHbmx9fwoheLtyI30/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcefwOU%2Fbtr7iLPd5GM%2FKSVZqyHbmx9fwoheLtyI30%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;549&quot; height=&quot;245&quot; data-origin-width=&quot;549&quot; data-origin-height=&quot;245&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;CloudFormation 작동 방식&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배포하고 이것저것 생성된 인프라를 보니까 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://docs.aws.amazon.com/ko_kr/AWSCloudFormation/latest/UserGuide/cfn-whatis-howdoesitwork.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;CloudFormation&lt;/a&gt;&lt;/span&gt;이란게 생성되어 있더라고요. CloudFormation은 aws인프라를 템플릿을 통해 생성하고 배포하는 서비스입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아마도 serverless framework는 CloudeFormation을 사용해서 인프라 구성을 하는 것 같아요. 직접 CloudeFormation을 사용할 수 도 있지만 좀 더 편하게 구성할 수 있게 도와주는 것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cGCJ7Q/btr7mtt9IM3/HXJNF7CZtuiXoBPArkpcxk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cGCJ7Q/btr7mtt9IM3/HXJNF7CZtuiXoBPArkpcxk/img.png&quot; data-origin-width=&quot;4154&quot; data-origin-height=&quot;950&quot; data-is-animation=&quot;false&quot; style=&quot;width: 67.6668%; margin-right: 10px;&quot; data-widthpercent=&quot;68.46&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cGCJ7Q/btr7mtt9IM3/HXJNF7CZtuiXoBPArkpcxk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcGCJ7Q%2Fbtr7mtt9IM3%2FHXJNF7CZtuiXoBPArkpcxk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4154&quot; height=&quot;950&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/boYWjV/btr7iK31K7H/YwnAe3WADnSoB9PCh6a9y1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/boYWjV/btr7iK31K7H/YwnAe3WADnSoB9PCh6a9y1/img.png&quot; data-origin-width=&quot;4246&quot; data-origin-height=&quot;2108&quot; data-is-animation=&quot;false&quot; style=&quot;width: 31.1704%;&quot; data-widthpercent=&quot;31.54&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/boYWjV/btr7iK31K7H/YwnAe3WADnSoB9PCh6a9y1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FboYWjV%2Fbtr7iK31K7H%2FYwnAe3WADnSoB9PCh6a9y1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4246&quot; height=&quot;2108&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;자동으로 생성된 인프라 리소스들&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2592&quot; data-origin-height=&quot;1014&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b1XXoD/btr7pUrrqeh/GSREBu8LCmXkZARWE5t1L1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b1XXoD/btr7pUrrqeh/GSREBu8LCmXkZARWE5t1L1/img.png&quot; data-alt=&quot;배포 파일은 S3에 올라가는걸로 보이네요&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b1XXoD/btr7pUrrqeh/GSREBu8LCmXkZARWE5t1L1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb1XXoD%2Fbtr7pUrrqeh%2FGSREBu8LCmXkZARWE5t1L1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;570&quot; height=&quot;223&quot; data-origin-width=&quot;2592&quot; data-origin-height=&quot;1014&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;배포 파일은 S3에 올라가는걸로 보이네요&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CloudeFormation에 가보면 어떤 이벤트들이 있었고 어떤 리소스가 생겨났는지 한 번에 확인할 수 있습니다. 저같은 경우는 HTTP 이벤트를 사용한다고 yaml에 적었기 때문에 API Gateway까지 자동으로 생성되고 람다와 연결된걸 확인 할 수 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2904&quot; data-origin-height=&quot;2150&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cstjLH/btr7fZ2cd8a/jwsAV2HWMMPAzjt2oQQYV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cstjLH/btr7fZ2cd8a/jwsAV2HWMMPAzjt2oQQYV0/img.png&quot; data-alt=&quot;스택 제거시 생성된 인프라들이 하나씩 삭제되는걸 볼 수 있습니다&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cstjLH/btr7fZ2cd8a/jwsAV2HWMMPAzjt2oQQYV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcstjLH%2Fbtr7fZ2cd8a%2FjwsAV2HWMMPAzjt2oQQYV0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;516&quot; height=&quot;382&quot; data-origin-width=&quot;2904&quot; data-origin-height=&quot;2150&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;스택 제거시 생성된 인프라들이 하나씩 삭제되는걸 볼 수 있습니다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;생성된 CloudeFormation&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://docs.aws.amazon.com/ko_kr/AWSCloudFormation/latest/UserGuide/stacks.html&quot;&gt;스택&lt;/a&gt;&lt;/span&gt;을 제거하면 연관된 인프라들도 자동으로 삭제가 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;4. 트러블 슈팅&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;serverless framework docs에 설명이 잘 되어있어서 크게 어려운 부분은 없었는데요. 다만 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;권한 설정하는데 시간을 많이 소비&lt;/b&gt;&lt;/span&gt;했던 것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1550&quot; data-origin-height=&quot;550&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/C3JwR/btr7hw5PXw6/pta5gZGC4k9qf0VdKPOO41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/C3JwR/btr7hw5PXw6/pta5gZGC4k9qf0VdKPOO41/img.png&quot; data-alt=&quot;배포시 연관된 리소스들에 대한 권한이 없으면 에러가 납니다&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/C3JwR/btr7hw5PXw6/pta5gZGC4k9qf0VdKPOO41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FC3JwR%2Fbtr7hw5PXw6%2Fpta5gZGC4k9qf0VdKPOO41%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1550&quot; height=&quot;550&quot; data-origin-width=&quot;1550&quot; data-origin-height=&quot;550&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;배포시 연관된 리소스들에 대한 권한이 없으면 에러가 납니다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배포할 때 사용할 리소스들에 대한 권한이 &lt;b&gt;IAM 계정에 없으면 위처럼 에러를 뿜습니다.&lt;/b&gt; 위 에러는 처음에 제가 CloudFormation에 대한 권한을 주지 않아서 에러가 나더라고요 ㅎㅎ 근데 이게 일일이 사용할 인프라들에 대한 권한을 줘야 하다 보니 한 5개 추가하다가 계속 에러가 나서 그냥 &lt;b&gt;administrator&lt;/b&gt; 권한을 줘버렸습니다 ㅎㅎ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 실무에서는 보안을 위해서 실제 사용하는 인프라에 대한 권한만 줘야 합니다. 회사 동료는 한 60개를 한 땀 한 땀 직접 찾아서 넣었다고 하네요...  저는 그냥 맛보기니까 그냥 administrator로 했...지만 ㅋㅋㅋ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;5. 마치며&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;람다를 사용할 일이 크게 없었어서 serverless framework와 같은 서비스가 있는지 몰랐고 실제로 사용해 보니 정말 편하네요! serverless framework 말고도 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://docs.aws.amazon.com/ko_kr/serverless-application-model/latest/developerguide/what-is-sam.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;AWS SAM&lt;/a&gt;&lt;/span&gt;과 같은 서비스들도 있다고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;람다를 적재적소에 잘 사용하면 좋기 때문에 여러분들도 한번 간단하게 실습을 해보시면 좋을 것 같습니다! 그럼 오늘도 좋은 하루 보내시길 바랍니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/h3&gt;
&lt;figure id=&quot;og_1680357058513&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[AWS] 서버리스 프레임워크란? (serverless framework)설치부터 배포까지 (node.js)&quot; data-og-description=&quot;Provider: AWS(Amazon Web Service) 작업환경: macOS(Mojave, 10.14.6 서버리스(Serverless)란? 요즘 이곳저곳에서 MSA(Micro Service Architecture)가 관심이 많아지고 있다. 이에따라 MSA를 편리하게 구현시킬 수 있는 클라&quot; data-og-host=&quot;yongyong-blog.tistory.com&quot; data-og-source-url=&quot;https://yongyong-blog.tistory.com/1&quot; data-og-url=&quot;https://yongyong-blog.tistory.com/1&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cRlxae/hyR6RKHhoc/ZKB4TAxnpNTOxPpesGTZhK/img.png?width=800&amp;amp;height=313&amp;amp;face=0_0_800_313,https://scrap.kakaocdn.net/dn/cbQfHP/hyR7CZt6PU/9Bc5cRW0TaZdR5J7wk1Qr1/img.png?width=800&amp;amp;height=313&amp;amp;face=0_0_800_313,https://scrap.kakaocdn.net/dn/2kINS/hyR6TBLotg/PxYSIRDtOJmplfheMAX0Bk/img.png?width=1280&amp;amp;height=501&amp;amp;face=0_0_1280_501&quot;&gt;&lt;a href=&quot;https://yongyong-blog.tistory.com/1&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://yongyong-blog.tistory.com/1&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cRlxae/hyR6RKHhoc/ZKB4TAxnpNTOxPpesGTZhK/img.png?width=800&amp;amp;height=313&amp;amp;face=0_0_800_313,https://scrap.kakaocdn.net/dn/cbQfHP/hyR7CZt6PU/9Bc5cRW0TaZdR5J7wk1Qr1/img.png?width=800&amp;amp;height=313&amp;amp;face=0_0_800_313,https://scrap.kakaocdn.net/dn/2kINS/hyR6TBLotg/PxYSIRDtOJmplfheMAX0Bk/img.png?width=1280&amp;amp;height=501&amp;amp;face=0_0_1280_501');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[AWS] 서버리스 프레임워크란? (serverless framework)설치부터 배포까지 (node.js)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Provider: AWS(Amazon Web Service) 작업환경: macOS(Mojave, 10.14.6 서버리스(Serverless)란? 요즘 이곳저곳에서 MSA(Micro Service Architecture)가 관심이 많아지고 있다. 이에따라 MSA를 편리하게 구현시킬 수 있는 클라&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;yongyong-blog.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;figure id=&quot;og_1680357311419&quot; style=&quot;color: #333333; text-align: start;&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Serverless Framework - AWS Credentials&quot; data-og-description=&quot;The Serverless Framework documentation for AWS Lambda, API Gateway, EventBridge, DynamoDB and much more.&quot; data-og-host=&quot;www.serverless.com&quot; data-og-source-url=&quot;https://www.serverless.com/framework/docs/providers/aws/guide/credentials&quot; data-og-url=&quot;https://serverless.com/framework/docs/providers/aws/guide/credentials&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/SYNIq/hyR7AN8plZ/Je5tmgLm0PtpK0EOoPkcz0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://www.serverless.com/framework/docs/providers/aws/guide/credentials&quot; data-source-url=&quot;https://www.serverless.com/framework/docs/providers/aws/guide/credentials&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/SYNIq/hyR7AN8plZ/Je5tmgLm0PtpK0EOoPkcz0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; style=&quot;color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;Serverless Framework - AWS Credentials&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; style=&quot;color: #909090;&quot; data-ke-size=&quot;size16&quot;&gt;The Serverless Framework documentation for AWS Lambda, API Gateway, EventBridge, DynamoDB and much more.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; style=&quot;color: #909090;&quot; data-ke-size=&quot;size16&quot;&gt;www.serverless.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;figure id=&quot;og_1680357316665&quot; style=&quot;color: #333333; text-align: start;&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;AWS CloudFormation으로 인프라 자동화 시작하기&quot; data-og-description=&quot;이 글은 CloudFormatin을 처음으로 시작하는 사용자를 위한 안내서이다. 이미 CloudFormation을 능숙하게 사용하고 있다면 사용 방법에 대한 설명은 대충 보고, 실무에서 어떻게 사용하는지에 대해서 주&quot; data-og-host=&quot;medium.com&quot; data-og-source-url=&quot;https://medium.com/pplink/aws-cloudformation%EC%9C%BC%EB%A1%9C-%EC%9D%B8%ED%94%84%EB%9D%BC-%EC%9E%90%EB%8F%99%ED%99%94-%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0-9fe13cdf08c9&quot; data-og-url=&quot;https://medium.com/pplink/aws-cloudformation%EC%9C%BC%EB%A1%9C-%EC%9D%B8%ED%94%84%EB%9D%BC-%EC%9E%90%EB%8F%99%ED%99%94-%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0-9fe13cdf08c9&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/coMRwt/hyR7xYbhJC/tQGHCVkP9LqAXEwqkospf0/img.png?width=1200&amp;amp;height=332&amp;amp;face=0_0_1200_332&quot;&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://medium.com/pplink/aws-cloudformation%EC%9C%BC%EB%A1%9C-%EC%9D%B8%ED%94%84%EB%9D%BC-%EC%9E%90%EB%8F%99%ED%99%94-%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0-9fe13cdf08c9&quot; data-source-url=&quot;https://medium.com/pplink/aws-cloudformation%EC%9C%BC%EB%A1%9C-%EC%9D%B8%ED%94%84%EB%9D%BC-%EC%9E%90%EB%8F%99%ED%99%94-%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0-9fe13cdf08c9&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/coMRwt/hyR7xYbhJC/tQGHCVkP9LqAXEwqkospf0/img.png?width=1200&amp;amp;height=332&amp;amp;face=0_0_1200_332');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; style=&quot;color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;AWS CloudFormation으로 인프라 자동화 시작하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; style=&quot;color: #909090;&quot; data-ke-size=&quot;size16&quot;&gt;이 글은 CloudFormatin을 처음으로 시작하는 사용자를 위한 안내서이다. 이미 CloudFormation을 능숙하게 사용하고 있다면 사용 방법에 대한 설명은 대충 보고, 실무에서 어떻게 사용하는지에 대해서 주&lt;/p&gt;
&lt;p class=&quot;og-host&quot; style=&quot;color: #909090;&quot; data-ke-size=&quot;size16&quot;&gt;medium.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;</description>
      <category>  프로그래밍/AWS</category>
      <category>AWS</category>
      <category>aws lambda</category>
      <category>cloudformation</category>
      <category>serverless framework</category>
      <author>피트웨어 제이 (FitwareJay)</author>
      <guid isPermaLink="true">https://jay-ji.tistory.com/118</guid>
      <comments>https://jay-ji.tistory.com/118#entry118comment</comments>
      <pubDate>Sat, 1 Apr 2023 22:57:33 +0900</pubDate>
    </item>
    <item>
      <title>중니어가 되고싶은 개발자의 2022년 회고</title>
      <link>https://jay-ji.tistory.com/117</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요! 운동'했'던 개발자 제이입니다!   매년 느끼는 거지만 시간이 참 빠르게 지나가는 것 같다는 생각이 듭니다ㅎㅎ 그만큼 바쁘게 살아왔다는 거겠죠?! ㅋㅋ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 한해를 마무리하면서 회고를 쓰는 게 참 좋은 것 같습니다. 회고를 통해서나마&lt;b&gt; 1년 동안 내가 목표했던 것들을 이루었는지, 무엇을 잘했고 못했는지를 정리하는 시간&lt;/b&gt;을 가지는 게 다음 해의 성장과 로드맵(인생, 커리어)을 그리는데 도움이 되는 것 같아요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저에게 2022년은 꽤 많은 일들이 있었던 한해였습니다. &lt;b&gt;당황, 슬픔, 기쁨...희로애락이 Big 이벤트로 하나씩 왔던 것 같습니다 ㅋㅋㅋ&lt;/b&gt; 올해는 어떤 일들이 있었는지 하나씩 살펴보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. 사내 컨퍼런스 (aka 프로콘)&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dqhW6a/btrUoNd6Y9I/K6iV0D9IUUGjJW6z1yTXCK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dqhW6a/btrUoNd6Y9I/K6iV0D9IUUGjJW6z1yTXCK/img.jpg&quot; data-origin-width=&quot;1278&quot; data-origin-height=&quot;958&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.4315%; margin-right: 10px;&quot; data-widthpercent=&quot;50.01&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dqhW6a/btrUoNd6Y9I/K6iV0D9IUUGjJW6z1yTXCK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdqhW6a%2FbtrUoNd6Y9I%2FK6iV0D9IUUGjJW6z1yTXCK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1278&quot; height=&quot;958&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cvhaF9/btrUnf9746f/mJsJBVmlIzdONgAZkkTxL0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cvhaF9/btrUnf9746f/mJsJBVmlIzdONgAZkkTxL0/img.jpg&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;960&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.4057%;&quot; data-widthpercent=&quot;49.99&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cvhaF9/btrUnf9746f/mJsJBVmlIzdONgAZkkTxL0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcvhaF9%2FbtrUnf9746f%2FmJsJBVmlIzdONgAZkkTxL0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;960&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;DDD 관련 주제로 발표를 진행했다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개인적으로 컨퍼런스에서 발표하는 게 버킷리스트 중 하나였습니다. 마침 회사에서 사내 컨퍼런스를 연다고 해서 &quot;이때다!&quot; 싶어서 바로 지원을 했습니다. 저의 발표 주제는 &lt;b&gt;새로운 프로젝트를 진행하면서 DDD를 처음 접했을 때 느꼈던 생각&lt;/b&gt;등에 대해서 정리한 내용이었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;발표는 늘 새롭고 힘든 것 같습니다. 몇 번을 연습했는데도 발표 당일 호흡조절도 잘 못하고 목소리도 떨리고 ㅋㅋㅋ 그래도 덕분에 좋은 경험을 했던 것 같습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨퍼런스를 통해 동료들과 더 친해지는 계기도 되고 준비를 하는 과정에서 많은 것들을 배웠습니다. 정말 나중에는 외부 컨퍼런스에서 여러 사람들에게 도움이 되는 발표를 하고 싶네요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. 사내 글쓰기 모임 리딩&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;737&quot; data-origin-height=&quot;401&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bb7bmY/btrUCjcW8YO/2FFMyPez1wQ6WIbK0raBHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bb7bmY/btrUCjcW8YO/2FFMyPez1wQ6WIbK0raBHk/img.png&quot; data-alt=&quot;채널에 글쓰기를 함께할 동료들을 모았다&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bb7bmY/btrUCjcW8YO/2FFMyPez1wQ6WIbK0raBHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbb7bmY%2FbtrUCjcW8YO%2F2FFMyPez1wQ6WIbK0raBHk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;537&quot; height=&quot;292&quot; data-origin-width=&quot;737&quot; data-origin-height=&quot;401&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;채널에 글쓰기를 함께할 동료들을 모았다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;글을 읽는 여러분들도 마찬가지겠지만, 저는 '&lt;b&gt;성장'&lt;/b&gt;을 중요하게 생각하는 사람입니다. 근데 이 '성장'이 저 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;혼자만의 성장이 아니라 나, 동료, 회사의 성장&lt;/b&gt;&lt;/span&gt;을 말합니다!&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;회사생활을 하면서 함께 성장할 수 있는 재밌는 이벤트가 뭐가 있을까 고민하다가 제가 예전에 참여했던 개발자 글쓰기 모임(글또)이 떠올랐습니다. 그래서 &lt;b&gt;다또(다노+글또)&lt;/b&gt;를 만들어서 함께할 동료들을 모집했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대단한 일은 아니지만 2주마다 서로 공부한 내용을 블로그로 적고 공유하는 과정에서 함께 성장한다는 느낌도 받았고 동료들에게 많은 동기부여도 많이 받았던 것 같습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 이런 모임을 만들어도 결국 같이 하는 동료들이 없다면 무용지물인데 생각보다 많은 동료들이 함께해줘서 놀랍고 고마웠습니다.&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1672004786217&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;사내 글쓰기 모임 운영 후기 및 회고 (feat.다또)&quot; data-og-description=&quot;올해 1월부터 6월까지 사내 글쓰기 모임을 운영하면서 느낀 점 등을 정리하는 글입니다! 시간이 생각보다 금방 흘러가네요...벌써 반년이 지나다니;;   사내 글쓰기 모임을 시작한 이유 개인적&quot; data-og-host=&quot;jay-ji.tistory.com&quot; data-og-source-url=&quot;https://jay-ji.tistory.com/103&quot; data-og-url=&quot;https://jay-ji.tistory.com/103&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dNhN7a/hyQ1gqgOCA/RHm4iPIGxsndlwWgKVGz11/img.png?width=290&amp;amp;height=250&amp;amp;face=0_0_290_250,https://scrap.kakaocdn.net/dn/vYKiv/hyQ1lLP7jT/maQb0AakRvsbHkXYBPDBlK/img.png?width=290&amp;amp;height=250&amp;amp;face=0_0_290_250,https://scrap.kakaocdn.net/dn/RmN9b/hyQ1sc9VJj/EiiF8hv8kKEbQLrBDhNtxK/img.png?width=830&amp;amp;height=686&amp;amp;face=0_0_830_686&quot;&gt;&lt;a href=&quot;https://jay-ji.tistory.com/103&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jay-ji.tistory.com/103&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dNhN7a/hyQ1gqgOCA/RHm4iPIGxsndlwWgKVGz11/img.png?width=290&amp;amp;height=250&amp;amp;face=0_0_290_250,https://scrap.kakaocdn.net/dn/vYKiv/hyQ1lLP7jT/maQb0AakRvsbHkXYBPDBlK/img.png?width=290&amp;amp;height=250&amp;amp;face=0_0_290_250,https://scrap.kakaocdn.net/dn/RmN9b/hyQ1sc9VJj/EiiF8hv8kKEbQLrBDhNtxK/img.png?width=830&amp;amp;height=686&amp;amp;face=0_0_830_686');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;사내 글쓰기 모임 운영 후기 및 회고 (feat.다또)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;올해 1월부터 6월까지 사내 글쓰기 모임을 운영하면서 느낀 점 등을 정리하는 글입니다! 시간이 생각보다 금방 흘러가네요...벌써 반년이 지나다니;;   사내 글쓰기 모임을 시작한 이유 개인적&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;jay-ji.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. 해커톤 아이디어가 프로덕으로!&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ctuS3V/btrUwr37TCX/LmKyiv6oB4Oxj7vM6nxNw1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ctuS3V/btrUwr37TCX/LmKyiv6oB4Oxj7vM6nxNw1/img.jpg&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;960&quot; data-is-animation=&quot;false&quot; style=&quot;width: 32.7418%; margin-right: 10px;&quot; data-widthpercent=&quot;33.52&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ctuS3V/btrUwr37TCX/LmKyiv6oB4Oxj7vM6nxNw1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FctuS3V%2FbtrUwr37TCX%2FLmKyiv6oB4Oxj7vM6nxNw1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;960&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/r5uSU/btrUyhNGN8I/YelGfEWeO8Ycbp53haZY7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/r5uSU/btrUyhNGN8I/YelGfEWeO8Ycbp53haZY7k/img.png&quot; data-origin-width=&quot;560&quot; data-origin-height=&quot;393&quot; data-is-animation=&quot;false&quot; style=&quot;width: 34.9912%; margin-right: 10px;&quot; data-widthpercent=&quot;35.82&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/r5uSU/btrUyhNGN8I/YelGfEWeO8Ycbp53haZY7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fr5uSU%2FbtrUyhNGN8I%2FYelGfEWeO8Ycbp53haZY7k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;560&quot; height=&quot;393&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/licWx/btrUujMoJFM/CbvqrsTkBSKwXviOrcdll0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/licWx/btrUujMoJFM/CbvqrsTkBSKwXviOrcdll0/img.png&quot; data-origin-width=&quot;417&quot; data-origin-height=&quot;342&quot; data-is-animation=&quot;false&quot; style=&quot;width: 29.9415%;&quot; data-widthpercent=&quot;30.66&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/licWx/btrUujMoJFM/CbvqrsTkBSKwXviOrcdll0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlicWx%2FbtrUujMoJFM%2FCbvqrsTkBSKwXviOrcdll0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;417&quot; height=&quot;342&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;해커톤 아이디어에 대한 구체적인 방향 논의&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2022년에는 뭔가 굵직한 이벤트들이 많았던 것 같습니다. 회사에서 무려 일주일 동안 해커톤을 진행했습니다. IT회사를 다니면서 나름 로망이 해커톤을 해보는 거였는데 로망을 이루었습니다 ㅋㅋㅋ&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해커톤은 아이디어를 제공하고 많은 픽(pick)이 된 아이디어를 가지고 프로토타입을 만드는 방식으로 진행되었습니다. 저도 아이디어를 냈는데 운 좋게(?) 픽이 되어서 함께할 동료들을 모아서 진행했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제가 낸 아이디어는 &lt;b&gt;여러 사람들이 플랜(plan)을 공유하고 피드백해주는 플랫폼&lt;/b&gt;입니다. 최근에 여자친구랑 제주도 여행을 준비하면서 계획을 짜는 과정이 쉽지 않았어서 누군가의 계획을 그대로 보고 따라 하면 좋을 것 같다는 생각에서 시작된 아이디어였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1181&quot; data-origin-height=&quot;775&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wTH6P/btrUxpZgp5Z/Xl015XgHO4yCPKaj1ZmK10/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wTH6P/btrUxpZgp5Z/Xl015XgHO4yCPKaj1ZmK10/img.png&quot; data-alt=&quot;코딩도 하긴 했지만... 저녁에 많이 놀긴 했음...ㅋㅋㅋ&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wTH6P/btrUxpZgp5Z/Xl015XgHO4yCPKaj1ZmK10/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwTH6P%2FbtrUxpZgp5Z%2FXl015XgHO4yCPKaj1ZmK10%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;426&quot; height=&quot;280&quot; data-origin-width=&quot;1181&quot; data-origin-height=&quot;775&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;코딩도 하긴 했지만... 저녁에 많이 놀긴 했음...ㅋㅋㅋ&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해커톤을 진행하던 일주일 동안은 동료들과 에어비엔비로 숙소를 잡아서 함께 코딩도 하고 맛있는 음식을 먹으면서 재밌는 시간을 보냈습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개인적으로 이번 해커톤이 더 뜻깊었던 것은 실제 프로덕까지 릴리즈 했다는 것입니다. 이 시기에 회사에서 많은 도전을 해보던 때라서 해커톤 프로젝트 중 몇 개를 선정해서 실제 릴리즈까지 하게 되었는데 그 과정에서 제 아이디어가 선택되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 달 좀 넘는 기간 동안 TF팀을 꾸려서 더 완성도 높은 프로덕으로 릴리즈를 했습니다. 팀원들 모두 열정을 다해서 기획, 개발, 디자인을 했던 것 같고 애정도 많았던 것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아쉽게도 회사 사정상 프로덕은 접게 되었지만 이 과정에서 혼자 백엔드 전반적인 부분을 담당하면서 얻어가는 것들이 많아서 개인적으로는 성장에 도움이 많이 되었던 것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함께해준 플랜어스 TF팀들에게도 다시 한번 고맙고 고생했다는 말을 전달하고 싶네요  &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1672004881248&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot; 해커톤 아이디어에서 실제 프로덕 배포까지 썰&quot; data-og-description=&quot;안녕하세요! 개발자 JAY입니다! 몇 달 전에 사내 해커톤을 진행했었는데요! 운이 좋게도 제가 낸 아이디어가 선정되어 팀을 만들어서 프로토타입을 만들었습니다! 더 신기하게도 해커톤 아이디&quot; data-og-host=&quot;jay-ji.tistory.com&quot; data-og-source-url=&quot;https://jay-ji.tistory.com/111&quot; data-og-url=&quot;https://jay-ji.tistory.com/111&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cuvxms/hyQ1oBO2LE/IlX6uyj20beIJRYc6nZKk0/img.png?width=732&amp;amp;height=732&amp;amp;face=0_0_732_732,https://scrap.kakaocdn.net/dn/ciLA8p/hyQ1lymhZ7/Kds7bULeS0umfTcCATlXDK/img.png?width=732&amp;amp;height=732&amp;amp;face=0_0_732_732,https://scrap.kakaocdn.net/dn/n4lSD/hyQ1hQfHrn/9pDBLowNpOiofL3D4VBBp0/img.png?width=1528&amp;amp;height=1442&amp;amp;face=0_0_1528_1442&quot;&gt;&lt;a href=&quot;https://jay-ji.tistory.com/111&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jay-ji.tistory.com/111&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cuvxms/hyQ1oBO2LE/IlX6uyj20beIJRYc6nZKk0/img.png?width=732&amp;amp;height=732&amp;amp;face=0_0_732_732,https://scrap.kakaocdn.net/dn/ciLA8p/hyQ1lymhZ7/Kds7bULeS0umfTcCATlXDK/img.png?width=732&amp;amp;height=732&amp;amp;face=0_0_732_732,https://scrap.kakaocdn.net/dn/n4lSD/hyQ1hQfHrn/9pDBLowNpOiofL3D4VBBp0/img.png?width=1528&amp;amp;height=1442&amp;amp;face=0_0_1528_1442');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt; 해커톤 아이디어에서 실제 프로덕 배포까지 썰&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;안녕하세요! 개발자 JAY입니다! 몇 달 전에 사내 해커톤을 진행했었는데요! 운이 좋게도 제가 낸 아이디어가 선정되어 팀을 만들어서 프로토타입을 만들었습니다! 더 신기하게도 해커톤 아이디&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;jay-ji.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;4. '나는 주니어 개발자다' 세종도서 학술 부문 선정&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcI5LU/btrUnY8aFgG/GftMLmeDgNlnjWNWMlnQWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcI5LU/btrUnY8aFgG/GftMLmeDgNlnjWNWMlnQWK/img.png&quot; data-origin-width=&quot;1418&quot; data-origin-height=&quot;1388&quot; data-is-animation=&quot;false&quot; width=&quot;457&quot; height=&quot;447&quot; style=&quot;width: 53.6076%; margin-right: 10px;&quot; data-widthpercent=&quot;54.24&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcI5LU/btrUnY8aFgG/GftMLmeDgNlnjWNWMlnQWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcI5LU%2FbtrUnY8aFgG%2FGftMLmeDgNlnjWNWMlnQWK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1418&quot; height=&quot;1388&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rGIxQ/btrUl0ePnp4/mqQW7K8KEqA2G2uIfMTgG1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rGIxQ/btrUl0ePnp4/mqQW7K8KEqA2G2uIfMTgG1/img.jpg&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1485&quot; data-is-animation=&quot;false&quot; style=&quot;width: 45.2296%;&quot; data-widthpercent=&quot;45.76&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rGIxQ/btrUl0ePnp4/mqQW7K8KEqA2G2uIfMTgG1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrGIxQ%2FbtrUl0ePnp4%2FmqQW7K8KEqA2G2uIfMTgG1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;1485&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;응? 이게 왜?ㅋㅋㅋ 갑자기 세종도서 학술부문 선정 되었다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;글또를 통해 만났던 분들과 작년에 '나는 주니어 개발자다'라는 책을 공동집필 했었습니다. 책을 출판했다는 것 자체만으로도 기분이 좋았는데 갑자기 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://bookapply.kpipa.or.kr/front/intro/introduce.do&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;세종도서 학술부문&lt;/a&gt;&lt;/span&gt;에 선정되었다고 해서 더 기분이 좋았던 것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 연락을 받기 전까지는 이런 기관이 존재한다는 것 자체도 몰랐지만 ㅋㅋㅋ 전문가들의 피드백을 통해서 저희 책이 선정되었다는 점에서 뜻깊었던 것 같습니다. 저희 책이 조금이나마 다른 분들에게 도움이 되고 긍정적인 영향을 줄 수 있으면 좋겠네요!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;5. 예정에 없던 퇴사 (Good Bye DANO)&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;375&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/boF8Qz/btrUncZZtCS/WK0MKTiB9Z2uNIoCtJzUV1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/boF8Qz/btrUncZZtCS/WK0MKTiB9Z2uNIoCtJzUV1/img.jpg&quot; data-alt=&quot;얼어붙은 IT 업계&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/boF8Qz/btrUncZZtCS/WK0MKTiB9Z2uNIoCtJzUV1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FboF8Qz%2FbtrUncZZtCS%2FWK0MKTiB9Z2uNIoCtJzUV1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;308&quot; height=&quot;231&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;375&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;얼어붙은 IT 업계&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;올 한 해중 가장 당황스럽고 아쉬웠던 순간이었습니다. 아무래도 올 한해 IT업계의 투자상황이 좋지 않은 것도 있고 회사 내부사정으로 여러 가지 힘든 일들이 겹쳤던 것 같습니다. 결론부터 말하자면 예정에 없던 퇴사를 하게 되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bQxHTn/btrUxo7cFf5/hc8T6KCPkZBeVBIIYWUtbK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bQxHTn/btrUxo7cFf5/hc8T6KCPkZBeVBIIYWUtbK/img.png&quot; data-origin-width=&quot;2948&quot; data-origin-height=&quot;3081&quot; data-is-animation=&quot;false&quot; style=&quot;width: 46.3379%; margin-right: 10px;&quot; data-widthpercent=&quot;46.88&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bQxHTn/btrUxo7cFf5/hc8T6KCPkZBeVBIIYWUtbK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbQxHTn%2FbtrUxo7cFf5%2Fhc8T6KCPkZBeVBIIYWUtbK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2948&quot; height=&quot;3081&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/clAcNg/btrUDiLPm4e/Lw85A3th1vNgr3PKcsK8x1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/clAcNg/btrUDiLPm4e/Lw85A3th1vNgr3PKcsK8x1/img.png&quot; data-origin-width=&quot;1496&quot; data-origin-height=&quot;1380&quot; data-is-animation=&quot;false&quot; style=&quot;width: 52.4993%;&quot; data-widthpercent=&quot;53.12&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/clAcNg/btrUDiLPm4e/Lw85A3th1vNgr3PKcsK8x1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FclAcNg%2FbtrUDiLPm4e%2FLw85A3th1vNgr3PKcsK8x1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1496&quot; height=&quot;1380&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;되돌아 보면 다양한 활동도 많이하고 재밌었던 일들도 많았던 것 같다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다노(DANO)는 정말 동료가 복지라는 말이 과언이 아닐 정도로 좋은 동료들이 많았습니다. 개발문화도 정말 좋았고 성장하기 정말 좋은 환&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;경이었어서 더 아쉬움이 큰 것 같습니다. (최소 2년은 있을 줄 알았는데... 1년 만에 ㅠㅠ) 살면서 내가 이런 일을 겪을지 몰랐는데... 사람일은 정말 어떻게 될지 모르는 것 같습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다노에서 함께했던 모든 동료들의 앞날을 응원하고 저와 비슷한 상황에 놓였던 분들도 응원하겠습니다! 그리고 저에게 좋은 동료들을 만나게 해 준 다노의 내일도 함께 응원합니다! &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;6. 재도전, 합격! 커리어 세 번째 이직 성공!&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3743&quot; data-origin-height=&quot;3024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cNy2Gz/btrUvXblRaf/6tzVjWex0LefNKMdPlHftk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cNy2Gz/btrUvXblRaf/6tzVjWex0LefNKMdPlHftk/img.jpg&quot; data-alt=&quot;출근 첫날 찍었다ㅋㅋㅋ 링크드인 프사로 이용중&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cNy2Gz/btrUvXblRaf/6tzVjWex0LefNKMdPlHftk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcNy2Gz%2FbtrUvXblRaf%2F6tzVjWex0LefNKMdPlHftk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;421&quot; height=&quot;340&quot; data-origin-width=&quot;3743&quot; data-origin-height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출근 첫날 찍었다ㅋㅋㅋ 링크드인 프사로 이용중&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다노에서 예상치 못한 퇴사를 정하고 다음 거처를 정해야 했습니다. 근데 한편으로는 다노에서 1년 동안 많이 성장했기 때문에 어디든 갈 곳은 있겠지라는 자신감은 있던 것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 예전에는 면접이 너무 무섭기만 했지만 지금은 저를 테스트해볼 수 있는 수단, 다른 회사의 개발자들을 만날 수 있는 기회(?) 같이 생각이 돼서 면접과 이직을 하는 과정이 설레고 재밌기도 했습니다. (물론 떨리기도 합니다 ㅋㅋㅋㅋㅋ)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론적으로 현재 &lt;b&gt;'화해'&lt;/b&gt;라는 서비스를 하고 있는 &lt;b&gt;'버드뷰'&lt;/b&gt;에 최종 합격하여 입사하게 되었습니다. 사실 버드뷰는 예전에 첫 이직준비 할 때 떨어졌었는데 이번에 재도전을 해서 합격하게 되었습니다. 지금 와서 보면 그때는 떨어질만했던 것 같습니다 ㅋㅋㅋㅋ 처음 지원했을 때 면접의 기억도 좋았고 버드뷰 기술블로그를 통해 접하는 개발문화를 보면서 꼭 이 회사에서 일해보고 싶다는 생각이 항상 있던 것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;회사 자랑 좀 하자면 복지도 좋고 개발문화도 좋고 사람들도 다 좋습니다! 정말 다들 성장에 대한 욕구와 서비스를 잘 만들고자 하는 마음이 커서 옆에 있는 동료들에게 동기부여도 많이 받고 또 동기부여를 줄 수 있는 환경입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 저희 회사가 완벽한 회사는 아니지만(완벽한 회사가 있나요?ㅋㅋ) 적어도&lt;b&gt; 앞으로 계속 나아가고 지속적으로 성장하려는 회사&lt;/b&gt;라고 자신 있게 말할 수 있습니다! &lt;b&gt;주도적으로 일하시는 분들에게는 좋은 환경&lt;/b&gt;이라고 자부합니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수습 3개월이 곧 끝나가는데, 개인적인 목표 및 바람으로는 동료들이 신뢰할 수 있는 개발자가 되고 싶네요. 그리고 동료들과 함께 열심히 성과를 내서 2023년에 버드뷰가 더 날개를 활짝 펴고 날아갈 수 있게 힘이 되고 싶네요!  &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;7. 나는 어떤 개발자가 되고 싶은가?!&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;224&quot; data-origin-height=&quot;224&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xJiGF/btrUun9hjAm/m0OgkJbk7q531L3xfo5rkK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xJiGF/btrUun9hjAm/m0OgkJbk7q531L3xfo5rkK/img.jpg&quot; data-alt=&quot;오늘 점심 고민만 하다가... 더 어려운 질문이...&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xJiGF/btrUun9hjAm/m0OgkJbk7q531L3xfo5rkK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxJiGF%2FbtrUun9hjAm%2Fm0OgkJbk7q531L3xfo5rkK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;278&quot; height=&quot;278&quot; data-origin-width=&quot;224&quot; data-origin-height=&quot;224&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;오늘 점심 고민만 하다가... 더 어려운 질문이...&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;회사 복지중 MSA 관련된 강의가 있는데 강의를 해주시는 동료께서 최근에 수강생들에게 &lt;b&gt;&quot;어떤 개발자가 되고싶냐?&quot;&lt;/b&gt;라는 질문을 했던 적이 있습니다. 이 질문은 지금까지 누군가에게 들어봤던 적은 몇 안 되는 것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 내년이면 5년 차 개발자입니다. 매년이 커리어에 중요한 시기지만 특히나 저희 회사에서는 5년 차부터는 미들급이기 때문에 더 중요한 시기로 와닿는 것 같습니다. 저 스스로도 이제는 주니어딱지(?)를 떼고 중니어로서 역할을 잘 해내야 하지 않나 생각도 했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 더 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;&quot;나는 어떤 개발자가 되고싶지?&quot;&lt;/b&gt;&lt;/span&gt;라는 질문에 대해서 더 깊게 고민해 봤습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;480&quot; data-origin-height=&quot;270&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cqQjxw/btrUAcLU7vc/w2CK2R6a2fDRH6j8k7Kdd1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cqQjxw/btrUAcLU7vc/w2CK2R6a2fDRH6j8k7Kdd1/img.jpg&quot; data-alt=&quot;함께라면...뭐든 할 수 있어!&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cqQjxw/btrUAcLU7vc/w2CK2R6a2fDRH6j8k7Kdd1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcqQjxw%2FbtrUAcLU7vc%2Fw2CK2R6a2fDRH6j8k7Kdd1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;480&quot; height=&quot;270&quot; data-origin-width=&quot;480&quot; data-origin-height=&quot;270&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;함께라면...뭐든 할 수 있어!&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 번 고민해본 결과 저는 &lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;&quot;동기부여를 줄 수 있는 개발자&quot;&lt;/b&gt;&lt;/span&gt;로 결론을 냈습니다. 예전에는 업계 최고의 개발자... 뭐 이런 목표를 가지고 있었던 기억이 있네요ㅋㅋ 그럼에도 불구하고 &quot;&lt;b&gt;동기부여를 줄 수 있는 개발자&quot;&lt;/b&gt;로 정한 이유는 나 혼자 잘되는 것보다는 누군가 포기하고 싶거나 도움이 필요할 때 손을 내밀수 있고 저를 통해서 한 단계 나아갈 수 있다면 그것만으로도 되게 의미 있고 보람이 있을 것 같다고 느꼈습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 생각을 가지게 된 이유는 제가 1년 차 때부터 그런 시기를 겪었고 그 과정 속에서 많은 분들에게 도움을 받으며 성장했기 때문입니다. 함께 일하던 동료와 지인들의 위로와 칭찬, 동기부여를 통해서 지금의 제가 있다고 생각합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;단순히 개발실력뿐만 아니라 멘털, 마인드 적으로도 도움이 될 수 있는 그런 개발자가 되고 싶습니다.&lt;/b&gt; (사실 실력 좋으신 분들은 너무 많아서 ㅋㅋㅋ 저는 이제 노빠꾸 정신력 뭐 이런 거... 혹은 아재개그(?)ㅋㅋ) 내년에는 멘토 혹은 어떤 방법이든 도움을 줄 수 있는 프로그램이나 글들을 남길 수 있는 활동들을 많이 하고 싶네요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;8. 회고를 마치며&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;740&quot; data-origin-height=&quot;468&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eMZInj/btrUuZULbr9/xAwN7kZtjjMoGxBhmCf0D1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eMZInj/btrUuZULbr9/xAwN7kZtjjMoGxBhmCf0D1/img.jpg&quot; data-alt=&quot;흐름을 탄다는걸 나름 고민해서 표현해본 짤&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eMZInj/btrUuZULbr9/xAwN7kZtjjMoGxBhmCf0D1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeMZInj%2FbtrUuZULbr9%2FxAwN7kZtjjMoGxBhmCf0D1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;487&quot; height=&quot;308&quot; data-origin-width=&quot;740&quot; data-origin-height=&quot;468&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;흐름을 탄다는걸 나름 고민해서 표현해본 짤&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2022년 한 해도 나름 재밌게 보낸 것 같습니다. 개발자로서 뿐만 아니라 좀 더 인간적으로 성숙해진 것 같기도 해요.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;30년 조금 넘게 살아오면서 느낀 건 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;인생은 예상치 못한 이벤트들을 통해서 흘러가는 것 같습니다.&lt;/b&gt;&lt;/span&gt; 그게 좋던 나쁘던 우리는 그 흐름을 타야 할 때가 있습니다. 그 흐름 속에서 중요한 건 내가 어떻게 방향을 잡느냐 인 것 같아요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떤 목표를 가지고 방향성을 잡느냐에 따라서 더 좋은 쪽으로 흘러갈 수도 있고 나쁜 쪽으로 흘러갈 수 도 있습니다. 뻔한 말이지만 여러분들도 여러분의 인생에서 목표와 방향성을 잘 잡고 나아가셨으면 좋겠습니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 23년도에도 모두 한층 더 성장하는 한 해가 되길 바라며...아디오스~ &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;240&quot; data-origin-height=&quot;178&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c57jXn/btrUuljbYP3/TnZyWSEAB2NIDfqRCcEldk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c57jXn/btrUuljbYP3/TnZyWSEAB2NIDfqRCcEldk/img.jpg&quot; data-alt=&quot;2022년 아디오스~&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c57jXn/btrUuljbYP3/TnZyWSEAB2NIDfqRCcEldk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc57jXn%2FbtrUuljbYP3%2FTnZyWSEAB2NIDfqRCcEldk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;240&quot; height=&quot;178&quot; data-origin-width=&quot;240&quot; data-origin-height=&quot;178&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;2022년 아디오스~&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;</description>
      <category> &amp;zwj;  개발자 제이의 이야기</category>
      <category>2022년 회고</category>
      <category>개발자 회고</category>
      <category>회고</category>
      <author>피트웨어 제이 (FitwareJay)</author>
      <guid isPermaLink="true">https://jay-ji.tistory.com/117</guid>
      <comments>https://jay-ji.tistory.com/117#entry117comment</comments>
      <pubDate>Mon, 26 Dec 2022 07:17:24 +0900</pubDate>
    </item>
    <item>
      <title>홈서버(?)에서 서빙하던 서비스 클라우드 이전 썰 (feat. OPGC, AWS Lightsail)</title>
      <link>https://jay-ji.tistory.com/116</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1452&quot; data-origin-height=&quot;1220&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SkQmE/btrNJBErTPg/BN4wBj74taNGmN3KGkEZT0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SkQmE/btrNJBErTPg/BN4wBj74taNGmN3KGkEZT0/img.png&quot; data-alt=&quot;재밌어 보이죠?!!ㅋㅋㅋ&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SkQmE/btrNJBErTPg/BN4wBj74taNGmN3KGkEZT0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSkQmE%2FbtrNJBErTPg%2FBN4wBj74taNGmN3KGkEZT0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;394&quot; height=&quot;1220&quot; data-origin-width=&quot;1452&quot; data-origin-height=&quot;1220&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;재밌어 보이죠?!!ㅋㅋㅋ&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;안녕하세요! 개발자 Jay입니다! 오늘은 약간 재미난 썰(이라고 쓰고 날벼락 맞은 썰 이라고 읽는다...)을 가지고 왔습니다ㅎㅎ&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;2년 전쯤 &lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://jay-ji.tistory.com/52&quot;&gt;[Server] 안쓰는 노트북으로 개인서버(Ubuntu) 만들기  &lt;/a&gt;&lt;/span&gt;&lt;/b&gt; 라는 글을 쓴 적이 있었습니다. 집에서 버리려다가 만 노트북을 ubuntu server로 만들어서 사용을 했습니다. 덕분에 이 서버에서 토이 프로젝트도 서빙하고 여러 가지 실험도 할 수 있었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;엊그제 까지만 해도(?) &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://opgc.me/#/main&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;OPGC&lt;/a&gt;&lt;/b&gt;&lt;/span&gt;라는 서비스를 서빙하고 있었죠 ㅋㅋ&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;2022년&amp;nbsp; 9월 31일 오후 1시 사건의 발단&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;230&quot; data-origin-height=&quot;219&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EmgKX/btrNyFBOjhb/6GkBRnOYSzr5rtH947Ofd0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EmgKX/btrNyFBOjhb/6GkBRnOYSzr5rtH947Ofd0/img.jpg&quot; data-alt=&quot;백수의 하루&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EmgKX/btrNyFBOjhb/6GkBRnOYSzr5rtH947Ofd0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEmgKX%2FbtrNyFBOjhb%2F6GkBRnOYSzr5rtH947Ofd0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;290&quot; height=&quot;276&quot; data-origin-width=&quot;230&quot; data-origin-height=&quot;219&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;백수의 하루&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;사건은... 평화로운 백수생활을 즐기면서 꿀잠자고 있던 2022년 9월 30일 오후 1시에 일어났습니다... 갑자기 탕! 하는 큰소리와 함께 건물 외벽이 울리는 겁니다...&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;순간 무슨 사고라도 밖에 터졌나 했는데 너무 조용하고...&quot;뭐지?&quot; 하다가 벽을 보니까 뭔가 끊어진 선이 하나... 보이더라고요. 3초간 머엉~ 하고 생각하다가 랜선인가? 하고 생각했는데 ㅋㅋㅋㅋ 서버가 죽었다고 슬랙 알림이 오기 시작했습니다ㅋㅋㅋㅋㅋ&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1440&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/B9mpS/btrNwDYLb4n/MDs95oG5m9m9lh5HK8Plb1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/B9mpS/btrNwDYLb4n/MDs95oG5m9m9lh5HK8Plb1/img.jpg&quot; data-alt=&quot;ㅋㅋㅋ 가운데 길게 떨어진게 우리집 랜선&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/B9mpS/btrNwDYLb4n/MDs95oG5m9m9lh5HK8Plb1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FB9mpS%2FbtrNwDYLb4n%2FMDs95oG5m9m9lh5HK8Plb1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;365&quot; height=&quot;487&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1440&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ㅋㅋㅋ 가운데 길게 떨어진게 우리집 랜선&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;어이가 없어서 황급히 밖에 나가보니 랜선 하나가 끊어져 있는게 보이더라고요 ㅋㅋㅋㅋㅋ 아니 살다 살다 ㅋㅋㅋ 탑차 같은게 지나가다가 저희 집 랜선을 걸고 가서 끊어진 걸로 추측이 됩니다ㅠㅠ&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1078&quot; data-origin-height=&quot;1081&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/biAsh4/btrNAxwxbLq/hs8HizdUt583iaqJA8G5k1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/biAsh4/btrNAxwxbLq/hs8HizdUt583iaqJA8G5k1/img.png&quot; data-alt=&quot;요렇게 든든하게 사용하던 홈서버인데....랜선 끊어지니 무용지물&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/biAsh4/btrNAxwxbLq/hs8HizdUt583iaqJA8G5k1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbiAsh4%2FbtrNAxwxbLq%2Fhs8HizdUt583iaqJA8G5k1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;417&quot; height=&quot;418&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1078&quot; data-origin-height=&quot;1081&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;요렇게 든든하게 사용하던 홈서버인데....랜선 끊어지니 무용지물&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2604&quot; data-origin-height=&quot;2316&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bfoeNc/btrNAMUC6uQ/mlqUVdHzkgcXuadd6tOVy0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bfoeNc/btrNAMUC6uQ/mlqUVdHzkgcXuadd6tOVy0/img.png&quot; data-alt=&quot;readme에 위 빨간박스 안에 뱃지로 제공해주는 OPGC&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bfoeNc/btrNAMUC6uQ/mlqUVdHzkgcXuadd6tOVy0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbfoeNc%2FbtrNAMUC6uQ%2FmlqUVdHzkgcXuadd6tOVy0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;621&quot; height=&quot;552&quot; data-origin-width=&quot;2604&quot; data-origin-height=&quot;2316&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;readme에 위 빨간박스 안에 뱃지로 제공해주는 OPGC&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;뭐 당장 인터넷이 안되는건 상관없는데 유저들이 사용하고 있는 &lt;b&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://opgc.me/#/main&quot;&gt;OPGC&lt;/a&gt;&lt;/b&gt;에 장애가 생기는게 걱정이었습니다. OPGC에서는 개발자 랭킹을 github 뱃지(?)로 제공하고 있어서 서비스 장애가 나면 깃헙 readme에 엑박(엑스박스)떠서 보기 좋지 않기 때문입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1544&quot; data-origin-height=&quot;760&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dxUitp/btrNIKBuSKn/VK0Etn10dZQ4YoWMUPVQm0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dxUitp/btrNIKBuSKn/VK0Etn10dZQ4YoWMUPVQm0/img.png&quot; data-alt=&quot;너무 황당해서 생코에 바로 글을 올렸습니다 ㅋㅋㅋ&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dxUitp/btrNIKBuSKn/VK0Etn10dZQ4YoWMUPVQm0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdxUitp%2FbtrNIKBuSKn%2FVK0Etn10dZQ4YoWMUPVQm0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;555&quot; height=&quot;273&quot; data-origin-width=&quot;1544&quot; data-origin-height=&quot;760&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;너무 황당해서 생코에 바로 글을 올렸습니다 ㅋㅋㅋ&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;유저가 많지는 않지만 실제로 유저들이 사용하는 서비스이기 때문에 빨리 복구를 해야겠다는 생각뿐이었습니다. 안그래도 맨날 이사 가거나 집 구조 바꿀 때마다 인터넷이 끊기면 서비스 장애가 돼서 클라우드로 이전을 해야겠다고 생각했는데 ㅋㅋㅋㅋ 강제로 그 시기가 찾아왔습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;클라우드로의 이전&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;이전 직장에서 동료들이 &lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://lightsail.aws.amazon.com/ls/webapp/home/instances&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;AWS Lightsail&lt;/a&gt;&lt;/span&gt;&lt;/b&gt;로 토이프로젝트를 서빙하고 있고 값이 싸다고 알려준 적이 있어서 바로 AWS로그인해서 Lightsail페이지로 들어갔습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rCB1J/btrNGxvEwps/81PdGYRRj9jS65cp1KMqbk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rCB1J/btrNGxvEwps/81PdGYRRj9jS65cp1KMqbk/img.png&quot; data-origin-width=&quot;2770&quot; data-origin-height=&quot;2248&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.2168%; margin-right: 10px;&quot; data-widthpercent=&quot;49.8&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rCB1J/btrNGxvEwps/81PdGYRRj9jS65cp1KMqbk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrCB1J%2FbtrNGxvEwps%2F81PdGYRRj9jS65cp1KMqbk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2770&quot; height=&quot;2248&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GFZjk/btrNyECQWjs/SwoguFLcIOEDuDSCwTPFOK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GFZjk/btrNyECQWjs/SwoguFLcIOEDuDSCwTPFOK/img.png&quot; data-origin-width=&quot;2020&quot; data-origin-height=&quot;1626&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.6204%;&quot; data-widthpercent=&quot;50.2&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GFZjk/btrNyECQWjs/SwoguFLcIOEDuDSCwTPFOK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGFZjk%2FbtrNyECQWjs%2FSwoguFLcIOEDuDSCwTPFOK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2020&quot; height=&quot;1626&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;클릭 몇번으로 인스턴스를 생성할 수 있다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;Lightsail은 클릭 몇번으로 원하는 사양과 목적에 맞는 서버를 생성할 수 있습니다. 저는 홈서버와 비슷하게 하나에 서버에 nginx, mysql, redis, django application을 구성할 거라 ubuntu 20.04 LTS로 선택했습니다. 서버 사양은 홈서버와 비슷하게 20달러짜리로 하고 싶었는데 10달러짜리가 3개월 무료라서 10달러짜리를 선택했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;어차피 트래픽이 그렇게 많지도 않고 고사양 스펙을 돌리는것도 아니라서 괜찮을 거라고 생각했습니다. (+ 고정아이피 사용)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;서버를 생성하고 기존 홈서버에서 몇가지 파일들과 DB data를 옮기기 위해 USB를 사용했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;1081&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b1R0d9/btrNFTlidhj/IvXcdeLZEfnkUWX9vaVbXK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b1R0d9/btrNFTlidhj/IvXcdeLZEfnkUWX9vaVbXK/img.jpg&quot; data-alt=&quot;USB 마운트 해서 파일 복사하는 과정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b1R0d9/btrNFTlidhj/IvXcdeLZEfnkUWX9vaVbXK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb1R0d9%2FbtrNFTlidhj%2FIvXcdeLZEfnkUWX9vaVbXK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1440&quot; height=&quot;1081&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;1081&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;USB 마운트 해서 파일 복사하는 과정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;탑차가 저희집 랜선을 끊고 간 덕분에 usb 마운트 해서 파일 옮기는 법도 알게 되었네요 ㅎㅎ 일단 파일들을 옮기고 기존 홈서버와 동일하게 환경 세팅을 했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;nginx, mysql, redis를 설치하고 원래 사용하던 fabfile을 통해 init 배포를 시작했습니다. fabfile은 fabric이라는 파이썬 라이브러리로 간단하게 배포를 할 수 있는 파일을 말합니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://jay-ji.tistory.com/38?category=828550&quot;&gt;https://jay-ji.tistory.com/38?category=828550&lt;/a&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1664794300098&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;local 개발환경 세팅부터 배포까지 - 3부(Fabric)&quot; data-og-description=&quot;안녕하세요! 운동하는 개발자 Jay입니다. 오늘은 대망의 3부 배포에 대해 알아 보겠습니다. 배포를 위해 Fabric 이라는 python 라이브러리를 사용하겠습니다. GitHub에서 프로젝트를 clone 받아서 실행(r&quot; data-og-host=&quot;jay-ji.tistory.com&quot; data-og-source-url=&quot;https://jay-ji.tistory.com/38?category=828550&quot; data-og-url=&quot;https://jay-ji.tistory.com/38&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bpdEew/hyPZaFxvho/BWFjVcsYIcEj8luSGfZ9nK/img.png?width=171&amp;amp;height=171&amp;amp;face=0_0_171_171,https://scrap.kakaocdn.net/dn/cn00Ku/hyP0KkVUhC/LSe8XLT59lnWKSdKmlllp1/img.png?width=171&amp;amp;height=171&amp;amp;face=0_0_171_171,https://scrap.kakaocdn.net/dn/C2ueK/hyPY0powS2/6XoKPksg6R9SnhxpWayy30/img.png?width=1900&amp;amp;height=1330&amp;amp;face=0_0_1900_1330&quot;&gt;&lt;a href=&quot;https://jay-ji.tistory.com/38?category=828550&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jay-ji.tistory.com/38?category=828550&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bpdEew/hyPZaFxvho/BWFjVcsYIcEj8luSGfZ9nK/img.png?width=171&amp;amp;height=171&amp;amp;face=0_0_171_171,https://scrap.kakaocdn.net/dn/cn00Ku/hyP0KkVUhC/LSe8XLT59lnWKSdKmlllp1/img.png?width=171&amp;amp;height=171&amp;amp;face=0_0_171_171,https://scrap.kakaocdn.net/dn/C2ueK/hyPY0powS2/6XoKPksg6R9SnhxpWayy30/img.png?width=1900&amp;amp;height=1330&amp;amp;face=0_0_1900_1330');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;local 개발환경 세팅부터 배포까지 - 3부(Fabric)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;안녕하세요! 운동하는 개발자 Jay입니다. 오늘은 대망의 3부 배포에 대해 알아 보겠습니다. 배포를 위해 Fabric 이라는 python 라이브러리를 사용하겠습니다. GitHub에서 프로젝트를 clone 받아서 실행(r&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;jay-ji.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;사실 기존 홈서버와 다른점이 클라우드라는 점만 빼면 동일했기 때문에 특별히 이슈는 없었고 OPGC의 클라우드 이전은 무사히 마칠 수 있었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;클라우드 서비스 이전 과정 요약&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;ubuntu 서버 생성&lt;/li&gt;
&lt;li&gt;nginx, mysql, redis 설치&lt;/li&gt;
&lt;li&gt;djagno application 배포 및 gunicorn 실행, nginx &amp;lt;-&amp;gt; gunicorn 연결&lt;/li&gt;
&lt;li&gt;프론트(react) build 및 nginx에 index경로 연결&lt;/li&gt;
&lt;li&gt;도메인 서비스(GoDaddy) 가서 A레코드 IP 주소 변경&lt;/li&gt;
&lt;li&gt;SSL 인증서 설치&lt;/li&gt;
&lt;li&gt;서비스 동작 확인&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;마치며&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;770&quot; data-origin-height=&quot;426&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pLuBX/btrNAL9jLix/XKXKod9PEBlu9H7Ij7pQKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pLuBX/btrNAL9jLix/XKXKod9PEBlu9H7Ij7pQKK/img.png&quot; data-alt=&quot;긍정회로 돌리&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pLuBX/btrNAL9jLix/XKXKod9PEBlu9H7Ij7pQKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpLuBX%2FbtrNAL9jLix%2FXKXKod9PEBlu9H7Ij7pQKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;414&quot; height=&quot;229&quot; data-origin-width=&quot;770&quot; data-origin-height=&quot;426&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;긍정회로 돌리&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;세상 황당한 일을 겪었지만 덕분에 많은걸 얻은 것 같습니다 (긍정 회로 돌리기)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;클라우드로 서비스 이전 (이제 이사가거나 두꺼비집 내려가서 서비스 장애 나는 불상사 없어짐)&lt;/li&gt;
&lt;li&gt;ubuntu usb 마운트 하는법 습득&lt;/li&gt;
&lt;li&gt;블로그 컨텐츠 획득&lt;/li&gt;
&lt;li&gt;서버 배포과정 한 번 더 복습&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러분들도 토이프로젝트 하신다면 AWS Lightsail 한 번 이용해보시길 바랍니다. 값이 싸서 이것저것 해보기 좋은 것 같아요! 인터넷이 복구되면 기존에 사용하던 서버는 좀 자유롭게 이상한짓(?)을 해보는 테스트 서버로 사용해야겠네요 ㅋㅋ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 오늘도 즐거운 코딩 하시길 바래요!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;참고자료&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://mapled.tistory.com/entry/%EC%9A%B0%EB%B6%84%ED%88%AC%EC%97%90%EC%84%9C-USB-%EB%A7%88%EC%9A%B4%ED%8A%B8-%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Ubuntu usb mount/unmount&lt;/a&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1664795256827&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[Ubuntu] USB 마운트(mount)/언마운트(unmount) 하는 방법&quot; data-og-description=&quot;안녕하세요. 메이플입니다. 최근에 라즈베리파이에 우분투 OS를 설치해서 작업 중인데, USB를 사용하는 방법을 잘 모르겠더라고요. 그래서 열심히 검색해봤는데.. 제가 원하는 딱! 정리된 정보가 &quot; data-og-host=&quot;mapled.tistory.com&quot; data-og-source-url=&quot;https://mapled.tistory.com/entry/%EC%9A%B0%EB%B6%84%ED%88%AC%EC%97%90%EC%84%9C-USB-%EB%A7%88%EC%9A%B4%ED%8A%B8-%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95&quot; data-og-url=&quot;https://mapled.tistory.com/entry/%EC%9A%B0%EB%B6%84%ED%88%AC%EC%97%90%EC%84%9C-USB-%EB%A7%88%EC%9A%B4%ED%8A%B8-%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dCkM8a/hyPY19GYuT/FyHn5JFkd9mv3zzyineH3K/img.png?width=445&amp;amp;height=247&amp;amp;face=0_0_445_247,https://scrap.kakaocdn.net/dn/VXB0v/hyP0yx3n3n/WCy2ymWPK7MYYVRPdCwvhK/img.png?width=445&amp;amp;height=247&amp;amp;face=0_0_445_247,https://scrap.kakaocdn.net/dn/fBbTP/hyP0zX1RiZ/0KwcV00xrG3eik6uq26NeK/img.png?width=601&amp;amp;height=754&amp;amp;face=0_0_601_754&quot;&gt;&lt;a href=&quot;https://mapled.tistory.com/entry/%EC%9A%B0%EB%B6%84%ED%88%AC%EC%97%90%EC%84%9C-USB-%EB%A7%88%EC%9A%B4%ED%8A%B8-%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://mapled.tistory.com/entry/%EC%9A%B0%EB%B6%84%ED%88%AC%EC%97%90%EC%84%9C-USB-%EB%A7%88%EC%9A%B4%ED%8A%B8-%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dCkM8a/hyPY19GYuT/FyHn5JFkd9mv3zzyineH3K/img.png?width=445&amp;amp;height=247&amp;amp;face=0_0_445_247,https://scrap.kakaocdn.net/dn/VXB0v/hyP0yx3n3n/WCy2ymWPK7MYYVRPdCwvhK/img.png?width=445&amp;amp;height=247&amp;amp;face=0_0_445_247,https://scrap.kakaocdn.net/dn/fBbTP/hyP0zX1RiZ/0KwcV00xrG3eik6uq26NeK/img.png?width=601&amp;amp;height=754&amp;amp;face=0_0_601_754');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[Ubuntu] USB 마운트(mount)/언마운트(unmount) 하는 방법&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;안녕하세요. 메이플입니다. 최근에 라즈베리파이에 우분투 OS를 설치해서 작업 중인데, USB를 사용하는 방법을 잘 모르겠더라고요. 그래서 열심히 검색해봤는데.. 제가 원하는 딱! 정리된 정보가&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;mapled.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://mingg123.tistory.com/88&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://mingg123.tistory.com/88&lt;/a&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1664795674252&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[Ubuntu] MySql 재설치, 제거부터 설치까지&quot; data-og-description=&quot;mySql을 로컬에 깔아야 할 일이 생겼다. 몇 번이나 삭제, 수정을 하면서 그냥 포스팅 하려고한다. 재설치 mysql관련된 라이브러리 까지 모두 깔끔하게 삭제한다. sudo apt-get remove --purge mysql* 혹여나 &quot; data-og-host=&quot;mingg123.tistory.com&quot; data-og-source-url=&quot;https://mingg123.tistory.com/88&quot; data-og-url=&quot;https://mingg123.tistory.com/88&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/d4PS61/hyPYWghzXP/akxDh94nBi3FejkSOPZZj1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/iiskk/hyPY729Wdw/21qqEl9rOsB6QmjGr8sTwk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/nYZvH/hyP0xMGniz/IzhBLEUkaUPLnDMgXI6960/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400&quot;&gt;&lt;a href=&quot;https://mingg123.tistory.com/88&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://mingg123.tistory.com/88&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/d4PS61/hyPYWghzXP/akxDh94nBi3FejkSOPZZj1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/iiskk/hyPY729Wdw/21qqEl9rOsB6QmjGr8sTwk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/nYZvH/hyP0xMGniz/IzhBLEUkaUPLnDMgXI6960/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[Ubuntu] MySql 재설치, 제거부터 설치까지&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;mySql을 로컬에 깔아야 할 일이 생겼다. 몇 번이나 삭제, 수정을 하면서 그냥 포스팅 하려고한다. 재설치 mysql관련된 라이브러리 까지 모두 깔끔하게 삭제한다. sudo apt-get remove --purge mysql* 혹여나&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;mingg123.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://wikidocs.net/6601&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://wikidocs.net/6601&lt;/a&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1664795686271&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;03) Nginx, Gunicorn 배포&quot; data-og-description=&quot;[TOC] # 시스템 구성 예시 * 우분투 16.04 * Django * nginx * Gunicorn 다음 설치 예제는 실제 물리서버가 아닌 vultr.com의 가상 ...&quot; data-og-host=&quot;wikidocs.net&quot; data-og-source-url=&quot;https://wikidocs.net/6601&quot; data-og-url=&quot;https://wikidocs.net/6601&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b0AszV/hyPYWm0TR1/Sx60ReJvqT9ZkQrKUXO6qk/img.png?width=100&amp;amp;height=45&amp;amp;face=0_0_100_45&quot;&gt;&lt;a href=&quot;https://wikidocs.net/6601&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://wikidocs.net/6601&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b0AszV/hyPYWm0TR1/Sx60ReJvqT9ZkQrKUXO6qk/img.png?width=100&amp;amp;height=45&amp;amp;face=0_0_100_45');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;03) Nginx, Gunicorn 배포&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;[TOC] # 시스템 구성 예시 * 우분투 16.04 * Django * nginx * Gunicorn 다음 설치 예제는 실제 물리서버가 아닌 vultr.com의 가상 ...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;wikidocs.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://itexpert.tips/ko/nginx-ko/%EC%9A%B0%EB%B6%84%ED%88%AC-%EB%A6%AC%EB%88%85%EC%8A%A4%EC%97%90-nginx-%EB%AC%B4%EB%A3%8C-https-%EC%9D%B8%EC%A6%9D%EC%84%9C-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;우분투 nignx 무료 ssl 인증서 설치하기&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1664795727717&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;우분투 리눅스에 Nginx 무료 HTTPS 인증서 설치하기&quot; data-og-description=&quot;이 튜토리얼은 우분투 리눅스에서 무료 SSL을 암호화하여 Nginx 무료 HTTPS 인증서를 설치하는 데 필요한 모든 단계를 보여줍니다.&quot; data-og-host=&quot;itexpert.tips&quot; data-og-source-url=&quot;https://itexpert.tips/ko/nginx-ko/%EC%9A%B0%EB%B6%84%ED%88%AC-%EB%A6%AC%EB%88%85%EC%8A%A4%EC%97%90-nginx-%EB%AC%B4%EB%A3%8C-https-%EC%9D%B8%EC%A6%9D%EC%84%9C-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0/&quot; data-og-url=&quot;https://itexpert.tips/ko/nginx-ko/우분투-리눅스에-nginx-무료-https-인증서-설치하기/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b19ULl/hyPZbdqH3L/Gjhnab04PE77VcKlaoIiGk/img.jpg?width=700&amp;amp;height=550&amp;amp;face=0_0_700_550,https://scrap.kakaocdn.net/dn/c1nVz7/hyP0CHdPqN/tJvzAJ57uQlEYaHRhbHji1/img.jpg?width=945&amp;amp;height=805&amp;amp;face=0_0_945_805,https://scrap.kakaocdn.net/dn/cIWMdY/hyPY2HwnhK/dDk2btkaeNQRlVFkiWZsbk/img.jpg?width=802&amp;amp;height=334&amp;amp;face=0_0_802_334&quot;&gt;&lt;a href=&quot;https://itexpert.tips/ko/nginx-ko/%EC%9A%B0%EB%B6%84%ED%88%AC-%EB%A6%AC%EB%88%85%EC%8A%A4%EC%97%90-nginx-%EB%AC%B4%EB%A3%8C-https-%EC%9D%B8%EC%A6%9D%EC%84%9C-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://itexpert.tips/ko/nginx-ko/%EC%9A%B0%EB%B6%84%ED%88%AC-%EB%A6%AC%EB%88%85%EC%8A%A4%EC%97%90-nginx-%EB%AC%B4%EB%A3%8C-https-%EC%9D%B8%EC%A6%9D%EC%84%9C-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b19ULl/hyPZbdqH3L/Gjhnab04PE77VcKlaoIiGk/img.jpg?width=700&amp;amp;height=550&amp;amp;face=0_0_700_550,https://scrap.kakaocdn.net/dn/c1nVz7/hyP0CHdPqN/tJvzAJ57uQlEYaHRhbHji1/img.jpg?width=945&amp;amp;height=805&amp;amp;face=0_0_945_805,https://scrap.kakaocdn.net/dn/cIWMdY/hyPY2HwnhK/dDk2btkaeNQRlVFkiWZsbk/img.jpg?width=802&amp;amp;height=334&amp;amp;face=0_0_802_334');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;우분투 리눅스에 Nginx 무료 HTTPS 인증서 설치하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;이 튜토리얼은 우분투 리눅스에서 무료 SSL을 암호화하여 Nginx 무료 HTTPS 인증서를 설치하는 데 필요한 모든 단계를 보여줍니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;itexpert.tips&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://joonyon.tistory.com/entry/EC2%EC%97%90%EC%84%9C-EC2%EB%A1%9C-ssh-public-key-%EB%B0%B0%ED%8F%AC%ED%95%98%EA%B8%B0PEM-File-%EC%9D%B4%EC%9A%A9&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://joonyon.tistory.com/entry/EC2%EC%97%90%EC%84%9C-EC2%EB%A1%9C-ssh-public-key-%EB%B0%B0%ED%8F%AC%ED%95%98%EA%B8%B0PEM-File-%EC%9D%B4%EC%9A%A9&lt;/a&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1664796272918&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;EC2에서 EC2로 ssh public key 배포하기(PEM File 이용)&quot; data-og-description=&quot;AWS EC2에 접근하기 위해서는 PEM File을 이용하게 되는데, 이 때문에 EC2 끼리 패스워드 없이 접속하기 위해서 ssh-keygen 후 public key를 배포하는데 ssh-copy-id 를 이용 할 수가 없다. 이러한 문제를 해결&quot; data-og-host=&quot;joonyon.tistory.com&quot; data-og-source-url=&quot;https://joonyon.tistory.com/entry/EC2%EC%97%90%EC%84%9C-EC2%EB%A1%9C-ssh-public-key-%EB%B0%B0%ED%8F%AC%ED%95%98%EA%B8%B0PEM-File-%EC%9D%B4%EC%9A%A9&quot; data-og-url=&quot;https://joonyon.tistory.com/entry/EC2%EC%97%90%EC%84%9C-EC2%EB%A1%9C-ssh-public-key-%EB%B0%B0%ED%8F%AC%ED%95%98%EA%B8%B0PEM-File-%EC%9D%B4%EC%9A%A9&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/81o0e/hyP0xlChYH/OcMExMdDDuIXk7h70diaNk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/pFkac/hyP0GbNlt6/xEeHXHrnI3lWsrakQZQfsK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://joonyon.tistory.com/entry/EC2%EC%97%90%EC%84%9C-EC2%EB%A1%9C-ssh-public-key-%EB%B0%B0%ED%8F%AC%ED%95%98%EA%B8%B0PEM-File-%EC%9D%B4%EC%9A%A9&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://joonyon.tistory.com/entry/EC2%EC%97%90%EC%84%9C-EC2%EB%A1%9C-ssh-public-key-%EB%B0%B0%ED%8F%AC%ED%95%98%EA%B8%B0PEM-File-%EC%9D%B4%EC%9A%A9&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/81o0e/hyP0xlChYH/OcMExMdDDuIXk7h70diaNk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/pFkac/hyP0GbNlt6/xEeHXHrnI3lWsrakQZQfsK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;EC2에서 EC2로 ssh public key 배포하기(PEM File 이용)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;AWS EC2에 접근하기 위해서는 PEM File을 이용하게 되는데, 이 때문에 EC2 끼리 패스워드 없이 접속하기 위해서 ssh-keygen 후 public key를 배포하는데 ssh-copy-id 를 이용 할 수가 없다. 이러한 문제를 해결&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;joonyon.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://chamshna.tistory.com/3&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://chamshna.tistory.com/3&lt;/a&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1664796309916&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;PEM 키를 이용한 SSH 원격 접속&quot; data-og-description=&quot;[목표] 터미널 창에서 pem 키를 이용하여 ssh 원격접속 1. 키페어 파일에 권한부여 (Linux의 경우) - OS마다 차이가 있지만 대표적인 예로 MacOS는 파일 권한이 400(파일 소유권자만 읽기 가능)이 아닌 경&quot; data-og-host=&quot;chamshna.tistory.com&quot; data-og-source-url=&quot;https://chamshna.tistory.com/3&quot; data-og-url=&quot;https://chamshna.tistory.com/3&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bE8nhg/hyPY1aLq2l/gHRtYUFNoQB0iwbuGaEPck/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/vrqFb/hyPY7hKP8K/OhqLdImILb86zw6ypL2m90/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://chamshna.tistory.com/3&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://chamshna.tistory.com/3&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bE8nhg/hyPY1aLq2l/gHRtYUFNoQB0iwbuGaEPck/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/vrqFb/hyPY7hKP8K/OhqLdImILb86zw6ypL2m90/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;PEM 키를 이용한 SSH 원격 접속&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;[목표] 터미널 창에서 pem 키를 이용하여 ssh 원격접속 1. 키페어 파일에 권한부여 (Linux의 경우) - OS마다 차이가 있지만 대표적인 예로 MacOS는 파일 권한이 400(파일 소유권자만 읽기 가능)이 아닌 경&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;chamshna.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category> &amp;zwj;  개발자 제이의 이야기</category>
      <category>AWS</category>
      <category>ligthsail</category>
      <category>ubuntu</category>
      <category>토이프로젝트</category>
      <author>피트웨어 제이 (FitwareJay)</author>
      <guid isPermaLink="true">https://jay-ji.tistory.com/116</guid>
      <comments>https://jay-ji.tistory.com/116#entry116comment</comments>
      <pubDate>Mon, 3 Oct 2022 20:19:14 +0900</pubDate>
    </item>
    <item>
      <title>[SQLAlchemy] async_scoped_session과 context-local</title>
      <link>https://jay-ji.tistory.com/115</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;안녕하세요! 개발자 Jay입니다! 오늘은 지난번 &lt;b&gt;Session vs scoped_session&lt;/b&gt;에 이어서 &lt;b&gt;async_scoped_session&lt;/b&gt;에 대해서 정리해보려고 합니다!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;async_scoped_session이 나오게 된 배경&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;async_scoped_session은 &lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://docs.sqlalchemy.org/en/14/changelog/changelog_14.html#change-1.4.19-asyncio&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;1.4.19 release&lt;/a&gt;&lt;/span&gt;&lt;/b&gt;에서 추가된 클래스입니다. 그럼 async_scoped_session은 왜 추가되었을까요? 릴리즈 내용을 먼저 확인해 보겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1898&quot; data-origin-height=&quot;558&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/umSiU/btrNu6T9gzk/0qHsXhZJk4gNKKYCZqRVZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/umSiU/btrNu6T9gzk/0qHsXhZJk4gNKKYCZqRVZK/img.png&quot; data-alt=&quot;async_scoped_session 릴리즈 내용&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/umSiU/btrNu6T9gzk/0qHsXhZJk4gNKKYCZqRVZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FumSiU%2FbtrNu6T9gzk%2F0qHsXhZJk4gNKKYCZqRVZK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1898&quot; height=&quot;558&quot; data-origin-width=&quot;1898&quot; data-origin-height=&quot;558&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;async_scoped_session 릴리즈 내용&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;scoped_session과 AsyncSession 사이의 비호환성을 해결하기 위해 async_scoped_session이&lt;/span&gt; 구현&lt;/b&gt;&lt;/span&gt;되었다고 합니다. 그리고 &lt;b&gt;async_scoped_session.remove()&lt;/b&gt;와 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;함께 사용&lt;/b&gt;&lt;/span&gt;되어야 한다고 하네요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;그럼 어떤 비호환성이 있었을까요?&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2332&quot; data-origin-height=&quot;1974&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LmzZq/btrNyG0t9Oc/QZ8KE0ykM5rEdgNqjSgC30/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LmzZq/btrNyG0t9Oc/QZ8KE0ykM5rEdgNqjSgC30/img.png&quot; data-alt=&quot;#6583 이슈&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LmzZq/btrNyG0t9Oc/QZ8KE0ykM5rEdgNqjSgC30/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLmzZq%2FbtrNyG0t9Oc%2FQZ8KE0ykM5rEdgNqjSgC30%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2332&quot; height=&quot;1974&quot; data-origin-width=&quot;2332&quot; data-origin-height=&quot;1974&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;#6583 이슈&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://github.com/sqlalchemy/sqlalchemy/issues/6583&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;#6584&lt;/a&gt;&lt;/b&gt;&lt;/span&gt; 이슈를 보면 &lt;b&gt;scoped_session&lt;/b&gt;과 &lt;b&gt;AsyncSession&lt;/b&gt;을 함께 사용한 코드에서 &lt;b&gt;AsyncSession&lt;/b&gt;의 &lt;b&gt;close&lt;/b&gt;가 호출되지 않는 오류입니다. 에러 메세지로는 이런 에러를 뿜어내고요!&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;groovy&quot;&gt;&lt;code&gt;RuntimeWarning: coroutine 'AsyncSession.close' was never awaited&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;뭐가 문제였을까요? &lt;b&gt;scoped_session의 remove는 async/await를 지원하지 않기 때문&lt;/b&gt;에 이런 문제가 생겼던 것입니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;두 번째로는 위 PR에도 이야기가 나오긴 하는데... scoped_session은 thread-local을 사용합니다. 하나의 스레드에 하나의 세션(Session)을 할당하는 방식이죠.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;293&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bpgmFg/btrNwo0xM92/gwWkAXkKel0H3YA2oj0r7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bpgmFg/btrNwo0xM92/gwWkAXkKel0H3YA2oj0r7k/img.png&quot; data-alt=&quot;출처: https://eng.paxos.com/python-3s-killer-feature-asyncio&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bpgmFg/btrNwo0xM92/gwWkAXkKel0H3YA2oj0r7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbpgmFg%2FbtrNwo0xM92%2FgwWkAXkKel0H3YA2oj0r7k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;559&quot; height=&quot;234&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;293&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처: https://eng.paxos.com/python-3s-killer-feature-asyncio&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;Asyncio 코루틴(coroutine)에서는 하나의 thread로 여러 컨텍스트(context)를 실행합니다. 이때 컨텍스트들은 동일한 세션에 접근하게 됩니다. 그럼 어떤 일이 벌어질까요? &lt;a style=&quot;letter-spacing: 0px;&quot; href=&quot;https://jay-ji.tistory.com/114&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;[SQLAlchemy] Session vs scoped_session&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt; 에서 설명했듯이&amp;nbsp;thread-safe하지 않은... 여기서는 context-safe라고 해야 하나... 아무튼 의도하지 않은 동작과 오류가 날 수 있습니다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;비동기를 지원하려면 context-local을 보장해야 한다&lt;/b&gt;&lt;/span&gt;는 말입니다!&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;async_scoped_sesison은 어떻게 context-local을 보장하는가?&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rykLJ/btrNzJWV4Ld/S3khH6cElmbRDAeQndGWUK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rykLJ/btrNzJWV4Ld/S3khH6cElmbRDAeQndGWUK/img.png&quot; data-origin-width=&quot;1482&quot; data-origin-height=&quot;1394&quot; data-is-animation=&quot;false&quot; style=&quot;width: 47.3147%; margin-right: 10px;&quot; data-widthpercent=&quot;47.87&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rykLJ/btrNzJWV4Ld/S3khH6cElmbRDAeQndGWUK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrykLJ%2FbtrNzJWV4Ld%2FS3khH6cElmbRDAeQndGWUK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1482&quot; height=&quot;1394&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/G48fZ/btrNyE2Fuh3/euxyl0j8xAAhbZ7K77vrUK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/G48fZ/btrNyE2Fuh3/euxyl0j8xAAhbZ7K77vrUK/img.png&quot; data-origin-width=&quot;1116&quot; data-origin-height=&quot;964&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;52.13&quot; style=&quot;width: 51.5226%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/G48fZ/btrNyE2Fuh3/euxyl0j8xAAhbZ7K77vrUK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FG48fZ%2FbtrNyE2Fuh3%2Feuxyl0j8xAAhbZ7K77vrUK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1116&quot; height=&quot;964&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;async_scoped_session이 context-local을 보장하는 코드&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;async_scoped_session&lt;/b&gt;은 &lt;b&gt;asyncio.current_task&lt;/b&gt;와 같은 scopedfunc을 주입받아서&lt;b&gt; self.registry&lt;/b&gt; 딕셔너리에 키값으로 사용합니다. 즉 각각의 context의 current_task를 key값으로 사용하고 Session(AsyncSession)을 vaule로 넣어줍니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;이렇게 되면 context-local을 보장하는 형태가 되는 거지요! ㅎㅎ 그럼 실제로 이렇게 동작하는지 확인해보겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUgH5b/btrNvMniOmZ/XG7yWMPeZn51ClikGGrPfK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUgH5b/btrNvMniOmZ/XG7yWMPeZn51ClikGGrPfK/img.png&quot; data-origin-width=&quot;1838&quot; data-origin-height=&quot;1054&quot; data-is-animation=&quot;false&quot; style=&quot;width: 46.7517%; margin-right: 10px;&quot; data-widthpercent=&quot;47.3&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUgH5b/btrNvMniOmZ/XG7yWMPeZn51ClikGGrPfK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUgH5b%2FbtrNvMniOmZ%2FXG7yWMPeZn51ClikGGrPfK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1838&quot; height=&quot;1054&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dMRIOo/btrNviG5oW2/VFeoP7IldtpId05XC4iiKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dMRIOo/btrNviG5oW2/VFeoP7IldtpId05XC4iiKK/img.png&quot; data-origin-width=&quot;1562&quot; data-origin-height=&quot;804&quot; data-is-animation=&quot;false&quot; style=&quot;width: 52.0855%;&quot; data-widthpercent=&quot;52.7&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dMRIOo/btrNviG5oW2/VFeoP7IldtpId05XC4iiKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdMRIOo%2FbtrNviG5oW2%2FVFeoP7IldtpId05XC4iiKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1562&quot; height=&quot;804&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;MySQL 커넥션을 담당하는 클래스를 만들고 내부에서 async_scoped_session을 사용하도록 정의&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1562&quot; data-origin-height=&quot;764&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RlOML/btrNzJbzUwI/nCvJbTcQr3wORXLZ1fnVck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RlOML/btrNzJbzUwI/nCvJbTcQr3wORXLZ1fnVck/img.png&quot; data-alt=&quot;쿼리를 날려서 정보를 출력&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RlOML/btrNzJbzUwI/nCvJbTcQr3wORXLZ1fnVck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRlOML%2FbtrNzJbzUwI%2FnCvJbTcQr3wORXLZ1fnVck%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;717&quot; height=&quot;351&quot; data-origin-width=&quot;1562&quot; data-origin-height=&quot;764&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;쿼리를 날려서 정보를 출력&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;쿼리는 select()이며 중간 생략하였습니다. 먼저 context-local에 대해 테스트를 해보기 위해 &lt;b&gt;async_scoped_session.remove()&lt;/b&gt;를 마지막에 호출하지는 않았습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;async_scoped_session.remove()&lt;/b&gt;를 꼭 호출해야 하는 이유는 위에서 언급한 context-local을 지원하기 위해 context마다 AsyncSession을 저장하고 작업이 완료되면 해당 AsyncSession을 삭제해야 하기 때문입니다. async_scoped_session.remove()를 호출하지 않으면 AsyncSession이 메모리에 남게 되고 &lt;b&gt;메모리 누수&lt;/b&gt;에 대한 위험이 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;저는 테스트를 위해 일부러(?) async_scoped_session.remove() 호출하지 않겠습니다. API를 호출해서 get_detail_info()를 한번 호출해보도록 하겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1508&quot; data-origin-height=&quot;368&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beVZZp/btrNyDinOYN/Ms1KFkzKHnHkXnLEncVBV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/beVZZp/btrNyDinOYN/Ms1KFkzKHnHkXnLEncVBV1/img.png&quot; data-alt=&quot;첫 호출에는 아무값도 없기 때문에 KeyError&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/beVZZp/btrNyDinOYN/Ms1KFkzKHnHkXnLEncVBV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbeVZZp%2FbtrNyDinOYN%2FMs1KFkzKHnHkXnLEncVBV1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;733&quot; height=&quot;179&quot; data-origin-width=&quot;1508&quot; data-origin-height=&quot;368&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;첫 호출에는 아무값도 없기 때문에 KeyError&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;당연히 처음 호출할 때는 self.registry에는 아무 값도 없기 때문에 예외처리로 들어가서 AsyncSession을 생성하겠죠? 그럼 두 번째 호출을 해봅시다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2698&quot; data-origin-height=&quot;1102&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rlDKp/btrNvi1kYWF/DGjlz7w2oFkIF2PdaYHxrk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rlDKp/btrNvi1kYWF/DGjlz7w2oFkIF2PdaYHxrk/img.png&quot; data-alt=&quot;오...무언가 들어있다&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rlDKp/btrNvi1kYWF/DGjlz7w2oFkIF2PdaYHxrk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrlDKp%2FbtrNvi1kYWF%2FDGjlz7w2oFkIF2PdaYHxrk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2698&quot; height=&quot;1102&quot; data-origin-width=&quot;2698&quot; data-origin-height=&quot;1102&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;오...무언가 들어있다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;self.registry에 무언가 들어있습니다. AsyncSession객체가 하나 들어있는데 이 객체는 방금 전 호출한 Task의 AsyncSession입니다. 우리가 async_scoped_session.remove()를 호출하지 않았기 때문에 메모리에 계속 남아있는 것입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;그럼 좀 더 많이 호출을 해보겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2646&quot; data-origin-height=&quot;1236&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2sVE0/btrNu7rXAoi/6wk4kLWjKviRGEY15tQUt1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2sVE0/btrNu7rXAoi/6wk4kLWjKviRGEY15tQUt1/img.png&quot; data-alt=&quot;엄청난게 쌓인 AsyncSession객체들&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2sVE0/btrNu7rXAoi/6wk4kLWjKviRGEY15tQUt1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2sVE0%2FbtrNu7rXAoi%2F6wk4kLWjKviRGEY15tQUt1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2646&quot; height=&quot;1236&quot; data-origin-width=&quot;2646&quot; data-origin-height=&quot;1236&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;엄청난게 쌓인 AsyncSession객체들&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;와우... 일단 첫 번째로 async_scoped_session이 context-local을 어떻게 보장하는지 눈으로 직접 확인할 수 있네요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;두 번째로는 async_scoped_session.remove()를 호출하지 않으면 메모리 누수를 일으킬 수 있다. 무조건 마지막에 호출을 해줘야 한다. &lt;/span&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;하지만 여기서 끝이 아닙니다...&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;838&quot; data-origin-height=&quot;652&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cm6xqd/btrNyCRjRgc/dlDU8t34q5bIvkhwdjGcak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cm6xqd/btrNyCRjRgc/dlDU8t34q5bIvkhwdjGcak/img.png&quot; data-alt=&quot;커넥션이 계속 생성됨&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cm6xqd/btrNyCRjRgc/dlDU8t34q5bIvkhwdjGcak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcm6xqd%2FbtrNyCRjRgc%2FdlDU8t34q5bIvkhwdjGcak%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;427&quot; height=&quot;332&quot; data-origin-width=&quot;838&quot; data-origin-height=&quot;652&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;커넥션이 계속 생성됨&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;더 큰 문제는 MySQL의 커넥션 스레드가 계속 증가한다는 점입니다. 다만 계속 호출하다 보면 max_overflow에 걸려서 연결된 커넥션 풀이 특정 개수 이상이 되면 오류를 냅니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1670&quot; data-origin-height=&quot;1524&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cIxRPe/btrNxeJXN6V/kUkXGHnFmadzhFQMUz4Xk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cIxRPe/btrNxeJXN6V/kUkXGHnFmadzhFQMUz4Xk0/img.png&quot; data-alt=&quot;연결할 수 있는 최대 connection pool을 넘어가면 오류&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cIxRPe/btrNxeJXN6V/kUkXGHnFmadzhFQMUz4Xk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcIxRPe%2FbtrNxeJXN6V%2FkUkXGHnFmadzhFQMUz4Xk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;615&quot; height=&quot;561&quot; data-origin-width=&quot;1670&quot; data-origin-height=&quot;1524&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;연결할 수 있는 최대 connection pool을 넘어가면 오류&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1084&quot; data-origin-height=&quot;372&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/evp4dM/btrNvhBryoL/lo2VzCnjLOQNPLn5X3KnY0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/evp4dM/btrNvhBryoL/lo2VzCnjLOQNPLn5X3KnY0/img.png&quot; data-alt=&quot;pool 설정 관련&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/evp4dM/btrNvhBryoL/lo2VzCnjLOQNPLn5X3KnY0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fevp4dM%2FbtrNvhBryoL%2Flo2VzCnjLOQNPLn5X3KnY0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;577&quot; height=&quot;198&quot; data-origin-width=&quot;1084&quot; data-origin-height=&quot;372&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;pool 설정 관련&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;저의 경우는 default를 사용해서 &lt;b&gt;self._overflow = 0 - 5(default)&lt;/b&gt; 이기 때문에 최대&amp;nbsp; 커넥션이 -5부터 +1씩 증가해서 최대 15개까지 만들어진 후에 그때부터 오류가 났습니다. 결과적으로 API 호출에 대해 응답이 오지도 않았고요 (프로덕션이었으면 장애)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;a href=&quot;https://docs.sqlalchemy.org/en/14/errors.html#connections-and-transactions&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;https://docs.sqlalchemy.org/en/14/errors.html#connections-and-transactions&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1664621103035&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Error Messages
 &amp;mdash;
    SQLAlchemy 1.4 Documentation&quot; data-og-description=&quot;Previous: Third Party Integration Issues Next: Changes and Migration Up: Home On this page: Error Messages Connections and Transactions DBAPI Errors SQL Expression Language Object Relational Mapping AsyncIO Exceptions Core Exception Classes ORM Exception C&quot; data-og-host=&quot;docs.sqlalchemy.org&quot; data-og-source-url=&quot;https://docs.sqlalchemy.org/en/14/errors.html#connections-and-transactions&quot; data-og-url=&quot;https://docs.sqlalchemy.org/en/14/errors.html#connections-and-transactions&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://docs.sqlalchemy.org/en/14/errors.html#connections-and-transactions&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.sqlalchemy.org/en/14/errors.html#connections-and-transactions&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Error Messages &amp;mdash; SQLAlchemy 1.4 Documentation&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Previous: Third Party Integration Issues Next: Changes and Migration Up: Home On this page: Error Messages Connections and Transactions DBAPI Errors SQL Expression Language Object Relational Mapping AsyncIO Exceptions Core Exception Classes ORM Exception C&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.sqlalchemy.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;974&quot; data-origin-height=&quot;696&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JmbL7/btrNu6zMbi3/E01GWi92hpBPHk9QYjPrW0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JmbL7/btrNu6zMbi3/E01GWi92hpBPHk9QYjPrW0/img.png&quot; data-alt=&quot;연결된 커넥션은 줄어들지만 생성된 커넥션 스레드는 줄어들지 않음&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JmbL7/btrNu6zMbi3/E01GWi92hpBPHk9QYjPrW0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJmbL7%2FbtrNu6zMbi3%2FE01GWi92hpBPHk9QYjPrW0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;440&quot; height=&quot;314&quot; data-origin-width=&quot;974&quot; data-origin-height=&quot;696&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;연결된 커넥션은 줄어들지만 생성된 커넥션 스레드는 줄어들지 않음&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;그리고 특이하게 MySQL에서 &lt;b&gt;Threads_connected&lt;/b&gt;는 당연히 연결된 커넥션이니까 애플리케이션을 종료하면 줄어드는데 &lt;b&gt;Threads_created&lt;/b&gt;는 줄어들지 않더라고요. 이 부분도 문제가 될 것 같고 정확한 내용은 MySQL 쪽 공부를 좀 더 해봐야 할 것 같습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;그래서 결론은...&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1960&quot; data-origin-height=&quot;938&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/birTYX/btrNvM10UF7/GiwmxAx0DRaeQt2lG05iRK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/birTYX/btrNvM10UF7/GiwmxAx0DRaeQt2lG05iRK/img.png&quot; data-alt=&quot;공식문서에서도 주의사항으로 나타내주고 있네요&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/birTYX/btrNvM10UF7/GiwmxAx0DRaeQt2lG05iRK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbirTYX%2FbtrNvM10UF7%2FGiwmxAx0DRaeQt2lG05iRK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;868&quot; height=&quot;415&quot; data-origin-width=&quot;1960&quot; data-origin-height=&quot;938&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;공식문서에서도 주의사항으로 나타내주고 있네요&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;async_scoped_session을 사용할 때는 항상 async_scoped_session.remove()를 호출해라&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;a href=&quot;https://docs.sqlalchemy.org/en/14/orm/extensions/asyncio.html#using-asyncio-scoped-session&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;https://docs.sqlalchemy.org/en/14/orm/extensions/asyncio.html#using-asyncio-scoped-session&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1664620716863&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Asynchronous I/O (asyncio)
 &amp;mdash;
    SQLAlchemy 1.4 Documentation&quot; data-og-description=&quot;Asynchronous I/O (asyncio) Support for Python asyncio. Support for Core and ORM usage is included, using asyncio-compatible dialects. Tip The asyncio extension as of SQLAlchemy 1.4.3 can now be considered to be beta level software. API details are subject &quot; data-og-host=&quot;docs.sqlalchemy.org&quot; data-og-source-url=&quot;https://docs.sqlalchemy.org/en/14/orm/extensions/asyncio.html#using-asyncio-scoped-session&quot; data-og-url=&quot;https://docs.sqlalchemy.org/en/14/orm/extensions/asyncio.html#using-asyncio-scoped-session&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://docs.sqlalchemy.org/en/14/orm/extensions/asyncio.html#using-asyncio-scoped-session&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.sqlalchemy.org/en/14/orm/extensions/asyncio.html#using-asyncio-scoped-session&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Asynchronous I/O (asyncio) &amp;mdash; SQLAlchemy 1.4 Documentation&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Asynchronous I/O (asyncio) Support for Python asyncio. Support for Core and ORM usage is included, using asyncio-compatible dialects. Tip The asyncio extension as of SQLAlchemy 1.4.3 can now be considered to be beta level software. API details are subject&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.sqlalchemy.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;마치며&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;며칠 동안 SQLAlchemy의 Session, scopred_session, async_scoped_session을 살펴보면서 상당히 많은 지식들을 공부했던 것 같고 습득했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;그냥 단순히 기술을 사용하는 것보다는 왜 이렇게 동작하고 어떤 문제가 있을 수 있는지에 대해 알아보고 테스트해봤습니다. 확실히 시간과 이해에 대한 시간이 오래 걸리긴 하지만 기술에 대해 제대로 알 수 있었던 것 같고 공식문서와 PR 등을 살펴보는 것도 나름 재밌었던 것 같습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;혹시나 위 글을 읽으면서 잘못된 내용이 있다면 댓글로 첨언 부탁드립니다! 큰 도움이 될 거예요!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;참고자료&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://www.hides.kr/1081?category=666044&quot;&gt;https://www.hides.kr/1081?category=666044&lt;/a&gt;&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1664781140673&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;FastAPI SQLAlchemy 연동하며 발생한 문제 정리&quot; data-og-description=&quot;개요 기존과 다른 패러다임을 가진 비동기 프레임워크 FastAPI와 SQLAlchemy를 연동하는 과정에서 발생했던 문제들과 어떠한 형태로 해결했는지에 대해 다뤄본다. 사전 지식 SQLAlchemy는 scoped_session() &quot; data-og-host=&quot;www.hides.kr&quot; data-og-source-url=&quot;https://www.hides.kr/1081?category=666044&quot; data-og-url=&quot;https://www.hides.kr/1081&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dlhWbl/hyPYZjBo89/rwrWY0mG4oryyJCbNqLc6K/img.png?width=800&amp;amp;height=288&amp;amp;face=0_0_800_288,https://scrap.kakaocdn.net/dn/cQ53yC/hyPY1Pf3LF/Qe1Gr5VHZorlvZ3l3Dnaa0/img.png?width=800&amp;amp;height=288&amp;amp;face=0_0_800_288,https://scrap.kakaocdn.net/dn/dRzkVe/hyP0yq9o4q/k1gup0Kjegu2uVF8XFEmZ0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://www.hides.kr/1081?category=666044&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.hides.kr/1081?category=666044&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dlhWbl/hyPYZjBo89/rwrWY0mG4oryyJCbNqLc6K/img.png?width=800&amp;amp;height=288&amp;amp;face=0_0_800_288,https://scrap.kakaocdn.net/dn/cQ53yC/hyPY1Pf3LF/Qe1Gr5VHZorlvZ3l3Dnaa0/img.png?width=800&amp;amp;height=288&amp;amp;face=0_0_800_288,https://scrap.kakaocdn.net/dn/dRzkVe/hyP0yq9o4q/k1gup0Kjegu2uVF8XFEmZ0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;FastAPI SQLAlchemy 연동하며 발생한 문제 정리&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;개요 기존과 다른 패러다임을 가진 비동기 프레임워크 FastAPI와 SQLAlchemy를 연동하는 과정에서 발생했던 문제들과 어떠한 형태로 해결했는지에 대해 다뤄본다. 사전 지식 SQLAlchemy는 scoped_session()&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.hides.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>  프로그래밍/Python</category>
      <category>async_scoped_session</category>
      <category>context local</category>
      <category>SQLAlchemy</category>
      <author>피트웨어 제이 (FitwareJay)</author>
      <guid isPermaLink="true">https://jay-ji.tistory.com/115</guid>
      <comments>https://jay-ji.tistory.com/115#entry115comment</comments>
      <pubDate>Sat, 1 Oct 2022 20:42:49 +0900</pubDate>
    </item>
    <item>
      <title>[SQLAlchemy] Session vs scoped_session</title>
      <link>https://jay-ji.tistory.com/114</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;안녕하세요! 개발자 Jay입니다!&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;블로그에 말하지는 않았지만 퇴사한지 거진 한 달쯤 다되어가네요 ㅋㅋㅋ 입사 전 이것저것 해볼 계획은 많았는데... 생각보다 많이 못해서 아쉽지만... 여하튼ㅋㅋㅋ&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;토이 프로젝트 프레임워크로 FastAPI를 사용하면서 &lt;b&gt;SQLAlchemy&lt;/b&gt;를 사용했었습니다. 그때는 막상 구현하는데 급급해서 자세히 알아보지 못했던 부분들이 있었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;이번에 repository 쪽 코드를 리팩토링 하면서 &lt;b&gt;Session&lt;/b&gt;과 &lt;b&gt;scoped_session&lt;/b&gt;에 대한 내용을 제대로 파보았습니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;Session이란?&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;SQLAlchemy에서 말하는 Session은 DB Session과는 전혀 다릅니다.(혹시나 헷갈릴 수도 있으니)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2764&quot; data-origin-height=&quot;1028&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dmZtnb/btrNibHbdHn/8KsO4BkKrkQVrfQ32an35K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dmZtnb/btrNibHbdHn/8KsO4BkKrkQVrfQ32an35K/img.png&quot; data-alt=&quot;session이 하는 역할을 그림으로 나타내어 봄&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dmZtnb/btrNibHbdHn/8KsO4BkKrkQVrfQ32an35K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdmZtnb%2FbtrNibHbdHn%2F8KsO4BkKrkQVrfQ32an35K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2764&quot; height=&quot;1028&quot; data-origin-width=&quot;2764&quot; data-origin-height=&quot;1028&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;session이 하는 역할을 그림으로 나타내어 봄&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;SQLAlchmey의 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://docs.sqlalchemy.org/en/14/orm/session_basics.html#session-basics&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Session&lt;/a&gt;&lt;/b&gt;&lt;/span&gt;은 일종에 ORM 버퍼라고 보면 되며 ORM 매핑 객체(object)에 대한 지속성 작업을 관리합니다. DB connection의 트랜잭션을 설정하고 관리합니다. &lt;b&gt;이 트랜잭션은 commit 하거나 rollback 지시가 있기 전까지 유효&lt;/b&gt;합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;그림에서 볼 수 있다시피 &lt;b&gt;Session&lt;/b&gt;은 &lt;b&gt;Unit-of-work(UoW)&lt;/b&gt; 패턴으로 되어있습니다. 공식문서에도 나오는 내용인데 UoW에 대해서는 &lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://martinfowler.com/eaaCatalog/unitOfWork.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;여기&lt;/a&gt;&lt;/span&gt;&lt;/b&gt;를 참고하길 바랍니다. 간단히 말하자면 비즈니스 레이어에서의 트랜잭션 개념입니다. UoW 패턴을 사용하면 데이터 무결성을 보장할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;span&gt;Session은 ORM 혹은 model 객체(object) 들을 이용하여 DB에 CRUD 작업들을 실행시킬 수 있습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;span&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;Session은 thread-safe를 보장하지 않습니다.&lt;/b&gt;&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;span&gt;(이게 진짜 오늘의 핵심 포인트)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;span&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://docs.sqlalchemy.org/en/14/orm/session_basics.html#is-the-session-thread-safe&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.sqlalchemy.org/en/14/orm/session_basics.html#is-the-session-thread-safe&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1664392365298&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Session Basics
 &amp;mdash;
    SQLAlchemy 1.4 Documentation&quot; data-og-description=&quot;Session Basics What does the Session do ? In the most general sense, the Session establishes all conversations with the database and represents a &amp;ldquo;holding zone&amp;rdquo; for all the objects which you&amp;rsquo;ve loaded or associated with it during its lifespan. It pro&quot; data-og-host=&quot;docs.sqlalchemy.org&quot; data-og-source-url=&quot;https://docs.sqlalchemy.org/en/14/orm/session_basics.html#is-the-session-thread-safe&quot; data-og-url=&quot;https://docs.sqlalchemy.org/en/14/orm/session_basics.html#is-the-session-thread-safe&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://docs.sqlalchemy.org/en/14/orm/session_basics.html#is-the-session-thread-safe&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.sqlalchemy.org/en/14/orm/session_basics.html#is-the-session-thread-safe&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Session Basics &amp;mdash; SQLAlchemy 1.4 Documentation&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Session Basics What does the Session do ? In the most general sense, the Session establishes all conversations with the database and represents a &amp;ldquo;holding zone&amp;rdquo; for all the objects which you&amp;rsquo;ve loaded or associated with it during its lifespan. It pro&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.sqlalchemy.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;span&gt;scoped_session이란?&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2096&quot; data-origin-height=&quot;342&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ce48AN/btrNi4gAlvR/8qTSSIKD1xnpzlzUHwYKT0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ce48AN/btrNi4gAlvR/8qTSSIKD1xnpzlzUHwYKT0/img.png&quot; data-alt=&quot;session은 오직 하나의 스레드에서만 사용하도록&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ce48AN/btrNi4gAlvR/8qTSSIKD1xnpzlzUHwYKT0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fce48AN%2FbtrNi4gAlvR%2F8qTSSIKD1xnpzlzUHwYKT0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2096&quot; height=&quot;342&quot; data-origin-width=&quot;2096&quot; data-origin-height=&quot;342&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;session은 오직 하나의 스레드에서만 사용하도록&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;span&gt;여기서부터가 진짜 중요한 내용입니다. 위에서 Session은 thread-safe하지 않다고 했습니다. 공식문서를 보면 Session은 일반적으로 하나의 스레드에서 비동기 방식으로 사용하기 위한 것이라고 나와있습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;span&gt;두 번째 문단의 내용을 간단히 말하면 아래와 같습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;다중 스레드(multi-thread)간에 Session이 공유되는 경우 thread-safe하지 못하다. &lt;br /&gt;이것을 막기 위해서는 하나의 스레드당 하나의 Session을 연결하면 된다.(=Thread-local). &lt;br /&gt;아니면 session이 함수 간에 전달되는 과정에서 다른 스레드와 공유하지 않는 패턴을 이용하는 것이다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;span&gt;근데 위와 같은 것을 자동으로 해주는 게 &lt;b&gt;scoped_session&lt;/b&gt;입니다! &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;span&gt;scoped_session은 &lt;b&gt;thread.local()&lt;/b&gt;을 사용하여 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;스레드 고유의 데이터 영역에 Session을 저장함으로서 thread-safe를 보장&lt;/b&gt;&lt;/span&gt;합니다. 이 말은 즉슨, 스레드끼리 Session을 공유하지 않습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;680&quot; data-origin-height=&quot;382&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cGxHd8/btrNwoyX1Sg/qSYxJLsS9CA8JKXkUmrrw0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cGxHd8/btrNwoyX1Sg/qSYxJLsS9CA8JKXkUmrrw0/img.jpg&quot; data-alt=&quot;그럼 여기서 질문! Session을 스레드끼리 공유하면 무슨 문제가 있나요?&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cGxHd8/btrNwoyX1Sg/qSYxJLsS9CA8JKXkUmrrw0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcGxHd8%2FbtrNwoyX1Sg%2FqSYxJLsS9CA8JKXkUmrrw0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;536&quot; height=&quot;301&quot; data-origin-width=&quot;680&quot; data-origin-height=&quot;382&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;그럼 여기서 질문! Session을 스레드끼리 공유하면 무슨 문제가 있나요?&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;span&gt;네 문제가 있죠. 위에서 계속 언급한 thread-safe와 관계있습니다. thread-safe는 다중 스레드 환경에서 여러 스레드가 공유자원에 접근해도 프로그램 실행에 문제가 없음을 뜻합니다. Session을 여러 스레드가 공유하게 되면 Session을 제어하면서 잘못된 동작 혹은 오류를 유발할 수 있습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;span&gt;요약하자면...&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;thread-local을 사용하는 scoped_session은 하나의 thread당 하나의 Session을 가지기 때문에 &lt;br /&gt;thread-safe 하게 Session을 다룰 수 있다!&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;코드로 알아보자!&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 scoped_session을 사용하면 정말 thread-safe 한 지? scpoed_session에서는 어떻게 thread-local을 구현해서 session을 매니징 하는지 알아보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1.&amp;nbsp; session을 다중 스레드에서 공유하는 형태&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1518&quot; data-origin-height=&quot;454&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGS0WS/btrNryH60Fk/ek0Qzf12LNmBgzVhdp3DT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGS0WS/btrNryH60Fk/ek0Qzf12LNmBgzVhdp3DT1/img.png&quot; data-alt=&quot;sessionmaker 선언&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGS0WS/btrNryH60Fk/ek0Qzf12LNmBgzVhdp3DT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGS0WS%2FbtrNryH60Fk%2Fek0Qzf12LNmBgzVhdp3DT1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;773&quot; height=&quot;231&quot; data-origin-width=&quot;1518&quot; data-origin-height=&quot;454&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;sessionmaker 선언&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Session은 sessionmaker로 생성합니다. 여기서 사용되는 engine은 데이터베이스 연결과 동작의 소스를 제공하는 객체입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1674&quot; data-origin-height=&quot;1416&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bCws6N/btrNob17ObB/GuqK7MQW8tDw9dM8jlCuvk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bCws6N/btrNob17ObB/GuqK7MQW8tDw9dM8jlCuvk/img.png&quot; data-alt=&quot;동일한 session이 thread의 arg로 전달되는 예제&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bCws6N/btrNob17ObB/GuqK7MQW8tDw9dM8jlCuvk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbCws6N%2FbtrNob17ObB%2FGuqK7MQW8tDw9dM8jlCuvk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;705&quot; height=&quot;596&quot; data-origin-width=&quot;1674&quot; data-origin-height=&quot;1416&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;동일한 session이 thread의 arg로 전달되는 예제&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드는 &lt;b&gt;UserRepository&lt;/b&gt;의 메서드에서 thread에 session이 공유되는 형태입니다. API 호출을 통해 &lt;b&gt;get_detail_info()&lt;/b&gt; 호출되면 어떻게 로그가 찍히는지 확인해 봅시다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1224&quot; data-origin-height=&quot;412&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXfvw1/btrNo7ELfRE/dJiICJLZy8nXXoNeguRM71/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXfvw1/btrNo7ELfRE/dJiICJLZy8nXXoNeguRM71/img.png&quot; data-alt=&quot;모두 동일한 Session을 사용하는걸 확인&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXfvw1/btrNo7ELfRE/dJiICJLZy8nXXoNeguRM71/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXfvw1%2FbtrNo7ELfRE%2FdJiICJLZy8nXXoNeguRM71%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;637&quot; height=&quot;214&quot; data-origin-width=&quot;1224&quot; data-origin-height=&quot;412&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;모두 동일한 Session을 사용하는걸 확인&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과는 역시 동일한 Session을 스레드가 공유하는 걸 확인할 수 있습니다. 그렇다면 이렇게 Session을 여러 스레드에서 공유하게 되면 어떤 문제가 있을 수 있을까요?&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2090&quot; data-origin-height=&quot;854&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cT2Yl9/btrNqceCLcU/TtXId7PLNYpLF5ZuoboKJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cT2Yl9/btrNqceCLcU/TtXId7PLNYpLF5ZuoboKJk/img.png&quot; data-alt=&quot;user를 추가하는 메소드&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cT2Yl9/btrNqceCLcU/TtXId7PLNYpLF5ZuoboKJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcT2Yl9%2FbtrNqceCLcU%2FTtXId7PLNYpLF5ZuoboKJk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2090&quot; height=&quot;854&quot; data-origin-width=&quot;2090&quot; data-origin-height=&quot;854&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;user를 추가하는 메소드&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;UserRepository&lt;/b&gt;에 위와 같은 &lt;b&gt;insert&lt;/b&gt; 메소드를 만들어 보았습니다. 예제가 다소 극단적이긴 하지만 만약에 두 개의 스레드가 동시에 같은 데이터를 가진 User객체를 add하고 main 스레드에서 commit하면 어떻게 될까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2120&quot; data-origin-height=&quot;596&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dN6Zvs/btrNqWWMZpU/kztYjDyDOI5mQU16Zq2AYk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dN6Zvs/btrNqWWMZpU/kztYjDyDOI5mQU16Zq2AYk/img.png&quot; data-alt=&quot;IntegrityError를 뿜는 sqlalchemy&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dN6Zvs/btrNqWWMZpU/kztYjDyDOI5mQU16Zq2AYk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdN6Zvs%2FbtrNqWWMZpU%2FkztYjDyDOI5mQU16Zq2AYk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2120&quot; height=&quot;596&quot; data-origin-width=&quot;2120&quot; data-origin-height=&quot;596&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;IntegrityError를 뿜는 sqlalchemy&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에러를 마주하게 됩니다.&amp;nbsp; 두개의 스레드가 동일한 session을 사용함으로써 같은 트랜잭션 내에서 오류가 생겼습니다(Duplicate entry). 뭐 위처럼 코드를 작성하지는 않겠지만 이런 식으로 오류를 일으킬 수 있다고 생각하시면 됩니다. 그리고 같은 session내에서 에러가 생겼기 때문에 User는 DB에 추가되지 않았음을 확인할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것이 SQLAlchemy 공식문서에서 말하는 Session이 thread-safe하지 않다는 말입니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 scoped_session을 사용하면 어떨까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2.&amp;nbsp; scoped_session에서 다중 스레드를 사용하는 경우&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1286&quot; data-origin-height=&quot;334&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OoVZy/btrNryVGsTw/gK7BAApHlnelUTK2IKQXn0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OoVZy/btrNryVGsTw/gK7BAApHlnelUTK2IKQXn0/img.png&quot; data-alt=&quot;scoped_session 사용&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OoVZy/btrNryVGsTw/gK7BAApHlnelUTK2IKQXn0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOoVZy%2FbtrNryVGsTw%2FgK7BAApHlnelUTK2IKQXn0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;675&quot; height=&quot;175&quot; data-origin-width=&quot;1286&quot; data-origin-height=&quot;334&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;scoped_session 사용&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드가 바뀌는 부분은 &lt;b&gt;scoped_session&lt;/b&gt;을 사용하는 것뿐입니다. 먼저 위에서 만든 &lt;b&gt;get_detail_info()&lt;/b&gt;를 호출해보겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1364&quot; data-origin-height=&quot;446&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CJtb1/btrNolXOndQ/hnAiscQKW9RHkwq7GVLpBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CJtb1/btrNolXOndQ/hnAiscQKW9RHkwq7GVLpBk/img.png&quot; data-alt=&quot;thread1과 thread2가 서로 다른 Session을 사용&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CJtb1/btrNolXOndQ/hnAiscQKW9RHkwq7GVLpBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCJtb1%2FbtrNolXOndQ%2FhnAiscQKW9RHkwq7GVLpBk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;674&quot; height=&quot;220&quot; data-origin-width=&quot;1364&quot; data-origin-height=&quot;446&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;thread1과 thread2가 서로 다른 Session을 사용&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오! 정말 하나의 thread당 하나의 Session사용이 가능해졌습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 insert()를 호출해볼 건데 약간의 코드 변경이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2290&quot; data-origin-height=&quot;1054&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BPYjT/btrNsFttyqR/tamtyvBKkc37bhtGe5hO61/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BPYjT/btrNsFttyqR/tamtyvBKkc37bhtGe5hO61/img.png&quot; data-alt=&quot;스레드 내부에서 commit() 호출&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BPYjT/btrNsFttyqR/tamtyvBKkc37bhtGe5hO61/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBPYjT%2FbtrNsFttyqR%2FtamtyvBKkc37bhtGe5hO61%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2290&quot; height=&quot;1054&quot; data-origin-width=&quot;2290&quot; data-origin-height=&quot;1054&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;스레드 내부에서 commit() 호출&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;scoped_session은 thread당 다른 Session을 사용하기 때문에 각자 commit()을 호출하도록 했습니다. 결과는 어떨까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1812&quot; data-origin-height=&quot;1260&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b9VVm7/btrNn3C8fDK/9LkkGmDabdPypTlu1w2tYk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b9VVm7/btrNn3C8fDK/9LkkGmDabdPypTlu1w2tYk/img.png&quot; data-alt=&quot;하나는 성공 하나는 실패&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b9VVm7/btrNn3C8fDK/9LkkGmDabdPypTlu1w2tYk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb9VVm7%2FbtrNn3C8fDK%2F9LkkGmDabdPypTlu1w2tYk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1812&quot; height=&quot;1260&quot; data-origin-width=&quot;1812&quot; data-origin-height=&quot;1260&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;하나는 성공 하나는 실패&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 번째 데이터를 추가할 때는 성공, 두번째 데이터를 추가할때는 오류가 났습니다. 어떻게 보면 당연한 거죠?! 다만 session을 서로 공유하지 않기 때문에 적어도 먼저 실행한 트랜잭션은 제대로 실행되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금 와서 보니 약간 예제가 다소 적절하지는 않은 것 같기도 하고... 좀 더 적절한 예제를 생각해본다면... Session을 여러 스레드에서 사용하는데 중간에 flush 혹은 commit을 어떤 스레드가 해버리면 다른 스레드에서는 잘못된 동작이 되겠... 죠?!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여튼 &quot;&lt;b&gt;여러 스레드에서 동일한 session을 공유하게 되면 thread-safe하지 않게 되어 의도하지 않은 동작이 일어날 수 있다&quot;&lt;/b&gt; 정도로 이해하면 좋을 것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 여기서 궁금증! &lt;b&gt;scoped_session은 어떻게 thread-safe 하게 Session을 사용할 수 있는 것일까?&lt;/b&gt; 앞서 말했던 &lt;b&gt;thread-local data&lt;/b&gt;를 사용하기 때문인데요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1100&quot; data-origin-height=&quot;992&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QvWoI/btrNs2B6OL3/ZOXrP6GHi9XnZNr7FODBG0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QvWoI/btrNs2B6OL3/ZOXrP6GHi9XnZNr7FODBG0/img.png&quot; data-alt=&quot;scoped_session init()&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QvWoI/btrNs2B6OL3/ZOXrP6GHi9XnZNr7FODBG0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQvWoI%2FbtrNs2B6OL3%2FZOXrP6GHi9XnZNr7FODBG0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;535&quot; height=&quot;482&quot; data-origin-width=&quot;1100&quot; data-origin-height=&quot;992&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;scoped_session init()&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1072&quot; data-origin-height=&quot;744&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9b02x/btrNryBomiY/rIXuDY7dXzhToM3kQakKnk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9b02x/btrNryBomiY/rIXuDY7dXzhToM3kQakKnk/img.png&quot; data-alt=&quot;ThreadLocalRegistry&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9b02x/btrNryBomiY/rIXuDY7dXzhToM3kQakKnk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9b02x%2FbtrNryBomiY%2FrIXuDY7dXzhToM3kQakKnk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;530&quot; height=&quot;368&quot; data-origin-width=&quot;1072&quot; data-origin-height=&quot;744&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ThreadLocalRegistry&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;scopre_session&lt;/b&gt;에서는 Session을 생성할 때&lt;b&gt; threading.local()&lt;/b&gt;을 사용합니다. &lt;b&gt;self.registry.value&lt;/b&gt;에 값이 있으면 그대로 리턴, 값이 없으면 새로운 Session을 만들어서 리턴합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1298&quot; data-origin-height=&quot;698&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mWuAY/btrNrUYD4xI/sSZVoiP0g2PvLB5S895gWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mWuAY/btrNrUYD4xI/sSZVoiP0g2PvLB5S895gWk/img.png&quot; data-alt=&quot;Session객체를 가지고 있는경우&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mWuAY/btrNrUYD4xI/sSZVoiP0g2PvLB5S895gWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmWuAY%2FbtrNrUYD4xI%2FsSZVoiP0g2PvLB5S895gWk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;588&quot; height=&quot;316&quot; data-origin-width=&quot;1298&quot; data-origin-height=&quot;698&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Session객체를 가지고 있는경우&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디버깅을 찍어보면 이렇게 thread-local data로 Session을 가지고 있는 것을 볼 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;번외 (Thread가 아닌 Process를 사용하는 경우)&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1630&quot; data-origin-height=&quot;614&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/chQxOW/btrNomWHwgi/uTfVpKibWfkg34FOScFOg1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/chQxOW/btrNomWHwgi/uTfVpKibWfkg34FOScFOg1/img.png&quot; data-alt=&quot;get_deatil_info()에서 Thread를 Process로 변경한 경우&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/chQxOW/btrNomWHwgi/uTfVpKibWfkg34FOScFOg1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FchQxOW%2FbtrNomWHwgi%2FuTfVpKibWfkg34FOScFOg1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;794&quot; height=&quot;299&quot; data-origin-width=&quot;1630&quot; data-origin-height=&quot;614&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;get_deatil_info()에서 Thread를 Process로 변경한 경우&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자 그럼 이 경우는 어떨까요? scoped_session을 사용할 때 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;Thread가 아닌 Process를 사용한다면?!&lt;/b&gt;&lt;/span&gt; ㅋㅋㅋ 한번 고민해보시고 아래를 봐주시겠어요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1276&quot; data-origin-height=&quot;352&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cLGTSz/btrNreXluST/fWwFUd0aamYLFkLBGDjAY1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cLGTSz/btrNreXluST/fWwFUd0aamYLFkLBGDjAY1/img.png&quot; data-alt=&quot;동일한 Session을 사용한다&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cLGTSz/btrNreXluST/fWwFUd0aamYLFkLBGDjAY1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcLGTSz%2FbtrNreXluST%2FfWwFUd0aamYLFkLBGDjAY1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;831&quot; height=&quot;229&quot; data-origin-width=&quot;1276&quot; data-origin-height=&quot;352&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;동일한 Session을 사용한다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과는 동일한 Session을 사용합니다! 이유는 scoped_session은 하나의 스레드당 하나의 Session을 사용한다고 했습니다. 위 코드에서는 메인 스레드에서 두 개의 Process를 실행했습니다. 결국 두 프로세스가 같은 메인 스레드에서 실행되었기 때문에 같은 Session을 사용한 것입니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에 Thread 말고 Process로 쓰다가 예상했던 동작이 아니어서 삽질하다가 발견한 내용입니다;; ㅋㅋㅋ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;마치며&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 이전에 SQLAlchemy를 사용할 때 토이 프로젝트에서 사용하기도 했고.... 그렇기에 구현 자체에만 집중했던 것 같습니다. 이번에 공식문서와 다른 블로그들을 참고하면서 Session 하나에서도 &lt;b&gt;thread-safe, thread-local, unit-of-work&lt;/b&gt; 등 다양한 개념들을 배울 수 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에 글을 쓰면서 공식문서를 잘 읽기 위해 영어를 공부해야겠다는 생각을 정말 많이 한 것 같네요 ㅋㅋㅋ 물론 구글 번역과 일부 문장은 해석이 되지만... 문법이 좀만 복잡해지거나 모르는 단어가 많으면 헷갈리더라고요 ㅋㅋㅋ 영어를 잘했으면 삽질을 덜 했을 것 같네요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여튼 글을 쓰면서도 재밌었고 다음은 &lt;b&gt;async_scope_session&lt;/b&gt;에 대한 내용을 정리해보도록 하겠습니다! 그런 오늘도 즐거운 코딩 하세요~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;참고자료&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://jybaek.tistory.com/914&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;https://jybaek.tistory.com/914&lt;/span&gt;&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1664557724649&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;SQLAlchemy add, flush, commit&quot; data-og-description=&quot;SQLAlchemy는 애플리케이션 개발자에게 SQL의 모든 기능과 유연성을 제공하는 Python SQL 툴킷 및 객체 관계형 매퍼입니다 (공식 홈페이지 소개 문구). 모든 데이터베이스 객체를 다룰 때 신경 써야 하&quot; data-og-host=&quot;jybaek.tistory.com&quot; data-og-source-url=&quot;https://jybaek.tistory.com/914&quot; data-og-url=&quot;https://jybaek.tistory.com/914&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/qyFnZ/hyPY015gfl/kd9Ty3zDAgkygADOBOsGSk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/b0E65K/hyPXDgnlim/HqHgC5GpYLtcFi5vDc6M0k/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://jybaek.tistory.com/914&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jybaek.tistory.com/914&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/qyFnZ/hyPY015gfl/kd9Ty3zDAgkygADOBOsGSk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/b0E65K/hyPXDgnlim/HqHgC5GpYLtcFi5vDc6M0k/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;SQLAlchemy add, flush, commit&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;SQLAlchemy는 애플리케이션 개발자에게 SQL의 모든 기능과 유연성을 제공하는 Python SQL 툴킷 및 객체 관계형 매퍼입니다 (공식 홈페이지 소개 문구). 모든 데이터베이스 객체를 다룰 때 신경 써야 하&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;jybaek.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://yujuwon.tistory.com/349&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;https://yujuwon.tistory.com/349&lt;/b&gt;&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1664557758588&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[SQLALCHEMY] session 관리&quot; data-og-description=&quot;SQLAlchemy에서는 정말 편리하게도 많은 기능들을 제공해 주고 있다. 그 중 하나로 pool 관리도 해주는데 대부분 아래와 같이 사용할 것이다. from sqlalchemy import create_engine from sqlalchemy.orm import s..&quot; data-og-host=&quot;yujuwon.tistory.com&quot; data-og-source-url=&quot;https://yujuwon.tistory.com/349&quot; data-og-url=&quot;https://yujuwon.tistory.com/entry/SQLALCHEMY-session-%EA%B4%80%EB%A6%AC&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/p6c2Y/hyPZa4IfaF/mRKsWeE20Vzw47sC0AoJok/img.png?width=525&amp;amp;height=118&amp;amp;face=0_0_525_118,https://scrap.kakaocdn.net/dn/ck30zS/hyPXI23JbE/JX2dDIZ39ByidSxME6mmB1/img.png?width=525&amp;amp;height=118&amp;amp;face=0_0_525_118&quot;&gt;&lt;a href=&quot;https://yujuwon.tistory.com/349&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://yujuwon.tistory.com/349&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/p6c2Y/hyPZa4IfaF/mRKsWeE20Vzw47sC0AoJok/img.png?width=525&amp;amp;height=118&amp;amp;face=0_0_525_118,https://scrap.kakaocdn.net/dn/ck30zS/hyPXI23JbE/JX2dDIZ39ByidSxME6mmB1/img.png?width=525&amp;amp;height=118&amp;amp;face=0_0_525_118');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[SQLALCHEMY] session 관리&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;SQLAlchemy에서는 정말 편리하게도 많은 기능들을 제공해 주고 있다. 그 중 하나로 pool 관리도 해주는데 대부분 아래와 같이 사용할 것이다. from sqlalchemy import create_engine from sqlalchemy.orm import s..&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;yujuwon.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@khh180cm/6.-%EC%9E%91%EC%97%85-%EB%8B%A8%EC%9C%84-%ED%8C%A8%ED%84%B4&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;https://velog.io/@khh180cm/6.-%EC%9E%91%EC%97%85-%EB%8B%A8%EC%9C%84-%ED%8C%A8%ED%84%B4&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1664557879349&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;6. 작업 단위 패턴&quot; data-og-description=&quot;UoW(Unit of Work)&quot; data-og-host=&quot;velog.io&quot; data-og-source-url=&quot;https://velog.io/@khh180cm/6.-%EC%9E%91%EC%97%85-%EB%8B%A8%EC%9C%84-%ED%8C%A8%ED%84%B4&quot; data-og-url=&quot;https://velog.io/@khh180cm/6.-작업-단위-패턴&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ezG755/hyPZbieDOS/vXozOEcf3uHsM87zexYcW1/img.png?width=950&amp;amp;height=500&amp;amp;face=0_0_950_500,https://scrap.kakaocdn.net/dn/chaRsn/hyPYWL9bKj/YUO8aSs81Ru48BPk4EZOYK/img.jpg?width=1280&amp;amp;height=1280&amp;amp;face=0_0_1280_1280,https://scrap.kakaocdn.net/dn/cr9DOG/hyPXNDhSj2/UHQ4mXeBzDMomXhbOc0j90/img.png?width=1404&amp;amp;height=204&amp;amp;face=0_0_1404_204&quot;&gt;&lt;a href=&quot;https://velog.io/@khh180cm/6.-%EC%9E%91%EC%97%85-%EB%8B%A8%EC%9C%84-%ED%8C%A8%ED%84%B4&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://velog.io/@khh180cm/6.-%EC%9E%91%EC%97%85-%EB%8B%A8%EC%9C%84-%ED%8C%A8%ED%84%B4&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ezG755/hyPZbieDOS/vXozOEcf3uHsM87zexYcW1/img.png?width=950&amp;amp;height=500&amp;amp;face=0_0_950_500,https://scrap.kakaocdn.net/dn/chaRsn/hyPYWL9bKj/YUO8aSs81Ru48BPk4EZOYK/img.jpg?width=1280&amp;amp;height=1280&amp;amp;face=0_0_1280_1280,https://scrap.kakaocdn.net/dn/cr9DOG/hyPXNDhSj2/UHQ4mXeBzDMomXhbOc0j90/img.png?width=1404&amp;amp;height=204&amp;amp;face=0_0_1404_204');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;6. 작업 단위 패턴&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;UoW(Unit of Work)&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;velog.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://soundprovider.tistory.com/entry/python-Thread-Local-Data&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://soundprovider.tistory.com/entry/python-Thread-Local-Data&lt;/a&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1664557903604&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[python] Thread-Local Data&quot; data-og-description=&quot;파이썬에서 thread-local data와 관련된 좋은 글이 있어 정리하고자 한다. 원글은 이 글인데 이 사이트에 Threading, Multiprocessing, ThreadPoolExecutor, ProcessPoolExecutor에 대한 설명들이 매우 잘 돼있다...&quot; data-og-host=&quot;soundprovider.tistory.com&quot; data-og-source-url=&quot;https://soundprovider.tistory.com/entry/python-Thread-Local-Data&quot; data-og-url=&quot;https://soundprovider.tistory.com/entry/python-Thread-Local-Data&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/boonXo/hyPXO3hkKy/ASrYd2STdPVCepHi1MYgw1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/cPt672/hyPYZoy0af/ngTkr69KdGebX75k1STN8K/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/BR5fo/hyPXCaHuiE/GHqBK0P9mKNDSEMa9wDsLk/img.jpg?width=2000&amp;amp;height=1728&amp;amp;face=293_306_1093_1008&quot;&gt;&lt;a href=&quot;https://soundprovider.tistory.com/entry/python-Thread-Local-Data&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://soundprovider.tistory.com/entry/python-Thread-Local-Data&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/boonXo/hyPXO3hkKy/ASrYd2STdPVCepHi1MYgw1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/cPt672/hyPYZoy0af/ngTkr69KdGebX75k1STN8K/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/BR5fo/hyPXCaHuiE/GHqBK0P9mKNDSEMa9wDsLk/img.jpg?width=2000&amp;amp;height=1728&amp;amp;face=293_306_1093_1008');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[python] Thread-Local Data&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;파이썬에서 thread-local data와 관련된 좋은 글이 있어 정리하고자 한다. 원글은 이 글인데 이 사이트에 Threading, Multiprocessing, ThreadPoolExecutor, ProcessPoolExecutor에 대한 설명들이 매우 잘 돼있다...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;soundprovider.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://www.hides.kr/1103?category=666044&quot;&gt;https://www.hides.kr/1103?category=666044&lt;/a&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1664558046169&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;FastAPI에서 SQLAlchemy Session 다루는 방법&quot; data-og-description=&quot;개요 FastAPI는 비동기 프레임워크이다. 내부적으로는 Starlette를 Wrapping한 프레임워크인데 일반적인 동기 프레임워크인 Flask, Django등과는 다른 패러다임을 가지고 있다. 그에 따라 프로덕션 레벨에&quot; data-og-host=&quot;www.hides.kr&quot; data-og-source-url=&quot;https://www.hides.kr/1103?category=666044&quot; data-og-url=&quot;https://www.hides.kr/1103&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b6eVxO/hyPXJgAGe7/gekeWfzjmTWst3IhANVs41/img.png?width=800&amp;amp;height=252&amp;amp;face=0_0_800_252,https://scrap.kakaocdn.net/dn/eVIo2/hyPXGjRSLy/fFG4kdCuwyY6K6vxD9NWP0/img.png?width=800&amp;amp;height=252&amp;amp;face=0_0_800_252,https://scrap.kakaocdn.net/dn/hvaQF/hyPY6utcce/yrC7zxoACQ7kKHHWwSzZuK/img.png?width=1255&amp;amp;height=636&amp;amp;face=0_0_1255_636&quot;&gt;&lt;a href=&quot;https://www.hides.kr/1103?category=666044&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.hides.kr/1103?category=666044&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b6eVxO/hyPXJgAGe7/gekeWfzjmTWst3IhANVs41/img.png?width=800&amp;amp;height=252&amp;amp;face=0_0_800_252,https://scrap.kakaocdn.net/dn/eVIo2/hyPXGjRSLy/fFG4kdCuwyY6K6vxD9NWP0/img.png?width=800&amp;amp;height=252&amp;amp;face=0_0_800_252,https://scrap.kakaocdn.net/dn/hvaQF/hyPY6utcce/yrC7zxoACQ7kKHHWwSzZuK/img.png?width=1255&amp;amp;height=636&amp;amp;face=0_0_1255_636');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;FastAPI에서 SQLAlchemy Session 다루는 방법&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;개요 FastAPI는 비동기 프레임워크이다. 내부적으로는 Starlette를 Wrapping한 프레임워크인데 일반적인 동기 프레임워크인 Flask, Django등과는 다른 패러다임을 가지고 있다. 그에 따라 프로덕션 레벨에&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.hides.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>  프로그래밍/Python</category>
      <category>Python</category>
      <category>scoped_session</category>
      <category>SQLAlchemy</category>
      <category>thread local</category>
      <author>피트웨어 제이 (FitwareJay)</author>
      <guid isPermaLink="true">https://jay-ji.tistory.com/114</guid>
      <comments>https://jay-ji.tistory.com/114#entry114comment</comments>
      <pubDate>Sat, 1 Oct 2022 02:23:10 +0900</pubDate>
    </item>
    <item>
      <title>RabbitMQ 톺아보기 2부 (feat.pika)</title>
      <link>https://jay-ji.tistory.com/113</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;a href=&quot;https://jay-ji.tistory.com/112&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;RabbitMQ 톺아보기 1부&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;에 이어서 2부를 시작하겠습니다!&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1662990427049&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;RabbitMQ 톺아보기 1부&quot; data-og-description=&quot;안녕하세요! 개발자 Jay입니다! 최근에 저의 관심사는 Event-driven, MSA입니다. 아무래도 MSA의 문제가 서비스가 잦은 호출로 인한 네트워크 과부하, 데이터 정합성, 트랜잭션 등에 문제가 있다 보니 E&quot; data-og-host=&quot;jay-ji.tistory.com&quot; data-og-source-url=&quot;https://jay-ji.tistory.com/112&quot; data-og-url=&quot;https://jay-ji.tistory.com/112&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bxQ8dz/hyPLgEK6Gb/M0ii1YI7iCECwJbSk3ye4K/img.png?width=420&amp;amp;height=420&amp;amp;face=0_0_420_420,https://scrap.kakaocdn.net/dn/95gmj/hyPLjVNDX2/U4ffImYViusUlFJkpL7rQ1/img.png?width=420&amp;amp;height=420&amp;amp;face=0_0_420_420,https://scrap.kakaocdn.net/dn/cuHK0h/hyPLqHo1Ce/kJ8uGdkw9vxLcTvkTjIBk1/img.png?width=698&amp;amp;height=526&amp;amp;face=83_101_622_374&quot;&gt;&lt;a href=&quot;https://jay-ji.tistory.com/112&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jay-ji.tistory.com/112&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bxQ8dz/hyPLgEK6Gb/M0ii1YI7iCECwJbSk3ye4K/img.png?width=420&amp;amp;height=420&amp;amp;face=0_0_420_420,https://scrap.kakaocdn.net/dn/95gmj/hyPLjVNDX2/U4ffImYViusUlFJkpL7rQ1/img.png?width=420&amp;amp;height=420&amp;amp;face=0_0_420_420,https://scrap.kakaocdn.net/dn/cuHK0h/hyPLqHo1Ce/kJ8uGdkw9vxLcTvkTjIBk1/img.png?width=698&amp;amp;height=526&amp;amp;face=83_101_622_374');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;RabbitMQ 톺아보기 1부&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;안녕하세요! 개발자 Jay입니다! 최근에 저의 관심사는 Event-driven, MSA입니다. 아무래도 MSA의 문제가 서비스가 잦은 호출로 인한 네트워크 과부하, 데이터 정합성, 트랜잭션 등에 문제가 있다 보니 E&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;jay-ji.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;2부에서는 실제 python application으로 &lt;b&gt;RabbitMQ&lt;/b&gt;를 활용하는 방법에 대해 알아보려고 합니다. &lt;b&gt;pika&lt;/b&gt;라는 라이브러리를 활용할 예정이에요!&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2056&quot; data-origin-height=&quot;1784&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5vOW7/btrMke6k4Wv/E0TQz9NgJxXTszzqmJLlpK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5vOW7/btrMke6k4Wv/E0TQz9NgJxXTszzqmJLlpK/img.png&quot; data-alt=&quot;공식 홈페이지에서 다양한 언어로 사용하는 방법이 예제로 나와있네요&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5vOW7/btrMke6k4Wv/E0TQz9NgJxXTszzqmJLlpK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5vOW7%2FbtrMke6k4Wv%2FE0TQz9NgJxXTszzqmJLlpK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;587&quot; height=&quot;509&quot; data-origin-width=&quot;2056&quot; data-origin-height=&quot;1784&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;공식 홈페이지에서 다양한 언어로 사용하는 방법이 예제로 나와있네요&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;pika는 RabbitMQ 공식 홈페이지 듀토리얼에서도 사용되는 라이브러리입니다! &lt;a href=&quot;https://www.rabbitmq.com/getstarted.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;공식홈페이지&lt;/b&gt;&lt;/span&gt;&lt;/a&gt;에 보면 다양한 언어에 대해 친절하게 예제들이 만들어져 있습니다! RabbitMQ 듀토리얼과 pika공식문서가 진짜 잘 나와 있어서 여길 보시는 게 제일 좋은 것 같아요! 일단 그냥 속성으로 아 이렇게 쓰구나 정도로 제 글을 보시면 될 것 같습니다!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;1. pika란?&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;262&quot; data-origin-height=&quot;192&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dqNrBA/btrLZQwyDNg/uefgegzckARhfe1Xd4sjxK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dqNrBA/btrLZQwyDNg/uefgegzckARhfe1Xd4sjxK/img.jpg&quot; data-alt=&quot;pika pika pika~~chu~&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dqNrBA/btrLZQwyDNg/uefgegzckARhfe1Xd4sjxK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdqNrBA%2FbtrLZQwyDNg%2FuefgegzckARhfe1Xd4sjxK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;262&quot; height=&quot;192&quot; data-origin-width=&quot;262&quot; data-origin-height=&quot;192&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;pika pika pika~~chu~&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;피카(pika)란 &lt;b&gt;피카 피카 피카츄~~~&lt;/b&gt;백만볼트를 사용하는 라이브러리...&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;259&quot; data-origin-height=&quot;194&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beL4H1/btrLOgcO9hx/B8FlRkau14p7yM26RxjpJK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/beL4H1/btrLOgcO9hx/B8FlRkau14p7yM26RxjpJK/img.jpg&quot; data-alt=&quot;미안합니다...&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/beL4H1/btrLOgcO9hx/B8FlRkau14p7yM26RxjpJK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbeL4H1%2FbtrLOgcO9hx%2FB8FlRkau14p7yM26RxjpJK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;259&quot; height=&quot;194&quot; data-origin-width=&quot;259&quot; data-origin-height=&quot;194&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;미안합니다...&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;에헴... &lt;a href=&quot;https://github.com/pika/pika&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;pika&lt;/b&gt;&lt;/span&gt;&lt;/a&gt;는 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;RabbitMQ를 사용할 수 있게 도와주는 python 라이브러리&lt;/b&gt;&lt;/span&gt; 입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1734&quot; data-origin-height=&quot;916&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHmBcl/btrLPdGTuri/S9PB9sITSHUnfrFDdr46m0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHmBcl/btrLPdGTuri/S9PB9sITSHUnfrFDdr46m0/img.png&quot; data-alt=&quot;네 pika는 이런 역할을 하는 라이브러리 입니다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHmBcl/btrLPdGTuri/S9PB9sITSHUnfrFDdr46m0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHmBcl%2FbtrLPdGTuri%2FS9PB9sITSHUnfrFDdr46m0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;582&quot; height=&quot;307&quot; data-origin-width=&quot;1734&quot; data-origin-height=&quot;916&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;네 pika는 이런 역할을 하는 라이브러리 입니다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;앞서 말씀드렸다시피 RabbitMQ 공식 튜도리얼에서도 이 라이브러리를 사용하는 거면 상당히(?) 검증이 되어있는 라이브러리라고 볼 수 있을 것 같습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;먼저 간단히 pika를 이용해서 RabbitMQ 커넥션과 Pub/Sub을 담당하는 모듈을 만들어 보겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;2. Pub/Sub 모듈 만들기&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1696&quot; data-origin-height=&quot;620&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b3kr1T/btrMd5VIs50/w6SOpeNNt4Q7BfzGPw87Yk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b3kr1T/btrMd5VIs50/w6SOpeNNt4Q7BfzGPw87Yk/img.png&quot; data-alt=&quot;pika에서 제공하는 커넥션 어댑터 모듈&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b3kr1T/btrMd5VIs50/w6SOpeNNt4Q7BfzGPw87Yk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb3kr1T%2FbtrMd5VIs50%2Fw6SOpeNNt4Q7BfzGPw87Yk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;657&quot; height=&quot;240&quot; data-origin-width=&quot;1696&quot; data-origin-height=&quot;620&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;pika에서 제공하는 커넥션 어댑터 모듈&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;pika는 동기, 비동기 커넥션 모듈을 제공합니다. 비동기 어댑터에서는 별도의 I/O loop와 콜백 형태의 사용 방식으로 비동기 구현을 할 수 있습니다. pika로 RabbitMQ 커넥션 하는 방법 중 가장 간단하고 쉬운 방법은 &lt;b&gt;BlockingConnection&lt;/b&gt;을 사용해 동기적으로 처리하는 방법입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;일단은 &lt;b&gt;BlockingConnection&lt;/b&gt; 어댑터를 사용해서 &lt;b&gt;Pub/Sub모듈&lt;/b&gt;을 만들고 간단히 테스트 먼저 해보겠습니다. 뒤에서 비동기 어댑터에 대한 내용을 좀 더 자세히 다루도록 할게요!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1528&quot; data-origin-height=&quot;1334&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RjeoA/btrMdSh0LsM/JV6Bw8ChOFMOviMkP7cKH0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RjeoA/btrMdSh0LsM/JV6Bw8ChOFMOviMkP7cKH0/img.png&quot; data-alt=&quot;BasicPikaClient&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RjeoA/btrMdSh0LsM/JV6Bw8ChOFMOviMkP7cKH0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRjeoA%2FbtrMdSh0LsM%2FJV6Bw8ChOFMOviMkP7cKH0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;670&quot; height=&quot;585&quot; data-origin-width=&quot;1528&quot; data-origin-height=&quot;1334&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;BasicPikaClient&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;첫 번째로 &lt;b&gt;BasicPikaClient&lt;/b&gt;라는 클래스를 정의했습니다. 기본적으로 RabbitMQ와의 커넥션을 만들어주는 클래스입니다. PlainCredentals은 말 그대로 인증과 관련된 클래스입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;ConnectionParameters&lt;/b&gt;를 통해 url, host, user, password, port, credentials 등의 값을 BlockingConnection 어댑터로 전달하여 인스턴스를 생성합니다. 생성된 커넥션 객체를 통하여 chnnel을 생성할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1984&quot; data-origin-height=&quot;338&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eAA1ZI/btrMffwxLLM/Swr5QF3jOMCRfzWAD3Ko51/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eAA1ZI/btrMffwxLLM/Swr5QF3jOMCRfzWAD3Ko51/img.png&quot; data-alt=&quot;chnnel 설명&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eAA1ZI/btrMffwxLLM/Swr5QF3jOMCRfzWAD3Ko51/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeAA1ZI%2FbtrMffwxLLM%2FSwr5QF3jOMCRfzWAD3Ko51%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1984&quot; height=&quot;338&quot; data-origin-width=&quot;1984&quot; data-origin-height=&quot;338&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;chnnel 설명&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;chnnel은 간단히 말하자면 &lt;b&gt;&quot;단일 TCP 연결을 공유하는 경량화된 연결&quot;&lt;/b&gt;이라고 합니다. 뭐 TCP연결을 여러 개 만들어서 사용하면 리소스 낭비니까 하나의 TCP 연결에 여러 개의 chnnel을 만들어서 공유한다는 의미인 것 같습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;주의사항으로는 &lt;b&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;멀티 프로세스, 스레드인 경우 chnnel을 공유하지 말고 새로운 각 프로세스, 스레드마다 새로운 chnnel을 만들어서 사용하는 것이 일반적&lt;/span&gt;&lt;/b&gt;이라고 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;좀 더 자세한 chnnel에 대한 설명은 &lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://www.rabbitmq.com/channels.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;여기서&lt;/a&gt;&lt;/span&gt;&lt;/b&gt; 확인하시길 바라요!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;기본적인 커넥션에 대한 클래스를 생성했으니 publisher, consumer 클래스를 만들어 보겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1726&quot; data-origin-height=&quot;1004&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8XuK5/btrMej0wGJv/AYP0aFz1N8WvOeXoII3KQ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8XuK5/btrMej0wGJv/AYP0aFz1N8WvOeXoII3KQ0/img.png&quot; data-alt=&quot;이벤트 생성 클래스&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8XuK5/btrMej0wGJv/AYP0aFz1N8WvOeXoII3KQ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8XuK5%2FbtrMej0wGJv%2FAYP0aFz1N8WvOeXoII3KQ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1726&quot; height=&quot;1004&quot; data-origin-width=&quot;1726&quot; data-origin-height=&quot;1004&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이벤트 생성 클래스&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;코드를 보면 queue, exchange를 선언하는 메소드와 메세지를 publish 하는 메소드가 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1760&quot; data-origin-height=&quot;1004&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/B6IX2/btrMe7ejBUP/ssLl0P4K6obdHyed8KaoU0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/B6IX2/btrMe7ejBUP/ssLl0P4K6obdHyed8KaoU0/img.png&quot; data-alt=&quot;이벤트 소비 클래스&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/B6IX2/btrMe7ejBUP/ssLl0P4K6obdHyed8KaoU0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FB6IX2%2FbtrMe7ejBUP%2FssLl0P4K6obdHyed8KaoU0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1760&quot; height=&quot;1004&quot; data-origin-width=&quot;1760&quot; data-origin-height=&quot;1004&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이벤트 소비 클래스&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;이벤트를 소비하는 클래스에서는 하나의 메세지만 처리하는 메소드, 메세지를 계속 소비하는 메소드 두 가지가 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;여기서 주의해서 봐야 할 건 basic_consume의 &lt;b&gt;auto_ack&lt;/b&gt;파라미터 인데요. 말 그대로 &lt;b&gt;acknowledgement&lt;/b&gt;를 자동으로 처리할 건지에 대한 옵션입니다. True인 경우 자동으로 처리해주고 아닌 경우 사용자가 직접 ack에 대한 처리를 해줘야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;여기서 ack에 대한 처리란 RabbitMQ로 ack를 보내줘야 한다는 의미입니다. 메세지에 대한 callback을 마지막까지 잘 처리했다는 걸 보장하는 의미입니다. 중간에 로직이 잘못되어 실행이 안 되는 경우 다시 이 메세지를 소비해야 하기 때문입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;688&quot; data-origin-height=&quot;322&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cfMBlv/btrMglC9G0r/Q4QZNrHzKdhFG7fqtdkjp0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cfMBlv/btrMglC9G0r/Q4QZNrHzKdhFG7fqtdkjp0/img.png&quot; data-alt=&quot;auto_ack=False&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cfMBlv/btrMglC9G0r/Q4QZNrHzKdhFG7fqtdkjp0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcfMBlv%2FbtrMglC9G0r%2FQ4QZNrHzKdhFG7fqtdkjp0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;312&quot; height=&quot;146&quot; data-origin-width=&quot;688&quot; data-origin-height=&quot;322&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;auto_ack=False&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;auto_ack가 False일때 메시지를 모두 처리하고 ack를 RabbitMQ로 전달하지 않은경우 위 처럼 메시지가 삭제되지 않고 Unacked에 남아있게 됩니다. 이때 실행중인 consumer를 중지하면 Ready로 메세지가 이동합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1132&quot; data-origin-height=&quot;1072&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KDiH6/btrMdEYJ8sy/JyAUieo0CvbJ0zkJ5ry251/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KDiH6/btrMdEYJ8sy/JyAUieo0CvbJ0zkJ5ry251/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KDiH6/btrMdEYJ8sy/JyAUieo0CvbJ0zkJ5ry251/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKDiH6%2FbtrMdEYJ8sy%2FJyAUieo0CvbJ0zkJ5ry251%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;537&quot; height=&quot;509&quot; data-origin-width=&quot;1132&quot; data-origin-height=&quot;1072&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;start_consuming()은모든 consumer들이 canceld 될 때까지 &lt;b&gt;I/O events, dispatchers timers, 'basic_consume' callback 등을&lt;/b&gt; 처리한다고 합니다. while문을 돌다가 채널이 close 되면 rasie 호출되면서 종료되는 형태로 보입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1674&quot; data-origin-height=&quot;1436&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ruod9/btrMcQymfGH/oq957cm9dFRcS7fRQoONcK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ruod9/btrMcQymfGH/oq957cm9dFRcS7fRQoONcK/img.png&quot; data-alt=&quot;flush_output()에서 ioloop pulling을 하고 있다&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ruod9/btrMcQymfGH/oq957cm9dFRcS7fRQoONcK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fruod9%2FbtrMcQymfGH%2Foq957cm9dFRcS7fRQoONcK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;716&quot; height=&quot;614&quot; data-origin-width=&quot;1674&quot; data-origin-height=&quot;1436&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;flush_output()에서 ioloop pulling을 하고 있다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2116&quot; data-origin-height=&quot;282&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PIFFD/btrMgRhCYI9/ddltNbUr9kvCg5DhNkAlLk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PIFFD/btrMgRhCYI9/ddltNbUr9kvCg5DhNkAlLk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PIFFD/btrMgRhCYI9/ddltNbUr9kvCg5DhNkAlLk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPIFFD%2FbtrMgRhCYI9%2FddltNbUr9kvCg5DhNkAlLk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2116&quot; height=&quot;282&quot; data-origin-width=&quot;2116&quot; data-origin-height=&quot;282&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;내부적으로 어떻게 되나 궁금해서 좀 더 파보았는데... 계속 event를 polling 하여 처리할 event가 있는지 확인합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1894&quot; data-origin-height=&quot;1934&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ekkVd7/btrMgmhNFan/ziXdhb8hCFCflLfBZ7lmzK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ekkVd7/btrMgmhNFan/ziXdhb8hCFCflLfBZ7lmzK/img.png&quot; data-alt=&quot;deque에 저장되어있는 이벤트들&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ekkVd7/btrMgmhNFan/ziXdhb8hCFCflLfBZ7lmzK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FekkVd7%2FbtrMgmhNFan%2FziXdhb8hCFCflLfBZ7lmzK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;751&quot; height=&quot;767&quot; data-origin-width=&quot;1894&quot; data-origin-height=&quot;1934&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;deque에 저장되어있는 이벤트들&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt; event가 존재하면 basic_consum()의 on_messge_callback 파라미터로 넘겨준 함수가 callback으로 실행됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/boWyll/btrMgmB5Py5/fLJNMhjtpXhv0yr0fUBXYk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/boWyll/btrMgmB5Py5/fLJNMhjtpXhv0yr0fUBXYk/img.png&quot; data-origin-width=&quot;1246&quot; data-origin-height=&quot;840&quot; data-is-animation=&quot;false&quot; width=&quot;590&quot; height=&quot;398&quot; style=&quot;width: 53.6172%; margin-right: 10px;&quot; data-widthpercent=&quot;54.25&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/boWyll/btrMgmB5Py5/fLJNMhjtpXhv0yr0fUBXYk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FboWyll%2FbtrMgmB5Py5%2FfLJNMhjtpXhv0yr0fUBXYk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1246&quot; height=&quot;840&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cy2UDY/btrMd2kxxW0/cNB4RokqsmxynYgFN00TaK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cy2UDY/btrMd2kxxW0/cNB4RokqsmxynYgFN00TaK/img.png&quot; data-origin-width=&quot;1226&quot; data-origin-height=&quot;980&quot; data-is-animation=&quot;false&quot; width=&quot;489&quot; height=&quot;391&quot; style=&quot;width: 45.22%;&quot; data-widthpercent=&quot;45.75&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cy2UDY/btrMd2kxxW0/cNB4RokqsmxynYgFN00TaK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcy2UDY%2FbtrMd2kxxW0%2FcNB4RokqsmxynYgFN00TaK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1226&quot; height=&quot;980&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;소켓에서 데이터를 읽어들여서 프로토콜로 전달&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;근본적으로 RabbtMQ에서 데이터를 어떻게 받아오는지 보고 싶어서 좀 더 들여다보았는데요! &lt;/span&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;on_socket_readable&lt;/b&gt; 메소드의 설명을 보면 &lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;소켓에서 데이터를 수집하고 예외가 발생하거나(일반적으로 EAGAIN 또는 EWOULDBLOCK), 이벤트별 데이터 소비 제한에 도달하거나, 전송이 비활성화되거나, 실패할 때까지 데이터를 프로토콜에 전달합니다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;라고 하네요.&amp;nbsp; 당연한 거긴 하지만 결국 모든 것은 소켓을 통해...ㅎㅎ&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;3. 메세지 생성 및 소비 테스트&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;1초 간격으로 메세지를 계속 생성하고, 그 메세지를 소비하는 예제를 만들어 보겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bsL4Tf/btrMcRRziqF/U1XRz3xWy5FK1QkXticKSK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bsL4Tf/btrMcRRziqF/U1XRz3xWy5FK1QkXticKSK/img.png&quot; data-origin-width=&quot;1708&quot; data-origin-height=&quot;1446&quot; data-is-animation=&quot;false&quot; style=&quot;width: 47.2325%; margin-right: 10px;&quot; data-widthpercent=&quot;47.79&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bsL4Tf/btrMcRRziqF/U1XRz3xWy5FK1QkXticKSK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbsL4Tf%2FbtrMcRRziqF%2FU1XRz3xWy5FK1QkXticKSK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1708&quot; height=&quot;1446&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/m3hEL/btrMfEQyjcZ/RBrdGnC51kzwKq3OKORuXk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/m3hEL/btrMfEQyjcZ/RBrdGnC51kzwKq3OKORuXk/img.png&quot; data-origin-width=&quot;1608&quot; data-origin-height=&quot;1246&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;52.21&quot; style=&quot;width: 51.6047%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/m3hEL/btrMfEQyjcZ/RBrdGnC51kzwKq3OKORuXk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fm3hEL%2FbtrMfEQyjcZ%2FRBrdGnC51kzwKq3OKORuXk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1608&quot; height=&quot;1246&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;(좌) 1초 간격으로 메세지를 publish (우) 메세지를 소비&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;저는 exchange를 topic타입으로 설정해서 테스트했습니다. 위 두 프로그램을 실행시키면 아래처럼 동작을 하게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1802&quot; data-origin-height=&quot;994&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Vqysz/btrMgmRk3XJ/hpkgzjIfmgx3v4aW9hA8M1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Vqysz/btrMgmRk3XJ/hpkgzjIfmgx3v4aW9hA8M1/img.png&quot; data-alt=&quot;메세지를 publish 하고 consum 하는 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Vqysz/btrMgmRk3XJ/hpkgzjIfmgx3v4aW9hA8M1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVqysz%2FbtrMgmRk3XJ%2FhpkgzjIfmgx3v4aW9hA8M1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;611&quot; height=&quot;337&quot; data-origin-width=&quot;1802&quot; data-origin-height=&quot;994&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;메세지를 publish 하고 consum 하는 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;RabbitMQ GUI에서 보면 현재 상태는 이렇습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1896&quot; data-origin-height=&quot;846&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lCphr/btrMhXDDx26/SYb52ecoIftMF2OxMEnKQK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lCphr/btrMhXDDx26/SYb52ecoIftMF2OxMEnKQK/img.png&quot; data-alt=&quot;publisher, consumer 두개의 커넥션이 연결된 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lCphr/btrMhXDDx26/SYb52ecoIftMF2OxMEnKQK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlCphr%2FbtrMhXDDx26%2FSYb52ecoIftMF2OxMEnKQK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;654&quot; height=&quot;292&quot; data-origin-width=&quot;1896&quot; data-origin-height=&quot;846&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;publisher, consumer 두개의 커넥션이 연결된 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2704&quot; data-origin-height=&quot;670&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNv3Ir/btrMi5HDrs9/eKfng5LYj1fsmFmaNoMZR1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNv3Ir/btrMi5HDrs9/eKfng5LYj1fsmFmaNoMZR1/img.png&quot; data-alt=&quot;두개의 채널 (publisher, consumer)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNv3Ir/btrMi5HDrs9/eKfng5LYj1fsmFmaNoMZR1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNv3Ir%2FbtrMi5HDrs9%2FeKfng5LYj1fsmFmaNoMZR1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2704&quot; height=&quot;670&quot; data-origin-width=&quot;2704&quot; data-origin-height=&quot;670&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;두개의 채널 (publisher, consumer)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3232&quot; data-origin-height=&quot;2036&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BiTY3/btrMjcNqQEZ/Lk2f5VHbuzWUEH4n0byNGk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BiTY3/btrMjcNqQEZ/Lk2f5VHbuzWUEH4n0byNGk/img.png&quot; data-alt=&quot;Queue에서 메세지의 소비와 어떤 cuonsumer가 연결되었는지 확인할 수 있음&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BiTY3/btrMjcNqQEZ/Lk2f5VHbuzWUEH4n0byNGk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBiTY3%2FbtrMjcNqQEZ%2FLk2f5VHbuzWUEH4n0byNGk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3232&quot; height=&quot;2036&quot; data-origin-width=&quot;3232&quot; data-origin-height=&quot;2036&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Queue에서 메세지의 소비와 어떤 cuonsumer가 연결되었는지 확인할 수 있음&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;a href=&quot;https://github.com/JAY-Chan9yu/rabbitmq-python-event/tree/master/blocking-connection-example&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;예제코드&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1663414075516&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - JAY-Chan9yu/rabbitmq-python-event&quot; data-og-description=&quot;Contribute to JAY-Chan9yu/rabbitmq-python-event development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/JAY-Chan9yu/rabbitmq-python-event/tree/master/blocking-connection-example&quot; data-og-url=&quot;https://github.com/JAY-Chan9yu/rabbitmq-python-event&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/fGjaq/hyPOMRuyt2/kwSMmJw657KgSlnSnWmfh0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/JAY-Chan9yu/rabbitmq-python-event/tree/master/blocking-connection-example&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/JAY-Chan9yu/rabbitmq-python-event/tree/master/blocking-connection-example&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/fGjaq/hyPOMRuyt2/kwSMmJw657KgSlnSnWmfh0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - JAY-Chan9yu/rabbitmq-python-event&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Contribute to JAY-Chan9yu/rabbitmq-python-event development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;4. 비동기 어댑터 (Asynchronous adapter)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1696&quot; data-origin-height=&quot;620&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b3kr1T/btrMd5VIs50/w6SOpeNNt4Q7BfzGPw87Yk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b3kr1T/btrMd5VIs50/w6SOpeNNt4Q7BfzGPw87Yk/img.png&quot; data-alt=&quot;pika에서 제공하는 커넥션 어댑터 모듈&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b3kr1T/btrMd5VIs50/w6SOpeNNt4Q7BfzGPw87Yk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb3kr1T%2FbtrMd5VIs50%2Fw6SOpeNNt4Q7BfzGPw87Yk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;657&quot; height=&quot;240&quot; data-origin-width=&quot;1696&quot; data-origin-height=&quot;620&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;pika에서 제공하는 커넥션 어댑터 모듈&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;위에서 잠시 설명했던 비동기 어댑터에 대해서 설명해보겠습니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1580&quot; data-origin-height=&quot;564&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/D9Fel/btrMgQLEycK/j1B9iqKDFxtkmfHntufAl0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/D9Fel/btrMgQLEycK/j1B9iqKDFxtkmfHntufAl0/img.png&quot; data-alt=&quot;BlockingConnection의 설명&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/D9Fel/btrMgQLEycK/j1B9iqKDFxtkmfHntufAl0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FD9Fel%2FbtrMgQLEycK%2Fj1B9iqKDFxtkmfHntufAl0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;630&quot; height=&quot;225&quot; data-origin-width=&quot;1580&quot; data-origin-height=&quot;564&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;BlockingConnection의 설명&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;blocking connection adapter 모듈은 Pika의 핵심 AMQP 드라이버 위에&amp;nbsp;blocking&amp;nbsp;semantics을&amp;nbsp;구현합니다.&amp;nbsp;&lt;br /&gt;blocking&amp;nbsp;connection&amp;nbsp;adapter를&amp;nbsp;사용할&amp;nbsp;때&amp;nbsp;대부분의&amp;nbsp;비동기식&amp;nbsp;예상(asynchronous&amp;nbsp;expectations)이&amp;nbsp;제거되지만,&lt;br /&gt;서버에서 보낸 RPC 명령의 지원,&amp;nbsp;AMQP&amp;nbsp;프로토콜의&amp;nbsp;비동기식&amp;nbsp;RPC&amp;nbsp;특성에&amp;nbsp;충실하려고&amp;nbsp;시도합니다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;공식문서 설명을 번역한 건데 정확히 맞는 표현인지는 조금 애매하지만, 결론적으로는 동기적(synchronous)으로 브로커(RabbitMQ)로부터 받은 message를 소비하는 모듈입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;그럼 비동기적으로 처리하는 방법이 있다는 건데 위에서 보다시피&lt;b&gt; AsyncConnection, SelectConnection, GeventConnection, TornadoConnection, TwistedProtocolConnection&lt;/b&gt;이 비동기적으로 event를 처리하는 어댑터들입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;비동기 커넥션 어댑터들은 BlockingConnection과는 다르게 별도의&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt; I/O loop와 콜백 형태의 문법을 통해 비동기적으로 event를 처리&lt;/b&gt;&lt;/span&gt;할 수 있습니다. 콜백형태의 문법이라 다소 파이써닉하지 않고 복잡하다고 하네요ㅎㅎ&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;이렇게 글로 보는 것보다는 코드로 한번 확인하는 게 좋을 것 같습니다! 저는 &lt;b&gt;AsyncConnection&lt;/b&gt;을 사용해서 설명드리겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;(영문으로 정확한 내용을 파악하시려면 &lt;a href=&quot;https://pika.readthedocs.io/en/stable/modules/adapters/index.html#adapters&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;공식문서&lt;/b&gt;&lt;/span&gt;&lt;/a&gt;를 보시길 추천드립니다!)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;publishing 하는 모듈은 동기로 그냥 사용하도록 하겠습니다. 비동기로 메세지를 소비하는 예제를 보겠습니다!&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2046&quot; data-origin-height=&quot;2086&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EFyRx/btrMgmjFGqL/28MdnFBbSQwF3SWoflr0V1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EFyRx/btrMgmjFGqL/28MdnFBbSQwF3SWoflr0V1/img.png&quot; data-alt=&quot;비동기적으로 메세지를 소비하는 예제&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EFyRx/btrMgmjFGqL/28MdnFBbSQwF3SWoflr0V1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEFyRx%2FbtrMgmjFGqL%2F28MdnFBbSQwF3SWoflr0V1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2046&quot; height=&quot;2086&quot; data-origin-width=&quot;2046&quot; data-origin-height=&quot;2086&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;비동기적으로 메세지를 소비하는 예제&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;main 함수에서 gather()를 통해 코루틴(random_task)을 실행시킵니다. 또 create_task()로 do_rabbitmq()를 schedule 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1456&quot; data-origin-height=&quot;1164&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PvOHi/btrMjEv4vYc/hpsYxcLizT3MsmSN2t4vHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PvOHi/btrMjEv4vYc/hpsYxcLizT3MsmSN2t4vHk/img.png&quot; data-alt=&quot;AsyncioConnection을 사용한는 RabbitMQ 커넥션 모듈&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PvOHi/btrMjEv4vYc/hpsYxcLizT3MsmSN2t4vHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPvOHi%2FbtrMjEv4vYc%2FhpsYxcLizT3MsmSN2t4vHk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;636&quot; height=&quot;508&quot; data-origin-width=&quot;1456&quot; data-origin-height=&quot;1164&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;AsyncioConnection을 사용한는 RabbitMQ 커넥션 모듈&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;AsyncioConnection&lt;/b&gt;으로 커넥션을 생성하는 모듈을 만들었습니다. 중요 코드만 설명하고 전체 코드는 깃헙을 참고해주시길 바랍니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;생성자에서 새로운 &lt;b&gt;이벤트 루프(new_event_loop())&lt;/b&gt;를 만들어서 &lt;b&gt;AyncioConnection&lt;/b&gt;의 &lt;b&gt;custom_ioloop&lt;/b&gt;로 전달합니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1748&quot; data-origin-height=&quot;1716&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/chen9C/btrMmg92y1G/STiq3bNIYe2OkKkk1B77R1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/chen9C/btrMmg92y1G/STiq3bNIYe2OkKkk1B77R1/img.png&quot; data-alt=&quot;AsyncioConnection 으로 cusuming 하는 테스트&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/chen9C/btrMmg92y1G/STiq3bNIYe2OkKkk1B77R1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fchen9C%2FbtrMmg92y1G%2FSTiq3bNIYe2OkKkk1B77R1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1748&quot; height=&quot;1716&quot; data-origin-width=&quot;1748&quot; data-origin-height=&quot;1716&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;AsyncioConnection 으로 cusuming 하는 테스트&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;참고 (요건 코드를 커스텀 해서 사용하는 부분에 대한 저의 개인적인 의견 - 정확하지 않을 수 있습니다)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;새로운 event loop를 만든 이유는 공개할 소스코드를 보면 확인할 수 있습니다만, 간략히 설명드리자면...&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1382&quot; data-origin-height=&quot;566&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b3I1y4/btrMjhutOZq/l9lwfmNaumfyayrDx55MzK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b3I1y4/btrMjhutOZq/l9lwfmNaumfyayrDx55MzK/img.png&quot; data-alt=&quot;RabbitMQConnection 클래스의 start 메소드&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b3I1y4/btrMjhutOZq/l9lwfmNaumfyayrDx55MzK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb3I1y4%2FbtrMjhutOZq%2Fl9lwfmNaumfyayrDx55MzK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;538&quot; height=&quot;220&quot; data-origin-width=&quot;1382&quot; data-origin-height=&quot;566&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;RabbitMQConnection 클래스의 start 메소드&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;코드에 RabbitMQ 커넥션을 시작하는 start 메소드가 있는데 여기서 새로운 스레드를 만들고 event loop를 &lt;b&gt;run_forever()&lt;/b&gt;로 running 시키기 때문입니다. 만약 이 상태에서 &lt;b&gt;RabbitMQConnection&lt;/b&gt;클래스의 생성자에서 &lt;b&gt;get_event_loop()&lt;/b&gt;를 사용하면 &lt;b&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;main thread의 evnet loop를 가져오게 되고 이미 running중인 event loop를 재실행하려고 해서 RuntimeError가 납니다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1754&quot; data-origin-height=&quot;356&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bTHPo1/btrMlV5I5Lp/du6y0ZXQVVnHwlghjHaYr1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bTHPo1/btrMlV5I5Lp/du6y0ZXQVVnHwlghjHaYr1/img.png&quot; data-alt=&quot;main thread의 event loop를 다시 running시키려고 해서 오류&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bTHPo1/btrMlV5I5Lp/du6y0ZXQVVnHwlghjHaYr1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbTHPo1%2FbtrMlV5I5Lp%2Fdu6y0ZXQVVnHwlghjHaYr1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;604&quot; height=&quot;123&quot; data-origin-width=&quot;1754&quot; data-origin-height=&quot;356&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;main thread의 event loop를 다시 running시키려고 해서 오류&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;그래서 main thread의 event loop를 사용해서 rabbitmq consumer를 비동기로 처리하고 싶다고 하시면 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;RabbitMQConnection의 start 메소드를 실행하지 않고 생성자에서 get_event_loop()를 호출&lt;/b&gt;&lt;/span&gt;하면 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2316&quot; data-origin-height=&quot;700&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kM2RG/btrMjm413mA/KE2ku6X9roulNTXFhOFKwk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kM2RG/btrMjm413mA/KE2ku6X9roulNTXFhOFKwk/img.png&quot; data-alt=&quot;요런 느낌?!&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kM2RG/btrMjm413mA/KE2ku6X9roulNTXFhOFKwk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkM2RG%2FbtrMjm413mA%2FKE2ku6X9roulNTXFhOFKwk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2316&quot; height=&quot;700&quot; data-origin-width=&quot;2316&quot; data-origin-height=&quot;700&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;요런 느낌?!&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;저도 참고한 코드라 처음 작성자의 의도는 모르겠지만... main thread가 아닌 새로운 thread의 event loop를 사용하려는 이유를 추측해 보자면 애초에 &lt;b&gt;하나의 thread(or process)에 하나의 chnnel을 권장&lt;/b&gt;하기도 하고 &lt;b&gt;main thread의 event loop를 그대로 사용하면 main에서 사용하는 다른 event들과 pika에서 처리하는 event들이 같은 event loop에서 처리되기 때문에 작업이 겹치는(?) 상황이라 이런 부분이 조금 어색하기 때문&lt;/b&gt;이지 않나 생각됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;결론은 &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&amp;nbsp;용도, 역할별로 별도의 event loop를 만들어서 사용하자라는 의미로 새로운 thread에 새로운 event loop를 사용하지 않았을까&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&amp;nbsp;그리고 main은 main대로 pika는 pika대로 따로 처리해야 하기 때문에&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;저는 이런 의미라고 이해하고 사용했습니다. (&lt;span style=&quot;color: #ee2323;&quot;&gt;혹시나 다른 의견이 있으시다면 댓글로 남겨주세요!&lt;/span&gt;)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://github.com/JAY-Chan9yu/rabbitmq-python-event/tree/master/async-connection-example&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;예제코드&lt;/a&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1663414113276&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - JAY-Chan9yu/rabbitmq-python-event&quot; data-og-description=&quot;Contribute to JAY-Chan9yu/rabbitmq-python-event development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/JAY-Chan9yu/rabbitmq-python-event/tree/master/async-connection-example&quot; data-og-url=&quot;https://github.com/JAY-Chan9yu/rabbitmq-python-event&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bdOImh/hyPOFkyWKz/7xYZOrhbzC4BrqGNtSe9sk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/JAY-Chan9yu/rabbitmq-python-event/tree/master/async-connection-example&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/JAY-Chan9yu/rabbitmq-python-event/tree/master/async-connection-example&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bdOImh/hyPOFkyWKz/7xYZOrhbzC4BrqGNtSe9sk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - JAY-Chan9yu/rabbitmq-python-event&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Contribute to JAY-Chan9yu/rabbitmq-python-event development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;5. pika 문서를 보면서 잘 모르던 단어&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;문서를 보면서 잘 모르지만 중요한 거 같은 단어들에 대해서 정리해보려고 합니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;첫 번째는 RPC입니다!&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;여기서 말하는 RPC는 gRPC의 RPC와 동일한 개념인데요. &lt;b&gt;RPC(Remote Procedure Call)&lt;/b&gt;란 간단하게 Client는 Request를 Server에 전달하고 Server는 해당 Request를 처리하여 알맞은 결과 값을 다시 Client에 Response 해주는 방법이라고 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;두 번째는 CPS(continuation-passing style)입니다!&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2406&quot; data-origin-height=&quot;1282&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b3SJxF/btrMlkYYdbb/3hLraKIXfvqT8N1TmpIoe1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b3SJxF/btrMlkYYdbb/3hLraKIXfvqT8N1TmpIoe1/img.png&quot; data-alt=&quot;CPS로 RabbitMQ 커넥팅 하는 방법&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b3SJxF/btrMlkYYdbb/3hLraKIXfvqT8N1TmpIoe1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb3SJxF%2FbtrMlkYYdbb%2F3hLraKIXfvqT8N1TmpIoe1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2406&quot; height=&quot;1282&quot; data-origin-width=&quot;2406&quot; data-origin-height=&quot;1282&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;CPS로 RabbitMQ 커넥팅 하는 방법&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;pika문서를 보다 보면 CPS에 대한 언급이 자주 나오는데요. CPS 코딩 패턴은&lt;b&gt; 함수 실행이 끝남과 동시에 연이어 함수가 또 실행되는 프로그래밍 모델로 callback형태의 스타일&lt;/b&gt;을 말합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;CPS에 대한 자세한 설명은 아래 블로그를 참고하시길 바랍니다!&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1663413250680&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;백엔드 개발자들이 알아야할 동시성 5 &amp;mdash; Continuation Passing Style&quot; data-og-description=&quot;협력적 스케줄링을 구현하기 위해서는 다양한 방법을 사용할 수 있습니다. 다양한 프로그래밍 언어에서 지향하는 다양한 철학에 따라 여러가지 구현 방법이 있을 수 있죠. 오늘은 협력적 스케&quot; data-og-host=&quot;choi-geonu.medium.com&quot; data-og-source-url=&quot;https://choi-geonu.medium.com/%EB%B0%B1%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%EC%9E%90%EB%93%A4%EC%9D%B4-%EC%95%8C%EC%95%84%EC%95%BC%ED%95%A0-%EB%8F%99%EC%8B%9C%EC%84%B1-5-continuation-passing-style-5058ab5cb781&quot; data-og-url=&quot;https://choi-geonu.medium.com/%EB%B0%B1%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%EC%9E%90%EB%93%A4%EC%9D%B4-%EC%95%8C%EC%95%84%EC%95%BC%ED%95%A0-%EB%8F%99%EC%8B%9C%EC%84%B1-5-continuation-passing-style-5058ab5cb781&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/IpcjA/hyPOFx4O1W/01Z4cKXFkKA73CKKYkPlI0/img.png?width=1200&amp;amp;height=488&amp;amp;face=0_0_1200_488,https://scrap.kakaocdn.net/dn/l8qKw/hyPOHQahJu/DSsmgKZWjNTy6tINbegNfk/img.png?width=1222&amp;amp;height=1242&amp;amp;face=0_0_1222_1242,https://scrap.kakaocdn.net/dn/bZt6tr/hyPOP1LnK9/PcOQspF5ePTu5HA4cOHkxk/img.png?width=1400&amp;amp;height=611&amp;amp;face=0_0_1400_611&quot;&gt;&lt;a href=&quot;https://choi-geonu.medium.com/%EB%B0%B1%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%EC%9E%90%EB%93%A4%EC%9D%B4-%EC%95%8C%EC%95%84%EC%95%BC%ED%95%A0-%EB%8F%99%EC%8B%9C%EC%84%B1-5-continuation-passing-style-5058ab5cb781&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://choi-geonu.medium.com/%EB%B0%B1%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%EC%9E%90%EB%93%A4%EC%9D%B4-%EC%95%8C%EC%95%84%EC%95%BC%ED%95%A0-%EB%8F%99%EC%8B%9C%EC%84%B1-5-continuation-passing-style-5058ab5cb781&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/IpcjA/hyPOFx4O1W/01Z4cKXFkKA73CKKYkPlI0/img.png?width=1200&amp;amp;height=488&amp;amp;face=0_0_1200_488,https://scrap.kakaocdn.net/dn/l8qKw/hyPOHQahJu/DSsmgKZWjNTy6tINbegNfk/img.png?width=1222&amp;amp;height=1242&amp;amp;face=0_0_1222_1242,https://scrap.kakaocdn.net/dn/bZt6tr/hyPOP1LnK9/PcOQspF5ePTu5HA4cOHkxk/img.png?width=1400&amp;amp;height=611&amp;amp;face=0_0_1400_611');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;백엔드 개발자들이 알아야할 동시성 5 &amp;mdash; Continuation Passing Style&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;협력적 스케줄링을 구현하기 위해서는 다양한 방법을 사용할 수 있습니다. 다양한 프로그래밍 언어에서 지향하는 다양한 철학에 따라 여러가지 구현 방법이 있을 수 있죠. 오늘은 협력적 스케&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;choi-geonu.medium.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;6. 마치며&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;pika라이브러리에 대한 설명만 하려고 했는데 Asyncio라던지 RPC, CPS 등 생소한 용어들에 대한 설명도 함께 하려다 보니 다소 길어지기도 하고 정리가 잘 안 되는 부분도 있긴 하네요 ㅎㅎ&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;내용을 pika 동기, 비동기 커넥션 두 가지로 쪼개는 게 좀 더 설명하기 좋았을 텐데... 이렇게 길어질 줄은 몰랐습니다. 그리고 공식문서와 깃헙을 보다보니 영어해석이 좀 난해한 부분이 있어서...영어 공부를 해야겠다는 생각을 했습니다 ㅠㅠ 구글번역으로는 뭔가 확 와닿지 않는 부분도 있고 해석에 자신감이 없으니 좀 더 이해하는데 오래걸리는 것 같기도 하네요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;여튼 여러분들이 pika문서 보시면서 한번 직접 해보시길 바래요! 공식문서에 여러 connection adaptor들을 사용한 예제도 잘 되어있어서 좋더라고요!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;그럼 오늘도 좋은 하루 보내세요!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;참고자료&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://www.rabbitmq.com/documentation.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;RabbitMQ 공식문서&lt;/a&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1663414159179&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Documentation: Table of Contents
 &amp;mdash; RabbitMQ&quot; data-og-description=&quot;Documentation: Table of Contents This page summarises the available RabbitMQ documentation for the latest patch release. Installation See the Downloads and Installation page for information on the most recent release and how to install it. Tutorials See th&quot; data-og-host=&quot;www.rabbitmq.com&quot; data-og-source-url=&quot;https://www.rabbitmq.com/documentation.html&quot; data-og-url=&quot;https://www.rabbitmq.com/documentation.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.rabbitmq.com/documentation.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.rabbitmq.com/documentation.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Documentation: Table of Contents &amp;mdash; RabbitMQ&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Documentation: Table of Contents This page summarises the available RabbitMQ documentation for the latest patch release. Installation See the Downloads and Installation page for information on the most recent release and how to install it. Tutorials See th&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.rabbitmq.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://pika.readthedocs.io/en/stable/index.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;pika 공식문서&lt;/a&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1663414261787&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Introduction to Pika &amp;mdash; pika 1.2.1 documentation&quot; data-og-description=&quot;&amp;copy; Copyright 2009-2017, Tony Garnock-Jones, Gavin M. Roy, Pivotal Software, Inc and contributors. Revision 741cfc4c.&quot; data-og-host=&quot;pika.readthedocs.io&quot; data-og-source-url=&quot;https://pika.readthedocs.io/en/stable/index.html&quot; data-og-url=&quot;https://pika.readthedocs.io/en/stable/index.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://pika.readthedocs.io/en/stable/index.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://pika.readthedocs.io/en/stable/index.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Introduction to Pika &amp;mdash; pika 1.2.1 documentation&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;copy; Copyright 2009-2017, Tony Garnock-Jones, Gavin M. Roy, Pivotal Software, Inc and contributors. Revision 741cfc4c.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;pika.readthedocs.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://github.com/pika/pika/tree/main/examples&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;pika github 예제들&lt;/a&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1663414294602&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - pika/pika: Pure Python RabbitMQ/AMQP 0-9-1 client library&quot; data-og-description=&quot;Pure Python RabbitMQ/AMQP 0-9-1 client library. Contribute to pika/pika development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/pika/pika/tree/main/examples&quot; data-og-url=&quot;https://github.com/pika/pika&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/1on4Z/hyPOSK4HKp/wC51HtZrKpdmBQzQFkrVV1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/pika/pika/tree/main/examples&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/pika/pika/tree/main/examples&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/1on4Z/hyPOSK4HKp/wC51HtZrKpdmBQzQFkrVV1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - pika/pika: Pure Python RabbitMQ/AMQP 0-9-1 client library&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Pure Python RabbitMQ/AMQP 0-9-1 client library. Contribute to pika/pika development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a style=&quot;color: #006dd7;&quot; href=&quot;https://hyos-dev-log.tistory.com/8&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;RabbitMQ connection, chnnel 설명&lt;/a&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1663414316085&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;RabbitMQ의 Connection과 Channel&quot; data-og-description=&quot;사내에서 진행되는 서비스를 개편하게 되면서, RabbitMQ를 사용하게 되었습니다. RabbitMQ을 사용하고, 운영하면서 Connection과 Channel에 대한 개념이 잡히지 않아서 정리하게 되었습니다. Connection 일반&quot; data-og-host=&quot;hyos-dev-log.tistory.com&quot; data-og-source-url=&quot;https://hyos-dev-log.tistory.com/8&quot; data-og-url=&quot;https://hyos-dev-log.tistory.com/8&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/SyO9L/hyPONixs0C/cZkNFqRj2e2phiZGM6lK8k/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/b89J4O/hyPOFkzc0Y/bG4a1UBHVV4kIhK2ljlGIK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://hyos-dev-log.tistory.com/8&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://hyos-dev-log.tistory.com/8&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/SyO9L/hyPONixs0C/cZkNFqRj2e2phiZGM6lK8k/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/b89J4O/hyPOFkzc0Y/bG4a1UBHVV4kIhK2ljlGIK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;RabbitMQ의 Connection과 Channel&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;사내에서 진행되는 서비스를 개편하게 되면서, RabbitMQ를 사용하게 되었습니다. RabbitMQ을 사용하고, 운영하면서 Connection과 Channel에 대한 개념이 잡히지 않아서 정리하게 되었습니다. Connection 일반&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;hyos-dev-log.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;a href=&quot;https://velog.io/@jakeseo_me/RPC%EB%9E%80&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;RPC란&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1663414383820&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;RPC란?&quot; data-og-description=&quot;분산 네트워크 컴퓨터 환경에서 프로그래밍을 쉽게 할 수 있는 방법을 찾다가...Client to Server 패턴Server를 켬Client는 Server에 데이터 혹은 행동을 요청Server는 요청 받은 내용에 대한 응답을 반환Clie&quot; data-og-host=&quot;velog.io&quot; data-og-source-url=&quot;https://velog.io/@jakeseo_me/RPC%EB%9E%80&quot; data-og-url=&quot;https://velog.io/@jakeseo_me/RPC란&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bpSijc/hyPOJ8gFgs/BBz6ScB7Vk2dSa4Sj6523K/img.png?width=791&amp;amp;height=631&amp;amp;face=0_0_791_631,https://scrap.kakaocdn.net/dn/bap1bD/hyPOElF0jW/NzNVsAQrOae5khyllHFkG0/img.png?width=791&amp;amp;height=631&amp;amp;face=0_0_791_631,https://scrap.kakaocdn.net/dn/Y0Uxh/hyPOMqnRjz/rdvm3rzenH8NxVFhG2LR71/img.jpg?width=1280&amp;amp;height=960&amp;amp;face=0_0_1280_960&quot;&gt;&lt;a href=&quot;https://velog.io/@jakeseo_me/RPC%EB%9E%80&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://velog.io/@jakeseo_me/RPC%EB%9E%80&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bpSijc/hyPOJ8gFgs/BBz6ScB7Vk2dSa4Sj6523K/img.png?width=791&amp;amp;height=631&amp;amp;face=0_0_791_631,https://scrap.kakaocdn.net/dn/bap1bD/hyPOElF0jW/NzNVsAQrOae5khyllHFkG0/img.png?width=791&amp;amp;height=631&amp;amp;face=0_0_791_631,https://scrap.kakaocdn.net/dn/Y0Uxh/hyPOMqnRjz/rdvm3rzenH8NxVFhG2LR71/img.jpg?width=1280&amp;amp;height=960&amp;amp;face=0_0_1280_960');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;RPC란?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;분산 네트워크 컴퓨터 환경에서 프로그래밍을 쉽게 할 수 있는 방법을 찾다가...Client to Server 패턴Server를 켬Client는 Server에 데이터 혹은 행동을 요청Server는 요청 받은 내용에 대한 응답을 반환Clie&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;velog.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a href=&quot;https://stackoverflow.com/questions/11987838/which-form-of-connection-to-use-with-pika&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://stackoverflow.com/questions/11987838/which-form-of-connection-to-use-with-pika&lt;/a&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1663414429218&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Which form of connection to use with pika&quot; data-og-description=&quot;I've been trying to figure out which form of connection i should use when using pika, I've got two alternatives as far as I understand. Either the BlockingConnection or the SelectConnection, howev...&quot; data-og-host=&quot;stackoverflow.com&quot; data-og-source-url=&quot;https://stackoverflow.com/questions/11987838/which-form-of-connection-to-use-with-pika&quot; data-og-url=&quot;https://stackoverflow.com/questions/11987838/which-form-of-connection-to-use-with-pika&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dvtEcL/hyPOI9niE2/TjPkmOYdFoNKbfCSOHp2gk/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316&quot;&gt;&lt;a href=&quot;https://stackoverflow.com/questions/11987838/which-form-of-connection-to-use-with-pika&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://stackoverflow.com/questions/11987838/which-form-of-connection-to-use-with-pika&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dvtEcL/hyPOI9niE2/TjPkmOYdFoNKbfCSOHp2gk/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Which form of connection to use with pika&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;I've been trying to figure out which form of connection i should use when using pika, I've got two alternatives as far as I understand. Either the BlockingConnection or the SelectConnection, howev...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;stackoverflow.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;</description>
      <category>  프로그래밍/Python</category>
      <category>PIKA</category>
      <category>Python</category>
      <category>RabbitMQ</category>
      <category>메세지브로커</category>
      <author>피트웨어 제이 (FitwareJay)</author>
      <guid isPermaLink="true">https://jay-ji.tistory.com/113</guid>
      <comments>https://jay-ji.tistory.com/113#entry113comment</comments>
      <pubDate>Sat, 17 Sep 2022 20:47:42 +0900</pubDate>
    </item>
  </channel>
</rss>