<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Ryan Server</title>
    <link>https://interconnection.tistory.com/</link>
    <description>I'm going to write about the server I learned and felt.</description>
    <language>ko</language>
    <pubDate>Sat, 11 Jul 2026 03:49:05 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>RyanGomdoriPooh</managingEditor>
    <image>
      <title>Ryan Server</title>
      <url>https://tistory1.daumcdn.net/tistory/1912174/attach/df4fedb9dbd14ec190310aa3a26b1d02</url>
      <link>https://interconnection.tistory.com</link>
    </image>
    <item>
      <title>Solution : &amp;quot;An error occurred (TargetNotConnected) when calling the StartSession operation: {instance-id} is not connected.&amp;quot;</title>
      <link>https://interconnection.tistory.com/146</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;I&amp;nbsp;have&amp;nbsp;a&amp;nbsp;problem&amp;nbsp;accessing&amp;nbsp;Instance&amp;nbsp;through&amp;nbsp;Session&amp;nbsp;Manager&amp;nbsp;in&amp;nbsp;AWS.&lt;br /&gt;&lt;br /&gt;That&amp;nbsp;message&amp;nbsp;is&amp;nbsp;&quot;An&amp;nbsp;error&amp;nbsp;occurred&amp;nbsp;(TargetNotConnected)&amp;nbsp;when&amp;nbsp;calling&amp;nbsp;the&amp;nbsp;StartSession&amp;nbsp;operation:&amp;nbsp;{instance-id}&amp;nbsp;is&amp;nbsp;not&amp;nbsp;connected.&quot;.&lt;br /&gt;&lt;br /&gt;In&amp;nbsp;this&amp;nbsp;post,&amp;nbsp;We&amp;nbsp;deal&amp;nbsp;with&amp;nbsp;how&amp;nbsp;to&amp;nbsp;solve&amp;nbsp;this&amp;nbsp;problem.&lt;br /&gt;&lt;br /&gt;We entered a command similar to the command below at the local terminal of Mac.&lt;/p&gt;
&lt;pre id=&quot;code_1642649168016&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;aws ssm start-session --target i-123456 --document-name AWS-StartSSHSession --parameters 'portNumber=8373'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;We got this error message.&lt;/p&gt;
&lt;pre id=&quot;code_1642650494513&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;An error occurred (TargetNotConnected) when calling the StartSession operation: i-123456 is not connected.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; letter-spacing: 0px;&quot;&gt;It has two solutions about the&amp;nbsp;error mentioned above.&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;Screen Shot 2022-01-22 at 1.07.39 AM.png&quot; data-origin-width=&quot;1184&quot; data-origin-height=&quot;218&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b7z6JF/btrros439V7/7OCMxI01OEdCjJAg28VkE1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b7z6JF/btrros439V7/7OCMxI01OEdCjJAg28VkE1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b7z6JF/btrros439V7/7OCMxI01OEdCjJAg28VkE1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb7z6JF%2Fbtrros439V7%2F7OCMxI01OEdCjJAg28VkE1%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;1184&quot; height=&quot;218&quot; data-filename=&quot;Screen Shot 2022-01-22 at 1.07.39 AM.png&quot; data-origin-width=&quot;1184&quot; data-origin-height=&quot;218&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: -apple-system, BlinkMacSystemFont, AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; letter-spacing: 0px;&quot;&gt;Eventually, Solutions has common reason. &lt;a href=&quot;https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-troubleshooting.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Link&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;First of all, We have to check settings for &quot;Session Manager&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;&lt;b&gt;Let's check steps of solution.&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. Check instance settings of &quot;Session Manager&quot; to be connected.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-getting-started.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Ref) Settings of Session Manager&lt;/a&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. Check instance settings of &quot;Session Manager&quot; to connect.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html#cli-configure-quickstart-config&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Ref) Settings of CLI&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/using-regions-availability-zones.html&quot;&gt;Ref) Region name&lt;/a&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1642783101316&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ aws configure
AWS Access Key ID [None]: AKIAIOSFODNN7EXAMPLE
AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Default region name [None]: us-west-2
Default output format [None]: json&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;And then, try again this command.&lt;/p&gt;
&lt;pre id=&quot;code_1642783230375&quot; class=&quot;dsconfig&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;aws ssm start-session --target i-123456 --document-name AWS-StartSSHSession --parameters 'portNumber=8373'&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;From now, We can access instance using by Session Manager.&lt;/p&gt;</description>
      <category>AWS</category>
      <author>RyanGomdoriPooh</author>
      <guid isPermaLink="true">https://interconnection.tistory.com/146</guid>
      <comments>https://interconnection.tistory.com/146#entry146comment</comments>
      <pubDate>Thu, 20 Jan 2022 11:53:44 +0900</pubDate>
    </item>
    <item>
      <title>Java User Defined Package Naming Convention (Spring, Android, ...)</title>
      <link>https://interconnection.tistory.com/142</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Overview&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;We usually make package name for Java program.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;But, when we try to name package, we&amp;nbsp;don't&amp;nbsp;know&amp;nbsp;how&amp;nbsp;to&amp;nbsp;name&amp;nbsp;the&amp;nbsp;package.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;In this post, We look what package name is and how to make package name by examples.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;let's look at some principles for package naming convention.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Index&lt;/b&gt;&lt;/h2&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;What is package name?&lt;/li&gt;
&lt;li&gt;How to make package name&lt;/li&gt;
&lt;li&gt;Examples for package name&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. What is user-defined package name?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Package name is a unique value of the applications.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Our application has a unique package name. Because it is to distinguish other applications.&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. How to make user-defined package name&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;508&quot; data-origin-height=&quot;223&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b45eEN/btrjmWyqSNL/frv4nTXZbVumm0BMSKJVi0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b45eEN/btrjmWyqSNL/frv4nTXZbVumm0BMSKJVi0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b45eEN/btrjmWyqSNL/frv4nTXZbVumm0BMSKJVi0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb45eEN%2FbtrjmWyqSNL%2Ffrv4nTXZbVumm0BMSKJVi0%2Fimg.png&quot; data-origin-width=&quot;508&quot; data-origin-height=&quot;223&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Many applications use &quot;company name&quot; or &quot;domain address&quot; for package name because of it is unique.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- The &quot;domain address&quot; must use in reverse order.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Recommend that it use lower case.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Recommend that it don't use upper case.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Divide source files into groups using dot('.').&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- File packages are made by package name which is made.&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;3.&lt;span&gt; Examples for user-defined package name&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Format 1)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[Domain in reverse order].[Program name]&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;Example)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;com.google.meet&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;Format 2)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[Domain in reverse order].[Platform].[Program name]&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;Example)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;com.google.meet&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;com.google.android.meet&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;com.google.ios.meet&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;com.google.admin.meet&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Developers feel difficult for package naming convention. Because They don't know how to make name for package.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;But, It is easy to make User-defined package name. Keep in mind to make unique name for java source.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;So, We usually are using for domain name or application service name.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Just make user-defined package name according to the principles written in this post.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Reference&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.baeldung.com/java-packages&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.baeldung.com/java-packages&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://java4beginnersblog.wordpress.com/2017/02/08/packeges-in-java/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://java4beginnersblog.wordpress.com/2017/02/08/packeges-in-java/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1635576929243&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;Packages in Java&quot; data-og-description=&quot;Package in java is a mechanism to encapsulate a group of classes, sub packages and interfaces. Packages are used for: Preventing naming conflicts. For example there can be two classes with name Emp&amp;hellip;&quot; data-og-host=&quot;java4beginnersblog.wordpress.com&quot; data-og-source-url=&quot;https://java4beginnersblog.wordpress.com/2017/02/08/packeges-in-java/&quot; data-og-url=&quot;https://java4beginnersblog.wordpress.com/2017/02/08/packeges-in-java/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/pQdvo/hyL9zHRW6U/bqnRDwINYBehiKWOkmKwpk/img.png?width=508&amp;amp;height=223&amp;amp;face=0_0_508_223,https://scrap.kakaocdn.net/dn/cwVXsY/hyL9HlAKJc/CgmMgXODNKaq3lkSPKrjrK/img.png?width=508&amp;amp;height=223&amp;amp;face=0_0_508_223,https://scrap.kakaocdn.net/dn/JxFcv/hyL9LIjbdz/bUVRFGIkwkvdkIkafSWbk1/img.png?width=508&amp;amp;height=223&amp;amp;face=0_0_508_223&quot;&gt;&lt;a href=&quot;https://java4beginnersblog.wordpress.com/2017/02/08/packeges-in-java/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://java4beginnersblog.wordpress.com/2017/02/08/packeges-in-java/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/pQdvo/hyL9zHRW6U/bqnRDwINYBehiKWOkmKwpk/img.png?width=508&amp;amp;height=223&amp;amp;face=0_0_508_223,https://scrap.kakaocdn.net/dn/cwVXsY/hyL9HlAKJc/CgmMgXODNKaq3lkSPKrjrK/img.png?width=508&amp;amp;height=223&amp;amp;face=0_0_508_223,https://scrap.kakaocdn.net/dn/JxFcv/hyL9LIjbdz/bUVRFGIkwkvdkIkafSWbk1/img.png?width=508&amp;amp;height=223&amp;amp;face=0_0_508_223');&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;Packages in Java&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Package in java is a mechanism to encapsulate a group of classes, sub packages and interfaces. Packages are used for: Preventing naming conflicts. For example there can be two classes with name Emp&amp;hellip;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;java4beginnersblog.wordpress.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;</description>
      <author>RyanGomdoriPooh</author>
      <guid isPermaLink="true">https://interconnection.tistory.com/142</guid>
      <comments>https://interconnection.tistory.com/142#entry142comment</comments>
      <pubDate>Sat, 30 Oct 2021 16:08:48 +0900</pubDate>
    </item>
    <item>
      <title>쿠키와 세션 개념</title>
      <link>https://interconnection.tistory.com/74</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://orgojy.oopy.io/579894a5-bffa-42b4-a644-1988f9a1c1f4&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;노션 페이지(아래 내용과 동일)&lt;/a&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;개요&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;line-height: 1.5;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;쿠키와&amp;nbsp;세션은&amp;nbsp;개발자&amp;nbsp;말고도&amp;nbsp;인터넷&amp;nbsp;사용자라면&amp;nbsp;누구나&amp;nbsp;많이&amp;nbsp;들어본&amp;nbsp;단어입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;하지만&amp;nbsp;개념에&amp;nbsp;대해서는&amp;nbsp;많은&amp;nbsp;사람들이&amp;nbsp;헷갈려&amp;nbsp;하기에&amp;nbsp;쉽고&amp;nbsp;간단하게&amp;nbsp;정리해보려고&amp;nbsp;합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;일단 쿠키를 발급받고 사용하는 과정에 대해서 그림으로 보여드리고,&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;쿠키와 세션에 대한 설명을 하도록 하겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;목차&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1. HTTP의&amp;nbsp;특징과&amp;nbsp;쿠키와&amp;nbsp;세션을&amp;nbsp;사용하는&amp;nbsp;이유&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2. 쿠키&amp;nbsp;(&amp;nbsp;Cookie&amp;nbsp;)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3. 세션&amp;nbsp;(&amp;nbsp;Session&amp;nbsp;)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4. 쿠키와&amp;nbsp;세션의&amp;nbsp;차이&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;5. 세션을 사용하면 좋은데 왜 쿠키를 사용할까?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;6. 쿠키/세션은&amp;nbsp;캐시와&amp;nbsp;엄연히&amp;nbsp;다르다!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;1. HTTP의 특징과 쿠키와 세션을 사용하는 이유&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2019-09-01 at 4.03.07 PM.png&quot; data-origin-width=&quot;1796&quot; data-origin-height=&quot;762&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/betTb6/btqxVesqYq0/sUO2b5dpKqVuR261lNZBKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/betTb6/btqxVesqYq0/sUO2b5dpKqVuR261lNZBKk/img.png&quot; data-alt=&quot;쿠키를 발급받고 사용하는 과정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/betTb6/btqxVesqYq0/sUO2b5dpKqVuR261lNZBKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbetTb6%2FbtqxVesqYq0%2FsUO2b5dpKqVuR261lNZBKk%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;1796&quot; height=&quot;762&quot; data-filename=&quot;Screen Shot 2019-09-01 at 4.03.07 PM.png&quot; data-origin-width=&quot;1796&quot; data-origin-height=&quot;762&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: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;HTTP 프로토콜의 특성이자 약점을 보완하기 위해서 쿠키 또는 세션을 사용합니다.&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: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;기본적으로 HTTP 프로토콜 환경은 &quot;connectionless, stateless&quot;한 특성을 가지기 때문에&amp;nbsp;서버는 클라이언트가 누구인지 매번 확인해야합니다. 이 특성을 보완하기 위해서 쿠키와 세션을 사용하게됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 164px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 10px;&quot;&gt;
&lt;td style=&quot;width: 100%; text-align: left; height: 10px;&quot;&gt;&lt;span style=&quot;color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;&lt;b&gt;connectionless&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 154px;&quot;&gt;
&lt;td style=&quot;width: 100%; text-align: left; height: 154px;&quot;&gt;&lt;span style=&quot;color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;클라이언트가&amp;nbsp;요청을&amp;nbsp;한&amp;nbsp;후&amp;nbsp;응답을&amp;nbsp;받으면&amp;nbsp;그&amp;nbsp;연결을&amp;nbsp;끊어&amp;nbsp;버리는&amp;nbsp;특징&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;HTTP는&amp;nbsp;먼저&amp;nbsp;클라이언트가&amp;nbsp;request를&amp;nbsp;서버에&amp;nbsp;보내면,&amp;nbsp;서버는&amp;nbsp;클라이언트에게&amp;nbsp;요청에&amp;nbsp;맞는&amp;nbsp;response를&amp;nbsp;보내고&amp;nbsp;접속을&amp;nbsp;끊는&amp;nbsp;특성이&amp;nbsp;있다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;헤더에&amp;nbsp;keep-alive라는&amp;nbsp;값을&amp;nbsp;줘서&amp;nbsp;커넥션을&amp;nbsp;재활용하는데&amp;nbsp;HTTP1.1에서는&amp;nbsp;이것이&amp;nbsp;디폴트다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;HTTP가&amp;nbsp;tcp위에서&amp;nbsp;구현되었기&amp;nbsp;때문에&amp;nbsp;(tcp는&amp;nbsp;연결지향,udp는&amp;nbsp;비연결지향)&amp;nbsp;네트워크&amp;nbsp;관점에서&amp;nbsp;keep-alive는&amp;nbsp;옵션으로&amp;nbsp;connectionless의&amp;nbsp;연결비용을&amp;nbsp;줄이는&amp;nbsp;것을&amp;nbsp;장점으로&amp;nbsp;비연결지향이라&amp;nbsp;한다.&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 190px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 19px; text-align: left;&quot;&gt;&lt;span style=&quot;color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;&lt;b&gt;stateless&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 171px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 171px; text-align: left;&quot;&gt;&lt;span style=&quot;color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;통신이&amp;nbsp;끝나면&amp;nbsp;상태를&amp;nbsp;유지하지&amp;nbsp;않는&amp;nbsp;특징&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;연결을&amp;nbsp;끊는&amp;nbsp;순간&amp;nbsp;클라이언트와&amp;nbsp;서버의&amp;nbsp;통신이&amp;nbsp;끝나며&amp;nbsp;상태&amp;nbsp;정보는&amp;nbsp;유지하지&amp;nbsp;않는&amp;nbsp;특성이&amp;nbsp;있다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;쿠키와&amp;nbsp;세션은&amp;nbsp;위의&amp;nbsp;두&amp;nbsp;가지&amp;nbsp;특징을&amp;nbsp;해결하기&amp;nbsp;위해&amp;nbsp;사용합니다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;예를&amp;nbsp;들어,&amp;nbsp;쿠키와&amp;nbsp;세션을&amp;nbsp;사용하지&amp;nbsp;않으면&amp;nbsp;쇼핑몰에서&amp;nbsp;옷을&amp;nbsp;구매하려고&amp;nbsp;로그인을&amp;nbsp;했음에도,&amp;nbsp;페이지를&amp;nbsp;이동할&amp;nbsp;때&amp;nbsp;마다&amp;nbsp;계속&amp;nbsp;로그인을&amp;nbsp;해야&amp;nbsp;합니다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;쿠키와&amp;nbsp;세션을&amp;nbsp;사용했을&amp;nbsp;경우,&amp;nbsp;한&amp;nbsp;번&amp;nbsp;로그인을&amp;nbsp;하면&amp;nbsp;어떠한&amp;nbsp;방식에&amp;nbsp;의해서&amp;nbsp;그&amp;nbsp;사용자에&amp;nbsp;대한&amp;nbsp;인증을&amp;nbsp;유지하게&amp;nbsp;됩니다.&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;line-height: 1.5;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;왜 쿠키와 세션이 필요한지 이야기했으니 이제는 쿠키와 세션을 발급받고 사용하는 과정을 알아보겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;line-height: 1.5;&quot;&gt;&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;&lt;/div&gt;
&lt;h2 style=&quot;line-height: 1.5;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;2. 쿠키 ( Cookie )&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;쿠키란?&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;쿠키는&amp;nbsp;클라이언트(브라우저)&amp;nbsp;로컬에&amp;nbsp;저장되는&amp;nbsp;키와&amp;nbsp;값이&amp;nbsp;들어있는&amp;nbsp;작은&amp;nbsp;데이터&amp;nbsp;파일입니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;사용자&amp;nbsp;인증이&amp;nbsp;유효한&amp;nbsp;시간을&amp;nbsp;명시할&amp;nbsp;수&amp;nbsp;있으며,&amp;nbsp;유효&amp;nbsp;시간이&amp;nbsp;정해지면&amp;nbsp;브라우저가&amp;nbsp;종료되어도&amp;nbsp;인증이&amp;nbsp;유지된다는&amp;nbsp;특징이&amp;nbsp;있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;쿠키는&amp;nbsp;클라이언트의&amp;nbsp;상태&amp;nbsp;정보를&amp;nbsp;로컬에&amp;nbsp;저장했다가&amp;nbsp;참조합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;클라이언트에&amp;nbsp;300개까지&amp;nbsp;쿠키저장&amp;nbsp;가능,&amp;nbsp;하나의&amp;nbsp;도메인당&amp;nbsp;20개의&amp;nbsp;값만&amp;nbsp;가질&amp;nbsp;수&amp;nbsp;있음,&amp;nbsp;하나의&amp;nbsp;쿠키값은&amp;nbsp;4KB까지&amp;nbsp;저장합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;Response&amp;nbsp;Header에&amp;nbsp;Set-Cookie&amp;nbsp;속성을&amp;nbsp;사용하면&amp;nbsp;클라이언트에&amp;nbsp;쿠키를&amp;nbsp;만들&amp;nbsp;수&amp;nbsp;있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;쿠키는&amp;nbsp;사용자가&amp;nbsp;따로&amp;nbsp;요청하지&amp;nbsp;않아도&amp;nbsp;브라우저가&amp;nbsp;Request시에&amp;nbsp;Request&amp;nbsp;Header를&amp;nbsp;넣어서&amp;nbsp;자동으로&amp;nbsp;서버에&amp;nbsp;전송합니다.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;쿠키의 구성 요소&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;이름&amp;nbsp;:&amp;nbsp;각각의&amp;nbsp;쿠키를&amp;nbsp;구별하는&amp;nbsp;데&amp;nbsp;사용되는&amp;nbsp;이름&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;값&amp;nbsp;:&amp;nbsp;쿠키의&amp;nbsp;이름과&amp;nbsp;관련된&amp;nbsp;값&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;유효시간&amp;nbsp;:&amp;nbsp;쿠키의&amp;nbsp;유지시간&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;도메인&amp;nbsp;:&amp;nbsp;쿠키를&amp;nbsp;전송할&amp;nbsp;도메인&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;경로&amp;nbsp;:&amp;nbsp;쿠키를&amp;nbsp;전송할&amp;nbsp;요청&amp;nbsp;경로&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;쿠키의 동작 방식&lt;/span&gt;&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;color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;클라이언트가 페이지를 요청&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;서버에서 쿠키를 생성&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;HTTP&amp;nbsp;헤더에&amp;nbsp;쿠키를&amp;nbsp;포함&amp;nbsp;시켜&amp;nbsp;응답&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;브라우저가&amp;nbsp;종료되어도&amp;nbsp;쿠키&amp;nbsp;만료&amp;nbsp;기간이&amp;nbsp;있다면&amp;nbsp;클라이언트에서&amp;nbsp;보관하고&amp;nbsp;있음&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;같은&amp;nbsp;요청을&amp;nbsp;할&amp;nbsp;경우&amp;nbsp;HTTP&amp;nbsp;헤더에&amp;nbsp;쿠키를&amp;nbsp;함께&amp;nbsp;보냄&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;서버에서&amp;nbsp;쿠키를&amp;nbsp;읽어&amp;nbsp;이전&amp;nbsp;상태&amp;nbsp;정보를&amp;nbsp;변경&amp;nbsp;할&amp;nbsp;필요가&amp;nbsp;있을&amp;nbsp;때&amp;nbsp;쿠키를&amp;nbsp;업데이트&amp;nbsp;하여&amp;nbsp;변경된&amp;nbsp;쿠키를&amp;nbsp;HTTP&amp;nbsp;헤더에&amp;nbsp;포함시켜&amp;nbsp;응답&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;쿠키의 사용 예&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;방문&amp;nbsp;사이트에서&amp;nbsp;로그인&amp;nbsp;시,&amp;nbsp;&quot;아이디와&amp;nbsp;비밀번호를&amp;nbsp;저장하시겠습니까?&quot;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;쇼핑몰의&amp;nbsp;장바구니&amp;nbsp;기능&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;자동로그인,&amp;nbsp;팝업에서&amp;nbsp;&quot;오늘&amp;nbsp;더&amp;nbsp;이상&amp;nbsp;이&amp;nbsp;창을&amp;nbsp;보지&amp;nbsp;않음&quot;&amp;nbsp;체크,&amp;nbsp;쇼핑몰의&amp;nbsp;장바구니&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;3. 세션 ( Session )&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;세션이란?&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;세션은&amp;nbsp;쿠키를&amp;nbsp;기반하고&amp;nbsp;있지만,&amp;nbsp;사용자&amp;nbsp;정보&amp;nbsp;파일을&amp;nbsp;브라우저에&amp;nbsp;저장하는&amp;nbsp;쿠키와&amp;nbsp;달리&amp;nbsp;세션은&amp;nbsp;서버&amp;nbsp;측에서&amp;nbsp;관리합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;서버에서는&amp;nbsp;클라이언트를&amp;nbsp;구분하기&amp;nbsp;위해&amp;nbsp;세션&amp;nbsp;ID를&amp;nbsp;부여하며&amp;nbsp;웹&amp;nbsp;브라우저가&amp;nbsp;서버에&amp;nbsp;접속해서&amp;nbsp;브라우저를&amp;nbsp;종료할&amp;nbsp;때까지&amp;nbsp;인증상태를&amp;nbsp;유지합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;물론&amp;nbsp;접속&amp;nbsp;시간에&amp;nbsp;제한을&amp;nbsp;두어&amp;nbsp;일정&amp;nbsp;시간&amp;nbsp;응답이&amp;nbsp;없다면&amp;nbsp;정보가&amp;nbsp;유지되지&amp;nbsp;않게&amp;nbsp;설정이&amp;nbsp;가능&amp;nbsp;합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;사용자에&amp;nbsp;대한&amp;nbsp;정보를&amp;nbsp;서버에&amp;nbsp;두기&amp;nbsp;때문에&amp;nbsp;쿠키보다&amp;nbsp;보안에&amp;nbsp;좋지만,&amp;nbsp;사용자가&amp;nbsp;많아질수록&amp;nbsp;서버&amp;nbsp;메모리를&amp;nbsp;많이&amp;nbsp;차지하게&amp;nbsp;됩니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;즉&amp;nbsp;동접자&amp;nbsp;수가&amp;nbsp;많은&amp;nbsp;웹&amp;nbsp;사이트인&amp;nbsp;경우&amp;nbsp;서버에&amp;nbsp;과부하를&amp;nbsp;주게&amp;nbsp;되므로&amp;nbsp;성능&amp;nbsp;저하의&amp;nbsp;요인이&amp;nbsp;됩니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;클라이언트가 Request를 보내면, 해당 서버의 엔진이 클라이언트에게 유일한 ID를 부여하는 데 이것이 세션 ID입니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;세션의 동작 방식&lt;/span&gt;&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;color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;클라이언트가 서버에 접속 시 세션 ID를 발급 받음&lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;클라이언트는 세션 ID에 대해 쿠키를 사용해서 저장하고 가지고 있음&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;클라리언트는 서버에 요청할 때, 이 쿠키의 세션 ID를 같이 서버에 전달해서 요청&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;서버는 세션 ID를 전달 받아서 별다른 작업없이 세션 ID로 세션에 있는 클라언트 정보를 가져와서 사용&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;클라이언트 정보를 가지고 서버 요청을 처리하여 클라이언트에게 응답&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;세션의 특징&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;각&amp;nbsp;클라이언트에게&amp;nbsp;고유&amp;nbsp;ID를&amp;nbsp;부여&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;세션&amp;nbsp;ID로&amp;nbsp;클라이언트를&amp;nbsp;구분해서&amp;nbsp;클라이언트의&amp;nbsp;요구에&amp;nbsp;맞는&amp;nbsp;서비스를&amp;nbsp;제공&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;보안&amp;nbsp;면에서&amp;nbsp;쿠키보다&amp;nbsp;우수&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;사용자가&amp;nbsp;많아질수록&amp;nbsp;서버&amp;nbsp;메모리를&amp;nbsp;많이&amp;nbsp;차지하게&amp;nbsp;됨&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;세션의 사용 예&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;로그인 같이 보안상&amp;nbsp;중요한&amp;nbsp;작업을&amp;nbsp;수행할&amp;nbsp;때&amp;nbsp;사용&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;4. 쿠키와 세션의 차이&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;쿠키와&amp;nbsp;세션은&amp;nbsp;비슷한&amp;nbsp;역할을&amp;nbsp;하며,&amp;nbsp;동작원리도&amp;nbsp;비슷합니다.&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;그&amp;nbsp;이유는&amp;nbsp;세션도&amp;nbsp;결국&amp;nbsp;쿠키를&amp;nbsp;사용하기&amp;nbsp;때문입니다.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;가장&amp;nbsp;큰&amp;nbsp;차이점은&amp;nbsp;사용자의 정보가&amp;nbsp;저장되는&amp;nbsp;위치입니다.&amp;nbsp;&lt;/span&gt;때문에&amp;nbsp;쿠키는&amp;nbsp;서버의&amp;nbsp;자원을&amp;nbsp;전혀&amp;nbsp;사용하지&amp;nbsp;않으며,&amp;nbsp;세션은&amp;nbsp;서버의&amp;nbsp;자원을&amp;nbsp;사용합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;보안&amp;nbsp;면에서&amp;nbsp;세션이&amp;nbsp;더&amp;nbsp;우수하며,&amp;nbsp;요청&amp;nbsp;속도는&amp;nbsp;쿠키가&amp;nbsp;세션보다&amp;nbsp;더&amp;nbsp;빠릅니다.&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;그&amp;nbsp;이유는&amp;nbsp;세션은&amp;nbsp;서버의&amp;nbsp;처리가&amp;nbsp;필요하기&amp;nbsp;때문입니다.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;보안,&amp;nbsp;쿠키는&amp;nbsp;클라이언트&amp;nbsp;로컬에&amp;nbsp;저장되기&amp;nbsp;때문에&amp;nbsp;변질되거나&amp;nbsp;request에서&amp;nbsp;스니핑&amp;nbsp;당할&amp;nbsp;우려가&amp;nbsp;있어서&amp;nbsp;보안에&amp;nbsp;취약하지만&amp;nbsp;세션은&amp;nbsp;쿠키를&amp;nbsp;이용해서&amp;nbsp;sessionid&amp;nbsp;만&amp;nbsp;저장하고&amp;nbsp;그것으로&amp;nbsp;구분해서&amp;nbsp;서버에서&amp;nbsp;처리하기&amp;nbsp;때문에&amp;nbsp;비교적&amp;nbsp;보안성이&amp;nbsp;좋습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;라이프 사이클, 쿠키도 만료시간이 있지만 파일로 저장되기 때문에 브라우저를 종료해도 계속해서 정보가 남아 있을 수 있다. 또한 만료기간을 넉넉하게 잡아두면 쿠키삭제를 할 때 까지 유지될 수도 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;반면에 세션도 만료시간을 정할 수 있지만 브라우저가 종료되면 만료시간에 상관없이 삭제됩니다. 예를 들어, 크롬에서 다른 탭을 사용해도 세션을 공유됩니다. 다른 브라우저를 사용하게 되면 다른 세션을 사용할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;속도, 쿠키에 정보가 있기 때문에 서버에 요청시 속도가 빠르고 세션은 정보가 서버에 있기 때문에 처리가 요구되어 비교적 느린 속도를 가집니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;5. 세션을 사용하면 좋은데 왜 쿠키를 사용할까?&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;세션은 서버의 자원을 사용하기 때문에 무분별하게 만들다보면 서버의 메모리가 감당할 수 없어질 수가 있고 속도가 느려질 수 있기 때문에 쿠키가 유리한 경우가 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;6. 쿠키/세션은 캐시와 엄연히 다르다!&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;캐시는 이미지나 css, js파일 등을 브라우저나 서버 앞 단에 저장해놓고 사용하는 것입니다.&lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;한번 캐시에 저장되면 브라우저를 참고하기 때문에 서버에서 변경이 되어도 사용자는 변경되지 않게 보일 수 있는데 이런 부분을 캐시를 지워주거나 서버에서 클라이언트로 응답을 보낼 때 header에 캐시 만료시간을 명시하는 방법등을 이용할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;보통 쿠키와 세션의 차이를 물어볼 때 저장위치와 보안에 대해서는 잘 말하는데 사실 중요한 것은 라이프사이클을 얘기하는 것입니다.&lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;이상으로&amp;nbsp;쿠키와&amp;nbsp;세션에&amp;nbsp;대해&amp;nbsp;알아보았습니다.&lt;br /&gt;&lt;br /&gt;세션은&amp;nbsp;사용자의&amp;nbsp;수&amp;nbsp;만큼&amp;nbsp;서버&amp;nbsp;메모리를&amp;nbsp;차지하기&amp;nbsp;때문에,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;최근에는 이런&amp;nbsp;문제들을&amp;nbsp;보완한&amp;nbsp;토큰&amp;nbsp;기반의&amp;nbsp;인증방식을&amp;nbsp;사용하는&amp;nbsp;추세입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;&lt;br /&gt;그&amp;nbsp;중&amp;nbsp;JWT(&amp;nbsp;JSON&amp;nbsp;Web&amp;nbsp;Token&amp;nbsp;)라는&amp;nbsp;것이&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;letter-spacing: 0px; color: #000000;&quot; data-darkreader-inline-color=&quot;&quot;&gt;JWT는 다음에 다루도록 하겠습니다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>Network</category>
      <author>RyanGomdoriPooh</author>
      <guid isPermaLink="true">https://interconnection.tistory.com/74</guid>
      <comments>https://interconnection.tistory.com/74#entry74comment</comments>
      <pubDate>Mon, 11 Oct 2021 23:44:37 +0900</pubDate>
    </item>
    <item>
      <title>Blocking or Non-Blocking, Synchronous and Asynchronous</title>
      <link>https://interconnection.tistory.com/141</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Overview&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;When we develop application, we always think concepts called &quot;Blocking, Non-blocking, Synchronous, Asynchronous&quot;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;We usually think that &quot;Blocking, non-blocking, Synchronous, Asynchronous&quot; are the same.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;But, This perspective is wrong. It is unrelated concepts each other. It is difficult and confusing concepts.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;It is confused between &quot;Blocking&quot; and &quot;Synchronous&quot;. Likewise, It is confused between &quot;Non-blocking&quot; and &quot;Asynchronous&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;&lt;u&gt;&quot;Synchronous and Asynchronous&quot; must have at least two subjects performing the task.&lt;/u&gt;&lt;br /&gt;At this time, if the (start, end) time of work is aligned with each other, it is called &quot;Synchronous&quot;, and if the time of work is not related to each other, it is called &quot;Asynchronous&quot;.&lt;br /&gt;&lt;br /&gt;&lt;u&gt;On the other hand, &quot;Blocking and Non-blocking&quot; requires at least two targets for work.&lt;/u&gt;&lt;br /&gt;Because the two concepts have different perspectives, various combinations of &quot;synchronous/blocking&quot;, &quot;synchronous/non-blocking&quot;, &quot;asynchronous/blocking&quot;, and &quot;asynchronous/non-blocking&quot; are possible.&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;Then, let's look at details of the contents now.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Index&lt;/b&gt;&lt;/h2&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Concept of Blocking and Non-blocking&lt;/li&gt;
&lt;li&gt;Concept of&amp;nbsp;Sync and Async&lt;/li&gt;
&lt;li&gt;Difference between &quot;Blocking and Non-blocking&quot; and &quot;Sync and Async&quot;&lt;/li&gt;
&lt;li&gt;Cases: (Blocking or Non-blocking) X (Sync or Async)&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. Blocking&amp;nbsp;and&amp;nbsp;Non-blocking&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;In blocking and non-blocking, it is important how to deal with the subject who performs other tasks.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;If you do your own work, it waits from the beginning to the end of the work done by another person, and start your work again, this is blocking.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;If you continue your work regardless of the work of other subjects, this is non-blocking.&lt;br /&gt;&lt;br /&gt;Thread A is calling another target to do something, receiving the results from it, and resuming the operation.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;For example, Java can use JDBC to ask DB questions and get results called blocking operations.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;On the contrary, if you ask another subject to work and do your own work without waiting for the results to be received, this can be called non-blocking.&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;Blocking and Non-blocking are mainly used in reading and writing IO.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Blocking&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- It ends when you get the return value.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- It continues to wait until the requested operation is completed.&lt;br /&gt;- Until the requested task is completed, the thread waits and continues to use/stand by one thread until the return value is received.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;970&quot; data-origin-height=&quot;716&quot; data-filename=&quot;Screen Shot 2021-10-10 at 2.28.21 AM.png&quot; width=&quot;400&quot; height=&quot;295&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b4LRTL/btrhdVW1B4a/KRNoCknL8SkwUzALO2XeYk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b4LRTL/btrhdVW1B4a/KRNoCknL8SkwUzALO2XeYk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b4LRTL/btrhdVW1B4a/KRNoCknL8SkwUzALO2XeYk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb4LRTL%2FbtrhdVW1B4a%2FKRNoCknL8SkwUzALO2XeYk%2Fimg.png&quot; data-origin-width=&quot;970&quot; data-origin-height=&quot;716&quot; data-filename=&quot;Screen Shot 2021-10-10 at 2.28.21 AM.png&quot; width=&quot;400&quot; height=&quot;295&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Non-blocking&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Although the requested work cannot be completed immediately, return it immediately.&lt;br /&gt;- Do not return immediately. It prevents you from working.&lt;br /&gt;- One thread can handle multiple IOs by non-blocking.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;962&quot; data-origin-height=&quot;694&quot; data-filename=&quot;Screen Shot 2021-10-10 at 2.28.47 AM.png&quot; width=&quot;400&quot; height=&quot;289&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bIoGiM/btrhdvKY6Hv/y2Z0kTIXIp4hXvWPYXKkm0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bIoGiM/btrhdvKY6Hv/y2Z0kTIXIp4hXvWPYXKkm0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bIoGiM/btrhdvKY6Hv/y2Z0kTIXIp4hXvWPYXKkm0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbIoGiM%2FbtrhdvKY6Hv%2Fy2Z0kTIXIp4hXvWPYXKkm0%2Fimg.png&quot; data-origin-width=&quot;962&quot; data-origin-height=&quot;694&quot; data-filename=&quot;Screen Shot 2021-10-10 at 2.28.47 AM.png&quot; width=&quot;400&quot; height=&quot;289&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. Synchronous and Asynchronous&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;When two or more subjects is executing for task, task of each subject finishes at the same time or starts at the same time.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Or, If you start and end at the same time, or if another subject starts working at the same time as one task.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;It can be seen as a synchronous task.&lt;br /&gt;&lt;br /&gt;Asynchronous work refers to when the two subjects have a separate start/end time regardless of each other's start or end time.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;It can be called asynchronous when the work done by different subjects has nothing to do with their work start or end time.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Synchronous&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Thread1 started working and waited until Task1 was over. And then It starts Task2.&lt;br /&gt;- When a work is requested, the result value of the request is directly returned.&lt;br /&gt;- The result value of the request is the same as the return value.&lt;br /&gt;- The called function cares about the completion of the task.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1544&quot; data-origin-height=&quot;470&quot; data-filename=&quot;Screen Shot 2021-10-10 at 2.27.02 AM.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d2Kmzf/btrhddw227Z/LToYCHkUJJVRFewIMnB0M1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d2Kmzf/btrhddw227Z/LToYCHkUJJVRFewIMnB0M1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d2Kmzf/btrhddw227Z/LToYCHkUJJVRFewIMnB0M1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd2Kmzf%2Fbtrhddw227Z%2FLToYCHkUJJVRFewIMnB0M1%2Fimg.png&quot; data-origin-width=&quot;1544&quot; data-origin-height=&quot;470&quot; data-filename=&quot;Screen Shot 2021-10-10 at 2.27.02 AM.png&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Asynchronous&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Thread1 can start work, not wait for completion, and Thread1 can handle other tasks.&lt;br /&gt;- When a work is requested, the result value of the request is indirectly received.&lt;br /&gt;- The result value of the request may be different from the return value.&lt;br /&gt;- The request operation is executed on another thread.&lt;br /&gt;- Processing through callback is called &quot;asynchronous processing&quot;.&lt;br /&gt;- The called function cares about completing the task.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1300&quot; data-origin-height=&quot;450&quot; data-filename=&quot;Screen Shot 2021-10-10 at 2.27.22 AM.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vBp5Q/btrhhSq4bK7/uTdQzA5fdRifpGPHX2gYpk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vBp5Q/btrhhSq4bK7/uTdQzA5fdRifpGPHX2gYpk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vBp5Q/btrhhSq4bK7/uTdQzA5fdRifpGPHX2gYpk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvBp5Q%2FbtrhhSq4bK7%2FuTdQzA5fdRifpGPHX2gYpk%2Fimg.png&quot; data-origin-width=&quot;1300&quot; data-origin-height=&quot;450&quot; data-filename=&quot;Screen Shot 2021-10-10 at 2.27.22 AM.png&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. Difference between &quot;Blocking and Non-blocking&quot; and &quot;Sync and Async&quot;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&quot;When an I/O function is called, it is whether or not to return immediately.&quot;&lt;/b&gt;&lt;br /&gt;Blocking: Don't return right away&lt;br /&gt;Non-Blocking:&amp;nbsp;Return&amp;nbsp;right&amp;nbsp;away&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Blocking&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Until the work of an object that cannot be directly controlled is completed, blocking doesn't hand over control.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- When a calling function requests IO, it means waiting without doing anything until IO processing is completed.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Non-blocking&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Non-Blocking is the opposite concept of blocking.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- It has nothing to do with the work of an object that cannot be directly controlled.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Regardless of whether IO processing is completed, a function requests I/O and then it can do its other work immediately.&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;The concern is who cares about the completion of the task of the called I/O function.&quot;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Sync: In charge of application&lt;br /&gt;Async: In charge of kernel&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Synchronous&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- After requesting a task, synchronous task waits for the result of it to come out and process it.&lt;br /&gt;-&amp;nbsp;the&amp;nbsp;process&amp;nbsp;continuously&amp;nbsp;checks&amp;nbsp;the&amp;nbsp;kernel&amp;nbsp;for&amp;nbsp;I/O&amp;nbsp;preparations.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Asynchronous&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- If it does not care whether the task is completed, the&amp;nbsp;called function is asynchronous.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- When&amp;nbsp;the&amp;nbsp;end&amp;nbsp;of&amp;nbsp;the&amp;nbsp;previous&amp;nbsp;system&amp;nbsp;call&amp;nbsp;occurs,&amp;nbsp;subsequent&amp;nbsp;processing&amp;nbsp;is&amp;nbsp;performed.&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;3. Cases: (Blocking or Non-blocking) X (Sync or Async)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;In this step, Explain the combination of (blocking, non-blocking) and (sync, async).&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. Synchronous&amp;nbsp;blocking&amp;nbsp;I/O&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. Synchronous&amp;nbsp;non-blocking&amp;nbsp;I/O&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. Asynchronous&amp;nbsp;blocking&amp;nbsp;I/O&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. Asynchronous&amp;nbsp;Non-Blocking&amp;nbsp;I/O&amp;nbsp;(AIO)&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-origin-width=&quot;1192&quot; data-origin-height=&quot;886&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tNK78/btrg0pQ5rkU/ORaGjkXvIE3qD0eIVIeVSk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tNK78/btrg0pQ5rkU/ORaGjkXvIE3qD0eIVIeVSk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tNK78/btrg0pQ5rkU/ORaGjkXvIE3qD0eIVIeVSk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtNK78%2Fbtrg0pQ5rkU%2FORaGjkXvIE3qD0eIVIeVSk%2Fimg.png&quot; data-origin-width=&quot;1192&quot; data-origin-height=&quot;886&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Synchronous&amp;nbsp;blocking&amp;nbsp;I/O&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;It is the most basic I/O model, which refers to I/O system calls such as read and write files in general.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;If there is no special setting, it operates as blocking.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;After the user process calls read(), the kernel does not return until the data is copied to the user buffer&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;and the user process waits while stopping its work. (Waste of resources such as CPU)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;Therefore, if a server to which multiple clients is connected is implemented in a blocking manner, if one client proceeds with an I/O operation, the process (or thread) will be stopped, so each client must create and connect a process (or thread).&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;However, as the number of users increases, the process (or thread) increases.&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;examples)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- query to DB by JDBC&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- In method, call another method to get result immediately&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;716&quot; data-origin-height=&quot;453&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beyoBo/btrg1ZduG5F/E1vkotx8vMgwwxW1ff6oWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/beyoBo/btrg1ZduG5F/E1vkotx8vMgwwxW1ff6oWk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/beyoBo/btrg1ZduG5F/E1vkotx8vMgwwxW1ff6oWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbeyoBo%2Fbtrg1ZduG5F%2FE1vkotx8vMgwwxW1ff6oWk%2Fimg.png&quot; data-origin-width=&quot;716&quot; data-origin-height=&quot;453&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Synchronous&amp;nbsp;non-blocking&amp;nbsp;I/O&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;The kernel reads the data, stores it in a buffer, and copies the content to the user.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Since the buffer is loaded into the memory held by the kernel, inter-memory copying occurs and can be received at a higher speed than I/O.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;However, if the buffer is empty, the kernel immediately returns an error (EWOULDBLOCK), causing the user process to continuously call read() to check the I/O readiness.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Since system calls occur repeatedly (polling method), resources such as cpu are wasted.&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;examples)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Polling&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;634&quot; data-origin-height=&quot;451&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/md0qj/btrg0qCGmSQ/n8U58L6GXRF4mTLKgJxKl1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/md0qj/btrg0qCGmSQ/n8U58L6GXRF4mTLKgJxKl1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/md0qj/btrg0qCGmSQ/n8U58L6GXRF4mTLKgJxKl1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fmd0qj%2Fbtrg0qCGmSQ%2Fn8U58L6GXRF4mTLKgJxKl1%2Fimg.png&quot; data-origin-width=&quot;634&quot; data-origin-height=&quot;451&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Asynchronous&amp;nbsp;blocking&amp;nbsp;I/O&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;It is used for the purpose of multiplexing I/O using system calls such as select or poll.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Select and poll may perform an inspection to see if data is prepared in multiple descriptors and return to process multiple I/O if a prepared descriptor is found.&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;However, the selection is limited to the number of management file descriptors and poll is not limited, but the size of the check mask per file descriptor is large, and thus performance degrades when the number of connectors increases.&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;Asynchronous blocking&quot; combinations eventually have to wait for other tasks to be completed, so they have similar work efficiency to &quot;Synchronous blocking&quot;, that is, they don't have very good efficiency.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;Synchronous blocking&quot; is not the situation the developers intended. They performed &quot;Asynchronous, non-blocking&quot; work, but this result comes out when they performed the blocking work without even realizing it.&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;examples)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Asynchronous, non-blocking operations are called, and when you try to check the result value of the called operation while working on your own (blocking method is executed)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;719&quot; data-origin-height=&quot;443&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byRPYw/btrg1KgBRda/k7zcTORfX6L3iF8cWWrfd1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byRPYw/btrg1KgBRda/k7zcTORfX6L3iF8cWWrfd1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byRPYw/btrg1KgBRda/k7zcTORfX6L3iF8cWWrfd1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbyRPYw%2Fbtrg1KgBRda%2Fk7zcTORfX6L3iF8cWWrfd1%2Fimg.png&quot; data-origin-width=&quot;719&quot; data-origin-height=&quot;443&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 id=&quot;333-asynchronous-non-blocking-io-aio&quot; data-ke-size=&quot;size23&quot;&gt;Asynchronous Non-Blocking I/O (AIO)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;An I/O model that responds to a result at a time when I/O processing is completed is referred to as asynchronous I/O.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;The asynchronous I/O reply is made in the form of a signal or callback, and the application may proceed with other tasks until a reply is made.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;The process is the same as non-blocking I/O in that it is not in a block state, but non-blocking I/O notifies when the I/O process is completed, while non-blocking I/O judges the I/O as an error.&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;examples)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Case consists of divided logic by a&amp;nbsp;signal&amp;nbsp;or&amp;nbsp;callback&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;630&quot; data-origin-height=&quot;437&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cC4Y6E/btrg2iDWoZy/hnDyVXktuhtiOMIpm2W1D1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cC4Y6E/btrg2iDWoZy/hnDyVXktuhtiOMIpm2W1D1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cC4Y6E/btrg2iDWoZy/hnDyVXktuhtiOMIpm2W1D1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcC4Y6E%2Fbtrg2iDWoZy%2FhnDyVXktuhtiOMIpm2W1D1%2Fimg.png&quot; data-origin-width=&quot;630&quot; data-origin-height=&quot;437&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Let's&amp;nbsp;talk&amp;nbsp;about&amp;nbsp;it&amp;nbsp;briefly.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Between application and kernel, it is how to act called logic.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;You read the details and the graphs for the above cases, you will understand.&lt;br /&gt;The&amp;nbsp;important&amp;nbsp;thing&amp;nbsp;here&amp;nbsp;is&amp;nbsp;to&amp;nbsp;look&amp;nbsp;at&amp;nbsp;the&amp;nbsp;application&amp;nbsp;and&amp;nbsp;kernel&amp;nbsp;areas&amp;nbsp;separately.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Reference&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Asynchronous_I/O&quot;&gt;https://en.wikipedia.org/wiki/Asynchronous_I/O&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1633846783618&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 - Wikipedia&quot; data-og-description=&quot;In computer science, asynchronous I/O (also non-sequential I/O) is a form of input/output processing that permits other processing to continue before the transmission has finished. Input and output (I/O) operations on a computer can be extremely slow compa&quot; data-og-host=&quot;en.wikipedia.org&quot; data-og-source-url=&quot;https://en.wikipedia.org/wiki/Asynchronous_I/O&quot; data-og-url=&quot;https://en.wikipedia.org/wiki/Asynchronous_I/O&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Asynchronous_I/O&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://en.wikipedia.org/wiki/Asynchronous_I/O&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 - Wikipedia&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;In computer science, asynchronous I/O (also non-sequential I/O) is a form of input/output processing that permits other processing to continue before the transmission has finished. Input and output (I/O) operations on a computer can be extremely slow compa&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;en.wikipedia.org&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://www.tornadoweb.org/en/stable/guide/async.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.tornadoweb.org/en/stable/guide/async.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1633846832841&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 and non-Blocking I/O &amp;mdash; Tornado 6.1 documentation&quot; data-og-description=&quot;Real-time web features require a long-lived mostly-idle connection per user. In a traditional synchronous web server, this implies devoting one thread to each user, which can be very expensive. To minimize the cost of concurrent connections, Tornado uses a&quot; data-og-host=&quot;www.tornadoweb.org&quot; data-og-source-url=&quot;https://www.tornadoweb.org/en/stable/guide/async.html&quot; data-og-url=&quot;https://www.tornadoweb.org/en/stable/guide/async.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.tornadoweb.org/en/stable/guide/async.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.tornadoweb.org/en/stable/guide/async.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;Asynchronous and non-Blocking I/O &amp;mdash; Tornado 6.1 documentation&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Real-time web features require a long-lived mostly-idle connection per user. In a traditional synchronous web server, this implies devoting one thread to each user, which can be very expensive. To minimize the cost of concurrent connections, Tornado uses a&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.tornadoweb.org&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://stackoverflow.com/questions/2625493/asynchronous-and-non-blocking-calls-also-between-blocking-and-synchronous&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://stackoverflow.com/questions/2625493/asynchronous-and-non-blocking-calls-also-between-blocking-and-synchronous&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1633846862061&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 and non-blocking calls? also between blocking and synchronous&quot; data-og-description=&quot;What is the difference between asynchronous and non-blocking calls? Also between blocking and synchronous calls (with examples please)?&quot; data-og-host=&quot;stackoverflow.com&quot; data-og-source-url=&quot;https://stackoverflow.com/questions/2625493/asynchronous-and-non-blocking-calls-also-between-blocking-and-synchronous&quot; data-og-url=&quot;https://stackoverflow.com/questions/2625493/asynchronous-and-non-blocking-calls-also-between-blocking-and-synchronous&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cwoTPd/hyLTEqo9Kn/Km7afOKXrE2A94JlmCO17K/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/2625493/asynchronous-and-non-blocking-calls-also-between-blocking-and-synchronous&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://stackoverflow.com/questions/2625493/asynchronous-and-non-blocking-calls-also-between-blocking-and-synchronous&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cwoTPd/hyLTEqo9Kn/Km7afOKXrE2A94JlmCO17K/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;asynchronous and non-blocking calls? also between blocking and synchronous&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;What is the difference between asynchronous and non-blocking calls? Also between blocking and synchronous calls (with examples please)?&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;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Java</category>
      <author>RyanGomdoriPooh</author>
      <guid isPermaLink="true">https://interconnection.tistory.com/141</guid>
      <comments>https://interconnection.tistory.com/141#entry141comment</comments>
      <pubDate>Sun, 10 Oct 2021 15:38:03 +0900</pubDate>
    </item>
    <item>
      <title>What is Java GC(Garbage Collection)?</title>
      <link>https://interconnection.tistory.com/139</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Java uses memory without explicitly releasing it. Instead,&amp;nbsp;JVM&amp;nbsp;manages&amp;nbsp;memory.&lt;br /&gt;&lt;br /&gt;JVM deletes unused objects in the Heap area by GC.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;540&quot; data-filename=&quot;BFDA844A-9DF4-4471-8B62-A57595896F8A.gif&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kZG22/btrgJX7kjz6/NDqZxpRuNjxuUJyK0kwVg0/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kZG22/btrgJX7kjz6/NDqZxpRuNjxuUJyK0kwVg0/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kZG22/btrgJX7kjz6/NDqZxpRuNjxuUJyK0kwVg0/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/kZG22/btrgJX7kjz6/NDqZxpRuNjxuUJyK0kwVg0/img.gif&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;540&quot; data-filename=&quot;BFDA844A-9DF4-4471-8B62-A57595896F8A.gif&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Heap area is dynamically allocated memory area.&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;Heap&amp;nbsp;manages&amp;nbsp;object-type&amp;nbsp;data&amp;nbsp;objects,&amp;nbsp;typically&amp;nbsp;classes&amp;nbsp;such&amp;nbsp;as&amp;nbsp;String&amp;nbsp;and&amp;nbsp;Collection.&lt;br /&gt;&lt;br /&gt;The important part of this is to determine which object to keep and which object to GC in Heap.&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;GC&amp;nbsp;is&amp;nbsp;designed&amp;nbsp;with&amp;nbsp;the&amp;nbsp;following&amp;nbsp;concept.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;The hypothesis for design of GC(Garbage Collection)&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;*&amp;nbsp;Most&amp;nbsp;objects&amp;nbsp;quickly&amp;nbsp;become&amp;nbsp;unreachable&amp;nbsp;state.&amp;nbsp;&amp;rArr;&amp;nbsp;Process&amp;nbsp;by&amp;nbsp;&quot;minor&amp;nbsp;GC&quot;&lt;br /&gt;*&amp;nbsp;There&amp;nbsp;are&amp;nbsp;very&amp;nbsp;few&amp;nbsp;references&amp;nbsp;from&amp;nbsp;old&amp;nbsp;objects&amp;nbsp;to&amp;nbsp;young&amp;nbsp;objects.&amp;nbsp;&amp;rArr;&amp;nbsp;Process&amp;nbsp;by&amp;nbsp;&quot;major&amp;nbsp;GC&quot;&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;So, Which objects will GC collect?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;If an object have a valid reference from GC Roots, it is called Reachable, otherwise Unreachable.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* Unreachable objects : Among&amp;nbsp;the&amp;nbsp;objects,&amp;nbsp;an&amp;nbsp;object&amp;nbsp;that&amp;nbsp;is&amp;nbsp;not&amp;nbsp;being&amp;nbsp;referenced.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* Unreachable objects are subject to GC collection.&lt;br /&gt;*&amp;nbsp;GC&amp;nbsp;Roots&amp;nbsp;:&amp;nbsp;Data&amp;nbsp;in&amp;nbsp;the&amp;nbsp;stack&amp;nbsp;area,&amp;nbsp;static&amp;nbsp;data&amp;nbsp;in&amp;nbsp;the&amp;nbsp;method&amp;nbsp;area,&amp;nbsp;and&amp;nbsp;objects&amp;nbsp;generated&amp;nbsp;by&amp;nbsp;JNI.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1235&quot; data-origin-height=&quot;977&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kOFPK/btrgHFlx7XG/s7vxdm8l1Sab4NxcKLb37K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kOFPK/btrgHFlx7XG/s7vxdm8l1Sab4NxcKLb37K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kOFPK/btrgHFlx7XG/s7vxdm8l1Sab4NxcKLb37K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkOFPK%2FbtrgHFlx7XG%2Fs7vxdm8l1Sab4NxcKLb37K%2Fimg.png&quot; data-origin-width=&quot;1235&quot; data-origin-height=&quot;977&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;How&amp;nbsp;does&amp;nbsp;gc&amp;nbsp;work?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;The basic principle of gc motion is as follows.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&quot;MARK and Sweep&quot;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1500&quot; data-origin-height=&quot;391&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c0rOmY/btrgMtlrRNe/9iwu6xt0FbpjJ2Js6dqRk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c0rOmY/btrgMtlrRNe/9iwu6xt0FbpjJ2Js6dqRk1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c0rOmY/btrgMtlrRNe/9iwu6xt0FbpjJ2Js6dqRk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc0rOmY%2FbtrgMtlrRNe%2F9iwu6xt0FbpjJ2Js6dqRk1%2Fimg.png&quot; data-origin-width=&quot;1500&quot; data-origin-height=&quot;391&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. &quot;Mark&quot; : From GC Root, GC scans all variables to find and mark which objects each is referring to. (The process of identifying a Reachable object and an Unreachable object)&lt;br /&gt;2. &quot;Sweep&quot; : Unreachable objects are removed from Heap.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;--&lt;br /&gt;3. (It can be added according to the algorithm) &quot;Compact&quot;: Sweep, collect the distributed objects to the starting address of Heap. And divide them into &quot;parts where memory is allocated&quot; and &quot;parts that are not&quot;. (It prevents memory fragmentation)&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;When&amp;nbsp;will&amp;nbsp;GC&amp;nbsp;happen&amp;nbsp;and&amp;nbsp;how&amp;nbsp;will&amp;nbsp;it&amp;nbsp;be&amp;nbsp;handled?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;First of all, We have to know concept for Heap.&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;The architecture of Heap is as follows.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;768&quot; data-origin-width=&quot;2720&quot; data-origin-height=&quot;1040&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uM5C2/btrgAUEP1yz/PeNLA6YbgNlUvz3NsXdSu0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uM5C2/btrgAUEP1yz/PeNLA6YbgNlUvz3NsXdSu0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uM5C2/btrgAUEP1yz/PeNLA6YbgNlUvz3NsXdSu0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuM5C2%2FbtrgAUEP1yz%2FPeNLA6YbgNlUvz3NsXdSu0%2Fimg.png&quot; width=&quot;768&quot; data-origin-width=&quot;2720&quot; data-origin-height=&quot;1040&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;The architecture of Heap&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* Young Generation(Eden, Survivor 0, Survivor 1): Newly created objects are located here. Because most objects become quickly inaccessible state, so many objects are created and disappeared only in the Young area. Minor GC occurs when an object disappears in this area.&lt;br /&gt;* Old Generation : The objects surviving for a long time in the Young area is copied here. Most of them are allocated larger than the Young Generation, and GC occurs less than the Young area as the size of them is large. Major GC occurs when an object disappears in this area.&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;Process of GC&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Eden =&amp;gt; Survivor(1,2) =&amp;gt; Old&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;What is Minor GC?&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* Occurs when the Eden area is full&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* At the same time, Minor GC also occurs in the Sirvivor area.&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;Sequence of Minor GC&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;768&quot; data-origin-width=&quot;1358&quot; data-origin-height=&quot;698&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/L43G2/btrgJYk2XDL/ur3rpuv46b5J5LkkRR2ls1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/L43G2/btrgJYk2XDL/ur3rpuv46b5J5LkkRR2ls1/img.png&quot; data-alt=&quot;In JVM, GC target area&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/L43G2/btrgJYk2XDL/ur3rpuv46b5J5LkkRR2ls1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FL43G2%2FbtrgJYk2XDL%2Fur3rpuv46b5J5LkkRR2ls1%2Fimg.png&quot; width=&quot;768&quot; data-origin-width=&quot;1358&quot; data-origin-height=&quot;698&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;In JVM, GC target area&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1-1. In Eden area, newly objects is created.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1-2. Objects are continuously created, and when the Eden area is full, it executes &quot;Minor GC&quot;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1-3. When &quot;Minor GC&quot; occurs in &quot;Eden&quot;, &quot;Mark&quot; executes about objects which existed in &quot;Eden&quot;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1-4. When &quot;Mark&quot; executes, Distinguish unreachable or reachable objects in &quot;Eden&quot;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1-5. Reachable objects move to &quot;Survivor 1 Area&quot; and the age number of them goes up by 1. (*Aging)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1-5. After &quot;Mark&quot; execution, Execute &quot;Sweep&quot; to remove unreachable objects in &quot;Eden Area&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;Important concept&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;*Objects must exist separately in the Survivor1 or Survivor2 area (When &quot;Minor GC&quot; is executed, one of the Survivor areas must be empty)&lt;/u&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-1. The&amp;nbsp;empty&amp;nbsp;Enden&amp;nbsp;area&amp;nbsp;creates&amp;nbsp;new&amp;nbsp;objects&amp;nbsp;again.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2-2. Step 1 is repeatly processed. Likewise, If &quot;Eden&quot; area is full, Execute &quot;Minor GC in Eden&quot;, Reachable objects move to &quot;Survivor Area&quot; that was not used in the previous step. Unreachable objects remove in &quot;Eden&quot;. Also, Execute &quot;Minor GC in Survivor which is executed in the previous step&quot;. Reachable objects move to &quot;Survivor Area&quot; that was not used in the previous step. Unreachable objects remove in Survivor which is executed in the previous step.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2-3. Likewise, Reachable objects that survived in &quot;Minor GC&quot; go up by 1. (*Aging)&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-1. When objects in &quot;Servivor Area&quot; reach its age threshold, its move to &quot;Old Generation&quot;. (*Promoted)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3-2. If &quot;Old Generation&quot; is full, &quot;Major GC(Full GC)&quot; is executed.&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;a href=&quot;https://youtu.be/Fe3TVCEJhzo?t=200&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;The&amp;nbsp;process&amp;nbsp;of&amp;nbsp;GC&amp;nbsp;generation.&lt;/a&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;What is Major GC?&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: If &quot;Old Generation&quot; is full, &quot;Stop-the-world&quot; is executed and then &quot;Major GC(Full GC)&quot; is executed.&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;Stop-the-world&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* JVM stops running the application to execute the GC.&lt;br /&gt;* All threads except threads running GC stop working.&lt;br /&gt;* After completing the GC work, Resume the discontinued works.&lt;br /&gt;* In most cases, Tuning GC is to reduce this stop-the-world time.&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;Type of Major GC (based on JDK 7)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*&amp;nbsp;Serial&amp;nbsp;GC&amp;nbsp;&amp;nbsp;&lt;br /&gt;*&amp;nbsp;Parallel&amp;nbsp;GC&amp;nbsp;&amp;nbsp;&lt;br /&gt;*&amp;nbsp;Parallel&amp;nbsp;Old&amp;nbsp;GC(Parallel&amp;nbsp;Compacting&amp;nbsp;GC)&amp;nbsp;&amp;nbsp;&lt;br /&gt;*&amp;nbsp;Concurrent&amp;nbsp;Mark&amp;nbsp;&amp;amp;&amp;nbsp;Sweep&amp;nbsp;GC&amp;nbsp;(CMS&amp;nbsp;또는&amp;nbsp;Mark&amp;nbsp;&amp;amp;&amp;nbsp;Sweep)&amp;nbsp;&amp;nbsp;&lt;br /&gt;*&amp;nbsp;G1(Garbage&amp;nbsp;First)&amp;nbsp;GC&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;Serial GC&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JVM option: -XX:+UseSerialGC&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;* Serial GC should never be used in the operating server.&lt;br /&gt;* Because It is made for a single core method, The process power is wasted.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* Serial&amp;nbsp;GC&amp;nbsp;is&amp;nbsp;suitable&amp;nbsp;for&amp;nbsp;fewer&amp;nbsp;memories&amp;nbsp;and&amp;nbsp;fewer&amp;nbsp;cores.&lt;br /&gt;* The &quot;Young area&quot; uses bump-the-pointer and TALBs methods.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* The &quot;Old area&quot; uses the Mark &amp;amp; Sweep Compact algorithm.&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;Parallel&amp;nbsp;GC&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JVM option: -XX:+UseParallelGC, -XX:ParallelGCThreads (Minor GC Thread Count)&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;* Serial GC has the same basic algorithm with Parallel GC.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* Parallel GC uses multi-thread for GC.&lt;br /&gt;* Parallel GC is suitable for multiple cores and large size memory.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* When throughput is more important than latency reduction(obtained using CMS GC), Use Parallel GC.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;2010&quot; data-origin-height=&quot;878&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bSZjx7/btrgOuqPUJh/zt7UretpQETVuSo4AG3RS1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bSZjx7/btrgOuqPUJh/zt7UretpQETVuSo4AG3RS1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bSZjx7/btrgOuqPUJh/zt7UretpQETVuSo4AG3RS1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbSZjx7%2FbtrgOuqPUJh%2Fzt7UretpQETVuSo4AG3RS1%2Fimg.png&quot; data-origin-width=&quot;2010&quot; data-origin-height=&quot;878&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&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;h3 data-ke-size=&quot;size23&quot;&gt;Parallel&amp;nbsp;Old&amp;nbsp;GC&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JVM&amp;nbsp;option:&amp;nbsp;-XX:+UseParallelOldGC,&amp;nbsp;-XX:ParallelGCThreads&amp;nbsp;(Minor,&amp;nbsp;Full&amp;nbsp;GC&amp;nbsp;Thread&amp;nbsp;Count)&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;* In Parallel GC, the GC algorithm in the Old region passes through Mark-Summary-Compaction.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* Unlike&amp;nbsp;Sweep,&amp;nbsp;the&amp;nbsp;Summary&amp;nbsp;step&amp;nbsp;goes&amp;nbsp;through&amp;nbsp;object&amp;nbsp;identification&amp;nbsp;for&amp;nbsp;the&amp;nbsp;area&amp;nbsp;where&amp;nbsp;GC&amp;nbsp;was&amp;nbsp;performed.&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;Concurrent Mark &amp;amp; Sweep GC(CMS GC)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JVM option: -XX:+UseConcMarkSweepGC&lt;br /&gt;&lt;br /&gt;* This is a more improved method than the GCs discussed earlier.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* Although its performance has improved, GC's process has become more complex.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* CMS GC is focused on minimizing STW(stop-the-world) time occurring during the GC process.&lt;br /&gt;* The concept of CMS GC is to identify the GC target in as much detail as possible and then take a short time to execute STW.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* CPU usage is higher than that of other GCs. Because the process of identifying GC targets is performed in various complicated steps.&lt;br /&gt;&lt;br /&gt;CMS GC : Initial Mark -&amp;gt; Concurrent Mark -&amp;gt; Remark -&amp;gt; Concurrent Sweep&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;316&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/n7WUL/btrgOuqQt5Z/Zik1A9WuCKiKQHVfILBJfK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/n7WUL/btrgOuqQt5Z/Zik1A9WuCKiKQHVfILBJfK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/n7WUL/btrgOuqQt5Z/Zik1A9WuCKiKQHVfILBJfK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fn7WUL%2FbtrgOuqQt5Z%2FZik1A9WuCKiKQHVfILBJfK%2Fimg.png&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;316&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Step &quot;Initial Mark&quot;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- It find reachable objects among the closest objects to the class loader. Therefore, the stopping time is very short.&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;Step &quot;Concurrent Mark&quot;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Check by following the objects referenced by the reachable objects which were checked in &quot;Initial Mark&quot;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- This step proceeds simultaneously while other threads are running.&lt;br /&gt;&lt;br /&gt;Step &quot;Remark&quot;&lt;br /&gt;- An object newly added or disconnected from reference is identified in the Current Mark step.&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;Step &quot;Concurrent Sweep&quot;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Cleaning up the garbage is performed.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- This work is also executed in a situation where other threads are being executed.&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;* The stop-the-world time is very short because it is a GC method that proceeds to this step.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* CMS GC is used when the response speed of all applications is very important, and it is also called Low Latency GC.&lt;br /&gt;&lt;br /&gt;However,&amp;nbsp;while&amp;nbsp;CMS&amp;nbsp;GC&amp;nbsp;has&amp;nbsp;the&amp;nbsp;advantage&amp;nbsp;of&amp;nbsp;short&amp;nbsp;stop-the-world&amp;nbsp;time,&amp;nbsp;the&amp;nbsp;following&amp;nbsp;disadvantages&amp;nbsp;exist.&lt;br /&gt;&lt;br /&gt;* It uses more memory and CPU than other GC methods.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* Compaction steps are not provided by default.&lt;br /&gt;* Therefore, when using CMS GC, it should be used after careful review.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* If you need a compaction operation because of many fragmented memories, you have to check how often and for how long the compaction operation is performed because STW time is longer than other GC STW time.&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;G1&amp;nbsp;GC&amp;nbsp;(G1:&amp;nbsp;Garbage&amp;nbsp;First)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JVM&amp;nbsp;option:&amp;nbsp;-XX:+UseG1GC&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;G1 manages heap memory in a different way than the gc discussed earlier.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Unlike parallel/CMS collectors, there is no continuous memory space with distinct boundaries from generation to generation&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Also, It has nothing to do with hemispherical heap layouts.&lt;br /&gt;&lt;br /&gt;G1 consists of a Region divided into logical units.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;The region allows generation to be placed discontinuously.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;And there is no need to collect the entire garbage every time the collector runs.&lt;br /&gt;&lt;br /&gt;The characteristics of G1 GC.&lt;br /&gt;* It is a gc developed for use in multi-processor systems with large memory.&lt;br /&gt;* It's much easier to tune than CMS.&lt;br /&gt;* They are less vulnerable for early promotion. (Early promotion is a problem in which the quota is too high to be promoted to the Old area too quickly.)&lt;br /&gt;* It has excellent scalability (especially break time) in large heap.&lt;br /&gt;* From Java 9, it is default gc.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;942&quot; data-origin-height=&quot;514&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bar41T/btrgDdqevwl/bodMKt943BQscvLTHkCTkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bar41T/btrgDdqevwl/bodMKt943BQscvLTHkCTkk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bar41T/btrgDdqevwl/bodMKt943BQscvLTHkCTkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbar41T%2FbtrgDdqevwl%2FbodMKt943BQscvLTHkCTkk%2Fimg.png&quot; data-origin-width=&quot;942&quot; data-origin-height=&quot;514&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;The heap of G1 consists of a region.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;The dictionary allows generations to be deployed discontinuously, and there is no need to collect the entire garbage every time the collector runs.&lt;br /&gt;&lt;br /&gt;The G1 collector tracks which objects are stored in which region through the Reserved Set (RSet).&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Thanks to this, G1 only needs to take out the Rset without having to go through the entire hip to find a reference looking inside the area.&lt;br /&gt;&lt;br /&gt;&lt;u&gt;The collection steps of G1 are as follows.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;Initial Mark-STW&quot;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- STW occurs.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Find the Survivor area referenced by objects existing in Old area.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;Root Region Scanning&quot;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Identify references pointing to the Old Area in the Survivor Area identified in &quot;Initial Mark-STW&quot; Step.&lt;br /&gt;&quot;Concurrent Mark&quot;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Find reachable objects throughout the heap.&lt;br /&gt;&quot;Remark-STW&quot;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- STW occurs.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Verify &quot;Concurrent Mark&quot; step and identify the objects that will finally survive. In this step, a snapshot-at-the-beginning (SATB) algorithm is used.&lt;br /&gt;&quot;Cleanup-STW&quot;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Stop the application (STW) and remove unused objects for the fewest reachable objects.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- After the STW is finished, and the completely empty region in the GC process is added to the Freelist to be reused.&lt;br /&gt;&quot;Copy&quot;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Copy the surviving objects of the relocation to GC but not completely empty during the Cleanup process to perform the Compaction operation by copying them to the new relocation.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;840&quot; data-origin-width=&quot;1004&quot; data-origin-height=&quot;250&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beUh91/btrgQBwDI6x/IrB40IYqO8u8vBpTWoqRW0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/beUh91/btrgQBwDI6x/IrB40IYqO8u8vBpTWoqRW0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/beUh91/btrgQBwDI6x/IrB40IYqO8u8vBpTWoqRW0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbeUh91%2FbtrgQBwDI6x%2FIrB40IYqO8u8vBpTWoqRW0%2Fimg.png&quot; width=&quot;840&quot; data-origin-width=&quot;1004&quot; data-origin-height=&quot;250&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&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;h3 data-ke-size=&quot;size23&quot;&gt;Since G1GC officially appeared in JDK 7, it has been widely used, so let's take a closer look at the setting options.&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-XX: G1HeapRegionSize&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Default: X&lt;br /&gt;Region&amp;nbsp;Size.&amp;nbsp;Can&amp;nbsp;be&amp;nbsp;set&amp;nbsp;from&amp;nbsp;1MB&amp;nbsp;to&amp;nbsp;32MB.&amp;nbsp;Minimum&amp;nbsp;heap&amp;nbsp;size&amp;nbsp;must&amp;nbsp;be&amp;nbsp;set&amp;nbsp;to&amp;nbsp;be&amp;nbsp;divided&amp;nbsp;into&amp;nbsp;2048&amp;nbsp;Region.&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;-XX:MaxGCPauseMillis&lt;br /&gt;Default:&amp;nbsp;200&lt;br /&gt;Maximum&amp;nbsp;time&amp;nbsp;of&amp;nbsp;STW&amp;nbsp;caused&amp;nbsp;by&amp;nbsp;G1GC.&amp;nbsp;G1&amp;nbsp;only&amp;nbsp;tries&amp;nbsp;to&amp;nbsp;match&amp;nbsp;the&amp;nbsp;set&amp;nbsp;value&amp;nbsp;as&amp;nbsp;much&amp;nbsp;as&amp;nbsp;possible,&amp;nbsp;but&amp;nbsp;it&amp;nbsp;is&amp;nbsp;not&amp;nbsp;a&amp;nbsp;guaranteed&amp;nbsp;value.&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;-XX:DefaultMinNewGenPercent&lt;br /&gt;Default:&amp;nbsp;5&lt;br /&gt;Minimum&amp;nbsp;size&amp;nbsp;of&amp;nbsp;the&amp;nbsp;heap&amp;nbsp;to&amp;nbsp;be&amp;nbsp;used&amp;nbsp;as&amp;nbsp;the&amp;nbsp;Young&amp;nbsp;area&amp;nbsp;(ratio&amp;nbsp;to&amp;nbsp;the&amp;nbsp;total&amp;nbsp;size&amp;nbsp;of&amp;nbsp;the&amp;nbsp;heap,&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;-XX:DefaultMaxNewGenPercent&lt;br /&gt;Default:&amp;nbsp;60&lt;br /&gt;Maximum&amp;nbsp;size&amp;nbsp;of&amp;nbsp;heap&amp;nbsp;to&amp;nbsp;be&amp;nbsp;used&amp;nbsp;as&amp;nbsp;Young&amp;nbsp;area&amp;nbsp;(ratio&amp;nbsp;to&amp;nbsp;total&amp;nbsp;heap&amp;nbsp;size,&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;-XX:ParallelGCThreads&lt;br /&gt;Default: X&lt;br /&gt;Number&amp;nbsp;of&amp;nbsp;threads&amp;nbsp;performing&amp;nbsp;GC&amp;nbsp;in&amp;nbsp;an&amp;nbsp;STW&amp;nbsp;situation.&amp;nbsp;If&amp;nbsp;the&amp;nbsp;number&amp;nbsp;of&amp;nbsp;CPU&amp;nbsp;cores&amp;nbsp;is&amp;nbsp;less&amp;nbsp;than&amp;nbsp;or&amp;nbsp;equal&amp;nbsp;to&amp;nbsp;8,&amp;nbsp;it&amp;nbsp;is&amp;nbsp;recommended&amp;nbsp;to&amp;nbsp;set&amp;nbsp;the&amp;nbsp;same&amp;nbsp;as&amp;nbsp;the&amp;nbsp;number&amp;nbsp;of&amp;nbsp;cores.&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;-XX:ConcGCThreads&lt;br /&gt;Default: X&lt;br /&gt;Number&amp;nbsp;of&amp;nbsp;threads&amp;nbsp;performing&amp;nbsp;Concurrent&amp;nbsp;Mark.&amp;nbsp;It&amp;nbsp;is&amp;nbsp;recommended&amp;nbsp;to&amp;nbsp;set&amp;nbsp;it&amp;nbsp;to&amp;nbsp;25%&amp;nbsp;of&amp;nbsp;Parallel&amp;nbsp;GCThreads.&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;-XX:InitiatingHeapOccupancyPercent&lt;br /&gt;Default:&amp;nbsp;45&lt;br /&gt;Option&amp;nbsp;to&amp;nbsp;perform&amp;nbsp;Mark&amp;nbsp;when&amp;nbsp;using&amp;nbsp;a&amp;nbsp;specific&amp;nbsp;percentage&amp;nbsp;(%)&amp;nbsp;of&amp;nbsp;the&amp;nbsp;hip&amp;nbsp;relative&amp;nbsp;to&amp;nbsp;the&amp;nbsp;total&amp;nbsp;size.&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;-XX:G1OldCSetRegionLiveThresholdPercent&lt;br /&gt;Default:&amp;nbsp;65&lt;br /&gt;The&amp;nbsp;ratio&amp;nbsp;of&amp;nbsp;the&amp;nbsp;Old&amp;nbsp;Region&amp;nbsp;size&amp;nbsp;at&amp;nbsp;which&amp;nbsp;the&amp;nbsp;mixed&amp;nbsp;GC&amp;nbsp;begins.&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;Memory Management&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Java does not directly access the memory area of the OS, but indirectly uses a virtual machine called JVM.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Take over all the tricky parts of memory management to Java virtual machine.&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;* Java's memory leakage?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- A phenomenon in which objects that are no longer used for memory leakage are not recovered by the garbage collection GC and are continuously accumulated. So, Major GC frequently occurs due to objects accumulated in the Old area, and the program's response speed is delayed, and eventually the program ends with an Out of Memory (OOM) error.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;In this way, Java has the advantage of using virtual machines (in addition to the advantage of being independent of the operating system) that memory leak at the OS level becomes impossible. But memoty leak can occur.&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;The reason is that if you hold a reference of an object that is not actually used in the program, the object will occupy memory (address space) as garbage objects that is not processed by GC and cannot be accessed and used within the program.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;Since Java's used memory is only likely to be used, there may be garbage objects, not objects that are being used logically and accurately, and these objects cause memory leaks.&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;Memory Leak Examples)&lt;br /&gt;- It usually occurs when objects stored in collections such as declarations of frequent global variables, lists, or hashmaps are maintained without releasing them.&lt;br /&gt;- When creating meaningless objects using rapper classes such as Integer and Long,&lt;br /&gt;- If the cache data is not declared and released in Map,&lt;br /&gt;- If you use a stream object and don't close it,&lt;br /&gt;- If you define the key of Map as a user object and do not override Equals() and hascode() and mistake it for the same key, and the data continues to accumulate.&lt;br /&gt;- If the key value of Map is not uncomfortable data and changes continuously when comparing data, although the key value is redefined by defining the key of Map as a user object.&lt;br /&gt;- If the data structure is created and used, and the memory is not released due to an implementation error,&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;Conclusion&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;I haven't experienced a large-scale project yet, so the topic of GC tuning doesn't touch much, but I think I need a deep understanding of GC to become a great Java developer.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;I think I need to know how GC works, how to tune, and what kind of memory leakage occurs so that I can write code with improved performance during a large scale of project.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Reference&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.oreilly.com/library/view/optimizing-java/9781492039259/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.oreilly.com/library/view/optimizing-java/9781492039259/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1633352641740&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;Optimizing Java&quot; data-og-description=&quot;Performance tuning is an experimental science, but that doesn&amp;rsquo;t mean engineers should resort to guesswork and folklore to get the job done. Yet that&amp;rsquo;s often the case. With this practical &amp;hellip; - Selection from Optimizing Java [Book]&quot; data-og-host=&quot;www.oreilly.com&quot; data-og-source-url=&quot;https://www.oreilly.com/library/view/optimizing-java/9781492039259/&quot; data-og-url=&quot;https://www.oreilly.com/library/view/optimizing-java/9781492039259/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cdsP4N/hyLPpNeK7E/FS3O5Q0KmL9kNKJjMVYko0/img.jpg?width=140&amp;amp;height=184&amp;amp;face=0_0_140_184&quot;&gt;&lt;a href=&quot;https://www.oreilly.com/library/view/optimizing-java/9781492039259/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.oreilly.com/library/view/optimizing-java/9781492039259/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cdsP4N/hyLPpNeK7E/FS3O5Q0KmL9kNKJjMVYko0/img.jpg?width=140&amp;amp;height=184&amp;amp;face=0_0_140_184');&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;Optimizing Java&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Performance tuning is an experimental science, but that doesn&amp;rsquo;t mean engineers should resort to guesswork and folklore to get the job done. Yet that&amp;rsquo;s often the case. With this practical &amp;hellip; - Selection from Optimizing Java [Book]&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.oreilly.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://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/cms.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/cms.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1633351037604&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;Concurrent Mark Sweep (CMS) Collector&quot; data-og-description=&quot;Concurrent Mode Failure The CMS collector uses one or more garbage collector threads that run simultaneously with the application threads with the goal of completing the collection of the tenured generation before it becomes full. As described previously, &quot; data-og-host=&quot;docs.oracle.com&quot; data-og-source-url=&quot;https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/cms.html&quot; data-og-url=&quot;https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/cms.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/cms.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/cms.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;Concurrent Mark Sweep (CMS) Collector&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Concurrent Mode Failure The CMS collector uses one or more garbage collector threads that run simultaneously with the application threads with the goal of completing the collection of the tenured generation before it becomes full. As described previously,&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.oracle.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://youtu.be/Fe3TVCEJhzo?t=200&quot;&gt;https://youtu.be/Fe3TVCEJhzo?t=200&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=Fe3TVCEJhzo&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/cJ3emy/hyLPotWkv5/anaHeVzY0y1BKVIpDOIBl1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=878_200_932_260&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/Fe3TVCEJhzo&quot; width=&quot;860&quot; height=&quot;484&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Java</category>
      <author>RyanGomdoriPooh</author>
      <guid isPermaLink="true">https://interconnection.tistory.com/139</guid>
      <comments>https://interconnection.tistory.com/139#entry139comment</comments>
      <pubDate>Tue, 5 Oct 2021 02:02:00 +0900</pubDate>
    </item>
    <item>
      <title>What is Java OOP(Object Oriented Programming)?</title>
      <link>https://interconnection.tistory.com/138</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;We have a lot of thoughts about OOP(Object Oriented Programming).&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;But many people can't answer easily. Some people answer SOLID principle.&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;From the beginning class, we are going to learn about the basics of OOPs in JAVA.&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;In order to implement OOP in JAVA, We have to satisfy a few things.&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;The concepts for OOP is as follows.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Class&lt;/li&gt;
&lt;li&gt;Object&lt;/li&gt;
&lt;li&gt;Abstraction&lt;/li&gt;
&lt;li&gt;Inheritance&lt;/li&gt;
&lt;li&gt;Encapsulation&lt;/li&gt;
&lt;li&gt;Polymorphism&lt;/li&gt;
&lt;li&gt;Attribute&lt;/li&gt;
&lt;li&gt;Method&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;762&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LKSZA/btrgAUYvfKk/dv4ofylUEer9ehkki3zjk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LKSZA/btrgAUYvfKk/dv4ofylUEer9ehkki3zjk1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LKSZA/btrgAUYvfKk/dv4ofylUEer9ehkki3zjk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLKSZA%2FbtrgAUYvfKk%2Fdv4ofylUEer9ehkki3zjk1%2Fimg.png&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;762&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;The aim of concepts is implementing real entities in programs.&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;So, We create class methods and variables to reuse them with capsulation.&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;OOP(Object-oriented programming) is composed of classes and objects.&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;I think SOLID or GRASP are important factors. Eventually We have to think &quot;Cohesion&quot; and &quot;Coupling&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;&quot;Cohesion&quot; and &quot;Coupling&quot; strengthen&amp;nbsp;reusability and responsibility for programming code.&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;It's easy to maintain codes which is implemented by &quot;Cohesion&quot; and &quot;Coupling&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;Of&amp;nbsp;course,&amp;nbsp;there&amp;nbsp;is&amp;nbsp;no&amp;nbsp;correct&amp;nbsp;answer&amp;nbsp;to&amp;nbsp;what&amp;nbsp;is&amp;nbsp;OOP.&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;Although we know that object orientation is literally aimed at objects, We are still looking at OOP centering on class or inheritance.&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;A&amp;nbsp;simple&amp;nbsp;way&amp;nbsp;to&amp;nbsp;design&amp;nbsp;OOP&amp;nbsp;is&amp;nbsp;as&amp;nbsp;follows.&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;The most important thing in OOP is to focus on the object and look at it.&lt;/li&gt;
&lt;li&gt;In&amp;nbsp;OOP,&amp;nbsp;objects&amp;nbsp;should&amp;nbsp;be&amp;nbsp;viewed&amp;nbsp;as&amp;nbsp;components&amp;nbsp;of&amp;nbsp;the&amp;nbsp;cooperative&amp;nbsp;community&amp;nbsp;to&amp;nbsp;implement&amp;nbsp;functions.&lt;/li&gt;
&lt;li&gt;It&amp;nbsp;is&amp;nbsp;to&amp;nbsp;give&amp;nbsp;appropriate&amp;nbsp;responsibilities&amp;nbsp;and&amp;nbsp;roles&amp;nbsp;to&amp;nbsp;objects&amp;nbsp;participating&amp;nbsp;in&amp;nbsp;cooperation.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;In conclusion, I think OOP is a way to make good codes that are easy to maintain.&lt;/p&gt;</description>
      <category>Java</category>
      <author>RyanGomdoriPooh</author>
      <guid isPermaLink="true">https://interconnection.tistory.com/138</guid>
      <comments>https://interconnection.tistory.com/138#entry138comment</comments>
      <pubDate>Sat, 2 Oct 2021 01:32:44 +0900</pubDate>
    </item>
    <item>
      <title>Jackson ObjectMapper 정리</title>
      <link>https://interconnection.tistory.com/137</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;개요&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Java 개발자라면 Jackson에서 제공하는 ObjectMapper와 자주 마주치게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Java 클래스 내용을 확인하거나 내용물의 Parsing 과정에 필요한 커스터마이징이 존재하기 때문입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 중요한 기능은 (1) &quot;Java Object&quot; =Serialize=&amp;gt; &quot;JSON&quot;, (2) &quot;JSON&quot; =Deserialize=&amp;gt; &quot;Java Object&quot; 입니다.&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;목차&lt;/b&gt;&lt;/h2&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Add Dependency for &quot;Jackson ObjectMapper&quot;&lt;/li&gt;
&lt;li&gt;Basic Features
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Convert &quot;Java Object&quot; to &quot;JSON&quot;&lt;/li&gt;
&lt;li&gt;Convert &quot;JSON&quot; to &quot;Java Object&quot;&lt;/li&gt;
&lt;li&gt;Convert &quot;JSON&quot; to &quot;Jackson JsonNode&quot;&lt;/li&gt;
&lt;li&gt;Convert &quot;JSON Array String&quot; to &quot;Java List&quot;&lt;/li&gt;
&lt;li&gt;Convert &quot;JSON String&quot; to &quot;Java Map&quot;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Advanced&amp;nbsp;Features
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Configuring&amp;nbsp;Serialization&amp;nbsp;or&amp;nbsp;Deserialization&amp;nbsp;Feature&lt;/li&gt;
&lt;li&gt;Creating&amp;nbsp;Custom&amp;nbsp;Serializer&amp;nbsp;or&amp;nbsp;Deserializer&lt;/li&gt;
&lt;li&gt;Handling&amp;nbsp;Date&amp;nbsp;Formats&lt;/li&gt;
&lt;li&gt;Handling&amp;nbsp;Collections&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. Add&amp;nbsp;Dependency&amp;nbsp;for&amp;nbsp;&quot;Jackson&amp;nbsp;ObjectMapper&quot;&lt;/b&gt;&lt;/h2&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;Maven의 경우)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 종속성을 pom.xml의 &amp;lt;dependencies&amp;gt;...&amp;lt;/dependencies&amp;gt;에 추가해줍니다.&lt;/p&gt;
&lt;pre id=&quot;code_1622293087316&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind --&amp;gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;com.fasterxml.jackson.core&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;jackson-databind&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;2.12.3&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Gradle의 경우)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 종속성을 build.gradle의 dependencies { ... }에 추가해줍니다.&lt;/p&gt;
&lt;pre id=&quot;code_1622293129426&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind
implementation 'com.fasterxml.jackson.core:jackson-databind:2.12.3'&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;다음 링크를 통해서 원하는 버전을 사용할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Jackson Databind 버전 확인 링크&lt;/a&gt;&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. Basic Features&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 User라는 Java Object가 존재한다고 가정하고, 2. Basic Features의 예시 코드를&amp;nbsp;보이겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1622433065427&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class User {

    private String name;
    private int age;
    
    public User(String name, int age) {
    	this.name = name;
        this.age = age;
    }
    
    public String getName() {
    	return name;
	}
    
    public int getAge() {
    	return age;
	}
}&lt;/code&gt;&lt;/pre&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.1. Convert&amp;nbsp;&quot;Java&amp;nbsp;Object&quot;&amp;nbsp;to&amp;nbsp;&quot;JSON&quot;&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1622432824765&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ObjectMapper objectMapper = new ObjectMapper();
User user = new User(&quot;Ryan&quot;, 30);

objectMapper.writeValue(new File(&quot;user.json&quot;), user);
// 파일 출력: user.json
{&quot;name&quot;:&quot;Ryan&quot;,&quot;age&quot;:30}
// 문자열 출력
String userAsString = objectMapper.writeValueAsString(user);
{&quot;name&quot;:&quot;Ryan&quot;,&quot;age&quot;:30}&lt;/code&gt;&lt;/pre&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.2. Convert&amp;nbsp;&quot;JSON&quot;&amp;nbsp;to&amp;nbsp;&quot;Java&amp;nbsp;Object&quot;&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1622437302016&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// String to Object
String json = &quot;{ \&quot;name\&quot; : \&quot;Ryan\&quot;, \&quot;age\&quot; : 30 }&quot;;
User user = objectMapper.readValue(json, User.class);
// JSON File to Object
User user = objectMapper.readValue(new File(&quot;user.json&quot;), User.class);
// JSON URL to Object
User user = objectMapper.readValue(new URL(&quot;file:user.json&quot;), User.class);&lt;/code&gt;&lt;/pre&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.3. Convert&amp;nbsp;&quot;JSON&quot;&amp;nbsp;to&amp;nbsp;&quot;Jackson&amp;nbsp;JsonNode&quot;&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1622437765803&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;String json = &quot;{ \&quot;name\&quot; : \&quot;Ryan\&quot;, \&quot;age\&quot; : 30 }&quot;;
JsonNode jsonNode = objectMapper.readTree(json);
String name = jsonNode.get(&quot;name&quot;).asText();// Ryan
int age = jsonNode.get(&quot;age&quot;).asInt();// 30&lt;/code&gt;&lt;/pre&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.4. Convert&amp;nbsp;&quot;JSON&amp;nbsp;Array&amp;nbsp;String&quot;&amp;nbsp;to&amp;nbsp;&quot;Java&amp;nbsp;List&quot;&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1622438611340&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;String jsonArr = &quot;[{\&quot;name\&quot;:\&quot;Ryan\&quot;,\&quot;age\&quot;:30},{\&quot;name\&quot;:\&quot;Jake\&quot;,\&quot;age\&quot;:20}]&quot;;
List&amp;lt;User&amp;gt; users = objectMapper.readValue(jsonArr, new TypeReference&amp;lt;&amp;gt;() {});&lt;/code&gt;&lt;/pre&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.5. Convert &quot;JSON String&quot; to &quot;Java Map&quot;&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1622631525656&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;String jsonArr = &quot;{\&quot;name\&quot;:\&quot;Ryan\&quot;,\&quot;age\&quot;:30}&quot;;
Map&amp;lt;String, Object&amp;gt; user = objectMapper.readValue(jsonArr, new TypeReference&amp;lt;&amp;gt;() {
});&lt;/code&gt;&lt;/pre&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;3. Advanced Features&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 설명한 Jackson Library의 Basic Features에 추가적으로 유용한 기능를 사용할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JSON과 Object에 대해서 커스터마이징한 Serialize/Deserialize가 가능한 기능을 사용할 수 있습니다.&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.1. Configuring Serialization or Deserialization Feature&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3.1.1. JSON에는 있지만 Mapping될 Object에는 없는 필드를 무시해야하는 경우&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1622981147525&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;String json = &quot;{\&quot;name\&quot;:\&quot;Ryan\&quot;,\&quot;age\&quot;:30,\&quot;sex\&quot;:\&quot;M\&quot;}&quot;;
// User Object에서는 &quot;sex&quot; field가 없습니다. 아래 설정을 안하게되면 익셉션이 발생합니다.
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
User user = objectMapper.readValue(json, User.class);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3.1.2. JSON에 있는 propety가 Mapping될 Object에 primitive인데 null 값이 전달을 무시해야하는 경우&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1623507654726&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;String json = &quot;{\&quot;name\&quot;:\&quot;Ryan\&quot;,\&quot;age\&quot;:null}&quot;;
// 기본적으로 FAIL_ON_NULL_FOR_PRIMITIVES 옵션은 false 상태입니다. 의도적으로 옵션을 설정해주었습니다.
// 옵션이 true가 되게되면, age가 int인 primitive 자료형이 null인 JSON이 전달되는 경우 익셉션을 발생합니다.
objectMapper.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false);
User user = objectMapper.readValue(json, User.class);&lt;/code&gt;&lt;/pre&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.2. Creating Custom Serializer or Deserializer&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JSON이 Object로 Deserialize될 때, 서로 다른 정보로 전달되고 있는데 Object나 JSON이 전달하는 모델을 변경하지 못하는 경우,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&quot;Custom Deserializer&quot;를 사용합니다.&lt;/u&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;Object이 JSON으로 Serialize될 때, 서로 다른 정보로 전달되고 있는데 Object나 JSON이 전달하는 모델을 변경하지 못하는 경우,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&quot;Custom Serializer&quot;를 사용합니다.&lt;/u&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;아래 Serializer와 Deserializer에 예시에 사용될 User Class입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1623595484902&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class User {
    private final int age;
	
    User(int age) {
    	this.age = age;
    }
}&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;&lt;b&gt;3.2.1. Custom Serializer Example&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;JSON&quot; =Custom Deserialize=&amp;gt; &quot;Object&quot;&lt;/p&gt;
&lt;pre id=&quot;code_1623595161474&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class CustomUserSerializer extends StdSerializer&amp;lt;Car&amp;gt; {
    public CustomUserSerializer() {
        this(null);
    }

    public CustomUserSerializer(Class&amp;lt;Car&amp;gt; t) {
        super(t);
    }

    @Override
    public void serialize(Car car, JsonGenerator jsonGenerator, SerializerProvider serializer) {
        jsonGenerator.writeStartObject();
        jsonGenerator.writeStringField(&quot;user_age&quot;, user.getAge());
        jsonGenerator.writeEndObject();
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1623595308931&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule(&quot;CustomUserSerializer&quot;, new Version(1, 0, 0, null, null, null));
module.addSerializer(User.class, new CustomUserSerializer());
mapper.registerModule(module);
User user = new User(20);
String userJson = mapper.writeValueAsString(user);
System.out.println(userJson);// {&quot;user_age&quot;:20}&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;&lt;b&gt;3.2.2. Custom Deserializer Example&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;Object&quot; =Custom Serialize=&amp;gt; &quot;JSON&quot;&lt;/p&gt;
&lt;pre id=&quot;code_1623596084719&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class CustomUserDeserializer extends StdDeserializer&amp;lt;User&amp;gt; {
    public CustomUserDeserializer() {
        this(null);
    }

    public CustomUserDeserializer(Class&amp;lt;?&amp;gt; vc) {
        super(vc);
    }

    @Override
    public User deserialize(JsonParser parser, DeserializationContext deserializer) {
        User user = new User();
        ObjectCodec codec = parser.getCodec();
        JsonNode node = codec.readTree(parser);
        
        // try catch block
        JsonNode ageNode = node.get(&quot;user_age&quot;);
        String age = ageNode.asText();
        user.setAge(age);
        return user;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1623596167659&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;String json = &quot;{ \&quot;user_age\&quot; : 30}&quot;;
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule(&quot;CustomUserDeserializer&quot;, new Version(1, 0, 0, null, null, null));
module.addDeserializer(User.class, new CustomUserDeserializer());
mapper.registerModule(module);
User user = mapper.readValue(json, User.class);&lt;/code&gt;&lt;/pre&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.3. Handling Date Formats&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Serialize를 하는 과정에서 Date로 구성된 Object field의 Format을 변경할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1623596598160&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class User {
    private int age;
    private Date createdAt;

    // getters, setters
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1623597518657&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;User user = new User();
user.setAge(30);
user.setCreatedAt(Date.from(Instant.now()));

ObjectMapper objectMapper = new ObjectMapper();
DateFormat df = new SimpleDateFormat(&quot;yyyy-MM-dd HH:mm a z&quot;);
objectMapper.setDateFormat(df);
String userAsString = objectMapper.writeValueAsString(user);
System.out.println(userAsString);// {&quot;age&quot;:30,&quot;createdAt&quot;:&quot;2021-06-10 11:43 AM CEST&quot;}&lt;/code&gt;&lt;/pre&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.4. Handling Collections&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JSON에 존재하는 복수개의 모델을 Collections 자료형으로 Deserialize할 수 있습니다.&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;Deserialize JSON to Array&lt;/p&gt;
&lt;pre id=&quot;code_1623597777595&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;String jsonUserArray = &quot;[{\&quot;age\&quot;:30,\&quot;createdAt\&quot;:\&quot;2021-06-10T11:43:12\&quot;},{\&quot;age\&quot;:30,\&quot;createdAt\&quot;:\&quot;2021-06-10T11:43:12\&quot;}]&quot;;
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY, true);
User[] users = objectMapper.readValue(jsonCarArray, User[].class);
// print users&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또는 Deserialize JSON to List&lt;/p&gt;
&lt;pre id=&quot;code_1623597804314&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;String jsonUserArray = &quot;[{\&quot;age\&quot;:30,\&quot;createdAt\&quot;:\&quot;2021-06-10T11:43:12\&quot;},{\&quot;age\&quot;:30,\&quot;createdAt\&quot;:\&quot;2021-06-10T11:43:12\&quot;}]&quot;;
ObjectMapper objectMapper = new ObjectMapper();
List&amp;lt;User&amp;gt; listUser = objectMapper.readValue(jsonCarArray, new TypeReference&amp;lt;List&amp;lt;User&amp;gt;&amp;gt;(){});
// print users&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;결론&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;잘 정리되어있던 참고자료에 있는 포스트를 통해서 하나씩 코드를 돌려보면서 정리하였습니다.&lt;/li&gt;
&lt;li&gt;Java를 쓰다보면 Jackson 라이브러리를 직접적인 코드를 사용하거나 Annotation을 사용하는 경우가 많습니다.&lt;/li&gt;
&lt;li&gt;그중에서 ObjectMapper를 직접 사용하는 것에 대한 정리를 이 포스트에 업데이트해나가겠습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;참고자료&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://www.baeldung.com/jackson-object-mapper-tutorial&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.baeldung.com/jackson-object-mapper-tutorial&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&quot;og_1622428162875&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;Intro to the Jackson ObjectMapper | Baeldung&quot; data-og-description=&quot;The article discusses Jackson's central ObjectMapper class, basic serialization and deserialization as well as configuring the two processes.&quot; data-og-host=&quot;www.baeldung.com&quot; data-og-source-url=&quot;https://www.baeldung.com/jackson-object-mapper-tutorial&quot; data-og-url=&quot;https://www.baeldung.com/jackson-object-mapper-tutorial&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dZxwPJ/hyKoZOZCpr/EsnjScAYmIy8vmjqXSuIZK/img.jpg?width=952&amp;amp;height=498&amp;amp;face=0_0_952_498,https://scrap.kakaocdn.net/dn/mjMW2/hyKoUGUfxq/Qq4Kt1WnhhIqGEFODgZnrK/img.jpg?width=952&amp;amp;height=498&amp;amp;face=0_0_952_498&quot;&gt;&lt;a href=&quot;https://www.baeldung.com/jackson-object-mapper-tutorial&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.baeldung.com/jackson-object-mapper-tutorial&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dZxwPJ/hyKoZOZCpr/EsnjScAYmIy8vmjqXSuIZK/img.jpg?width=952&amp;amp;height=498&amp;amp;face=0_0_952_498,https://scrap.kakaocdn.net/dn/mjMW2/hyKoUGUfxq/Qq4Kt1WnhhIqGEFODgZnrK/img.jpg?width=952&amp;amp;height=498&amp;amp;face=0_0_952_498');&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;Intro to the Jackson ObjectMapper | Baeldung&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The article discusses Jackson's central ObjectMapper class, basic serialization and deserialization as well as configuring the two processes.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.baeldung.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>Java</category>
      <author>RyanGomdoriPooh</author>
      <guid isPermaLink="true">https://interconnection.tistory.com/137</guid>
      <comments>https://interconnection.tistory.com/137#entry137comment</comments>
      <pubDate>Mon, 14 Jun 2021 00:40:48 +0900</pubDate>
    </item>
    <item>
      <title>자바 인터페이스(Java Interface)는 무엇인가?</title>
      <link>https://interconnection.tistory.com/129</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;개요&lt;/h2&gt;
&lt;p&gt;&quot;자바 인터페이스(Java Interface)는 무엇인가?&quot;&lt;/p&gt;
&lt;p&gt;이런 궁금점을 가지고 있는 Java Programmer가 많습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;저는&amp;nbsp;&lt;a href=&quot;https://velog.io/@lsb156/%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5-%EA%B0%9C%EB%B0%9C-5%EB%8C%80-%EC%9B%90%EC%B9%99-SOLID&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&quot;객체 지향 개발 5대 원칙 - SOLID&quot;&lt;/a&gt;을 만족시켜줄 수 있어서라고 생각합니다.&lt;/p&gt;
&lt;p&gt;그러면 &quot;왜 SOLID를 만족시켜야 하는가?&quot;라는 질문을 가지게 됩니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;서비스 애플리케이션의 라이프사이클을 &quot;설계 / 개발 / 유지보수&quot; 세 단계로 나누면,&lt;/p&gt;
&lt;p&gt;유지보수가 소프트웨어 라이프사이클에서 가장 큰 부분을 차지합니다.&lt;/p&gt;
&lt;p&gt;유지보수에서 인터페이스(interface)는 SOLID를 구현하고, 객체 지향 개발을 하는데 큰 도움을 줍니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&quot;설계 / 개발 / 유지보수&quot; 관점에서 객체 지향을 설명하면, &lt;/span&gt;다음과 같은 장점이 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;객체 지향 사용하여, 대상을 추상화를 하고, 추상화된 대상의 행동을 묘사하면서, 설계를 쉽게 할 수 있게 합니다.&lt;/li&gt;
&lt;li&gt;설계가 끝나고, 개발하게 되는데, 개발자는 설계된 추상화 객체 단위로 쉽게 대상을 이해할 수 있습니다.&lt;/li&gt;
&lt;li&gt;개발이 완료되고 유지보수를 하면, 기존 코드와 로직을 그대로 두고, 새로운 기능을 유연하게 추가할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;그럼 다시&amp;nbsp;&lt;span style=&quot;color: #333333;&quot;&gt;&quot;자바 인터페이스(Java interface)는 무엇인가?&quot;로 돌아와서,&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;자바 인터페이스(Java interface)가 &quot;객체 지향&quot;에 어떤 도움을 주는지 알아보도록 하겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;목차&lt;/h2&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;인터페이스(interface) 역할&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;인터페이스(interface) 선언&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;인터페이스(interface) 구현&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;인터페이스(interface) 사용&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;인터페이스(interface) 타입 변환과 다형성&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;인터페이스(interface) 상속&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;인터페이스(interface) 디폴트 메서드와 확장&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. &lt;span style=&quot;color: #333333;&quot;&gt;인터페이스(interface)&lt;/span&gt;&amp;nbsp;역할&lt;/h2&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;인터페이스는 어떤 역할을 할까요?&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;인터페이스는 객체를 어떻게 구성해야 하는지 정리한 설계도입니다.&lt;/li&gt;
&lt;li&gt;인터페이스는 객체의 교환성(또는 다형성)을 높여줍니다.&lt;/li&gt;
&lt;li&gt;인터페이스 변수에 인터페이스가 구현된 서로 다른 구현 객체를 할당해서 사용이 가능합니다.&lt;/li&gt;
&lt;li&gt;구현 객체를 직접 몰라도 인터페이스 메서드만 알아도 객체 호출이&lt;span&gt;&amp;nbsp;&lt;/span&gt;가능하게 합니다.&lt;/li&gt;
&lt;li&gt;객체가 인터페이스를 사용하면, 인터페이스 메서드를 반드시 구현해야 하는 제약을 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;위 특징을 이용해서 얻고자 하는 인터페이스(interface) 역할은 다음과 같습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;Screen Shot 2020-11-22 at 7.13.15 PM.png&quot; data-origin-width=&quot;1028&quot; data-origin-height=&quot;528&quot; width=&quot;498&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brgAeM/btqN2VpqaBi/kanTFm2nCAyOjYIQL95Bik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brgAeM/btqN2VpqaBi/kanTFm2nCAyOjYIQL95Bik/img.png&quot; data-alt=&quot;인터페이스의 역할&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brgAeM/btqN2VpqaBi/kanTFm2nCAyOjYIQL95Bik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbrgAeM%2FbtqN2VpqaBi%2FkanTFm2nCAyOjYIQL95Bik%2Fimg.png&quot; data-filename=&quot;Screen Shot 2020-11-22 at 7.13.15 PM.png&quot; data-origin-width=&quot;1028&quot; data-origin-height=&quot;528&quot; width=&quot;498&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;인터페이스의 역할&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;u&gt;&lt;b&gt;&quot;interface를 이용하여, 개발 코드를 직접 수정하지 않고도, 사용하고 있는 객체만 변경할 수 있도록 하기 위함입니다.&quot;&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 인터페이스(interface) 선언&lt;/h2&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;인터페이스(Interface) &lt;/span&gt;선언 형식은 다음과 같이합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;인터페이스(Interface)&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1606137206710&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[public] interface 인터페이스이름 { ... }
// 예시
public interface User { ... }&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&quot;인터페이스이름&quot;은 Upper CamelCase로 작성되어야 합니다.&lt;/li&gt;
&lt;li&gt;interface도 Class, Enum, Annotation처럼 &quot;~.java&quot; 파일로 작성되고, 컴파일러(javac.exe)를 통해서 바이트코드 형태의 &quot;~.class&quot; 파일로 컴파일됩니다.&lt;/li&gt;
&lt;li&gt;interface는 접근 지정자로 public을 사용하면, 다른 패키지에서도 사용이 가능합니다. public을 사용하지 않으면, interface가 위치한 해당 패키지 내에서만 사용이 가능합니다.&lt;/li&gt;
&lt;li&gt;interface의 접근 지정자는 public만 가능합니다. 이유는 interface는 class 설계도 이기 때문에 애초에 존재 목적이 공개이기 때문입니다.&lt;/li&gt;
&lt;li&gt;interface는 객체로 생성할 수 없기 때문에, 생성자를 가질 수 없습니다.&lt;/li&gt;
&lt;li&gt;class는 상수 필드, 정적 필드, 인스턴스 필드, 생성자, 인스턴스 메서드, 정적 메서드를 구성 멤버로 가지는데, interface는 상수 필드, 추상 메서드, 디폴트 메서드, 정적 메서드를 구성 멤버로 가집니다.&lt;/li&gt;
&lt;li&gt;Java 7까지는 실행 블록이 없는 추상 메서드로만 선언이 가능했습니다. Java 8부터는 디폴트 메서드와 정적 메서드도 선언이 가능합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;인터페이스(Interface) 구성요소는 다음과 같습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;2-1. 상수 필드(Constant Field)&lt;/p&gt;
&lt;p&gt;2-2. 추상 메서드(Abstract Method)&lt;/p&gt;
&lt;p&gt;2-3. 디폴트 메서드(Default Method)&lt;/p&gt;
&lt;p&gt;2-4. 정적 메서드(Static Method)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;2-1. 상수 필드(Constant Field)&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1606063002207&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public interface User {
    // 상수 필드(Constant Field)
    [public static final] 필드타입 상수명 = 값;
    // 예시
    String FIRST_NAME = &quot;Ryan&quot;; // 또는
    public static final String FIRST_NAME = &quot;Ryan&quot;; // 는 같다.
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;인터페이스는 객체가 될 수 없기 때문에, 런타임에 필드 데이터를 저장할 수 없습니다. 그래서 인스턴스 필드/ 정적 필드는 선언이 불가능합니다.&lt;/li&gt;
&lt;li&gt;상수 필드는 Compile Time에 선언되고 Run Time에 변경되지 않으므로 인터페이스에 선언이 가능합니다.&lt;/li&gt;
&lt;li&gt;[public static final]는 명시적으로 사용하지 않아도, Compile Time에 자동으로 선언되어 상수로 만듭니다.&lt;/li&gt;
&lt;li&gt;네이밍은 모두 대문자로 구성되고 구분자는 &quot;_&quot;(언더바)로 표현됩니다. (Java Convention)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;b&gt;2-2.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;추상 메서드(Abstract Method)&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1606137225710&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public interface User {
    // 추상 메서드(Abstract Method)
    [public abstract] 리턴타입 메서드이름(매개변수, ...);
    // 예시
    String sendMoney(Money money); // 와
    public abstract String sendMoney(Money money); // 는 같다.
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;인터페이스 변수로 호출된 메서드는 최종적으로 구현 객체에서 실행됩니다. 그래서 실체는 인터페이스에 없고, 구현 클래스에 있습니다.&lt;/li&gt;
&lt;li&gt;추상 메서드는 리턴 타입 / 메서드 이름 / 매개변수 가 기술되는 클래스 설계 메서드입니다.&lt;/li&gt;
&lt;li&gt;[public abstract]은&lt;span style=&quot;letter-spacing: 0px;&quot;&gt; 명시적으로 선언하지 않아도, Compile Time에 자동으로 선언됩니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;b&gt;2-3.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;디폴트 메서드(Default Method)&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1606137227027&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public interface User {
    // 디폴트 메서드(Default Method)
    [public] default 리턴타입 메서드이름(매개변수, ...) { ... }
    // 예시
    public default void setStatus(Status status) {
        if(status == Status.ACTIVE) {
            System.out.println(&quot;사용자가 활성화 되었습니다&quot;);
            return;
        }
        System.out.println(&quot;사용자가 비활성화 되었습니다&quot;);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Java 8에서 추가된 인터페이스의 멤버입니다.&lt;/li&gt;
&lt;li&gt;클래스의 인스턴스 메서드와 동일합니다. 즉, 인스턴스 메서드입니다. 다만 인터페이스에서 선언할 때, 리턴 타입 앞에 default 키워드가 붙습니다.&lt;/li&gt;
&lt;li&gt;[public]은&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;명시적으로 사용하지 않아도, Compile Time에 자동 선언됩니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;디폴트 메서드는 나중에 인터페이스를 구현한 구현 클래스에 인스턴스 메서드로 추가됩니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;재정의(Override)를 통해서 구현 클래스에서 재정의된 인스턴스 메서드로 사용할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;b&gt;2-4.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;정적 메서드(Static Method)&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1606137228499&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public interface User {
    // 정적 메서드(Static Method)
    [public] static 리턴타입 메서드이름(매개변수, ...) { ... }
    // 예시
    public static void printFirstName() {
        System.out.println(&quot;나의 이름은 &quot; + firstName + &quot;입니다.&quot;);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Java 8에서 추가된 인터페이스의 멤버입니다.&lt;/li&gt;
&lt;li&gt;선언 형식은 클래스 정적 메서드와 완전 동일합니다.&lt;/li&gt;
&lt;li&gt;[public]은&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;명시적으로 사용하지 않아도, Compile Time에 자동으로 선언됩니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;인터페이스의 정적 메서드도 클래스의 정적 메서드와 똑같은 방식으로 사용이 가능합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;인터페이스(interface) 구현&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;개발 코드에서 인터페이스의 메서드를 호출하면, 인터페이스는 구현 객체의 메서드를 찾아서 호출합니다.&lt;/p&gt;
&lt;p&gt;객체는 인터페이스에 있는 추상 메서드를 구현한 실체 메서드를 가지고 있어야 합니다.&lt;/p&gt;
&lt;p&gt;인터페이스를 구현한 객체를 구현 객체(구현체)라고 합니다.&lt;/p&gt;
&lt;p&gt;구현 객체를 생성하는 클래스를 구현 클래스라고 합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;인터페이스 구현 방식은 세 가지 방식이 있습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;3-1. 단일 인터페이스 구현 클래스(Single Interface Implement Class)&lt;/p&gt;
&lt;p&gt;3-2. 다중 인터페이스 구현 클래스(Multiple Interface Implement Class)&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;3-3. 익명 구현 객체(Anonymous Implement Object)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;세 가지 방식에 대해서 설명하겠습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;b&gt;3-1.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;단일 인터페이스 구현 클래스(Implement Class)&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1606144484808&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class 구현클래스이름 implements 인터페이스이름 {
    // 인터페이스의 추상 메서드를 구현한 실체 메서드를 선언하는 부분
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;인터페이스 예시를 먼저 제시하겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1606203895120&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public interface User {

    public static final String FIRST_NAME = &quot;Ryan&quot;;

    public abstract String sendMoney(Money money);

    public default void setStatus(Status status) {
        if(status == Status.ACTIVE) {
            System.out.println(&quot;사용자가 활성화 되었습니다&quot;);
            return;
        }
        System.out.println(&quot;사용자가 비활성화 되었습니다&quot;);
    }

    public static void printFirstName() {
        System.out.println(&quot;나의 이름은 &quot; + firstName + &quot;입니다.&quot;);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;인터페이스 예시를 구현한 구현 클래스 예시입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1606203647395&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class Recipient implements User {

    // 추상 메서드는 다음처럼 실체 메서드를 정의해야합니다.
    public String sendMoney(Money money) {
        thirdpartyApi.send(money.getType(), money.getAmount());
        return Status.SUCCESS.name();
    }

    // 디폴트 메서드는 재정의가 가능합니다.
    // 재정의 하지 않으면, 인터페이스에 정의된 내용 그대로 사용됩니다.
    @Override
    public default void setStatus(Status status) {
        if(status == Status.ACTIVE) {
            System.out.println(&quot;수취인이 활성화 되었습니다&quot;);
            return;
        }
        System.out.println(&quot;수취인이 비활성화 되었습니다&quot;);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;만약 인터페이스를 구현한다고 하고, 추상 메서드를 구현 클래스에서 실체 메서드를 모두 작성하지 않으면 해당 구현 클래스는 추상 클래스로 선언되어야 합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1606211248085&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public abstract class Recipient implements User {

}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;인터페이스 변수에 구현 객체 대입 예시&lt;/p&gt;
&lt;pre id=&quot;code_1606211021347&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// User 인터페이스를 구현한 구현 클래스 Recipient
public class Recipient implements User { ... }
// User 인터페이스를 구현한 구현 클래스 Sender
public class Sender implements User { ... }

User user = new Recipient();
user = new Sender();&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;3-2. 다중 인터페이스 구현 클래스(Multiple Interface Implement Class)&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1606218875290&quot; class=&quot;java&quot; style=&quot;margin: 20px auto 0px; display: block; overflow: auto; padding: 15px; color: #383a42; background: #f6f7f8; font-size: 14px; border-radius: 3px; font-family: Menlo, Consolas, Monaco, monospace; border: 1px solid #dddddd; cursor: default; z-index: 1; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class 구현클래스이름 implements 인터페이스이름1, 인터페이스이름2 {
    // 인터페이스의 추상 메서드를 구현한 실체 메서드를 선언하는 부분
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;인터페이스를 구현한 구현 클래스는 다중 인터페이스를 구현 가능합니다.&lt;/li&gt;
&lt;li&gt;다중 인터페이스를 구현한 구현 클래스는 반드시 모든 인터페이스의 추상 메서드를 실체 메서드로 구현해야 합니다.&lt;/li&gt;
&lt;li&gt;하나라도 추상 메서드가 구현되지 않으면, 구현 클래스는 추상 클래스로 선언되어야 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;b&gt;3-3.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;익명 구현 객체(Anonymous Implement Object)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;구현 클래스를 만들어서 사용하는 것이 일반적이고, 재사용이 가능하기에 편리합니다. 하지만 일회성으로 사용하는 구현 클래스는 클래스로 만들어서 선언해서 쓰는 것이 비효율적입니다.&lt;/li&gt;
&lt;li&gt;비효율을 개선하기 위해서 만들어진 것이 익명 구현 객체입니다. 익명 구현 객체는 임시 작업 스레드를 만들기 위해 많이 활용됩니다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;특징 중에 하나는 new 키워드 뒤에 원래는 인터페이스 구현 클래스 이름이 와야 하는데, 익명 구현 객체의 경우에는 참조할 구현 클래스가 없기 때문에 User 인터페이스 이름을 그대로 사용합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;다만, 익명 구현 객체의 구현 부에는 인터페이스의 추상 메서드가 아닌 실체 메서드를 선언해야 합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;익명 구현 객체 예시&lt;/p&gt;
&lt;pre id=&quot;code_1606214865483&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 인터페이스에 선언된 추상 메서드의 실체 메서드 선언
User user = new User() {
    public String sendMoney(Money money) {
        thirdpartyApi.send(money.getType(), money.getAmount());
        return Status.SUCCESS.name();
    }

    @Override
    public default void setStatus(Status status) {
        if(status == Status.ACTIVE) {
            System.out.println(&quot;수취인이 활성화 되었습니다&quot;);
            return;
        }
        System.out.println(&quot;수취인이 비활성화 되었습니다&quot;);
    }
};&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;그렇다고 익명 구현 객체를 사용한다고 해서, 클래스가 생성되지 않는 것은 아닙니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;익명 구현 객체가 사용된 자바 파일을 컴파일을 하게 되면 자동으로 익명 구현 객체의 클래스 파일이 생성됩니다.&lt;/p&gt;
&lt;p&gt;생성된 익명 구현 클래스 파일은 이름은 다음과 같습니다.&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;[익명 구현 객체가 사용된 자바 파일]$[번호].class (&lt;span style=&quot;color: #333333;&quot;&gt;[번호]는 1부터 시작되어, 증가합니다.)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;ex) TestExample$1.class&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;인터페이스(interface) 사용&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;인터페이스 변수는 참조 타입이기 때문에 구현 객체가 대입될 경우 구현 객체의 번지가 저장됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1606222654520&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;User sender = new Sender(); // User 인터페이스 참조변수 sender에 Sender 객체의 번지 저장
User recipient = new Recipient(); // User 인터페이스 참조변수 recipient에 Recipient 객체의 번지 저장&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;u&gt;인터페이스 변수는 다음 5개의 부분에서 구현 객체의 참조 용도로 사용될 수 있습니다.&lt;/u&gt;&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;생성자의 파라미터&lt;/li&gt;
&lt;li&gt;생성자의 로컬 변수&lt;/li&gt;
&lt;li&gt;메서드의 파라미터&lt;/li&gt;
&lt;li&gt;메서드의 로컬 변수&lt;/li&gt;
&lt;/ol&gt;
&lt;pre id=&quot;code_1606223532915&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class TestClass {
    // 1.클래스의 필드
    User user = new Recipient();
    
    // 2.생성자의 파라미터
    TestClass(User user) {
    	this.user = user;
    	// 3.생성자의 로컬변수
    	User recipient = new Recipient();        
    }

    // 4.메서드의 파라미터
    void methodA(User user) {
    	...
    }

    void methodB() {
        // 5.메서드의 로컬변수
    	User user = new Recipient();
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;이 부분부터는 인터페이스의 구성요소를 어떻게 사용하는지 살펴보겠습니다.&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;4-1. 상수 필드(Constant Field) 사용&lt;/p&gt;
&lt;p&gt;4-2. 추상 메서드(Abstract Method) 사용&lt;/p&gt;
&lt;p&gt;4-3. 디폴트 메서드(Default Method) 사용&lt;/p&gt;
&lt;p&gt;4-4. 정적 메서드(Static Method) 사용&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;설명을 위해서 User 인터페이스를 예시 용도로 가져왔습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1606225281880&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public interface User {

    public static final String FIRST_NAME = &quot;Ryan&quot;;

    public abstract String sendMoney(Money money);

    public default void setStatus(Status status) {
        if(status == Status.ACTIVE) {
            System.out.println(&quot;사용자가 활성화 되었습니다.&quot;);
            return;
        }
        System.out.println(&quot;사용자가 비활성화 되었습니다.&quot;);
    }

    public static void printFirstName() {
        System.out.println(&quot;나의 이름은 &quot; + firstName + &quot;입니다.&quot;);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;4-1. 상수 필드(Constant Field) 사용&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1606225415101&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;User.FIRST_NAME&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;위 방식으로 상수는 클래스의 상수와 같은 방식으로 사용할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;4-2. 추상 메서드(Abstract Method) 사용&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1606225521115&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class Example {
    public static void main(String[] args) {
        User user = null;
        
        user = new Recipient();
        user.sendMoney(new Money(1l));// Recipient가 1원을 보냈다.
        
        user = new Sender();
        user.sendMoney(new Money(2l));// Sender가 2원을 보냈다.
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;user 인터페이스의 추상 메서드 sendMoney를 호출하면, 인터페이스 변수에 대입되었던 구현 객체의 주소를 판단해서 해당하는 실체 메서드를 호출합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;4-3. 디폴트 메서드(Default Method) 사용&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1606225965033&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class Example {
    public static void main(String[] args) {
        User user = null;
        
        user = new Recipient();
        user.setStatus(Status.ACTIVE); // 사용자가 활성화 되었습니다.
        
        user = new Sender();
        user.setStatus(Status.INACTIVE); // 사용자가 비활성화 되었습니다.
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;구현 클래스에 실체 메서드를 작성하지 않아도 구현 객체에서 호출이 가능합니다.&lt;/p&gt;
&lt;p&gt;물론, 구현 클래스에서 디폴트 메서드가 변경이 필요한 경우, 재정의(Override)가 가능합니다.&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;추상 메서드가 아니고 인스턴스 메서드이기 때문에 생성한&amp;nbsp;&lt;/span&gt;구현 객체가 있어야 사용할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;디폴트 메서드를 재정의한 예시를 보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1606226746471&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class Recipient implements User {

    @Override
    public default void setStatus(Status status) {
        if(status == Status.ACTIVE) {
            System.out.println(&quot;수취인이 활성화 되었습니다.&quot;);
            return;
        }
        System.out.println(&quot;수취인이 비활성화 되었습니다.&quot;);
    }
}

public class Sender implements User {

    @Override
    public default void setStatus(Status status) {
        if(status == Status.ACTIVE) {
            System.out.println(&quot;송신자가 활성화 되었습니다.&quot;);
            return;
        }
        System.out.println(&quot;송신자가 비활성화 되었습니다.&quot;);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1606226903243&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class Example {
    public static void main(String[] args) {
        User user = null;
        
        user = new Recipient();
        user.setStatus(Status.ACTIVE); // 수취인이 활성화 되었습니다.
        
        user = new Sender();
        user.setStatus(Status.INACTIVE); // 송신자가 비활성화 되었습니다.
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;구현 클래스에서 재정의된 디폴트 메서드가 사용되어 호출됩니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;4-4. 정적 메서드(Static Method) 사용&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1606227217479&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class Example {
    public static void main(String[] args) {
        User.printFirstName(); // 나의 이름은 Ryan입니다.
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;인터페이스의 정적 메서드도 클래스의 정적 메서드와 같은 방식으로 사용합니다.&lt;/p&gt;
&lt;p&gt;정적 메서드이기 때문에 재정의(Override)는 불가능합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;5. &lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;인터페이스(interface) 타입 변환과 다형성&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;인터페이스는 다형성을 이용해서 타입 변환을 합니다. 타입 변환에 대한 이야기 하기에 앞서서 다형성에 대해서 알아보겠습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;다형성(Polymorphism) 이란?&lt;/p&gt;
&lt;p&gt;: 하나의 타입 변수에 대입되는 객체에 따라서 실행 결과가 다양한 타입의 형태로 나오는 성질을 이야기합니다. 즉, 하나의 타입 변수를 동일한 메서드로 동작시키지만 실제 동작은 다를 수 있는 성질입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;인터페이스를 사용해서 다형성을 사용하면, 사용할 구현 객체만 바꿔주면 나머지 소스코드는 변경할 필요가 없습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1606404199259&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Interface i = new ImplementObjectA();
// i를 수정해도
i = new ImplementObjectB();

// 변경이 없습니다.
i.method1();
i.method2();&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;상속에서도 부모 클래스 타입의 변수에 어떤 자식 객체를 대입하냐에 따라서 객체의 메서드 실행 결과는 달라질 수 있습니다.&lt;/p&gt;
&lt;p&gt;결국, 상속에서도 인터페이스와 마찬가지로 다형성을 구현하고 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1606404629845&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ParentClass p = new ChildClassA();
// 자식 객체로 대입이 가능하다. (다형성)
p = new ChildClassB();

// 다만, ParentClass안에 구현된 메서드만 호출이 가능
p.methodAInParent();
p.methodBInParent();&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;인터페이스가 매개변수로 쓰이는 경우&lt;/p&gt;
&lt;pre id=&quot;code_1606405032294&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class UserService {
  // User 인터페이스를 매개변수로 사용.
  public void printUserType(User user) {
      user.printType();
  }
}

// User 인터페이스를 구현한 구현 객체 Recipient, Sender를 매개변수로 사용
userService.printUserType(new Recipient()); // 수취인입니다.
userService.printUserType(new Sender()); // 송신자입니다.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;간단하게 인터페이스와 상속 관계에서 타입 변환과 다형성에 대해서 살펴보았습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;여기서 조금 더 자세하게 &quot;타입 변환&quot;과 &quot;다형성&quot;에 대해서 알아보겠습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;5-1. 자동&amp;nbsp;타입&amp;nbsp;변환(Promotion)&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;5-2. 매개 변수의 다형성&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;5-3. 강제 타입 변환(Casting)&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;5-4. 객체 타입 확인(instanceof)&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;위에 나열한 목록 순서로 설명하겠습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;5-1.&lt;span&gt;&amp;nbsp;&lt;/span&gt;자동&amp;nbsp;타입&amp;nbsp;변환(Promotion)&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Runtime에 &lt;/span&gt;구현 객체가 인터페이스 타입의 참조 변수로 자동 변환하는 것을 &quot;자동 타입 변환(Promotion)&quot;이라고 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;자동 타입 변환은 인터페이스를 구현한 구현 클래스의 자식 클래스를 만들고, 자식 객체를 인터페이스의 변수에 담아도 다형성이 적용됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;그러면 왜 인터페이스를 구현한 클래스의 자식 클래스도 다형성이 적용되고 자동 타입 변환이 가능할까요?&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;부모 클래스인 구현 클래스는 자식 클래스에게 상속을 하고 나면,&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;인터페이스와 마찬가지로 부모 클래스에 대한 멤버를 자식 클래스에게 전달하게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;결국 부모 클래스는 이미 먼저 인터페이스를 통해서 추상 메서드를 실체 메서드로 구현하였기 때문에,&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;결국 구현된 실체 메서드가 자식 클래스에게 전달되는 것이 확실해집니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;u&gt;&lt;span style=&quot;color: #333333;&quot;&gt;그렇기 때문에 &lt;span style=&quot;color: #333333;&quot;&gt;인터페이스를 구현한 클래스의 자식 클래스도 다형성이 적용되고 자동 타입 변환이 가능합니다.&lt;/span&gt;&lt;/span&gt;&lt;/u&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;/span&gt;&lt;u&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;예시)&lt;/p&gt;
&lt;pre id=&quot;code_1606485394298&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 인터페이스 A
// 인터페이스 A를 구현한 클래스 B
// 인터페이스 A를 구현한 클래스 C
// 클래스 B를 상속한 자식 클래스 D
// 클래스 C를 상속한 자식 클래스 E

// B, C, D, E에는 printClassName를 자기 클래스 이름을 출력하는 로직이 재정의 되어있다고 가정합니다.

A a1 = new B(); // OK
a1.printClassName(); // B 클래스입니다.

A a2 = new C(); // OK
a2.printClassName(); // C 클래스입니다.

A a3 = new D(); // OK
a3.printClassName();
// 기본은 상속된 printClassName가 호출됩니다. &quot;B 클래스입니다.&quot;
// 만약 클래스 D의 printClassName를 재정의하면 &quot;D 클래스입니다.&quot;가 됩니다.

A a4 = new E(); // OK
a4.printClassName();
// 기본은 상속된 printClassName가 호출됩니다. &quot;C 클래스입니다.&quot;
// 만약 클래스 E의 printClassName를 재정의하면 &quot;E 클래스입니다.&quot;가 됩니다.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;5-2. 매개 변수의 다형성&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;매개 변수를 인터페이스 변수로 두고, 구현 객체를 대입해주면 다형성을 적용해서 사용할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;예시)&lt;/p&gt;
&lt;pre id=&quot;code_1606487294215&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 인터페이스
public interface User {
    void printType();
}

// 구현 클래스 &quot;Recipient&quot;
public class Recipient implements User {
    @Override
    public void printType() {
        System.out.println(&quot;수취인입니다.&quot;);
    }
}

// 구현 클래스 &quot;Sender&quot;
public class Sender implements User {
    @Override
    public void printType() {
        System.out.println(&quot;송신자입니다.&quot;);
    }
}

public class Mail {
    public void printUserType(User user) {
        user.printType();
    }
}

public class Main {
    public static void main(String[] args) {
        Mail mail = new Mail();
        mail.printUserType(new Recipient()); // User user = new Recipient(); &quot;수취인입니다.&quot;
        mail.printUserType(new Sender()); // User user = new Sender(); &quot;송신자입니다.&quot;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;5-3. 강제 타입 변환(Casting)&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;인터페이스의 변수를 구현 객체와 사용하면, 인터페이스에서 정의된 추상 메서드의 실체 메서드 이외에는 호출할 수 없습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;즉,&lt;/p&gt;
&lt;p&gt;&lt;u&gt;구현 클래스에 추가로 메서드를 구현하고,&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;&lt;u&gt;나중에 구현 객체를 사용할 때, 인터페이스 변수가 사용된다면,&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;&lt;u&gt;추가로 구현된 메서드는 호출이 되지 않습니다.&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그래서 다음 솔루션을 사용합니다.&lt;/p&gt;
&lt;p&gt;5-3-1. 직접 구현 클래스 변수에 구현 객체를 대입하는 방법&lt;/p&gt;
&lt;pre id=&quot;code_1606490157930&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Recipient recipient = new Recipient();&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;5-3-2. 인터페이스 변수를 구현 객체로 강제 타입 변환을 사용하면 됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1606490181531&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;User user = new Recipient();
Recipient recipient = (Recipient) user;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;예시)&lt;/p&gt;
&lt;pre id=&quot;code_1606488527696&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 인터페이스
public interface User {
    void printType();
}

// 구현 클래스 &quot;Recipient&quot;
public class Recipient implements User {
    private static final String COUNTRY = &quot;KOREA&quot;;

    @Override
    public void printType() {
        System.out.println(&quot;수취인입니다.&quot;);
    }
    
    // 추가로 메서드 구현
    public void printCountry() {
        System.out.println(&quot;국가는 &quot; + COUNTRY + &quot;입니다.&quot;);
    }
}

public class Main {
    public static void main(String[] args) {
        User user = new Recipient();
        user.printType(); // &quot;수취인입니다.&quot;
        user.printCountry(); // 호출이 불가능합니다.
        // 
        Recipient recipient = (Recipient) user;
        recipient.printType(); // &quot;수취인입니다.&quot;
        recipient.printCountry(); // &quot;국가는 KOREA입니다.&quot;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;5-4. 객체 타입 확인(instanceof)&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;위 강제 타입 변환(Casting)은 구현 객체가 인터페이스 타입으로 변환되어 있는 상태에서 가능합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1606490206068&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;User user = new Recipient();&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그런데 어떤 구현 객체가 대입되는지 모르는 상태에서 강제 타입 변환을 하게 되면 ClassCastException이 발생할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1606490218183&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;User user = new Recipient();
Sender sender = (Sender) user; // ClassCastException 발생&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;ClassCastException를 발생시키지 않기 위해서 &quot;instanceof&quot; 를 사용합니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1606490399191&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;User user = new Recipient();
if( user instanceof Recipient ) { // user 변수에 담긴 객체가 Recipient 타입이면,
    Recipient recipient = (Recipient) user;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&quot;instanceof&quot;를 사용하면, 강제 타입 변환에 앞서서 &lt;span style=&quot;color: #333333;&quot;&gt;ClassCastException을 방지할 수 있습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;6.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;인터페이스(interface) 상속&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;인터페이스도 다른 인터페이스를 상속할 수 있습니다.&lt;/p&gt;
&lt;p&gt;클래스는 다중 상속을 허용하지 않지만, 인터페이스는 다중 상속을 허용합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;다음 방식으로 선언되어 인터페이스 상속이 가능합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1606492798303&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public interface 하위인터페이스 extends 상위인터페이스1, 상위인터페이스2, ... { ... }&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;하위 인터페이스를 구현하는 구현 클래스에서는 &lt;u&gt;&quot;하위 인터페이스의 추상 메서드&quot;&lt;/u&gt;와 &lt;u&gt;&quot;상속하는 모든 상위 인터페이스의 추상 메서드&quot;&lt;/u&gt;의 실체 메서드로 구현해야 합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1606493440467&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;하위인터페이스 변수 = new 구현클래스();
상위인터페이스1 변수 = new 구현클래스();
상위인터페이스2 변수 = new 구현클래스();&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&quot;하위 인터페이스 변수&quot;는 &lt;u&gt;하위인터페이스,&lt;/u&gt; &lt;u&gt;상위 인터페이스1,&lt;/u&gt; &lt;u&gt;상위 인터페이스2&lt;/u&gt;의 실체 메서드를 모두 사용할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&quot;상위 인터페이스1 변수&quot;는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;u&gt;상위인터페이스1&lt;/u&gt;&lt;span style=&quot;color: #333333;&quot;&gt;의 실체 메서드를 사용할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&quot;상위 인터페이스2 변수&quot;는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;u&gt;상위인터페이스2&lt;/u&gt;&lt;span style=&quot;color: #333333;&quot;&gt;의 실체 메서드를 사용할 수 있습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;예시)&lt;/p&gt;
&lt;pre id=&quot;code_1606494106456&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public interface InterfaceA {
    public void methodA();
}

public interface InterfaceB {
    public void methodB();
}

public interface InterfaceC extends InterfaceA, InterfaceB {
    public void methodC();
}

// InterfaceC를 구현했기 때문에 methodA(), methodB(), methodC() 실체 메서드를 모두 가져야합니다.
public class ImplementationClassC implements InterfaceC {
    public void methodA() {
        System.out.println(&quot;ImplementationClassC-methodA()&quot;);
    }
    
    public void methodB() {
        System.out.println(&quot;ImplementationClassC-methodB()&quot;);
    }
    
    public void methodC() {
        System.out.println(&quot;ImplementationClassC-methodC()&quot;);
    }
}

public class Main {
    public static void main(String[] args) {
        ImplementationC implC = new ImplementationC();
        
        InterfaceA iA = implC;
        iC.methodA(); // OK
        iC.methodB(); // NO
        iC.methodC(); // NO
        
        InterfaceB iB = implC;
        iC.methodA(); // NO
        iC.methodB(); // OK
        iC.methodC(); // NO
        
        InterfaceC iC = implC;
        iC.methodA(); // OK
        iC.methodB(); // OK
        iC.methodC(); // OK
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;7.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;인터페이스(interface) 디폴트 메서드와 확장&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;b&gt;7-1. 디폴트 메서드는 왜 만들어졌을까?&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;디폴트 메서드는 인스턴스 메서드입니다. 즉, 구현 객체가 있어야 사용할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;인스턴스 메서드인데 왜 인터페이스에 있을까요?&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Java8에서 인터페이스에서 디폴트 메서드를 허용하는 이유는 기존 인터페이스를 확장해서 새로운 기능을 추가하기 위해서입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;만약 기존 인터페이스에 새로운 기능을 위해서 추상 메서드를 추가하면 어떤 상황이 발생할까요?&lt;/p&gt;
&lt;p&gt;추상 메서드를 새롭게 선언하면, 해당 인터페이스를 구현하는 구현 클래스를 찾아다니면서,&lt;/p&gt;
&lt;p&gt;새로 선언된 추상 메서드에 대한 실체 메서드를 선언해주어야 합니다. 아니면 Compile Error가 발생합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;하지만 인터페이스에 디폴트 메서드를 선언하게 되면,&lt;/p&gt;
&lt;p&gt;이미 선언된 인스턴스 메서드이기에 실체 메서드를 선언하지 않아도 문제없이 필요한 곳에서 디폴트 메서드를 사용할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;u&gt;디폴트 메서드는 추상 메서드가 구현 클래스에서 실체 메서드로 구현되어야 한다는 제약을 없애준 편의 메서드로 볼 수 있습니다.&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1606495813854&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public interface SampleInterface {
    // 무조건 구현 클래스에서 실체 메서드로 정의해야하는 추상 메서드
    public void abstractMethod();

    // 구현 객체에서 사용할 수 있는 인스턴스인 디폴트 메서드
    // 구현 클래스에서 재정의도 가능합니다.
    public default void defaultMethod() {
        System.out.println(&quot;(1) SampleInterface-defaultMethod()&quot;);
    }
}

public class ImplementationClassA implements SampleInterface {
    @Override
    public void abstractMethod() {
        System.out.println(&quot;(2) ImplementationClassA-abstractMethod()&quot;);
    }
}

public class ImplementationClassB implements SampleInterface {
    @Override
    public void abstractMethod() {
        System.out.println(&quot;(3) ImplementationClassB-abstractMethod()&quot;);
    }
    
    // 디폴트 메서드 재정의 가능
    @Override
    public void defaultMethod() {
        System.out.println(&quot;(4) ImplementationClassB-defaultMethod()&quot;);
    }
}

public class Main {
    public static void main(String[] args) {
        SampleInterface sI1 = new ImplementationClassA();
        sI1.abstractMethod(); // (2)
        sI1.defaultMethod(); // (1)
        
        SampleInterface sI2 = new ImplementationClassB();
        sI2.abstractMethod(); // (3)
        sI2.defaultMethod(); // (4)
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;7-2. 디폴트 메서드가 있는 인터페이스 상속&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;디폴트 메서드를 가진&amp;nbsp;&lt;/span&gt;부모 인터페이스를 상속한 자식 인터페이스에서 디폴트 메서드를 활용하는 방법에 대해서 알아보겠습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;자식 인터페이스에서는 디폴트 메서드를 다음 방식으로 사용할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;7-2-1. 부모 인터페이스의 디폴트 메서드를 상속받아서 그대로 사용&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;7-2-2. &lt;span style=&quot;color: #333333;&quot;&gt;부모 인터페이스의 디폴트 메서드를 자식 인터페이스에서 재정의하여 사용&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;7-2-3. &lt;span style=&quot;color: #333333;&quot;&gt;부모 인터페이스의 디폴트 메서드를 추상 메서드로 재선언하여, 구현 클래스에서 실체 메서드로 구현하여 사용&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;위 세 가지 방식에 대해서 예시를 보이겠습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;7-2-1. 부모 인터페이스의 디폴트 메서드를 상속받아서 그대로 사용&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1606544183256&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public interface ParentInterface {
    public default void defaultMethod() {
        System.out.println(&quot;(1) ParentInterface-defaultMethod()&quot;);
    }
}

public interface ChildInterface extends ParentInterface {
}

public class ImplementationClass implements ChildInterface {
}

public class Main {
    public static void main(String[] args) {
        ChildInterface iC = new ImplementationClass();
        iC.defaultMethod(); // (1) ParentInterface-defaultMethod()
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;7-2-2.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;부모 인터페이스의 디폴트 메서드를 자식 인터페이스에서 재정의하여 사용&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;자식 인터페이스에서 디폴트 메서드를 재정의한 경우&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1606545089657&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public interface ParentInterface {
    public default void defaultMethod() {
        System.out.println(&quot;(1) ParentInterface-defaultMethod()&quot;);
    }
}

public interface ChildInterface extends ParentInterface {
    @Override
    public default void defaultMethod() {
        System.out.println(&quot;(2) ChildInterface-defaultMethod()&quot;);
    }
}

public class ImplementationClass implements ChildInterface {
}

public class Main {
    public static void main(String[] args) {
        ChildInterface iC = new ImplementationClass();
        iC.defaultMethod(); // (2) ChildInterface-defaultMethod()
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;구현 클래스에서 디폴트 메서드를 재정의한 경우&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1606545811602&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public interface ParentInterface {
    public default void defaultMethod() {
        System.out.println(&quot;(1) ParentInterface-defaultMethod()&quot;);
    }
}

public interface ChildInterface extends ParentInterface {
    @Override
    public default void defaultMethod() {
        System.out.println(&quot;(2) ChildInterface-defaultMethod()&quot;);
    }
}

public class ImplementationClass implements ChildInterface {
    @Override
    public void defaultMethod() {
        System.out.println(&quot;(3) ImplementationClass-defaultMethod()&quot;);
    }
}

public class Main {
    public static void main(String[] args) {
        ChildInterface iC = new ImplementationClass();
        iC.defaultMethod(); // (3) ImplementationClass-defaultMethod()
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;7-2-3.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;부모 인터페이스의 디폴트 메서드를 추상 메서드로 재선언하여, 구현 클래스에서 실체 메서드로 구현하여 사용&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1606547318255&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public interface ParentInterface {
    public default void defaultMethod() {
        System.out.println(&quot;(1) ParentInterface-defaultMethod()&quot;);
    }
}

public interface ChildInterface extends ParentInterface {
    // 추상 메서드로 재선언
    void defaultMethod();
}

public class ImplementationClass implements ChildInterface {
    // 추상 메서드의 실체 메서드 구현
    @Override
    public void defaultMethod() {
        System.out.println(&quot;(2) ImplementationClass-defaultMethod()&quot;);
    }
}

public class Main {
    public static void main(String[] args) {
        ChildInterface iC = new ImplementationClass();
        iC.defaultMethod(); // (2) ImplementationClass-defaultMethod()
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;결론&lt;/h2&gt;
&lt;p&gt;지금까지 인터페이스는 무엇이고, 어떻게 사용하는지에 대해서 알아봤습니다.&lt;/p&gt;
&lt;p&gt;하지만 여전히 인터페이스는 왜 사용해야 하는지에 대해서 의문일 수 있습니다.&lt;/p&gt;
&lt;p&gt;저는 &quot;객체 지향 프로그래밍을 돕는 디자인 패턴이니까 사용해서 구현하자.&quot;라고 말할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;인터페이스를 구현하고, 상속하고, 확장하면서 얻을 수 있는 프로그래밍의 장점을 다형성과 사용하면서,&lt;/p&gt;
&lt;p&gt;유지보수에 있어서 기존의 코드를 변경 없이 해당 구현 객체를 변경하기만 해도 호출되는 소스의 내용을 바꿔줄 수 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;저는 보통 클래스의 상속보다 추상 클래스와 인터페이스를 이용해서 공통된 메서드를 구현하고, 다형성을 이용합니다.&lt;/p&gt;
&lt;p&gt;이유는 클래스 간 강한 결합도를 낮추기 위함입니다.&lt;/p&gt;
&lt;p&gt;응집도를 높이고, 결합도를 낮추는 게 객체지향이 추구하는 기본 원칙이기 때문입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;인터페이스를 잘 사용하는 방법은 많이 사용해보고, 장단점을 파악해서 필요한 곳에 사용할 수 있도록 하는 것이라고 생각합니다.&lt;/p&gt;
&lt;p&gt;글을 마치겠습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;참고자료&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://velog.io/@lsb156/%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5-%EA%B0%9C%EB%B0%9C-5%EB%8C%80-%EC%9B%90%EC%B9%99-SOLID&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&quot;객체 지향 개발 5대 원칙 - SOLID&quot;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Java</category>
      <author>RyanGomdoriPooh</author>
      <guid isPermaLink="true">https://interconnection.tistory.com/129</guid>
      <comments>https://interconnection.tistory.com/129#entry129comment</comments>
      <pubDate>Thu, 25 Jun 2020 19:44:04 +0900</pubDate>
    </item>
    <item>
      <title>AWS RDS Proxy를 활용한 Aurora Failover 구현하기</title>
      <link>https://interconnection.tistory.com/125</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot; style=&quot;text-align: left;&quot;&gt;개요&lt;/h2&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;AWS RDS Proxy은 &quot;DB Connection Pool Management&quot; 또는 &quot;Automatic Failover를 위한 Proxy&quot; 기능을 제공합니다.&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;결국, AWS RDS Proxy를 사용하는 이유는 &lt;span style=&quot;color: rgb(51, 51, 51);&quot;&gt;HA(High Availability)를 구현하기 위함입니다.&lt;/span&gt;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;Solution을 사용하기 앞서서,&amp;nbsp;&lt;span style=&quot;color: rgb(51, 51, 51);&quot;&gt;HA(High Availability)를 위한 Multi-AZ(Multi Availability Zone) 개념을 시작으로 이야기를 풀어가보겠습니다.&lt;/span&gt;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;RDS는 HA(High Availability)를 위해서 Multi-AZ(Multi Availability Zone)를 권장합니다. &lt;span style=&quot;color: rgb(51, 51, 51);&quot;&gt;Downtime 없는 &lt;/span&gt;DB Instance를 사용하기 위함입니다.&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;Multi-AZ를 통한 DB 구성과 Application에서 활용하는 방식은 다음과 같습니다.&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/bEgVR5/btqE0aEaM58/EXVLaAIjRgnls65gTwKuY1/img.jpg&quot; width=&quot;656.0&quot; data-origin-width=&quot;0.0&quot; data-origin-height=&quot;0.0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bEgVR5/btqE0aEaM58/EXVLaAIjRgnls65gTwKuY1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bEgVR5/btqE0aEaM58/EXVLaAIjRgnls65gTwKuY1/img.jpg&quot; data-alt=&quot;Multi-AZ 구성과 Application에서 활용&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bEgVR5/btqE0aEaM58/EXVLaAIjRgnls65gTwKuY1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbEgVR5%2FbtqE0aEaM58%2FEXVLaAIjRgnls65gTwKuY1%2Fimg.jpg&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/bEgVR5/btqE0aEaM58/EXVLaAIjRgnls65gTwKuY1/img.jpg&quot; width=&quot;656.0&quot; data-origin-width=&quot;0.0&quot; data-origin-height=&quot;0.0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;Multi-AZ 구성과 Application에서 활용&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;여기서 AZ(Availability Zone)의 개념은 물리적으로 구분된 IDC라고 생각하시면 됩니다.&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;예를 들면, Zone A는 Seoul, Zone B는 Daegu, Zone C는 Busan과 같이 보통 지역으로 분리해놓습니다.&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;u&gt;Multi-AZ를 구성하고, 어느 하나의 &lt;span style=&quot;color: rgb(51, 51, 51);&quot;&gt;AZ 또는 DB Instance에 장애가 발생하였을 때 &lt;/span&gt;장점은 다음과 같습니다.&lt;/u&gt;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;&lt;b&gt;Enhanced durability&lt;/b&gt;: 장애가 발생한 Workload를 안전하게 보장해서 DB에 반영해줍니다.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Increased availability&lt;/b&gt;: Aurora는 1분 이내, MariaDB는 30초 이내, 다른 DB Engine은 1~2분 이내로 Automatic failover를 통해서 정상화시킵니다. 그리고 maintenance 또는 backup이 발생했을 때도 DB에 반영할 Workload를 보장해줍니다.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Protection of your database performance&lt;/b&gt;: MySQL, MariaDB, Oracle, PostgreSQL Engine에서 Backup이 발생하였을 때, I/O workload를 지속적으로 보장해줍니다. Aurora를 사용하고 있는 경우에도 마찬가지로 I/O workload를 보장하고, 장애가 발생하여도 Automatic Failover과 Read Replica를 통해서 Performance를 유지시켜줍니다.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Automatic failover&lt;/b&gt;: Primary DB가 있는 AZ에서 Downtime이 발생했을 때, Failover를 통해서 짧은 시간 안에 Secondary DB를 승격시켜서 DB를 정상화시킵니다. 마찬가지로 Secondary DB에서 Downtime이 발생했을 때, 다른 정상적인 AZ로 Workload를 넘겨줍니다.&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;또한, AWS Multi-AZ 구성은 다음 아래와 같은 내용을 보장합니다.&lt;/p&gt;&lt;blockquote data-ke-style=&quot;style2&quot;&gt;Amazon RDS Service Level Agreement Multi-AZ configurations for MySQL, MariaDB, Oracle, and PostgreSQL are covered by the Amazon RDS Service Level Agreement (&quot;SLA&quot;). The RDS SLA affirms that AWS will use commercially reasonable efforts to make Multi-AZ instances of Amazon RDS available with a Monthly Uptime Percentage of at least 99.95% during any monthly billing cycle. In the event Amazon RDS does not meet the Monthly Uptime Percentage commitment, affected customers will be eligible to receive a service credit.&lt;/blockquote&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;요약한 내용은 다음과 같습니다.&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;한 달의 Billing Cycle 동안 99.95% 이상의 서비스 시간 보장 (30일*24시간*60분 * 0.0005 = 21.6분 이하의 Downtime 보장)&lt;/li&gt;&lt;li&gt;99.95%이상 SLA 보장을 못 받은 사용자에게는 그만큼의 Service Credit 제공&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: rgb(51, 51, 51);&quot;&gt;하지만 Multi-AZ가 장점이 많음에도 비용이 증가하는 단점이 있기 때문에, 웬만한 소규모 상용 서비스들은 보통 1개 DB Instance로 Multi-AZ를 구현하지 않고 사용합니다.&lt;/span&gt;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&quot;서비스의 초반에는 굳이 Multi-AZ까지 필요할까?&quot;라는 말엔 공감합니다. 그러나 서비스가 성장하고, 24시간 쉼 없이 사용자들에게 서비스를 제공하게 되면서, DB의 HA(High Availability)가 중요해집니다.&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: rgb(51, 51, 51);&quot;&gt;결국, Multi-AZ가 필요한 시점이 옵니다.&lt;/span&gt;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;u&gt;그러면 Multi-AZ를 어떻게 사용할까요? 내부 Architecture는 비슷하지만, Engine에 따라서 구성하는 방식은 조금 다릅니다.&lt;/u&gt;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;&lt;span&gt;MySQL, MariaDB, Oracle, PostgreSQL Engine: DB를 생성할 때, Multi-AZ를 선택할 수 있습니다. 생성 후에 적용도 가능합니다.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;Aurora: Read Replica를 생성하면 자동으로 Multi-AZ가 구성이 됩니다.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: rgb(51, 51, 51);&quot;&gt;MySQL, MariaDB, Oracle, PostgreSQL Engine은 장애가 발생하였을 때, 동일한 endpoint를 통해서 요청해도 Automatic Failover를 통해서 DB를 전환시켜주기 때문에 그대로 endpoint를 사용하시면 HA(High Availability)를 구성할 수 있습니다.&lt;/span&gt;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/RnChn/btqEZ9ZEtit/hHR3d9w8rH6SAhxXUv2Q8k/img.png&quot; data-origin-width=&quot;0.0&quot; data-origin-height=&quot;0.0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RnChn/btqEZ9ZEtit/hHR3d9w8rH6SAhxXUv2Q8k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RnChn/btqEZ9ZEtit/hHR3d9w8rH6SAhxXUv2Q8k/img.png&quot; data-alt=&quot;AWS Aurora의 구성 Architecture&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RnChn/btqEZ9ZEtit/hHR3d9w8rH6SAhxXUv2Q8k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRnChn%2FbtqEZ9ZEtit%2FhHR3d9w8rH6SAhxXUv2Q8k%2Fimg.png&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/RnChn/btqEZ9ZEtit/hHR3d9w8rH6SAhxXUv2Q8k/img.png&quot; data-origin-width=&quot;0.0&quot; data-origin-height=&quot;0.0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;AWS Aurora의 구성 Architecture&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: rgb(51, 51, 51);&quot;&gt;이 글에선 더 다양한 기능과 확장성을 제공하는 Aurora를 기준으로 Proxy를 활용해서 Automatic Failover를 구현하고, HA(&lt;/span&gt;&lt;span style=&quot;color: rgb(51, 51, 51);&quot;&gt;High Availability)를 가능하게 만들어보겠습니다.&lt;/span&gt;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: rgb(51, 51, 51);&quot;&gt;&lt;span style=&quot;color: rgb(51, 51, 51);&quot;&gt;AWS Aurora Automatic Failover&lt;/span&gt;&amp;nbsp;테스트를 진행하기 위한 구성은 다음과 같습니다.&lt;/span&gt;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;&lt;span style=&quot;color: rgb(51, 51, 51);&quot;&gt;RDS Aurora Instance Cluster 1(Primary Instance 1, Replica Instance 1)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;color: rgb(51, 51, 51);&quot;&gt;RDS Proxy 1(&lt;/span&gt;&lt;span style=&quot;color: rgb(51, 51, 51);&quot;&gt;Secrets Manager &quot;Secret&quot;, &lt;/span&gt;&lt;span style=&quot;color: rgb(51, 51, 51);&quot;&gt;IAM &quot;Policy&quot;, &lt;/span&gt;&lt;span style=&quot;color: rgb(51, 51, 51);&quot;&gt;IAM &quot;Role&quot;)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;color: rgb(51, 51, 51);&quot;&gt;EC2 Instance 1&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: rgb(51, 51, 51);&quot;&gt;&lt;span style=&quot;color: rgb(51, 51, 51);&quot;&gt;// RDS Aurora Instance Cluster 1(Primary Instance 1, Replica Instance 1)는 이미 생성되어있다고 가정합니다. 이 글에서 사용하는 DB Instance Name은 test입니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/pgSNw/btqE13cvvr6/kd0QYBJy0yWCtQ4MirKFb0/img.png&quot; data-origin-width=&quot;847.0&quot; data-origin-height=&quot;374.0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pgSNw/btqE13cvvr6/kd0QYBJy0yWCtQ4MirKFb0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pgSNw/btqE13cvvr6/kd0QYBJy0yWCtQ4MirKFb0/img.png&quot; data-alt=&quot;예시로 사용하는 Aurora cluster&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pgSNw/btqE13cvvr6/kd0QYBJy0yWCtQ4MirKFb0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpgSNw%2FbtqE13cvvr6%2Fkd0QYBJy0yWCtQ4MirKFb0%2Fimg.png&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/pgSNw/btqE13cvvr6/kd0QYBJy0yWCtQ4MirKFb0/img.png&quot; data-origin-width=&quot;847.0&quot; data-origin-height=&quot;374.0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;예시로 사용하는 Aurora cluster&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;hr data-ke-type=&quot;horizontalRule&quot; contenteditable=&quot;false&quot; data-ke-style=&quot;style6&quot;&gt;&lt;h2 data-ke-size=&quot;size26&quot; style=&quot;text-align: left;&quot;&gt;목차&lt;/h2&gt;&lt;ol style=&quot;list-style-type: decimal;&quot;&gt;&lt;li&gt;RDS Proxy에 사용할 Secrets Manager &quot;secret&quot; 생성하기&lt;/li&gt;&lt;li&gt;&lt;span&gt;RDS Proxy에 사용할&lt;/span&gt;&lt;span&gt; IAM &quot;policy&quot; 생성하기&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;RDS Proxy에 사용할 IAM &quot;role&quot; 생성하기&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;RDS Proxy를 생성하고, Aurora cluster에 연결하기&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;RDS Proxy Endpoint를 사용해서, &quot;Automatic Failover&quot; 테스트하기&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;hr data-ke-type=&quot;horizontalRule&quot; contenteditable=&quot;false&quot; data-ke-style=&quot;style6&quot;&gt;&lt;h2 data-ke-size=&quot;size26&quot; style=&quot;text-align: left;&quot;&gt;1. RDS&amp;nbsp;Proxy에&amp;nbsp;사용할&amp;nbsp;Secrets&amp;nbsp;Manager&amp;nbsp;&quot;secret&quot;&amp;nbsp;생성하기&lt;/h2&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;: RDS Proxy를 이용하기 위해서는 Proxy가 어디로 어떤 정보를 이용해서 DB에 접속해야 하는 지를 정보를 저장해야 합니다. Proxy는 그 정보의 단위를 Secrets Manager &quot;secret&quot;를 생성해서 관리하고 사용합니다.&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/sU0M9/btqE13XN0dZ/8SJKQ6z5dlXYPkxAL3yX7k/img.png&quot; data-origin-width=&quot;842.0&quot; data-origin-height=&quot;772.0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sU0M9/btqE13XN0dZ/8SJKQ6z5dlXYPkxAL3yX7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sU0M9/btqE13XN0dZ/8SJKQ6z5dlXYPkxAL3yX7k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sU0M9/btqE13XN0dZ/8SJKQ6z5dlXYPkxAL3yX7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsU0M9%2FbtqE13XN0dZ%2F8SJKQ6z5dlXYPkxAL3yX7k%2Fimg.png&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/sU0M9/btqE13XN0dZ/8SJKQ6z5dlXYPkxAL3yX7k/img.png&quot; data-origin-width=&quot;842.0&quot; data-origin-height=&quot;772.0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;Secret type: &quot;Credentials for RDS database&quot;&lt;/li&gt;&lt;li&gt;User name: 접속할 DB의 username&lt;/li&gt;&lt;li&gt;Password: 접속할 DB의 password&lt;/li&gt;&lt;li&gt;Encryption key: DefaultEncryptionKey&lt;/li&gt;&lt;li&gt;RDS database this secret will access: &quot;secret&quot;을 사용하여 Proxy를 사용할 DB&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;Next~&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/bjd6hX/btqE1rLRxDw/5OeoSvTZp0xgwzJF3nYg5K/img.png&quot; data-origin-width=&quot;862.0&quot; data-origin-height=&quot;601.0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjd6hX/btqE1rLRxDw/5OeoSvTZp0xgwzJF3nYg5K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjd6hX/btqE1rLRxDw/5OeoSvTZp0xgwzJF3nYg5K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjd6hX/btqE1rLRxDw/5OeoSvTZp0xgwzJF3nYg5K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbjd6hX%2FbtqE1rLRxDw%2F5OeoSvTZp0xgwzJF3nYg5K%2Fimg.png&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/bjd6hX/btqE1rLRxDw/5OeoSvTZp0xgwzJF3nYg5K/img.png&quot; data-origin-width=&quot;862.0&quot; data-origin-height=&quot;601.0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;Secret name: &quot;secret&quot; 구분하기 위한 이름. 보통 {Environment}/{Object}/{DBtype}로 만듭니다.&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: rgb(51, 51, 51);&quot;&gt;Next~&lt;/span&gt;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/de0rJq/btqE00udhyJ/nZVtTIXnKJnk1SK0KBuTr0/img.png&quot; data-origin-width=&quot;840.0&quot; data-origin-height=&quot;772.0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/de0rJq/btqE00udhyJ/nZVtTIXnKJnk1SK0KBuTr0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/de0rJq/btqE00udhyJ/nZVtTIXnKJnk1SK0KBuTr0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/de0rJq/btqE00udhyJ/nZVtTIXnKJnk1SK0KBuTr0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fde0rJq%2FbtqE00udhyJ%2FnZVtTIXnKJnk1SK0KBuTr0%2Fimg.png&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/de0rJq/btqE00udhyJ/nZVtTIXnKJnk1SK0KBuTr0/img.png&quot; data-origin-width=&quot;840.0&quot; data-origin-height=&quot;772.0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;automatic rotation은 &quot;secret&quot;의 rotation 사용 전략입니다. 여기서는 일단, &quot;Disable automatic rotation&quot;을 선택하겠습니다.&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: rgb(51, 51, 51);&quot;&gt;Next~&lt;/span&gt;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/bmTS85/btqE0O1QMHt/CPDlc4XMbcjS50pY8pUT7k/img.png&quot; data-origin-width=&quot;779.0&quot; data-origin-height=&quot;721.0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bmTS85/btqE0O1QMHt/CPDlc4XMbcjS50pY8pUT7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bmTS85/btqE0O1QMHt/CPDlc4XMbcjS50pY8pUT7k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bmTS85/btqE0O1QMHt/CPDlc4XMbcjS50pY8pUT7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbmTS85%2FbtqE0O1QMHt%2FCPDlc4XMbcjS50pY8pUT7k%2Fimg.png&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/bmTS85/btqE0O1QMHt/CPDlc4XMbcjS50pY8pUT7k/img.png&quot; data-origin-width=&quot;779.0&quot; data-origin-height=&quot;721.0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;최종적으로 설정한 부분을 확인합니다.&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: rgb(51, 51, 51);&quot;&gt;Store~&lt;/span&gt;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/9dBbJ/btqE00HJwJZ/C68DbiuNDi9UgopSv3zYVk/img.png&quot; data-origin-width=&quot;893.0&quot; data-origin-height=&quot;350.0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9dBbJ/btqE00HJwJZ/C68DbiuNDi9UgopSv3zYVk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9dBbJ/btqE00HJwJZ/C68DbiuNDi9UgopSv3zYVk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9dBbJ/btqE00HJwJZ/C68DbiuNDi9UgopSv3zYVk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9dBbJ%2FbtqE00HJwJZ%2FC68DbiuNDi9UgopSv3zYVk%2Fimg.png&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/9dBbJ/btqE00HJwJZ/C68DbiuNDi9UgopSv3zYVk/img.png&quot; data-origin-width=&quot;893.0&quot; data-origin-height=&quot;350.0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;최종적으로 생성된 &quot;secret&quot;을 볼 수 있습니다. 생성된 &quot;secret&quot;은 RDS Proxy를 생성하는데 쓰이게 됩니다.&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/caSx4f/btqE1qGe7gX/p5wTdn2IR1WsbN8cNiY7JK/img.png&quot; data-origin-width=&quot;1351.0&quot; data-origin-height=&quot;441.0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/caSx4f/btqE1qGe7gX/p5wTdn2IR1WsbN8cNiY7JK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/caSx4f/btqE1qGe7gX/p5wTdn2IR1WsbN8cNiY7JK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/caSx4f/btqE1qGe7gX/p5wTdn2IR1WsbN8cNiY7JK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcaSx4f%2FbtqE1qGe7gX%2Fp5wTdn2IR1WsbN8cNiY7JK%2Fimg.png&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/caSx4f/btqE1qGe7gX/p5wTdn2IR1WsbN8cNiY7JK/img.png&quot; data-origin-width=&quot;1351.0&quot; data-origin-height=&quot;441.0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;아래 단계로 넘어가기 앞서서 생성된 &quot;secret&quot;으로 들어가면 생성된 &quot;Secret ARN&quot;을 볼 수 있습니다. 복사해둡니다.&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;h2 data-ke-size=&quot;size26&quot; style=&quot;text-align: left;&quot;&gt;2. RDS&amp;nbsp;Proxy에&amp;nbsp;사용할&amp;nbsp;IAM&amp;nbsp;&quot;policy&quot;&amp;nbsp;생성하기&lt;/h2&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;: RDS Proxy를 생성하는 데에 IAM &quot;policy&quot;를 생성하는 이유는 결국, IAM &quot;role&quot;을 Proxy가 가지기 위함입니다.&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;그러면 IAM &quot;role&quot;을 생성하는 이유는 RDS Proxy가 다른 서비스 자원을 이용하기 위한 권한을 획득하는 단위이기 때문입니다.&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;풀어보면, &quot;secret&quot; 리소스를 제어할 수 있는 &quot;policy&quot;를 만들어서, &lt;span style=&quot;color: rgb(51, 51, 51);&quot;&gt;IAM &quot;role&quot;을 생성해서, RDS Proxy에게 권한을 넘겨주기 위함입니다.&lt;/span&gt;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/chCBQn/btqE2tPlBoO/LkO1I0j2RyXJNATYDeU8xK/img.png&quot; data-origin-width=&quot;581.0&quot; data-origin-height=&quot;346.0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/chCBQn/btqE2tPlBoO/LkO1I0j2RyXJNATYDeU8xK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/chCBQn/btqE2tPlBoO/LkO1I0j2RyXJNATYDeU8xK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/chCBQn/btqE2tPlBoO/LkO1I0j2RyXJNATYDeU8xK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FchCBQn%2FbtqE2tPlBoO%2FLkO1I0j2RyXJNATYDeU8xK%2Fimg.png&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/chCBQn/btqE2tPlBoO/LkO1I0j2RyXJNATYDeU8xK/img.png&quot; data-origin-width=&quot;581.0&quot; data-origin-height=&quot;346.0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;AWS IAM으로 들어갑니다. IAM policy를 생성하기 위해서 Access management =&amp;gt; Policies =&amp;gt; &quot;Create policy&quot;를 선택합니다.&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/dFZs5h/btqE2kykcW9/KN2qke48LzYI6NcDXuS9Fk/img.png&quot; data-origin-width=&quot;1217.0&quot; data-origin-height=&quot;900.0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dFZs5h/btqE2kykcW9/KN2qke48LzYI6NcDXuS9Fk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dFZs5h/btqE2kykcW9/KN2qke48LzYI6NcDXuS9Fk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dFZs5h/btqE2kykcW9/KN2qke48LzYI6NcDXuS9Fk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdFZs5h%2FbtqE2kykcW9%2FKN2qke48LzYI6NcDXuS9Fk%2Fimg.png&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/dFZs5h/btqE2kykcW9/KN2qke48LzYI6NcDXuS9Fk/img.png&quot; data-origin-width=&quot;1217.0&quot; data-origin-height=&quot;900.0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;&quot;JSON&quot; 탭으로 이동합니다. 그리고 Policy의 JSON을 넣습니다.&lt;/li&gt;&lt;li&gt;&quot;secret&quot; Resource를 사용할 수 있게 허용하기 위해서 &quot;your_secret_ARN&quot;에 secret 생성 시에 얻었던 &quot;Secret ARN&quot;로 변경해줍니다.&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;Policy의 JSON은 다음과 같습니다.&lt;/p&gt;&lt;div data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot; data-ke-type=&quot;moreLess&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;&lt;div class=&quot;moreless-content&quot;&gt;&lt;div&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;Version&quot;:&amp;nbsp;&quot;2012-10-17&quot;,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;Statement&quot;:&amp;nbsp;[&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;Sid&quot;:&amp;nbsp;&quot;VisualEditor0&quot;,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;Effect&quot;:&amp;nbsp;&quot;Allow&quot;,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;Action&quot;:&amp;nbsp;[&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;secretsmanager:GetRandomPassword&quot;,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;secretsmanager:CreateSecret&quot;,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;secretsmanager:ListSecrets&quot;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;],&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;Resource&quot;:&amp;nbsp;&quot;*&quot;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;Sid&quot;:&amp;nbsp;&quot;VisualEditor1&quot;,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;Effect&quot;:&amp;nbsp;&quot;Allow&quot;,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;Action&quot;:&amp;nbsp;&quot;secretsmanager:*&quot;,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;Resource&quot;:&amp;nbsp;[&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;your_secret_ARN&quot;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;]&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;]&lt;br&gt;}&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;Policy JSON을 반영했으면, &quot;Review policy&quot;를 선택해줍니다.&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/czdLQL/btqE00gH1sd/eNp7J4oNvKVOR1A8pDC6kk/img.png&quot; data-origin-width=&quot;1219.0&quot; data-origin-height=&quot;894.0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/czdLQL/btqE00gH1sd/eNp7J4oNvKVOR1A8pDC6kk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/czdLQL/btqE00gH1sd/eNp7J4oNvKVOR1A8pDC6kk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/czdLQL/btqE00gH1sd/eNp7J4oNvKVOR1A8pDC6kk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FczdLQL%2FbtqE00gH1sd%2FeNp7J4oNvKVOR1A8pDC6kk%2Fimg.png&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/czdLQL/btqE00gH1sd/eNp7J4oNvKVOR1A8pDC6kk/img.png&quot; data-origin-width=&quot;1219.0&quot; data-origin-height=&quot;894.0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;Name을 적어주고 나서, &quot;Create policy&quot;를 눌러줍니다.&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;이제 AWS IAM &quot;role&quot;을 생성하기 위한 &quot;policy&quot; 생성이 되었습니다.&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;h2&gt;3.&lt;span&gt; RDS&amp;nbsp;Proxy에&amp;nbsp;사용할&amp;nbsp;IAM&amp;nbsp;&quot;role&quot;&amp;nbsp;생성하기&lt;/span&gt;&lt;/h2&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;: 위 단계에서 만들어진 IAM &quot;policy&quot;를 이용해서, 다음 단계에서 만들게 될 RDS Proxy가 사용할 리소스의 권한을 얻기 위한 IAM &quot;role&quot;을 만들어보겠습니다.&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/cXpuZ4/btqE1DFaH1E/Nk6xoKd5yB4bfGYQqhnpGk/img.png&quot; data-origin-width=&quot;534.0&quot; data-origin-height=&quot;594.0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cXpuZ4/btqE1DFaH1E/Nk6xoKd5yB4bfGYQqhnpGk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cXpuZ4/btqE1DFaH1E/Nk6xoKd5yB4bfGYQqhnpGk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cXpuZ4/btqE1DFaH1E/Nk6xoKd5yB4bfGYQqhnpGk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcXpuZ4%2FbtqE1DFaH1E%2FNk6xoKd5yB4bfGYQqhnpGk%2Fimg.png&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/cXpuZ4/btqE1DFaH1E/Nk6xoKd5yB4bfGYQqhnpGk/img.png&quot; data-origin-width=&quot;534.0&quot; data-origin-height=&quot;594.0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;&quot;role&quot;을 생성하기 위해서, 다음 순서로 들어가 줍니다.&lt;/li&gt;&lt;li&gt;IAM =&amp;gt; Roles 탭 =&amp;gt; &quot;Create role&quot;&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/9NuH4/btqE00nxxfD/Ac2pZUjhZ0RsCSMiMmi7i0/img.png&quot; data-origin-width=&quot;652.0&quot; data-origin-height=&quot;913.0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9NuH4/btqE00nxxfD/Ac2pZUjhZ0RsCSMiMmi7i0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9NuH4/btqE00nxxfD/Ac2pZUjhZ0RsCSMiMmi7i0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9NuH4/btqE00nxxfD/Ac2pZUjhZ0RsCSMiMmi7i0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9NuH4%2FbtqE00nxxfD%2FAc2pZUjhZ0RsCSMiMmi7i0%2Fimg.png&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/9NuH4/btqE00nxxfD/Ac2pZUjhZ0RsCSMiMmi7i0/img.png&quot; data-origin-width=&quot;652.0&quot; data-origin-height=&quot;913.0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;AWS Service에서 RDS Proxy의 role을 만들어주기 위해서 &quot;RDS&quot;를 선택하고, role을 추가합니다.&lt;/li&gt;&lt;li&gt;&quot;AWS Service&quot; =&amp;gt; &quot;RDS&quot; =&amp;gt; &quot;RDS - Add Role to Database&quot; =&amp;gt; &quot;Next: Permissions&quot;&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/JrMpn/btqE1EYqUIH/ez7OguWgyuzVML2NKpSxLK/img.png&quot; data-origin-width=&quot;969.0&quot; data-origin-height=&quot;875.0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JrMpn/btqE1EYqUIH/ez7OguWgyuzVML2NKpSxLK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JrMpn/btqE1EYqUIH/ez7OguWgyuzVML2NKpSxLK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JrMpn/btqE1EYqUIH/ez7OguWgyuzVML2NKpSxLK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJrMpn%2FbtqE1EYqUIH%2Fez7OguWgyuzVML2NKpSxLK%2Fimg.png&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/JrMpn/btqE1EYqUIH/ez7OguWgyuzVML2NKpSxLK/img.png&quot; data-origin-width=&quot;969.0&quot; data-origin-height=&quot;875.0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;위 단계에서 RDS Proxy IAM &quot;role&quot;위해서 만들었던, IAM policy &quot;test-rds-proxy&quot;를 IAM &quot;role&quot;에 붙여줍니다.&lt;/li&gt;&lt;li&gt;&quot;test-rds-proxy&quot; 검색 =&amp;gt; &quot;Next: Tags&quot;&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/cAzIv8/btqE2ugthgT/O7YoWg89oMugyq0BJlZIbK/img.png&quot; data-origin-width=&quot;972.0&quot; data-origin-height=&quot;880.0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cAzIv8/btqE2ugthgT/O7YoWg89oMugyq0BJlZIbK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cAzIv8/btqE2ugthgT/O7YoWg89oMugyq0BJlZIbK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cAzIv8/btqE2ugthgT/O7YoWg89oMugyq0BJlZIbK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcAzIv8%2FbtqE2ugthgT%2FO7YoWg89oMugyq0BJlZIbK%2Fimg.png&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/cAzIv8/btqE2ugthgT/O7YoWg89oMugyq0BJlZIbK/img.png&quot; data-origin-width=&quot;972.0&quot; data-origin-height=&quot;880.0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;그냥 넘어가도 되는 부분입니다. tag를 붙여서 가독성을 주고 싶다면, Key: Name , Value: &quot;원하는 이름&quot;으로 넣어주시고, 넘어가 줍니다.&lt;/li&gt;&lt;li&gt;&quot;Next: Review&quot;&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/buC2I7/btqE1ERAW3M/ndK2gsNAVVyZuK7rXQaO4k/img.png&quot; data-origin-width=&quot;978.0&quot; data-origin-height=&quot;886.0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/buC2I7/btqE1ERAW3M/ndK2gsNAVVyZuK7rXQaO4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/buC2I7/btqE1ERAW3M/ndK2gsNAVVyZuK7rXQaO4k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/buC2I7/btqE1ERAW3M/ndK2gsNAVVyZuK7rXQaO4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbuC2I7%2FbtqE1ERAW3M%2FndK2gsNAVVyZuK7rXQaO4k%2Fimg.png&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/buC2I7/btqE1ERAW3M/ndK2gsNAVVyZuK7rXQaO4k/img.png&quot; data-origin-width=&quot;978.0&quot; data-origin-height=&quot;886.0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;최종적으로 설정한 IAM &quot;role&quot;의 내용을 보고, 맞다면 생성해줍니다.&lt;/li&gt;&lt;li&gt;&quot;Role name&quot; 입력 =&amp;gt; &quot;Create role&quot;&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/bZjjLQ/btqE2mCWlwK/exOkJic7Xd0TQ2sWS2Brnk/img.png&quot; data-origin-width=&quot;1093.0&quot; data-origin-height=&quot;603.0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZjjLQ/btqE2mCWlwK/exOkJic7Xd0TQ2sWS2Brnk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZjjLQ/btqE2mCWlwK/exOkJic7Xd0TQ2sWS2Brnk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZjjLQ/btqE2mCWlwK/exOkJic7Xd0TQ2sWS2Brnk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZjjLQ%2FbtqE2mCWlwK%2FexOkJic7Xd0TQ2sWS2Brnk%2Fimg.png&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/bZjjLQ/btqE2mCWlwK/exOkJic7Xd0TQ2sWS2Brnk/img.png&quot; data-origin-width=&quot;1093.0&quot; data-origin-height=&quot;603.0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;생성된 IAM &quot;role&quot;을 확인하고 선택해서 들어가 줍니다.&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/pT4cf/btqE1vN7MDN/MJqnhpK4nuxs00n6hFkMVK/img.png&quot; data-origin-width=&quot;809.0&quot; data-origin-height=&quot;606.0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pT4cf/btqE1vN7MDN/MJqnhpK4nuxs00n6hFkMVK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pT4cf/btqE1vN7MDN/MJqnhpK4nuxs00n6hFkMVK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pT4cf/btqE1vN7MDN/MJqnhpK4nuxs00n6hFkMVK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpT4cf%2FbtqE1vN7MDN%2FMJqnhpK4nuxs00n6hFkMVK%2Fimg.png&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/pT4cf/btqE1vN7MDN/MJqnhpK4nuxs00n6hFkMVK/img.png&quot; data-origin-width=&quot;809.0&quot; data-origin-height=&quot;606.0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;하나 남은 작업이 있습니다. RDS와의 신뢰 정책을 편집해서 보다 안전하게 리소스 간에 신뢰를 구성하기 위해서입니다.&lt;/li&gt;&lt;li&gt;&quot;Trust relationships&quot; =&amp;gt; &quot;Edit trust relationship&quot;&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/l1KO4/btqE1v8qLQi/rK37exsKCkP0AWq2q20WX0/img.png&quot; data-origin-width=&quot;838.0&quot; data-origin-height=&quot;851.0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/l1KO4/btqE1v8qLQi/rK37exsKCkP0AWq2q20WX0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/l1KO4/btqE1v8qLQi/rK37exsKCkP0AWq2q20WX0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/l1KO4/btqE1v8qLQi/rK37exsKCkP0AWq2q20WX0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fl1KO4%2FbtqE1v8qLQi%2FrK37exsKCkP0AWq2q20WX0%2Fimg.png&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/l1KO4/btqE1v8qLQi/rK37exsKCkP0AWq2q20WX0/img.png&quot; data-origin-width=&quot;838.0&quot; data-origin-height=&quot;851.0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;Trust Policy를 넣어주고 &quot;Update Trust Policy&quot;를 눌러 갱신해줍니다.&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: rgb(51, 51, 51);&quot;&gt;Trust Relationship을 위한 Policy JSON은 다음과 같습니다.&lt;/span&gt;&lt;/p&gt;&lt;div data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot; data-ke-type=&quot;moreLess&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;&lt;div class=&quot;moreless-content&quot;&gt;&lt;div&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;{&lt;/span&gt;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp;&quot;Version&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;&quot;2012-10-17&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&quot;Statement&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&quot;Effect&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;&quot;Allow&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&quot;Principal&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&quot;Service&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;&quot;rds.amazonaws.com&quot;&lt;/span&gt;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&quot;Action&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;&quot;sts:AssumeRole&quot;&lt;/span&gt;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: rgb(51, 51, 51);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: rgb(51, 51, 51);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;}&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: rgb(51, 51, 51);&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;]&lt;/span&gt;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;}&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;이렇게 RDS Proxy가 RDS Aurora DB cluster와 연결되어 제 기능을 할 수 있게 하는 IAM &quot;role&quot;, &quot;policy&quot;의 생성을 마쳤습니다.&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;h2&gt;4.&lt;span&gt; RDS&amp;nbsp;Proxy를&amp;nbsp;생성하고,&amp;nbsp;Aurora&amp;nbsp;cluster에&amp;nbsp;연결하기&lt;/span&gt;&lt;/h2&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;: 여기서는 &lt;span style=&quot;color: rgb(51, 51, 51);&quot;&gt;RDS Proxy를 생성하고, RDS Aurora DB cluster와 연결해보겠습니다. 연결을 마치게 되면, RDS Proxy에서 제공하는 기능들을 사용할 수 있습니다.&lt;/span&gt;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: rgb(51, 51, 51);&quot;&gt;RDS Proxy가 제공하는 기능은 DB의 HA(High Availability)를 구현하기 위함이고, 특징적인 기능은 다음과 같습니다.&lt;/span&gt;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;&lt;span style=&quot;color: rgb(51, 51, 51);&quot;&gt;DB Connection Pool Management&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;color: rgb(51, 51, 51);&quot;&gt;Automatic Failover&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/eNBTog/btqE0Cgpnqz/iKl7Q89UK9Ay4pfvaKO6t1/img.png&quot; data-origin-width=&quot;783.0&quot; data-origin-height=&quot;596.0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eNBTog/btqE0Cgpnqz/iKl7Q89UK9Ay4pfvaKO6t1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eNBTog/btqE0Cgpnqz/iKl7Q89UK9Ay4pfvaKO6t1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eNBTog/btqE0Cgpnqz/iKl7Q89UK9Ay4pfvaKO6t1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeNBTog%2FbtqE0Cgpnqz%2FiKl7Q89UK9Ay4pfvaKO6t1%2Fimg.png&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/eNBTog/btqE0Cgpnqz/iKl7Q89UK9Ay4pfvaKO6t1/img.png&quot; data-origin-width=&quot;783.0&quot; data-origin-height=&quot;596.0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;Proxy identifier 입력 =&amp;gt; Proxy가 사용될 DB Engine 선택 =&amp;gt; TLS 연결이 필요하면 선택 =&amp;gt; &quot;Idle client connection timeout&quot; 시간 선택&lt;/li&gt;&lt;li&gt;Proxy는 자체적으로 Connection Pool을 관리해주기 때문에 서비스의 Idel time이 적다면 &quot;Idle client connection timeout&quot;을 원하는 만큼 늘리면 됩니다.&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/oVmy3/btqE1uuXzal/B2l76jwKWYlGZk9Br6FlCk/img.png&quot; data-origin-width=&quot;786.0&quot; data-origin-height=&quot;404.0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oVmy3/btqE1uuXzal/B2l76jwKWYlGZk9Br6FlCk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oVmy3/btqE1uuXzal/B2l76jwKWYlGZk9Br6FlCk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oVmy3/btqE1uuXzal/B2l76jwKWYlGZk9Br6FlCk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoVmy3%2FbtqE1uuXzal%2FB2l76jwKWYlGZk9Br6FlCk%2Fimg.png&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/oVmy3/btqE1uuXzal/B2l76jwKWYlGZk9Br6FlCk/img.png&quot; data-origin-width=&quot;786.0&quot; data-origin-height=&quot;404.0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;&quot;Database&quot;: Proxy와 연결할 RDS Database를 골라줍니다. 여기서는 미리 생성해두었던 RDS Database &quot;test&quot;를 선택해줍니다.&lt;/li&gt;&lt;li&gt;&quot;Connection pool maximum connections&quot;: 생성한 Database &quot;test&quot;의 설정되어 있는 옵션 &quot;max_connections&quot;의 percent 만큼만 RDS Proxy에서 할당받아서 연결합니다.&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/p4QRk/btqE0BV5IAo/MuUbTuW0rtrPxQZpXkc3zK/img.png&quot; data-origin-width=&quot;710.0&quot; data-origin-height=&quot;829.0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/p4QRk/btqE0BV5IAo/MuUbTuW0rtrPxQZpXkc3zK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/p4QRk/btqE0BV5IAo/MuUbTuW0rtrPxQZpXkc3zK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/p4QRk/btqE0BV5IAo/MuUbTuW0rtrPxQZpXkc3zK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fp4QRk%2FbtqE0BV5IAo%2FMuUbTuW0rtrPxQZpXkc3zK%2Fimg.png&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/p4QRk/btqE0BV5IAo/MuUbTuW0rtrPxQZpXkc3zK/img.png&quot; data-origin-width=&quot;710.0&quot; data-origin-height=&quot;829.0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;&quot;Secrets Manager secret(s)&quot;: &lt;u&gt;&quot;1.&lt;/u&gt;&lt;u&gt; RDS Proxy에 사용할 Secrets Manager &quot;secret&quot; 생성하기&quot;에서&lt;/u&gt;&lt;span style=&quot;color: rgb(51, 51, 51);&quot;&gt; 생성한 secret을 적용해줍니다.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&quot;IAM role&quot;: &lt;u&gt;&quot;RDS Proxy에 사용할 IAM &quot;policy&quot; 생성하기&quot;&lt;/u&gt;와 &lt;u&gt;&quot;&lt;/u&gt;&lt;/span&gt;&lt;u&gt;RDS Proxy에 사용할 IAM &quot;role&quot; 생성하기&quot;&lt;/u&gt;에서 생성하였던 IAM role인 &quot;test-rds-proxy&quot;를 넣어줍니다.&lt;/li&gt;&lt;li&gt;&quot;IAM authentication&quot;: 여기서는 1) IAM을 통한 사용자 접근 제어 방법과 2) 기존의 DB 접속 방식 이 있습니다. 여기서는 2) 번으로 사용할 것이기 때문에 Disabled를 사용합니다.&lt;/li&gt;&lt;li&gt;&quot;Subnets&quot;: VPC로 사용한 곳에서 Database가 사용할 Subnet의 범위를 결정합니다. 2개 이상을 선택해주는 것이 필수입니다.&lt;/li&gt;&lt;li&gt;&quot;VPC security group&quot;: 은 &quot;Create new&quot;로 생성해도 되고, 기존에 VPC가 있는 경우에는 &quot;Choose existing&quot;으로 선택해줍니다. VPC를 선택해주시는 경우에는 꼭 VPC에 &quot;Internet Gateway&quot;를 장착해주시길 바랍니다.&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/bk2oli/btqE0CnbwbK/8iZfIPDWRkkBi014KAR54k/img.png&quot; data-origin-width=&quot;703.0&quot; data-origin-height=&quot;366.0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bk2oli/btqE0CnbwbK/8iZfIPDWRkkBi014KAR54k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bk2oli/btqE0CnbwbK/8iZfIPDWRkkBi014KAR54k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bk2oli/btqE0CnbwbK/8iZfIPDWRkkBi014KAR54k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbk2oli%2FbtqE0CnbwbK%2F8iZfIPDWRkkBi014KAR54k%2Fimg.png&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/bk2oli/btqE0CnbwbK/8iZfIPDWRkkBi014KAR54k/img.png&quot; data-origin-width=&quot;703.0&quot; data-origin-height=&quot;366.0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;&quot;Enhanced logging&quot;: CloudWatch에서 커스텀하게 Logging을 관리하길 원하시면, &quot;Enable enhanced logging&quot;을 선택해줍니다.&lt;/li&gt;&lt;li&gt;아직은 Preview 상태로 정식 제품이 아니기 때문에 상용에는 사용하지 마시길 바랍니다. 그리고 인지하였음을 선택해줍니다.&lt;/li&gt;&lt;li&gt;&quot;Create proxy&quot; 생성 완료!&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/biwbQb/btqE0Ps2Xta/9JQkwmWtHyo800eWOmiUY1/img.png&quot; data-origin-width=&quot;1065.0&quot; data-origin-height=&quot;519.0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/biwbQb/btqE0Ps2Xta/9JQkwmWtHyo800eWOmiUY1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/biwbQb/btqE0Ps2Xta/9JQkwmWtHyo800eWOmiUY1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/biwbQb/btqE0Ps2Xta/9JQkwmWtHyo800eWOmiUY1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbiwbQb%2FbtqE0Ps2Xta%2F9JQkwmWtHyo800eWOmiUY1%2Fimg.png&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/biwbQb/btqE0Ps2Xta/9JQkwmWtHyo800eWOmiUY1/img.png&quot; data-origin-width=&quot;1065.0&quot; data-origin-height=&quot;519.0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;몇 분 정도 기다리면, Proxy가 생성됩니다.&lt;/li&gt;&lt;li&gt;&quot;test-proxy&quot;를 선택해서 들어가 줍니다.&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/zotAX/btqE3d130aT/NqXizJg8SNUKFqK5iO2Sck/img.png&quot; data-origin-width=&quot;1122.0&quot; data-origin-height=&quot;729.0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zotAX/btqE3d130aT/NqXizJg8SNUKFqK5iO2Sck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zotAX/btqE3d130aT/NqXizJg8SNUKFqK5iO2Sck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zotAX/btqE3d130aT/NqXizJg8SNUKFqK5iO2Sck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzotAX%2FbtqE3d130aT%2FNqXizJg8SNUKFqK5iO2Sck%2Fimg.png&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/zotAX/btqE3d130aT/NqXizJg8SNUKFqK5iO2Sck/img.png&quot; data-origin-width=&quot;1122.0&quot; data-origin-height=&quot;729.0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;생성된 proxy의 정보를 확인할 수 있습니다.&lt;/li&gt;&lt;li&gt;&quot;Proxy ARN&quot;은 이제 DB의 host endpoint처럼 사용할 수 있습니다.&lt;/li&gt;&lt;li&gt;&lt;b&gt;&lt;u&gt;중요한 점은 RDS Proxy는 AWS 내부 환경에서만 사용할 수 있습니다. Tool을 사용하여 접속하려고 하면 접속이 불가능합니다.&lt;/u&gt;&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;그래서 테스트 환경을 구성해서 Test를 진행하기 위해서, 다음 단계로 넘어가겠습니다.&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;h2&gt;5.&lt;span&gt; RDS&amp;nbsp;Proxy&amp;nbsp;Endpoint를&amp;nbsp;사용해서,&amp;nbsp;&quot;Automatic&amp;nbsp;Failover&quot;&amp;nbsp;테스트하기&lt;/span&gt;&lt;/h2&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;: 이제 필요한 모든 Resource를 생성했습니다. 마지막으로 테스트 환경을 구성해서 과연 RDS Proxy를 사용해서 Primary DB(Writer)가 장애(failure)가 발생하였을 때, Automatic Failover가 반영이 되는지 확인해보겠습니다.&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: rgb(51, 51, 51);&quot;&gt;&lt;span style=&quot;color: rgb(51, 51, 51);&quot;&gt;AWS Aurora Automatic Failover&lt;/span&gt;&amp;nbsp;테스트를 진행하기 위한 구성은 다음과 같습니다.&lt;/span&gt;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;&lt;span style=&quot;color: rgb(51, 51, 51);&quot;&gt;RDS Aurora Instance Cluster 1(Primary Instance 1, Replica Instance 1)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;color: rgb(51, 51, 51);&quot;&gt;RDS Proxy 1(&lt;/span&gt;&lt;span style=&quot;color: rgb(51, 51, 51);&quot;&gt;Secrets Manager &quot;Secret&quot;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(51, 51, 51);&quot;&gt;IAM &quot;Policy&quot;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(51, 51, 51);&quot;&gt;IAM &quot;Role&quot;)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;color: rgb(51, 51, 51);&quot;&gt;EC2 Instance 1&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/bctnvn/btqE5PZL6yK/z9MWloqpDNeKRF1QHCWg1K/img.png&quot; data-origin-width=&quot;549.0&quot; data-origin-height=&quot;439.0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bctnvn/btqE5PZL6yK/z9MWloqpDNeKRF1QHCWg1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bctnvn/btqE5PZL6yK/z9MWloqpDNeKRF1QHCWg1K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bctnvn/btqE5PZL6yK/z9MWloqpDNeKRF1QHCWg1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbctnvn%2FbtqE5PZL6yK%2Fz9MWloqpDNeKRF1QHCWg1K%2Fimg.png&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/bctnvn/btqE5PZL6yK/z9MWloqpDNeKRF1QHCWg1K/img.png&quot; data-origin-width=&quot;549.0&quot; data-origin-height=&quot;439.0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;EC2 Instance를 생성하기 위해서, &quot;EC2&quot; =&amp;gt; &quot;Instances&quot; =&amp;gt; &quot;Launch Instance&quot; 선택합니다.&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/b2Ok3U/btqE5O0RbbS/PvmKjekGr50BgjT0GpqE9K/img.png&quot; data-origin-width=&quot;1896.0&quot; data-origin-height=&quot;240.0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b2Ok3U/btqE5O0RbbS/PvmKjekGr50BgjT0GpqE9K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b2Ok3U/btqE5O0RbbS/PvmKjekGr50BgjT0GpqE9K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b2Ok3U/btqE5O0RbbS/PvmKjekGr50BgjT0GpqE9K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb2Ok3U%2FbtqE5O0RbbS%2FPvmKjekGr50BgjT0GpqE9K%2Fimg.png&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/b2Ok3U/btqE5O0RbbS/PvmKjekGr50BgjT0GpqE9K/img.png&quot; data-origin-width=&quot;1896.0&quot; data-origin-height=&quot;240.0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;테스트를 위한 MySQL을 패키지로 제공하는 &quot;Amazon Linux AMI&quot;를 사용했습니다.&lt;/li&gt;&lt;li&gt;물론 다른 OS를 선택하시고, MySQL을 설치해주어도 됩니다.&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/wuU9M/btqE5PFsc29/hWnC9YoTyJqCRE7vuZDeK0/img.png&quot; data-origin-width=&quot;1064.0&quot; data-origin-height=&quot;840.0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wuU9M/btqE5PFsc29/hWnC9YoTyJqCRE7vuZDeK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wuU9M/btqE5PFsc29/hWnC9YoTyJqCRE7vuZDeK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wuU9M/btqE5PFsc29/hWnC9YoTyJqCRE7vuZDeK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwuU9M%2FbtqE5PFsc29%2FhWnC9YoTyJqCRE7vuZDeK0%2Fimg.png&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/wuU9M/btqE5PFsc29/hWnC9YoTyJqCRE7vuZDeK0/img.png&quot; data-origin-width=&quot;1064.0&quot; data-origin-height=&quot;840.0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;원하는 EC2 Type을 선택하면 됩니다. 여기서는 t2.micro를 사용했습니다.&lt;/li&gt;&lt;li&gt;&quot;Next: Configure Instance Details&quot;를 선택&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/czvpnQ/btqE6xc3jHo/sPLe3oB85Fqc3pkoV2y3CK/img.png&quot; data-origin-width=&quot;1055.0&quot; data-origin-height=&quot;834.0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/czvpnQ/btqE6xc3jHo/sPLe3oB85Fqc3pkoV2y3CK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/czvpnQ/btqE6xc3jHo/sPLe3oB85Fqc3pkoV2y3CK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/czvpnQ/btqE6xc3jHo/sPLe3oB85Fqc3pkoV2y3CK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FczvpnQ%2FbtqE6xc3jHo%2FsPLe3oB85Fqc3pkoV2y3CK%2Fimg.png&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/czvpnQ/btqE6xc3jHo/sPLe3oB85Fqc3pkoV2y3CK/img.png&quot; data-origin-width=&quot;1055.0&quot; data-origin-height=&quot;834.0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;여기서 테스트를 위한 설정으로 중요한 부분은 VPC 설정입니다.&lt;/li&gt;&lt;li&gt;VPC는 테스트에 사용되는 RDS Aurora Cluster와 같은 VPC를 사용하시면 됩니다. 서로 다른 VPC 접근은 허용하게 설계되었다면,&amp;nbsp; VPC가 달라도 무관합니다.&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/bKcPr9/btqE5P6y95l/6M1cFcKmErc7vBUQvK8260/img.png&quot; data-origin-width=&quot;1064.0&quot; data-origin-height=&quot;835.0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKcPr9/btqE5P6y95l/6M1cFcKmErc7vBUQvK8260/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKcPr9/btqE5P6y95l/6M1cFcKmErc7vBUQvK8260/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKcPr9/btqE5P6y95l/6M1cFcKmErc7vBUQvK8260/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKcPr9%2FbtqE5P6y95l%2F6M1cFcKmErc7vBUQvK8260%2Fimg.png&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/bKcPr9/btqE5P6y95l/6M1cFcKmErc7vBUQvK8260/img.png&quot; data-origin-width=&quot;1064.0&quot; data-origin-height=&quot;835.0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;테스트를 위해서 방화벽인 Security Group의 Inbound Rule은 All traffic을 허용해두겠습니다.&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/bH79wF/btqE3dudnsF/AIOnk12PR5XZZoeffJDX2K/img.png&quot; data-origin-width=&quot;1061.0&quot; data-origin-height=&quot;840.0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bH79wF/btqE3dudnsF/AIOnk12PR5XZZoeffJDX2K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bH79wF/btqE3dudnsF/AIOnk12PR5XZZoeffJDX2K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bH79wF/btqE3dudnsF/AIOnk12PR5XZZoeffJDX2K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbH79wF%2FbtqE3dudnsF%2FAIOnk12PR5XZZoeffJDX2K%2Fimg.png&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/bH79wF/btqE3dudnsF/AIOnk12PR5XZZoeffJDX2K/img.png&quot; data-origin-width=&quot;1061.0&quot; data-origin-height=&quot;840.0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;마지막으로 설정된 정보를 확인하고, &quot;Launch&quot;를 눌러서 EC2 Instance를 생성합니다.&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/bTZeBm/btqE5OGyZ1c/XXgDQKdwaPh5CNFGkLqvBK/img.png&quot; data-origin-width=&quot;644.0&quot; data-origin-height=&quot;394.0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bTZeBm/btqE5OGyZ1c/XXgDQKdwaPh5CNFGkLqvBK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bTZeBm/btqE5OGyZ1c/XXgDQKdwaPh5CNFGkLqvBK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bTZeBm/btqE5OGyZ1c/XXgDQKdwaPh5CNFGkLqvBK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbTZeBm%2FbtqE5OGyZ1c%2FXXgDQKdwaPh5CNFGkLqvBK%2Fimg.png&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/bTZeBm/btqE5OGyZ1c/XXgDQKdwaPh5CNFGkLqvBK/img.png&quot; data-origin-width=&quot;644.0&quot; data-origin-height=&quot;394.0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;EC2 Instance를 생성하기 위해서는 접근을 위한, &quot;.pem&quot; 파일을 생성하거나, 기존의 &quot;.pem&quot;파일을 사용하셔도 됩니다.&lt;/li&gt;&lt;li&gt;여기에서는 기존의 &quot;.pem&quot;파일을 사용하겠습니다.&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/6Tern/btqE4EdxEj7/YRRFtepFoeJkpVaHerbf31/img.png&quot; data-origin-width=&quot;821.0&quot; data-origin-height=&quot;247.0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6Tern/btqE4EdxEj7/YRRFtepFoeJkpVaHerbf31/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6Tern/btqE4EdxEj7/YRRFtepFoeJkpVaHerbf31/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6Tern/btqE4EdxEj7/YRRFtepFoeJkpVaHerbf31/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6Tern%2FbtqE4EdxEj7%2FYRRFtepFoeJkpVaHerbf31%2Fimg.png&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/6Tern/btqE4EdxEj7/YRRFtepFoeJkpVaHerbf31/img.png&quot; data-origin-width=&quot;821.0&quot; data-origin-height=&quot;247.0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;생성된 EC2를 확인할 수 있습니다.&lt;/li&gt;&lt;li&gt;이제 직접 접속하기 위해서 &quot;Connect&quot;를 선택해줍니다.&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/bgDcj9/btqE3dOwcHn/h8rA6InKjRCqQlWOxXfxpK/img.png&quot; data-origin-width=&quot;731.0&quot; data-origin-height=&quot;589.0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgDcj9/btqE3dOwcHn/h8rA6InKjRCqQlWOxXfxpK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgDcj9/btqE3dOwcHn/h8rA6InKjRCqQlWOxXfxpK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgDcj9/btqE3dOwcHn/h8rA6InKjRCqQlWOxXfxpK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgDcj9%2FbtqE3dOwcHn%2Fh8rA6InKjRCqQlWOxXfxpK%2Fimg.png&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/bgDcj9/btqE3dOwcHn/h8rA6InKjRCqQlWOxXfxpK/img.png&quot; data-origin-width=&quot;731.0&quot; data-origin-height=&quot;589.0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;여기에서 EC2 Instance에 접속하기 위해서 Example의 CLI 명령어를 복사합니다.&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/biYdd4/btqE5P6zzss/eOwujQFdPRKYKGGabE3hWK/img.png&quot; data-origin-width=&quot;655.0&quot; data-origin-height=&quot;212.0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/biYdd4/btqE5P6zzss/eOwujQFdPRKYKGGabE3hWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/biYdd4/btqE5P6zzss/eOwujQFdPRKYKGGabE3hWK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/biYdd4/btqE5P6zzss/eOwujQFdPRKYKGGabE3hWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbiYdd4%2FbtqE5P6zzss%2FeOwujQFdPRKYKGGabE3hWK%2Fimg.png&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/biYdd4/btqE5P6zzss/eOwujQFdPRKYKGGabE3hWK/img.png&quot; data-origin-width=&quot;655.0&quot; data-origin-height=&quot;212.0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;터미널로 와서 위에서 복사한 CLI 명령어를 붙여 넣어서 접속합니다.&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;접속하고 나면, 일단 필요한 MySQL 패키지를 설치하기 위해서 다음 명령어를 실행해줍니다.&lt;/p&gt;&lt;blockquote data-ke-style=&quot;style2&quot;&gt;sudo yum update -y&lt;br&gt;sudo yum install mysql-server -y&lt;/blockquote&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;테스트를 하기 위한 Database: &quot;test&quot;와 Table: &quot;user&quot;를 생성하기 위해서 다음 명령어를 실행해줍니다.&lt;/p&gt;&lt;blockquote data-ke-style=&quot;style2&quot;&gt;mysql -s -N --host=test.cluster-test1290393.ap-northeast-1.rds.amazonaws.com --user=admin --password=testdb1234! --port=3306 -e &quot;create database test;use test;create table user (id BIGINT(20) UNSIGNED not null auto_increment, name varchar(255), age varchar(255), created_at datetime(6) not null, modified_at datetime(6) not null, primary key (id)) engine=InnoDB;&quot;;&lt;/blockquote&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/zotAX/btqE3d130aT/NqXizJg8SNUKFqK5iO2Sck/img.png&quot; data-origin-width=&quot;1122.0&quot; data-origin-height=&quot;729.0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zotAX/btqE3d130aT/NqXizJg8SNUKFqK5iO2Sck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zotAX/btqE3d130aT/NqXizJg8SNUKFqK5iO2Sck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zotAX/btqE3d130aT/NqXizJg8SNUKFqK5iO2Sck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzotAX%2FbtqE3d130aT%2FNqXizJg8SNUKFqK5iO2Sck%2Fimg.png&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/zotAX/btqE3d130aT/NqXizJg8SNUKFqK5iO2Sck/img.png&quot; data-origin-width=&quot;1122.0&quot; data-origin-height=&quot;729.0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;테스트를 위해서 이전에 만들었던, RDS Proxy endpoint을 복사합니다.&lt;/li&gt;&lt;li&gt;RDS Proxy endpoint 접근은 AWS 내부에서 접근이 가능합니다. 외부에서는 접근이 불가능합니다. 혹시 DB tool로 사용하신다면, 접속이 안되실 겁니다.&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/cjS7By/btqE40tVevY/l1npWnS9voFhWP4G3rUjy1/img.png&quot; data-origin-width=&quot;1052.0&quot; data-origin-height=&quot;705.0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cjS7By/btqE40tVevY/l1npWnS9voFhWP4G3rUjy1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cjS7By/btqE40tVevY/l1npWnS9voFhWP4G3rUjy1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cjS7By/btqE40tVevY/l1npWnS9voFhWP4G3rUjy1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcjS7By%2FbtqE40tVevY%2Fl1npWnS9voFhWP4G3rUjy1%2Fimg.png&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/cjS7By/btqE40tVevY/l1npWnS9voFhWP4G3rUjy1/img.png&quot; data-origin-width=&quot;1052.0&quot; data-origin-height=&quot;705.0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;RDS Proxy가 생성되었다고 해서, Aurora Cluster의 Endpoint를 사용하지 못하진 않습니다.&lt;/li&gt;&lt;li&gt;하단에 보이는 &quot;Writer&quot;, &quot;Reader&quot; cluster endpoint 도 여전히 사용 가능합니다.&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/b3VYPz/btqE31tETkV/VH1HMusVa2hDkka8KR1LSK/img.png&quot; data-origin-width=&quot;967.0&quot; data-origin-height=&quot;61.0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b3VYPz/btqE31tETkV/VH1HMusVa2hDkka8KR1LSK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b3VYPz/btqE31tETkV/VH1HMusVa2hDkka8KR1LSK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b3VYPz/btqE31tETkV/VH1HMusVa2hDkka8KR1LSK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb3VYPz%2FbtqE31tETkV%2FVH1HMusVa2hDkka8KR1LSK%2Fimg.png&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/b3VYPz/btqE31tETkV/VH1HMusVa2hDkka8KR1LSK/img.png&quot; data-origin-width=&quot;967.0&quot; data-origin-height=&quot;61.0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;테스트를 위한 Insert 쿼리 하나, Select 쿼리 하나를 1초 간격으로 반복문으로 실행시켜놓습니다. (테스트가 끝났을 때는 control + C로 종료해줍니다.)&lt;/li&gt;&lt;/ul&gt;&lt;blockquote data-ke-style=&quot;style2&quot;&gt;while true; do mysql -s -N --host=test.cluster-test1290393.ap-northeast-1.rds.amazonaws.com --user=admin --password=testdb1234! --port=3306 --database=test -e &quot;insert into user(name, age, created_at, modified_at) values('name', 'age', now(), now());select now();&quot;; sleep 1; done&lt;/blockquote&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/C9SP6/btqE5PZL6Ew/VFtks9kQd9KxqbafwdvM1K/img.png&quot; data-origin-width=&quot;1050.0&quot; data-origin-height=&quot;516.0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/C9SP6/btqE5PZL6Ew/VFtks9kQd9KxqbafwdvM1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/C9SP6/btqE5PZL6Ew/VFtks9kQd9KxqbafwdvM1K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/C9SP6/btqE5PZL6Ew/VFtks9kQd9KxqbafwdvM1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FC9SP6%2FbtqE5PZL6Ew%2FVFtks9kQd9KxqbafwdvM1K%2Fimg.png&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/C9SP6/btqE5PZL6Ew/VFtks9kQd9KxqbafwdvM1K/img.png&quot; data-origin-width=&quot;1050.0&quot; data-origin-height=&quot;516.0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;RDS는 Instance를 수동으로 DB를 Failover 시킬 수 있게 기능을 제공합니다.&lt;/li&gt;&lt;li&gt;Failover 테스트를 위해서, RDS Databases =&amp;gt; Writer DB Instance 선택 =&amp;gt; &quot;Actions&quot; =&amp;gt; Failover 선택 OK&lt;/li&gt;&lt;li&gt;쿼리를 반복문으로 실행하였던, 터미널로 돌아갑니다.&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/c5YZgX/btqE4pt9QYh/D6BT6YqgIHRXNedpCND1h1/img.gif&quot; data-origin-width=&quot;1920.0&quot; data-origin-height=&quot;940.0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c5YZgX/btqE4pt9QYh/D6BT6YqgIHRXNedpCND1h1/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c5YZgX/btqE4pt9QYh/D6BT6YqgIHRXNedpCND1h1/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c5YZgX/btqE4pt9QYh/D6BT6YqgIHRXNedpCND1h1/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/c5YZgX/btqE4pt9QYh/D6BT6YqgIHRXNedpCND1h1/img.gif&quot; data-image-src=&quot;https://k.kakaocdn.net/dn/c5YZgX/btqE4pt9QYh/D6BT6YqgIHRXNedpCND1h1/img.gif&quot; data-origin-width=&quot;1920.0&quot; data-origin-height=&quot;940.0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;RDS Aurora를 이용한 Primary DB 장애 발생 시, Failover를 위한 RDS Proxy 테스트가 완료되었습니다.&lt;/li&gt;&lt;li&gt;기본적으로 RDS는 Engine에 따라서 Failover 되어 보통은 30초 이내 시간을 보장합니다.&lt;/li&gt;&lt;li&gt;&lt;u&gt;다시 한번 말씀드리면, RDS Proxy는 현재 Preview 이기 때문에 상용 DB에 쓰는 것을 아직 권하지 않습니다.&lt;/u&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;hr data-ke-type=&quot;horizontalRule&quot; contenteditable=&quot;false&quot; data-ke-style=&quot;style6&quot;&gt;&lt;h2 data-ke-size=&quot;size26&quot; style=&quot;text-align: left;&quot;&gt;결론&lt;/h2&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;메인 DB가 장애가 오거나, 유지 보수하는 경우에는 Failover를 구현하는 것은 상당히 중요합니다.&lt;/li&gt;&lt;li&gt;Downtime을 짧게 하고, DB에 요청된 쿼리를 안전하게 무효화시키는 것도 중요합니다.&lt;/li&gt;&lt;li&gt;&lt;u&gt;RDS Aurora를 사용하시는 분이라면, 추후에 RDS Proxy가 서비스 정식 런칭이 되면, 사용하시길 추천합니다.&lt;/u&gt;&lt;/li&gt;&lt;li&gt;추천하는 이유가 한 가지 더 있는데요. DB connection pool을 관리시켜줘서, 중복되거나 유휴된 Connection을 관리하여, 적은 Connection을 가지고, Connection 최적화를 이룰 수 있습니다.&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;hr data-ke-type=&quot;horizontalRule&quot; contenteditable=&quot;false&quot; data-ke-style=&quot;style6&quot;&gt;&lt;h2 data-ke-size=&quot;size26&quot; style=&quot;text-align: left;&quot;&gt;참고자료&lt;/h2&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/AmazonRDS/latest/AuroraUserGuide/rds-proxy.html&quot; target=&quot;_blank&quot;&gt;AWS RDS Proxy Docs&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;figure data-ke-type=&quot;opengraph&quot; data-og-title=&quot;Amazon RDS Proxy(미리 보기)를 사용한 연결 관리 - Amazon Aurora&quot; data-og-description=&quot;현재 Amazon RDS Proxy는 미리 보기로 제공됩니다. RDS Proxy를 프로덕션 워크로드에 사용하지 마십시오. 또한 RDS Proxy 미리 보기로 사용하는 데이터베이스에는 중요한 데이터를 저장하지 않는 것이 좋�&quot; data-og-host=&quot;docs.aws.amazon.com&quot; data-og-source-url=&quot;https://docs.aws.amazon.com/ko_kr/AmazonRDS/latest/AuroraUserGuide/rds-proxy.html&quot; data-og-url=&quot;https://docs.aws.amazon.com/ko_kr/AmazonRDS/latest/AuroraUserGuide/rds-proxy.html&quot;&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/AmazonRDS/latest/AuroraUserGuide/rds-proxy.html&quot; target=&quot;_blank&quot; data-source-url=&quot;https://docs.aws.amazon.com/ko_kr/AmazonRDS/latest/AuroraUserGuide/rds-proxy.html&quot;&gt;&lt;div class=&quot;og-image&quot;&gt;&lt;/div&gt;&lt;div class=&quot;og-text&quot;&gt;&lt;p class=&quot;og-title&quot;&gt;Amazon RDS Proxy(미리 보기)를 사용한 연결 관리 - Amazon Aurora&lt;/p&gt;&lt;p class=&quot;og-desc&quot;&gt;현재 Amazon RDS Proxy는 미리 보기로 제공됩니다. RDS Proxy를 프로덕션 워크로드에 사용하지 마십시오. 또한 RDS Proxy 미리 보기로 사용하는 데이터베이스에는 중요한 데이터를 저장하지 않는 것이 좋�&lt;/p&gt;&lt;p class=&quot;og-host&quot;&gt;docs.aws.amazon.com&lt;/p&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;&lt;a href=&quot;https://aws.amazon.com/ko/rds/aurora/&quot; target=&quot;_blank&quot;&gt;AWS Amazon Aurora&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;figure data-ke-type=&quot;opengraph&quot; data-og-title=&quot;데이터 베이스 관리 시스템 | MySQL | Amazon Web Services&quot; data-og-description=&quot;Amazon Aurora는 관계형 데이터베이스를 사용할 수 있는 엔터프라이즈 애플리케이션에 매우 적합한 옵션입니다. Amazon Aurora는 상용 데이터베이스와 비교하여 데이터베이스 비용을 90% 이상 낮추면서&quot; data-og-host=&quot;aws.amazon.com&quot; data-og-source-url=&quot;https://aws.amazon.com/ko/rds/aurora/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/tBjaG/hyGxbZZHus/6rVXHSnMTIRATVtI3j2X70/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot; data-og-url=&quot;https://aws.amazon.com/ko/rds/aurora/&quot;&gt;&lt;a href=&quot;https://aws.amazon.com/ko/rds/aurora/&quot; target=&quot;_blank&quot; data-source-url=&quot;https://aws.amazon.com/ko/rds/aurora/&quot;&gt;&lt;div class=&quot;og-image&quot; style=&quot;background-image:url(https://scrap.kakaocdn.net/dn/tBjaG/hyGxbZZHus/6rVXHSnMTIRATVtI3j2X70/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630)&quot;&gt;&lt;/div&gt;&lt;div class=&quot;og-text&quot;&gt;&lt;p class=&quot;og-title&quot;&gt;데이터 베이스 관리 시스템 | MySQL | Amazon Web Services&lt;/p&gt;&lt;p class=&quot;og-desc&quot;&gt;Amazon Aurora는 관계형 데이터베이스를 사용할 수 있는 엔터프라이즈 애플리케이션에 매우 적합한 옵션입니다. Amazon Aurora는 상용 데이터베이스와 비교하여 데이터베이스 비용을 90% 이상 낮추면서&lt;/p&gt;&lt;p class=&quot;og-host&quot;&gt;aws.amazon.com&lt;/p&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;&lt;a href=&quot;https://www.allthingsdistributed.com/2017/05/amazon-aurora-design-considerations.html&quot; target=&quot;_blank&quot;&gt;AWS Amazon Aurora Concept&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;figure data-ke-type=&quot;opengraph&quot; data-og-title=&quot;Weekend Reading: Amazon Aurora: Design Considerations for High Throughput Cloud-Native Relational Databases. - All Things Distri&quot; data-og-description=&quot;In many high-throughput OLTP style applications, the database plays a crucial role in achieving scale, reliability, high-performance, and cost efficiency. For a long time, these requirements were almost exclusively served by commercial, proprietary databas&quot; data-og-host=&quot;www.allthingsdistributed.com&quot; data-og-source-url=&quot;https://www.allthingsdistributed.com/2017/05/amazon-aurora-design-considerations.html&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/d8LZrI/hyGw65rd6Z/k1hm6XpWJuFPGT1wZbwKB1/img.png?width=650&amp;amp;height=335&amp;amp;face=0_0_650_335&quot; data-og-url=&quot;https://www.allthingsdistributed.com/2017/05/amazon-aurora-design-considerations.html&quot;&gt;&lt;a href=&quot;https://www.allthingsdistributed.com/2017/05/amazon-aurora-design-considerations.html&quot; target=&quot;_blank&quot; data-source-url=&quot;https://www.allthingsdistributed.com/2017/05/amazon-aurora-design-considerations.html&quot;&gt;&lt;div class=&quot;og-image&quot; style=&quot;background-image:url(https://scrap.kakaocdn.net/dn/d8LZrI/hyGw65rd6Z/k1hm6XpWJuFPGT1wZbwKB1/img.png?width=650&amp;amp;height=335&amp;amp;face=0_0_650_335)&quot;&gt;&lt;/div&gt;&lt;div class=&quot;og-text&quot;&gt;&lt;p class=&quot;og-title&quot;&gt;Weekend Reading: Amazon Aurora: Design Considerations for High Throughput Cloud-Native Relational Databases. - All Things Distri&lt;/p&gt;&lt;p class=&quot;og-desc&quot;&gt;In many high-throughput OLTP style applications, the database plays a crucial role in achieving scale, reliability, high-performance, and cost efficiency. For a long time, these requirements were almost exclusively served by commercial, proprietary databas&lt;/p&gt;&lt;p class=&quot;og-host&quot;&gt;www.allthingsdistributed.com&lt;/p&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/AmazonRDS/latest/UserGuide/Concepts.MultiAZ.html&quot; target=&quot;_blank&quot;&gt;AWS RDS HA(Multi-AZ)&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;figure data-ke-type=&quot;opengraph&quot; data-og-title=&quot;Amazon RDS를 위한 고가용성(다중 AZ) - Amazon Relational Database Service&quot; data-og-description=&quot;Amazon RDS를 위한 고가용성(다중 AZ) Amazon RDS는 다중 AZ 배포를 사용해 DB 인스턴스에 고가용성과 장애 조치 기능을 지원합니다. Amazon RDS는 다양한 기술을 이용해 장애 조치 지원을 제공합니다. MariaD&quot; data-og-host=&quot;docs.aws.amazon.com&quot; data-og-source-url=&quot;https://docs.aws.amazon.com/ko_kr/AmazonRDS/latest/UserGuide/Concepts.MultiAZ.html&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/guV1Y/hyGxdcrF1Z/vHVgWyUj8bTVIXSjOVDiXk/img.png?width=690&amp;amp;height=346&amp;amp;face=0_0_690_346&quot; data-og-url=&quot;https://docs.aws.amazon.com/ko_kr/AmazonRDS/latest/UserGuide/Concepts.MultiAZ.html&quot;&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/AmazonRDS/latest/UserGuide/Concepts.MultiAZ.html&quot; target=&quot;_blank&quot; data-source-url=&quot;https://docs.aws.amazon.com/ko_kr/AmazonRDS/latest/UserGuide/Concepts.MultiAZ.html&quot;&gt;&lt;div class=&quot;og-image&quot; style=&quot;background-image:url(https://scrap.kakaocdn.net/dn/guV1Y/hyGxdcrF1Z/vHVgWyUj8bTVIXSjOVDiXk/img.png?width=690&amp;amp;height=346&amp;amp;face=0_0_690_346)&quot;&gt;&lt;/div&gt;&lt;div class=&quot;og-text&quot;&gt;&lt;p class=&quot;og-title&quot;&gt;Amazon RDS를 위한 고가용성(다중 AZ) - Amazon Relational Database Service&lt;/p&gt;&lt;p class=&quot;og-desc&quot;&gt;Amazon RDS를 위한 고가용성(다중 AZ) Amazon RDS는 다중 AZ 배포를 사용해 DB 인스턴스에 고가용성과 장애 조치 기능을 지원합니다. Amazon RDS는 다양한 기술을 이용해 장애 조치 지원을 제공합니다. MariaD&lt;/p&gt;&lt;p class=&quot;og-host&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; style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>AWS</category>
      <author>RyanGomdoriPooh</author>
      <guid isPermaLink="true">https://interconnection.tistory.com/125</guid>
      <comments>https://interconnection.tistory.com/125#entry125comment</comments>
      <pubDate>Thu, 18 Jun 2020 21:14:36 +0900</pubDate>
    </item>
    <item>
      <title>Spring &amp;quot;Field Injection&amp;quot;? or &amp;quot;Constructor Injection&amp;quot;?</title>
      <link>https://interconnection.tistory.com/124</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;이야기에 앞서서...&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;Spring Framework에서 제공하는 @Autowired나 @Qualifier를 이용해서 객체를 찾아서 DI(&lt;span style=&quot;color: #333333;&quot;&gt;Dependency Injection)&lt;/span&gt;해왔습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;물론 Java에서도 @Inject, @Resource를 제공해주어서 DI(Dependency Injection)를 할 수 있었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;우선, DI는 IoC(Inversion of Control)의 핵심 원리를 구현하는 개념이라고 할 수 있습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;간단하게 IoC(Inversion of Control)란?&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;: IoC의 핵심은 기존의 Programing code 안에 들어가 있던 객체의 생성/관리를 Spring Container에게 위임하여 객체의 생명주기를 관리하게 하는 것입니다. 관리하는 객체의 단위를 Bean이라고 명명합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;IoC를 구현하기 위해서는 DI를 통해서 Bean을 생성하는 시점에 필요한 객체를 주입해주어야 합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;결국, 우리가 이야기하는 핵심은 &lt;b&gt;&quot;언제 어떻게 Bean을 생성하는 시점에 필요한 객체를 주입해야 하는가?&quot;&lt;/b&gt;가 됩니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Field Injection인 @Autowired의 이야기부터 시작하겠습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-filename=&quot;Screen Shot 2020-06-15 at 10.28.11 PM.png&quot; data-origin-width=&quot;320&quot; data-origin-height=&quot;59&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PH28f/btqEP2M7awt/8FxOnO6HGK5kGUVZXiQ6m1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PH28f/btqEP2M7awt/8FxOnO6HGK5kGUVZXiQ6m1/img.png&quot; data-alt=&quot;IDE에서 보여주는 경고&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PH28f/btqEP2M7awt/8FxOnO6HGK5kGUVZXiQ6m1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPH28f%2FbtqEP2M7awt%2F8FxOnO6HGK5kGUVZXiQ6m1%2Fimg.png&quot; data-filename=&quot;Screen Shot 2020-06-15 at 10.28.11 PM.png&quot; data-origin-width=&quot;320&quot; data-origin-height=&quot;59&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;IDE에서 보여주는 경고&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;최근에 리팩터링을 진행하면서, 코드에서 발견한 부분이 있었습니다. @Autowired에 대한 노란색 밑줄 경고죠.&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;해당하는 경고 문구는 다음과 같습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-filename=&quot;Screen Shot 2020-06-15 at 10.29.18 PM.png&quot; data-origin-width=&quot;547&quot; data-origin-height=&quot;63&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ER890/btqESXJHihK/TIIb8bB5zLZ0D6DiIj5WuK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ER890/btqESXJHihK/TIIb8bB5zLZ0D6DiIj5WuK/img.png&quot; data-alt=&quot;Injection 경고 문구&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ER890/btqESXJHihK/TIIb8bB5zLZ0D6DiIj5WuK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FER890%2FbtqESXJHihK%2FTIIb8bB5zLZ0D6DiIj5WuK%2Fimg.png&quot; data-filename=&quot;Screen Shot 2020-06-15 at 10.29.18 PM.png&quot; data-origin-width=&quot;547&quot; data-origin-height=&quot;63&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;figcaption&gt;Injection 경고 문구&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;경고 문구는 간략하게 다음과 같습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Field injection을 추천하지 않는다.&lt;/li&gt;
&lt;li&gt;Spring Team은 너의 Bean들에게 Constructor 기반의 DI를 항상 사용해라.&lt;/li&gt;
&lt;li&gt;필수적인 의존성들을 위한 assertions를 사용해라.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;위 문구는 한 문장으로 &quot;Constructor based injection을 써라. 안 쓰면 DI를 보장 못할 수 있어.&quot;라고 표현하면 맞겠네요.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;뭔가 문제가 있다고 생각하니 경고를 보내고 있다고만 일단 생각하면 됩니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그러면 이제 &quot;어떤 문제가 있는 것인가?&quot;를 찾아보면 되겠네요.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Field Injection은 어떤 문제를 가지고 있는가?&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;우리는 Java를 사용하면서, 가장 많이 들었던 말이 있습니다. OOP(Object Oriented Programming)입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;OOP는 낮은 &quot;결합성&quot;, 높은 &quot;응집성&quot; 구현하기 위한 개념이죠.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;결국, &quot;Inheritance&quot;, &quot;Polymolphism&quot;, &quot;Encapsulation&quot;, &quot;Abstraction&quot;는 &lt;span style=&quot;color: #333333;&quot;&gt;낮은 &quot;결합성&quot;, 높은 &quot;응집성&quot; 구현하기 위한 개념입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;IoC의 DI를 통해서 우리는 낮은 &quot;결합성&quot;을 구현할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;여기까지는 &quot;Setter Injection&quot;, &quot;Constructor Injection&quot;, &quot;Field Injection&quot; 모두 아무런 문제를 발견할 수 없었습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Code를 통한 Injection : &lt;span style=&quot;color: #333333;&quot;&gt;&quot;Setter Injection&quot;, &quot;Constructor Injection&quot;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Annotation을 통한 Injection : &lt;span style=&quot;color: #333333;&quot;&gt;&quot;Field Injection&quot;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이제 문제를 찾아보겠습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;다음은 &quot;Setter Injection&quot;에 대한 코드입니다. (코드를 간단하게 표현하기 위해서 DTO는 사용하지 않겠습니다.)&lt;/p&gt;
&lt;pre id=&quot;code_1592233663380&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Service
public class UserService {
    private UserRepository userRepository;

    public void setUserRepository(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public User getUser(long userId) {
        return userRepository.findById(userId);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1592234342591&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Controller
public class UserController {
	
    @GetMapping(&quot;/users/{id}&quot;)
    public User getUserInfo(@PathVariable long id) {
    	UserService userService = new UserService();
        userService.setUserRepository(new UserRepository());
        
        return userService.getUser(id);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;여기까지는 정상적으로 new UserRepository()를 setter에 전달해주었기 때문에 문제가 없습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그런데 항상 우리 개발자는 실수를 할 수도 있죠. 바로 다음과 같은 코드입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1592235342215&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Controller
public class UserController {
	
    @GetMapping(&quot;/users/{id}&quot;)
    public User getUserInfo(@PathVariable long id) {
    	UserService userService = new UserService();
        // userService.setUserRepository(new UserRepository());
        
        return userService.getUser(id);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;new UserRepository()를 setter로 전달해주는 것을 까먹은 것입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;문제는 CompileTime에 이 실수를 잡아주지 않습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;UserService는 생성이 되고, 결국 RunTime에 userService.getUser(id);가 호출되는 시점에 NullPointException()이 발생하게 됩니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;u&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Field Injection도 &lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Setter Injection과 마찬가지로&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Spring Container가 주입해야할 new UserRepository()를 주입하지 않아도&amp;nbsp; UserService가 생성되는 문제가 있습니다.&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;&lt;u&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;결국 Setter Injection처럼 &lt;span style=&quot;color: #333333;&quot;&gt;userService.getUser(id);가 호출되는 시점에 NullPointException()이 발생하게 됩니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/u&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1592236178633&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;//&amp;lt;- null

    public User getUser(long userId) {
        return userRepository.findById(userId);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1592236152679&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Controller
public class UserController {
	
    @GetMapping(&quot;/users/{id}&quot;)
    public User getUserInfo(@PathVariable long id) {
    	UserService userService = new UserService();
        
        return userService.getUser(id);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;차이점은 주입을 setter로 프로그래머가 직접 하는가, 아니면 @Autowired로 Spring Container가 해주는가입니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;여기까지 Setter Injection / Field Injection의 단점에 대해서 알게 되었습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;CompileTime에 문제가 발견되지 않고, &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;RunTime에 Method를 호출하게 되면, NPE가 발생하는 것&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;Constructor Injection은 어떤 장점이 있을까?&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;Service Layer의 Business Logic이 복잡해지면 복잡해질수록, 우리는 주입된 Bean들이 엄청 늘어나는 것을 볼 수 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Bean들이 늘어나면서, &lt;span style=&quot;color: #333333;&quot;&gt;서로 다른 Service에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;거미줄처럼 주입되어있게 되는데,&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Annotation &quot;@Autowired&quot;을 통한 &lt;span style=&quot;color: #333333;&quot;&gt;Field Injection은 CompileTime에 순환 참조를 확인할 수 없습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;이유는 다음과 같습니다.&lt;/span&gt;&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;color: #333333;&quot;&gt;Setter Injection / Field Injection은 일단 모든 Bean을 생성하여 Bean Factory에 등록합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Bean이 모두 생성되어 Bean Factory에 등록되고나면, 주입할 Bean들을 가져와서 주입합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;결국 순환 참조를 알아챌 타이밍을 이 시점에는 놓쳐버리게 되는 겁니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;이제 순환 참조가 만들 지옥은 Runtime에 Business Logic에서 발생하게 되겠습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;결국에 나도 모르는 사이에 Runtime 순환 참조가 발생할 수 있는 가능성이 생겨버릴 수 있는 것입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Field Injection을 통한 순환 참조 발생 문제 발생을 설명하겠습니다.&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;순환 참조된 상태의 Bean이 2개가 생성된다.&lt;/li&gt;
&lt;li&gt;순환 참조된 상태의 Bean A와 Bean B가 Business Logic에 서로 Method를 호출하는 Method A를 만든다.&lt;/li&gt;
&lt;li&gt;Method A가 Runtime에 호출이 된다.&lt;/li&gt;
&lt;li&gt;서로 호출되면서 Recusive 방식으로 Stack에 호출된 Method가 쌓인다.&lt;/li&gt;
&lt;li&gt;결국 Stack의 Memory Size가 넘어가면서, java.lang.StackOverflowError가 발생합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;코드는 다음과 같습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1592311367773&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Service
public class AService {

    @Autowired
    private BService bService;

    public void aMethod() {
        bService.bMethod();
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1592311534397&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Service
public class BService {

    @Autowired
    private AService aService;

    public void bMethod() {
        aService.aMethod();
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1592311583089&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;aService.aMethod(); //가 호출되는 순간 StackOverflowError가 발생됩니다.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그래서 우리는 애초에 Bean이 주입되는 시점에 순환 참조의 가능성을 막아야 합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이 시점에 IDE에서 Constructor Injection을 추천하는 이유가 나옵니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;결론부터 이야기를 하면,&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;u&gt;Spring Container가 Constructor Injection을 사용하면 Application 실행 시점에 Bean이 순환 참조되었다는 것을 다음처럼 BeanCreationException으로 알려줍니다.&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;알려줄 수 있는 이유는 다음과 같습니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Setter Injection / Field Injection과 다르게 Constructor Injection은 생성자로 빈을 주입하게 됩니다.&lt;/li&gt;
&lt;li&gt;생성자로 빈을 주입한다는 이야기는 자바에서 객체가 생성이 되려면, 주입될 Bean의 소재지를 찾아서 넣어줘야한다는 것입니다.&lt;/li&gt;
&lt;li&gt;결국 생성 시점에 모든 Bean이 정상적인 상태가 아니면 에러를 발생시킬 수 있다는 것입니다.&lt;/li&gt;
&lt;li&gt;자바의 객체 생성 원리가 Bean의 순환 참조 가능성을 제거해줄 수 있습니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Constructor Injection을 통한 순환 참조 예시입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1592313779451&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Service
public class AService {

    private final BService bService;
    
    public AService(BService bService) {
        this.bService = bService;
    }

    public void aMethod() {
        bService.bMethod();
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1592313835964&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Service
public class BService {

    private final AService aService;
    
    public BService(AService aService) {
        this.aService = aService;
    }

    public void bMethod() {
        aService.aMethod();
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1592313266607&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;***************************
APPLICATION FAILED TO START
***************************

Description:

The dependencies of some of the beans in the application context form a cycle:

┌─────┐
|  AService defined in file [AService.class]
&amp;uarr;     &amp;darr;
|  BService defined in file [BService.class]
└─────┘


2020-06-16 22:12:55.080  WARN 13272 --- [           main] o.s.boot.SpringApplication               : Unable to close ApplicationContext

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'applicationAvailability' defined in class path resource [org/springframework/boot/autoconfigure/availability/ApplicationAvailabilityAutoConfiguration.class]: BeanPostProcessor before instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'metaDataSourceAdvisor': Cannot resolve reference to bean 'methodSecurityMetadataSource' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration': Initialization of bean failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'org.springframework.context.annotation.ConfigurationClassPostProcessor.importRegistry' available
...&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그리고 한 가지 더 Constructor Injection을 이용하면, 위 코드에서 보셨겠지만 final 키워드를 사용할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;final은 상수를 만드는 키워드 입니다. 한 번 주입된 객체를 다른 객체로 변경을 불가능합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;흔히 &quot;Immutable Object&quot;라 이야기 많이 합니다. Spring Container가 아니면 Tread Safe 이야기도 나올 수 있는 부분이죠.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;물론 primitive가 아니기 때문에 객체 내용물의 상태는 변화할 수 있습니다. 하지만 객체 자체를 수정하는 것은 불가능합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그래서 Bean 주입을 위해서 쓰이기에는 최적입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;결론&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;Field Injection은 다음과 같은 문제점이 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주입되지 않은 Bean으로 인한 NullPointException 발생 가능성&lt;/li&gt;
&lt;li&gt;Runtime에 순환 참조로 인한 StackOverflowError 발생 가능성&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;그래서 &lt;span style=&quot;color: #333333;&quot;&gt;사전에&amp;nbsp;&lt;/span&gt;위 문제점을 해결이 가능한 Construction Injection을 사용하는 것입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;장점은 다음과 같습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Bean이 주입되지 않는 경우, Compile Time에 알려주어서 NullPointException을 예방할 수 있습니다.&lt;/li&gt;
&lt;li&gt;Bean이 순환 참조될 경우를 Spring Container가 미리 알려주기 때문에 순환참조 가능성을 없앨 수 있습니다.&lt;/li&gt;
&lt;li&gt;final로 &quot;Immutable Object&quot;를 만들어버리기 때문에 Application이 재가동이 되기 전까지는 불변하는 Bean을 사용할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;최근에는 Lombok의 @RequiredArgsConstructor를 이용해서 생성자 주입을 하기도 합니다만,&lt;/p&gt;
&lt;p&gt;DDD를 공부하는 저는 개인적으로 Lombok을 좋아하지 않아서 사용하진 않았습니다.&lt;/p&gt;</description>
      <category>Spring</category>
      <author>RyanGomdoriPooh</author>
      <guid isPermaLink="true">https://interconnection.tistory.com/124</guid>
      <comments>https://interconnection.tistory.com/124#entry124comment</comments>
      <pubDate>Tue, 16 Jun 2020 22:45:31 +0900</pubDate>
    </item>
  </channel>
</rss>