<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Blog by Eunyoung]]></title><description><![CDATA[작업 기록 블로그]]></description><link>http://github.com/dylang/node-rss</link><generator>GatsbyJS</generator><lastBuildDate>Mon, 02 Feb 2026 08:06:19 GMT</lastBuildDate><item><title><![CDATA[GSLB에 매핑된 VIP 변경 작업 기록]]></title><link>https://ssongey.github.io/works/posts/2025-03-19--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2025-03-19--001</guid><pubDate>Wed, 19 Mar 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;이번에 클러스터 이관작업을 하면서 GSLB에 매핑된 VIP 변경도 진행하게 되었는데, 이에 대한 작업 이력을 기록한다.&lt;/p&gt;
&lt;br/&gt;
&lt;h3&gt;✔︎ GSLB에 새로운 VIP 추가&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;새로운 vip 추가시, 트래픽 분배 방식을 ratio 로 설정. (기존 트래픽 방식은 round robin)&lt;/li&gt;
&lt;li&gt;한 리전씩 1%로 설정하여 투입.&lt;/li&gt;
&lt;/ul&gt;
&lt;Br/&gt;
&lt;h3&gt;✔︎ 1% 투입 후 테스트&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;도메인에 매핑되는 IP를 강제하여 새로 투입된 VIP 연결에 문제가 없는지 확인한다.&lt;/li&gt;
&lt;li&gt;TLS 또는 Pod까지 플로우에 문제가 없는지 체크&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;확인방법 1) /etc/hosts 파일 수정&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;여태 &lt;code class=&quot;language-text&quot;&gt;/etc/hosts&lt;/code&gt; 파일을 수정해서 curl 테스트를 진행했었는데, 파일 수정 후 curl 명령어를 수행하는게 번거로웠다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sql&quot;&gt;&lt;pre class=&quot;language-sql&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;$ curl &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;v https:&lt;span class=&quot;token comment&quot;&gt;//digitaldocs.kakao.com -o /dev/null -s&lt;/span&gt;

&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; Host digitaldocs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;kakao&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;com:&lt;span class=&quot;token number&quot;&gt;443&lt;/span&gt; was resolved&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; IPv6: &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;none&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; IPv4: &lt;span class=&quot;token number&quot;&gt;121.53&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;.108&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;.101&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;   Trying &lt;span class=&quot;token number&quot;&gt;121.53&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;.108&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;.101&lt;/span&gt;:&lt;span class=&quot;token number&quot;&gt;443.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; Connected &lt;span class=&quot;token keyword&quot;&gt;to&lt;/span&gt; digitaldocs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;kakao&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;com &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;121.53&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;.108&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;.101&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; port &lt;span class=&quot;token number&quot;&gt;443&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;p&gt;&lt;strong&gt;확인방법 2) curl resolve 옵션&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;curl에 &lt;code class=&quot;language-text&quot;&gt;—resolve&lt;/code&gt; 옵션을 사용하여 ip를 강제 지정하는 방법이 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sql&quot;&gt;&lt;pre class=&quot;language-sql&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;$ curl &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;v &lt;span class=&quot;token comment&quot;&gt;--resolve digitaldocs.kakao.com:443:211.183.222.21 https://digitaldocs.kakao.com -o /dev/null -s&lt;/span&gt;

&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; Added digitaldocs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;kakao&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;com:&lt;span class=&quot;token number&quot;&gt;443&lt;/span&gt;:&lt;span class=&quot;token number&quot;&gt;211.183&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;.222&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;.21&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;to&lt;/span&gt; DNS cache
&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; Hostname digitaldocs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;kakao&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;com was found &lt;span class=&quot;token operator&quot;&gt;in&lt;/span&gt; DNS cache
&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;   Trying &lt;span class=&quot;token number&quot;&gt;211.183&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;.222&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;.21&lt;/span&gt;:&lt;span class=&quot;token number&quot;&gt;443.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; Connected &lt;span class=&quot;token keyword&quot;&gt;to&lt;/span&gt; digitaldocs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;kakao&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;com &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;211.183&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;.222&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;.21&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; port &lt;span class=&quot;token number&quot;&gt;443&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;ip가 잘못 들어가면 커넥션에 실패한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sql&quot;&gt;&lt;pre class=&quot;language-sql&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;$ curl &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;v &lt;span class=&quot;token comment&quot;&gt;--resolve digitaldocs.kakao.com:443:211.183.222.222 https://digitaldocs.kakao.com -o /dev/null -s&lt;/span&gt;

&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; Added digitaldocs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;kakao&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;com:&lt;span class=&quot;token number&quot;&gt;443&lt;/span&gt;:&lt;span class=&quot;token number&quot;&gt;211.183&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;.222&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;.222&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;to&lt;/span&gt; DNS cache
&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; Hostname digitaldocs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;kakao&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;com was found &lt;span class=&quot;token operator&quot;&gt;in&lt;/span&gt; DNS cache
&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;   Trying &lt;span class=&quot;token number&quot;&gt;211.183&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;.222&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;.222&lt;/span&gt;:&lt;span class=&quot;token number&quot;&gt;443.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;connect&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;211.183&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;.222&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;.222&lt;/span&gt; port &lt;span class=&quot;token number&quot;&gt;443&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;.40&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;.200&lt;/span&gt; port &lt;span class=&quot;token number&quot;&gt;50047&lt;/span&gt; failed: Operation timed &lt;span class=&quot;token keyword&quot;&gt;out&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; Failed &lt;span class=&quot;token keyword&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;connect&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;to&lt;/span&gt; digitaldocs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;kakao&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;com port &lt;span class=&quot;token number&quot;&gt;443&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;after&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;75000&lt;/span&gt; ms: Couldn&apos;t &lt;span class=&quot;token keyword&quot;&gt;connect&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;to&lt;/span&gt; server
&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; Closing connection&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;h3&gt;✔︎ dig 명령어로는 1% 테스트가 잘 안된다?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;dig(Domain Information Groper)는 &lt;strong&gt;DNS(Domain Name System) 정보를 조회하는 명령어&lt;/strong&gt;로, 주로 도메인의 IP 주소, 네임서버(NS)를 조회하는데 확인한다.&lt;/li&gt;
&lt;li&gt;/etc/hosts 파일 수정 후, dig 명령어를 이용해도 동일하게 강제 설정된 IP가 조회될 것이라고 생각했지만, 예상과는 다르게 ratio가 높은 IP가 조회되었다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;원인)&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;/etc/hosts&lt;/code&gt;는 로컬에서만 적용됨&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;/etc/hosts는 OS의 로컬 DNS 해석 단계에서만 사용.&lt;/li&gt;
&lt;li&gt;하지만 dig는 기본적으로 네트워크상의 DNS 서버를 직접 조회하기 때문에 /etc/hosts의 설정을 반영하지 않음.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;dig&lt;/code&gt;는 시스템 DNS 설정을 무시하고 네트워크 쿼리를 수행&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;dig example.com&lt;/code&gt;을 실행하면, 현재 설정된 DNS 서버(ex. 8.8.8.8 같은 공용 DNS)를 사용해서 실제 네트워크에서 조회한 결과를 반환.&lt;/li&gt;
&lt;li&gt;즉, /etc/hosts 설정을 사용하지 않고, 네트워크에 등록된 공식적인 DNS 정보를 가져온다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;</content:encoded></item><item><title><![CDATA[당신의 파드는 graceful 하게 종료되고 있을까?]]></title><link>https://ssongey.github.io/works/posts/2025-03-10--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2025-03-10--001</guid><pubDate>Mon, 10 Mar 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;1. Kubernetes에서의 Graceful Termination&lt;/h2&gt;
&lt;p&gt;쿠버네티스를 사용을 한다면, 파드를 graceful 하게 종료시키기 위해 deployment 매니페스트에 preStop Hook, terminationGracePeriodSeconds 를 설정하곤 한다.&lt;/p&gt;
&lt;h3&gt;✔️ preStop Hook&lt;/h3&gt;
&lt;ul&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;/ul&gt;
&lt;br/&gt;
&lt;h3&gt;✔️ terminationGracePeriodSeconds&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;파드 내의 모든 컨테이너가 종료 작업을 완료할 수 있도록 주어지는 유예기간 (초단위)&lt;/li&gt;
&lt;li&gt;preStop Hook 과 마찬가지로 데이터 무결성 보장, 서비스 가용성 유지, 안정성 확보 등의 이점이 있다.&lt;/li&gt;
&lt;li&gt;기본값은 30초이며, 설정된 시간이 넘게되면 파드는 SIGKILL 신호로 즉시 종료된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;예시&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; apps/v1
&lt;span class=&quot;token key atrule&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Deployment
&lt;span class=&quot;token key atrule&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; example&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;deployment
&lt;span class=&quot;token key atrule&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;replicas&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;selector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;matchLabels&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; example&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;app
  &lt;span class=&quot;token key atrule&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; example&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;app
    &lt;span class=&quot;token key atrule&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;terminationGracePeriodSeconds&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# 유예 기간을 60초로 설정&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;containers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; example&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;container
        &lt;span class=&quot;token key atrule&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; example&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;image&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;latest
        &lt;span class=&quot;token key atrule&quot;&gt;lifecycle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;preStop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token key atrule&quot;&gt;exec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
              &lt;span class=&quot;token key atrule&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;sh&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;-c&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;echo &apos;PreStop Hook Triggered&apos;; sleep 10&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# preStop Hook 명령 설정&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;containerPort&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;80&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;h3&gt;✔️ Kubernetes에서 파드가 종료되는 순서&lt;/h3&gt;
&lt;p&gt;그럼, 쿠버네티스에서 파드가 종료되는 순서를 알아보자.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. 파드 삭제 요청&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;deployment rollout, scale down 등의 사용자 또는 시스템으로부터 파드 삭제 요청을 받는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;2. 파드를 종료중 상태로 업데이트&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;K8S API 서버는 파드의 상태를 ‘Terminating’으로 업데이트를 하고, 해당 파드는 모든 서비스의 endpodint에서 제거된다.&lt;/li&gt;
&lt;li&gt;이 시점에 파드는 새 트래픽 수신을 중지하게되고, 실행중인 요청은 정상적으로 처리한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;3. preStop Hook 실행&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;파드에 ‘preStop’ 훅이 정의되어 있으면, 종료 신호를 받았을때 정의된 명령어가 실행된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;4. 컨테이너에 SIGTERM 신호 전송&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;preStop Hook 이 완료되면, K8S는 파드 내 컨테이너들에게 SIGTERM 신호를 보낸다.&lt;/li&gt;
&lt;li&gt;이때 DB연결, WebSocket 스트림 등 오래 지속되는 연결에 대한 중지가 일어난다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;5. Graceful Termination Period&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;K8S는 파드에 정의된 ‘terminationGracePeriodSeconds’ 동안 컨테이너가 종료되기를 기다린다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;6. 파드 제거&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;마지막으로 파드가 제거된다.&lt;/li&gt;
&lt;li&gt;이때, Graceful Termination Period 후에도 컨테이너가 계속 실행 중이면, SIGKILL 신호가 전송되어 강제로 컨테이너가 종료된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;유의할점.&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Graceful Termination Period 와 preStop hook, SIGTERM signal이 병렬로 발생한다.&lt;/li&gt;
&lt;li&gt;때문에 ‘애플리케이션이 종료 전에 필요한 작업을 완료할 수 있는 시간(preStop Hook 수행시간) + 애플리케이션 종료시간’ 보다  ‘terminationGracePeriodSeconds’ 시간이 커야 Graceful Termination이 보장된다고 봐야한다.&lt;/li&gt;
&lt;li&gt;정상적인 Graceful Termination&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/13d88dee915e569cbb98a1a2e41f6d7b/53639/01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 73.33333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAABYlAAAWJQFJUiTwAAAB0ElEQVQ4y31UXY+iQBDk//+ne7ncy2ou3HJowKCLChhlQVCRD2eooxuGHdm97aQyk+6eoma6GwODtW3Lq5QSQghem6ZBFEXY7XbYbre8Enzfx+FwwOPx4DwF4jCmhERSliWqqkJRFNjv99hsNiOIbL1es/9+v3Megc7QBz4RkpMUKkxN5ZHpeQQmpAQd5JwSfBfX7Umh7tRVPBFzXIzk7Nc+yoTn8xlJkiDPc1wuV5auguSj+O12gzpe3K7w394QhgEXrKnr8YNMWL5bKE+/O5ioYhMyWwCFB1xdiOQvRGoD5Lv7QPILj/0LMstCZpvInQXEnxlQlYN6unLbdPR1DzRdZVNsIwfB0UN4WvMaxf2aV1FX2bS/pxQ96qpTJz8IW/UOw1ul3QHr3cQisQa8MtzzEj9PP+BfNn2/on06N155WkUpJL4ziuv5aHvakfBzlRvI7gqy7TWovcJXbaX3JSvUx0dvZlVxNZLsk71v2vi0r7uKG7Q5Ho9wXReO4/B40Z4QBAEnkYVhCNu2Oe55HpbLJY+esjiOec4NpYCGfTabwTRNzOdzrFarUQHNKs0v+SlOxESYpulHgw83Nf43m/obUaIaAFKSZRnv6ecxfcd/isaJvC7NirMAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/13d88dee915e569cbb98a1a2e41f6d7b/d9199/01.png&quot;
        srcset=&quot;/devHistoryBlog/static/13d88dee915e569cbb98a1a2e41f6d7b/8ff5a/01.png 240w,
/devHistoryBlog/static/13d88dee915e569cbb98a1a2e41f6d7b/e85cb/01.png 480w,
/devHistoryBlog/static/13d88dee915e569cbb98a1a2e41f6d7b/d9199/01.png 960w,
/devHistoryBlog/static/13d88dee915e569cbb98a1a2e41f6d7b/53639/01.png 1358w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;terminationGracePeriodSeconds 시간이 충분치 않은 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/3652e02db8a2b4d5715af061e14a3c48/bb543/02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 66.66666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAABYlAAAWJQFJUiTwAAABr0lEQVQ4y3VTa5OaQBDk//+q+5T7dEQsTEmMWiZw4aXACvLa3c7MCmS1vKlqB3Z7WnZ61oEVWmv7FeM4Is9zpGmKLMtMTpLE5LZt8arWeV6QUqJpGnRdh7quF8EZs6AQwogylFKLhsM/Mzh4k0Xtta+C95nLNTPfeSYpJYk0Mv0/9B28rqevWfgkaIcjab/tFXrSGAiKaqW+Sw3E7UeNcdLgNdG0iLMc57JCermgoyJuUVlV5vhO3+TI/3ioki3K+Adk/Zv+4RO4RajzHUQaoCsPpJ5AFS6KvY904yP7FSDbbVF9hvj2/o4wDE3fHYyCBEJCBHSRERTplsQCwk80BJPPO2gRQJcJUBaEM1Bd0F9yRFFkJsIc2eqUiZZ68vHXhZswvuMjpkzwMg9v6RuEbJbjM9STSZPLyoAbz6bgC3e7obkbNk/A5LKcjFkE7ZgJ9jjNHK30w8zN/Ic5nB9ezdyDGGXu0/Pcvbwpt9sNh8MBrku98jyD1WqF/X5vbgtHHMfmnQ1gR1n8dDphvV7D930URTGZYn3B8XjEZrNBEASmeBiGl3fcDr6C1+t14f0DzaLw4tOwjj8AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/3652e02db8a2b4d5715af061e14a3c48/d9199/02.png&quot;
        srcset=&quot;/devHistoryBlog/static/3652e02db8a2b4d5715af061e14a3c48/8ff5a/02.png 240w,
/devHistoryBlog/static/3652e02db8a2b4d5715af061e14a3c48/e85cb/02.png 480w,
/devHistoryBlog/static/3652e02db8a2b4d5715af061e14a3c48/d9199/02.png 960w,
/devHistoryBlog/static/3652e02db8a2b4d5715af061e14a3c48/bb543/02.png 1418w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h2&gt;2. 컨테이너에서의 Graceful Termination&lt;/h2&gt;
&lt;p&gt;적당한 preStop Hook, terminationGracePeriodSeconds 설정으로 Graceful Termination 이 되었을까?&lt;br/&gt;
나도 그런줄 알았지만.. 컨테이너에 함정이 숨어 있었다.&lt;br/&gt;
리얼 환경 배포시에 위 설정값을 충분히 크게 줘도 &lt;strong&gt;DB 커넥션이 애플리케이션에서 강제로 종료되는 현상&lt;/strong&gt;이 발생하였고, &lt;br/&gt;
팀 내에서 아래 글을 발견하게 되었다.&lt;br/&gt;
&lt;a href=&quot;https://vinodhinic.medium.com/are-you-sure-sigterm-is-received-by-your-application-in-kubernetes-885a3ce7ae4e&quot;&gt;https://vinodhinic.medium.com/are-you-sure-sigterm-is-received-by-your-application-in-kubernetes-885a3ce7ae4e&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;정리하면 도커는 2가지 방식, Shell과 Exec 방식을 지원하는데, &lt;strong&gt;도커파일에서 애플리케이션 실행 구문에 어떤 방식을 사용하냐에 따라&lt;/strong&gt; kubelet이 보낸 &lt;strong&gt;SIGTERM이 실제로 애플리케이션에 수신이 되지 않는다&lt;/strong&gt;는 점이다.&lt;/p&gt;
&lt;br/&gt;
&lt;h3&gt;✔️ Shell 방식&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;컨테이너 내 shell에서 해당 명령을 실행하며, &lt;strong&gt;PID 1 인 프로세스는 shell&lt;/strong&gt; 이 된다.&lt;/li&gt;
&lt;li&gt;계층 순서는 ‘파드 &gt; 컨테이너 &gt; &lt;strong&gt;shell&lt;/strong&gt; &gt; 애플리케이션’ 이 된다.&lt;/li&gt;
&lt;li&gt;kubelet이 SIGTERM 신호를 보내면 shell 프로세스에서 소비된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;docker&quot;&gt;&lt;pre class=&quot;language-docker&quot;&gt;&lt;code class=&quot;language-docker&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;ENTRYPOINT&lt;/span&gt; java &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;Dspring.profiles.active=$&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;APP_PHASE&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;sandbox&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;jar /app/app.jar&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;h3&gt;✔️ Exec 방식&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;컨테이너에서 바로 애플리케이션이 실행되며, &lt;strong&gt;PID 1인 프로세스는 애플리케이션&lt;/strong&gt;이다.&lt;/li&gt;
&lt;li&gt;계층 순서는 ‘파드 &gt; 컨테이너 &gt; 애플리케이션’ 이 된다.&lt;/li&gt;
&lt;li&gt;kubelet이 SIGTERM 신호를 보내면 애플리케이션 프로세스에서 소비된다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;최대 단점은 환경변수를 사용할 수 없다는 것&lt;/strong&gt;이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;docker&quot;&gt;&lt;pre class=&quot;language-docker&quot;&gt;&lt;code class=&quot;language-docker&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;ENTRYPOINT&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;java&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;-jar&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/app/app.jar&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;h3&gt;✔️Shell 방식의 컨테이너 내 애플리케이션 종료&lt;/h3&gt;
&lt;p&gt;내가 서비스하고 있는 애플리케이션의 &lt;strong&gt;dockerfile 설정은 shell 방식&lt;/strong&gt;으로 되어 있었고,&lt;/p&gt;
&lt;p&gt;kubelet에서 &lt;strong&gt;SIGTERM 신호를 보내도 shell 이 받아버려&lt;/strong&gt; Graceful Termination 을 위해 세팅되었던 K8S 설정들이 무의미 했다는걸 알게 되었다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;shell 방식의 애플리케이션 종료&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/01d4e72d63760a32a3263008e59d4fe6/0d292/03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 58.333333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAABYlAAAWJQFJUiTwAAACKUlEQVQoz21T207bQBD1/79UtFW/IX0pICgXVaoKEkEEhBpCaKxEIQ5Jk/iWtWPHe7NPZ9cY0dKVx3PWM3Nmd33WwX+GlBJKKWy3W8xmT/A8D9Pp1PrJZALf922OlOJNrWNeVVVaAq1ry/OMyHJkWYY4jhBFIdmzD0MwtrZxk9fUlKWuCR8fJwiCGFwoFIWkJE5EBRUIa5wra8Wzt5jyTGxDeVnGqUaQ30IIAcf355h6PcTRBGkypeVGKHVIvWLCsZ1bjBpXZVgbYa38l5hWCTUp4CgZwp8dYz4+wNL7ioL9QLm9QFVcALxNdgmenCOLvkPn9A03QNkh8ms67Cs8PZ5iOTtFlg5pF7ImrNJjqPALVLQLbSzeRcX2Ua73MO5+Qu/yHdybj3CvduBef8CvznsMCN+1d9C5bGEdnEGJiT0GR4qUuq6oo1m+T1tZoTJbMVvVAeZeH53zE3zbb+Fkr4XDgxaOjj7j7OwQvV4bktMxYQEpIiLkcLQu3/z6UTDE3e+feFjdww0f8LDooj/v4tbvgOWMijX+rTNzIzMnTVMrgcaMFAK2QpCuEKY+gqTGLI/hsTGSjEFwYYs3m9TmF4XBG/KFWaHppu0vbwStFXWnR4lXWGrIohY7F/xF+KaOc245qqqqhW0GYwyu69K59DAYDNDv39ubYQrMSNIET3RrlqsliT22zReLhRW8uTmGzArbgGayXq8xHA4xGo3+Imvir0dT18Qa/AdPsI5MLMsufQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/01d4e72d63760a32a3263008e59d4fe6/d9199/03.png&quot;
        srcset=&quot;/devHistoryBlog/static/01d4e72d63760a32a3263008e59d4fe6/8ff5a/03.png 240w,
/devHistoryBlog/static/01d4e72d63760a32a3263008e59d4fe6/e85cb/03.png 480w,
/devHistoryBlog/static/01d4e72d63760a32a3263008e59d4fe6/d9199/03.png 960w,
/devHistoryBlog/static/01d4e72d63760a32a3263008e59d4fe6/07a9c/03.png 1440w,
/devHistoryBlog/static/01d4e72d63760a32a3263008e59d4fe6/0d292/03.png 1620w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;h3&gt;✔️그래서 어떻게 적용해야하나?&lt;/h3&gt;
&lt;p&gt;보통은 환경변수를 통해 애플리케이션의 페이즈 등을 애플리케이션으로 전달하기 때문에, Exec 방식은 사용하기 힘들다. 그럼 어떻게 PID가 1 인 애플리케이션의 컨테이너 환경을 만들 수 있을까?&lt;/p&gt;
&lt;p&gt;아래 해결책이 있다!!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;K8S 매니페스트에 command 와 args 필드를 이용하여 ENTRYPOINT 에 정의된 내용을 재정의 할수있다.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://stackoverflow.com/questions/44316361/difference-between-docker-entrypoint-and-kubernetes-container-spec-command&quot;&gt;https://stackoverflow.com/questions/44316361/difference-between-docker-entrypoint-and-kubernetes-container-spec-command&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;아래는 실제 수정된 deployment.yaml 파일이다.&lt;/p&gt;
&lt;p&gt;ENTRYPOINT에 정의한 내용을 다시 정의하고 있다. 여기서는 환경변수 사용도 가능하다.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/ea96b1487d97387f108435ade11f4259/1c1a4/04.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 86.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAYAAADdRIy+AAAACXBIWXMAABYlAAAWJQFJUiTwAAACMklEQVQ4y42Ti3KiQBBF+f+f2qqtbIzJ6qbiExTlzQwgCBpjFLjbPQYlKc0uVbcGmpnD7W5aC8sEsk4RIYN/jNCXIzxLHRwXFGeF1WmV14TWStKcUsKvY/hIYJchBtkMk9xBQM8sH/HHfXyOtd+dzl6kuQQMKBhiBfsYYpSbGK8djDMH08Il+El64WGwsvEcLZX+yIWCKXh9+YjmVZEK+ApKLg8SHVtH1zPwO5jjbjHB3XKKR3+GYWrDLSNY70KpAZ7BDGwcNmkt94H6OsN+mmN1zyB2yXvClr7CWsBE1ZADy32Ivlig4xj4YQzhHCUElaMNaOumQ//sMKR0Z5TmBPeU+hOl+pJYtM4xymzakal6S9I3Dj8D+XDH0fFI4K5rqBryB/rChLkLYGx81TBV/+sOk09APshNeKI6skuGPRCYxbU1tr6q6TfAtsMAPQJyp39ZUyWGzl7ZlYc5ORRXUm7Wq0B2yLXjWrJLTp/XwcqiJkWqQV4VX23QjZQXqnb3ln5Om5/ZIf/gDAu/TE3j8gxsAtb7CfhAv03XnaEXmgrGbjnGjRrSxPDUvMQWRqmjfv4RTRZ3n2ZZwCOQV0dqFhnYE3PoWw8mpW8fBc24hFNdtDyEsChuHYRa+Zn3eDzLaVUgqzfIsUV0TOFsaFMaw1wJuEWCNcX53bqlW8/M0dC6qrJEsS1QvK6x2ewg4xwyyoEa/31p+7IG6410oIP52x6GcODGGSZ2jLjYYV8Bzb5/6S8HRftCZb/Q2gAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;04&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/ea96b1487d97387f108435ade11f4259/d9199/04.png&quot;
        srcset=&quot;/devHistoryBlog/static/ea96b1487d97387f108435ade11f4259/8ff5a/04.png 240w,
/devHistoryBlog/static/ea96b1487d97387f108435ade11f4259/e85cb/04.png 480w,
/devHistoryBlog/static/ea96b1487d97387f108435ade11f4259/d9199/04.png 960w,
/devHistoryBlog/static/ea96b1487d97387f108435ade11f4259/1c1a4/04.png 1046w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;수정 전/후 PID 상태&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/a3055c4390889ca036fc202472109311/8aace/05.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 22.499999999999996%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAABYlAAAWJQFJUiTwAAABIUlEQVQY01WMW07CQBiFhxDRYrlUjMa1SEy0BVrKJSqJPJhCgWJ0K/IgDwKVAm5HYloak8YO7uU4HZTow5fvnDN/hiyX73DdFVzPxxvLvv8Bz1shCAJ8rSloGHLWlDLCP/13o+xuzU3DT5AYITjJSTiWMsgICZ6Psmmk9xLIJgUcpkVOLiXiQExC2t9sURbiMX6X2t1hJBBnf5FmowHLNNExDHRaBu66XdxbFqOHh/7GltlGr93i7rKbfsfc5miPHPXb5g3I4HGA8WiM0fMIw6ch7MkEU9vGYuZsmTtTzsJxfjz99x7xOp/hZTIGkc/yuK5XcVnVUdNKaLB8VauwrKKua6iVVWgFGZoio1xQoMoXKBcLDIXtCrfOeqVUxHn+FN/qK+R9BMsKQwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;05&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/a3055c4390889ca036fc202472109311/d9199/05.png&quot;
        srcset=&quot;/devHistoryBlog/static/a3055c4390889ca036fc202472109311/8ff5a/05.png 240w,
/devHistoryBlog/static/a3055c4390889ca036fc202472109311/e85cb/05.png 480w,
/devHistoryBlog/static/a3055c4390889ca036fc202472109311/d9199/05.png 960w,
/devHistoryBlog/static/a3055c4390889ca036fc202472109311/07a9c/05.png 1440w,
/devHistoryBlog/static/a3055c4390889ca036fc202472109311/29114/05.png 1920w,
/devHistoryBlog/static/a3055c4390889ca036fc202472109311/8aace/05.png 2732w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;hr&gt;
&lt;br/&gt;
&lt;h2&gt;3. 테스트 해보자&lt;/h2&gt;
&lt;p&gt;간단하게 DB Pool 가진 Springboot 애플리케이션을 만들어서 테스트 해본다.&lt;/p&gt;
&lt;h3&gt;✔️Exec 환경 테스트&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Exec 방식으로 ENTRYPOINT 를 수행하여 도커 이미지를 빌드한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;docker&quot;&gt;&lt;pre class=&quot;language-docker&quot;&gt;&lt;code class=&quot;language-docker&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;ENTRYPOINT&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;java&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;-jar&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;-Dspring.profiles.active=docker&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/app/check-pid-0.0.1-SNAPSHOT.jar&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;컨테이너 실행 후, PID 확인을 하면 java 가 PID 1 이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/f2537a1caade4a7d2592be5c5aa11d03/bd9eb/06.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 10.833333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAACCAYAAABYBvyLAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAjUlEQVQI12OQ1lL+L6er9l9ZTeu/mqbuf00d/f/GZlZA2gDMV1TR/C+rIPtfSlbmv4i4zH9RCSCWhNJALCYpCxSXAtO8/EL/GYKjM/4n59b9D4rN/h8Ul/0/NCHnfwiQ9g5L/u8WEPPf1T8aSMf9dw+K/+8eGAsWcw+KA9NuQL5HcPx/Z58IMK1rYvMfAHnFQz93mcG8AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;06&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/f2537a1caade4a7d2592be5c5aa11d03/d9199/06.png&quot;
        srcset=&quot;/devHistoryBlog/static/f2537a1caade4a7d2592be5c5aa11d03/8ff5a/06.png 240w,
/devHistoryBlog/static/f2537a1caade4a7d2592be5c5aa11d03/e85cb/06.png 480w,
/devHistoryBlog/static/f2537a1caade4a7d2592be5c5aa11d03/d9199/06.png 960w,
/devHistoryBlog/static/f2537a1caade4a7d2592be5c5aa11d03/07a9c/06.png 1440w,
/devHistoryBlog/static/f2537a1caade4a7d2592be5c5aa11d03/bd9eb/06.png 1442w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;해당 컨테이너에 SIGTERM 신호를 보내면&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;docker &lt;span class=&quot;token function&quot;&gt;kill&lt;/span&gt; --signal&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;SIGTERM check-pid-exec&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;start 로그 이후에 DB Pool이 정리되는 로그가 보인다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/80dabbbf097b0d505cc38fa57fe59f81/b4904/07.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 11.249999999999998%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAACCAYAAABYBvyLAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAdElEQVQI1z2J2QrCMBQFL27dshcLfdS4pEmjpeL/f9oxXLAPw3DOUEhvTPOC+PpsTHll0vLFLWRc7hHXRypE+GIf5kLm79/8M7FpGEe44QwpWgjR4bDfoWsbKClgjUbv7LZl6c4a3kQErSSaumIbrVCdjvgBkg40dJgfgeAAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;07&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/80dabbbf097b0d505cc38fa57fe59f81/d9199/07.png&quot;
        srcset=&quot;/devHistoryBlog/static/80dabbbf097b0d505cc38fa57fe59f81/8ff5a/07.png 240w,
/devHistoryBlog/static/80dabbbf097b0d505cc38fa57fe59f81/e85cb/07.png 480w,
/devHistoryBlog/static/80dabbbf097b0d505cc38fa57fe59f81/d9199/07.png 960w,
/devHistoryBlog/static/80dabbbf097b0d505cc38fa57fe59f81/07a9c/07.png 1440w,
/devHistoryBlog/static/80dabbbf097b0d505cc38fa57fe59f81/b4904/07.png 1768w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;h3&gt;✔️Shell 환경 테스트&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Shell 방식으로 ENTRYPOINT 를 수행하여 도커 이미지를 빌드한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;docker&quot;&gt;&lt;pre class=&quot;language-docker&quot;&gt;&lt;code class=&quot;language-docker&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;ENTRYPOINT&lt;/span&gt; java \
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;Dspring.profiles.active=$&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;APP_PHASE&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;docker&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; \
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;jar /app/check&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;pid&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;0.0.1&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;SNAPSHOT.jar&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;컨테이너 실행 후, PID 확인을 하면 java PID는 7 이고, 이를 수행하는 /bin/sh 이 PID 1 이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/a17aff22f24a98f1dfbcc4ad11572163/6fa81/08.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 10%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAACCAYAAABYBvyLAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAjUlEQVQI1x2L2QqCUAAF/YhKr9clbRMiCHooyjb1huaCRCvU/3/GpD4Mwxk4mvQ9DN/B9SZMgzmL5Qp/PGsIcDwXISW6sDGkg7BcDNOmr5v0BqLbpj3sbLmjzlp2+5HWX6L8gSpfJMWTzSlruBImFduo4HCp2auKXVwQqrblrI8p5+yOqj7Eza91Ur75A5SCP/5mCeTzAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;08&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/a17aff22f24a98f1dfbcc4ad11572163/d9199/08.png&quot;
        srcset=&quot;/devHistoryBlog/static/a17aff22f24a98f1dfbcc4ad11572163/8ff5a/08.png 240w,
/devHistoryBlog/static/a17aff22f24a98f1dfbcc4ad11572163/e85cb/08.png 480w,
/devHistoryBlog/static/a17aff22f24a98f1dfbcc4ad11572163/d9199/08.png 960w,
/devHistoryBlog/static/a17aff22f24a98f1dfbcc4ad11572163/07a9c/08.png 1440w,
/devHistoryBlog/static/a17aff22f24a98f1dfbcc4ad11572163/6fa81/08.png 1856w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;해당 컨테이너에 SIGTERM 신호를 보내면&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;docker &lt;span class=&quot;token function&quot;&gt;kill&lt;/span&gt; --signal&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;SIGTERM check-pid-exec&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;아무런 반응이 없다. 애플리케이션 종료가 안된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/ba2c636da4f737b5894a0d0a0ab3e89b/9c1e6/09.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 12.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAiklEQVQI102L2wrCMBBEg9m8WhObXqCfoq2i1AvUau2D4P9/x7gbmuDDYYc5s6rtn2gvL+z5dtcJh9vMecTxPuM0fJbuDdl1vNudH2nbj99wxUkvqI0rIGTOw+YlUyGzHs7X8FUDuy1DL15Y2zwg2RV18NHJnzJEMKQDtCAdac56lXqTIMSf6P/dD7DrUgehMSidAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;09&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/ba2c636da4f737b5894a0d0a0ab3e89b/d9199/09.png&quot;
        srcset=&quot;/devHistoryBlog/static/ba2c636da4f737b5894a0d0a0ab3e89b/8ff5a/09.png 240w,
/devHistoryBlog/static/ba2c636da4f737b5894a0d0a0ab3e89b/e85cb/09.png 480w,
/devHistoryBlog/static/ba2c636da4f737b5894a0d0a0ab3e89b/d9199/09.png 960w,
/devHistoryBlog/static/ba2c636da4f737b5894a0d0a0ab3e89b/07a9c/09.png 1440w,
/devHistoryBlog/static/ba2c636da4f737b5894a0d0a0ab3e89b/9c1e6/09.png 1734w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;해당 컨테이너 종료 명령어를 수행하면&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;docker stop check-pid-exec&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;SIGTERM 신호를 전달하고 10초간 대기 후 SIGKILL 신호를 전달하여 강제 종료한다. (start 로그 이후에 아무런 로그가 없다.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/882e4de08fc6b1aed471b358982a706e/baa75/10.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 11.249999999999998%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAACCAYAAABYBvyLAAAACXBIWXMAABYlAAAWJQFJUiTwAAAARElEQVQI12NQ1zb8D8a6xmCsoWvyX13HCIiBbD1TIN8YzIfRakC1WvqmQGwGVQcR09QzAetlYObh+c/AxfWfgYGBKhgAc5kylKz+3/8AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;10&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/882e4de08fc6b1aed471b358982a706e/d9199/10.png&quot;
        srcset=&quot;/devHistoryBlog/static/882e4de08fc6b1aed471b358982a706e/8ff5a/10.png 240w,
/devHistoryBlog/static/882e4de08fc6b1aed471b358982a706e/e85cb/10.png 480w,
/devHistoryBlog/static/882e4de08fc6b1aed471b358982a706e/d9199/10.png 960w,
/devHistoryBlog/static/882e4de08fc6b1aed471b358982a706e/07a9c/10.png 1440w,
/devHistoryBlog/static/882e4de08fc6b1aed471b358982a706e/baa75/10.png 1746w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;4. 애플리케이션이 SIGKILL 신호를 못받으면 무엇이 문제가 될까?&lt;/h2&gt;
&lt;h3&gt;✔️ 맺고 있었던 DB 커넥션 등이 클라이언트에서 강제 종료가 된다.&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;애플리케이션(클라이언트)에서 커넥션이 강제 종료 되면, 클라이언트가 보낸 데이터가 DB에 적용되지 않을 수 있고,&lt;/li&gt;
&lt;li&gt;클라이언트가 트랜잭션을 진행 중이었다면, 해당 트랜잭션은 롤백될 수 있다.&lt;/li&gt;
&lt;li&gt;또한, 강제로 종료된 커넥션은 DB 입장에서 종료되지 않은 상태로 남아있을 수 있어 자원 누수로 이어질 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;실제 Shell 환경 테스트를 진행해보면, DB에 클라이언트가 비정상적으로 종료된 흔적이 남는다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sql&quot;&gt;&lt;pre class=&quot;language-sql&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;SHOW&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;STATUS&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;LIKE&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Aborted%&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Aborted_clients&lt;/code&gt;: 클라이언트가 비정상적으로 종료되어 서버가 연결을 중단한 횟수&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Aborted_connects&lt;/code&gt;: MySQL 서버에 접속을 시도했으나 실패한 연결 횟수&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/0916035b6f88afceddebf7b9290f26ce/6e6fb/11.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 618px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 52.916666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABYlAAAWJQFJUiTwAAABVklEQVQoz3WT25KCQAxEUUREUS4iIl4QQSyf/f9va+tkd/ZhCx5SmSFJpzsZvLIsdTwetVwutd/v9Xq9lOe52fV6VV3XCsNQh8PB8larlS6Xi8Wpvd1uStNUs9lMnufJezwewqIo0ul00ufzsULOwzCo6zrFcaymaczIoylxGr7fbxVFocVi8QO4Xq8VBIF98H3/7zyfz+0Mu81mY0DEiaGGOgP4b8g8n89Gn45Iy7JMbduaFJIAAZR4VVXGGNBRwO12qyRJhAcIEM4AA8JsmBtGHHkAwnwUcLfbGQASSMQDBANi3AHDA8gokD4pGQnP59MY3e93kwQLhs42nWyakOcKJxkyu77vDZAngAeUswNlObBDiSucnCFy3GadNO4UYG7TGDnuPikZSbBgMcwMDzMkureGCr7zGgBiUcxxFJBuPB0AYMh7owns8PwRLIvv5MFwFOjXviWi+kiB0RiaAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;11&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/0916035b6f88afceddebf7b9290f26ce/6e6fb/11.png&quot;
        srcset=&quot;/devHistoryBlog/static/0916035b6f88afceddebf7b9290f26ce/8ff5a/11.png 240w,
/devHistoryBlog/static/0916035b6f88afceddebf7b9290f26ce/e85cb/11.png 480w,
/devHistoryBlog/static/0916035b6f88afceddebf7b9290f26ce/6e6fb/11.png 618w&quot;
        sizes=&quot;(max-width: 618px) 100vw, 618px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;h3&gt;✔️ 애플리케이션 종료 리스너가 수행하지 않는다.&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;애플리케이션이 종료될때 이벤트 리스너를 받아 필요한 로직을 수행하는 경우가 있을 것이다.&lt;/li&gt;
&lt;li&gt;애플리케이션이 강제 종료되면, 리스너 수행이 되지 않아 문제가 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/c90d1fdc8048cde5a574336e5dbebb45/f0293/12.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 10%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAACCAYAAABYBvyLAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAiElEQVQI1x2K6QqCQAAGe4AwSwvNMwsiCIs0j1VrNex6//eZtv0xDN8xKZuBQpELSZoL8lpyLjoy0VPfnzTDh3b4Ivo3mdpq+dLdP5fdSHUbKdoHl0pyurZMtseUeH/AcT3slaPthzFxsmPth5og2uAFEdbS0dn1AtUl6u9imBazua28YGqY/AAyMDwnLiQTRAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;12&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/c90d1fdc8048cde5a574336e5dbebb45/d9199/12.png&quot;
        srcset=&quot;/devHistoryBlog/static/c90d1fdc8048cde5a574336e5dbebb45/8ff5a/12.png 240w,
/devHistoryBlog/static/c90d1fdc8048cde5a574336e5dbebb45/e85cb/12.png 480w,
/devHistoryBlog/static/c90d1fdc8048cde5a574336e5dbebb45/d9199/12.png 960w,
/devHistoryBlog/static/c90d1fdc8048cde5a574336e5dbebb45/07a9c/12.png 1440w,
/devHistoryBlog/static/c90d1fdc8048cde5a574336e5dbebb45/29114/12.png 1920w,
/devHistoryBlog/static/c90d1fdc8048cde5a574336e5dbebb45/f0293/12.png 2250w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;h3&gt;✔️ 기타&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;애플리케이션이 강제 종료되면, 메모리 누수, 파일 디스크립터 누수 등의 문제를 초래할 수 있고,&lt;/li&gt;
&lt;li&gt;서비스가 갑자기 중단되므로 해당 서비스의 가용성이 저하된다.&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[프로메테우스 삽질기]]></title><link>https://ssongey.github.io/works/posts/2025-01-23--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2025-01-23--001</guid><pubDate>Thu, 23 Jan 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;1. 무엇을 표현하고 싶었는가?&lt;/h2&gt;
&lt;h3&gt;✔︎ 서비스 지표&lt;/h3&gt;
&lt;p&gt;발급 건수, 카드 종류별 건수, 실패 건수 등 카드 발급 현황에 대한 지표 구성&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;무엇을 고려 하였는가?&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;카드별 발급 건수 표시로 카드 선호도/수요 분석&lt;/li&gt;
&lt;li&gt;카드 발급 실패에 대한 원인 파악&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/1009f4ccff1970c73f107aec857ea569/cf151/01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 45.416666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAABYlAAAWJQFJUiTwAAACE0lEQVQozyWSW0/bQBCF/UoIKont+Lbrtb2OEzsXIAQIkNJQFapEatWLCu1DpUq0VV/b/y99nYSHo/WOR2fmnLNOnKT0i4pJ1RCFCV4QU9gB9fYeJHR7EWXTkFUVgVIs3y24XY9ZrXLWryybi5LNqGKkMhLpd+5szUN9wkNzwlQXTFTOpj/mYXjMTBW4WjG7P6W+GhOZlPWPFV9/nvPtccDT54rfb4f8WUy5NCVZqHG+VxP+Naf8qqasTJ+l/HgaHPN3NOcmsbhWc/ZhzvT+iLhIuf1yxfJ+xM1Nzv3LgvV5yVo2nGYFRqc47Z6iE+fovCaMNQdeQNsP8cKYJM3xejGdbkDXD4jSlJPlKc2wJEpigijCc13cjkvX8+iGPo5qXqOO3mOONxg7FCKDki1za1FpQaIzelFCRwbl5YDJ7JJPC0ueir9+RHv/gFarTWvvGY4aLEiHC0xekRrxTHxI5Cz7dke2hReEHLq+DCqYXSy5m1mMks2l1trbZ0/Qau3vvh1fkvEl2TBWslHOYTfEl7QTremJbFdSDhMtMM916YlFQSjhBVKLlRHpetfnbVMOU00gOBSfImPIxyWxeOWFSkiUDAt3TykQ2WEcEwmBzkr6wxHlYEQ9PpKzke0tmVjiXG/mrD5e0Jw1XK7nvHm8RhVGBvTIbC5eZvL+ZJA1WMELN0CL9KoeUQ23hFMhrHfqMlvxHzU0/yh++51sAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/1009f4ccff1970c73f107aec857ea569/d9199/01.png&quot;
        srcset=&quot;/devHistoryBlog/static/1009f4ccff1970c73f107aec857ea569/8ff5a/01.png 240w,
/devHistoryBlog/static/1009f4ccff1970c73f107aec857ea569/e85cb/01.png 480w,
/devHistoryBlog/static/1009f4ccff1970c73f107aec857ea569/d9199/01.png 960w,
/devHistoryBlog/static/1009f4ccff1970c73f107aec857ea569/07a9c/01.png 1440w,
/devHistoryBlog/static/1009f4ccff1970c73f107aec857ea569/29114/01.png 1920w,
/devHistoryBlog/static/1009f4ccff1970c73f107aec857ea569/cf151/01.png 3672w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;h3&gt;✔︎ traffic (트래픽)&lt;/h3&gt;
&lt;p&gt;서버로 들어오는 총 요청에 대한 파악을 위해 지표 구성&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;무엇을 고려 하였는가?&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;부하 확인&lt;/li&gt;
&lt;li&gt;리전별 요청 비율로 리전 이상 현상 감지

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/627313729d2936c49adef62548d110f5/e437f/02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 17.083333333333332%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAABYlAAAWJQFJUiTwAAAA3UlEQVQI10XOvUrDUADF8SBYaXLTm9wmN6lJmpukHza0WC0oCOIiRRzVqYODFAcfokN3cRBcfBdf7e/FxeEsZzjn54RRQl8PiPQxodKoOMUPNUE/wZMR2bBitlhSVCNkGOG6As/zbQSdrmRhAu42t+jTS9IkxWlWU+qzCe3NnKKtKY3hwnZ5kfN4v2TejiibGfX4xJ4OcLve36AvBM5hyOdzh4+fPcP9N7GUODrL0HlOPjbosmDSGHZP12zXK762a86nFa6VqjghUP9CYYUHRwGbK8Hb+yvpwwuq1+MXzWFVWUOlqJcAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/627313729d2936c49adef62548d110f5/d9199/02.png&quot;
        srcset=&quot;/devHistoryBlog/static/627313729d2936c49adef62548d110f5/8ff5a/02.png 240w,
/devHistoryBlog/static/627313729d2936c49adef62548d110f5/e85cb/02.png 480w,
/devHistoryBlog/static/627313729d2936c49adef62548d110f5/d9199/02.png 960w,
/devHistoryBlog/static/627313729d2936c49adef62548d110f5/07a9c/02.png 1440w,
/devHistoryBlog/static/627313729d2936c49adef62548d110f5/29114/02.png 1920w,
/devHistoryBlog/static/627313729d2936c49adef62548d110f5/e437f/02.png 3664w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;h3&gt;✔︎ atency (지연)&lt;/h3&gt;
&lt;p&gt;응답 시간에 대한 파악을 위해 지표 구성&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;무엇을 고려 하였는가?&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;일반 사용자가 체감하는 응답 시간 - P95, 성공 응답 평균 시간

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/fb1b0bd5527096f80528ab2b3408fcc5/5148a/03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 99.58333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAABYlAAAWJQFJUiTwAAAD/klEQVQ4y4VUWW8bVRj1OyL17vHs+2KPZ2yPl6S2SZxmUSFp2hAS4kBoglKUKAIkEEIgoBIgnhE8wCvifx7OnbiR+lIejr47yz33+853vlsolmsoVeooVe9QrjYg3jl+hDjpI2ynaHV6jAljN4+a6WClVEGxUrvfV8r3VVGQNRP1popKvfka6rJG6JBUHabnw3JDHtLKIdaG7ZPYRbUh8385jyKZgiC7e9mExFhjLBPVugSlQWKuQ2YbxF0k/RG6g1WkjNl4gjBOUa5JeXZif04oKTrqkoIiP6hNBQphySp8ZjazbdR4oN/qEAni7gBJb3gXSRp3M7TTDColEIRCujzDCjMTZFuOg4lp4qssxe0ow3XWQ7Mpo+UHCKhlZ0nUIWmajRkHObnI2vainLRQbmqYOi5+SCNcpzHOO238uTnDP9vr+HdzglgVFagQWotMhG6qYS/XTh7Fs+H4qEkyCqL++cYWvri4wvGLW+yfXeLi+59x+9NvuPn2RzheiLdL1VyrIksqVpYdXa7z5/t1DYWVlRLWDk/w/I+/cfTNd3j88TlOX/6C57//heOXv0IP27mNKsvGvQm5hpWGgsh3sTUdYX3cx6OHGTYnA8zHPUz7HRimjeKyi/9LSD8WyrU7I0v0XIN6NhWT1pEZDTSEDwlxsrDEGyEkIU+hWKpxUccD6vSAL15FocmrKYnoQdFhYRGXEojvQsfSkqxUadxPWMGOQqSjAaKEm4m42+PGLmzfZ4YiU4WZy5AVFRKt1SQa7KZE1Je61mUl73Cu4XB/iO1PZrCooxN68Ns+vIhrz6J+KmxHh21z/HQVhqrAJAweYisaFA5EhdPkDVyYXZvknJTeZoads0fY+WCK3cM1PDud4OD9MRaLCU6OVnG5mOH8aIrFu/wvs7GfediNPTxrRRjQfyss1eLcR6p5N3qjvTEObnZxfLuJ0+t1XH1J3Exx9WmKsyMPn30Y4PLAw+3TEC92Iny+FeNqLcbXoz52eUm8xTKDpo6hYqMqCINhGz6nw6WWHhHGLY4ZbxPLgKJxJHUFmkawVI2l6oRGzQzOu1TjhWLpUFs2JJ8ZipLDQYyE/usMUiREn/7rDhIMV7voZwkeToZoUVNLl2FTR4ewVRWeqkGlh6skV6ixTGJhwYI/iOC0AliBB5vwIh9u4BIewshB3Lbhuzp8mySmhoDwdGqmG9DqCiSSueMIamDdNSXbHuHx+Q72PprjyeIdnF5s4PhsisvLGebzPixbg2UqcCwNtqHCJZmtiQxZKi8NYa0k0WE5Wu7LQjQLsfo0xcZhjPlBiL2jAO89cbE4cdHvqjCNJlxLhmvKLFeGRz0dRUZAX6rCg1IDaUelLCy/VsN/GfNGSOzZU9kAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/fb1b0bd5527096f80528ab2b3408fcc5/d9199/03.png&quot;
        srcset=&quot;/devHistoryBlog/static/fb1b0bd5527096f80528ab2b3408fcc5/8ff5a/03.png 240w,
/devHistoryBlog/static/fb1b0bd5527096f80528ab2b3408fcc5/e85cb/03.png 480w,
/devHistoryBlog/static/fb1b0bd5527096f80528ab2b3408fcc5/d9199/03.png 960w,
/devHistoryBlog/static/fb1b0bd5527096f80528ab2b3408fcc5/5148a/03.png 1228w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;h3&gt;✔︎ errors (오류)&lt;/h3&gt;
&lt;p&gt;에러 응답에 대해 파악하기 위한 지표 구성&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;무엇을 고려 하였는가?&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;5xx/ 4xx 에러율 확인에 따른 이상현상 감지 및 에러 메시지 확인&lt;/li&gt;
&lt;li&gt;연동서버 이상현상 감지

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/099d6e1b09b5e056fac2132f31d6a008/5ab15/04.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 50%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABYlAAAWJQFJUiTwAAABzklEQVQoz2VSTW+bQBTkmiaVbTC7sB8sGAzY4LhVouZSRWl76KGHtlL//1+ZzlsTK1IOTwuz++bNzG6S5iUyZZAXDtvCYqvlf8FKR9wizQviJlaqLvulqxB2e1TNHornNjyT24BklZPENLDtBB0GrDONj6nm5i5iReixIqbZpEoSUoAMsKFGfzhhnD+hbvs4WJkKyfN9wI/HDv9eJvz9OqIsS8ydxcvDPmI/n3p4WyCjOuM9XVycFC5QXQe/lKma6CD5dvb4fnb49eDw58mjCwZTayP2+wvxR49DY+L03WGArmnR1dhsNd2oWPItJXEkd+scdxuFD2uFm5WincuG2L4ldst9adqqAm5HJXUHW7fQxsfsYq6MIBZJE9+O8Dzkww6OspvhhEALZWkjVrcDnA+xMWOTVCl2eSGB2RlfR7JMk9w2SIbpHMPtDzPqbkA3zjEbUSA5tf0x3qaoyZYbFoLNVqHp9tiPJ7TDEdpW0IwiETUVLQiJoRL5LkgmjYrhB9r0xC6E5vqkZH19SlG94ByUjNN9VDccZ04cOHGKzelibT5/xjid3igsrnXNbinZTxxzssxO8isoW3ITlW8f9CuR8RUsXViu8rCz/D3pfxmnCs9fokrAAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;04&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/099d6e1b09b5e056fac2132f31d6a008/d9199/04.png&quot;
        srcset=&quot;/devHistoryBlog/static/099d6e1b09b5e056fac2132f31d6a008/8ff5a/04.png 240w,
/devHistoryBlog/static/099d6e1b09b5e056fac2132f31d6a008/e85cb/04.png 480w,
/devHistoryBlog/static/099d6e1b09b5e056fac2132f31d6a008/d9199/04.png 960w,
/devHistoryBlog/static/099d6e1b09b5e056fac2132f31d6a008/07a9c/04.png 1440w,
/devHistoryBlog/static/099d6e1b09b5e056fac2132f31d6a008/29114/04.png 1920w,
/devHistoryBlog/static/099d6e1b09b5e056fac2132f31d6a008/5ab15/04.png 2446w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h2&gt;2.︎ 무엇이 어려웠는가? (왜 안맞나?, 표현이 어려웠던 것은 무엇인가? …)&lt;/h2&gt;
&lt;h3&gt;2.1. promQL 문법의 이해&lt;/h3&gt;
&lt;h4&gt;✔︎ &lt;code class=&quot;language-text&quot;&gt;http_server_requests_seconds_count{uri=&amp;quot;/api&amp;quot;}[5m]&lt;/code&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;http_server_requests_seconds_count&lt;/code&gt; 메트릭을 사용할꺼고,&lt;/li&gt;
&lt;li&gt;uri가 “/api” 인 데이터만 필터 할꺼고,&lt;/li&gt;
&lt;li&gt;지금 시점부터 5분 전까지의 데이터를 추출&lt;/li&gt;
&lt;li&gt;현재 2dzzv 파드에서 발생한 이벤트 총 카운트는 2건, cxw24 파드는 1건

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/89da7a1b5575ce43ffacd2964e115976/869d7/06.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 19.583333333333332%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAlUlEQVQY04WO2wrDIBBE/f/vKxQKKYVeSTTaRtdLE6erSSh5ijA4e2ZgV3gfQEUU4MiDnK9z9YucIzhLtUNLv+SWu8i5+sPxjFZqCOy+vNsIIaK53KHNAKHNB7J/z1IGSmmo3syemdbMefPKC+s4k+zbrocdXL349uxqJlL6Isa0Vfr7TZ7meWXlsmmc4Pk/NVc8XhI/rj02J8GTuF0AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;06&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/89da7a1b5575ce43ffacd2964e115976/d9199/06.png&quot;
        srcset=&quot;/devHistoryBlog/static/89da7a1b5575ce43ffacd2964e115976/8ff5a/06.png 240w,
/devHistoryBlog/static/89da7a1b5575ce43ffacd2964e115976/e85cb/06.png 480w,
/devHistoryBlog/static/89da7a1b5575ce43ffacd2964e115976/d9199/06.png 960w,
/devHistoryBlog/static/89da7a1b5575ce43ffacd2964e115976/07a9c/06.png 1440w,
/devHistoryBlog/static/89da7a1b5575ce43ffacd2964e115976/869d7/06.png 1477w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;✔︎ &lt;code class=&quot;language-text&quot;&gt;increase(http_server_requests_seconds_count{uri=&amp;quot;/api&amp;quot;}[5m])&lt;/code&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;위 결과에서 증가건수 계산&lt;/li&gt;
&lt;li&gt;시간에 따른 카운트 변화가 없으므로 증가는 0

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/7915e4c2940451822eea8344f5bf0aba/07d7d/07.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 10%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAACCAYAAABYBvyLAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAZElEQVQI1zWNQQ6AIAwE/f9HBVpAo6KHwrrFeJhs03SnSy4bUspIUhCJOJk7qRCtc78GRYj63TBFMs6rod0Peu8wI8wxBpZSdqh+5UixOD6z7AJ/FoIgUvo/9vu6HRMzm9IJhS/6zJhJ4gLzCAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;07&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/7915e4c2940451822eea8344f5bf0aba/d9199/07.png&quot;
        srcset=&quot;/devHistoryBlog/static/7915e4c2940451822eea8344f5bf0aba/8ff5a/07.png 240w,
/devHistoryBlog/static/7915e4c2940451822eea8344f5bf0aba/e85cb/07.png 480w,
/devHistoryBlog/static/7915e4c2940451822eea8344f5bf0aba/d9199/07.png 960w,
/devHistoryBlog/static/7915e4c2940451822eea8344f5bf0aba/07a9c/07.png 1440w,
/devHistoryBlog/static/7915e4c2940451822eea8344f5bf0aba/07d7d/07.png 1478w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;h3&gt;2.2. 프로메테우스에서 수집하는 메트릭 중에 무엇을 사용했나?&lt;/h3&gt;
&lt;h4&gt;✔︎ &lt;code class=&quot;language-text&quot;&gt;http_server_requests_seconds_count&lt;/code&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;서비스 시작 이후의 누적 요청 횟수

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/6fe4a476d34425d77836b9370abca975/11a8f/08.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 2.9166666666666665%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAABCAYAAADeko4lAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAOElEQVQI1zWLwQ0AIAgD3X9RjRYBGQCB6ONyTdo2kDhtdZZTTibYidXxcsJi5RX7PlD73yNQtfpe+RpLtV0AIl4AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;08&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/6fe4a476d34425d77836b9370abca975/d9199/08.png&quot;
        srcset=&quot;/devHistoryBlog/static/6fe4a476d34425d77836b9370abca975/8ff5a/08.png 240w,
/devHistoryBlog/static/6fe4a476d34425d77836b9370abca975/e85cb/08.png 480w,
/devHistoryBlog/static/6fe4a476d34425d77836b9370abca975/d9199/08.png 960w,
/devHistoryBlog/static/6fe4a476d34425d77836b9370abca975/11a8f/08.png 1272w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;✔︎ &lt;code class=&quot;language-text&quot;&gt;http_server_requests_seconds_bucket&lt;/code&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;요청 응답 시간의 분포

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/999dae4e408a6fde49330febe320c7ce/fe720/09.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 34.166666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAAAsTAAALEwEAmpwYAAABCElEQVQoz31Ru3LDMAzT//9chgxObMvWW1acXtJrd5SgnF6mDDoaJAiSsCnbHanc9Pm0gbi2L4TckOuOKJE1F6tifm/tjigxCJ84y5uWhOf3L4w2SYKNbEqCy7bDx05mZG1x+V+kCCcc/D6w4TJ73PYHDAmrL1jkTUtUgZAa7JrgQoUVIdavc8AqWIVFiPxZOIxB8DA5FTdMjDbqG0bXSdJ0mbwOYI6182AVq7BLuNpw1AKs5E/nUQfryVyfW3GD/Olk5cnJenrTCxiz5LlIFW/Ny3j1UAhqcu2C8fgZrNl3wTcPGYm5OXsNE9xsDd0TNrwEKMrNOIhnU4BnpcN3+syongrv8fzBH5M1AOkFqsaVAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;09&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/999dae4e408a6fde49330febe320c7ce/d9199/09.png&quot;
        srcset=&quot;/devHistoryBlog/static/999dae4e408a6fde49330febe320c7ce/8ff5a/09.png 240w,
/devHistoryBlog/static/999dae4e408a6fde49330febe320c7ce/e85cb/09.png 480w,
/devHistoryBlog/static/999dae4e408a6fde49330febe320c7ce/d9199/09.png 960w,
/devHistoryBlog/static/999dae4e408a6fde49330febe320c7ce/07a9c/09.png 1440w,
/devHistoryBlog/static/999dae4e408a6fde49330febe320c7ce/fe720/09.png 1448w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;h3&gt;2.3. 지표를 표현하기 위해서 어떤 함수를 사용했는가?&lt;/h3&gt;
&lt;h4&gt;✔︎ 단순히 카운터로 누적 수를 계산하면 될꺼 같은데, 왜 increase, rate 를 사용했을까?&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;프로세스가 재실행 될 경우 해당 메트릭의 값이 0으로 리셋된다.&lt;/li&gt;
&lt;li&gt;increase, rate 함수는 리셋을 스스로 감지하여 이전 상태를 보정하여 증가량을 계산한다.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;아래와 같이 카운터의 결과가 나왔을때, 각 increase의 값을 더해서 누적 수를 계산한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;시간      누적수   증가
13:00:00 100
13:01:00 200 -&amp;gt; 100
13:02:00 300 -&amp;gt; 100
13:03:00 150 -&amp;gt; 0 (리셋 이벤트 발생)
13:04:00 0
13:05:00 0
13:06:00 50  -&amp;gt; 50
13:07:00 100 -&amp;gt; 50
--------------------
increase 결과: 300&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/c26e8d2ebd81a5724258c61d2bb8e772/71b12/10.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 51.25000000000001%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABYlAAAWJQFJUiTwAAAB2klEQVQoz41S227TQBT0D0RQFMeO7+u74yYhBURREaiobWLHjZ1wkUquvJC4RDyUl/L1w+66scoDEg+rmdk9Ozv2OcL+9hajqytkaYosSfhKRyNMJznK7Q7lrsTu+xY/ypLqLdd5lmGcjOr66/EYF+cf8OvuDsLw8hLtVguyKFbrEVdlGZqiQGu3oUgS14okQ2o2ITfFuo6dHT1pIKWPCBP6GjFNOJYFm6JLCOwHblsmR2IYHA81UewhjDzKqTZMBL4L4uqYFQUEFtfSdX7pcJFhvUd1zXUDfmgjHgSIjj26X9XF/QAmUVHQ30QTXtcm/zI8aNcl6Dz3EfU8dHo+LM2AF9jovohgmAqmOTVkDTA17b8SMpOo68HrEDi+CV1V4MeEJzSsB8MsSf/6ZG72iB/Mg8jh6cJjF/nHDMvNHJ++zDD7nKN7EkE325UhGxlDVeuLnuPwlCy1axPeCMvQqZGHuBvwhpy+eYVheoH352/x+vQl+oMYtmNWTXl3dgZRfAbPtuFTs0G/z5EZxWGIE6odYlVnvR4fsaNGg48SG5mnlOt0tJSWhGQ4hPBzv8dkkmGzXmOzWmG9XGJ+c8P54uuc4zd6tlosOGcp2KcVdDGcFjnfY2a/7+/xB6xCOF7Nm4s8AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;10&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/c26e8d2ebd81a5724258c61d2bb8e772/d9199/10.png&quot;
        srcset=&quot;/devHistoryBlog/static/c26e8d2ebd81a5724258c61d2bb8e772/8ff5a/10.png 240w,
/devHistoryBlog/static/c26e8d2ebd81a5724258c61d2bb8e772/e85cb/10.png 480w,
/devHistoryBlog/static/c26e8d2ebd81a5724258c61d2bb8e772/d9199/10.png 960w,
/devHistoryBlog/static/c26e8d2ebd81a5724258c61d2bb8e772/71b12/10.png 1308w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;✔︎ increase&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;주어진 시간 범위 내에서 카운터 값의 총 증가량&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;5분동안 요청된 총 증가량&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;increase(http_server_requests_seconds_count[5m])&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;✔︎ rate&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;초당 증가율&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;5분동안의 초당 증가율&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;rate(http_server_requests_seconds_count[5m])&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;✔︎ histogram_quantile&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;히스토그램 데이터 기반으로 특정 분위수(예: 50%, 90%) 값을 추정하는 데 사용&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;5분동안의 초당 증가율을 구하는데, 상위 1%는 제외하여 연산한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;histogram_quantile(0.9, rate(http_server_requests_seconds_bucket[5m]))&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;✔︎ 왜 소수가 나올까?&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;선형 보간&lt;/strong&gt;을 수행하기 때문이다.&lt;/li&gt;
&lt;li&gt;실제 요청이 특정 시점에 몰려 있더라도 일정한 속도로 증가한다고 가정하여 1.009와 같은 소수점 값이 나올 수 있음.&lt;/li&gt;
&lt;li&gt;보간: 주어진 데이터 사이의 값들을 추정하여 새로운 값을 생성하는 방법&lt;/li&gt;
&lt;li&gt;참고: &lt;br/&gt;
&lt;a href=&quot;https://promlabs.com/blog/2021/01/29/how-exactly-does-promql-calculate-rates/&quot;&gt;https://promlabs.com/blog/2021/01/29/how-exactly-does-promql-calculate-rates/&lt;/a&gt; &lt;br/&gt;
&lt;a href=&quot;https://velog.io/@skynet/Prometheus-rate-%EC%97%B0%EC%82%B0%EC%9D%98-%EC%8B%A4%ED%96%89-%EC%9B%90%EB%A6%AC&quot;&gt;https://velog.io/@skynet/Prometheus-rate-%EC%97%B0%EC%82%B0%EC%9D%98-%EC%8B%A4%ED%96%89-%EC%9B%90%EB%A6%AC&lt;/a&gt; &lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;h3&gt;2.4. 그래서 그라파나에서 어떻게 사용하는데?&lt;/h3&gt;
&lt;p&gt;그라파나에서는 프로메테우스 웹 ui와는 다르게 from, to, step 를 추가 설정한다.&lt;/p&gt;
&lt;h4&gt;✔︎ from, to(range) 의 총 수치 나타내기&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;그라파나에서 지정한 시간 범위의 총 수치를 표현하기 위해서는 $__range 변수를 사용한다.

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/ae84ae6f83f430706976c2ae4e4978bc/bc70e/11.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 62.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAABYlAAAWJQFJUiTwAAACIElEQVQ4y22T3XKbMBCFuYkxGBDoDwHGBmzseGznIk4zzUxv+iCd6fu/xOmuME6nzcXHSoI9HGlXQRStEMcJlssYYRj9B6/zNxwXiyWG3RG3bx94ffvu2Y8ndMPhQcAfzklRlNwjEU/jNBXIC+Xn/N22H3F+uRGvuBDH4wn9MHoxfhdkosBXpBmTQ+QShdTIeE7rVVWj27Zw1RrGNRQb2LJGSXNXt5MgJ85kYo4FRCEnccFziZgctsd3XH/+xmZ3Jmd7bLq93zZHFv3SYZLmUKXBcBtQ7xt0Lx0OHwdIm6M5vGP88QvNQCI9vd/26Mcj6k0HZRyClJJnkkSQmPCRhXVtSUTDrEu4vkLZVVDaoiSB9XmEamqPbGh9XUPTcQSSnDCqMj7RNCWNLZSzPtrWodxUHjc0MHUN25Gj6wGaxHQ9CWlbTQ5rSpBWwVQlCiMhVP6JLibUREZrkhwqTT8+b2GvPeylhzl1MH0L7chhkSvfHgW1RqEdJTpfAE92R3zCgpqqaahFdLMlVyV0WU2Qy0DRI6e28ILKEuRU0jHQmJP/hbdlxivc8xtMu39sdSbQ9EiEQq5JWLFLEpeKipN+NvmD2P/QnW7oLpfp/Cw7c/dIDlcrSqT+KmyDnCqaKIGVyBCnCcJlhKen0F/BxSL0V49vjWl31E7PVKiNd/W3aMBdzo5WfLXCGFpPZ8gi3EKGzoYbnXfCt4YLwuOJ6iE4xz8uakSV/Ay8BgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;11&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/ae84ae6f83f430706976c2ae4e4978bc/d9199/11.png&quot;
        srcset=&quot;/devHistoryBlog/static/ae84ae6f83f430706976c2ae4e4978bc/8ff5a/11.png 240w,
/devHistoryBlog/static/ae84ae6f83f430706976c2ae4e4978bc/e85cb/11.png 480w,
/devHistoryBlog/static/ae84ae6f83f430706976c2ae4e4978bc/d9199/11.png 960w,
/devHistoryBlog/static/ae84ae6f83f430706976c2ae4e4978bc/07a9c/11.png 1440w,
/devHistoryBlog/static/ae84ae6f83f430706976c2ae4e4978bc/29114/11.png 1920w,
/devHistoryBlog/static/ae84ae6f83f430706976c2ae4e4978bc/bc70e/11.png 2738w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;✔︎ 시간 흐름에 따른 수치 나타내기&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;시간 흐름에 따른 수치를 표현하기 위해서는 [계산시간범위:step] 을 사용한다.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;아래 쿼리는 (sum by (uri) (rate(http&lt;em&gt;server&lt;/em&gt;requests&lt;em&gt;seconds&lt;/em&gt;count{namespace=“$namespace”, uri!~”^(/actuator|/swagger|/api-docs).*“}[1m:1m]))),&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;ol&gt;
&lt;li&gt;그라파나에서 지정한 시간 범위(24h)를&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;1분마다 쪼개 초당 증가율을 구하는데,&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;x축의 기준을 1분 단위로 가져간다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/0936e28b9fb7dd289069df2183cb4c8c/292f3/12.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 42.91666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAABYlAAAWJQFJUiTwAAABlUlEQVQoz22SS2/bMBCEeUjj6E09SOptibIUW47d5pYUhR2gQNFD21vbW4Dk//+HyYoKWiPO4cOuAO5whitm2y6sCcs5w3Y8LBYWoljierNHv77BcD2i6wYs2/5d2DTkEK7r/8OZqhfAD0JMF8aJRKs7NLqnSmKNRllrVMvuDMbD2Az+JzIE/JWAIxYZ+v0XFPUKWVEjLxuDysozmO1xisTBIw6Phl0/oBrAoWq5ATn1EcoSq/u/qPsduWjRTJHJbSxScp/O9RX26zDi+ecNnn58xOO3Lf587fH4fYffD2vc7Rt0lUKuJGSrUYwd4ipDXBeGpCBUhiTNicz07DhqPGw1DusWh6HBcWxxnPpNi8/rBrerErqkw80AtfsEudIQbWVIliWSkkSrYq5ZDnbl+Li0fSy8CBd2gIsrd8by8IFY2LQwehZFcfPtLTkp55jJSdyT2CyMBL2hgFBkW2YQMjXEiaJvRYek2bKkhVTDBoJcTIPT2fdgKW2G83nTKi0Qkvi03YT6SJIYiYb0HxoRMQ+d9m95AXSB6SkkGFUvAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;12&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/0936e28b9fb7dd289069df2183cb4c8c/d9199/12.png&quot;
        srcset=&quot;/devHistoryBlog/static/0936e28b9fb7dd289069df2183cb4c8c/8ff5a/12.png 240w,
/devHistoryBlog/static/0936e28b9fb7dd289069df2183cb4c8c/e85cb/12.png 480w,
/devHistoryBlog/static/0936e28b9fb7dd289069df2183cb4c8c/d9199/12.png 960w,
/devHistoryBlog/static/0936e28b9fb7dd289069df2183cb4c8c/07a9c/12.png 1440w,
/devHistoryBlog/static/0936e28b9fb7dd289069df2183cb4c8c/29114/12.png 1920w,
/devHistoryBlog/static/0936e28b9fb7dd289069df2183cb4c8c/292f3/12.png 3400w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;두 포인트간 사이는 1분&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/39153e9ef8f0a7bfcb6b171c6e32f88c/29c1d/13.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 44.583333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB6klEQVQozz1S25KaUBDkJZWrV1AEURFFRRHkIqC7Gs1uLpVfSDaVb1PXqk1espsP7PQ5a+Whizlzpnt6hqOsrrZIlgXy9QbLfIWsWCPL14zXyIsrzMMY3+5+4PHpLxZxivVmhzRbIU4yxGlObo4lzxLkKHVNR6mmQe86KFXqqDAuC1Q1VOsNvHj5Bteb9zgcT3j1ugTDHmISJJhd4E58mJ0+4UA3u1AMswOtZcH25mjoJppE4wLdsPCuXMN+f4PT/Rklxt2Rh1laIIwzROkKiyTHdB5hRP6Ad4rR7qLZ7v0XFNCahoSI35aq2O5ucDzdywlsOjI4TaWmoqY2JcSU9YYOtdG6CNKyPQ1kYdtxobJAChJiHfuPX+TI5aoKx1+g3XeJIUfsPDenkBAzqKN0KGCNpnBo2xqM0Z+F0OisZdkcbwqVe/nw+SsOh6Pc7SBMYA0n6IndcZ91OhQNRCz4iuhoewHy6z2Wqy2KzR4+SS5X4F2a7G4/4fzwGzpJgyCWTYWBHmvEvYgd5oUBpeN60OimP/alyJjFI47fY6FNaHS44Q7PD7/QpKDpjGCNZ89fck26bTFv0KVhD6BkfGtTP4A/X8CbBYgS8fcy5kL4QYSx5+P73U/8eXxCGKXyXQoERMG3G8hzJGuF1j8oKhC2Ym6tpwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;13&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/39153e9ef8f0a7bfcb6b171c6e32f88c/d9199/13.png&quot;
        srcset=&quot;/devHistoryBlog/static/39153e9ef8f0a7bfcb6b171c6e32f88c/8ff5a/13.png 240w,
/devHistoryBlog/static/39153e9ef8f0a7bfcb6b171c6e32f88c/e85cb/13.png 480w,
/devHistoryBlog/static/39153e9ef8f0a7bfcb6b171c6e32f88c/d9199/13.png 960w,
/devHistoryBlog/static/39153e9ef8f0a7bfcb6b171c6e32f88c/29c1d/13.png 1375w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;h3&gt;2.5. 왜 기대한 값이 나오지 않을까?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;rate, increase 를 쓰면 총 건수에 대한 값이 정확히 노출 될 줄 알았지…&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;✔︎ 소수로 나타나지는 결과&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;위에서 설명한 것 처럼 보간법 때문에 정수가 아닌 소수로 나타날 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;✔︎ 카운터 리셋 감지시에 기대와 다른  increase 결과&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;롤아웃 후, 각 파드 별로 1건의 요청이 들어왔을때, increase 의 결과는 1이 아니라 0으로 표시가 된다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;카운트가 0→1 로 변하는게 아니라 NaN → 1로 변화하는걸로 예상&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;때문에, 정확한 총 건수에 실패하며, 파드 수가 많을 수록 누락되는 건수가 많아 진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;http_server_requests_seconds_count{uri=&amp;quot;/card-types/{cardType}/intro&amp;quot;}[5m] 결과&lt;/code&gt;&lt;/strong&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/bd7ab20b0949d00ce35a03c8faaef6b1/3c5de/14.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 472px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 62.083333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsTAAALEwEAmpwYAAABOUlEQVQoz51TXW+DMAzk//+5FaZRAgQIX9MArVJbHlpIbzlvsJdqGliykjjJ5Xx2vMv1iqquYcoSTdNCZ5mMSZoiL4zzQmJ0nvk8nWBMiSRJEanYuUJhDJq2xePxgIeNNs8z8rxwD2rESYKDHyDLcrTtu+x5RN3iAlj8Ar4cfGid7QOkTdOMVGtJ9Rgp+EEg8uxO2VqLvh/w0XXo+l7Gfhhwvlxkf2Vo7XNWS9zK3K5Mn5kwHMdR8qfQddOgLCupIqtKrQpXaYpOnbh/dV1h3JnUramjimMZKQMfFIbUhU5Rp2nC/X5fnbHb7SZxXuCY5bkUhG0TBK8Cqtx8YlH2tA1Zk1EcJwjDoxSFLilvrrID1E4C5cCOUYS3MPyZq++U/8tsAeQlas7fVddO86qSn8L15rb5q8KLfQFJlptBMgDPNgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;14&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/bd7ab20b0949d00ce35a03c8faaef6b1/3c5de/14.png&quot;
        srcset=&quot;/devHistoryBlog/static/bd7ab20b0949d00ce35a03c8faaef6b1/8ff5a/14.png 240w,
/devHistoryBlog/static/bd7ab20b0949d00ce35a03c8faaef6b1/3c5de/14.png 472w&quot;
        sizes=&quot;(max-width: 472px) 100vw, 472px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;increase(http_server_requests_seconds_count{uri=&amp;quot;/card-types/{cardType}/intro&amp;quot;}[5m]) 결과&lt;/code&gt;&lt;/strong&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/7f7256ac9e1c02cdf5df4cc87c576abd/b4098/15.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 816px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 36.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAAAsTAAALEwEAmpwYAAABTUlEQVQoz21R23aCMBDk/7+sVWwVrKjcBJSrINTKpQrTnbS+Nefsyewmu5mZaF+3G9I0Q1lVCMMIjuvieIpRFGeUZSX4BM/z1V5dLoiTBEmaIs0yhFEEV866vkffD+i6Hlqe5zgEAQzDxMvrDLO5Dtt24DguDodA4fflSg0l1hdv2GwsuK6n9vX6AzchNU0T7vc7tCzLEUVH+P5BMTzFsTwQwpaBQRiqOiOOE1TVBeM4SjPU4pBxnPB4PP5yQCNNSqN0ymRjnheo6waf16vClMszMqnrWtlD+ZmoK85nNayn7GEQhlKknN1uj7m+gC5BdqyROT1dimRa4HoeVisD1nan8qVgwzTVILIcOJAG01zDXMOyttjKZTayyXYc7Pe2wr74SQvKskTTNIpR13Vo21Z597RAY8If+pb9+Urb/l5knY3ErE9P8/5Zyk+JHxPpCxiRX3FiAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;15&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/7f7256ac9e1c02cdf5df4cc87c576abd/b4098/15.png&quot;
        srcset=&quot;/devHistoryBlog/static/7f7256ac9e1c02cdf5df4cc87c576abd/8ff5a/15.png 240w,
/devHistoryBlog/static/7f7256ac9e1c02cdf5df4cc87c576abd/e85cb/15.png 480w,
/devHistoryBlog/static/7f7256ac9e1c02cdf5df4cc87c576abd/b4098/15.png 816w&quot;
        sizes=&quot;(max-width: 816px) 100vw, 816px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;2건의 요청이 들어왔을땐?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;http_server_requests_seconds_count{uri=&amp;quot;/card-types/{cardType}/intro&amp;quot;}[5m] 결과&lt;/code&gt;&lt;/strong&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/c0f79e89e550f25f1f74be195df3ef47/4ee7f/16.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 486px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 61.24999999999999%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsTAAALEwEAmpwYAAABU0lEQVQoz51T2ZKCQAz0/39vvWAARS5RTgELUGyng+ju0y47ValOxaFNpyeLtm2RZhmKskSaZsiLQpA1iXSMTOd13aBpGhRFKffzvBCsde3xeIBncb1eEUVHnJNEMD6d4Pk+gjDEMY4lZ8Q6z7IcQRBia5gwTYXlag1D534Q4H6/j4SYcdgFCZVlwbIdIbU1hmH0IeSl32J44e12E0JTWUJqaELH2YmaYRj+TjjNh10cDp4mMqE0KeWSmCPp+36+ZB4aUNU1OPuqqnDRQWPfHVJG13US/Jduiq6Xi62ut20nyDq75G/T/V6+7z8u8ynsdnuEUQTP80USZexdF657kKFPgy8vF3GUkk2lBLeGIfgvlylrdNkendY4Eqt5Ln83hZ3ajiNhvbqnQbNM+eGy570f9nqzwddyJbI579mElMxV41YlSaq354ToqLfsnOg3Okp+Arh+mwnovsyKAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;16&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/c0f79e89e550f25f1f74be195df3ef47/4ee7f/16.png&quot;
        srcset=&quot;/devHistoryBlog/static/c0f79e89e550f25f1f74be195df3ef47/8ff5a/16.png 240w,
/devHistoryBlog/static/c0f79e89e550f25f1f74be195df3ef47/e85cb/16.png 480w,
/devHistoryBlog/static/c0f79e89e550f25f1f74be195df3ef47/4ee7f/16.png 486w&quot;
        sizes=&quot;(max-width: 486px) 100vw, 486px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-text&quot;&gt;increase(http_server_requests_seconds_count{uri=&amp;quot;/card-types/{cardType}/intro&amp;quot;}[5m]) 결과&lt;/code&gt;&lt;/strong&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/73fda5a36757dc9c2209adf52b04267c/d56e1/17.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 27.083333333333332%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA50lEQVQY001Qi46DMAzj//9utw0Kg41C24F4iSLeAl8T6XazZLlpKseNp42BUhq5UgjDiNWYt1MNmWVQWnM/ih6QMuN+3/dY1xWEbdvQdh3atsMwDPCezxc/9gMBIUJcrzfc/QCPOEYqJRvkuUJRFM5Y8V2cJG6oYWPCeZ4feuTeNA1PMO8Cdd2gqmtYO2BZFialsdZinCbs+45vUH0cx79hHCf8Vd+lulx+WAXVQYBAiE9ySk283X1O2LYtJjdg23Y2+kvqlWUJrQ3vijRNJX+rqmpORJzmmVOSwezO1u1qHEfmtxnhF8l3d0IfhOMUAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;17&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/73fda5a36757dc9c2209adf52b04267c/d9199/17.png&quot;
        srcset=&quot;/devHistoryBlog/static/73fda5a36757dc9c2209adf52b04267c/8ff5a/17.png 240w,
/devHistoryBlog/static/73fda5a36757dc9c2209adf52b04267c/e85cb/17.png 480w,
/devHistoryBlog/static/73fda5a36757dc9c2209adf52b04267c/d9199/17.png 960w,
/devHistoryBlog/static/73fda5a36757dc9c2209adf52b04267c/d56e1/17.png 1130w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;h3&gt;2.5. 아쉬운 점&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;프로메테우스를 통해 수집한 지표들은 정확한 &lt;strong&gt;“건수”&lt;/strong&gt;를 도출하기 힘들다.&lt;/li&gt;
&lt;li&gt;실제, 건수가 많은 지표에 10건 이하의 건수 누락은 크게 문제가 안되겠지만, 카드 발급 현황의 경우, 파드 수 만큼 개수가 빠지므로 크게 표시가 남.&lt;/li&gt;
&lt;li&gt;따라서, &lt;strong&gt;정확한 건수를 위한 지표보다는 현황 및 이상 감지 용도로 적합하다.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[rateLimit 고민 기록]]></title><link>https://ssongey.github.io/works/posts/2024-07-14--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2024-07-14--001</guid><pubDate>Sun, 14 Jul 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;이번에 톡사원증이 오픈을 하게 되었다.&lt;br/&gt;
톡사원증은 특정 증명서 발급을 통해 회사 이력을 카드로 인증해주는 서비스이다.&lt;br/&gt;
요 기쁜 소식을 사내에 오픈 공지를 올렸을때, 순간적으로 트래픽이 살짝 높아지게 되었는데, 이때 증명서 발급 신청 건이 우수수 실패가 되었다.&lt;/p&gt;
&lt;p&gt;맙소사… 아직 대외로 오픈소식을 알리기도 전인데 이게 왠 날벼락인가…&lt;br/&gt;
이대로라면 프로모션시에 큰 장애가 날 듯 싶어 급하게 rate limiter 를 개발하게 되었다.&lt;/p&gt;
&lt;h2&gt;요구사항은,&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;증명서 별로, 발급 신청시 rate limit 을 적용한다.&lt;/li&gt;
&lt;li&gt;분산환경에서 동작해야 한다.&lt;/li&gt;
&lt;li&gt;발급신청시에 요청수 체크 및 카운트를 증가 시키고, 그외 특정 api 들에서도 요청수 체크를 할 수 있어야 한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;br/&gt;
&lt;h2&gt;구현방법&lt;/h2&gt;
&lt;p&gt;rate limit 를 구현하는 방법은 다양하다.&lt;/p&gt;
&lt;p&gt;nginx에서 사용자 IP 별 요청을 제한하거나 어플리케이션 단에서 queue를 이용하는 방법, 또는 redis 를 이용하는 방법 등 여러가지 방법이 있는데, 이중 최대한 쉽게 구현할 수 있는 redis 를 사용하기로 했다. (예시도 많고..)&lt;/p&gt;
&lt;p&gt;그리고 방법은 2가지를 정할 수 있는데,&lt;/p&gt;
&lt;h3&gt;구현방법1) 고정 윈도 카운터&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;타임라인을 고정된 윈도우로 나누고, 각 윈도우마다 카운트 체크를 한다.&lt;/li&gt;
&lt;li&gt;카운트가 임계치를 넘어가면 새로운 윈도우가 열릴때까지 요청은 버려진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/328e1684ea378d8b8658a13d91b33830/bc3ae/01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 52.916666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABYlAAAWJQFJUiTwAAABP0lEQVQoz31SCY6DMAzk/z/rH2C3UFigpRwNN5SpJ1ojWLFYshxn7ImPOBB5v99Wj4T38zyf4ootywKHh2marKMBPKulkFATtrjeMX9HWFUVmqZBnucIggBRFOF2uyHLMgzDgDRNMY6jtbwPw9Cq5tHuCEngui7u9zviOLaaJIklIHa5XKzl3RZnvOd5FtPuLCGr0PaORFs6EuYxf1dh23XoJamoXngWJUzbEl2T2JbOTlVnSDLiO8LumaH3v2CCK4z/jS4MMFw95DLDUuaTPR6n1fd9v/rOLC9VsoxGdBl6zFLdIgF5/APf99f5FkVht83lkISWfivxXIp+Laeua5RlieplUDctjJRvxNbGoBGMOMmM+PWvv1WSMZ9t8yHbMre5LXsrfJlV/vexOUPdsm1Zt/R36Nvh87EzXH8J9QPqQ1i0wS7TXAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/328e1684ea378d8b8658a13d91b33830/d9199/01.png&quot;
        srcset=&quot;/devHistoryBlog/static/328e1684ea378d8b8658a13d91b33830/8ff5a/01.png 240w,
/devHistoryBlog/static/328e1684ea378d8b8658a13d91b33830/e85cb/01.png 480w,
/devHistoryBlog/static/328e1684ea378d8b8658a13d91b33830/d9199/01.png 960w,
/devHistoryBlog/static/328e1684ea378d8b8658a13d91b33830/bc3ae/01.png 1268w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h3&gt;고정 윈도 카운터의 단점&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;이 방법은 redis 공식 문서에도 소개된 만큼 구현하기 쉬운 장점이 있지만, (&lt;a href=&quot;https://redis.io/docs/latest/commands/incr/&quot;&gt;https://redis.io/docs/latest/commands/incr/&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;아래와 같이 윈도우 경계부근에서 일시적으로 많은 트래픽이 몰려드는 경우에는, 기대했던 시스템의 처리 한도보다 최대 2배의 많은양을 처리하게 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/a90e342e346ec010d2d9e208f08ed059/7b1dc/02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 956px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 52.083333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABYlAAAWJQFJUiTwAAABKElEQVQoz41Sa2+DMAzs//9x3ecCQUC7VcB4Bcobbr5MQWys6iydsHzkcrZzWtcVjL7vMc8z0jQ1SJIEn1mGaRjQdR3mcURVVRsXxzHatsUo9WmajAa1TlbQ8zxcr1f4vm9yQkn+HkV4O5/hOReEQbBxxO12g+M4KIriKEgXz2IQ92L/T47u6PIgSPvMiWVZvscg7bZNDS2t6rJEXWvDWZjL5J+XgrbWNA1cpXDxFFQY4uN+f+3QEs9antMED+WiVQ5KWZKua7Mcghfmeb6dNYJUtwS/P/B4oJWBl0mMWlBJzsUFshzXdRHJwniulHGwQ47BtEzbLPLZ7GdkUWltntV+JHaGFNLC27ppmUK8yf70O3JplQdtW/tgPRP+sBQbexf7Bf2HY3wBs48Jbk/2R8YAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/a90e342e346ec010d2d9e208f08ed059/7b1dc/02.png&quot;
        srcset=&quot;/devHistoryBlog/static/a90e342e346ec010d2d9e208f08ed059/8ff5a/02.png 240w,
/devHistoryBlog/static/a90e342e346ec010d2d9e208f08ed059/e85cb/02.png 480w,
/devHistoryBlog/static/a90e342e346ec010d2d9e208f08ed059/7b1dc/02.png 956w&quot;
        sizes=&quot;(max-width: 956px) 100vw, 956px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;ts &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; CURRENT_UNIX_TIME&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
keyname &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; key+&lt;span class=&quot;token string&quot;&gt;&quot;:&quot;&lt;/span&gt;+ts
MULTI
    INCR&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;keyname&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    EXPIRE&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;keyname,10&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
EXEC
current &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; RESPONSE_OF_INCR_WITHIN_MULTI
IF current &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt; THEN
    ERROR &lt;span class=&quot;token string&quot;&gt;&quot;too many requests per second&quot;&lt;/span&gt;
ELSE
    PERFORM_API_CALL&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
END&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;구현방법2) 이동 윈도우&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;매번 현재시간을 기준으로 윈도우를 나누고, 각 윈도우마다 카운트 체크를 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/40b2d0601a8bd4b5cf80c9f7ba40486a/7960f/03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 57.50000000000001%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAABYlAAAWJQFJUiTwAAABZklEQVQoz5VTi26DMAzs///gNE0rpWODUsqrBEhIuPmyggjaQ4tkSM7JxT47h3mesR1c77EFz/McaZpCa71iWz/HYQ/+RtjUNcrbDWaafibkZ5INzjmiXHgH14yI1nXdljkg4L5pc4EnVEqtaaRvZyRJgizLEEUR4jjG8XhEdrkgPp1QF0VASDKeDwiHYYAxxoNaddDjCCsbrbVwYnVVQfU9RrFJfHvCXvCAkIAnfGwy8i/rBq3czGS0kK5D5vN/InTpO4Y4Qvn6gjY+QSdn5M9PuElBKimI7tXfEZJwERaSMozo6exXNOOAD9ExFU2pbXG9BtWnLAuhrzKBtm09SFIjGhnrfGvQrFSxvd8xCj5JFoby0Cdz7mcwTdOsnXJg/pWITlBJdJ0cZpvQ7jKnvyxLf6nqQj+N53iec17iUy6kFcZH9b5raL6OVZLdYIZsseClbDXcvhYa02CUPLj3LYT0+4ch4xPnrqtRlSRpzAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/40b2d0601a8bd4b5cf80c9f7ba40486a/d9199/03.png&quot;
        srcset=&quot;/devHistoryBlog/static/40b2d0601a8bd4b5cf80c9f7ba40486a/8ff5a/03.png 240w,
/devHistoryBlog/static/40b2d0601a8bd4b5cf80c9f7ba40486a/e85cb/03.png 480w,
/devHistoryBlog/static/40b2d0601a8bd4b5cf80c9f7ba40486a/d9199/03.png 960w,
/devHistoryBlog/static/40b2d0601a8bd4b5cf80c9f7ba40486a/7960f/03.png 1274w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h3&gt;이동 윈도우의 단점&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;위 그림만 봐서는 고정 윈도우의 단점을 해결 할 수 있을 듯.. 보였지만&lt;/li&gt;
&lt;li&gt;실제 구현 방법을 보면 이 방법도 함정이 보인다..ㅠㅜ&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;current = 0
MULTI
ZREMRANGEBYSCORE $key 0 ($currentTime - $slidingwindow)
current = ZRANGE $key 0 -1
EXEC

IF current &amp;gt; 100 THEN
ERROR &amp;quot;too many requests per second&amp;quot;
ELSE
PERFORM_API_CALL()
MULTI
ZADD $key $currentTime
EXPIRE $key $slidingwindow
EXEC&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;위 코드는 sorted set를 이용한 이동 윈도우 구현 방법이고, 데이터는 현재 시간이 들어간다.&lt;/li&gt;
&lt;li&gt;sorted set 이기 때문에 시간순으로 정렬이 되며, ZREMRANGEBYSCORE 명령어를 이용하여 현재 윈도우에서 제외되는 데이터를 지운다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/eff7c4de3be3b5ede70b15ea88480466/fbf76/04.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 63.33333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAABYlAAAWJQFJUiTwAAABfUlEQVQ4y31Ta2+DMAzs//9rkzbtOxOshfIYBcqbJHDzRaQqjM7SCcePi+2YE0SWZbFw4jRnJ/I8R5Km6LsOlehGa+xz+T29InwmI4qiQLoS1rd/CDdEO+Ij6YTwJuRt227sLs9WqJSCMYZWTNME1fcYBdSzLEMYhrherxiGAWVV4Sa2QfwULZUyf9NyvyZTiqJE4Hn49n07M1++npz5jYU0CAKkUfSojHn9Sv4g5M28iXNhO3mS2GqPxLY2z1gErjvm/6nQla0ZyFnuiQSksE+xIzyskA6GNP4Xuo836OgMlcbow7OF+Ukx+R6az3eM0QXzetFhhTTwUdg255OHFyh5xbFpkPEcxzAS01clksBHIbM1a4XM2RDSUNe1XQfOcBLMKznbnyWI0GJT1m8wawUlj8EY5jGf+izxJxq4tJWsA/VGqiK4Zw7dk97St/oZf7/fUZal1UlqW+aujeN4+KoMiqTtVwvPdrmjTuyf4srd/24E7Rz8kc/5me/OvzpZ98YG8RBHAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;04&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/eff7c4de3be3b5ede70b15ea88480466/d9199/04.png&quot;
        srcset=&quot;/devHistoryBlog/static/eff7c4de3be3b5ede70b15ea88480466/8ff5a/04.png 240w,
/devHistoryBlog/static/eff7c4de3be3b5ede70b15ea88480466/e85cb/04.png 480w,
/devHistoryBlog/static/eff7c4de3be3b5ede70b15ea88480466/d9199/04.png 960w,
/devHistoryBlog/static/eff7c4de3be3b5ede70b15ea88480466/fbf76/04.png 1252w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;이때, ZREMRANGEBYSCORE 명령어와 ZADD 명령어는 한 트랜잭션에 존재하지 않기 때문에 정말 짧은 순간에 트래픽이 몰렸을 경우, 방어가 되지 않는 문제가 생긴다.&lt;/p&gt;
&lt;br/&gt;
&lt;h2&gt;그래서 결론은?&lt;/h2&gt;
&lt;p&gt;각 단점을 다시 정리하면,&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;고정윈도우는, 정해진 시간(윈도우)에&lt;/strong&gt; burst traffic 발생시에 최대 2배 처리가 되고,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;이동윈도우는, 동일하거나 정말 짧은 시간에&lt;/strong&gt; burst traffic 발생시 아예 방어가 안된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;하지만 전자증명서 서비스 특성상, 정말 짧은시간에 burst traffic이 발생할 확률보단 정해진 시간에 burst traffic 이 발생할 확률이 높아 두번째 방법을 선택하게 되었다.&lt;/p&gt;
&lt;p&gt;아직 개발 전이지만.. 시간이 너무 촉박하다ㅠㅜ 어휴&lt;/p&gt;</content:encoded></item><item><title><![CDATA[스프링 배치작업 기록]]></title><link>https://ssongey.github.io/works/posts/2024-06-22--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2024-06-22--001</guid><pubDate>Sat, 22 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;스프링 배치를 사용하여 매일 한번씩 카카오 계정 서버에서 휴면/탈퇴 계정 목록을 가져와 내가 담당하고 있는 서비스를 탈퇴 시키는 작업을 진행했고, 이에 대한 기록을 남긴다.&lt;/p&gt;
&lt;h2&gt;1. 요구사항&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;매일 휴면계정 목록을 가져와서 카카오 전자증명서 서비스를 탈퇴시킨다.&lt;/li&gt;
&lt;li&gt;매일 탈퇴계정 가져와서 카카오 전자증명서 서비스 탈퇴 및 DB에 저장된 증명서 발급 내역 테이블에서 개인정보 컬럼을 null로 업데이트한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;h2&gt;2. 배치 스케줄러를 어떻게 수행할 것인가?&lt;/h2&gt;
&lt;h3&gt;2.1. k8s cronJob + api 서버&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;방법&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;스케줄러는 k8s cronJob 이 담당&lt;/li&gt;
&lt;li&gt;배치 작업을 수행하는 api 를 생성하며, cronJob이 해당 api를 호출한다.&lt;/li&gt;
&lt;li&gt;해당 api 의 배치 로직 실패시에 알람 구현 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;배치 오류 발생시?&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;상세 에러 내용은 kibana에서 확인 (es에 서빙이 되도록 로그 작업 필요)&lt;/li&gt;
&lt;li&gt;배치 작업을 수행하는 api 를 수동으로 호출 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;h3&gt;2.2. jenkins + api 서버&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;방법&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;스케줄러는 jenkins cron이 담당&lt;/li&gt;
&lt;li&gt;배치 작업을 수행하는 api 를 생성하며, jenkins가 해당 api를 호출한다.&lt;/li&gt;
&lt;li&gt;실패에 대한 알람은 jenkins 플러그인 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;배치 오류 발생시?&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;상세 에러 내용은 kibana에서 확인 (es에 서빙이 되도록 로그 작업 필요)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;배치가 오래 걸릴수 있으니 http 커넥션을 계속 맺고 있을수 없다고 판단, @Async 어노테이션을 이용하여 비동기로 수행. 때문에 젠킨스에 배치에 대한 호출로그는 남겠지만, 수행 로그는 남지 않음.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;수동으로 실행하는 젠킨스 파이프라인 미리 생성하여 해당 파이프라인 수행.&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;h3&gt;2.3. jenkins + springbatch&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;방법&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;스케줄러는 jenkins cron이 담당&lt;/li&gt;
&lt;li&gt;배치 작업은 spring batch가 담당, jenkins cron은 springbatch 애플리케이션 파드를 실행시킴&lt;/li&gt;
&lt;li&gt;수행 시간에 파드가 생겼다가 작업이 끝나면 사라짐.&lt;/li&gt;
&lt;li&gt;실패에 대한 알람은 jenkins 플러그인 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;배치 오류 발생시?&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;상세 에러 내용은 젠킨스 수행 로그에서 확인&lt;/li&gt;
&lt;li&gt;수동으로 실행하는 젠킨스 파이프라인 미리 생성하여 해당 파이프라인 수행.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;3번 사용 결정 이유&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;배치를 위한 파드(서버)를 계속 띄울 필요 없이, 배치가 수행되는 시간에만 파드를 띄울수 있다는 장점이 있다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;리소스 절약 및 서버에 대한 관리가 불필요.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;파트 내에 이미 kubernetes plugin 이 설치된 젠킨스가 있어서 세팅이 간단 했던것도 한몫함.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://plugins.jenkins.io/kubernetes&quot;&gt;Jenkins kubernetes plugin&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;한 곳에서 (jenkins) 수행 로그(결과 또는 에러 로그) 확인 및 재수행(retry)을 진행할 수 있다는 장점이 있다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;api로 수행을 할 경우, 수행 로그 확인과 재수행(retry) 위치가 달라진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;h2&gt;3. spring batch 작업을 진행하면서 겪은 일&lt;/h2&gt;
&lt;h3&gt;3.1. multi datasource 설정&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;spring batch 를 사용하기 위해서는 &lt;strong&gt;기본적으로 필요한 메타 테이블들이 존재&lt;/strong&gt;한다.&lt;/li&gt;
&lt;li&gt;해당 테이블은 비즈니스 로직에서 사용하는 DB에 생성하기에는 너무 불필요한 테이블이였다.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;때문에 &lt;strong&gt;비즈니스 DB와 spring batch DB를 분리&lt;/strong&gt;하기로 결정.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;비즈니스 DB는 기존대로 mysql 사용, spring batch DB는 h2 사용.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;파드가 생성되어 애플리케이션이 시작될때 h2 로드 및 아래 spring batch 메타 테이블은 h2에 생성.&lt;/li&gt;
&lt;li&gt;애플리케이션이 종료되면 h2에 생성된 테이블 삭제 및 h2도 같이 종료. (메타 테이블에 저장된 배치 이력 데이터 사라짐)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/bce78d74ec50ca823267f3786e435b30/58a91/01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 80.83333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAACXBIWXMAABYlAAAWJQFJUiTwAAAClElEQVQ4y4VUaXPaMBTk//+cNue0nU4DTSbhDtjGFz4xYPAFtqmxzfZJQJoPIdXMWpZk7Vvte3LDj1Lcv0i4ex7j9umV4+5ZQEdxcakdDoeLa41NusVYmkCcyLwXJBlBvMGu2GObF3BXMWYEexFgHiSoT2SXSBtRskFvJHK0ByOMJBWiOoVhu/BWIa4eOrj69YLrZge/XxWUVf05YV3XqOoD2HKa5fRe8037skK+y+HYJhzTgL/wgLp6I7pIyB6iscCXZh83j0N8bfbwrS1ht68Qxgl64wk6wzGpH0Mi5fuy5BuZkJqEvAcLwgkX6xUE8lCSFTgzD0GUoOIqa6RFhWibI87+ICtKTvRZ44RRFNHRbNi2BcdxkGUZXzQpEdePr7hu9fH1oYvvbREFWTEPUnSpCgbaDH3VRVe20SFE6e5IuA5D6NMpFEVFSO9nf7abmOYUqATHsXlg1py5j2Z7iObLAK3OEK+KAc1ZYpOdCYMAuq7zzZZloSSf9vs9wijm85qmwTRNFEXBPQyI2KXT2JQslrRzqylpnHC1XmNKCjVV5ZvZRkYaJQkMw+CBPM/j/rFA7EQsgKpq8H3/jZBVyD+FROiSfyqRuu7xlmzTFBapMGhtSkp9f8nnfRIgSRIH8zzZbBAQR57np6TEMUyLJcTlkZmPrAVhBEHWMBJlKngZE1VHSQrZTVLtOXRnTr0H1ZphYhDxNj0ShuTJ9OQVQ0zjkrK53uywTHLYPnm2TuCFWyRUPv8tG8dboi/IGBBYLyo65usIP9oC7p+GuGl1cdvq4WdvgpEx51VwCZyQihzVO7Axu3ayQj8NQYAkitwvppz5dC7uj65f4zj5DqePsnwHQTMxVg0OaWrT2IJuz05q8KHCv7datrAKw+zRAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/bce78d74ec50ca823267f3786e435b30/d9199/01.png&quot;
        srcset=&quot;/devHistoryBlog/static/bce78d74ec50ca823267f3786e435b30/8ff5a/01.png 240w,
/devHistoryBlog/static/bce78d74ec50ca823267f3786e435b30/e85cb/01.png 480w,
/devHistoryBlog/static/bce78d74ec50ca823267f3786e435b30/d9199/01.png 960w,
/devHistoryBlog/static/bce78d74ec50ca823267f3786e435b30/07a9c/01.png 1440w,
/devHistoryBlog/static/bce78d74ec50ca823267f3786e435b30/29114/01.png 1920w,
/devHistoryBlog/static/bce78d74ec50ca823267f3786e435b30/58a91/01.png 1990w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;비즈니스 로직에서 사용하는 DB(mysql) 설정(application.yaml)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;kotlin&quot;&gt;&lt;pre class=&quot;language-kotlin&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;spring&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
  jpa&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
    database&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; mysql
    database&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;platform&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; org&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;hibernate&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dialect&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;MySQL8Dialect
    &lt;span class=&quot;token operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;spring batch에서 필요한 메타 데이터 테이블 생성을 위한 설정 (BatchConfig.kt)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;kotlin&quot;&gt;&lt;pre class=&quot;language-kotlin&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;&lt;span class=&quot;token annotation builtin&quot;&gt;@EnableConfigurationProperties&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;BatchProperties&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token annotation builtin&quot;&gt;@Configuration&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; BatchConfig &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token comment&quot;&gt;// @Bean 없이 생성해야 primany datasource bean 은 mysql 이 된다.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; batchDataSource &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;EmbeddedDatabaseBuilder&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;EmbeddedDatabaseType&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;H2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addScript&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;classpath:org/springframework/batch/core/schema-drop-h2.sql&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addScript&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;classpath:/org/springframework/batch/core/schema-h2.sql&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

		&lt;span class=&quot;token comment&quot;&gt;// 메타 테이블 스키마에 대한 초기화를 진행한다. 해당 설정이 없으면 테이블 생성은 mysql에 생성된다.&lt;/span&gt;
    &lt;span class=&quot;token annotation builtin&quot;&gt;@Bean&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;batchDataSourceInitializer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        resourceLoader&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ResourceLoader&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        properties&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; BatchProperties&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; BatchDataSourceInitializer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;BatchDataSourceInitializer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            batchDataSource&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            resourceLoader&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            properties&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

		&lt;span class=&quot;token comment&quot;&gt;// 배치설정를 진행하며, 여기서 설정된 datasource에 배치 메타 데이터에 대해 crud 가 발생&lt;/span&gt;
    &lt;span class=&quot;token annotation builtin&quot;&gt;@Bean&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;batchConfigurer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; BatchConfigurer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;DefaultBatchConfigurer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;batchDataSource&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;h3&gt;3.2. JPA로 수행되는 CUD 쿼리가 수행이 안되는 현상.&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;위처럼 생성하게 되면 batch 관련 DataSource 는 h2 기준으로 생성이 된다.&lt;/li&gt;
&lt;li&gt;Spring Batch는 기본적으로 &lt;code class=&quot;language-text&quot;&gt;DataSourceTransactionManager&lt;/code&gt; 를 사용하므로 JPA로 수행되는 쿼리도 해당 트랜잭션 매니저로 수행이 된다.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;DataSourceTransactionManager&lt;/code&gt;으로 수행이 되면 JpaTransaction이 생성되지 않아 기본 쿼리인 조회(select)만 수행이 가능하게 된다.&lt;/li&gt;
&lt;li&gt;이를 해결하기 위해 JpaTransaction bean을 생성하여 batch job에 주입해준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;kotlin&quot;&gt;&lt;pre class=&quot;language-kotlin&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;&lt;span class=&quot;token annotation builtin&quot;&gt;@Configuration&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; JpaConfig &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token comment&quot;&gt;// datasource bean 은 mysql 이다.&lt;/span&gt;
    &lt;span class=&quot;token annotation builtin&quot;&gt;@Bean&lt;/span&gt;
    &lt;span class=&quot;token annotation builtin&quot;&gt;@Primary&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;jpaTransactionManager&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dataSource&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DataSource&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; JpaTransactionManager &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;JpaTransactionManager&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;apply&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dataSource &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; dataSource &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; JobConfig &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token annotation builtin&quot;&gt;@Bean&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;dormantStep&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        jpaTransactionManager&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; JpaTransactionManager&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Step &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; stepBuilderFactory&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;dormantStep&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;tasklet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dormantUserTasklet&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;transactionManager&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;jpaTransactionManager&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token annotation builtin&quot;&gt;@Bean&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;dormantJob&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        dormantStep&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Step&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        jobCompletionListener&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; JobExecutionListener
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Job &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; jobBuilderFactory&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;dormantJob&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;listener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;jobCompletionListener&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dormantStep&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;h3&gt;3.3. index가 없을 경우 update, delete 쿼리가 수행되면?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;update, delete 쿼리에 필요한 인덱스를 DB팀에 요청 후에 jenkins 세팅을 하게 되었다.&lt;/li&gt;
&lt;li&gt;리얼에서 파이프라인 세팅 및 테스트를 하다가 실수로 spring batch job을 수행하게 되었다.&lt;/li&gt;
&lt;li&gt;갑자기 약 1-2분간 ‘PessimisticLockingFailureException’ 오류가 발생하여 서비스 불능 상태가 되었고, batch job 수행이 완료된 후 락이 풀렸다.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;where 절로 인해 테이블 전체가 Lock이 걸리진 않을거라고 예상했는데… &lt;strong&gt;InnoDB에서 &lt;a href=&quot;https://dev.mysql.com/doc/refman/8.4/en/update.html&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;UPDATE&lt;/code&gt;&lt;/a&gt;또는 &lt;a href=&quot;https://dev.mysql.com/doc/refman/8.4/en/delete.html&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;DELETE&lt;/code&gt;&lt;/a&gt;는 where 절과 상관없이 스캔된 모든 인덱스 레코드에 잠금을 건다&lt;/strong&gt;. 수행 당시에는 조건에 걸린 필드에 인덱스가 없었기 때문에 모든 row에 락이 걸리게 된 것이다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://dev.mysql.com/doc/refman/8.4/en/innodb-locks-set.html&quot;&gt;https://dev.mysql.com/doc/refman/8.4/en/innodb-locks-set.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;실시간 서비스에서 서치가 오래걸리는 update, delete 의 경우는 꼭꼭 인덱스를 세팅하고 수행하자.&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;h3&gt;4. Transaction 이 너무 긴 현상&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;kotlin&quot;&gt;&lt;pre class=&quot;language-kotlin&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ATestlet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Tasklet &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;
		&lt;span class=&quot;token function&quot;&gt;loop&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;token function&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;RunnerClass&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token annotation builtin&quot;&gt;@Transactional&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;한개의 tasklet 을 사용하여 loop를 돌며 트랜젝션 어노테이션이 붙은 함수를 수행하도록 하였고, 해당 함수에서는 update, delete 쿼리가 수행된다.&lt;/li&gt;
&lt;li&gt;loop 가 한번 돌떄마다 commit 이 발생할 것이라고 예상했는데, 예상한바와 다르게 프로세스가 끝나야 실제 DB에 반영이 되었다.&lt;/li&gt;
&lt;li&gt;해당 원인파악은 아직 못한 상태…&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Circuit 적용 고민]]></title><link>https://ssongey.github.io/works/posts/2024-06-15--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2024-06-15--001</guid><pubDate>Sat, 15 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;현재 맡고 있는 서비스는 정부전자문서지갑 API에 대한 의존도가 높은데, 이 API는 장애가 잦은 편이다.
장애가 발생하면 서비스 응답 속도가 느려지고, 결국 사용자 경험이 나빠진다.
&lt;br/&gt;
이런 문제를 해결하기 위해 &lt;strong&gt;Circuit Breaker 적용을 좀 더 세분화하여 진행&lt;/strong&gt;했다.
&lt;br/&gt;
기존에는 큰 기능 단위로만 Client Bean을 나누었지만, &lt;strong&gt;API 특성별로 더 세분화하여 대응&lt;/strong&gt;하기로 했다.&lt;/p&gt;
&lt;br/&gt;
&lt;h2&gt;1. Client Bean 세분화&lt;/h2&gt;
&lt;p&gt;일반적으로 외부 API를 호출하는 Client Bean은 &lt;strong&gt;host 단위&lt;/strong&gt;로 생성한다.
하지만 장애가 잦은 API에 대해 더 정밀한 대응이 필요했기에, &lt;strong&gt;장애 유형별, 구간별로 Client Bean을 추가 분리&lt;/strong&gt;했다.
&lt;strong&gt;분리된 client들은 서로 중복으로 api path를 가질 수 있으며, 각 client 객체는 호출되는 시점이 다르다.&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;✔︎ 구조 개선&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;기존 구조 (AS-IS)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;개인 전자문서 지갑 관련 api 연동 client bean&lt;/li&gt;
&lt;li&gt;수취기관 관련 api 연동 client bean&lt;/li&gt;
&lt;li&gt;증명서 신청/제출 등 api 연동 client bean&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;개선된 구조 (TO-BE)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;장애가 자주 발생하는 api별 client bean 생성&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;증명서 신청을 위한 부가정보 조회 api 전용 client bean&lt;/li&gt;
&lt;li&gt;사용자의 전자문서지갑 상태 조회 api 전용 client bean&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;점검 유형 정하기 위한 구간별 client bean&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;전자증명서 홈 진입 시 사용되는 api 전용 client bean&lt;/li&gt;
&lt;li&gt;증명서 신청 플로우에서 사용되는 api 전용 client bean&lt;/li&gt;
&lt;li&gt;증명서 보냄/받음 플로우에서 사용되는 api 전용 client bean&lt;/li&gt;
&lt;li&gt;내 증명서 확인 플로우에서 사용되는 api 전용 client bean&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;그외 api 전용 client bean 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;h3&gt;✔︎ 적용 효과&lt;/h3&gt;
&lt;p&gt;서비스 특성상 &lt;strong&gt;read timeout이 15초&lt;/strong&gt;로 설정되어 있었고,
정부전자문서지갑 서버는 &lt;strong&gt;Timeout 에러가 자주 발생&lt;/strong&gt;하는 상태였다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Circuit Breaker가 오픈되면서&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;15초 동안 기다리지 않고 &lt;strong&gt;빠르게 사용자에게 오류 페이지로 랜딩&lt;/strong&gt;이 가능했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Client Bean을 세분화하면서&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;어떤 플로우가 문제인지 좀 더 명확하게 파악&lt;/strong&gt;할 수 있었다.&lt;/li&gt;
&lt;li&gt;점검 종류를 빠르게 파악이 가능하여 &lt;strong&gt;빠른 대응이 가능&lt;/strong&gt;했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;h2&gt;2. 불필요한 Pod 수 조정&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Circuit Breaker는 각 파드에서의 에러율을 기준으로 동작&lt;/strong&gt;하기 때문에,
트래픽 대비 Pod 수가 많으면 &lt;strong&gt;서킷이 제대로 동작하지 않는 문제&lt;/strong&gt;가 있다.&lt;br/&gt;
현재 트래픽에 비해 설정된 Pod 수가 많았고, &lt;strong&gt;적절한 Pod 개수로 조정&lt;/strong&gt;하여 서킷이 정상적으로 동작할 수 있도록 했다.&lt;/p&gt;
&lt;h3&gt;✔︎ 적용 효과&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;트래픽이 많지 않은 시간대 &amp;#x26; 요일에도 &lt;strong&gt;Circuit Breaker가 정상적으로 동작&lt;/strong&gt;하도록 개선됨.&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;h2&gt;3. Sliding Window 타입 결정&lt;/h2&gt;
&lt;p&gt;Resilience4j의 Circuit Breaker는 아래 2가지 &lt;strong&gt;Sliding Window 방식&lt;/strong&gt;을 지원한다.
&lt;a href=&quot;https://resilience4j.readme.io/docs/circuitbreaker&quot;&gt;참고&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Count-based Sliding Window&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;요청 개수 단위로 데이터를 저장하고 집계하는 방식&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Time-based Sliding Window&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;요청 시간 단위로 데이터를 저장하고 집계하는 방식&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;처음에는 Time-based 방식을 고려했지만,
&lt;strong&gt;Client Bean 세분화 및 낮은 트래픽을 가진 서비스의 특성&lt;/strong&gt;을 고려하여 &lt;strong&gt;Count-based&lt;/strong&gt;로 결정했다.&lt;/p&gt;
&lt;h3&gt;✔︎ 적용 효과&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;트래픽이 낮은 늦은 밤, 새벽 시간대에도 서킷이 동작하도록 개선 됨&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;h2&gt;4. Fallback 적용 여부&lt;/h2&gt;
&lt;h3&gt;✔︎ Fallback이란?&lt;/h3&gt;
&lt;p&gt;서비스를 차단한 경우, 예외를 발생시키는 대신 미리 준비된 동작을 실행하는 것을 의미한다.&lt;br/&gt;
즉, Circuit Breaker가 Open 상태일 때 요청을 에러로 응답하지 않고, 대체 응답을 제공하는 방식이다.&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;이번 작업의 목표는 빠르게 에러를 감지하고 사용자에게 안내하는 것&lt;/strong&gt;이었기 때문에, &lt;strong&gt;Fallback을 적용하지 않고 즉시 에러 안내 페이지를 노출&lt;/strong&gt;하도록 했다.&lt;/p&gt;
&lt;br/&gt;
&lt;h2&gt;5. 최종 정리&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;장애가 자주 발생하는 API별로 Client Bean을 세분화&lt;/strong&gt;하여 장애 감지 속도를 높임&lt;br/&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pod 개수를 조정하여 Circuit Breaker가 정상 동작하도록 개선&lt;/strong&gt;&lt;br/&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;트래픽 특성을 고려해 Count-based Sliding Window 방식 적용&lt;/strong&gt;&lt;br/&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fallback을 사용하지 않고 빠른 에러 안내 제공&lt;/strong&gt;&lt;br/&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[nginx proxy serving 이슈]]></title><link>https://ssongey.github.io/works/posts/2024-06-15--002</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2024-06-15--002</guid><pubDate>Sat, 15 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;1. 구조 파악&lt;/h2&gt;
&lt;p&gt;구조가 좀 복잡하다…&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;모바일에서 요청시에 제일 먼저 webapp nginx 로 요청이 들어오고&lt;/li&gt;
&lt;li&gt;사용자 인증을 위해 에서 kakaotalk pilsner server 프록시 하고&lt;/li&gt;
&lt;li&gt;pilsner 서버에서 계정 인증 후 webapp server 로 또 프록시 된다.&lt;/li&gt;
&lt;li&gt;그리고 webapp으로 프록시된 요청은 실제 api 서버로 요청을 하게된다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;요청 흐름도)&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;모바일&lt;/strong&gt; → &lt;strong&gt;webapp server&lt;/strong&gt; -(proxy)→ &lt;strong&gt;필스너 서버&lt;/strong&gt; -(proxy)→ &lt;strong&gt;webapp server&lt;/strong&gt; -(proxy)→ &lt;strong&gt;디지털카드 api server&lt;/strong&gt;&lt;/p&gt;
&lt;h4&gt;응답 흐름도)&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;디지털카드 api server&lt;/strong&gt; -(proxy res)→ &lt;strong&gt;webapp server&lt;/strong&gt; -(proxy res)→ &lt;strong&gt;필스너서버&lt;/strong&gt; -(proxy res)→ &lt;strong&gt;webapp serve&lt;/strong&gt;r → &lt;strong&gt;모바일&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/fa0dcf3ba63f020a113f88e65a7ffed5/8ce22/02-001.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 685px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 72.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsTAAALEwEAmpwYAAACGUlEQVQ4y41UXW/aMBTNj+cH7H1PaC97qDRVfdg0iapQPtsMWggh6QYBCoSGlCTk2yac2qawbGsnrnRl5/r6+Prc40jb7RZZloGPv50e57vdTvg+h7IRbATCMEAURYjjWHgYhuJb4snvmbVawRiP8TidwnUdEcuIjYx68Dwfi8UCc+amacJxHAF6BNxXwsZthCydi9hwOEJLlqGNDJiWLWKB+RnErYj5XfceXUVBf6CB0P2tchW+AidDOMYH+H6E+14PjVodxm0TT5Meq2KN1coWTkiKH507dHsKVFVBEkeg9BVwuVyiVCpBlm+xfLJg2w5bpNBZZfpNC+WLS3S0GrI4EMdyPrkpfRUDBvbp6w1k1WC3o5D4vceMJ9d1oWma4OVghBAkSYzu1MSjE4Kk6ZEebimhiEMfZ9ca2vqc8wVpNptB13VsNhtUKhVBLHJVREEApVGFpQ9YcHck561m8gIkz/MwmUxQKBRQLBZzDdpv8J5tPD9oqJe/4fzqYn/YNjgeats21uu1aIgA5Bu5jvjCwfKAlPEi+DI0fLn+DuJrCOYfRayvqkJWI+Y8n/P+hw7zQHmu8rGVZcK2DKaCANV6A/VmC23W7Yefv7Dx/b91+P6cX+/Aa5JQ8SpqjSYur8pMj11W7UCI+x/AU/yQbzK5VapVyO2OkJDDlPLfp3eKBUwVrushYGpIkhTS2z+H05w3AbmCUqbTF91dLc2vUy38AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;02 001&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/fa0dcf3ba63f020a113f88e65a7ffed5/8ce22/02-001.png&quot;
        srcset=&quot;/devHistoryBlog/static/fa0dcf3ba63f020a113f88e65a7ffed5/8ff5a/02-001.png 240w,
/devHistoryBlog/static/fa0dcf3ba63f020a113f88e65a7ffed5/e85cb/02-001.png 480w,
/devHistoryBlog/static/fa0dcf3ba63f020a113f88e65a7ffed5/8ce22/02-001.png 685w&quot;
        sizes=&quot;(max-width: 685px) 100vw, 685px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;h2&gt;2. 이슈 내용&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;간헐적으로 모바일에서만 정적파일(js, css, html) 서빙시에 타임아웃 발생 또는 css가 깨진 화면이 노출&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;h2&gt;3. 원인&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;talk-pilsner OS upgrade를 작업을 위해 gslb 내 vip 하나를 Down 하였고,&lt;/li&gt;
&lt;li&gt;webapp nginx 는 talk-pilsner dns의 변경사항을 감지하고 못하고 down 된 vip로 요청.&lt;/li&gt;
&lt;li&gt;nginx는 proxy pass 할 talk-pilsner &lt;strong&gt;도메인의 vip 목록을 서버 실행시 캐싱하여 계속 사용하기 때문에 down된 vip로 요청&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/3456062b96d1a337bb8ad41bcb768d84/91e7e/02-002.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 692px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 70.83333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsTAAALEwEAmpwYAAACNUlEQVQ4y62Uy5LSUBCGeRs3PowLXbi3XLjQKh9Ai4UbyzeY0hpduLCsccuMeBkgOCByDSQZAgG5FhASgUwIBH5PnyQYmFnaVc2pc7rznT/dHSKO48B1XazX653TfrvdgozWw3iQs9lseJxW8tVqhQgFD42Se70eup0uhoMBTwzggU2nUwyHQ3RZHq26rsOyLA8Y3BJ+oFgqQ5RkSPUGQsfcDMPAYrFAWRQhyTIu6ypse8mF7CkkIN1imiZ+ZLKoForQxF+Y/9EZxMRsNkOr3cLR6yO8fXeM2Nln1NUGFFlib+FwURECNRoNxGIxaJrGYfaVjVQmA/VrAl++f4MxlhjMguMsYVtLjNoTTLsmBOEC1VoVp6k8mr/7JAkR27ahKAp/jUqlslM7mUxgMlVCTcPcWmDJYGSXcxEP83fwqHgPCrvIMud4dZLDRbXlAam4pIzAyWRyByT5pmmgXi7CXVxh7Xql6VganmUeI5p9CsPV+ZmztHk+lS9CygRBQDQaRSKR8GpJI8CCvZoI+TyOj5+OMZ2Z/7qy8d2/ODAOpJ/xeAxVVf3OeEmu39kx6+bd5w9Qa0reQ0wpmwnPQ7O6B9wezgUFC08w/HAL+sltWKn7ezHKD8OuAcPSdaa20+mjnX+PWvwF1MRLtH6+Qb8/QLPZxGg0uhF6Dbj1a1dlnY6fnSKbLSJXkJGvqDgXckin0+wsi1KpxAc4DL0R+D+MA4M/h8DpkL7dNXO++vtVaB/ODzvF/wKVESHe245AUQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;02 002&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/3456062b96d1a337bb8ad41bcb768d84/91e7e/02-002.png&quot;
        srcset=&quot;/devHistoryBlog/static/3456062b96d1a337bb8ad41bcb768d84/8ff5a/02-002.png 240w,
/devHistoryBlog/static/3456062b96d1a337bb8ad41bcb768d84/e85cb/02-002.png 480w,
/devHistoryBlog/static/3456062b96d1a337bb8ad41bcb768d84/91e7e/02-002.png 692w&quot;
        sizes=&quot;(max-width: 692px) 100vw, 692px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;h2&gt;4. 조치 내용&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;dns resolve 설정을 추가하여 talk-pilsner 도메인의 ip를 주기적으로 가져오도록 설정&lt;/li&gt;
&lt;li&gt;인증이 불필요한 정적 파일은 talk-pilsner를 타지 않도록 수정.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;resolver &lt;span class=&quot;token number&quot;&gt;10.20&lt;/span&gt;.30.40 &lt;span class=&quot;token assign-left variable&quot;&gt;valid&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;10s&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
 
server &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    location / &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token builtin class-name&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$talk_pilsner&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;talk-pilsner.kakao.com&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        proxy_pass http://&lt;span class=&quot;token variable&quot;&gt;$talk_pilsner&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;h2&gt;5. 참고 내용 - nginx 에서 도메인명을 이용하여 서비스를 검색하는 방법&lt;/h2&gt;
&lt;h3&gt;5-1. proxy_pass 지시어에 도메인명 사용&lt;/h3&gt;
&lt;p&gt;가장 간단한 방법이지만 가장 유연성이 떨어지는 방법이며 다음과 같은 단점이 있다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;도메인 이름을 확인할 수 없는 경우 서버가 실행되지 않는다.&lt;/li&gt;
&lt;li&gt;재시작 할때까지 DNS 레코드를 캐시하고 레코드의 TTL도 무시한다.&lt;/li&gt;
&lt;li&gt;로드 밸런싱 알고리즘을 지정할 수 없다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;server &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    location / &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        proxy_pass http://talk-pilsner.kakao.com&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;h3&gt;5-2. Upstream Server Group에 도메인명 사용&lt;/h3&gt;
&lt;p&gt;로드 밸런싱 알고리즘을 지정할 수 있다. (ex&gt; least_conn)&lt;/p&gt;
&lt;p&gt;max_fails 를 지정하여 연속 요청이 지정한 횟수에 다다르면 서버가 다운 된것으로 표시.&lt;/p&gt;
&lt;p&gt;다음과 같은 단점이 여전히 존재&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;도메인 이름을 확인할 수 없는 경우 서버가 실행되지 않는다.&lt;/li&gt;
&lt;li&gt;재시작 할때까지 DNS 레코드를 캐시하고 레코드의 TTL도 무시한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;upstream talk_pilsner &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    least_conn&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
 
    server talk-pilsner.kakao.com &lt;span class=&quot;token assign-left variable&quot;&gt;max_fails&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
 
server &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    location / &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        proxy_pass http://talk_pilsner&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;h3&gt;5-3. 변수에 도메인 이름 지정&lt;/h3&gt;
&lt;p&gt;도메인 이름을 다시 확인하는 빈도를 제어할 수 있다.&lt;/p&gt;
&lt;p&gt;resolver valid 설정을 통해 지정된 시간마다 도메인 이름을 다시 확인 하도록 할수 있다.&lt;/p&gt;
&lt;p&gt;도메인 이름을 확인 할 수 없을때 nginx 재시작 없이 서비스 탐색을 재시도 하기때문에 첫번째 방법의 두가지 단점을 보완할수 있다.&lt;/p&gt;
&lt;p&gt;단, 로드 밸런싱 알고리즘을 지정 할 수 없다.&lt;/p&gt;
&lt;p&gt;nginx plus를 사용하지 않는다면 가장 유연성이 높은 방법이다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;resolver &lt;span class=&quot;token number&quot;&gt;10.20&lt;/span&gt;.30.40 &lt;span class=&quot;token assign-left variable&quot;&gt;valid&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;10s&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
 
server &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    location / &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token builtin class-name&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$talk_pilsner&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;talk-pilsner.kakao.com&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        proxy_pass http://&lt;span class=&quot;token variable&quot;&gt;$talk_pilsner&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[GSLB에 대해 알아봅시다]]></title><link>https://ssongey.github.io/works/posts/2024-05-10--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2024-05-10--001</guid><pubDate>Fri, 10 May 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;1. GSLB 는 SLB와 무엇이 다른가?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;SLB : Server Load Balancing&lt;/li&gt;
&lt;li&gt;GSLB : Global Server Load Balancing&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;GSLB는 DNS + SLB&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;일반적인 DNS 기능 + LB Method 적용이 가능&lt;/li&gt;
&lt;li&gt;DNS는 단순 R/R 으로 IP만 응답함&lt;/li&gt;
&lt;li&gt;위치(topology)를 기반으로 응답을 다르게 주거나&lt;/li&gt;
&lt;li&gt;Ratio를 줘서 6:4 등의 비율로 나누어 주거나&lt;/li&gt;
&lt;li&gt;하는 등의 제어가 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;h2&gt;2. SLB&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;구성단위는 &lt;strong&gt;VIP&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;VIP에 여러대의 서버를 바인딩&lt;/li&gt;
&lt;li&gt;즉, LB가 실제 트래픽을 받는 구조, 때문에 트래픽 규모에 따른 한계가 있을 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;✔️ Traffic Flow&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;클라이언트는 DNS에서 도메인 주소의 IP 주소를 질의하여 얻어옴&lt;/li&gt;
&lt;li&gt;레코드 타입: A (도메인에 IPv4 주소를 연결하는 방식)&lt;/li&gt;
&lt;li&gt;이때 IP는 미리 등록한 SLB VIP&lt;/li&gt;
&lt;li&gt;클라이언트는 DNS 질의를 통해 얻어온 VIP로 접속을 시도&lt;/li&gt;
&lt;li&gt;해당 VIP를 가진 SLB는 Method에 따라 Client의 요청을 서버로 분배&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/7514617a693225b4aeeff4093b637649/09ede/01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 57.50000000000001%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAABYlAAAWJQFJUiTwAAACEElEQVQoz32TTY/SQBzG+V6e/ACe/TheNvGwRhOzwdIt9HU67ZQOLGWDlRdhKbBmY4I3o9GYcDCiB7MGD8vC48xAWdclTvKkzbz8/s88/7awXq8hJcf7Dx9xNswwGQ2RTd4gy4YYDjcajUYYj8d7NZlM1Pp8Pkchhy2vlghChvODh/j06D5C7SnikwTNJEEiFIYhKqYJc48sy0KpVFLQG6BQwm18fvwAvw7uoWUcIu0NcDboo9/vo3l6CkIIfN+/I0qpgkqnhZUArRYL/O41wHkEahRR15/AJRSe58FzXRDPFQeJOOirpwT/LQmVThVQ2cMCyx/fwOoNuH4AwmJVlcrqIgY3jIQDB+WKBceV4OCWOxnHDvj2IsO76QV+Xl7iVVkDdUyEgafchNUYccVAWCziyPRxpFvQLF+tVcUa5zGCIFDaXbnbey0yGuD71y8YvHgG5uioMku4I2CcIy5pqD8/BIuOwekxGK0gYj5qtboAcgGu3gZiO66vV2AnDTgeERtrSNMUL1stpJ0OPN6E7gQwVV6bG0TKIRfX/cfhrsvLK3BRjYhGyA0yl1yUeGrecgOUPQoWborudXgDXKoNediu6K7sch68KhJQJSreVdO2YozBtu27wLxbhmFA0zT1scrKjuOoA7btbGWruXxeFtd1XfxZ2QaYQ6fTqcqu2+3u1BEZttvt/0rukedmsxn+AC9M8gVQEbhxAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/7514617a693225b4aeeff4093b637649/d9199/01.png&quot;
        srcset=&quot;/devHistoryBlog/static/7514617a693225b4aeeff4093b637649/8ff5a/01.png 240w,
/devHistoryBlog/static/7514617a693225b4aeeff4093b637649/e85cb/01.png 480w,
/devHistoryBlog/static/7514617a693225b4aeeff4093b637649/d9199/01.png 960w,
/devHistoryBlog/static/7514617a693225b4aeeff4093b637649/07a9c/01.png 1440w,
/devHistoryBlog/static/7514617a693225b4aeeff4093b637649/09ede/01.png 1710w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h4&gt;✔️ Health Check&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;보통 아래 2가지를 방식을 표준으로 사용한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;L4 : TCP port check&lt;/li&gt;
&lt;li&gt;L7 : HTTP METHOD 를 사용하여 response code 또는 message 확인 (ex. health_check.html)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;interval, response timeout, retry, down time 등의 정책을 정하여 헬스체크를 수행한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;h2&gt;3. GSLB&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;구성단위는 &lt;strong&gt;도메인&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;도메인에 여러개의 서버 IP 혹은 VIP를 바인딩&lt;/li&gt;
&lt;li&gt;도메인으로 들어오는 질의에 대해 GSLB에서 서버 IP 혹은 VIP를 응답&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;즉, GSLB는 DNS의 쿼리만 받음&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;클라이언트에서는 응답받은 서버 IP 혹은 VIP로 트래픽 전송&lt;/li&gt;
&lt;li&gt;트래픽의 규모와는 직접적으로 연관이 없음&lt;/li&gt;
&lt;li&gt;DNS 질의양(QPS)에 따른 영향은 있을 수 있으나, 큰 문제가 되는 경우는 적음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;✔️ Traffic Flow&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;클라이언트는 DNS에서 서비스 도메인 주소를 질의하여 얻어옴&lt;/li&gt;
&lt;li&gt;레코드 타입: CNAME (Alias 형태로 다른 도메인을 연결하는 방식)&lt;/li&gt;
&lt;li&gt;이때는 결과값은 GSLB의 도메인&lt;/li&gt;
&lt;li&gt;클라이언트는 DNS 질의를 통해 얻어온 GSLB 도메인으로 다시 질의&lt;/li&gt;
&lt;li&gt;요청을 받은 GSLB는 Method에 따라 VIP 또는 서버 IP를 응답&lt;/li&gt;
&lt;li&gt;클라이언트는 질의를 통해 얻어온 VIP 또는 서버 IP로 접속을 시도&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;5-1. VIP로 시도했다면, 해당 VIP를 가진 SLB는 Method에 따라 Client의 요청을 서버로 분배&lt;/p&gt;
&lt;p&gt;5-2. 서버 IP로 시도했다면, 바로 서버로 접근&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/b173b9b97802a2d4f97574a7bc05934f/05244/02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 55.833333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABYlAAAWJQFJUiTwAAACUklEQVQoz22S22sTQRSH898JPor/gG8+CL6JT75YFB+09qFqaS57n53dbS6Nbpq0uTVtEooKCmIQUttk074HC1WknzOb4n3gsMw5v/nNd85Oht/W6ekprXabN6+HMJ/BxbnKflPxlYtBC75/udyfp7n/rcx8PmcymTCbzRgffubD231Go/ccVUNOPr7jeJZwkiRMjw5JplOSZMJ0dsL0+BPT6TGJOpfouqqdnZ2RaSuibDaLZZoYriB+skRpdRlLFLm3cosbD66Ss7K027spfTWu464/Y3z/Cu3l22xuNdntdqi+rHJwcECm1WphKjPP83Bcj8BbR6oIhWDp+R1uPr6OI/Lsd1v0ujs0GjUC4wWHj67RXb1LvNOhv79HrVZjOBwuCC3LQigDIXwiWSCUFoFvYXkhtutTcCXCM/E9AylMosDCFqG6SCoQF1fB5HI5+v3+wtA0rZRQRxjK1DznBOQdiS+81DTrFjEdoTRCaQKl8XBdR4WL7/vk8/lfhppQtx1GG7yqlKlUNjHEBq5jpwbikiJrB5RKFaWpsKk0uuY6zp+GnU4n/Smr68qwHLH39AE1UcCQIYbtKbMFuetpakmxJNlbeUjsm+REhOV4fxu2sR2XSrVKuSjTOYaBT7lcRIYqlFibBmGkyMuUNrRGEoVKUykRREUCKSkUCgwGAzLb29vpRlPYtoNhGFj2olVPzUePQ+dslXNUe5ZlpzR67np+umVdW1tbo9frkRmNRuopNNDPR3/jOKZe36LZbP4brWaq0U+k0aj/zOuz9Xqd8XjMDzz0sZkhIY8/AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/b173b9b97802a2d4f97574a7bc05934f/d9199/02.png&quot;
        srcset=&quot;/devHistoryBlog/static/b173b9b97802a2d4f97574a7bc05934f/8ff5a/02.png 240w,
/devHistoryBlog/static/b173b9b97802a2d4f97574a7bc05934f/e85cb/02.png 480w,
/devHistoryBlog/static/b173b9b97802a2d4f97574a7bc05934f/d9199/02.png 960w,
/devHistoryBlog/static/b173b9b97802a2d4f97574a7bc05934f/07a9c/02.png 1440w,
/devHistoryBlog/static/b173b9b97802a2d4f97574a7bc05934f/05244/02.png 1752w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h4&gt;✔️ Health Check&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;DNS는 H/C 가 안되지만, GSLB는 바인딩된 VIP 혹은 서버 IP에 대해 SLB H/C 가 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;h2&gt;4. 도메인 구성은 어떻게 해야 하는데?&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;서비스 도메인 &gt; CNAME : GSLB 도메인 &gt; VIP 또는 서버IP&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;서비스 도메인 &lt;a href=&quot;http://www.my-service.com&quot;&gt;my-service.com&lt;/a&gt; 설정&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;레코드 타입: CNAME&lt;/li&gt;
&lt;li&gt;TTL : 600&lt;/li&gt;
&lt;li&gt;레코드 값: my-service-hash.kgslb.com&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;GSLB 도메인 &lt;a href=&quot;http://my-service-hash.kgslb.com&quot;&gt;my-service-hash.kgslb.com&lt;/a&gt; 설정&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;레코드 타입: A&lt;/li&gt;
&lt;li&gt;트래픽 분배 방식: R/R&lt;/li&gt;
&lt;li&gt;H/C : TCP 443, 80&lt;/li&gt;
&lt;li&gt;레코드 값&lt;/li&gt;
&lt;li&gt;vip 10.1.1.1, 설정트래픽 50%&lt;/li&gt;
&lt;li&gt;vip 10.1.1.2, 설정트래픽 50%&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;h2&gt;5. H/C 는 어떻게 동작하고 있는거지?&lt;/h2&gt;
&lt;p&gt;아래 L4, L7 H/C 동작을 보면, L4는 80포트 커넥션 확인만, L7는 HTTP 요청까지 진행한다.&lt;/p&gt;
&lt;p&gt;뭐가 더 좋을까?&lt;/p&gt;
&lt;h4&gt;✔️ &lt;strong&gt;L4 H/C&lt;/strong&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;GSLB ↔ SLB, SLB ↔ 서버 각각 H/C 를 진행한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/14a8fb70b4b481d0cd26d0ff0ab8ac2e/17fba/03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 40.833333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABYlAAAWJQFJUiTwAAABHElEQVQoz3VSi26EIBD0/7+x1VrP87QgDxFR1Km7qQYvKclIlNlhdtYsxghjDIqiQPNsUFUPVN8V5nkGrX3fsW0b74S6rlGWJYNq2ra9eISMHsuywFqL0XkM1sG5kUXOlQp67zGOI8ONDtM03QXPoil41KLAj2rgZ0cUJqSC/61T7BJctwgXNJ7mA8LVWNZwK0gF5yVA6haP7hPKSoTob9yMWg1hgpQCeZ5zNkorDMOApmk4SxKj1rTWINl4GAjrzDuZIZ6xBjSPjG6nIq00Hwgh+D2EgK7roJTCuq7scqO8DwP29YIuvuCOs+0Q6fueQRdyyzQUKSU7pCmykySztOX9EAcN7KgBfXvLNruIf78HgRylQV+CJ/cdCfcXc1tvY4CMt9gAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/14a8fb70b4b481d0cd26d0ff0ab8ac2e/d9199/03.png&quot;
        srcset=&quot;/devHistoryBlog/static/14a8fb70b4b481d0cd26d0ff0ab8ac2e/8ff5a/03.png 240w,
/devHistoryBlog/static/14a8fb70b4b481d0cd26d0ff0ab8ac2e/e85cb/03.png 480w,
/devHistoryBlog/static/14a8fb70b4b481d0cd26d0ff0ab8ac2e/d9199/03.png 960w,
/devHistoryBlog/static/14a8fb70b4b481d0cd26d0ff0ab8ac2e/07a9c/03.png 1440w,
/devHistoryBlog/static/14a8fb70b4b481d0cd26d0ff0ab8ac2e/29114/03.png 1920w,
/devHistoryBlog/static/14a8fb70b4b481d0cd26d0ff0ab8ac2e/17fba/03.png 2456w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h4&gt;✔️ &lt;strong&gt;L7 H/C&lt;/strong&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;GSLB ↔ 서버 H/C 진행도 가능하다.&lt;/li&gt;
&lt;li&gt;때문에, 최종 endpoint 까지의 H/C 가 가능하다는 점에서 L7 H/C 가 매력적으로 보인다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/c1c3aef34dabe737c84b3962d7fe043e/0e758/04.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 49.583333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABYlAAAWJQFJUiTwAAABcUlEQVQoz3VSiZaDIAz0/3+w+3bdWs9aFa0W8ACZTejaukfDw/BMGCaZBCAbhgFRFCFNU9oJ4jiGUopDcM5hXVfv2dq2xfF4RJ7n/k6SxDDGPnIDPhhjCPQGJfX3VrD2nsS2B5znBTfKHfVMXkIr/Yh5QD47WnIckFQfyJsIVynozx2E1x5wsTNEXyG6HFB1BfR8uz/q1ifD1VmouUM9fNKO6NLz1T8MjcYw1si7A/kKdp2xt6DrOkzTBL0A78WE8DxCUs5I/wrqE8cYkFvQNA0YV/QL3lKFQkwwvq8CNcU4J+CPpQvlzeF0BT5bQBL40Pe++T35ZVk8Q0O5RkqoJMMQ51BZAWdXL1AYhpAUC7ZmstLMqDyfwaxfiWJJwE40KPMMorqQKM9p8CVvKrdCIMsyD8ovMch/Y8OM67r27C9VBbkDfIjCJZVl6efqRDPIs7YB/mbIgNxLLpGBtdY/Ge7VZGAulf0rQPYcZ7G2vWf4BfYdB71b5iU3AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;04&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/c1c3aef34dabe737c84b3962d7fe043e/d9199/04.png&quot;
        srcset=&quot;/devHistoryBlog/static/c1c3aef34dabe737c84b3962d7fe043e/8ff5a/04.png 240w,
/devHistoryBlog/static/c1c3aef34dabe737c84b3962d7fe043e/e85cb/04.png 480w,
/devHistoryBlog/static/c1c3aef34dabe737c84b3962d7fe043e/d9199/04.png 960w,
/devHistoryBlog/static/c1c3aef34dabe737c84b3962d7fe043e/07a9c/04.png 1440w,
/devHistoryBlog/static/c1c3aef34dabe737c84b3962d7fe043e/29114/04.png 1920w,
/devHistoryBlog/static/c1c3aef34dabe737c84b3962d7fe043e/0e758/04.png 2502w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h4&gt;✔️  L7 H/C를 사용하는게 항상 좋을까?&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;SRV#2가 H/C에 실패하면&lt;/li&gt;
&lt;li&gt;GSLB도 SLB#1 H/C를 실패로 간주할 수 있고,&lt;/li&gt;
&lt;li&gt;실패로 간주되면 GSLB에서 VIP1이 다운이되어 Datacenter#1 로 트래픽 요청이 끊길 수 있다는 점을 고려해야하기 때문에 보통은 L4 H/C를 사용한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/a9a7987bf72c12eb3a82267ccb6b1e4e/50e7d/05.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 56.666666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABYlAAAWJQFJUiTwAAACRElEQVQoz22T22/TMBTG+9fxyDsSiIf9G/CAkNA2BuIybUzrJakTXxJnTdKm3VRtS7vC0ySEuL0gNLakHZvUPTKE0MexW6RNYOnIzvHnn48/OxVcadPpFMPhEG9eH+D35RllflH8pLic93/HJn7gf61yfn6OsiwxmUxw9O0YH98f4vOHQxTHX3A2PsJJUWAynpCmwHg8Rnk6QXH6HeXJVxTFMcrxKeVLy7i4uEBFSolqtQrXdSkYFK9B+ZvwWIDF9Xu4++gGXmw+xW5/D/3dXeRuHdHKEt4t38Lh4m1EcYp8fx/9fh9xHKMShiGazSY45/B8TsA6Ar6BkCs8W72Phcc3se48x2iQY7DXR96JoZw6Pq3cwdsnC0izHkajAwwGA0RRhIrWGowxCCHAhYRWLnToouVuIHv4AA6XcHwJwV0EwoFSnp03Wk8o6gV837cMU5QFmgp9+jCJIJBQUqDhK1QbDFJwmiNbPA2H0aa0OCSNlDOQ53m2GDOeAyMwAppQKkS73Ubc7kDUGfSrNfjksYEa0CZTCHQLnU4badomvSIguw6MIo16vYaXG3ScUCKLBdKOhl5bRbC8BD8I6LjcLqgRUEcKWSLRSRSaMkCDcQLy68Bmk9nbSlrB7NiSI040pN6iKqStQEqFrThBsjXzLVCCbjWCDGcaAzQ6+2wch6qjnpNXxtyZL9LubMbGY9NzWym3T4yxuYZyjOYMw+QreZ4jyzLs7Oyg283sW0rTFL1eD9vb2/+E0SZJYr2+mu92u/Yv+wM1/6yqllDuaAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;05&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/a9a7987bf72c12eb3a82267ccb6b1e4e/d9199/05.png&quot;
        srcset=&quot;/devHistoryBlog/static/a9a7987bf72c12eb3a82267ccb6b1e4e/8ff5a/05.png 240w,
/devHistoryBlog/static/a9a7987bf72c12eb3a82267ccb6b1e4e/e85cb/05.png 480w,
/devHistoryBlog/static/a9a7987bf72c12eb3a82267ccb6b1e4e/d9199/05.png 960w,
/devHistoryBlog/static/a9a7987bf72c12eb3a82267ccb6b1e4e/07a9c/05.png 1440w,
/devHistoryBlog/static/a9a7987bf72c12eb3a82267ccb6b1e4e/50e7d/05.png 1738w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;</content:encoded></item><item><title><![CDATA[Backoff 정책 정리]]></title><link>https://ssongey.github.io/works/posts/2024-03-23--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2024-03-23--001</guid><pubDate>Sat, 23 Mar 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;진행하고 있는 프로젝트에서 사용하고 있는 backoff 내용을 정리한다. &lt;br/&gt;
사용중인 메시지 브로커: RabbitMQ&lt;/p&gt;
&lt;h2&gt;1. 용어 정리&lt;/h2&gt;
&lt;h3&gt;✔︎ Exchange&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Producer로 부터 전달받은 메시지를 어떤 큐들에게 발송할지 결정하는 객체&lt;/li&gt;
&lt;li&gt;4가지의 타입이 있으며, 라우터 기능을 한다.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;타입 4가지&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Direct: 라우팅 키가 정확히 일치하는 큐에 메시지 전송 (unicast)&lt;/li&gt;
&lt;li&gt;Topic: 라우팅 키 패턴이 일치하는 큐에 메시지 전송 (multicast)&lt;/li&gt;
&lt;li&gt;Headers: [key:value]로 이루어진 header값을 기존으로 일치하는 queue에 메시지 전송 (multicast)&lt;/li&gt;
&lt;li&gt;Fanout: 해당 exchange에 등록된 모든 큐에 메시지 전송 (broadcast)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;✔︎ Binding&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Exchange와 큐를 연결하는 관계&lt;/li&gt;
&lt;li&gt;모든 메시지는 Exchange가 가장 먼저 수신하는데, Exchange 타입과 binding 규칙에 따라 적절한 큐로 전달된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;✔︎ Dead Letter Queue(DLQ)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;오류로 인해 처리할 수 없는 메시지를 임시로 저장하는 메시지 대기열&lt;/li&gt;
&lt;li&gt;소스 대기열에 처리되지 않은 메시지가 넘치지 않도록 잘못된 메시지 및 실패한 메시지의 임시 저장소 역할을 수행한다.&lt;/li&gt;
&lt;li&gt;DLQ에 TTL을 지정하여, 일정 시간이 지난 후 다시 작업 큐로 라우팅 되도록 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;일반적인 메시지 큐에서 &lt;strong&gt;메시지가 정상적으로 소비되지 못하면&lt;/strong&gt; 어떻게 될까?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;계속 큐에 들어가게 되어 무한 재시도 수행, 이는 시스템 부하의 원인이 됨&lt;/li&gt;
&lt;li&gt;무한 대기 상태가 되면 큐가 가득 차서 다른 메시지도 처리 불가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;문제가 있는 메시지는 기록하고 분석할 필요가 있기 때문에 RabbitMQ, Kafka 같은 메시지 브로커는 이런 메시지를 별도의 “Dead Letter Queue(DLQ)“에 저장하도록 지원&lt;/p&gt;
&lt;br/&gt;
&lt;h2&gt;2. 구조&lt;/h2&gt;
&lt;p&gt;담당중인 서비스의 기능 중, 파트너사에 요청한 작업 상태를 polling 방식으로 체크하여 작업 완료시 사용자에게 알림을 보내는 기능이 있다.&lt;br/&gt;
해당 기능은 비동기로 수행되며, 이를 위해 RabbitMQ를 사용중이고, 수행 플로우는 아래와 같다.&lt;/p&gt;
&lt;h3&gt;플로우&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;파트너사로 작업을 요청 후, polling을 위해 작업 큐에 메시지를 넣는다.&lt;/li&gt;
&lt;li&gt;큐에 담긴 메시지를 consume 하여 해당 message 기반으로 파트너사 쪽으로 상태를 체크한다.&lt;/li&gt;
&lt;li&gt;만약 내부 서비스 오류 또는 통신 오류 등, 재시도가 필요한 오류가 발생하게 되면, retry 큐에 들어가게 된다.&lt;/li&gt;
&lt;li&gt;이때, backoff 정책에 의해, 재시도를 수행한 횟수에 따라 매번 다른 dead letter queue에 들어가게 된다.&lt;/li&gt;
&lt;li&gt;DLQ에 지정된 TTL이 만료되면 다시 작업 큐에 들어가게 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/011fd273a1f411959a6e2b8ca4861432/d6331/001.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 702px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 72.91666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB8ElEQVQ4y4WU6W7qQAyF8/7SvW9DxU8koGIR+yr2vWGPgLAG3HxWh4ZUai1ZmWTGxz7HnlgSsOFwKI1GQwaDgdRqNdnv988927al1WpJu92WyWQSDJP7/a7Px+Mh1na7ld1up8EcxJfLpXS7XZnP53I8HuVwOAjnNpuNOI4j6/Vav7muq369Xr8Bi8WiFAoFyefzCnC5XHRjOp1KpVLRikqlkjhbR/cwKu33+/okMUlfKlytVupk926eeJ4np9NJRqORAiIDyQw9ABaLhSbFXwDlF+PA7XZTNzqFteOMOYtZLMKOnc9naTab2iiowcQEAgR9WJ38c8ECrOBL0KGNdtFoVGKxmDbOGHSRoepPQrValYm/fnwxsMIUTXWGKhqibdDo7Hg89hszkPT7u7z9/yc7nwGVW8HqzNo9uLoJMFSh3ul01BkXY+xnMhlJptOSSqW0iT8A6W5wrphJaDEeAPJumgF4uVyWRDwuyWRSmVgGCIMigADgzCiUEZ9qaAQjwgihI/vcKPQl9qmhyUgQayrh+jG8s9lMQQhgH+dbvV7XquJ+daZhzy5zTxOJhJafy+U0O8JDiaoIIIn9YSs4kjAFBiS4VkDuMRrROYRFi/PXfAGazWYlEoloNUgQHuYfg/2X8VNg7nq93ss1C18Gnp9jaXb18QnVCgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/011fd273a1f411959a6e2b8ca4861432/d6331/001.png&quot;
        srcset=&quot;/devHistoryBlog/static/011fd273a1f411959a6e2b8ca4861432/8ff5a/001.png 240w,
/devHistoryBlog/static/011fd273a1f411959a6e2b8ca4861432/e85cb/001.png 480w,
/devHistoryBlog/static/011fd273a1f411959a6e2b8ca4861432/d6331/001.png 702w&quot;
        sizes=&quot;(max-width: 702px) 100vw, 702px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;h2&gt;3. Backoff 구성&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;일반적으로 재처리를 위해 requeue를 하는 방법을 사용하는데, 처리 서버 부하로 인해 requeue 를 반복적으로 수행하면 이는 부하만 가중될 뿐이다. (최악은 DDos)&lt;/li&gt;
&lt;li&gt;일정시간 간격을 두고 재처리를 하는것도 동일하게 부하가 될 가능성이 크다고 한다.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;그래서 도입된게 Exponential Backoff 전략이였나보다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;찾아보니 이 역시도 한계가 있다고 하며, Jitter(지연변이)를 사용하는 곳도 있다고 한다.&lt;/li&gt;
&lt;li&gt;Jitter: 재시도 간격에 무작위성을 추가하여 요청하는 시간대를 분산시키는 개념&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/79df5d4c1b00a317486cd9e16377376f/f09ab/002.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 25.416666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAAAsTAAALEwEAmpwYAAABC0lEQVQY012Q2UrDUBCG87Y+gs8jeOOlgmDxxuWiFVEEtSWiJWljTJs055yszXY+T1rr9sPMwD/bP2PVVYUSgiLPAQ1dQw/Pn3F9c8783WUHrTW+55FnGb/R8zuzApVyaTuM/RDWkipZ0pUZQeRxenWIv5xt9jRNQ1XXnNyPccJ4O6iDuqkJVi7zxStpLrGGTsD+2S0Hdy9QKKQIjeIYmUaMngeIJKQoSrI0YSUVe8dDLt58pFwwcW1kIjZ1g+ER3mKKVZQlUSxQSfLnDJmseJiMTIy/udaoDMKIzLxH5IJAfRjxmrZtWVfr7cnG/zSYhO46RCawfZtH94mp2apyRWf43v6j5/TXjL7/E8IZe1uEbMhLAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/79df5d4c1b00a317486cd9e16377376f/d9199/002.png&quot;
        srcset=&quot;/devHistoryBlog/static/79df5d4c1b00a317486cd9e16377376f/8ff5a/002.png 240w,
/devHistoryBlog/static/79df5d4c1b00a317486cd9e16377376f/e85cb/002.png 480w,
/devHistoryBlog/static/79df5d4c1b00a317486cd9e16377376f/d9199/002.png 960w,
/devHistoryBlog/static/79df5d4c1b00a317486cd9e16377376f/f09ab/002.png 1250w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h3&gt;플로우&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;작업에 실패하게 되면 retry.x Exchange에서 해당 작업의 재시도 횟수를 확인하여 그에 맞는 DLQ로 라우팅한다.&lt;/li&gt;
&lt;li&gt;DLQ에 들어온 메시지는 지정된 TTL 동안 머무른다.&lt;/li&gt;
&lt;li&gt;TTL이 만료되면 backoff.x Exchange로 이동하게 되고, header 값에 저장되어 있는 작업 큐 이름을 확인하여 해당 작업 큐로 requeue 된다.&lt;/li&gt;
&lt;li&gt;이렇게 실패 횟수에 따라 1초, 5초, 10초 … exponential 하게 재시도 시간을 증가시키며 특정 작업을 반복한다.&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Aritable 의 대체 오픈소스 NocoDB]]></title><link>https://ssongey.github.io/works/posts/2023-07-30--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2023-07-30--001</guid><pubDate>Sun, 30 Jul 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;✔️ NocoDB?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Aritable 의 대체 오픈소스로, MySql, MariaDB, PostgreSql, SqlServer, Sqlite, Amazon Aurora 등 관계형 데이터베이스를 스마트 스프레드 시트로 변경하여 사용 가능한 툴이다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DB 데이터 CRUD를 위한 어드민 페이지 대체용&lt;/strong&gt;으로 아주 적합하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;h2&gt;✔️ 설치하기&lt;/h2&gt;
&lt;h3&gt;1. docker로 설치하기&lt;/h3&gt;
&lt;p&gt;1.1. docker image pull&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ docker pull nocodb/nocodb&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;1.2. docker run&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DB(&lt;code class=&quot;language-text&quot;&gt;d=nocodb&lt;/code&gt;)가 없을 경우, DB계정(&lt;code class=&quot;language-text&quot;&gt;u=user&lt;/code&gt;)은 데이터베이스 및 테이블 생성 권한이 있어야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ docker run -d --name nocodb-mysql &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
-v &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;pwd&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;/nocodb:/usr/app/data/ &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# 볼륨 마운트&lt;/span&gt;
-p &lt;span class=&quot;token number&quot;&gt;18080&lt;/span&gt;:8080 &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
-e &lt;span class=&quot;token assign-left variable&quot;&gt;NC_DB&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;mysql2://host.docker.internal:3306?u=user&amp;amp;p=user_password&amp;amp;d=nocodb&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
nocodb/nocodb:latest&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;h3&gt;2. K8S로 설치하기&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;NocoDB를 구성하기 위해서는 DB가 필요하기 때문에 mysql 컨테이너와 함께 pod를 구성하도록 한다.&lt;/li&gt;
&lt;li&gt;만약 별도로 DB가 구성되어 있다면, DB 컨테이너를 제거하고 NocoDB 컨테이너의 env 필드를 수정한다.&lt;/li&gt;
&lt;li&gt;deployment.yaml&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; apps/v1
&lt;span class=&quot;token key atrule&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Deployment
&lt;span class=&quot;token key atrule&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; noco&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;deploy
  &lt;span class=&quot;token key atrule&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; noco
  &lt;span class=&quot;token key atrule&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; noco&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;deploy
&lt;span class=&quot;token key atrule&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;selector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;matchLabels&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; noco&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;deploy
  &lt;span class=&quot;token key atrule&quot;&gt;replicas&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;minReadySeconds&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; noco&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;deploy
    &lt;span class=&quot;token key atrule&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;containers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; noco&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;mysql
          &lt;span class=&quot;token key atrule&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; mysql&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;5.7.40&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;debian &lt;span class=&quot;token comment&quot;&gt;# 상황에 맞게 이미지 주소 수정&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;imagePullPolicy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Always
          &lt;span class=&quot;token key atrule&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; MYSQL_ROOT_PASSWORD
              &lt;span class=&quot;token key atrule&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; root
          &lt;span class=&quot;token key atrule&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;containerPort&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3306&lt;/span&gt;

        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; noco&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;deploy
          &lt;span class=&quot;token key atrule&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; noco &lt;span class=&quot;token comment&quot;&gt;# 상황에 맞게 이미지 주소 수정&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;imagePullPolicy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Always
          &lt;span class=&quot;token key atrule&quot;&gt;livenessProbe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token key atrule&quot;&gt;httpGet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
              &lt;span class=&quot;token key atrule&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; /dashboard
              &lt;span class=&quot;token key atrule&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8080&lt;/span&gt;
            &lt;span class=&quot;token key atrule&quot;&gt;initialDelaySeconds&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;
            &lt;span class=&quot;token key atrule&quot;&gt;periodSeconds&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
            &lt;span class=&quot;token key atrule&quot;&gt;failureThreshold&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;resources&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token key atrule&quot;&gt;limits&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
              &lt;span class=&quot;token key atrule&quot;&gt;cpu&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
              &lt;span class=&quot;token key atrule&quot;&gt;memory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1Gi
            &lt;span class=&quot;token key atrule&quot;&gt;requests&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
              &lt;span class=&quot;token key atrule&quot;&gt;cpu&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
              &lt;span class=&quot;token key atrule&quot;&gt;memory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1Gi
          &lt;span class=&quot;token key atrule&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;containerPort&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8080&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; NC_DB
              &lt;span class=&quot;token key atrule&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; mysql2&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;//localhost&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;3306&lt;span class=&quot;token punctuation&quot;&gt;?&lt;/span&gt;u=root&lt;span class=&quot;token important&quot;&gt;&amp;amp;p=root&amp;amp;d=noco&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;h2&gt;✔️ 주요기능 사용해보기 (0.109.5 Releases 기준)&lt;/h2&gt;
&lt;h3&gt;1. Super Admin 계정 생성&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;처음 접속하면 super admin 계정을 생성하기 위한 sign up 화면이 뜬다.&lt;/li&gt;
&lt;li&gt;패스워드는 최소 8글자 및 한개 이상의 대문자, 숫자, 특수문자를 포함해야 한다.&lt;/li&gt;
&lt;li&gt;super admin 계정 생성 버튼을 누르면 계정 생성과 동시에 로그인이 되며, project 목록을 볼 수 있는 대시보드로 이동된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/3491ca6b8026663ab1c25668c0334fe7/5b712/01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 40%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABYlAAAWJQFJUiTwAAABX0lEQVQoz1WRPU4DMRCFc2MaDkFFzw2QKBA0uQACkY4CUUAQQpCA0O5md732+vcxb6yIYOnJsj3zzbzxYrIZVjSajPVrgJ14Lphk52r6Bg/Pd3h6u4GxE2IErJM4G5BLQUqMDZh9Vi0IC6HACGB13yHMSR7kbJICXz4fcXZ1jIvlEdrdF4SBbtdjGEYB17xpsvAhwUveInh2UgSSsN10SDEjZwZW4Pt2jfPLEyyvT9F3PxIpHVonMR6bbcTHJsDNRmBeG1s4F+HEQggVQAsxZrUsXLBg892h7x2S1C7SIpVzHUkpWbodBDhXoLUR8+ylSkLTJgUSzlEwJwjcjJPY8/pGN3so7bO4MVZzquVQtNKu97hdsfWsweyQu85zqoqxxh4u3vFDKc5UOzTGo+sGjOOAtjX6awoUz0ESrMvioKgldnko3vGNYnGZIeeVVPxZ7rTrXNHPOVx/Vv8L2Av4BVFlbJtCgJnaAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/3491ca6b8026663ab1c25668c0334fe7/d9199/01.png&quot;
        srcset=&quot;/devHistoryBlog/static/3491ca6b8026663ab1c25668c0334fe7/8ff5a/01.png 240w,
/devHistoryBlog/static/3491ca6b8026663ab1c25668c0334fe7/e85cb/01.png 480w,
/devHistoryBlog/static/3491ca6b8026663ab1c25668c0334fe7/d9199/01.png 960w,
/devHistoryBlog/static/3491ca6b8026663ab1c25668c0334fe7/07a9c/01.png 1440w,
/devHistoryBlog/static/3491ca6b8026663ab1c25668c0334fe7/29114/01.png 1920w,
/devHistoryBlog/static/3491ca6b8026663ab1c25668c0334fe7/5b712/01.png 2692w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;h3&gt;2. Project 생성&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;New Project&lt;/code&gt; 버튼을 클릭하여 project를 생성한다.&lt;/li&gt;
&lt;li&gt;이때 기본적으로 base DB가 생성되며, 생성된 프로젝트 내에서 기존 DB를 연결할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/eb47fb3f0d4dab48db71c0943abf5808/afa16/02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 26.666666666666668%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAw0lEQVQY04WQzQrCMBCE+/6v40Xw4knPgiIKIoreTCq0idn8jbtJKuLFhWG3w+7XaTtw5ZylwVqLvu+htQaRx3fFmNlLIF93jyeP9eqJFKsn8qxOYCmlsjSOI5RSLM1egNIJ2z3xnAtQuuzmHHG7P3A6XOHJYQrlAwNlwTnHBxETvAXG+UJYLE2BRYaJbcwLw2DLjjwHhojkVnpXh/CBERFH9y11bqqHApYu3mZHmM1NTZ9q+vLJ+CkBTb9AUrSxvfC/3uVxh7WPDpMIAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/eb47fb3f0d4dab48db71c0943abf5808/d9199/02.png&quot;
        srcset=&quot;/devHistoryBlog/static/eb47fb3f0d4dab48db71c0943abf5808/8ff5a/02.png 240w,
/devHistoryBlog/static/eb47fb3f0d4dab48db71c0943abf5808/e85cb/02.png 480w,
/devHistoryBlog/static/eb47fb3f0d4dab48db71c0943abf5808/d9199/02.png 960w,
/devHistoryBlog/static/eb47fb3f0d4dab48db71c0943abf5808/07a9c/02.png 1440w,
/devHistoryBlog/static/eb47fb3f0d4dab48db71c0943abf5808/29114/02.png 1920w,
/devHistoryBlog/static/eb47fb3f0d4dab48db71c0943abf5808/afa16/02.png 2602w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;h3&gt;3. 기존 DB 연결&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Add new table&lt;/code&gt; 옆 three-dot 메뉴버튼을 클릭하면 &lt;code class=&quot;language-text&quot;&gt;connect to new datasource&lt;/code&gt; 항목에서 연결할 DB 종류를 선택한다.&lt;/li&gt;
&lt;li&gt;연결할 DB 정보 기입 후 &lt;code class=&quot;language-text&quot;&gt;test database connection&lt;/code&gt; 버튼을 클릭하여 연결 확인 후 생성한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/c287835ff177af28d6e53d79bbed7fb8/11f80/03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 51.66666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABYlAAAWJQFJUiTwAAABH0lEQVQoz3VSy27DMAzL///RLgN22HHAfmDYtdiy1M/4Eces6caZ26YCCMcqTVGqhtNpxs+vh50XLMuCGCO0WTGdE0JI8N7VHCPEXDgJfeScbzAIaSGVK8Rrgg+UXjH+JcyuYLZF1NfHxhhM04R1XWtxng+CFAohI5aTBD7SWlVXJDCXUtrd8K6UghCiFJvrbz2G3j7J1lqYgr4luunvLErQ+aEgSXTEBAXHcdzn1gvym1GLFkEaaEjb/HfBVsGVNuYNvLd59YItl/N1hiHEMgYN5zyGNsxGnISs80lpPRRs3O3A13fEy6vG27vBx6e7FaTIKFRpyfR78eCw/1fv41awuBFSQ0oDrhs3IMZnDvPxHt63rLXHWfxDCHco+Cwu3XESYv/qTxMAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/c287835ff177af28d6e53d79bbed7fb8/d9199/03.png&quot;
        srcset=&quot;/devHistoryBlog/static/c287835ff177af28d6e53d79bbed7fb8/8ff5a/03.png 240w,
/devHistoryBlog/static/c287835ff177af28d6e53d79bbed7fb8/e85cb/03.png 480w,
/devHistoryBlog/static/c287835ff177af28d6e53d79bbed7fb8/d9199/03.png 960w,
/devHistoryBlog/static/c287835ff177af28d6e53d79bbed7fb8/07a9c/03.png 1440w,
/devHistoryBlog/static/c287835ff177af28d6e53d79bbed7fb8/29114/03.png 1920w,
/devHistoryBlog/static/c287835ff177af28d6e53d79bbed7fb8/11f80/03.png 2498w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;연결을 완료하면, 이미 생성된 테이블 및 데이터를 볼 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/7e3e5929305002fe793b2cd4206dc522/37114/04.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 26.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAuUlEQVQY051QSQoDMQzL/z9Zul1aGGbirHYc1Q6llx4KDQhHkRc5Yd8rcmYwD4gISmnYth1EESwDMXa0PtB7txxe8DzntdYPb289RCKklOFHVZGt4RET9oOsoCHljEhpwYelVJbmkazuiLRiLnUhtFZNJJTqTedqyqLorJh2V53Lib/POc2FwE14NGpDyvs+MYYiXO+M07nhcmt4PIdNFBPGWld+gL+4IBCpraA2dZplX5nNHduf/IcXRaaGOGe2+hcAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;04&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/7e3e5929305002fe793b2cd4206dc522/d9199/04.png&quot;
        srcset=&quot;/devHistoryBlog/static/7e3e5929305002fe793b2cd4206dc522/8ff5a/04.png 240w,
/devHistoryBlog/static/7e3e5929305002fe793b2cd4206dc522/e85cb/04.png 480w,
/devHistoryBlog/static/7e3e5929305002fe793b2cd4206dc522/d9199/04.png 960w,
/devHistoryBlog/static/7e3e5929305002fe793b2cd4206dc522/07a9c/04.png 1440w,
/devHistoryBlog/static/7e3e5929305002fe793b2cd4206dc522/29114/04.png 1920w,
/devHistoryBlog/static/7e3e5929305002fe793b2cd4206dc522/37114/04.png 2300w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;h3&gt;4. 계정&amp;#x26;권한&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;nocoDB는 계정 관리 및 권한 관리 기능을 가지고 있다.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Team &amp;amp; Auth&lt;/code&gt; 탭에서 사용자 생성 및 권한 부여를 할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/502e42e97baf0912a65397006de11850/0f7bd/05.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 23.75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAABYlAAAWJQFJUiTwAAAA7ElEQVQY01WQ3W7DIAyF8/4PtJu9xKTdVEpXUW35rTICTQIEzKlNt3ZDOgLbsvmOq2UhOBcwzwbbtiGlhBgTAMLbu0P9Efid0fcD2rZF0zSYpgnGGO6ZYUT8NtZiHEdUsyF4H7GuC98ev2dZCW0fOZf5kwitdak755Bzxt+TBYBTKwNVITgmio9i4CZKAYfa4+X1ikknHhCLgxBCGUpExYmIEuGzN/jqNya3qMTmvu/lV5HTF5jpGz49KaRu2ZKAyTqI/hNeeNDViksmfGD/DHzGYIJ7LCSyP6VUUdd1GIbhLt7b+XCEqhVO6owbMmmCvprUgLIAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;05&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/502e42e97baf0912a65397006de11850/d9199/05.png&quot;
        srcset=&quot;/devHistoryBlog/static/502e42e97baf0912a65397006de11850/8ff5a/05.png 240w,
/devHistoryBlog/static/502e42e97baf0912a65397006de11850/e85cb/05.png 480w,
/devHistoryBlog/static/502e42e97baf0912a65397006de11850/d9199/05.png 960w,
/devHistoryBlog/static/502e42e97baf0912a65397006de11850/07a9c/05.png 1440w,
/devHistoryBlog/static/502e42e97baf0912a65397006de11850/29114/05.png 1920w,
/devHistoryBlog/static/502e42e97baf0912a65397006de11850/0f7bd/05.png 2540w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;invite&lt;/code&gt; 버튼을 클릭하면 초대 url이 생성되며, 해당 url 을 통해 계정생성이 가능하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/721826786fd77e290fa9840f61b1dff7/e4611/06.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 35.833333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAABYlAAAWJQFJUiTwAAAA4ElEQVQoz32RbW+EIBCE7///Qd++KGCj9sQTC4oC04W7Nqm5SvJkloGdhOUGWiGEKGCMoW1bdF2XtO97KKUwzzOh/hB9KSfUdf3bH/V2DnzMD8hpxChHrJvB1fLBg3MO7/37QM4F7ptArxkGQ7X9SDqsAp9rS2e0J43efAxQxx2MN1eBHItWmNQEvX3BWA0TldAvjazku7Dj8JYC2f+BQghobWhGC6ylhsMRz8sIJ1Ifrp/cNA0Ne8E4SpqhpHCNfd9Twzucc+lTLgOzLENRFImyLFFVVdIz0c/zPNU/GZFvbpAbXqnSy9IAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;06&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/721826786fd77e290fa9840f61b1dff7/d9199/06.png&quot;
        srcset=&quot;/devHistoryBlog/static/721826786fd77e290fa9840f61b1dff7/8ff5a/06.png 240w,
/devHistoryBlog/static/721826786fd77e290fa9840f61b1dff7/e85cb/06.png 480w,
/devHistoryBlog/static/721826786fd77e290fa9840f61b1dff7/d9199/06.png 960w,
/devHistoryBlog/static/721826786fd77e290fa9840f61b1dff7/e4611/06.png 1298w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;invite url 로 접근하면 해당 계정에 대한 sign up 이 가능해진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/ac7ce11bac01168d082fd1784bcc37cc/9d53e/07.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 30.83333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABYlAAAWJQFJUiTwAAABBElEQVQY01WQzUoEMRCE8/7P42UvXj14ERYUhPWgsKxKHGcyyeSvu+xOsrPYEKanQ31dKVMrQ+v05nF8sq1PicDMSJnwbSsWV7FtAc45hBBQa90PM7VzfI6wPxmGqQMvF4f301frS7kB7URwKyHFCO89onz1roO6tgrDBxIdw8SYxFGWS9kGApEAKw8RNxellF2spe31L8aCw33A3WHF70ww25bQoeoIAmTkXAeAmyN95nWBTkvO2Own1sVjCUWck8ByM2LGTry8Bjw8+tZrrjSi0GdO0/TPZRTgx/mM1XmESE2jEWiZUqo4ypjnVYRewpdNMutABdMI/xYDab57AmNGPdM/ZhXVIFZwy/8AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;07&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/ac7ce11bac01168d082fd1784bcc37cc/d9199/07.png&quot;
        srcset=&quot;/devHistoryBlog/static/ac7ce11bac01168d082fd1784bcc37cc/8ff5a/07.png 240w,
/devHistoryBlog/static/ac7ce11bac01168d082fd1784bcc37cc/e85cb/07.png 480w,
/devHistoryBlog/static/ac7ce11bac01168d082fd1784bcc37cc/d9199/07.png 960w,
/devHistoryBlog/static/ac7ce11bac01168d082fd1784bcc37cc/07a9c/07.png 1440w,
/devHistoryBlog/static/ac7ce11bac01168d082fd1784bcc37cc/29114/07.png 1920w,
/devHistoryBlog/static/ac7ce11bac01168d082fd1784bcc37cc/9d53e/07.png 2542w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;h3&gt;5. 쿼리 API 사용&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;생성된 테이블에 대한 쿼리를 API를 사용하여 할 수 있다.&lt;/li&gt;
&lt;li&gt;api에 대한 swagger도 제공해주는데, 이는  프로젝트 → &lt;code class=&quot;language-text&quot;&gt;swagger: REST APIs&lt;/code&gt; 버튼을 클릭하면 접속할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/e1ccbde9bad849873434e3833efc80ee/50517/08.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 55.00000000000001%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABYlAAAWJQFJUiTwAAAB9UlEQVQoz3VS7Y6bMBDk/V/n/vUh2krVtbooiUJCAhiDjW3Mt6dj5yJdf3Sl0S4SHs/MOjufDfKLQS08tB4xzzOmaSIWtN3CvmPbNnSdhvUtAnaEACJ84jm/KqtrjbpSkLLHMIxY1wXLsrBvMDZesCZCpQ3GafhC9C/WwIuJzHsH5wyM0Tw84WtN0/gkJ3TbYvQj/ldumzAQmbWOVvsEpTQJVuz7TgT4ccIe1fkVP/IGUlkoqm7NgLYf0A8kmbcEP++MZEEmaotbYXDJmeXNoKwG2vPolIfiISaEC6N4u1Y41w0OlcDHo8afosSpaXHrmT8vrog758wYmwJ/Qn0qDAlxQbGUMXg/nVDLFlVEI/EQTZpF20FbSzh0fY9Ma02rHQw/eiIw2FfF/KJC3Tr8/pmjfEjciwbFTeCaV+m7EZpnfYJqqdC5mKHmhodE8tparJE2EDbkFng7zrjUCsdK41gqfBQSJ865dKjdBuEDyn58Ehpaiuri89hDSEuJpH7kVmm98Arfru8kLEn4YJYlDvdb6reuQTNayMmhMipu2SaFkTDmt6wrZlrdSBoVkg+2kzj/+g5Rlagfd4jygbIoUm/qCqoRMIyt539ZtBoJo9KoKqnct6Ry8J6PNWAyParTgRl16KRExzcphUjdaAVHh5MfMFiDv8kATJVr+HESAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;08&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/e1ccbde9bad849873434e3833efc80ee/d9199/08.png&quot;
        srcset=&quot;/devHistoryBlog/static/e1ccbde9bad849873434e3833efc80ee/8ff5a/08.png 240w,
/devHistoryBlog/static/e1ccbde9bad849873434e3833efc80ee/e85cb/08.png 480w,
/devHistoryBlog/static/e1ccbde9bad849873434e3833efc80ee/d9199/08.png 960w,
/devHistoryBlog/static/e1ccbde9bad849873434e3833efc80ee/07a9c/08.png 1440w,
/devHistoryBlog/static/e1ccbde9bad849873434e3833efc80ee/29114/08.png 1920w,
/devHistoryBlog/static/e1ccbde9bad849873434e3833efc80ee/50517/08.png 2060w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;API를 사용하기 위해서는 Authorization이 필요한데, 이는 프로젝트 → &lt;code class=&quot;language-text&quot;&gt;Team &amp;amp; Settings&lt;/code&gt; → &lt;code class=&quot;language-text&quot;&gt;API Tokens Management&lt;/code&gt; 탭에서 token을 생성하여 사용하면 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/a38007eb0e81ab79aceff835c491721b/50517/09.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 33.75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAABYlAAAWJQFJUiTwAAAA/UlEQVQoz4VQu04EMQzc//8pOmoaGiQ4UUCxT91m87ATZy72khO65kaynDiT8djDPO+IkSBSECKjFAGR4Oc3YpwKrrveCSEE5FwQU4UP0ngVjxARDNu6IaVkBSIVbJ9ixecl4vJNGOdi7957MBe4Q6wJc0WtYlwfKsjuFcOyTNi2tcmdBO0iUrHvrglRq+EvqmXpufFSM/D2XvDySvj4YjM1jOMV8+LaKNy6sRH1s44YY7RGOWcch7e6vusK1LUGMxmvlHwKruvRdleaZd0h2cgKzRqns3pv1M+PoXUTnKbRHGhBcxfs6MRn6GsZnHM2ArOOnO6C3c3/87NQ3AAnwCWKrAsJwgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;09&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/a38007eb0e81ab79aceff835c491721b/d9199/09.png&quot;
        srcset=&quot;/devHistoryBlog/static/a38007eb0e81ab79aceff835c491721b/8ff5a/09.png 240w,
/devHistoryBlog/static/a38007eb0e81ab79aceff835c491721b/e85cb/09.png 480w,
/devHistoryBlog/static/a38007eb0e81ab79aceff835c491721b/d9199/09.png 960w,
/devHistoryBlog/static/a38007eb0e81ab79aceff835c491721b/07a9c/09.png 1440w,
/devHistoryBlog/static/a38007eb0e81ab79aceff835c491721b/29114/09.png 1920w,
/devHistoryBlog/static/a38007eb0e81ab79aceff835c491721b/50517/09.png 2060w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;생성한 token 은 swagger 페이지에서 우측에 &lt;code class=&quot;language-text&quot;&gt;Authorize&lt;/code&gt; 버튼 클릭 → xcToken 에 붙여넣기 → &lt;code class=&quot;language-text&quot;&gt;Authorize&lt;/code&gt; 버튼 클릭을 하여 사용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/66582fa2d6decf08081a0895fe469560/1ffbd/10.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 57.08333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABYlAAAWJQFJUiTwAAABgElEQVQoz31SCXKDMAzk/z/MMRMI4XbAgLlsYCuJkjZpUjFiPPJ6vSvLW9cVn1LbDulY42hSJING0CtZ29mBAFjenPHwTwyrQ70MyKcG2vUoZoPUNv8dgVfXNe73O8qyRFVV0Fo/ct+bpgmm61AUBUp1h1LqKRnDe03TwDscjgiCKy6XAGmaCTEDOJnU932qpzidz5LH05mwPvI8Q5Ztmec5brcbTrTnMbhpDIZxfG97GOh2hSiKYEyHtjUf7WZE7DEzg5ZlkaZys+XjNUXbtmInDENqicY4ThtGsHg8hnMOSZJsCiWo2NoB1WTQkZJ5np8Jr1cIA8U4W1Q0AdxXa63UmDBlwph+XddLumWGXZxssuJXhaxOSGhsJsIx2Y5zJCAhcWQ5Eiv8kvi2uQn+a1nrWi5eX3G/LUdxglw19FolwkzBuJ9bOfq+3wi514YtuoeivS17pBkpDIJAFJZlhUhluOYxkjiWseE5jIiICTdcJbNW0Wjxq7OivVYSnl18AX4UT+cEZM3eAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;10&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/66582fa2d6decf08081a0895fe469560/d9199/10.png&quot;
        srcset=&quot;/devHistoryBlog/static/66582fa2d6decf08081a0895fe469560/8ff5a/10.png 240w,
/devHistoryBlog/static/66582fa2d6decf08081a0895fe469560/e85cb/10.png 480w,
/devHistoryBlog/static/66582fa2d6decf08081a0895fe469560/d9199/10.png 960w,
/devHistoryBlog/static/66582fa2d6decf08081a0895fe469560/07a9c/10.png 1440w,
/devHistoryBlog/static/66582fa2d6decf08081a0895fe469560/29114/10.png 1920w,
/devHistoryBlog/static/66582fa2d6decf08081a0895fe469560/1ffbd/10.png 2108w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;curl 을 이용할 경우, xc-token 해더값에 발급한 토큰을 넣어 사용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; -X &lt;span class=&quot;token string&quot;&gt;&apos;GET&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&apos;http://localhost:18080/api/v1/db/data/v1/elsie-project/MemberTable?limit=25&amp;amp;shuffle=0&amp;amp;offset=0&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  -H &lt;span class=&quot;token string&quot;&gt;&apos;accept: application/json&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  -H &lt;span class=&quot;token string&quot;&gt;&apos;xc-token: KDOxfcagx7dgp0XcP07Cc0gBrAvI35eJ84ipppXS&apos;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;h3&gt;6. webhook 사용&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;nocoDB에서 발생된 insert, update, delete 이벤트 감지가 필요할 경우, webhook을 이용하면 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/98169f63d3979f4e09162274d5941990/6f175/11.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 41.66666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABYlAAAWJQFJUiTwAAABK0lEQVQoz2WR207EMAxE+/8fxgMPSHwBvIF62SRt09wzjJPNCpZIo9SVczy2p5wTYkjYdYZW/HYJwXuEEBBjbHetharYd4N5nqGUwrZt7XbOw3uLl9cLb+8eU2Fi8BG7stgWBXMzcJdjUofKHWOCnBAL416olNIkhUS5VMYVE8AgR5z2hNa6PchMzDm3ByllxNSB1mbK8l+PB0wkHH5gMnuG0gSeJ2XxfMod3hzScQi+P0b9AxwisGC9BbozWJalgaWloeaYQDGhtOPcHLvJlLTPmcfQQGMEk1SWxRjTB35dVwNIW3KP5Qjw43PG17clWEwk5sa2sAF7AGXoB50dx0FAvLdGEeS4FJmjnHVdYLR6jEOM/Gt5DPd3lWeNHOlCFifuxUR3PpbSc34A0wlyT257snoAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;11&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/98169f63d3979f4e09162274d5941990/d9199/11.png&quot;
        srcset=&quot;/devHistoryBlog/static/98169f63d3979f4e09162274d5941990/8ff5a/11.png 240w,
/devHistoryBlog/static/98169f63d3979f4e09162274d5941990/e85cb/11.png 480w,
/devHistoryBlog/static/98169f63d3979f4e09162274d5941990/d9199/11.png 960w,
/devHistoryBlog/static/98169f63d3979f4e09162274d5941990/07a9c/11.png 1440w,
/devHistoryBlog/static/98169f63d3979f4e09162274d5941990/29114/11.png 1920w,
/devHistoryBlog/static/98169f63d3979f4e09162274d5941990/6f175/11.png 2036w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;아래 sample payload에 대한 테스트도 가능하니, 참고하여 이벤트 트리거를 개발하면 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/3b30f8e420d52d025468b74517b1ed92/9e7e4/12.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 25.83333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAABYlAAAWJQFJUiTwAAAA10lEQVQY042RTW7EIAxGc//bdNNzdFep3VVRW1VJSPgNGHg1GanqbsbwZDDmMzKT9459NyzLon5nWVeMEueZ9P3B+8sXT8+OdAq9CXFbSfagpaTEP6ru87EzpXQSQsRai/f+IijFbMixsX4evL4lziw0uQk66wgxU3KhaqxXoRYhGcN0auVRPWdNKIXWGrVWRL20TqcBemHE9VyCxy0r84/lCJnWG32gI+vLJ+5Z19lvy1oyOQaCtsbYeJX6b8VZpq7Zj3AJSrn6lLQdfjMq4C6RgehfjPgv9QCFVSNcZzEAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;12&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/3b30f8e420d52d025468b74517b1ed92/d9199/12.png&quot;
        srcset=&quot;/devHistoryBlog/static/3b30f8e420d52d025468b74517b1ed92/8ff5a/12.png 240w,
/devHistoryBlog/static/3b30f8e420d52d025468b74517b1ed92/e85cb/12.png 480w,
/devHistoryBlog/static/3b30f8e420d52d025468b74517b1ed92/d9199/12.png 960w,
/devHistoryBlog/static/3b30f8e420d52d025468b74517b1ed92/07a9c/12.png 1440w,
/devHistoryBlog/static/3b30f8e420d52d025468b74517b1ed92/29114/12.png 1920w,
/devHistoryBlog/static/3b30f8e420d52d025468b74517b1ed92/9e7e4/12.png 2056w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;h3&gt;7. 그외..&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;그외 더 많은 기능들을 제공하고 있으니, 더 필요한 기능들에 대해서는 아래 nocoDB 문서를 참고한다.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.nocodb.com/&quot;&gt;https://docs.nocodb.com/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[warm up 은 어떻게 수행을 하는게 가장 좋을까?]]></title><link>https://ssongey.github.io/works/posts/2023-07-10--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2023-07-10--001</guid><pubDate>Mon, 10 Jul 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;SpringBoot/Java + K8S 환경 기반에서 어떤 방식으로 웜업을 수행해야 좋을지 고민을 한 내용을 정리한다.&lt;/p&gt;
&lt;br/&gt;
&lt;h2&gt;1. 스프링부트 애플리케이션 시작 시점에 웜업 수행&lt;/h2&gt;
&lt;h3&gt;✔️ 방법&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;CommandLineRunner&lt;/code&gt; 또는 &lt;code class=&quot;language-text&quot;&gt;ApplicationRunner&lt;/code&gt; 인터페이스를 구현한 클래스에 &lt;code class=&quot;language-text&quot;&gt;@Component&lt;/code&gt; 를 선언하면, 컴포넌트 스캔 후에 override 된 run 메소드 로직이 수행된다.&lt;/li&gt;
&lt;li&gt;여기서 웜업 로직을 넣어 애플리케이션 시작시에 웜업 코드가 돌도록 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token annotation punctuation&quot;&gt;@Component&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;BeforeStartRunner&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CommandLineRunner&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token annotation punctuation&quot;&gt;@Override&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt; args&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token comment&quot;&gt;// 웜업 로직&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

또는

&lt;span class=&quot;token annotation punctuation&quot;&gt;@Component&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;BeforeStartRunner&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ApplicationRunner&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token annotation punctuation&quot;&gt;@Override&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;ApplicationArguments&lt;/span&gt; args&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token comment&quot;&gt;// 웜업 로직&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;✔️ 장점&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;애플리케이션 시작 시 무조껀 수행이 보장된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;✔️ 단점&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;로컬, 개발 페이즈 등, 웜업이 불필요한 페이즈에 대해 예외처리를 해줘야 한다.&lt;/li&gt;
&lt;li&gt;웜업이 끝나기 전까지 트래픽을 받을 수 없도록 조치가 필요하다. (ex. 로컬 메모리에 웜업 종료에 대한 플래그 저장 등)&lt;/li&gt;
&lt;li&gt;liveness probe에서 지정한 timeoutSeconds값 보다 웜업 수행 시간이 길어질 경우, liveness probe 실패로 파드 무한 재시작이 될 수 있다.&lt;/li&gt;
&lt;li&gt;그렇다고 timeoutSeconds 값을 크게주면, liveness probe 주기가 길어지게 되므로 적절하지 않다.&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;h2&gt;2. K8S Startup Probe 사용하여 웜업 수행&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Pod Probe 중 &lt;code class=&quot;language-text&quot;&gt;startupProbe&lt;/code&gt; 는 아래 그림과 같이 성공이 될때까지 다른 probe를 활성화하지 않기 때문에, 웜업을 수행하기 적절하다.&lt;/li&gt;
&lt;li&gt;만약 &lt;code class=&quot;language-text&quot;&gt;startupProbe&lt;/code&gt; 가 실패하면, kubelet이 컨테이너를 죽이고, 컨테이너는 재시작 정책에 따라 처리된다.&lt;/li&gt;
&lt;li&gt;실제, k8s 매뉴얼에도 서비스를 시작하는 데 오랜 시간이 걸리는 컨테이너가 있는 파드에 유용하다고 가이드가 되어있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/e71b16a7ec85bc1a46b34407e281e179/af777/01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 50.416666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABYlAAAWJQFJUiTwAAABcklEQVQoz31SaVPCMBDt//9hooNfVFCoFoQBaq/0SNokTdPnNtCR4XCnmW02e7236+GO9H3vtLEG22SDVRhA6gZKKrRtOzigt9b5jb6D9v5N6L4eUjVgeYZGNojiGEKIo8+NBrzxcl7l/AyiWwteK/efJQxa6THL0W9MOia8rHIpb0GK11UKXgl8TAMkYQ7JMuwnDwifp7Ba/0HuRy5OfCil0DQSXdfBGANLmlUSERNoKTDeE3QhUQuOKk3REvxjrL3NIeccURTB2g5lWRJfHLKp0dQCNZ3hPoBLKFnJ+RUaj4cHsE8f+SogbiTypEK4jmmSBotNhqRQrtOODuOabMy9RZsU2U9BXSsU6zUy34ehwp7Y7ZC+z8GWS2gyhNsEwWxDsBVevmLs0xpFnoMxhjCryZbQtBVW8y0O3zE0TZ75S8TzGQwhuLs2bronsjnBLMrCQR1t9+RqKP3ZKnSmQ14xTP0nPC4mYGXmbP3lep3F/wJ2+AkYEM7hUAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/e71b16a7ec85bc1a46b34407e281e179/d9199/01.png&quot;
        srcset=&quot;/devHistoryBlog/static/e71b16a7ec85bc1a46b34407e281e179/8ff5a/01.png 240w,
/devHistoryBlog/static/e71b16a7ec85bc1a46b34407e281e179/e85cb/01.png 480w,
/devHistoryBlog/static/e71b16a7ec85bc1a46b34407e281e179/d9199/01.png 960w,
/devHistoryBlog/static/e71b16a7ec85bc1a46b34407e281e179/07a9c/01.png 1440w,
/devHistoryBlog/static/e71b16a7ec85bc1a46b34407e281e179/29114/01.png 1920w,
/devHistoryBlog/static/e71b16a7ec85bc1a46b34407e281e179/af777/01.png 3474w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h3&gt;✔️ 장점&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;필요한 페이즈의 매니페스트에 startupProbe를 등록하면 된다.&lt;/li&gt;
&lt;li&gt;웜업이 끝나기 전까지 다른 probe가 활성화 되지 않으므로 트래픽을 받지 않는다.&lt;/li&gt;
&lt;li&gt;웜업 수행시간이 길어지게 되면, startupProbe의 timeoutSeconds 값만 수정하면 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;✔️ 단점&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;startupProbe 를 위한 api 가 필요하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;h2&gt;3. 결론&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;웜업 수행 시간이 짧다면 1번째 방법이 나쁘지 않다.&lt;/li&gt;
&lt;li&gt;하지만 트래픽이 많은 컴포넌트의 경우, 배포 실패 및 파드 무한 재시작이 일어날 수 있다.&lt;/li&gt;
&lt;li&gt;따라서 좀 더 안정적인 배포가 가능한 2번째 방법으로 선택하자.&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;참고)&lt;br&gt;
&lt;a href=&quot;https://nearhome.tistory.com/89&quot;&gt;https://nearhome.tistory.com/89&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://kubernetes.io/ko/docs/concepts/workloads/pods/pod-lifecycle/&quot;&gt;https://kubernetes.io/ko/docs/concepts/workloads/pods/pod-lifecycle/&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[docker 로그 사이즈 16k limit 에 따른 조치]]></title><description><![CDATA[fluent-concat-plugin]]></description><link>https://ssongey.github.io/works/posts/2023-01-29--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2023-01-29--001</guid><pubDate>Sun, 29 Jan 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;이번에 내가 담당하고 있던 한 서비스를 PM장비에서 K8S로 이전하는 작업을 진행하게 됐는데,&lt;br&gt;
해당 서버가 출력하고 있던 로그 사이즈가 16k 가 넘어버려서 로그가 제대로 ES에 적재되지 못하는 이슈가 발생했다.&lt;br&gt;
이에 &lt;strong&gt;fluentd concat plugin&lt;/strong&gt; 을 적용한 내용을 기록한다.&lt;/p&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;p&gt;Docker는 16k 버퍼에서 로그메시지를 받고 있기 때문에 기본적으로 16kb를 초과하는 로그 메시지를 분할한다.&lt;br&gt;
때문에 로그가 16kb가 초과했을 경우 아래와 같이 다음줄에 이어서 로그가 출력된다.  &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;k8s 환경의 container 로그

&lt;span class=&quot;token number&quot;&gt;2023&lt;/span&gt;-05-29T17:31:12.139673797+09:00 stdout F &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;log_index_type&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;stat&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;request&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;.,&lt;span class=&quot;token string&quot;&gt;&quot;service_id&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;service-A&quot;&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;2023&lt;/span&gt;-05-29T17:31:12.139673797+09:00 stdout F &lt;span class=&quot;token string&quot;&gt;&quot;service_name:&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;서비스에이&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;response&quot;&lt;/span&gt;:&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;, request_uuid: &lt;span class=&quot;token string&quot;&gt;&quot;TEST-01&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;p&gt;우리 부서에서는 로그 수집기로 Fluentd 를 사용하고 있었고, 관련 plugin 을 찾아보니 &lt;code class=&quot;language-text&quot;&gt;fluent-plugin-concat&lt;/code&gt; 이 있다는걸 알게되었다.&lt;/p&gt;
&lt;p&gt;참고: &lt;a href=&quot;https://github.com/fluent-plugins-nursery/fluent-plugin-concat&quot;&gt;https://github.com/fluent-plugins-nursery/fluent-plugin-concat&lt;/a&gt;&lt;/p&gt;
&lt;br/&gt;
&lt;h2&gt;1. fluent-plugin-concat 을 추가한 docker file  작성&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/fluent/fluentd-kubernetes-daemonset&quot;&gt;https://github.com/fluent/fluentd-kubernetes-daemonset&lt;/a&gt; 에서는 여러 fluentd-daemonset 을 제공해준다. 여기서 베이스 이미지를 선택하였다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;## v1.16.1-debian-kafka2-1.2_plugin_concat.Dockerfile&lt;/span&gt;
FROM fluentd-kubernetes-daemonset:v1.16.1-debian-kafka2-1.2

&lt;span class=&quot;token comment&quot;&gt;# Install concat plugin&lt;/span&gt;
RUN gem &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; fluent-plugin-concat

&lt;span class=&quot;token comment&quot;&gt;# Environment variables&lt;/span&gt;
ENV &lt;span class=&quot;token assign-left variable&quot;&gt;FLUENTD_OPT&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;
ENV &lt;span class=&quot;token assign-left variable&quot;&gt;FLUENTD_CONF&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;fluent.conf&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Overwrite ENTRYPOINT to run fluentd as root for /var/log / /var/lib&lt;/span&gt;
ENTRYPOINT &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;tini&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;--&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;/fluentd/entrypoint.sh&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;h2&gt;2. 어플리케이션 로깅 수정&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;concat plugin 의 usage 내용을 보면 여러 방법이 있지만, 현재 내 상황에 맞는 방법은 start, end regexp 를 사용하는 방법이라 판단하였고, &lt;strong&gt;모든 로그의 시작을 &lt;code class=&quot;language-text&quot;&gt;log_type&lt;/code&gt; 으로, 끝을 &lt;code class=&quot;language-text&quot;&gt;log_end&lt;/code&gt;로 통일&lt;/strong&gt;하였다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;k8s 환경의 container 로그

&lt;span class=&quot;token number&quot;&gt;2023&lt;/span&gt;-05-29T17:31:12.139673797+09:00 stdout F &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;log_type&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;stat&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;request&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;.,&lt;span class=&quot;token string&quot;&gt;&quot;service_id&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;service-A&quot;&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;2023&lt;/span&gt;-05-29T17:31:12.139673797+09:00 stdout F &lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;.,&lt;span class=&quot;token string&quot;&gt;&quot;log_end&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;2023&lt;/span&gt;-05-29T17:31:12.139673797+09:00 stdout F &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;log_type&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;stat&quot;&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;.,&lt;span class=&quot;token string&quot;&gt;&quot;log_end&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;h2&gt;3. config 설정&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;input&amp;#x26;parse 설정&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;로컬에서 테스트를 위한 설정 파일이므로, input을 forward 로 설정한다.&lt;/li&gt;
&lt;li&gt;실제 concat이 필요한 부분은 맨 끝 어플리케이션 로그쪽이라 구분을 위해 파싱을 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;concat 설정&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;로그의 시작과 끝의 패턴을 설정해준다.&lt;/li&gt;
&lt;li&gt;참고로, &lt;code class=&quot;language-text&quot;&gt;separator&lt;/code&gt; 은 로그를 concat 할때의 구분자이며, 기본값은 &lt;code class=&quot;language-text&quot;&gt;\n&lt;/code&gt; 이다. 따로 설정을 해주지 않으면 concat 된 두 로그 사이에 &lt;code class=&quot;language-text&quot;&gt;\n&lt;/code&gt; 값이 들어가게 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;output 설정&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;로컬에서 테스트를 위한 설정이므로 stdout으로 출력한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;## fluentd.conf&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 데이터가 위 예시와 같은 포맷으로 들어올때의 input과 parse 설정&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;source&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  @type                           http
  port                            &lt;span class=&quot;token number&quot;&gt;9880&lt;/span&gt;
  &lt;span class=&quot;token builtin class-name&quot;&gt;bind&lt;/span&gt;                            &lt;span class=&quot;token number&quot;&gt;0.0&lt;/span&gt;.0.0
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;parse&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    @type                         regexp
    expression                    /^&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;?&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;time&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;^ &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;+&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;?&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;stream&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;stdout&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;stderr&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;?&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;flags&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;^ &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;+&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;?&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;log&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;.*&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;$/
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/parse&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/source&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;#multiline start&amp;amp;end regexp&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;filter **&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  @type                           concat
  key                             log
  separator                       &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;
  multiline_start_regexp          /^&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;&quot;log_type/
  multiline_end_regexp            /log_end&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;&quot;:&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;&quot;&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;&quot;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;$/
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/filter&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;

&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;match **&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  @type stdout
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/match&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;h3&gt;4. 도커파일 빌드 후 실행&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;위에서 작성한 도커파일 빌드 후 실행한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ docker build -t fluentd-kubernetes-daemonset:v1.16.1-debian-kafka2-1.2-with_concat_plugin -f v1.16.1-debian-kafka2-1.2_plugin_concat.Dockerfile &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;

$ docker run --name fluentd &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
	-p &lt;span class=&quot;token number&quot;&gt;9880&lt;/span&gt;:9880 &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
	-v &lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;pwd&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;/fluentd.conf:/fluentd/etc/fluentd.conf &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
	-e &lt;span class=&quot;token assign-left variable&quot;&gt;FLUENTD_CONF&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;fluentd.conf &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
	fluentd-kubernetes-daemonset:v1.16.1-debian-kafka2-1.2-with_concat_plugin&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;h3&gt;5. 테스트&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;fluentd 로 보낼 테스트파일 2개를 생성한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# test1.text&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;2023&lt;/span&gt;-05-29T17:31:12.139673797+09:00 stdout F &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;log_type&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;stat&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;phase&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;beta&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# test2.text&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;2023&lt;/span&gt;-05-29T17:31:12.139673797+09:00 stdout F &lt;span class=&quot;token string&quot;&gt;&quot;level&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;INFO&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;log_end&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;ul&gt;
&lt;li&gt;먼저 test1.text 파일을 보내면 fluentd 로그에 stdout 이 나오지 않지만,&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; -X POST &lt;span class=&quot;token string&quot;&gt;&quot;http://127.0.0.1:9880/sample.test&quot;&lt;/span&gt; -d @test1.text&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;다음에 test2.text 파일을 보내면, test1.text의 로그와 함께 concat이 되어 fluentd 로그에 출력되는걸 확인할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; -X POST &lt;span class=&quot;token string&quot;&gt;&quot;http://127.0.0.1:9880/sample.test&quot;&lt;/span&gt; -d @test2.text&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/e1dafca50b6d901cd97dd0d51a9aa90c/e4d4a/Untitled.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 6.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAABCAYAAADeko4lAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAM0lEQVQI1z3IwQYAQAhF0aGSRKn//9c3tHiLw3Xf7qK7T1WxZ4YvMxERMDMSEba7Q1XPB4MfFkhxCpFzAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Untitled&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/e1dafca50b6d901cd97dd0d51a9aa90c/d9199/Untitled.png&quot;
        srcset=&quot;/devHistoryBlog/static/e1dafca50b6d901cd97dd0d51a9aa90c/8ff5a/Untitled.png 240w,
/devHistoryBlog/static/e1dafca50b6d901cd97dd0d51a9aa90c/e85cb/Untitled.png 480w,
/devHistoryBlog/static/e1dafca50b6d901cd97dd0d51a9aa90c/d9199/Untitled.png 960w,
/devHistoryBlog/static/e1dafca50b6d901cd97dd0d51a9aa90c/07a9c/Untitled.png 1440w,
/devHistoryBlog/static/e1dafca50b6d901cd97dd0d51a9aa90c/29114/Untitled.png 1920w,
/devHistoryBlog/static/e1dafca50b6d901cd97dd0d51a9aa90c/e4d4a/Untitled.png 2198w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;</content:encoded></item><item><title><![CDATA[ES Node Role 정리]]></title><link>https://ssongey.github.io/history/posts/2023-01-07--001</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2023-01-07--001</guid><pubDate>Sat, 07 Jan 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;사내 스터디로 ES 책을 보고있는데, 문득 내가 사용하고 있는 ES 들의 role 구성이 궁금했고,&lt;br&gt;
생각보다 node 들의 role 이 많아서 정리하려고 한다.&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;📢 환경&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ElasticSearch 7.17.8&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;h2&gt;✔️ 노드 role 확인&lt;/h2&gt;
&lt;p&gt;노드 정보 확인 API 를 사용하면 노드의 role 을 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/6d7d8dd2b0ecdc30b4746e24703100d0/7970d/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 21.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAxElEQVQY001P2wpFUBTcuZSEpFwSioPYORsRJQ9evPgD//8hc45V5GGamdbMai32FV84gYM8/yBN0z/nKIoCVVUhyzKUZYkoihCGIeHSFzzPQxAEiOMYSZJA0zTs+w7Gaw7btsEYI6iqSuz7PmnTNCn8niuK8njDMGihrutY1xXsuuIyd+CGZVnE7/J7qSzLj3ddF5IkYRxHsOM4ME0T6rpG0zTouo7eXZYFQggMw4C2bWl+Z+Z5pjLnHH3fY9s2ypzniR8J3WeewHL3+wAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/6d7d8dd2b0ecdc30b4746e24703100d0/d9199/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/6d7d8dd2b0ecdc30b4746e24703100d0/8ff5a/001-01.png 240w,
/devHistoryBlog/static/6d7d8dd2b0ecdc30b4746e24703100d0/e85cb/001-01.png 480w,
/devHistoryBlog/static/6d7d8dd2b0ecdc30b4746e24703100d0/d9199/001-01.png 960w,
/devHistoryBlog/static/6d7d8dd2b0ecdc30b4746e24703100d0/07a9c/001-01.png 1440w,
/devHistoryBlog/static/6d7d8dd2b0ecdc30b4746e24703100d0/7970d/001-01.png 1908w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;여기서 node.role 필드 값에 대한 정의는 아래와 같다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;✔️ 노드 role 정의&lt;/h2&gt;
&lt;h3&gt;m (master-eligible node)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;마스터, 마스터 후보 노드&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# elasticsearch.yaml

node.roles: [&amp;quot;master&amp;quot;]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;v (voting-only node)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;마스터 노드 선출을 위한 투표에는 참여하지만, 마스터 역할은 수행하지 않는 마스터 후보 노드&lt;/li&gt;
&lt;li&gt;마스터 노드에만 해당 role을 줄 수 있다.&lt;/li&gt;
&lt;li&gt;만약 장애로 마스터 노드가 3개에서 1개로 줄어 최소 마스터 노드의 수를 충족하지 못할 경우 클러스터 전체 장애로 이어지는데, 이를 방지하기 위해 낮은 스펙을 가진 voting_only 마스터 노드를 더 추가하여 마스터 후보 노드 수를 높이는 것도 괜찮을 듯 싶다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# elasticsearch.yaml
node.roles: [&amp;quot;master&amp;quot;, &amp;quot;voting_only&amp;quot;]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/6450ac93c555c71198b0bdfd722727fc/7970d/001-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 3.3333333333333335%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAABCAYAAADeko4lAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAOklEQVQI1z3JSQoAQQhD0T6aEyrizvufJUULVYtPHuQjIrg7VBXX3b1rZpgZZOZ+zLz9ripExFpEXgefVSP4d074pwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/6450ac93c555c71198b0bdfd722727fc/d9199/001-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/6450ac93c555c71198b0bdfd722727fc/8ff5a/001-02.png 240w,
/devHistoryBlog/static/6450ac93c555c71198b0bdfd722727fc/e85cb/001-02.png 480w,
/devHistoryBlog/static/6450ac93c555c71198b0bdfd722727fc/d9199/001-02.png 960w,
/devHistoryBlog/static/6450ac93c555c71198b0bdfd722727fc/07a9c/001-02.png 1440w,
/devHistoryBlog/static/6450ac93c555c71198b0bdfd722727fc/7970d/001-02.png 1908w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h3&gt;d (data node)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;데이터 CRUD, 인덱싱, 검색 및 집계를 처리&lt;/li&gt;
&lt;li&gt;multi-tier architecture 에서 사용할 수 있는 특수 데이터 역할이 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# elasticsearch.yaml

node.roles: [ &amp;quot;data&amp;quot;]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;s (data content node)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;contents 를 저장하는 노드로, product catalog or article archive 와 같은 데이터를 CRUD, 검색 및 집계 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# elasticsearch.yaml

node.roles: [ &amp;quot;data_content&amp;quot;]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;h (data hot node)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;자주 업데이트되는 시계열 데이터를 저장하는데 사용&lt;/li&gt;
&lt;li&gt;검색 및 인덱싱이 모두 빨라야하므로 많은 CPU, RAM 및 빠른 storage를 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# elasticsearch.yaml

node.roles: [ &amp;quot;data_hot&amp;quot;]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;w (data warm node)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;쿼리 빈도가 낮고 거의 업데이트되지 않는 시계열 데이터를 저장하는데 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# elasticsearch.yaml

node.roles: [ &amp;quot;data_warm&amp;quot;]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;c (data cold node)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;더 이상 정기적으로 검색할 필요가 없는 시계열 데이터는 warm에서 cold로 이동&lt;/li&gt;
&lt;li&gt;검색 성능이 우선이 아니기 때문에 일반적으로 CPU, RAM 대비 큰 storage를 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# elasticsearch.yaml

node.roles: [ &amp;quot;data_cold&amp;quot;]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;f (data frozen node)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;거의 쿼리되지 않고 더이상 업데이트되지 않는 데이터는 cold에서 frozen으로 이동&lt;/li&gt;
&lt;li&gt;해당 노드는 적은 비용으로 frozen 된 데이터를 운영하기 위함이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# elasticsearch.yaml

node.roles: [ &amp;quot;data_frozen&amp;quot;]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;i (ingest node)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;인덱싱에 전처리가 필요한 경우 사용&lt;/li&gt;
&lt;li&gt;스택 모니터링 및 수집 파이프라인에는 ingest역할이 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# elasticsearch.yaml

node.roles: [ &amp;quot;ingest&amp;quot;]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;(coordinating node only)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;사용자 요청을 데이터 노드로 전달하고, 그 결과를 취합하는데 사용&lt;/li&gt;
&lt;li&gt;기본적으로 모든 노드에 coordinating role을 가지고 있지만, 운영시에는 모든 사용자 요청은 coordinating only 노드로만 가도록 하여 다른 role을 가진 노드(master, data 등..)의 부하를 줄이도록 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# elasticsearch.yaml

node.roles: []&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/cf711803b49866b9cfeecdec6b3e5066/3e992/001-03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 3.3333333333333335%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAABCAYAAADeko4lAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAOklEQVQI1z2KuQkAMAwDM5Y//IA77z+PglOkEKdDOsyMzISZgYhQVehuuPvLzLxtfyLyqarfty8jAhdWRCIhXQTpfwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/cf711803b49866b9cfeecdec6b3e5066/d9199/001-03.png&quot;
        srcset=&quot;/devHistoryBlog/static/cf711803b49866b9cfeecdec6b3e5066/8ff5a/001-03.png 240w,
/devHistoryBlog/static/cf711803b49866b9cfeecdec6b3e5066/e85cb/001-03.png 480w,
/devHistoryBlog/static/cf711803b49866b9cfeecdec6b3e5066/d9199/001-03.png 960w,
/devHistoryBlog/static/cf711803b49866b9cfeecdec6b3e5066/07a9c/001-03.png 1440w,
/devHistoryBlog/static/cf711803b49866b9cfeecdec6b3e5066/3e992/001-03.png 1902w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h3&gt;l (machine learning node)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ES에서 제공하는 머신러닝 기능이 필요한 경우 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# elasticsearch.yaml

node.roles: [&amp;quot;ml&amp;quot;]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;r (remote cluster client node)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;다른 클러스터와의 검색이나 복제 등을 수행&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# elasticsearch.yaml

node.roles: [&amp;quot;remote_cluster_client&amp;quot;]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;t (transform node)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;기존 인덱스를 변환하거나 insight 및 요약된 데이터 분석 등의 api 요청을 수행&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# elasticsearch.yaml

node.roles: [&amp;quot;transform&amp;quot;]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;모든 롤을 가진 node 설정 방법&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# elasticsearch.yaml

# 아무런 설정을 하지 않는다. (default)
# node.roles: []&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/b196e0f8b527495c527eda21f8bb426c/3e992/001-04.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 3.3333333333333335%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAABCAYAAADeko4lAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAOUlEQVQI102LywkAMAjFOpfgB7yq4P7DvGKhpYccEsgSEUQEzAxEhMxEVR13d3Q3VBXM/Jjnb+OXDYwyIzs8V0jlAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 04&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/b196e0f8b527495c527eda21f8bb426c/d9199/001-04.png&quot;
        srcset=&quot;/devHistoryBlog/static/b196e0f8b527495c527eda21f8bb426c/8ff5a/001-04.png 240w,
/devHistoryBlog/static/b196e0f8b527495c527eda21f8bb426c/e85cb/001-04.png 480w,
/devHistoryBlog/static/b196e0f8b527495c527eda21f8bb426c/d9199/001-04.png 960w,
/devHistoryBlog/static/b196e0f8b527495c527eda21f8bb426c/07a9c/001-04.png 1440w,
/devHistoryBlog/static/b196e0f8b527495c527eda21f8bb426c/3e992/001-04.png 1902w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;p&gt;&lt;strong&gt;참고)&lt;/strong&gt;&lt;br&gt;
&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-node.html&quot;&gt;https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-node.html&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://opster.com/guides/elasticsearch/data-architecture/how-to-configure-all-elasticsearch-node-roles/#Master-node&quot;&gt;https://opster.com/guides/elasticsearch/data-architecture/how-to-configure-all-elasticsearch-node-roles/#Master-node&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://jeongxoo.tistory.com/12&quot;&gt;https://jeongxoo.tistory.com/12&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[무료 사용 가능한 오픈렌즈(OpenLens) 설치 방법]]></title><link>https://ssongey.github.io/history/posts/2022-12-22--001</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2022-12-22--001</guid><pubDate>Thu, 22 Dec 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;너무너무 잘 사용하던 Lens가 2023년 1월 2일 이후로는 기업에서 유료화가 된다고 한다.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://medium.com/k8slens/lens-6-released-vision-for-the-future-new-subscription-model-and-features-available-628ff21fe14a&quot;&gt;https://medium.com/k8slens/lens-6-released-vision-for-the-future-new-subscription-model-and-features-available-628ff21fe14a&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://medium.com/k8slens/lens-6-released-vision-for-the-future-new-subscription-model-and-features-available-628ff21fe14a&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;하지만 &lt;strong&gt;개인용, 교육용, 스타트업(연매출 또는 자금 1,000만 달러 미만) 은 무료&lt;/strong&gt;라고 하니..&lt;br&gt;
개인 노트북에서는 계속 사용해도 될 듯 싶다.&lt;/p&gt;
&lt;p&gt;다만 기존 오픈소스는 ‘오픈렌즈(OpenLens)‘로 이름을 바꿔 유지되고, ‘MIT 라이선스’ 이니, 무료로 사용이 가능하다.&lt;br&gt;
오픈렌즈를 설치하는 방법은 아래와 같다.&lt;/p&gt;
&lt;h3&gt;✔️ MacOS - Homebrew&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; --cask openlens&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;✔️ Windows - Scoop&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;scoop bucket &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; extra
scoop &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; openlens&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;또는 아래 오픈렌즈 깃헙에서 빌드된 파일을 받아 설치해도 된다.&lt;br&gt;
&lt;a href=&quot;https://github.com/MuhammedKalkan/OpenLens&quot;&gt;https://github.com/MuhammedKalkan/OpenLens&lt;/a&gt;&lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;참고로, 오픈렌즈에서는 pod 메뉴가 없다.(pod 로그 보기 등.. 불가능)&lt;br&gt;
이를 사용하려면 extension을 설치해야한다.&lt;/p&gt;
&lt;h3&gt;✔️ 설치 방법&lt;/h3&gt;
&lt;p&gt;메뉴 &gt; extensions &gt; 설치란에 &lt;code class=&quot;language-text&quot;&gt;@alebcay/openlens-node-pod-menu&lt;/code&gt; 입력 후 install 버튼 클릭&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Unable to acquire JDBC Connection 에러 오답노트2]]></title><description><![CDATA[DHCP lease lost]]></description><link>https://ssongey.github.io/works/posts/2022-12-09--002</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2022-12-09--002</guid><pubDate>Fri, 09 Dec 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;이전글)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://ssongey.github.io/devHistoryBlog/works/posts/2022-12-09--001&quot;&gt;Unable to acquire JDBC Connection 에러 오답노트1&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;현재글)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Unable to acquire JDBC Connection(DHCP lease lost) 에러 오답노트2&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;h2&gt;✔️ 문제 재확인&lt;/h2&gt;
&lt;p&gt;어플리케이션의 문제는 아닌듯 보여 VM 장비로 포커스를 맞춰 문제를 다시 파악했다.&lt;br&gt;
여러 VM의 어플리케이션 로그들을 키바나에서 보고 있어서 몰랐는데, 자세히 보니 특정 패턴이 보였다.&lt;br&gt;
각 장비마다 &lt;strong&gt;매일 특정 시간대에 connection 에러를 발생&lt;/strong&gt;시키고 있었다..!!!&lt;br&gt;
즉, 1번 워커노드의 서버는 매일 대약 2시쯤, 2번 워커노드의 서버는 매일 대략 3시 반쯤 등 timeout 오류를 발생시키고 있었다.&lt;/p&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;p&gt;열심히 인사이트를 찾아보다가 syslog를 확인하게 되었는데,&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# syslog 위치 (나는 무슨 문제였는지 몰랐기 때문에 syslog 내용을 확인 하였다.)&lt;/span&gt;
$ ll /var/log/syslog*&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;아래와 같이 systemd-networkd 에서 &lt;strong&gt;eth0: DHCP lease lost&lt;/strong&gt; 가 발생이 되고 있다는 걸 알게 되었다.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/227992d3eb72343b5578cb6c9992d803/7ca1f/002-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 52.083333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABYlAAAWJQFJUiTwAAAB80lEQVQoz21SaW/aQBA1CBFuE2x8rm+DA6jiCNjG0NAcbaJ+rBQpitqq//9PvM4sUVRF/TCaebs7b97MrPJye8KPY4Vfjw94ufuC14dbPJ8+k7+T+PfTV3n25/sj2RN+fju/2xcFirJEQb4kn+c5VqsVFHV4iebFBUzLwkjToBsG+oMBDNOU2HYcqMMh9PEYjuu+x6qqolarSavX61AURcYKJ2i6jjCKYNk2hPBgEpnwPEkWxbEsxjhNUxnzPRMyyb/W7XahJL4H37aQUWLkCUyjEB4lTeMIie9jPkkJm0iDQMYBFfWp0JCUfiRst9tQcuFgaejYBx62roXcc7GxDRS+kPiYhBS75CPcTGLsQ3onbGijEQakUn2zXq93JrQdF5d0yS1zW+y5LfYeKUwnExiEE2o3u7qSYwnCEA6p7Pf7koh9p9M5E1o0D5YvhMCYhm1Tsk4zdSjRoAUFRMqY72MqwsoYM8F/W+ZqriuQZRl8SuYl8DLiJJFKpnRus6qA4mn2tjiBERF/JJRFluMRskFXzmtl6thYY3zShrh2TJqthuJ9pi6q0MeO3i3p3YDabLVa0lhZs9lEo9GAcn864VgWuKkqFNcbVEWO7XqFA/lyu5Xnu/UaFX3c0+GALX3eMt9hvdlgsVhgNpthPp/LDvlb/QWUxQ0pe23OpgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/227992d3eb72343b5578cb6c9992d803/d9199/002-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/227992d3eb72343b5578cb6c9992d803/8ff5a/002-01.png 240w,
/devHistoryBlog/static/227992d3eb72343b5578cb6c9992d803/e85cb/002-01.png 480w,
/devHistoryBlog/static/227992d3eb72343b5578cb6c9992d803/d9199/002-01.png 960w,
/devHistoryBlog/static/227992d3eb72343b5578cb6c9992d803/07a9c/002-01.png 1440w,
/devHistoryBlog/static/227992d3eb72343b5578cb6c9992d803/7ca1f/002-01.png 1890w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;참고) systemd-networkd 로그만 확인하는 방법&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ journalctl -u systemd-networkd&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;p&gt;즉!! &lt;strong&gt;VM에서 커넥션 종료&lt;/strong&gt;를 시켰고, 어플리케이션 서버에서는 이를 전혀 감지하지 못하고 &lt;strong&gt;dead connection 을 가지고 요청을 수행&lt;/strong&gt;하려다가  결국 타임아웃 에러가 발생 한 것이다.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/0b14f90493521ee2b3a2db37eb2e00d2/81ebd/002-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 33.33333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAABYlAAAWJQFJUiTwAAABQUlEQVQoz3WR627CMAyFeX4kXgEeaPxAmioVEGyjpJckTWjTtFpLe2Y3DG2TZsnqxcffsZOFcw5pmkIpCdc0qLSG/3hD837C2LXguN/vqKoKdV1DzFqFmr4b0nNM04TvWHjvkSQJijxH13WwskB9OsD/AA7DMMMYwFopJb27/4F5lkEUGpmhCUSK8VE8HI4ziBt4woa14joD9c2ha4Nh3/eI4xi87aKln6kQSAh4zgyi1xjlQLCrwmq1wnb7MjdZa+FJq1IBTStLW6P1YUI2WC6X2O12YUJBrpdc4ZxbnI5neNpA6AqbzQZRFP0CyuQCmRcorCOgf9bW6zX2+30AsoPSJWxVz8UQE8ZxfF4Kr8OXJslcK40bHUX7WDmoH2fIgLIsYUxIbvx70Ay0xlDdQJO5y9M5fZGhtwaftqQn5c3gC5GrEl0CJH88AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/0b14f90493521ee2b3a2db37eb2e00d2/d9199/002-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/0b14f90493521ee2b3a2db37eb2e00d2/8ff5a/002-02.png 240w,
/devHistoryBlog/static/0b14f90493521ee2b3a2db37eb2e00d2/e85cb/002-02.png 480w,
/devHistoryBlog/static/0b14f90493521ee2b3a2db37eb2e00d2/d9199/002-02.png 960w,
/devHistoryBlog/static/0b14f90493521ee2b3a2db37eb2e00d2/07a9c/002-02.png 1440w,
/devHistoryBlog/static/0b14f90493521ee2b3a2db37eb2e00d2/81ebd/002-02.png 1868w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;h3&gt;Hikari Pool 에서 타임아웃 에러가 발생한 이유는 아래와 같다.&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;DB 수행이 필요한 요청이 들어온다.&lt;/li&gt;
&lt;li&gt;Connection Pool에서 커넥션을 가져온다.&lt;/li&gt;
&lt;li&gt;Hikari CP에서 가져온 커넥션에 대한 validation을 진행한다. 이때, &lt;strong&gt;validation timeout은 default로 5초이다.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DHCP lease lost 때문에 dead connection으로 validation에 실패하게 되고(5초 소요)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;해당 커넥션을 종료시키고 &lt;strong&gt;다시 2번부터 수행한다.&lt;/strong&gt; (커넥션을 종료하면 Pool의 개수를 맞추기 위해 hikari 의 housekeeper 스레드에서 새로운 커넥션을 생성하여 pool에 넣는다.)&lt;/li&gt;
&lt;li&gt;2-5번을 반복하며 vaildation을 하는데 시간을 계속 소비하여 available 한 커넥션을 찾지 못하고, 결국 db connetion timout 에러가 발생하게 된다. (기본 db connection timeout 시간은 30초이다. : spring.datasource.hikari.connectionTimeout )&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/40b2ae00d620a480f3f444024ab89f03/555cf/002-03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 82.91666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAYAAADdRIy+AAAACXBIWXMAABYlAAAWJQFJUiTwAAACBklEQVQ4y6WU25KiQBBE/f9/MzY0FBTQcFQuIgqKIF5r+rRbrjKz8zIdUUADnZ2ZldA5n89SVZVwZiyXSxkOhzIajcRxHImiSNbrtaRp+qw4jmWxWNh35/O5rFYru/Z+v0unKArxPE9ms5kcDgcLst1uZbfbyX6/l+v1autyudhihGEog8FAxuOx3bzb7VowRofD8XgUgLMsE9d1n7sBoMx1cD8IAplOp5IkiUSGLeBPhoqsN2DHmQ243mw2lnnTNHI6nez1xACGWBGFsl+nEkwmCvBgqKCwUT/wChuQh494hpfIL8vSbJaL0+9LGi7FNxsAdm8DIpFFDBghCaYA4OntdrPP8jy3jWwqw9z47Pn+P8ltQLqGLAC0Odogimeo8A3I7ONDfCMX39+aohPOLIaVAnHdLr0PU4r5G+BrU34z3iQrGL4RCxoyMXLocpupWqAq8PhbDzEdEDpK0V1exjf1lWbwTq/Xs8Emg1+C/doUGGmEmJM9zaAOPj1UOKYZdBjw/3aZ/MEUs4kQxRdEIZNnaoHvDiWPIxv0HwEZLAYEQGVY17UFJE7loZKsMDaYgPdcX5qrRfo+2MwBQxqZ468CCD4Whl1iWJV1I/24FC+r5Y8byOWR+a+A+um9esfP4zVSSE6SlSRZbt8PvPFDchsQOXQWdjRHC3bqo9pg/4d/04ACxfgEeK8XD9LzWlAAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002 03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/40b2ae00d620a480f3f444024ab89f03/d9199/002-03.png&quot;
        srcset=&quot;/devHistoryBlog/static/40b2ae00d620a480f3f444024ab89f03/8ff5a/002-03.png 240w,
/devHistoryBlog/static/40b2ae00d620a480f3f444024ab89f03/e85cb/002-03.png 480w,
/devHistoryBlog/static/40b2ae00d620a480f3f444024ab89f03/d9199/002-03.png 960w,
/devHistoryBlog/static/40b2ae00d620a480f3f444024ab89f03/07a9c/002-03.png 1440w,
/devHistoryBlog/static/40b2ae00d620a480f3f444024ab89f03/29114/002-03.png 1920w,
/devHistoryBlog/static/40b2ae00d620a480f3f444024ab89f03/555cf/002-03.png 1960w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;p&gt;DHCP 현상에 대한 인프라팀 답변으로는, 생성된 VM 들은 DHCP 기반으로 IP를 할당받도록 되어 있었고, DHCP 갱신을 24시간 주기로 수행하며 갱신하는 시점에 순간 네트워크 설정이 reset 되면서 기존 연결이 무효화가 되어 DB처럼 커넥션을 연결해놓고 사용하는 경우에는 해당 문제가 발생했다고 한다.&lt;/p&gt;
&lt;br/&gt;
&lt;hr&gt;
&lt;h2&gt;✔️ 문제를 확인 했으니, 조치를 해보자&lt;/h2&gt;
&lt;p&gt;ubuntu 18.04 기준으로 &lt;strong&gt;/etc/netplan/50-cloud-init.yaml&lt;/strong&gt; 파일에 &lt;strong&gt;critical: true&lt;/strong&gt; 필드를 추가 후 apply 하면 된다.&lt;/p&gt;
&lt;h3&gt;1. 설정파일 수정&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# /etc/netplan/50-cloud-init.yaml&lt;/span&gt;
network:
    ethernets:
        eth0:
            dhcp4: &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
            critical: &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;#추가&lt;/span&gt;
            match:
                macaddress: fa:&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;.
            set-name: eth0
    version: &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;2. 설정파일 적용&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; netplan apply&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;p&gt;당일에는 DHCP 갱신이 이미 발생이 된 후라 다음날 확인을 해보니, 더이상 connection 오류가 발생하지 않았다.&lt;/p&gt;
&lt;p&gt;어휴! 이슈 해결하느라 고생한 나 자신 칭찬한다.&lt;/p&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;p&gt;참고)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;dhcp란?&lt;br&gt;
&lt;a href=&quot;https://jwprogramming.tistory.com/35&quot;&gt;https://jwprogramming.tistory.com/3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;dhcp ip 대여시간&lt;br&gt;
&lt;a href=&quot;https://points.tistory.com/15&quot;&gt;https://points.tistory.com/15&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;dhcp message type&lt;br&gt;
&lt;a href=&quot;http://www.ktword.co.kr/test/view/view.php?m_temp1=5419&amp;#x26;id=1244&quot;&gt;http://www.ktword.co.kr/test/view/view.php?m_temp1=5419&amp;#x26;id=1244&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;라우터 vs 공유기&lt;br&gt;
&lt;a href=&quot;https://m.blog.naver.com/PostView.naver?blogId=msnayana&amp;#x26;logNo=80105365859&amp;#x26;proxyReferer=&quot;&gt;https://m.blog.naver.com/PostView.naver?blogId=msnayana&amp;#x26;logNo=80105365859&amp;#x26;proxyReferer=&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;configuring dhcp lease&lt;br&gt;
&lt;a href=&quot;https://serverfault.com/questions/1022612/configuring-dhcp-lease-when-using-systemd-networkd-on-ubuntu-18-04-server&quot;&gt;https://serverfault.com/questions/1022612/configuring-dhcp-lease-when-using-systemd-networkd-on-ubuntu-18-04-server&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Unable to acquire JDBC Connection 에러 오답노트1]]></title><description><![CDATA[Connection is not available, request timed out after 5000ms]]></description><link>https://ssongey.github.io/works/posts/2022-12-09--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2022-12-09--001</guid><pubDate>Fri, 09 Dec 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;현재글)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Unable to acquire JDBC Connection 에러 오답노트1&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;다음글)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://ssongey.github.io/devHistoryBlog/works/posts/2022-12-09--002&quot;&gt;Unable to acquire JDBC Connection&lt;strong&gt;(DHCP lease lost)&lt;/strong&gt; 에러 오답노트2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;p&gt;내가 담당하고 있는 서비스에서 간헐적으로 DB Connection이 끊기는 현상이 발생했다.&lt;br&gt;
처음에는 단순히 DB Connection Pool 의 개수가 모자른가? 라고 생각했었지만, 생각치도 못했던 여러 문제를 접하였고, 그에 대한 오답노트를 적어보려고 한다.  &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;📢 환경
- Ubuntu 18.04.5 LTS
- SpringBoot 2.5.12
- MySQL 5.7.28&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;h2&gt;✔️ 1. 문제 확인&lt;/h2&gt;
&lt;p&gt;DB에서 데이터를 꺼내기 위해 커넥션을 사용하려고 하는데, 설정된 timeout 시간까지 커넥션 풀에서 사용 가능한 커넥션을 못찾아 에러가 발생하였다.
stack trace 를 보면 아래와 같다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;DataAccessResourceFailureException

Unable to acquire JDBC Connection; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to acquire JDBC Connection


JDBCConnectionException

Unable to acquire JDBC Connection


SQLTransientConnectionException

HikariPool-1 - Connection is not available, request timed out after 15016ms.


SQLNonTransientConnectionException

No operations allowed after connection closed.

...&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;p&gt;처음 저 에러를 접했을때, 오잉? &lt;strong&gt;Connection Pool Size 가 작은가??&lt;/strong&gt; 해당 서버에 요청이 많아졌나..?? 라고 생각했고, 단순하게 Pool Size만 늘리는 조치를 취했지만… 해당 에러는 계속 발생했다.  &lt;/p&gt;
&lt;br&gt;
&lt;p&gt;그래서 열심히 구글에 검색을 해보니, 아래와 같은 키워드를 발견하였다.&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;✔️ MySQL - wait_time&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;jdbc, odbc, php 등을 통한 커넥션 중 요청이 없는 커넥션(non-interactive 세션) 의 최대 수명시간&lt;/li&gt;
&lt;li&gt;기본값은 28800s (8시간) 이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;strong&gt;✔️ Hikari - max-lifetime&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;커넥션 풀에서 사용하지 않은 커넥션의 최대 수명시간&lt;/li&gt;
&lt;li&gt;사용 후 반환 됐을때부터 wait 시간을 측정하게 된다.&lt;/li&gt;
&lt;li&gt;풀 전체가 아닌 커넥션 별로 적용이 되는 이유는 풀에서 한번에 많은 커넥션들이 제거되는 것을 방지하기 위함이라고 한다.&lt;/li&gt;
&lt;li&gt;0으로 설정하면 infinite lifetime이 적용된다.&lt;/li&gt;
&lt;li&gt;기본값은 1800000ms (30분) 이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;만약, &lt;strong&gt;wait_time &amp;#x3C; max-lifetime&lt;/strong&gt; 일 경우 커넥션 풀에 존재하는 모든 커넥션이 &lt;strong&gt;유효한 커넥션이 아닐 수도 있게된다&lt;/strong&gt;.&lt;br&gt;
왜냐면, wait_time 시간이 지난 커넥션들은 &lt;strong&gt;DB서버에서 먼저 연결을 끊기 때문&lt;/strong&gt;이다.&lt;br&gt;
때문에 풀은 이걸 모르고 계속 가지고 있다가 어플리케이션에서 요청하면 유효하지 않은 커넥션을 계속 주게 될 수도 있다는거다.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/1f1bddb41e04d59da99d449fa7d5bf7e/098c1/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 106.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAVCAYAAABG1c6oAAAACXBIWXMAABYlAAAWJQFJUiTwAAABwklEQVQ4y6WU607CQBCFfW0VfRp+kBD+Eokx0WiMLwAJpCLQlt7pDWih7R5nFjRAAGndZLPJ7ubszJxv5woHQwgh1zzPYds21MkEvj+T+2Ln/HD9GVenBJMkged5ME0LtjtDQQ/wKIoccRwfFftTMI4jGKYJL1ogTDK5ryifaDQaMAxj+0BxmWCapgiCAJOJCieI4S3WCGj/4eUdtzfX6Ha75QXDMMRoPIbpzxGmOVZ01KcIO50OXNctV8PlcilN8X0fYRRtayiO3r1IkNfVaiWFsyzbc5nTLO0yY8NpaaqKkGopBcU/sXEdB5o+3cNGiEJGXQGbVPJmEjYuYRMQNuwnm1Kv18tjwxGyy5quwyZsfMImJhQfn19xV6tVw4Y5HI9GiBwb85mH0DKhDvpot9vVsLEsCw7VkVNnfDRNQ7KtX+kaciqMy+5cr9fIyJxK2PD6YwrX89y9i1PWKcXhcIipYe50m+L3gdLdJqIvp0+nsIINNiw5/PpCs9mU37I02CzI0dnbbrOg/ae3D9zf1dDr9apxqBOHi/kcebbph4N+H61WS9a2UrdRFOX3V4gTdy8SZEzYZU6beeQHeHLk57D5BnldZRwCaMR0AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/1f1bddb41e04d59da99d449fa7d5bf7e/d9199/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/1f1bddb41e04d59da99d449fa7d5bf7e/8ff5a/001-01.png 240w,
/devHistoryBlog/static/1f1bddb41e04d59da99d449fa7d5bf7e/e85cb/001-01.png 480w,
/devHistoryBlog/static/1f1bddb41e04d59da99d449fa7d5bf7e/d9199/001-01.png 960w,
/devHistoryBlog/static/1f1bddb41e04d59da99d449fa7d5bf7e/07a9c/001-01.png 1440w,
/devHistoryBlog/static/1f1bddb41e04d59da99d449fa7d5bf7e/098c1/001-01.png 1578w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;hr&gt;
&lt;br/&gt;
&lt;h2&gt;✔️ 2. 문제를 확인 했으니, 조치를 해보자&lt;/h2&gt;
&lt;h3&gt;1. 각 설정값 확인&lt;/h3&gt;
&lt;p&gt;MySQL의 wait_timeout 을 확인해보니 &lt;strong&gt;기본값인 8시간&lt;/strong&gt;이다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sql&quot;&gt;&lt;pre class=&quot;language-sql&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;show&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;global&lt;/span&gt; variables &lt;span class=&quot;token operator&quot;&gt;like&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;wait_timeout&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/e834e19eebd2da39b46dc59b0b91ead3/f213e/001-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 31.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABYlAAAWJQFJUiTwAAAA8ElEQVQY04WRu4qEQBBFfYIgKqggGpiZGIqfYOALERVN/ALBP1dBI8Xg7lbD7M4ws2zD7VtUFae6KQ7f57ouTNOEJEmQpinKskRRFMwpV1UVE9VIeZ4jyzLWQ3nyfd8JBY6u8zwRhiE4joMsyxBFkbkgCCwmp9pfop51XV+BURRBVVU4jgPTNGFZFjRNg23bMAwDkiSB53kGJz1iAuq6/g6M45gBCea6LmtSFAW+78PzvJ+XP4uGEJAGbtv2CgyC4ONX/vvuQ8uy/ALv+8Y8z6jrGl3XMfV9j3EcMQwDmqZhS6BlPIuWQUtq2xbHcTDgFzen4UnQvlPQAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/e834e19eebd2da39b46dc59b0b91ead3/d9199/001-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/e834e19eebd2da39b46dc59b0b91ead3/8ff5a/001-02.png 240w,
/devHistoryBlog/static/e834e19eebd2da39b46dc59b0b91ead3/e85cb/001-02.png 480w,
/devHistoryBlog/static/e834e19eebd2da39b46dc59b0b91ead3/d9199/001-02.png 960w,
/devHistoryBlog/static/e834e19eebd2da39b46dc59b0b91ead3/f213e/001-02.png 1192w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;오잉??&lt;br&gt;
application.yaml 파일에도 max-lifetime을 설정하지 않았는데.. 그럼 &lt;strong&gt;기본값이니 30분일 텐데&lt;/strong&gt;.. 충분히 작은데..?&lt;br&gt;
그럼 max-lifetime을 10분으로 설정해서 max-lifetime에 새로 연결을 맺는지 한번 확인해보자.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/f446da8155c52e665344adbf5b71522d/891d5/001-03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 39.166666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABYlAAAWJQFJUiTwAAABfElEQVQoz3WSzW7aQBSF8xgVQg0EYxxmxsY2DuanRjEuKnThn5JWfQPeCAUWlbrohrcDlsDXMVVTtQ0jHd0Zaea75+jOzfF4pFw/vn9j7Fl8HAeMwgDX9fC86/J9HyEEaZqy3+8vjPP5zM1v4OZ5hai/IXJNfGkiWw2UZWAYBo1G4z81m02q1SpxHLPb7S6M0+n0B/i83mA175j0Hd6HirinGHQdpFIIKZH/yLZtTNNkPp+/DtxsNry9rdHzbCYPgnGgUEo/Fm1sKVA6ntJV6iqkujQq3c9ms2sO19RrtcvlgSd4DASx1sgXuoEkdAVRV9L3FF74Dsf1MXT0q8C1Bt7V6zqKw8CXTHTk0mWkVZ5LWPLQJvLv6XRcwniGdAMN/PAylL+Aq9WKSqWC2bIYOiajjknfNhnq+uiXg2rR6fYIogQ7GGLdt7nViZIked3hdrtlOp2S5zlPRcoi/6Vy/+VTRpFnZMWC4vNXisUTWZYy13GXyyWHw+Hl2/wER2xo6rOHf6oAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/f446da8155c52e665344adbf5b71522d/d9199/001-03.png&quot;
        srcset=&quot;/devHistoryBlog/static/f446da8155c52e665344adbf5b71522d/8ff5a/001-03.png 240w,
/devHistoryBlog/static/f446da8155c52e665344adbf5b71522d/e85cb/001-03.png 480w,
/devHistoryBlog/static/f446da8155c52e665344adbf5b71522d/d9199/001-03.png 960w,
/devHistoryBlog/static/f446da8155c52e665344adbf5b71522d/07a9c/001-03.png 1440w,
/devHistoryBlog/static/f446da8155c52e665344adbf5b71522d/891d5/001-03.png 1520w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;h3&gt;2. 설정 내용 실제 동작 확인&lt;/h3&gt;
&lt;p&gt;참고) Hikari Pool 로그를 보기 위해 logback-spring.xml 를 아래와 같이 설정해야 한다. (logback 기준)&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/d5938c8cd4d2f167a99b7fc19fca64d9/a878e/001-04.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 10.416666666666668%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAACCAYAAABYBvyLAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAgUlEQVQI11WKTQrCMBSEe54uNH9GEitu3FbwvYBdiUXwCNZbFOp16j63Gl+zEFx8fDPMVO9pRH+94NEvdLjfOnBiEJ1BTGL6OaX0lxeYWSC0pxY5Z1TD6wlrNfbR4HhwaHYBG++g7RrGKbEqNvIJIZSujSo5xgi/9bJr1Ksa82fGFxYqTIaf0hNEAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 04&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/d5938c8cd4d2f167a99b7fc19fca64d9/d9199/001-04.png&quot;
        srcset=&quot;/devHistoryBlog/static/d5938c8cd4d2f167a99b7fc19fca64d9/8ff5a/001-04.png 240w,
/devHistoryBlog/static/d5938c8cd4d2f167a99b7fc19fca64d9/e85cb/001-04.png 480w,
/devHistoryBlog/static/d5938c8cd4d2f167a99b7fc19fca64d9/d9199/001-04.png 960w,
/devHistoryBlog/static/d5938c8cd4d2f167a99b7fc19fca64d9/07a9c/001-04.png 1440w,
/devHistoryBlog/static/d5938c8cd4d2f167a99b7fc19fca64d9/29114/001-04.png 1920w,
/devHistoryBlog/static/d5938c8cd4d2f167a99b7fc19fca64d9/a878e/001-04.png 2048w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h4&gt;커넥션 max-lifetime 로그 확인&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;23:55분&lt;/strong&gt;에 &lt;code class=&quot;language-text&quot;&gt;connection adder&lt;/code&gt; 스레드로 &lt;strong&gt;커넥션이 풀에 추가&lt;/strong&gt;가 되었고, &lt;strong&gt;00:05분&lt;/strong&gt;에(10분 후) 해당 커넥션을 사용하지 않아 &lt;code class=&quot;language-text&quot;&gt;connection closer&lt;/code&gt; 스레드로 &lt;strong&gt;Closing&lt;/strong&gt; 되었다.&lt;/li&gt;
&lt;li&gt;그리고 바로 새로운 커넥션이 추가된 것을 볼 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;즉, 이건 아주 잘 작동이 되고 있다…&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/6af868c8a73a5530b086f68e386f3b13/9b1e2/001-05.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 31.666666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAs0lEQVQY05VQWw7CMAzr/Y/FafgYrI/1FbSZuKxQKn6o5LaJHMuOSSnDhw3OecSU2ut9gFME7Vut7/cVWwg4jgP7fuL8kxOGecOrCUyCvgtah5sKhi02wRld0DqHGFWwVgFdErVW5FKQ8wcpZxTtfbkb0Hk0Q47BH+eXw/mYnp9IZ/wxMt91tViWi0a6qhtpPMaj8/cOva4sRhgRQdGopVSIPFpsroH1669rGGLPILfzOf8EsKrUSyB6NocAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 05&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/6af868c8a73a5530b086f68e386f3b13/d9199/001-05.png&quot;
        srcset=&quot;/devHistoryBlog/static/6af868c8a73a5530b086f68e386f3b13/8ff5a/001-05.png 240w,
/devHistoryBlog/static/6af868c8a73a5530b086f68e386f3b13/e85cb/001-05.png 480w,
/devHistoryBlog/static/6af868c8a73a5530b086f68e386f3b13/d9199/001-05.png 960w,
/devHistoryBlog/static/6af868c8a73a5530b086f68e386f3b13/07a9c/001-05.png 1440w,
/devHistoryBlog/static/6af868c8a73a5530b086f68e386f3b13/9b1e2/001-05.png 1880w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;p&gt;아니 그럼 대체 뭐가 문제인 것인가?? 뷁!&lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;&lt;strong&gt;다음 페이지로 &gt;&lt;/strong&gt; &lt;a href=&quot;https://ssongey.github.io/devHistoryBlog/works/posts/2022-12-09--002&quot;&gt;Unable to acquire JDBC Connection&lt;strong&gt;(DHCP lease lost)&lt;/strong&gt; 에러 오답노트2&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[리눅스 접속 로그 확인 명령어]]></title><link>https://ssongey.github.io/history/posts/2022-11-24--001</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2022-11-24--001</guid><pubDate>Thu, 24 Nov 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;목차&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;이번에 업무 관련 검증을 받게 되면서 서버의 접속 로그를 신경쓸일이 생겼다.&lt;br&gt;
접속로그는 /var/log/wtmp 에 기록이 된다고 하는데, tail, vi 등으로는 볼 수가 없었고, 찾아보니 last 명령어를 사용해야한다고 한다.&lt;/p&gt;
&lt;h2&gt;✔️ 리눅스 접속 로그 확인&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;last 명령어를 사용한다.&lt;/li&gt;
&lt;li&gt;해당 명령어를 이용하여 /var/log/wtmp 에 기록된 내용을 보여준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ last&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/5a840be9e975736fdc54fbeb82ad4fbf/133ae/001.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 24.166666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAxUlEQVQY042Q2Q6DIBBFEXdRFBeqxhjU///G295JaF/7MIFZ7plF2dnCOIPRT0iLFHlRYBxH9H2PaZpQliWaphGf5r1HXdcSM8ZgXVc456C1hlIKyg0Opv4k/EsCTBA0zzOO4xAxQRQSdp6n+MuyCOi6Luz7/gOyiIlwBehUI89zKSDseR6Zgv5939i2TYCxWYyHEH5ATkBI27YSSJLku461FlmWoes6aRqnZZ5/agjniagTIB0Wc81hGFBVlbzxhrHRv/YGSZhzclzKw1AAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/5a840be9e975736fdc54fbeb82ad4fbf/d9199/001.png&quot;
        srcset=&quot;/devHistoryBlog/static/5a840be9e975736fdc54fbeb82ad4fbf/8ff5a/001.png 240w,
/devHistoryBlog/static/5a840be9e975736fdc54fbeb82ad4fbf/e85cb/001.png 480w,
/devHistoryBlog/static/5a840be9e975736fdc54fbeb82ad4fbf/d9199/001.png 960w,
/devHistoryBlog/static/5a840be9e975736fdc54fbeb82ad4fbf/133ae/001.png 1424w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;h2&gt;✔️ 특정 계정 접속 확인&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ last root&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;h2&gt;✔️ 특정 시간 이전 접속 확인&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# 시간 포맷: YYYYMMDDHHMMSS&lt;/span&gt;
$ last -t &lt;span class=&quot;token number&quot;&gt;202211242359&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;h2&gt;✔️ 연도 정보 같이 확인&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ last -F&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;h2&gt;✔️ 이번달 기록만 나올 경우&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;/var/log/wtmp 파일이 logrotate에 의해 순환될 경우 이번달만 나올 수 있다.&lt;/li&gt;
&lt;li&gt;과거 기록을 보려면 rotate 된 파일을 지정해주면 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ last -f /var/log/wtmp.1&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;p&gt;참고)&lt;br&gt;
&lt;a href=&quot;https://zetawiki.com/wiki/%EB%A6%AC%EB%88%85%EC%8A%A4_%EC%A0%91%EC%86%8D%EA%B8%B0%EB%A1%9D_%ED%99%95%EC%9D%B8_last&quot;&gt;리눅스 접속기록 확인 last&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Cordon, Drain 명령어를 이용하여 Node 작업하기]]></title><link>https://ssongey.github.io/works/posts/2022-10-29--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2022-10-29--001</guid><pubDate>Sat, 29 Oct 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;이번에 전사적으로 사용하고 있는 리소스 최적화 요청이 내려왔다.&lt;br&gt;
때문에 내가 운영하고 있던 서비스들의 VM 스펙 변경 및 클러스터 노드를 줄이는 작업을 진행하게 되었다.&lt;/p&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;p&gt;클러스터 노드를 줄이는 작업을 진행할때, 삭제 대상이 된 노드에 서비스하고 있는 파드들을 어떻게 옮길지에 대한 고민을 하게 되었다.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/1a0decba31a526be34202bd47ff5a4bc/a7115/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 23.75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA8klEQVQY01VQ2XKEMAzj//+whd3hJiSEKyHAcKgy2z70QTOyLR9ytK4r9n1/sG0bnHP/4vM8geuCGwb4ecK2LAhuxqwVhqYmd1gXj+DZFxZE1losFAm6rsP7/Yb3/oEMDyEA943s9UKrFDyHOQ62WiP5/sLY91w0YxpHTORRmqbI8xxVVaEsS8Rx/MTC67qGpeg6DhRZ9iwrigJ10yCjJkkS6qonJ7E1+nOh5raejQ2FilfIpQKpDdx8nweMbmGYEwy0X/IApVr05MYYaKLvDCL54R/EolgVLlYD3yC/vPnDmcP9NP5ioj2LWeySC9z4qf0AZzp7IINjqrEAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/1a0decba31a526be34202bd47ff5a4bc/d9199/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/1a0decba31a526be34202bd47ff5a4bc/8ff5a/001-01.png 240w,
/devHistoryBlog/static/1a0decba31a526be34202bd47ff5a4bc/e85cb/001-01.png 480w,
/devHistoryBlog/static/1a0decba31a526be34202bd47ff5a4bc/d9199/001-01.png 960w,
/devHistoryBlog/static/1a0decba31a526be34202bd47ff5a4bc/07a9c/001-01.png 1440w,
/devHistoryBlog/static/1a0decba31a526be34202bd47ff5a4bc/29114/001-01.png 1920w,
/devHistoryBlog/static/1a0decba31a526be34202bd47ff5a4bc/a7115/001-01.png 2186w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;처음엔 &lt;code class=&quot;language-text&quot;&gt;nodeSelector&lt;/code&gt; 를 이용하여 삭제 대상 노드에서 파드들을 빼려고 했는데,&lt;/p&gt;
&lt;p&gt;이를 쉽게 해주는 &lt;strong&gt;cordon, drain&lt;/strong&gt; 기능이 있다는걸 알게 되었다..!&lt;/p&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;h2&gt;✔️ Cordon&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;지정된 노드에 더이상 Pod들이 스케줄링되지 않도록 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ kubectl cordon &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;노드명&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/353075458c49085386b14e24328bd54e/ad00e/001-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 36.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAAAsTAAALEwEAmpwYAAABZklEQVQoz2VRa2+CQBBEEwVFAUUQ5ABFhePpuw+oiU3//2+a7l2aGNMPk7tsZmdndhW2XmMWRVBNC6OxAb3fx0RR4EynCJgHb+Viu90hIo5hGJhS3XVdxHGMPnEV4r7germgKUvskgS32xV5VWGf57BsG133BU0bgWccYRjC930Jz/NQUs8/MYHz+xvObYv6fMHj+wfXusZ704CRi4/PG8YTDRnfk0CFLMvAOceaUrXUM5vNJFRVfQqyXYLd6YxNUYJFCWpyWrAAxWYDe2EiSWPEmwg2ObYsC/P5XMYWQqImMBwOn4Jxuoe/TzFxXIx1A/ZoBEdTwYjIIp/EQixdD8vl8iWaaZry1TQNg8FA7lUMUTqyfjoekaapjFHRDkUsx3HweDyQkOMgCGRM8RfH0HUd9/td1ouikMNEX03rUgpablk34HSItu2Q8xwlkWx7gcPh8BrnD71eTw4VcVerlVyFcCgO9gtEorWRrVwuSgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/353075458c49085386b14e24328bd54e/d9199/001-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/353075458c49085386b14e24328bd54e/8ff5a/001-02.png 240w,
/devHistoryBlog/static/353075458c49085386b14e24328bd54e/e85cb/001-02.png 480w,
/devHistoryBlog/static/353075458c49085386b14e24328bd54e/d9199/001-02.png 960w,
/devHistoryBlog/static/353075458c49085386b14e24328bd54e/ad00e/001-02.png 1366w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;p&gt;노드에 cordon 을 걸면 노드의 상태가 ScheduleingDisabled 가 된 것을 확인할 수 있다.&lt;br&gt;
그럼 더이상 해당 노드에는 새로운 파드들이 들어오지 않게 된다.&lt;br&gt;
다시 정상적으로 노드에 스케줄링을 하기 위해서는 &lt;strong&gt;uncordon&lt;/strong&gt;을 수행하면 된다. &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ kubectl uncordon &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;노드명&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/6bbbafbe2a9aeee4e92c33367b443e01/e4611/001-03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 26.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA/klEQVQY03WQTW+CQBCGMeVAgoAtKuwCCigFDOIuGHto+f8/6+lCDx5MD5M3mY9n5h0rTvaUXUdeN8gspykKzlJyTjOkjInElrquOZ1OBEGAEILNZkMURcRxvOictyzrL9LPiGqaKNRAUl64JQl6v2UwKqIPwp2PiMUy7DjOc/C/aLqK7eGIvV7j+u94tk1gv+EbLcsjh1ySJCnX65UwDBew53k0TUOWZQtktVo9gapXKNNcVxVfjwdd39NrjW9sDcNIaqy7rss4jqzN0hk0W2zblsK85+VCPSr0/U57ufD9M6H6G6NS7EJje9Dmj2IBarNkvmyGzJrnuanJF+AvB3J/U/18lNYAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/6bbbafbe2a9aeee4e92c33367b443e01/d9199/001-03.png&quot;
        srcset=&quot;/devHistoryBlog/static/6bbbafbe2a9aeee4e92c33367b443e01/8ff5a/001-03.png 240w,
/devHistoryBlog/static/6bbbafbe2a9aeee4e92c33367b443e01/e85cb/001-03.png 480w,
/devHistoryBlog/static/6bbbafbe2a9aeee4e92c33367b443e01/d9199/001-03.png 960w,
/devHistoryBlog/static/6bbbafbe2a9aeee4e92c33367b443e01/e4611/001-03.png 1298w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;h2&gt;✔️ Drain&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;지정된 노드에 있는 Pod들을 다른 노드들로 재생성 후, 지정된 노드에서 Pod 삭제&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ kubectl drain &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;노드명&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; 

$ kubectl drain &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;노드명&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; --ignore-daemonsets&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;p&gt;cordon 작업을 통해 삭제 대상 노드에 더이상 새로운 파드가 못들어오도록 막았다면, 이젠 삭제 대상의 노드들에 있는 Pod들을 삭제대상이 아닌 노드로 옮기는 작업을 할 차례이다.&lt;/p&gt;
&lt;p&gt;식제 대상 노드의 pod들을 확인해보니, daemonset 등도 포함되어 있는 것을 확인할 수 있다.

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/1b07df40dd7bf0adcc5685e76a4a1dcb/2e92a/001-04.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 19.583333333333332%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAvElEQVQY0z2QyRKDIBBEcSmXCLgrWorxpCdP/v+vdexJJYcpoKf7MaDe+w6dJAiUgrEGzo0oXgXiOIZ6tF9VVYWu61CWJdq2RdM0slLnnnqWZVB+XREGgYSMsdj8hmEYxBiGIaIokp5zTvS+7wWwbV8fod578bPUdV1I01RCNN/3LbUsi9zKYv88T4FSJ5BnrfUfyOnGcYSa5xl5nguwrmsxHschwWmaBBg8L+A0DBFgrZVw8nwVoexxT+8H0tpgZae8r9YAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 04&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/1b07df40dd7bf0adcc5685e76a4a1dcb/d9199/001-04.png&quot;
        srcset=&quot;/devHistoryBlog/static/1b07df40dd7bf0adcc5685e76a4a1dcb/8ff5a/001-04.png 240w,
/devHistoryBlog/static/1b07df40dd7bf0adcc5685e76a4a1dcb/e85cb/001-04.png 480w,
/devHistoryBlog/static/1b07df40dd7bf0adcc5685e76a4a1dcb/d9199/001-04.png 960w,
/devHistoryBlog/static/1b07df40dd7bf0adcc5685e76a4a1dcb/07a9c/001-04.png 1440w,
/devHistoryBlog/static/1b07df40dd7bf0adcc5685e76a4a1dcb/29114/001-04.png 1920w,
/devHistoryBlog/static/1b07df40dd7bf0adcc5685e76a4a1dcb/2e92a/001-04.png 2508w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;daemonset 의 특성상 pod가 죽게되면 즉시 다시 생성되기 때문에 노드에 daemonset 이 있는 경우 drain 명령어를 실행하면 error: cannot delete DaemonSet-managed Pods 오류가 발생한다.

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/87dc747f538ba462c6314ba961146532/10f47/001-05.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 16.666666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAjklEQVQI133MTwuEIBCHYREiMitISsHW9NDaH+2w3/+7/XZ3DsJe9vAyMMM87LxvnCnjihHxuWHfI3LOCCHAe49pmjCOY5ld16Gua4pzDsbYb25Z4NcV7vP8cI4gay2MMZjnGVprQqqqKtBfcDsOHFfCKyWE1RGmlIKUkvpiQgiqbdtS0zR07/sewzCU/RsXZUiIEtQciQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 05&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/87dc747f538ba462c6314ba961146532/d9199/001-05.png&quot;
        srcset=&quot;/devHistoryBlog/static/87dc747f538ba462c6314ba961146532/8ff5a/001-05.png 240w,
/devHistoryBlog/static/87dc747f538ba462c6314ba961146532/e85cb/001-05.png 480w,
/devHistoryBlog/static/87dc747f538ba462c6314ba961146532/d9199/001-05.png 960w,
/devHistoryBlog/static/87dc747f538ba462c6314ba961146532/07a9c/001-05.png 1440w,
/devHistoryBlog/static/87dc747f538ba462c6314ba961146532/29114/001-05.png 1920w,
/devHistoryBlog/static/87dc747f538ba462c6314ba961146532/10f47/001-05.png 2726w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;보통은 로깅, proxy, 네트웍 관련 데몬셋은 떠있기 때문에 꼭 &lt;code class=&quot;language-text&quot;&gt;--ignore-daemonsets&lt;/code&gt; 옵션을 주고 실행을 한다.
그럼 데몬셋 파드는 무시하고 나머지 파드들만 옮긴다.

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/87e5c175e853bd0ccf95d66fe5a8ef6c/cb88c/001-06.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 16.666666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAeUlEQVQI142MuwoDIQAEFURQ0BMU7Czik2iM+f+P29wJSX3FMNvskLE+aH2gl4ocH8g5o5SCEAK89zDGwFq70VrjOA5IKfdWSv39g7znxJwvPEdHbQ21VsQY4ZzbZyEECCH3mWew9461Fq59OaW0g5xzMMZAKb0d/AJ8lUgm2nNW+QAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 06&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/87e5c175e853bd0ccf95d66fe5a8ef6c/d9199/001-06.png&quot;
        srcset=&quot;/devHistoryBlog/static/87e5c175e853bd0ccf95d66fe5a8ef6c/8ff5a/001-06.png 240w,
/devHistoryBlog/static/87e5c175e853bd0ccf95d66fe5a8ef6c/e85cb/001-06.png 480w,
/devHistoryBlog/static/87e5c175e853bd0ccf95d66fe5a8ef6c/d9199/001-06.png 960w,
/devHistoryBlog/static/87e5c175e853bd0ccf95d66fe5a8ef6c/07a9c/001-06.png 1440w,
/devHistoryBlog/static/87e5c175e853bd0ccf95d66fe5a8ef6c/29114/001-06.png 1920w,
/devHistoryBlog/static/87e5c175e853bd0ccf95d66fe5a8ef6c/cb88c/001-06.png 2728w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;삭제 노드에는 데몬셋 파드만 남은 것을 확인할 수 있다.

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/425e65c7ef2b4c2b46de43dddc350bfe/0ddab/001-07.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 16.249999999999996%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAqklEQVQI1y2P2w6DIBBEoeIlUVoVFDHGGyRqG+v/f90UN304mYdJzuwyf+zwxwemLCE5RxwLGNugrmskSUKUoev7HkqpPzWeL4m2banL85yIogjsfRzwzoExRnD+gHMey7JgnmdkWYau6zBNE6qqwjAM0Epj27YwHmMcR+pucdM0YOf3xHVd0FoHGSdWt2Lf9yB2EELAWgtjDIqioJRSkug+4B67RWma0lc/nwJJ65Q8+XMAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 07&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/425e65c7ef2b4c2b46de43dddc350bfe/d9199/001-07.png&quot;
        srcset=&quot;/devHistoryBlog/static/425e65c7ef2b4c2b46de43dddc350bfe/8ff5a/001-07.png 240w,
/devHistoryBlog/static/425e65c7ef2b4c2b46de43dddc350bfe/e85cb/001-07.png 480w,
/devHistoryBlog/static/425e65c7ef2b4c2b46de43dddc350bfe/d9199/001-07.png 960w,
/devHistoryBlog/static/425e65c7ef2b4c2b46de43dddc350bfe/07a9c/001-07.png 1440w,
/devHistoryBlog/static/425e65c7ef2b4c2b46de43dddc350bfe/29114/001-07.png 1920w,
/devHistoryBlog/static/425e65c7ef2b4c2b46de43dddc350bfe/0ddab/001-07.png 2220w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;이후 삭제 대상 노드 처리를 해주면 끝!!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[docker 호스트로 연결]]></title><link>https://ssongey.github.io/history/posts/2022-10-29--001</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2022-10-29--001</guid><pubDate>Sat, 29 Oct 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;docker 로 띄운 컨테이너에서 내 현재 로컬의 DB를 붙여 테스트를 하게 되었다.&lt;br&gt;
때문에 컨테이너에서 호스트의 주소로 연결하는 방법이 필요했다.&lt;/p&gt;
&lt;p&gt;docker 18.03 부터 호스트의 IP를 직접 입력하는 방법 외에 호스트 주소로 바로 연결이 가능하다.&lt;/p&gt;
&lt;h3&gt;✔️ Mac or Windows&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&apos;host.docker.internal&apos;&lt;/span&gt;
또는
&lt;span class=&quot;token number&quot;&gt;172.17&lt;/span&gt;.0.1&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;✔️ Linux&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ docker run --network&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;host&quot;&lt;/span&gt;

localhost
또는
&lt;span class=&quot;token number&quot;&gt;127.0&lt;/span&gt;.0.1&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[503 Service Unavailable 오류!! 범인은 누구냐! (WAS? Nginx? GSLB?)]]></title><link>https://ssongey.github.io/works/posts/2022-10-23--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2022-10-23--001</guid><pubDate>Sun, 23 Oct 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;503 Service Unavailable 오류가 발생하기 전, 해당 서비스의 인프라 구성은 아래와 같았다.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/6e7f019e9e1d17fc2de2f4d15f49b5d1/49853/001-1.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 55.833333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsTAAALEwEAmpwYAAABW0lEQVQoz5WT6W7CQAyE8/5PRzhzQkggBEK4T3FM81laqT8q2q5krbPeHY89jqcP6/1+277b7TSZTHS5XHS9Xu27aRptNhvzgyBQGIa2e5/AHOB2u9XxeNT9ftfz+dThcFAchVoul9rv9wYWx7GGw6E89/Ane71eBgiT8Xis1WplBlCaJJrNZsaQWJZlnxl+Z9rtdlXXtc7ns5W8Xq/ldzqatiAAjkYjDQYD2z2CXCYrlynNnWGLxUJVVVn/HCCM82mmqo01rQ8Q7Pr9vryiKBRFkdI0tYfQL8vSREjasjh7PB52mRIx4hAgVuS5fN+3eK/Xk0dml931Dp8zRIAtSWi+W8QAhSk+7Jz92kMWKgLAqLiRCVpFy/ncJoDqMAP8i8o8ojWAwYpSaVPelsuZm8F/zSFtuN1ulgThkhawbkeImQQcM5X/8qcAcDqdDBCV6Sfqkggf8RCR4f4CyKZEBTxgHF4AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 1&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/6e7f019e9e1d17fc2de2f4d15f49b5d1/d9199/001-1.png&quot;
        srcset=&quot;/devHistoryBlog/static/6e7f019e9e1d17fc2de2f4d15f49b5d1/8ff5a/001-1.png 240w,
/devHistoryBlog/static/6e7f019e9e1d17fc2de2f4d15f49b5d1/e85cb/001-1.png 480w,
/devHistoryBlog/static/6e7f019e9e1d17fc2de2f4d15f49b5d1/d9199/001-1.png 960w,
/devHistoryBlog/static/6e7f019e9e1d17fc2de2f4d15f49b5d1/07a9c/001-1.png 1440w,
/devHistoryBlog/static/6e7f019e9e1d17fc2de2f4d15f49b5d1/29114/001-1.png 1920w,
/devHistoryBlog/static/6e7f019e9e1d17fc2de2f4d15f49b5d1/49853/001-1.png 2224w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;얼마전 IDC1 에 문제가 발생하였고, 결국 &lt;strong&gt;IDC1은 down&lt;/strong&gt;이 되었다.&lt;/p&gt;
&lt;p&gt;하지만, &lt;strong&gt;GSLB에 의해 요청은 모두 IDC2로 연결&lt;/strong&gt;이 되었고, 해당 deployment 는 Autoscale도 걸려있었기 때문에 큰 문제없이 &lt;strong&gt;서비스가 정상으로 작동&lt;/strong&gt;이 되는듯 하였다.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/ec46d7a95980d6d71de6ea8264a8d146/f37ba/001-2.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 59.583333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsTAAALEwEAmpwYAAABxklEQVQoz41TSW7jMBDk/1+R6zxibnPJwYgde7TvsvZdtqM4klxTJOBgLjFMoNDNllhd7G4KPFi3203ZeZpQBh7mcSB6rNMHkl8vaP/8xnK9ogp9NMkRbRRAPCK7E36dRuS2hZl2JT6HHs3mFYOlY+o7hLqGmN+Tww7ifvAnKIXnE8auw3A+Y/q8oqW/N0wExyO6voemG9gdDopYPCK6rauyU9sg8T11uKlrFEUBnQSe42AYBoRBAM/3kVKlwBNrNDXUWYqOh89U2dOapok0TVUSy7JgkTzQ/kLUzFiWpcLlclEZm6ZBVVVoq1Jdd7mcgGX+TvDBWE2VPf+bmMAloWkYyCwDwvM8HCjfdV0kSQKHmaIoYlYbnmWiorKVZM77FlUUKnTpEWORY8gz1HEIa7eFs3+HvXuDmOcZy7Lgyvbfl/Rl/IuQN/BZn5yKrtyvrG8/jsjyAhUVDvRdipLQWQbx06j8v2zbVupPJ3abBDXL8bbZwGG8Z8dlDWVNNU17bmwkkSxFlmXI81yplmRxHKuaq6YQivCZwZaqJr6W765zL5uQUrX0A47NkTNpMCaeeXpyVOQUdLyehFR4h5yG/X6P7Xar7D87k5DMJ7BpSgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 2&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/ec46d7a95980d6d71de6ea8264a8d146/d9199/001-2.png&quot;
        srcset=&quot;/devHistoryBlog/static/ec46d7a95980d6d71de6ea8264a8d146/8ff5a/001-2.png 240w,
/devHistoryBlog/static/ec46d7a95980d6d71de6ea8264a8d146/e85cb/001-2.png 480w,
/devHistoryBlog/static/ec46d7a95980d6d71de6ea8264a8d146/d9199/001-2.png 960w,
/devHistoryBlog/static/ec46d7a95980d6d71de6ea8264a8d146/07a9c/001-2.png 1440w,
/devHistoryBlog/static/ec46d7a95980d6d71de6ea8264a8d146/29114/001-2.png 1920w,
/devHistoryBlog/static/ec46d7a95980d6d71de6ea8264a8d146/f37ba/001-2.png 2216w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;하지만, 어느순간부터 해당 서비스에서 &lt;strong&gt;503 오류&lt;/strong&gt;가 발생한다는 제보가 들어왔다.&lt;/p&gt;
&lt;p&gt;503 오류는 “&lt;strong&gt;서비스를 일시적으로 사용할 수 없음(503 Service Temporarily Unavailable Error)&lt;/strong&gt;” 을 의미하고, 나는 로그도 제대로 확인도 안하고.. nginx에서 발생하는 오류라고 바로 판단을 해버렸다. (삽질의 시작…)&lt;/p&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;h2&gt;✔️ 첫번째 삽질!!&lt;/h2&gt;
&lt;h3&gt;👀 첫번째 의심)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;“&lt;strong&gt;(클라 요청수) &gt; (pod 들이 수행할 수 있는 요청 수) 상태라서 nginx에서 was로 못보내고 있나?&lt;/strong&gt;”&lt;/li&gt;
&lt;li&gt;autoscaling이 발생되었지만, 순간 요청수가 많아 pod가 추가 생성되기 전에 요청을 모두 견뎌내지 못하여 503 오류가 발생한 것인가?&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;strong&gt;💩 첫번째 조치)&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;최소 pod수를 2배로 증가&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;하지만.. 503 에러는 계속 발생하였다….😢&lt;/p&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;h2&gt;✔️ 두번째 삽질!!&lt;/h2&gt;
&lt;h3&gt;&lt;strong&gt;👀 두번째 의심)&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;두개의 ingress가 총 요청수를 못견디고 있는건가?&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;현재 ingress node는 2개인 상태였고, 해당 클러스터에 딱 그 시점에! 다른 서비스가 잠시 머물고 있었는데, nginx가 일시적으로 과부하가 되거나 리소스 제약에 직면하면 해당 오류가 발생할 수 있다는 글을 보게 되었고 nginx를 의심을 하게 됬었다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;strong&gt;💩 두번째 조치)&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ingress pod 한개 추가&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;역시.. 503 에러는 계속 발생하였다….😢&lt;/p&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;h2&gt;✔️ 세번째 드디어!!!&lt;/h2&gt;
&lt;p&gt;“&lt;strong&gt;LB에서 요청을 잘못 전달하고 있는게 아닐까?”&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;👀 세번째 의심)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;앞단 LB에서 로드밸런싱이 잘못되고 있는건 아닐까?&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;위 조치까지 하고 nginx 로그를 살펴보게 되었는데, 503 오류에 대한 로그가 딱히 보이지 않아서 물음표를 그리고 있다가 문득! 로드밸런싱이 잘못되고 있을수도 있겠다는 생각이 들었다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;🤡 세번째 조치)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;GSLB로 묶은 VIP 중에 IDC1의 VIP를 제외하도록 요청을 하였다.&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;그랬더니!! 드디어 503 오류가 사라졌다!! 만쉐이! 🙌&lt;/p&gt;
&lt;p&gt;아 진짜.. 경험에 의해 바로 판단하지 말고 로그를 꼭 확인하는 습관을 길러야겠다…ㅠㅜ&lt;br&gt;
하지만 왜 지금 off 인 IDC1 쪽으로 로드밸런싱이 되고 있던건지, GSLB에 버그가 있던거지 정확한 원인은 파악을 하지 못한체, 일단 서비스가 정상화 된 것으로 만족하고 마무리를 지었다.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;하루가 지난 후, 인프라팀에서 공지가 내려왔다.&lt;br&gt;
아래 상황에서 장애가 난 IDC1에 구축된 클러스터로 트래픽이 인입되면서 서비스 장애로 이어지는 상황이 발생!!&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;worker node 가 하나라도 살아난 경우(pod 실행 여부와 상관 없이 핑만 나가는 경우)&lt;/li&gt;
&lt;li&gt;ingress가 하나라도 살아난 경우&lt;/li&gt;
&lt;li&gt;GSLB로 묶여있고, 해당 VIP를 제외(요청등을 통해)하지 않은 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;즉, 풀어서 얘기하면 아래와 같다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;IDC1에 전력이 조금씩 on이 되면서 클러스터를 구성하는 &lt;strong&gt;일부 노드들이 정상화&lt;/strong&gt; 되었고,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;서비스 상태는 정상이 아니지만&lt;/strong&gt;(pod가 없고 ingress만 있는 경우 등..) GSLB에서 health check를 성공으로 판단하였고,&lt;/li&gt;
&lt;li&gt;때문에 &lt;strong&gt;트래픽이 인입되면서 서비스 장애가 발생&lt;/strong&gt;하니, IDC1의 VIP를 제거 요청해라!!&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;그래 GSLB는 잘못이 없구나.. (policy 가 어떻게 설정이 되었는지는 난 알지 못하니깐)
IDC에 문제가 생기면 일단 GSLB에 묶여있는 VIP를 제거하는게 안전하구나.. 라는 배움을 하나 얻게되었다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[파일 업로드 크기 제한 늘리기 (Ingress Nginx & SpringBoot)]]></title><link>https://ssongey.github.io/history/posts/2022-10-23--001</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2022-10-23--001</guid><pubDate>Sun, 23 Oct 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;1. Nginx 설정&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;nginx 의 기본 body sizesms 1MB이다.&lt;/li&gt;
&lt;li&gt;이 때, 업로드 파일을 포함한 요청 사이즈가 1MB가 넘으면 413(Request Entity Too Large) 에러를 반환한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;1.1. ConfigMap 으로 설정하기&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; v1
&lt;span class=&quot;token key atrule&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; ConfigMap
&lt;span class=&quot;token key atrule&quot;&gt;proxy-body-size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;10m&quot;&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; ingress&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;nginx
&lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; nginx&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;configuration&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;1.2. Ingress Annotation 으로 설정하기&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; networking.k8s.io/v1
&lt;span class=&quot;token key atrule&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Ingress
&lt;span class=&quot;token key atrule&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;annotations&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;nginx.ingress.kubernetes.io/proxy-body-size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;50m&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;h1&gt;2. SpringBoot 설정&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;SpringBoot 에 설정된 기본값은 1048576 bytes 이다.&lt;/li&gt;
&lt;li&gt;이 때, 업로드 파일 사이즈가 위 사이즈를 넘으면 &lt;strong&gt;“multipart.MaxUploadSizeExceededException”&lt;/strong&gt; 에러가 발생한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2.1. SpringBoot 2.x 버전&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# application.yaml&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;spring&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
	&lt;span class=&quot;token key atrule&quot;&gt;servlet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
		&lt;span class=&quot;token key atrule&quot;&gt;multipart&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 
			&lt;span class=&quot;token key atrule&quot;&gt;maxFileSize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 10MB
			&lt;span class=&quot;token key atrule&quot;&gt;maxRequestSize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 10MB&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;2.2. SpringBoot 1.4 &amp;#x26; 1.5 버전&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;spring&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
	&lt;span class=&quot;token key atrule&quot;&gt;http&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
		&lt;span class=&quot;token key atrule&quot;&gt;multipart&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
			&lt;span class=&quot;token key atrule&quot;&gt;maxFileSize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 10MB
			&lt;span class=&quot;token key atrule&quot;&gt;maxRequestSize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 10MB&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;2.3. SpringBoot 1.3.x 이하 버전&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;multipart&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
	&lt;span class=&quot;token key atrule&quot;&gt;maxFileSize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 10MB
	&lt;span class=&quot;token key atrule&quot;&gt;maxRequestSize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 10MB&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[로컬에 있는 도커 이미지 수동으로 서버에 로딩 시키기]]></title><link>https://ssongey.github.io/works/posts/2022-10-19--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2022-10-19--001</guid><pubDate>Wed, 19 Oct 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;이번에 전사적으로 모든 CI/CD 툴이 작동하지 않는 상태에서 새로 빌드/배포를 해야하는 상황이 있었다.&lt;br&gt;
이에 로컬에서 빌드한 docker 이미지를 k8s에 배포까지 수동으로 작업한 내용을 기록한다.&lt;/p&gt;
&lt;h3&gt;✔️ docker image 빌드&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;docker build -t &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;image명&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;:&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;tag&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;✔️ 컨테이너 이미지 tar 파일로 저장&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ docker save &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;image명&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;:&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;tag&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; -o dockerImage.tar&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;✔️ tar 파일 서버로 전송&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;scp&lt;/span&gt; ./dockerImage.tar &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;계정&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;@&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;host&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;:&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;경로&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;✔️ 해당 서버에서 컨테이너 이미지 로딩&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;이미지를 로딩하면 k8s에서 해당 이미지로 배포가 가능하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; docker load -i dockerImage.tar&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;✔️ k8s 배포시&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;deployment.yaml 파일 내에 &lt;code class=&quot;language-text&quot;&gt;imagePullPolicy&lt;/code&gt; 필드값을 &lt;code class=&quot;language-text&quot;&gt;Never&lt;/code&gt; 로 설정하여 위에 로드한 이미지를 사용하도록 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; apps/v1
&lt;span class=&quot;token key atrule&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Deployment
&lt;span class=&quot;token key atrule&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;containers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; app
          &lt;span class=&quot;token key atrule&quot;&gt;imagePullPolicy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Never
&lt;span class=&quot;token punctuation&quot;&gt;...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Fluentd 설정파일 분석]]></title><link>https://ssongey.github.io/history/posts/2022-09-17--001</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2022-09-17--001</guid><pubDate>Sat, 17 Sep 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;✔️ 먼저 알아두면 좋은 내용&lt;/h1&gt;
&lt;h2&gt;1. common plugin parameters&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;builtin plugin parameter 의 경우 prefix로 &lt;code class=&quot;language-text&quot;&gt;@&lt;/code&gt; 가 붙는다&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;1.1. &lt;code class=&quot;language-text&quot;&gt;@type&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;specifies the plugin type&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;1.2. &lt;code class=&quot;language-text&quot;&gt;@id&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;specifies the plugin id.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;in_monitor_agent&lt;/code&gt; uses this value for&lt;code class=&quot;language-text&quot;&gt;plugin_id&lt;/code&gt; field&lt;/li&gt;
&lt;li&gt;버퍼, 스토리지, 로깅 및 기타 목적을 위한 경로로 사용됨&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;1.3. &lt;code class=&quot;language-text&quot;&gt;@label&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;specifies the label symbol. See&lt;a href=&quot;https://www.notion.so/configuration/config-file#5.-group-filter-and-output-the-label-directive&quot;&gt;label&lt;/a&gt;section.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;1.4. &lt;code class=&quot;language-text&quot;&gt;@log_level&lt;/code&gt;&lt;/strong&gt; &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;specifies per plugin log level. See &lt;a href=&quot;https://www.notion.so/deployment/logging#per-plugin-log&quot;&gt;Per Plugin Log&lt;/a&gt; section.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;자세한 내용은 아래 참고&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.fluentd.org/configuration/plugin-common-parameters#parameters-for-all-the-plugins&quot;&gt;Config: Common Parameters&lt;/a&gt;&lt;/p&gt;
&lt;br/&gt;
&lt;h2&gt;2. wildcards, expansions and other tips&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;match&lt;/code&gt; , &lt;code class=&quot;language-text&quot;&gt;filter&lt;/code&gt; 태그에서 사용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;2.1. &lt;code class=&quot;language-text&quot;&gt;*&lt;/code&gt;&lt;/strong&gt; &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;single tag 와 매치&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;a.*&lt;/code&gt; 의 경우 &lt;code class=&quot;language-text&quot;&gt;a.b&lt;/code&gt; 와 매치, &lt;code class=&quot;language-text&quot;&gt;a&lt;/code&gt; 또는 &lt;code class=&quot;language-text&quot;&gt;a.b.c&lt;/code&gt; 와는 매치 안됨&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;2.2. `&lt;/strong&gt;`**&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;zero or more tag 와 매치&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;a.**&lt;/code&gt; 의 경우 &lt;code class=&quot;language-text&quot;&gt;a&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;a.b&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;a.b.c&lt;/code&gt; 와 모두 매치&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;2.3. 그외&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;그외 regex, 값 매치 등은 아래에서 확인&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.fluentd.org/configuration/config-file#wildcards-expansions-and-other-tips&quot;&gt;Config File Syntax&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;h2&gt;&lt;strong&gt;3. Embedding Ruby Expressions&lt;/strong&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;fluentd 1.4.0 부터 &lt;code class=&quot;language-text&quot;&gt;#{...}&lt;/code&gt; 표현식에 루비 코드를 넣을 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;match &lt;span class=&quot;token string&quot;&gt;&quot;app.#{ENV[&apos;FLUENTD_TAG&apos;]}&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  @type stdout
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/match&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;h1&gt;✔️ Directive&lt;/h1&gt;
&lt;h2&gt;1. source&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;input 에 대한 지시어&lt;/li&gt;
&lt;li&gt;사용할 input plugin에 대한 값이 &lt;code class=&quot;language-text&quot;&gt;@type&lt;/code&gt; 으로 명시가 되야한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Receive events from 24224/tcp&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# This is used by log forwarding and the fluent-cat command&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;source&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  @type forward
  port &lt;span class=&quot;token number&quot;&gt;24224&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/source&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# http://&amp;lt;ip&gt;:9880/myapp.access?json={&quot;event&quot;:&quot;data&quot;}&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;source&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  @type http
  port &lt;span class=&quot;token number&quot;&gt;9880&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/source&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;2. match&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;output plugin 으로 동작하며, 명시된 태그에 대해서만 output destination으로 보내진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Receive events from 24224/tcp&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# This is used by log forwarding and the fluent-cat command&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;source&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  @type forward
  port &lt;span class=&quot;token number&quot;&gt;24224&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/source&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# http://&amp;lt;ip&gt;:9880/myapp.access?json={&quot;event&quot;:&quot;data&quot;}&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;source&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  @type http
  port &lt;span class=&quot;token number&quot;&gt;9880&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/source&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Match events tagged with &quot;myapp.access&quot; and&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# store them to /var/log/fluent/access.%Y-%m-%d&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Of course, you can control how you partition your data&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# with the time_slice_format option.&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;match myapp.access&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  @type &lt;span class=&quot;token function&quot;&gt;file&lt;/span&gt;
  path /var/log/fluent/access
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/match&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;3. filter&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;match 와 동일한 syntax를 가지고 있고, 로그 필터에 대한 지시어이다.&lt;/li&gt;
&lt;li&gt;event flow 는 아래와 같다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/ec6a4bfdf176b286337a7b944acbde90/8ae78/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 7.916666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAACCAYAAABYBvyLAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAaUlEQVQI1yWMSxKAMAhDvf8dHZ1q7b/0py5jwUUGSF5YqHa08cBHgjYexkWwV9pA7ffMXvT7F/uXC9DWI6QCn0g4mrpskGzJpQmYqMnDTem5VxFnUqhDJt8uZihtcU7WhoSYf457637gA/pxlxte/OxfAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/ec6a4bfdf176b286337a7b944acbde90/d9199/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/ec6a4bfdf176b286337a7b944acbde90/8ff5a/001-01.png 240w,
/devHistoryBlog/static/ec6a4bfdf176b286337a7b944acbde90/e85cb/001-01.png 480w,
/devHistoryBlog/static/ec6a4bfdf176b286337a7b944acbde90/d9199/001-01.png 960w,
/devHistoryBlog/static/ec6a4bfdf176b286337a7b944acbde90/8ae78/001-01.png 1096w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# http://this.host:9880/myapp.access?json={&quot;event&quot;:&quot;data&quot;}&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;source&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  @type http
  port &lt;span class=&quot;token number&quot;&gt;9880&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/source&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;

&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;filter myapp.access&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  @type record_transformer
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;record&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    host_param &lt;span class=&quot;token string&quot;&gt;&quot;#{Socket.gethostname}&quot;&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/record&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/filter&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;

&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;match myapp.access&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  @type &lt;span class=&quot;token function&quot;&gt;file&lt;/span&gt;
  path /var/log/fluent/access
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/match&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;✔️ 위 예제 동작 플로우&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;input 으로 tag: myapp.access, data: {”event”: “data”} 이벤트를 받고,&lt;/li&gt;
&lt;li&gt;첫번째 filter인 record&lt;em&gt;transformer 는 `“host&lt;/em&gt;param”` 필드를 이벤트에 추가한다.&lt;/li&gt;
&lt;li&gt;그럼 &lt;code class=&quot;language-text&quot;&gt;{&amp;quot;event&amp;quot;:&amp;quot;data&amp;quot;,&amp;quot;host_param&amp;quot;:&amp;quot;webserver1&amp;quot;}&lt;/code&gt; 값이 ouput plugin 으로 보내져 파일로 출력하게 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/f2f8dc70a72607c91067758eb1b40258/f32b7/001-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 34.583333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAABYlAAAWJQFJUiTwAAAAzElEQVQoz31R0Q6DIBDj/79QExNnsuiDOhVEQIUbPefijK5JcwSa3l0RIQQ6E/A+0LKszHUFPZ/396P2CEE3mCZLWfakPC+5pmlBj6Iia92P4Zmi61UUzeTcRpzneWHDsmyobnqqqiaypbruSCn9aRkuBxFJUpCMon18TKC1uRv82xBADDu995uh1pbG0bARhMY4zuxqLQA5SqmpfQ2s33NGI1QBZ4hRN4a/GQFSjpyrjrEMwxgHmkhFsuHVWsefvLpHY2wCIlPkDeL+DQ4cJZdwVmywAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/f2f8dc70a72607c91067758eb1b40258/d9199/001-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/f2f8dc70a72607c91067758eb1b40258/8ff5a/001-02.png 240w,
/devHistoryBlog/static/f2f8dc70a72607c91067758eb1b40258/e85cb/001-02.png 480w,
/devHistoryBlog/static/f2f8dc70a72607c91067758eb1b40258/d9199/001-02.png 960w,
/devHistoryBlog/static/f2f8dc70a72607c91067758eb1b40258/f32b7/001-02.png 1136w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;hr&gt;
&lt;h1&gt;✔️ 서비스에 설정한 fluentd daemonset config 설정 분석&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;전체 설정 내용&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;data:
  fluent.conf: &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;system&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      workers &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
      @log_level info
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/system&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    @include input-kubernetes.conf
    @include filter-kubernetes.conf
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;match **&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      @type copy
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;store&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        @type                         kafka2
        @id                           out_kafka
        brokers                       logis-kafka.dev.kakaoi.io:9092
        max_send_retries              &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;
        required_acks                 &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;

        default_topic                 xoauth-dev
    
        exception_backup              &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;
        compression_codec             &lt;span class=&quot;token function&quot;&gt;gzip&lt;/span&gt;
    
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;format&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
          @type                       json
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/format&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;

        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;buffer topic,tag&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
          @type                       &lt;span class=&quot;token function&quot;&gt;file&lt;/span&gt;
          path                        /var/log/td-agent/buffer/td
          flush_interval              5s
          chunk_limit_size            16M
          queue_limit_length          &lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt;
          retry_forever               &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/buffer&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/store&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/match&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;

  input-kubernetes.conf: &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# Prevent fluentd from handling records containing its own logs. Otherwise&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# it can lead to an infinite loop, when error in sending one message generates&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# another message which also fails to be sent and so on.&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;match fluent.**&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      @type                           null
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/match&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;source&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      @type                           &lt;span class=&quot;token function&quot;&gt;tail&lt;/span&gt;
      @id                             in_tail_container_logs
      path                            /var/log/containers/xoauth*.log
      pos_file                        /var/log/fluentd-containers.log.pos
      tag                             kubernetes.*
      read_from_head                  &lt;span class=&quot;token string&quot;&gt;&quot;#{ENV[&apos;FLUENTD_INPUT_READ_FROM_HEAD&apos;] || &apos;false&apos;}&quot;&lt;/span&gt;
      limit_recently_modified         &lt;span class=&quot;token string&quot;&gt;&quot;#{ENV[&apos;LIMIT_RECENTLY_MODIFIED&apos;] || &apos;120m&apos;}&quot;&lt;/span&gt;
      rotate_wait                     &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
      enable_stat_watcher             &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;parse&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        @type                         regexp
        expression                    /^&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;?&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;time&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;^ &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;+&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;?&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;stream&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;stdout&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;stderr&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;?&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;flags&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;^ &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;+&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;?&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;message&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;.*&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;$/
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/parse&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/source&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;

  filter-kubernetes.conf: &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;filter kubernetes.**&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      @type                           kubernetes_metadata
      @id                             filter_kube_metadata
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/filter&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;filter kubernetes.**&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      @type                           record_modifier
      tag                             &lt;span class=&quot;token variable&quot;&gt;${record.dig(&quot;kubernetes&quot;&lt;span class=&quot;token operator&quot;&gt;,&lt;/span&gt; &quot;container_name&quot;).gsub(&apos;-&apos;&lt;span class=&quot;token operator&quot;&gt;,&lt;/span&gt; &apos;.&apos;)}&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;record&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        @timestamp                    &lt;span class=&quot;token variable&quot;&gt;${(Time.at(time) + (60*60*9)).strftime(&apos;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;Y-&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;m-&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;dT&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;H&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;M&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;S.&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;L+09&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;00&apos;)}&lt;/span&gt;
        cluster_name                  &lt;span class=&quot;token string&quot;&gt;&quot;xoauth-dev&quot;&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;hostname&lt;/span&gt;                      &lt;span class=&quot;token string&quot;&gt;&quot;#{ENV[&apos;K8S_NODE_NAME&apos;]}&quot;&lt;/span&gt;
        container_image               &lt;span class=&quot;token variable&quot;&gt;${record.dig(&quot;kubernetes&quot;&lt;span class=&quot;token operator&quot;&gt;,&lt;/span&gt; &quot;container_image&quot;)}&lt;/span&gt;
        pod_name                      &lt;span class=&quot;token variable&quot;&gt;${record.dig(&quot;kubernetes&quot;&lt;span class=&quot;token operator&quot;&gt;,&lt;/span&gt; &quot;pod_name&quot;)}&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/record&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/filter&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;filter kubernetes.**&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      @type                           parser
      key_name                        message
      reserve_data                    &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
      remove_key_name_field           &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;parse&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        @type                         json
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/parse&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/filter&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;filter kubernetes.**&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      @type                           record_transformer
      remove_keys                     $.kubernetes
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/filter&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;1. Input에 대한 설정&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;input-kubernetes.conf: &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;match fluent.**&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      @type                           null
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/match&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;source&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      @type                           &lt;span class=&quot;token function&quot;&gt;tail&lt;/span&gt;
      @id                             in_tail_container_logs
      path                            /var/log/containers/xoauth*.log
      pos_file                        /var/log/fluentd-containers.log.pos
      tag                             kubernetes.*
      read_from_head                  &lt;span class=&quot;token string&quot;&gt;&quot;#{ENV[&apos;FLUENTD_INPUT_READ_FROM_HEAD&apos;] || &apos;false&apos;}&quot;&lt;/span&gt;
      limit_recently_modified         &lt;span class=&quot;token string&quot;&gt;&quot;#{ENV[&apos;LIMIT_RECENTLY_MODIFIED&apos;] || &apos;120m&apos;}&quot;&lt;/span&gt;
      rotate_wait                     &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
      enable_stat_watcher             &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;parse&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        @type                         regexp
        expression                    /^&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;?&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;time&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;^ &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;+&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;?&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;stream&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;stdout&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;stderr&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;?&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;flags&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;^ &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;+&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;?&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;message&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;.*&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;$/
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/parse&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/source&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;1.1. 로그 input&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;/var/log/containers/xoauth*.log 파일을 타겟으로 tail 을 사용하여 input을 수행한다.&lt;/li&gt;
&lt;li&gt;해당 이벤트에 kubernetes.* 태그를 붙인다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;source&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  @type                           &lt;span class=&quot;token function&quot;&gt;tail&lt;/span&gt;
  @id                             in_tail_container_logs
  path                            /var/log/containers/xoauth*.log
  pos_file                        /var/log/fluentd-containers.log.pos
  tag                             kubernetes.*
  read_from_head                  &lt;span class=&quot;token string&quot;&gt;&quot;#{ENV[&apos;FLUENTD_INPUT_READ_FROM_HEAD&apos;] || &apos;false&apos;}&quot;&lt;/span&gt;
  limit_recently_modified         &lt;span class=&quot;token string&quot;&gt;&quot;#{ENV[&apos;LIMIT_RECENTLY_MODIFIED&apos;] || &apos;120m&apos;}&quot;&lt;/span&gt;
  rotate_wait                     &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
  enable_stat_watcher             &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;parse&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    @type                         regexp
    expression                    /^&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;?&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;time&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;^ &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;+&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;?&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;stream&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;stdout&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;stderr&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;?&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;flags&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;^ &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;+&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;?&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;message&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;.*&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;$/
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/parse&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/source&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;실제 들어온 이벤트의 레코드 데이터는 아래와 같다 (/var/log/containers/xoauth*.log 파일 포맷)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token number&quot;&gt;2022&lt;/span&gt;-08-23T16:20:02.313036458+09:00 stdout F &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;@timestamp&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2022-08-23T07:20:02.312+00:00&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;@version&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;message&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Running with Spring Boot v2.2.0.RELEASE, Spring v5.2.0.RELEASE&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;logger_name&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;com.kakao.xoauth.XoauthApplication&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;thread_name&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;main&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;level&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;DEBUG&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;level_value&quot;&lt;/span&gt;:10000&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;lt;parse&amp;gt;&lt;/code&gt; 의 regexp 를 통해 아래와 같이 파싱이 된다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;regexp 의 결과값을 확인할 수 있는 사이트 : &lt;a href=&quot;http://fluentular.herokuapp.com/&quot;&gt;http://fluentular.herokuapp.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/193efcf311a7efcc41c6851eab2594dd/6052f/001-03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 42.083333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAzElEQVQoz5WS2QrEIAxF/f9/lIJd3uy+bxlOIKXDdGAmcLBeY7ymurIsJU1TybJMvPdS17UQ53l+8Eu4qqokSRJpmkaO45B933WEe1DQ9G+Q43BE0XVdZZommedZ6fteQgh6EHRdd609wV5quHEcdfPdiY3DMGgiLMvytv4U6pAe0j8cUHzbNj2J0VpgmP4Ea+S4tm31R+Amxnht/Ie7Ce0hhbgSveJ6OAX7tmsb1jODHDR1iEBBTuD52BMqikLyPFfQmKMz59vmBjqFXyhXbZH8VWj7AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/193efcf311a7efcc41c6851eab2594dd/d9199/001-03.png&quot;
        srcset=&quot;/devHistoryBlog/static/193efcf311a7efcc41c6851eab2594dd/8ff5a/001-03.png 240w,
/devHistoryBlog/static/193efcf311a7efcc41c6851eab2594dd/e85cb/001-03.png 480w,
/devHistoryBlog/static/193efcf311a7efcc41c6851eab2594dd/d9199/001-03.png 960w,
/devHistoryBlog/static/193efcf311a7efcc41c6851eab2594dd/07a9c/001-03.png 1440w,
/devHistoryBlog/static/193efcf311a7efcc41c6851eab2594dd/29114/001-03.png 1920w,
/devHistoryBlog/static/193efcf311a7efcc41c6851eab2594dd/6052f/001-03.png 2030w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h3&gt;1.2. fluentd 로그 제거&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;fluentd.** tag로 들어온 이벤트는 모두 버린다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;match fluent.**&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  @type                           null
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/match&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;h2&gt;2. Filter에 대한 설정&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;✔️ 전체 코드&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;filter-kubernetes.conf: &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;filter kubernetes.**&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      @type                           kubernetes_metadata
      @id                             filter_kube_metadata
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/filter&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;filter kubernetes.**&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      @type                           record_modifier
      tag                             &lt;span class=&quot;token variable&quot;&gt;${record.dig(&quot;kubernetes&quot;&lt;span class=&quot;token operator&quot;&gt;,&lt;/span&gt; &quot;container_name&quot;).gsub(&apos;-&apos;&lt;span class=&quot;token operator&quot;&gt;,&lt;/span&gt; &apos;.&apos;)}&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;record&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        @timestamp                    &lt;span class=&quot;token variable&quot;&gt;${(Time.at(time) + (60*60*9)).strftime(&apos;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;Y-&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;m-&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;dT&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;H&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;M&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;S.&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;L+09&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;00&apos;)}&lt;/span&gt;
        cluster_name                  &lt;span class=&quot;token string&quot;&gt;&quot;xoauth-dev&quot;&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;hostname&lt;/span&gt;                      &lt;span class=&quot;token string&quot;&gt;&quot;#{ENV[&apos;K8S_NODE_NAME&apos;]}&quot;&lt;/span&gt;
        container_image               &lt;span class=&quot;token variable&quot;&gt;${record.dig(&quot;kubernetes&quot;&lt;span class=&quot;token operator&quot;&gt;,&lt;/span&gt; &quot;container_image&quot;)}&lt;/span&gt;
        pod_name                      &lt;span class=&quot;token variable&quot;&gt;${record.dig(&quot;kubernetes&quot;&lt;span class=&quot;token operator&quot;&gt;,&lt;/span&gt; &quot;pod_name&quot;)}&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/record&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/filter&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;filter kubernetes.**&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      @type                           parser
      key_name                        message
      reserve_data                    &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
      remove_key_name_field           &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;parse&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        @type                         json
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/parse&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/filter&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;filter kubernetes.**&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      @type                           record_transformer
      remove_keys                     $.kubernetes
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/filter&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;2.1. K8S Metadata 정보 포함시키기&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;kubernetes_metadata&lt;/code&gt; 타입의 필터로 인해 해당 로그 레코드를 내보낸 컨테이너에 대한 기본 메타데이터(hostname, pod&lt;em&gt;name, container&lt;/em&gt;name 등) 가 해당 레코드에 포함된다.&lt;/li&gt;
&lt;li&gt;해당 필터는 fluend 에 내장된 플러그인은 아니고, &lt;code class=&quot;language-text&quot;&gt;fluent-plugin-kubernetes_metadata_filter&lt;/code&gt; 를 설치해야 사용할 수 있다. (&lt;a href=&quot;https://github.com/fabric8io/fluent-plugin-kubernetes_metadata_filter&quot;&gt;https://github.com/fabric8io/fluent-plugin-kubernetes_metadata_filter&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;filter kubernetes.**&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  @type                           kubernetes_metadata
  @id                             filter_kube_metadata
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/filter&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;✔️ fluent-plugin-kubernetes&lt;em&gt;metadata&lt;/em&gt;filter 설치는 언제?&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;daemonset으로 설치된 fluentd pod 에서 Gemfile을 확인해보니 해당 플러그인이 포함되어 있었다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/db3cbcc11dad1ee8e0d55256f6e1fb5d/53639/001-04.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 49.16666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABYlAAAWJQFJUiTwAAABTklEQVQoz4WS266CUAxECRIUEsALARHFewygQVDB+P//VbOacF6Mnoem7N12OjMbY7lcyuVykcViIb7vy3g8lvl8rnkymUgQBDKbzSQMQ/E8TwzD+B2bzUYej4es12sFmE6nwhIywZI4jiWKIrEs63/A6/Uqt9tN9vu9MiGvVitdsN1u9QxjAFk0GAx+AzJMM2BEzw4L0jSVqqo0I7ksS7ViNBp9B6Q5SRKVBjALGO6B67qWLMu0pygKud/v0rat7HY7rX8Ank4nfRQygzQiEW8Bf71efzZgDYyxg4UQ+ACkiLzep+PxqBLxj29YUSNYSL/rut8lw44hWPS/EGDcEV3XaQ2w8/mscmE9HA7Ftm1xHEeDbwXM81x9appG5TD0fD71jj+AAJRFBKxZjAXYhCoU8qAKSBEGBP4dDgdlBkvOSGSQM0x6aTAyTfND8hsT7fxPGQXvFwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 04&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/db3cbcc11dad1ee8e0d55256f6e1fb5d/d9199/001-04.png&quot;
        srcset=&quot;/devHistoryBlog/static/db3cbcc11dad1ee8e0d55256f6e1fb5d/8ff5a/001-04.png 240w,
/devHistoryBlog/static/db3cbcc11dad1ee8e0d55256f6e1fb5d/e85cb/001-04.png 480w,
/devHistoryBlog/static/db3cbcc11dad1ee8e0d55256f6e1fb5d/d9199/001-04.png 960w,
/devHistoryBlog/static/db3cbcc11dad1ee8e0d55256f6e1fb5d/53639/001-04.png 1358w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;✔️ &lt;strong&gt;input/output 에 대한 예제&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/e638e9f47d1756d2582376b943ef4375/966c1/001-05.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 86.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAYAAADdRIy+AAAACXBIWXMAABYlAAAWJQFJUiTwAAAByUlEQVQ4y41U2XKCQBDkPakcqKDIIYcXgqgoaGKZVI7//6TJ9MhS3vGha2aX3WZ6ekBrOxHtEZLlDajj9gWmHVKj7ZFuutTs9O6ER1ownFK2fKc0f6Ni+01TzvvxnKLxjHqDlGx/REY3uAstyycN1eASohOMJe/2hpL7TOiEsRxUF66hJjTtQOR2XJaNnKUaXZ8eXwx6eG5JfNLbd0MDEapDHzsMS3oYkW44NV4N+zJa59AgSfUszkqJLu9hHzJumdCyzvuoedGE0sWGxtOVIGLyXj8R4Bkg+ckagLLTXmowAE7DAERUpy4iV/CipCbCWUARHrkMwjgraLH+oIQrRbWQHs9KClm+LW5PpceYy0McunvgckiDyYJyJpwwSbn9oXm5kzyZryViTjGT6JspU3A8e2eEw3RJ690vzVZbIcg3nzLoqDCqAJMgsVlVB/KLhEiCUUYbJpwXO8qYtHj/EoNG/CKRz0ArsEal6gu6KhlNHya5jA/gVtXgEr4YZYwTVIaxMej9dUI+BGPQSwBE2JN5q+Q1DuK/kvFWGICIytTYnI7FpZ/B2RziEsrfSxrXuZJ9i/Di38aUhb//bvnf12DoZpWLtPuB83+xMdJoHZd7egAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 05&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/e638e9f47d1756d2582376b943ef4375/d9199/001-05.png&quot;
        srcset=&quot;/devHistoryBlog/static/e638e9f47d1756d2582376b943ef4375/8ff5a/001-05.png 240w,
/devHistoryBlog/static/e638e9f47d1756d2582376b943ef4375/e85cb/001-05.png 480w,
/devHistoryBlog/static/e638e9f47d1756d2582376b943ef4375/d9199/001-05.png 960w,
/devHistoryBlog/static/e638e9f47d1756d2582376b943ef4375/07a9c/001-05.png 1440w,
/devHistoryBlog/static/e638e9f47d1756d2582376b943ef4375/966c1/001-05.png 1694w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h3&gt;2.2. 이벤트 레코드에 필드 추가하기&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;record_modifier 타입의 필터를 사용하여 필드를 추가/수정 할 수 있다.&lt;/li&gt;
&lt;li&gt;추가/수정되는 필드는 &lt;code class=&quot;language-text&quot;&gt;&amp;lt;record&amp;gt;&lt;/code&gt; 내에 정의 해주면 된다.&lt;/li&gt;
&lt;li&gt;기본 내장된 플러그인은 아니며, &lt;code class=&quot;language-text&quot;&gt;fluent-plugin-record-modifier&lt;/code&gt; 플러그인을 설치해줘야 한다. (&lt;a href=&quot;https://github.com/repeatedly/fluent-plugin-record-modifier&quot;&gt;https://github.com/repeatedly/fluent-plugin-record-modifier&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;filter kubernetes.**&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  @type                           record_modifier
  tag                             &lt;span class=&quot;token variable&quot;&gt;${record.dig(&quot;kubernetes&quot;&lt;span class=&quot;token operator&quot;&gt;,&lt;/span&gt; &quot;container_name&quot;).gsub(&apos;-&apos;&lt;span class=&quot;token operator&quot;&gt;,&lt;/span&gt; &apos;.&apos;)}&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;record&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    @timestamp                    &lt;span class=&quot;token variable&quot;&gt;${(Time.at(time) + (60*60*9)).strftime(&apos;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;Y-&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;m-&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;dT&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;H&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;M&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;S.&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;L+09&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;00&apos;)}&lt;/span&gt;
    cluster_name                  &lt;span class=&quot;token string&quot;&gt;&quot;xoauth-dev&quot;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;hostname&lt;/span&gt;                      &lt;span class=&quot;token string&quot;&gt;&quot;#{ENV[&apos;K8S_NODE_NAME&apos;]}&quot;&lt;/span&gt;
    container_image               &lt;span class=&quot;token variable&quot;&gt;${record.dig(&quot;kubernetes&quot;&lt;span class=&quot;token operator&quot;&gt;,&lt;/span&gt; &quot;container_image&quot;)}&lt;/span&gt;
    pod_name                      &lt;span class=&quot;token variable&quot;&gt;${record.dig(&quot;kubernetes&quot;&lt;span class=&quot;token operator&quot;&gt;,&lt;/span&gt; &quot;pod_name&quot;)}&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/record&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/filter&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;✔️ fluent-plugin-record-modifier 설치는 언제?&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;위 k8s metadata 필터와 동일하게 daemonset pod 의 Gemfile 에 명시가 되어있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/439a3524ae30b1fd3d6179cdee6ce244/b1001/001-06.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 7.916666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAACCAYAAABYBvyLAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAf0lEQVQI1z2MsQqFIABFQyhoDYJCjZqksSF1k/Av+oGGCvT/hxPP4Q2He85yqxAC1lqcc8QYC/u+cxwH27bhvWddV5ZlQWuNMabQdR193zNNE8MwMM9z8SqlxHVdPM/Dfd+871s651z8PE/GcURKWQ6UUrRtixCCuq5pmua/Pz50aD7OuGu0YAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 06&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/439a3524ae30b1fd3d6179cdee6ce244/d9199/001-06.png&quot;
        srcset=&quot;/devHistoryBlog/static/439a3524ae30b1fd3d6179cdee6ce244/8ff5a/001-06.png 240w,
/devHistoryBlog/static/439a3524ae30b1fd3d6179cdee6ce244/e85cb/001-06.png 480w,
/devHistoryBlog/static/439a3524ae30b1fd3d6179cdee6ce244/d9199/001-06.png 960w,
/devHistoryBlog/static/439a3524ae30b1fd3d6179cdee6ce244/b1001/001-06.png 1380w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;✔️ record_transformer 와의 차이점은?&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;속도가 더 빠르다고 한다. 그외의 내용은 깃헙을 참고한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2.3. 서비스 Application에서 출력한 로그 파싱&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;parser&lt;/code&gt; 타입의 필터는 key_name에 명시된 필드를 파싱하고 이벤트 레코드를 파싱된 결과로 변경한다.&lt;/li&gt;
&lt;li&gt;위 input의 &lt;code class=&quot;language-text&quot;&gt;&amp;lt;source&amp;gt;&lt;/code&gt; 태그에서 message 키에 매핑된 application 로그를 파싱한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;filter kubernetes.**&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  @type                           parser
  key_name                        message
  reserve_data                    &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
  remove_key_name_field           &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;parse&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    @type                         json
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/parse&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/filter&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;✔️ reserve_data&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;파싱된 결과에서 원래 key-value 쌍을 유지한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;filter foo.bar&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  @type parser
  key_name log
  reserve_data &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;parse&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    @type json
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/parse&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/filter&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/5d28144d91159a4e450fa3d9264dce4c/00e09/001-07.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 34.166666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAABYlAAAWJQFJUiTwAAABB0lEQVQoz5VR2W7DMAzL///khrZJcye+z4ST1CHI42aAsE1YlEg3znkobWCdw7YraDoba2Gtg1IapRT8ZZ3nKWhiSjAkagWBxNx118bBh4gQE2LKsjOYS7mg1ONCLpWaVzTGejy7Ht/PDv20oBsmtP2I13sgfkD7HvFoe7zo/B5nfD1adP0kb+dNYVp2jPMGTTo+ZjQhRngf4G7wIQgXaZpaP51L/QVFwFym/QJNW48DB1vWxkheLCR2BVayTDnjv6txlAeP3JOdVRlM6/6xsWwYphXzqoRje+uu5S1zYjEkuBsC5dzwZOO8UvGChYpmKl42FqVCgvMR3JQhAv6zB8pLPuoG/qgfz0UeALzdiZEAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 07&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/5d28144d91159a4e450fa3d9264dce4c/d9199/001-07.png&quot;
        srcset=&quot;/devHistoryBlog/static/5d28144d91159a4e450fa3d9264dce4c/8ff5a/001-07.png 240w,
/devHistoryBlog/static/5d28144d91159a4e450fa3d9264dce4c/e85cb/001-07.png 480w,
/devHistoryBlog/static/5d28144d91159a4e450fa3d9264dce4c/d9199/001-07.png 960w,
/devHistoryBlog/static/5d28144d91159a4e450fa3d9264dce4c/07a9c/001-07.png 1440w,
/devHistoryBlog/static/5d28144d91159a4e450fa3d9264dce4c/00e09/001-07.png 1854w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;✔️ remove&lt;em&gt;key&lt;/em&gt;name_field&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;파싱에 성공하면 key_name에 해당하는 필드를 지운다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;filter foo.bar&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  @type parser
  key_name log
  reserve_data &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
  remove_key_name_field &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;parse&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    @type json
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/parse&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/filter&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/62abac888cbac04b8d93496b763175a5/6fa81/001-08.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 16.249999999999996%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAd0lEQVQI15WMWw4DIQhF3f9K2/GJ4GO0ya1o2/+anFxAOCYzQ2ERJCJQZkgpECnIq55z4p9niAt8yrA+IRLDR4ILafOt7afXf82w9qV2tD5Q+71Y2W6M+YLRpaf1eFzuHHsl4nJh55nFDUtdooayZCo6wvETq/ANTR/nrsCdbAEAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 08&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/62abac888cbac04b8d93496b763175a5/d9199/001-08.png&quot;
        srcset=&quot;/devHistoryBlog/static/62abac888cbac04b8d93496b763175a5/8ff5a/001-08.png 240w,
/devHistoryBlog/static/62abac888cbac04b8d93496b763175a5/e85cb/001-08.png 480w,
/devHistoryBlog/static/62abac888cbac04b8d93496b763175a5/d9199/001-08.png 960w,
/devHistoryBlog/static/62abac888cbac04b8d93496b763175a5/07a9c/001-08.png 1440w,
/devHistoryBlog/static/62abac888cbac04b8d93496b763175a5/6fa81/001-08.png 1856w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h3&gt;2.4. 불필요한 K8S Metadata 정보 제거&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;위 record&lt;em&gt;modifier filter에서 필요한 kubernetes 메타 정보만 새로 추가했으므로, kubernetes&lt;/em&gt;metadata filter에서 추가한 메타정보를 모두 삭제한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;filter kubernetes.**&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  @type                           record_transformer
  remove_keys                     $.kubernetes
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/filter&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;위 필터를 추가하지 않으면 불필요한 kubernetes 메타정보들이 표시된다.&lt;/li&gt;
&lt;li&gt;따라서 kubernetes_metadata filter 에서 생성된 메타정보 중, 필요한 정보만 새로운 key로 이벤트 레코드에 추가해주는것이 좋다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/27ef619477b99d6d6e557d5980c50b95/f51c0/001-09.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 31.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAwElEQVQY03WRCw6EMAhEvf9Z1dKPWovtLGA1rps1mUgtvAEcfAjwPoC8RymM1iBqt47jgHNOcjxCjCAik55TSrdCiPYeHHkp8Fi3LMX1W7WZyThO0DwWeJVvKr3nR+4VG3CaSRwStrzfoDOhYe/AZVkt5l78T4OOq9AQk3RTuhjVRgaYWSZQw4AoI+v9ey1PGZDo3M++F+miA+sJ1FhBzAdyzmaghdfobw3UgVqoz+mODmy2t2ma7UeYqXXYAe1XH2r11XDUD/i6AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 09&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/27ef619477b99d6d6e557d5980c50b95/d9199/001-09.png&quot;
        srcset=&quot;/devHistoryBlog/static/27ef619477b99d6d6e557d5980c50b95/8ff5a/001-09.png 240w,
/devHistoryBlog/static/27ef619477b99d6d6e557d5980c50b95/e85cb/001-09.png 480w,
/devHistoryBlog/static/27ef619477b99d6d6e557d5980c50b95/d9199/001-09.png 960w,
/devHistoryBlog/static/27ef619477b99d6d6e557d5980c50b95/07a9c/001-09.png 1440w,
/devHistoryBlog/static/27ef619477b99d6d6e557d5980c50b95/29114/001-09.png 1920w,
/devHistoryBlog/static/27ef619477b99d6d6e557d5980c50b95/f51c0/001-09.png 2994w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;h2&gt;3. Output에 대한 설정&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;match **&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  @type copy
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;store&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    @type                         kafka2
    @id                           out_kafka
    brokers                       logis-kafka.dev.kakaoi.io:9092
    max_send_retries              &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;
    required_acks                 &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;

    default_topic                 xoauth-dev

    exception_backup              &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;
    compression_codec             &lt;span class=&quot;token function&quot;&gt;gzip&lt;/span&gt;

    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;format&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      @type                       json
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/format&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;

    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;buffer topic,tag&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      @type                       &lt;span class=&quot;token function&quot;&gt;file&lt;/span&gt;
      path                        /var/log/td-agent/buffer/td
      flush_interval              5s
      chunk_limit_size            16M
      queue_limit_length          &lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt;
      retry_forever               &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/buffer&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/store&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;/match&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[/var/run/docker.sock의 permission denied 발생하는 경우]]></title><description><![CDATA[dependent child images로 인한 오류]]></description><link>https://ssongey.github.io/errors/posts/2022-09-14--001</link><guid isPermaLink="false">https://ssongey.github.io/errors/posts/2022-09-14--001</guid><pubDate>Wed, 14 Sep 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;아래 명령어 실행 후 docker 재시작 또는 해당 유저 ssh 재접속&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# usermod로 사용자를 docker 그룹에 추가&lt;/span&gt;
$ &lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;usermod&lt;/span&gt; -aG docker &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;계정명&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;p&gt;만약 위 명령어 실행 후 터미널 재접속까지 했으나 permission denied 이 계속 발생한다면..&lt;br&gt;
/var/run/docker.sock 파일의 권한을 666으로 변경한다.&lt;br&gt;
그럼 그룹 내 다른 사용자도 접근 가능하게 변경된다.  &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# chmod 이용하여 모든 유저 읽기/쓰기 가능하도록 파일 권한 변경&lt;/span&gt;
$ &lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;chmod&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;666&lt;/span&gt; /var/run/docker.sock&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[swap 메모리 초기화]]></title><link>https://ssongey.github.io/history/posts/2022-09-03--001</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2022-09-03--001</guid><pubDate>Sat, 03 Sep 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;리눅스에서 일시적 메모리 사용의 증가로 swap을 사용하게될 경우 메모리에 여유가 생겨도 swap 메모리는 자동으로 초기화되지 않는다.&lt;br&gt;
이것을 수동으로 초기화하려면 아래의 명령을 입력하면 된다. 당연히 root 권한에서 실행해야 한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ swapoff -a &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;swapon&lt;/span&gt; -a&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;p&gt;swapoff 처리에 시간이 조금 오래 걸릴 수 있는데 서버가 멈춘 것은 아니므로 걱정하지 않아도 된다.&lt;br&gt;
swap 메모리에서 필요한 부분을 물리 메모리로 옮기는 처리중인 것이다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[클러스터 이전 작업 로그]]></title><link>https://ssongey.github.io/works/posts/2022-08-23--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2022-08-23--001</guid><pubDate>Tue, 23 Aug 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;이번에 인프라 이전 작업이 잦아질 듯 싶다.&lt;br&gt;
작업 기록을 정리하고 스크립트를 만들 수 있는 곳을 찾아봐야겠다.&lt;/p&gt;
&lt;h1&gt;✔️ 깃헙 레포 미러링&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;공동체 깃헙에서 kep 깃헙으로 미러링 필요시&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; clone --mirror &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;기존 레포 주소&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
$ &lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;기존 레포명&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;.git
$ &lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; remote set-url --push origin &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;신규 레포 주소&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
$ &lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push --mirror&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;✔️ 클러스터 생성&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;IKE 클러스터 생성시에 커버로스 인증을 위해 아래 스크립트 수행이 필요하다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; -s https://kenopy.kakaoicloud.in/kenopy/IKE/kenopy-ike.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;✔️ 클러스터 세팅&lt;/h1&gt;
&lt;h2&gt;1. ingress controller 설치&lt;/h2&gt;
&lt;h3&gt;&lt;strong&gt;1.1 도커파일 세팅&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;필요시 &lt;a href=&quot;https://hub.docker.com/r/nginx/nginx-ingress&quot;&gt;nginx-ingress docker hub 사이트&lt;/a&gt;에서 도커 이미지를 받는다.  &lt;/li&gt;
&lt;li&gt;official 사이트에서 도커 이미지 받아서 사내 registry에 올릴 경우, 아래 명령어를 이용한다.  &lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ docker pull &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;official docker image&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 이미지명 변경&lt;/span&gt;
$ docker image tag &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;이미지ID&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;변경할 이름&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;:&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;태그&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
또는
$ docker image tag &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;변경전 이름&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;:&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;태그&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;변경할 이름&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;:&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;태그&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

$ docker push &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;변경된 이름&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;:&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;태그&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;터미널에서 docker login 명령어&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;패스워드/CREDENTIAL_SECRET&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; docker login &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;registry 주소&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; -u &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;아이디/CREDENTIAL_ID&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; --password-stdin&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;&lt;strong&gt;1.2. 설치&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;k8s 매니페스트로 설치&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/kubernetes/ingress-nginx/blob/main/deploy/static/provider/cloud/deploy.yaml&quot;&gt;https://github.com/kubernetes/ingress-nginx/blob/main/deploy/static/provider/cloud/deploy.yaml&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://raw.githubusercontent.com/kakaoicloud-guide/kubernetes-engine/main/guide-samples/settingIC/ingress-nginx/controller-v1.3.1/deploy.yml&quot;&gt;https://raw.githubusercontent.com/kakaoicloud-guide/kubernetes-engine/main/guide-samples/settingIC/ingress-nginx/controller-v1.3.1/deploy.yml&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;헬름으로 설치&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;헬름레포 추가&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ helm repo &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; ingress-nginx https://kubernetes.github.io/ingress-nginx
&lt;span class=&quot;token string&quot;&gt;&quot;ingress-nginx&quot;&lt;/span&gt; has been added to your repositories 

$ helm repo update
Hang tight &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; we grab the latest from your chart repositories&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;.
&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;.Successfully got an update from the &lt;span class=&quot;token string&quot;&gt;&quot;ingress-nginx&quot;&lt;/span&gt; chart repository
Update Complete. ⎈Happy Helming&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;⎈&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;배포&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ helm &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; ingress-nginx ingress-nginx/ingress-nginx &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    --version &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;버전&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    --set controller.hostNetwork&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;true &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    --namespace ingress-nginx --create-namespace&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;strong&gt;1.3. 배포 확인&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;파드 정상 작동 확인&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ kubectl get pods -n ingress-nginx &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
-l app.kubernetes.io/name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;ingress-nginx --watch&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;설치 완료 후 LoadBalancer EXTERNAL-IP(엔드포인트) 확인&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ kubectl get &lt;span class=&quot;token function&quot;&gt;service&lt;/span&gt; -n ingress-nginx
NAME                                 TYPE           CLUSTER-IP      EXTERNAL-IP       PORT&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;S&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;                      AGE
ingress-nginx-controller             LoadBalancer   &lt;span class=&quot;token number&quot;&gt;10.101&lt;/span&gt;.148.33   xxx.xxx.xxx.xxx   &lt;span class=&quot;token number&quot;&gt;80&lt;/span&gt;:31027/TCP,443:31138/TCP   36m
ingress-nginx-controller-admission   ClusterIP      &lt;span class=&quot;token number&quot;&gt;10.104&lt;/span&gt;.56.176   &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;none&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;            &lt;span class=&quot;token number&quot;&gt;443&lt;/span&gt;/TCP                      36m&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;h2&gt;2. secret 생성&lt;/h2&gt;
&lt;h3&gt;&lt;strong&gt;✔️ docker-registry&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;만약, 배포시 사용하는 registry가 public이 아닐 경우, docker 인증을 위한 secret 등록이 필요하다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ kubectl create secret docker-registry &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;docker-registry secret명&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
--docker-server&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;registry 주소&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
--docker-username&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;아이디/CREDENTIAL_ID&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
--docker-password&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;패스워드/CREDENTIAL_SECRET&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
-n &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;namespace&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;strong&gt;✔️ tls 인증서&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;https 프로토콜 사용을 위해 tls 인증서를 등록한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;kubectl create secret tls &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;tls secret명&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
--key &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;private key&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; 
--cert &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;cert&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; 
-n &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;namespace&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;만약 private key 가 암호화 되어있을 경우 openssl 을 이용하여 복호화하여 tls secret으로 등록한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ openssl rsa -in key.pem -out decrypted_key.pem&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;h2&gt;3. proxy daemonset 설치&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;사내에서는 외부통신과 내부통신에 대한 proxy/non-proxy 설정이 필요하다.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;아래 파일을 참고해서 http-proxy 데몬셋을 적용한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; DaemonSet
&lt;span class=&quot;token key atrule&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; apps/v1
&lt;span class=&quot;token key atrule&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; set&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;http&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;proxy
  &lt;span class=&quot;token key atrule&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; set&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;http&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;proxy
&lt;span class=&quot;token key atrule&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;selector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;matchLabels&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; set&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;http&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;proxy
  &lt;span class=&quot;token key atrule&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; set&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;http&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;proxy
    &lt;span class=&quot;token key atrule&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;hostPID&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;containers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; startup&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;script
          &lt;span class=&quot;token key atrule&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;아래 명령어를 실행할 수 있는 linux 이미지&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;securityContext&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token key atrule&quot;&gt;privileged&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; PROXY
              &lt;span class=&quot;token key atrule&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;proxy 주소&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; NO_PROXY
              &lt;span class=&quot;token key atrule&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;non&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;proxy 주소들&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; nsenter &lt;span class=&quot;token comment&quot;&gt;# namespace enter의 약어. 격리된 namespace에 진입하는 명령어&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;mount=/proc/1/ns/mnt
            &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; sh
            &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;xc
            &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;token scalar string&quot;&gt;
              # Create environment file
              cloud-init-per always set_proxy_to_environment cat &amp;lt;&amp;lt; EOF &gt;&gt; /etc/environment
              http_proxy=$PROXY
              https_proxy=$PROXY
              HTTP_PROXY=$PROXY
              HTTPS_PROXY=$PROXY
              no_proxy=$NO_PROXY
              NO_PROXY=$NO_PROXY
              EOF
              # Configure containerd with proxy
              cloud-init-per always use_environment_to_containerd tee &amp;lt;&amp;lt;EOF /etc/systemd/system/containerd.service.d/proxy.conf &gt;/dev/null
              [Service]
              EnvironmentFile=/etc/environment
              EOF
              # Reload the daemon and restart containerd
              cloud-init-per always reload_daemon_for_containerd systemctl daemon-reload
              cloud-init-per always restart_containerd systemctl restart containerd
              trap : TERM INT
              sleep infinity &amp;amp; wait&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;적용&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;$ kubectl apply &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;f http&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;proxy&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;daemonset.yaml&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;h1&gt;✔️ EFK 세팅&lt;/h1&gt;
&lt;h2&gt;1. ES 설치는 인프라팀에 요청&lt;/h2&gt;
&lt;h2&gt;2. Kibana 설치&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;yaml 파일&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; apps/v1
&lt;span class=&quot;token key atrule&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Deployment
&lt;span class=&quot;token key atrule&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; kibana
  &lt;span class=&quot;token key atrule&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; kibana
  &lt;span class=&quot;token key atrule&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; kibana
&lt;span class=&quot;token key atrule&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;replicas&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;selector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;matchLabels&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; kibana
  &lt;span class=&quot;token key atrule&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; kibana
    &lt;span class=&quot;token key atrule&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;containers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; kibana
        &lt;span class=&quot;token key atrule&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;kibana 이미지 주소&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;containerPort&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5601&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; ELASTICSEARCH_HOSTS
              &lt;span class=&quot;token key atrule&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;ES 주소&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;---&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; v1
&lt;span class=&quot;token key atrule&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Service
&lt;span class=&quot;token key atrule&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; kibana
  &lt;span class=&quot;token key atrule&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; kibana
  &lt;span class=&quot;token key atrule&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; kibana
&lt;span class=&quot;token key atrule&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; http
      &lt;span class=&quot;token key atrule&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;80&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;protocol&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; TCP
      &lt;span class=&quot;token key atrule&quot;&gt;targetPort&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5601&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;selector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; kibana
&lt;span class=&quot;token punctuation&quot;&gt;---&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; networking.k8s.io/v1
&lt;span class=&quot;token key atrule&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Ingress
&lt;span class=&quot;token key atrule&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; kibana&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;ingress
  &lt;span class=&quot;token key atrule&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; kibana
  &lt;span class=&quot;token key atrule&quot;&gt;annotations&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;nginx.ingress.kubernetes.io/rewrite-target&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; /
    &lt;span class=&quot;token key atrule&quot;&gt;kubernetes.io/ingress.class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; nginx
&lt;span class=&quot;token key atrule&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;rules&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;Kibana 호스트주소&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;http&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;paths&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;pathType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Prefix
        &lt;span class=&quot;token key atrule&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/&quot;&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;backend&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; kibana
            &lt;span class=&quot;token key atrule&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
              &lt;span class=&quot;token key atrule&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;80&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;h2&gt;3. Log Aggregator 서버 설치&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;fluentd 로 로그 수집서버를 세팅한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;strong&gt;3.1. vm 생성 후 apt 업데이트&lt;/strong&gt;&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;$ sudo apt &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;y update&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;&lt;strong&gt;3.2. td-agent 설치&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;참고: &lt;a href=&quot;https://docs.fluentd.org/installation/install-by-deb&quot;&gt;https://docs.fluentd.org/installation/install-by-deb&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; -fsSL https://toolbelt.treasuredata.com/sh/install-ubuntu-bionic-td-agent4.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sh&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 설치 후 fluentd 버전 확인&lt;/span&gt;
$ /opt/td-agent/bin/fluentd --version&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;만약 아래와 같은 오류가 발생한다면, /tmp 디렉토리의 권한을 777로 변경해준 후, 작업완료되면 775로 롤백한다&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# 에러:&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Couldn&apos;t create temporary file /tmp/apt.conf.** for passing config to apt-key&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;##&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# 조치:&lt;/span&gt;
$ &lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;chmod&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;777&lt;/span&gt; /tmp
&lt;span class=&quot;token comment&quot;&gt;# 작업 완료 후 롤백&lt;/span&gt;
$ &lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;chmod&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;775&lt;/span&gt; /tmp&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3.3. /etc/td-agent/td-agent.conf 파일 수정&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;기본세팅&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&amp;lt;system&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;
  @log_level info 
  workers    8 &lt;span class=&quot;token comment&quot;&gt;# 필요에 따라 워커수 조절&lt;/span&gt;
&amp;lt;/system&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;

&amp;lt;source&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;
  @type     monitor_agent
  port      24420
&amp;lt;/source&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;

&amp;lt;source&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;
  @id   in_forward
  @type forward
  port 24224
  &amp;lt;parse&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;
    @type json
    type_key @timestamp
    time_format %Y&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;%m&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;%dT%H&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;%M&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;%S.%N%z
    localtime
  &amp;lt;/parse&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;
&amp;lt;/source&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;

&amp;lt;match tag_prefix.&lt;span class=&quot;token important&quot;&gt;**&gt;&lt;/span&gt;
  @type copy
  &amp;lt;store&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;
    @id   copy_stdout
    @type stdout
  &amp;lt;/store&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;
  &amp;lt;store&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;
    @type                         elasticsearch
    @id                           out_es
    include_tag_key               true
    host                          &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;es 주소&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    port                          9200
    scheme                        http
    reload_connections            &quot;&lt;span class=&quot;token comment&quot;&gt;#{ENV[&apos;ELASTICSEARCH_RELOAD_CONNECTIONS&apos;] || &apos;true&apos;}&quot;&lt;/span&gt;
    logstash_prefix               $&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;tag&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    logstash_format               true
    logstash_dateformat           %Y.%m.%d
    type_name                     fluentd
    id_key                        _uuid
    &amp;lt;buffer tag&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;
      @type                       file
      path                        /var/log/td&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;agent/buffer/es/
      flush_thread_count          1
      chunk_limit_size            16mb
      queue_limit_length          2560
      flush_interval              5s
      flush_at_shutdown           true
      retry_max_times             10
      retry_forever               false
    &amp;lt;/buffer&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;
  &amp;lt;/store&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;
&amp;lt;/match&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;해당 VM 인바운드 정책에 forward의 포트 24224 허용 필요!!!&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;3.4에서 서비스 실행 후 acl 확인&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ telnet &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;vm 주소 또는 로그어그리게이터서버 도메인주소&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;24224&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;strong&gt;3.4. td-agent 실행&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;서비스 실행&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; systemctl start td-agent.service&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;로그 확인&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;tail&lt;/span&gt; -f /var/log/td-agent/td-agent.log&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;h2&gt;4. fluentd 데몬셋 세팅&lt;/h2&gt;
&lt;h4&gt;4.1. RBAC 설정&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; v1
&lt;span class=&quot;token key atrule&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; ServiceAccount
&lt;span class=&quot;token key atrule&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; fluentd&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;service&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;account
  &lt;span class=&quot;token key atrule&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; fluentd

&lt;span class=&quot;token punctuation&quot;&gt;---&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; rbac.authorization.k8s.io/v1
&lt;span class=&quot;token key atrule&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; ClusterRole
&lt;span class=&quot;token key atrule&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; fluentd&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;cluster&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;role
  &lt;span class=&quot;token key atrule&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; fluentd
&lt;span class=&quot;token key atrule&quot;&gt;rules&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;apiGroups&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;resources&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; pods
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; namespaces
    &lt;span class=&quot;token key atrule&quot;&gt;verbs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; get
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; list
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; watch
&lt;span class=&quot;token punctuation&quot;&gt;---&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; ClusterRoleBinding
&lt;span class=&quot;token key atrule&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; rbac.authorization.k8s.io/v1
&lt;span class=&quot;token key atrule&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; fluentd&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;cluster&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;role&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;binding
  &lt;span class=&quot;token key atrule&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; fluentd
&lt;span class=&quot;token key atrule&quot;&gt;roleRef&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; ClusterRole
  &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; fluentd&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;cluster&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;role
  &lt;span class=&quot;token key atrule&quot;&gt;apiGroup&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; rbac.authorization.k8s.io
&lt;span class=&quot;token key atrule&quot;&gt;subjects&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; ServiceAccount
    &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; fluentd&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;service&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;account
    &lt;span class=&quot;token key atrule&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; fluentd&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;4.2. input, filter, output 에 대한 기본 설정 (configmap.yaml)&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; v1
&lt;span class=&quot;token key atrule&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; ConfigMap
&lt;span class=&quot;token key atrule&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; fluentd&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;configmap
  &lt;span class=&quot;token key atrule&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; fluentd
  &lt;span class=&quot;token key atrule&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;k8s-app&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; fluentd&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;logging
    &lt;span class=&quot;token key atrule&quot;&gt;kubernetes.io/cluster-service&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;true&quot;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; v1
&lt;span class=&quot;token key atrule&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;fluent.conf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;token scalar string&quot;&gt;
    &amp;lt;system&gt;
      workers 1
      @log_level info
    &amp;lt;/system&gt;
    @include input-kubernetes.conf
    @include filter-kubernetes.conf&lt;/span&gt;

    &amp;lt;match &lt;span class=&quot;token important&quot;&gt;**&gt;&lt;/span&gt;
      @type copy
      &amp;lt;store&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;
        @type                         forward
        @id                           out_ai_forward
        expire_dns_cache              60s
        &amp;lt;server&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;
          host                        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;로그어그리게이터 서버주소&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &amp;lt;/server&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;
        &amp;lt;buffer&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;
          @type                       memory
          flush_interval              5s
          flush_at_shutdown           true
        &amp;lt;/buffer&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;
      &amp;lt;/store&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;
    &amp;lt;/match&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;

  &lt;span class=&quot;token key atrule&quot;&gt;input-kubernetes.conf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;token scalar string&quot;&gt;
    &amp;lt;match fluent.**&gt;
      @type                           null
    &amp;lt;/match&gt;
    &amp;lt;source&gt;
      @type                           tail
      @id                             in_tail_container_logs
      path                            /var/log/containers/*.log
      pos_file                        /var/log/fluentd-containers.log.pos
      exclude_path                    [&quot;/var/log/containers/fluentd*.log&quot;]
      tag                             kubernetes.*
      read_from_head                  &quot;#{ENV[&apos;FLUENTD_INPUT_READ_FROM_HEAD&apos;] || &apos;false&apos;}&quot;
      limit_recently_modified         &quot;#{ENV[&apos;LIMIT_RECENTLY_MODIFIED&apos;] || &apos;120m&apos;}&quot;
      rotate_wait                     0
      enable_stat_watcher             false
      &amp;lt;parse&gt;
        @type                         regexp
        expression                    /^(?&amp;lt;time&gt;[^ ]+) (?&amp;lt;stream&gt;stdout|stderr) (?&amp;lt;flags&gt;[^ ]+) (?&amp;lt;message&gt;.*)$/
      &amp;lt;/parse&gt;
    &amp;lt;/source&gt;&lt;/span&gt;

  &lt;span class=&quot;token key atrule&quot;&gt;filter-kubernetes.conf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;token scalar string&quot;&gt;
    &amp;lt;filter kubernetes.**&gt;
      @type                           kubernetes_metadata
      @id                             filter_kube_metadata
    &amp;lt;/filter&gt;&lt;/span&gt;
    
    
    &amp;lt;filter kubernetes.&lt;span class=&quot;token important&quot;&gt;**&gt;&lt;/span&gt;
      @type                           record_modifier
      tag                             $&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;record.dig(&quot;kubernetes&quot;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &quot;container_name&quot;).gsub(&apos;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&apos;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &apos;.&apos;)&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &amp;lt;record&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;
        @timestamp                    $&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;(Time.at(time) + (60&lt;span class=&quot;token important&quot;&gt;*60*9)).strftime(&apos;%Y-%m-%dT%H:%M:%S.%L+09:00&apos;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        cluster_name                  &quot;cluster name&quot;
        hostname                      &quot;&lt;span class=&quot;token comment&quot;&gt;#{ENV[&apos;K8S_NODE_NAME&apos;]}&quot;&lt;/span&gt;
        container_image               $&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;record.dig(&quot;kubernetes&quot;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &quot;container_image&quot;)&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        pod_name                      $&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;record.dig(&quot;kubernetes&quot;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &quot;pod_name&quot;)&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &amp;lt;/record&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;
    &amp;lt;/filter&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;
    
    &amp;lt;filter kubernetes.&lt;span class=&quot;token important&quot;&gt;**&gt;&lt;/span&gt;
      @type                           parser
      key_name                        message
      reserve_data                    true
      remove_key_name_field           true
      &amp;lt;parse&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;
        @type                         json
      &amp;lt;/parse&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;
    &amp;lt;/filter&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;
    
    &amp;lt;filter kubernetes.&lt;span class=&quot;token important&quot;&gt;**&gt;&lt;/span&gt;
      @type                           record_transformer
      remove_keys                     $.kubernetes
    &amp;lt;/filter&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;4.3. 데몬셋 설정&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;fluentd-daemonset 도커 이미지 official github
- &lt;a href=&quot;https://github.com/fluent/fluentd-kubernetes-daemonset&quot;&gt;https://github.com/fluent/fluentd-kubernetes-daemonset&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; apps/v1
&lt;span class=&quot;token key atrule&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; DaemonSet
&lt;span class=&quot;token key atrule&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; fluentd&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;daemonset
  &lt;span class=&quot;token key atrule&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; fluentd
  &lt;span class=&quot;token key atrule&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;k8s-app&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; fluentd&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;logging
    &lt;span class=&quot;token key atrule&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; v1
    &lt;span class=&quot;token key atrule&quot;&gt;kubernetes.io/cluster-service&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;true&quot;&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;selector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;matchLabels&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;k8s-app&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; fluentd&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;logging
      &lt;span class=&quot;token key atrule&quot;&gt;kubernetes.io/cluster-service&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;true&quot;&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; v1
  &lt;span class=&quot;token key atrule&quot;&gt;updateStrategy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; RollingUpdate
  &lt;span class=&quot;token key atrule&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;k8s-app&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; fluentd&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;logging
        &lt;span class=&quot;token key atrule&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; v1
        &lt;span class=&quot;token key atrule&quot;&gt;kubernetes.io/cluster-service&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;true&quot;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;hostNetwork&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;dnsPolicy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; ClusterFirstWithHostNet
      &lt;span class=&quot;token key atrule&quot;&gt;serviceAccount&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; fluentd&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;service&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;account
      &lt;span class=&quot;token key atrule&quot;&gt;serviceAccountName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; fluentd&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;service&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;account
      &lt;span class=&quot;token key atrule&quot;&gt;tolerations&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; node&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;role.kubernetes.io/master
          &lt;span class=&quot;token key atrule&quot;&gt;effect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; NoExecute
      &lt;span class=&quot;token key atrule&quot;&gt;containers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; fluentd
          &lt;span class=&quot;token key atrule&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;fluentd 이미지&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;imagePullPolicy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; IfNotPresent
          &lt;span class=&quot;token key atrule&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; K8S_NODE_NAME
              &lt;span class=&quot;token key atrule&quot;&gt;valueFrom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;token key atrule&quot;&gt;fieldRef&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
                  &lt;span class=&quot;token key atrule&quot;&gt;fieldPath&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; spec.nodeName
          &lt;span class=&quot;token key atrule&quot;&gt;resources&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token key atrule&quot;&gt;limits&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
              &lt;span class=&quot;token key atrule&quot;&gt;memory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 400Mi
            &lt;span class=&quot;token key atrule&quot;&gt;requests&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
              &lt;span class=&quot;token key atrule&quot;&gt;cpu&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 100m
              &lt;span class=&quot;token key atrule&quot;&gt;memory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 200Mi
          &lt;span class=&quot;token key atrule&quot;&gt;volumeMounts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; varlog
              &lt;span class=&quot;token key atrule&quot;&gt;mountPath&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; /var/log
            &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; varlibdockercontainers
              &lt;span class=&quot;token key atrule&quot;&gt;mountPath&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; /var/lib/docker/containers
              &lt;span class=&quot;token key atrule&quot;&gt;readOnly&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; resolvconf
              &lt;span class=&quot;token key atrule&quot;&gt;mountPath&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; /etc/resolv.conf
            &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; tz&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;config
              &lt;span class=&quot;token key atrule&quot;&gt;mountPath&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; /etc/localtime
              &lt;span class=&quot;token key atrule&quot;&gt;readOnly&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; fluentd&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;config
              &lt;span class=&quot;token key atrule&quot;&gt;mountPath&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; /fluentd/etc/
      &lt;span class=&quot;token key atrule&quot;&gt;terminationGracePeriodSeconds&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; varlog
          &lt;span class=&quot;token key atrule&quot;&gt;hostPath&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token key atrule&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; /var/log
        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; varlibdockercontainers
          &lt;span class=&quot;token key atrule&quot;&gt;hostPath&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token key atrule&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; /var/lib/docker/containers
        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; resolvconf
          &lt;span class=&quot;token key atrule&quot;&gt;hostPath&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token key atrule&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; /etc/resolv.conf
        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; tz&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;config
          &lt;span class=&quot;token key atrule&quot;&gt;hostPath&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token key atrule&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; /etc/localtime
        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; fluentd&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;config
          &lt;span class=&quot;token key atrule&quot;&gt;configMap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; fluentd&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;configmap&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;위 순서대로 클러스터에 apply 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;h2&gt;5. Kibana에서 index 패턴 추가&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;메뉴 &gt; stack management &gt; index patterns 에서 인덱스 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/8b41d2ac44d3b7f92f4efcbfd5de6d55/764d7/001.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 36.66666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAABYlAAAWJQFJUiTwAAAA6UlEQVQoz52Qy07DMBBF/f/7totKIIFEHefR8g0s+Qc2kLRu0xaSOE78urhx1QhRIeBKRzOasWauh8xojMktxfSGYn7HwJIlongJGmdDjLNHsHSFKAk1yjIsWPqFhyjFPU2w8O+JkD1kp3AS5xx5XqAsS/xFLx/A9LnC06sC2e72EG03DK3rBk0jIEQ70o5RaX0dpdGrkJO3fI0N3/mCgZQdjHXQxsI5eNyZkBtrr2IvOJC82KCqBbS2ONQd3oXybuTQ/Ib7ARuWk2K9Rbk/DgOrpoXswz1Hd7/n7JDjcKz8/83lyKfmf/UJG88SQhOYJfUAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/8b41d2ac44d3b7f92f4efcbfd5de6d55/d9199/001.png&quot;
        srcset=&quot;/devHistoryBlog/static/8b41d2ac44d3b7f92f4efcbfd5de6d55/8ff5a/001.png 240w,
/devHistoryBlog/static/8b41d2ac44d3b7f92f4efcbfd5de6d55/e85cb/001.png 480w,
/devHistoryBlog/static/8b41d2ac44d3b7f92f4efcbfd5de6d55/d9199/001.png 960w,
/devHistoryBlog/static/8b41d2ac44d3b7f92f4efcbfd5de6d55/07a9c/001.png 1440w,
/devHistoryBlog/static/8b41d2ac44d3b7f92f4efcbfd5de6d55/764d7/001.png 1782w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;</content:encoded></item><item><title><![CDATA[SSL Offloading 작업]]></title><link>https://ssongey.github.io/works/posts/2022-08-21--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2022-08-21--001</guid><pubDate>Sun, 21 Aug 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;내가 담당하고 있는 서비스에서 클라이언트 IP가 필요한 상황이 생겼는데, 계속 서버IP가 들어와서 해당 작업을 하게되었다.&lt;br&gt;
이때 offloading 개념을 알게되어 정리한다.&lt;/p&gt;
&lt;h2&gt;✔️ 기존 구성&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ingress 까지 HTTPS 구간이라 클라이언트와 ingress의 구현체인 nginx가 SSL 커넥션을 맺고 있다.&lt;/li&gt;
&lt;li&gt;그러다보니 빨간색 구간이 모두 암호화되어 LB에서 헤더를 삽입할 수 없어 클라이언트 IP를 얻을 수 없는 상태였다.&lt;/li&gt;
&lt;li&gt;KIC의 LB가 아직 &lt;strong&gt;Terminated HTTPS(HTTPS Offloading)&lt;/strong&gt; 도입이 되지 않아 현재 상태로는 클라이언트 IP를 얻는건 불가능 했다.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이때 LB 와 인그레스와의 설정은 아래와 같다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;HTTPS → 443(HTTPS)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HTTP → 80(HTTP)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;인증서는 인그레스 쪽에 설치&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/0cf8dda803035b2ea83ca5f4c4a28892/e4d4a/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 31.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABYlAAAWJQFJUiTwAAABYUlEQVQY0x2RWZOaUBCF+f//JylLp5yUBBdkVBRFVocdARcyE8eJy5cLD1/d7vNw7ulu6bHPeGYxzzzhnkYtTd3wEDp5ytk2OZkr7F2MvstxshPR+YpffuDua/ziD05ek9VfSP/igItr8eXZkIQ8BRdR/xXaLfQ5GDpGr4P50mEweuPncMGbExPVN+ZeysQMGG92TLYBbnpAOlkbgrFCPtc4rJeUq0VbN/jKgHI5x5F/Yb/2UNQFXdVAs0KMsGwNZd2mr63FJwl2XCJ9eA6JNqHQZ5y3a86mQSVMC2HU6KE6wuy/sO13kcczOuMlUytgHVXiDRnMt/yQNRTDwwxypEezs/i9pRmZJOAe7lqa/irGdwevOCLhcKrTnYo0bkJw+hYJM2YiZU9doVoRbnYUhlVBc5h7c5wi55pEbIa/2YwUjs1ej2WrXQKfOK94rz5ZuSGytmTlRew/by1pfeV4ufEfRj6vn+4J6DIAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/0cf8dda803035b2ea83ca5f4c4a28892/d9199/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/0cf8dda803035b2ea83ca5f4c4a28892/8ff5a/001-01.png 240w,
/devHistoryBlog/static/0cf8dda803035b2ea83ca5f4c4a28892/e85cb/001-01.png 480w,
/devHistoryBlog/static/0cf8dda803035b2ea83ca5f4c4a28892/d9199/001-01.png 960w,
/devHistoryBlog/static/0cf8dda803035b2ea83ca5f4c4a28892/07a9c/001-01.png 1440w,
/devHistoryBlog/static/0cf8dda803035b2ea83ca5f4c4a28892/29114/001-01.png 1920w,
/devHistoryBlog/static/0cf8dda803035b2ea83ca5f4c4a28892/e4d4a/001-01.png 2198w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h2&gt;✔️ 변경된 구성&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;그래서 별도로 LB VIP 요청을 하여 ssl offloading 및 x-forwarded-for 적용을 하였다.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이때 new LB 와 인그레스와의 설정은 아래와 같다. (계속 https → 443 으로 연결해서.. 삽질했다)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;HTTPS → 80(HTTP)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HTTP → 80(HTTP)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;인증서는 new LB에 설치&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/c173f98c4a21fba34d4fa56f72b0dec5/5b2ff/001-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 31.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABYlAAAWJQFJUiTwAAABZUlEQVQY0x2RbXOaYBBF+f//p500ZsykaVWiKAqKKCLvIGoCaEzU4unKhzt35+7OmWefVeos4ZZGoph/SUh9VxaTfXwSFGfi8sw0yDG8DNPfMFmnLNMPwuIbd3vA2ZSs8opFVpCWXyiXYM3JsflyFyCwW+TzuVrixjuc3QndTfnxR+OhM6KlTsR1hk5MWF0bVy2fnuWJfJxkj7KfGfi9vyTaG4U1ZTseEkmt6hbPQwt9ldAeTBvY3Z/eDAZ2gOHnjKT3Ol40uSbwRZSjVMs5Ub9HLqDKngnUJB720cwlnalL11zxq6vzKLrDWuqYvgDNYNv4y2jOz9cBHdPF8lOUOg5kTY869Jp1EdVRQLw/4hUX7LTgqT/lUTVoazNaAh06CUF5YSTfoUl9z1Q7xEnfUdjnHP01498v2GqXg+dy227YyFHi8pvN4YK/O7DOS3lBRrs7QJ3MCSTLpJdWZ/LjtZl9P135DwqFr3pERyQTAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/c173f98c4a21fba34d4fa56f72b0dec5/d9199/001-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/c173f98c4a21fba34d4fa56f72b0dec5/8ff5a/001-02.png 240w,
/devHistoryBlog/static/c173f98c4a21fba34d4fa56f72b0dec5/e85cb/001-02.png 480w,
/devHistoryBlog/static/c173f98c4a21fba34d4fa56f72b0dec5/d9199/001-02.png 960w,
/devHistoryBlog/static/c173f98c4a21fba34d4fa56f72b0dec5/07a9c/001-02.png 1440w,
/devHistoryBlog/static/c173f98c4a21fba34d4fa56f72b0dec5/29114/001-02.png 1920w,
/devHistoryBlog/static/c173f98c4a21fba34d4fa56f72b0dec5/5b2ff/001-02.png 2190w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h2&gt;✔️ HTTPS Offloading ?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;서버 애플리케이션 외에서 SSL/TLS(이하 TLS) 처리를 대신 하는 것을 말한다.&lt;/li&gt;
&lt;li&gt;대부분의 서비스의 경우 API 서버군 앞에 Proxy 서버를 두고 해당 Proxy 서버에 SSL 관련 작업을 위임한다.&lt;/li&gt;
&lt;li&gt;Proxy 서버를 거친 데이터는 decrpty 되어 HTTP 통신을 하게 되므로. HTTPS를 사용해 통신하는 것 보다 빠른 속도로 통신하게 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/f2556b08477328af1984eade598db5b1/7d62e/001-03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 36.66666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAABYlAAAWJQFJUiTwAAABTUlEQVQoz32R3U7CQBCFeWEfxVuvfAav9IYfvQCTJkghJmIgbQUKBQKUQmH738/dheodJ9l0O7Mzc+acWhAEuK7LYu7gzn6wLIvRaMRkMtF3f7cCSvKioLhxyrIkyzJqlDlxHNEd7LAcH3EOORyOJEki4zH1tzVzL0VB1txEnuey4RXDUcF+r8sQIiIMQ7I0ZS4JLteC0ynULEQUcTwe/4am8o3v+7qZYnppKCd7wYbt6SALT9iOjW3bbLYbSAUfXYOeaeqCpbdgPB5LiVwSuYEp44Zh6CEKtWqXu4dH7p9eWAcOn67B6uBiztrsvBWtRpOv4ZAkOiO+n8l8h9hqEq2GtN8NzF4P5cV/Q4npZIrnLS9aFJJ+WWjqZyFodzq0XlvXovJignoj1+z3BzQadW2sblg5VKH6r77qRFI3JYXSqcoV15xyVpmnYir/C043E7rBFsVlAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/f2556b08477328af1984eade598db5b1/d9199/001-03.png&quot;
        srcset=&quot;/devHistoryBlog/static/f2556b08477328af1984eade598db5b1/8ff5a/001-03.png 240w,
/devHistoryBlog/static/f2556b08477328af1984eade598db5b1/e85cb/001-03.png 480w,
/devHistoryBlog/static/f2556b08477328af1984eade598db5b1/d9199/001-03.png 960w,
/devHistoryBlog/static/f2556b08477328af1984eade598db5b1/07a9c/001-03.png 1440w,
/devHistoryBlog/static/f2556b08477328af1984eade598db5b1/29114/001-03.png 1920w,
/devHistoryBlog/static/f2556b08477328af1984eade598db5b1/7d62e/001-03.png 2368w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h2&gt;✔️ &lt;strong&gt;X-Forwarded-For(XFF) 란?&lt;/strong&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;XFF 는 HTTP Header 중 하나로 HTTP Server 에 요청한 Client 의 IP 를 식별하기 위한 표준이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;p&gt;참고)&lt;br&gt;
&lt;a href=&quot;https://minholee93.tistory.com/entry/SSL-offloading-%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C&quot;&gt;[TIL] SSL offloading 이란 무엇일까?&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[cron 표현식]]></title><link>https://ssongey.github.io/history/posts/2022-08-21--001</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2022-08-21--001</guid><pubDate>Sun, 21 Aug 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;계속 까먹는다.. 표현식에 대해 정리한다.&lt;/p&gt;
&lt;h2&gt;✔️ 특수문자&lt;/h2&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/1bf9f19622798d14ad31d90a0897da64/d30ee/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 55.00000000000001%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABYlAAAWJQFJUiTwAAABOElEQVQoz42SiW7EIAxE8/+/GSn3fRBCDpdnrVdpq1WLZGHAHo/HJMdxiFsWaZpGrSgKqapKQghi677vP83ikhPAeVEQANnzPJclFtn3XSj4n2WgyRmZuGlWEMDatpU0TZUpd+M4avB1XXKep+7YZ4YxaNs2BavrWrquE+ecAmPc9X2vPh2YT7zJQ9E34AHDdVVWPFogyYBxHoZByrJ8swYQKSBjrL9p6CMjkgkk2djZoPBhvsbC6Poc2C8NQwzY4gBIoh2MZGOLDzuAkQJmmAH/1PI15VmqyBB2BmTABs7bUwZa52zMbCVHrOTbXuYICggJBAJkbQNmX4kBcAfrLMtkmiZ9YwYwVkDXD5I9vo0xYCexfrHnDh9DTxuKyaAtX/EibF6r832896oVjDnj2zDYeWf/9OG/AAsBUBUcZu3GAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/1bf9f19622798d14ad31d90a0897da64/d9199/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/1bf9f19622798d14ad31d90a0897da64/8ff5a/001-01.png 240w,
/devHistoryBlog/static/1bf9f19622798d14ad31d90a0897da64/e85cb/001-01.png 480w,
/devHistoryBlog/static/1bf9f19622798d14ad31d90a0897da64/d9199/001-01.png 960w,
/devHistoryBlog/static/1bf9f19622798d14ad31d90a0897da64/d30ee/001-01.png 980w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h2&gt;✔️ 주기 설정&lt;/h2&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/0302946c7deff6d4ca982b2011fe351f/07d37/001-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 60.416666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAABYlAAAWJQFJUiTwAAABeUlEQVQoz5VTi5KCMAzs//+d3vk4REUR5E2LCL4gl41TB507b64zS0ObbLNJq4hHURQUxzHleS42EEURZVkmM9Yx+r4XvBsKn7IsJdCSJUlCTdNI8O12o67r/kdojBFCzJa8bdsnR0v2FxQ+l8tFMjqfz2KDDJlZop+y+y1bZeVgDG0rte+7gX0vwf2wXtZgX6/XBxRk5nkhcg+HAzciZ9ma6rrmepaktSFTVVRqzbamim2ogR/2oAaqoA5QCETd4IhNNAWBsI2pBCDQfCAOrY9HOp1OlPINeCXErLDg+zva7yPyvA1tNlvJeOEuyWX4u4DCcE/brc//K/J438qGxCGZEOL0NRMFYUjL5YocZ8FdjmWeTmeyt1p7/O8KKfxBNCR5IkTdQASS+dwhZ+HyJU9oPP6kyWQmWc+/HBqNPihN08eNaJpWAPlPkrGAoDTNaMfyIB+SkQ0Q8QvCvOYsIR0lCYJQAF80x2YsTRm+guEde2e/XmZwWHwDheSdbCHiXvoAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/0302946c7deff6d4ca982b2011fe351f/d9199/001-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/0302946c7deff6d4ca982b2011fe351f/8ff5a/001-02.png 240w,
/devHistoryBlog/static/0302946c7deff6d4ca982b2011fe351f/e85cb/001-02.png 480w,
/devHistoryBlog/static/0302946c7deff6d4ca982b2011fe351f/d9199/001-02.png 960w,
/devHistoryBlog/static/0302946c7deff6d4ca982b2011fe351f/07a9c/001-02.png 1440w,
/devHistoryBlog/static/0302946c7deff6d4ca982b2011fe351f/07d37/001-02.png 1790w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h2&gt;✔️ 예시&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;0-6시 사이에 11분 + 10분마다&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;11,21,31,41,51 0-6 * * *&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;0-6시 사이 매 5분 마다&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;*/5 0-6 * * *&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[SpringBoot 빌드시 2개 jar 파일 생성되는 이유?]]></title><link>https://ssongey.github.io/history/posts/2022-08-07--001</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2022-08-07--001</guid><pubDate>Sun, 07 Aug 2022 00:00:00 GMT</pubDate><content:encoded>&lt;br/&gt;
&lt;p&gt;최근에 빌드를 하면 jar 파일이 두개가 생성이 되는걸 확인하게 되었고, 해당 부분이 궁금해서 찾아봤다.&lt;/p&gt;
&lt;h2&gt;✔️ 왜 2개가 생성이 될까?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;springboot 2.5 이후 부터는 빌드시 jar 파일이 2개 생긴다.&lt;/li&gt;
&lt;li&gt;springboot 2.4.11 document 를 보면, &lt;code class=&quot;language-text&quot;&gt;jar or war tasks are disabled&lt;/code&gt; 이기 때문에 jar task 가 기본적으로 스킵이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/d21e7b2a7e5ef1864222968d7c74880a/2376a/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 24.583333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAABYlAAAWJQFJUiTwAAABQElEQVQY002QS0sCURiG558YbpIEIy9T05iipVZGo2gqKeGmiJJw0VIKugdWRP9QUaGNOs5FNHg6x0X0wMs53+I85+VT+v0+vV7vL9+DAa5lYU9MbNtG8v75RbFa57RxzcnZFZX6OblSjXy5hlE8Jpsrkc7meXxpo3S7XabT6eKx67o4kwm2OcYaj5mIu6R1c0swHObAMMge5ohu6miREFvaBsHVAH7/CkseD5eXFyjD4RBLyKTQEs0sy8ZxHFzxiZwlT8+vqJqOUa5yVK6QSiRIRHUy4lwPBQkEAiz7fDSbTZROp4MjZLKNFJimuRDOZrNFY8nd/QNrYZX9QoVcvoCuR1EjEeKxGKqqioZ+vF4vjUYDZTwa8TOfM/8XKZORq5C03z5I7qQxhEwms7tHKpUiub1NTEjj8TiaptFqtfgFZV0WhvXP6J8AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/d21e7b2a7e5ef1864222968d7c74880a/d9199/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/d21e7b2a7e5ef1864222968d7c74880a/8ff5a/001-01.png 240w,
/devHistoryBlog/static/d21e7b2a7e5ef1864222968d7c74880a/e85cb/001-01.png 480w,
/devHistoryBlog/static/d21e7b2a7e5ef1864222968d7c74880a/d9199/001-01.png 960w,
/devHistoryBlog/static/d21e7b2a7e5ef1864222968d7c74880a/07a9c/001-01.png 1440w,
/devHistoryBlog/static/d21e7b2a7e5ef1864222968d7c74880a/29114/001-01.png 1920w,
/devHistoryBlog/static/d21e7b2a7e5ef1864222968d7c74880a/2376a/001-01.png 3138w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;springboot 2.5.0 이후부터는 bootJar, bootWar 수행시에 &lt;code class=&quot;language-text&quot;&gt;jar or war task are configured to use plain&lt;/code&gt; 이기 때문에 plain 이라는 이름으로 jar 파일이 한개 더 생긴다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/7ca391d0d671f90674a0ec6eca5b71d2/30a3b/001-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 27.083333333333332%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAABYlAAAWJQFJUiTwAAABKUlEQVQY01WQ2U7CUBRF+x/GGGRo6QRtobfzIFChSFBCCAGVqDExxv9/Xd4SNfFh5+Q8nJW1jxIFMVGQEEUZfjPDlLEn8IYehm7xfHrhYX+k3hxY705Uqy3F5JZptWBW1WTljKSYIuKcIClQBvJQ65v0dZtOT+e6o/3l4rLF/vDIvF4iwpg4zYjilNQfM0ljcuHjWiaGYaD2umiaijISEdbAQ5U2qgT/RpN7q93j9e2d+82WMM7IihvSvJSNAooso8xz2ShkMBziui62baMYlkNX1Wl3tZ/0z7Oxvbxqc3w6sVyt5TsiaZhLcIrrjfB9H18IHMfBNM0zTNd1lCQraSwdz/8XdyQwbYePzy+2uz3VfMFiuZL175hMptR1TSENG3AgjYWEh9L2GxC7pgVt0X+SAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/7ca391d0d671f90674a0ec6eca5b71d2/d9199/001-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/7ca391d0d671f90674a0ec6eca5b71d2/8ff5a/001-02.png 240w,
/devHistoryBlog/static/7ca391d0d671f90674a0ec6eca5b71d2/e85cb/001-02.png 480w,
/devHistoryBlog/static/7ca391d0d671f90674a0ec6eca5b71d2/d9199/001-02.png 960w,
/devHistoryBlog/static/7ca391d0d671f90674a0ec6eca5b71d2/07a9c/001-02.png 1440w,
/devHistoryBlog/static/7ca391d0d671f90674a0ec6eca5b71d2/29114/001-02.png 1920w,
/devHistoryBlog/static/7ca391d0d671f90674a0ec6eca5b71d2/30a3b/001-02.png 3254w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;즉, 스프링부트의 버전에 따른 gradle 플러그인의 packageing 기본 설정 차이가 있기 때문이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;h2&gt;✔️ executable jar, plain jar 의 차이가 뭐지?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;plain jar 파일의 경우 어플리케이션 실행에 필요한 모든 의존성을 포함하지 않고 소스코드의 클래스파일과 리소스 파일만 포함한다.&lt;/li&gt;
&lt;li&gt;executable jar 파일의 경우 실행에 필요한 모든 의존성을 함께 빌드한다. 따라서 해당 파일은 &lt;code class=&quot;language-text&quot;&gt;java -jar&lt;/code&gt; 명령어를 통해 실행이 가능하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;h2&gt;✔️ plain jar 를 생성하지 않는 방법은?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;jar task 를 수행하지 않으면 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/885fe781359728669b700b0697ddbfce/764d0/001-03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 29.583333333333332%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAxUlEQVQY05WP3QrCMAyF+96CV8IeSUUfQ/BCcM510/24v6xb2sKOtRcKIqiBj4SQnOSIuq6R5zmklDjHMaIoQpKmHpkkKIoCxhiP1voJM0O/9ay1EE3ToCxLv3jNMi9+qypU7tAjd0T4J8RsPsciCBCGIYi6j0PTNP2EF1yuN1httpDpBcWtBinGyM6CsWBtHNbX3xjZODc9hBoYLQ04HE/Y7Q84yQyhzFG1CoMbUqP+GVIjREuvReoHlxmd+7J3hx79f7kD/5LNOIFlhS0AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/885fe781359728669b700b0697ddbfce/d9199/001-03.png&quot;
        srcset=&quot;/devHistoryBlog/static/885fe781359728669b700b0697ddbfce/8ff5a/001-03.png 240w,
/devHistoryBlog/static/885fe781359728669b700b0697ddbfce/e85cb/001-03.png 480w,
/devHistoryBlog/static/885fe781359728669b700b0697ddbfce/d9199/001-03.png 960w,
/devHistoryBlog/static/885fe781359728669b700b0697ddbfce/07a9c/001-03.png 1440w,
/devHistoryBlog/static/885fe781359728669b700b0697ddbfce/764d0/001-03.png 1898w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;</content:encoded></item><item><title><![CDATA[[대세는 쿠버네티스] Kubernetes Architecture]]></title><link>https://ssongey.github.io/history/posts/2022-08-07--002</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2022-08-07--002</guid><pubDate>Sun, 07 Aug 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;✔️ Kubernetes Concepts&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;K8S가 관리하는 각 항목은 객체로 표시되며 이러한 객체의 속성과 상태를 확인하고 변경할 수 있다.&lt;/li&gt;
&lt;li&gt;Kubernetes는 ‘watch loop’를 사용하여 관리되고 있는 객체에 대해 원하는 상태를 지정할 수 있고, Kubernetes는 객체를 해당 상태로 전환&amp;#x26;유지한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1&gt;✔️ 제어 영역 Kubernetes 구성요소&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;제어 영역의 역할은 전체 클러스터를 조정하는 것이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/faae6f0c2e555185e9dd495b1e963613/bd9eb/002-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 42.91666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAABYlAAAWJQFJUiTwAAACQUlEQVQozz2QTU8TYRSF+xtcGHe6cuHOpYmJe3+LG91oojExJhA1ho3RkECC0EBbaAu2nc5HZ2qEdtppp6W0pV/TUsCCoQWBSFA3j1dF3+Qk99yb98m519dptxgMj4lbWZaNNdS890dGro7pNIiWPMLFTZaKdSKuJ77FUqEm9W/fJfLbOzVChTr57gG+kuvS6u1SzcRx9AWyWpCMyLXC1LIqkfVV/Pll5p0VwhtZolULvx0lVIoRqeSll2IuGyFQTpDtbuEbHhywtTvguLDAqfWYz+8uM3h7iRP9IUN7Fq0UR8mGMJwl1JqOXv0gdZiUu4haT2Gsr5ByomjFRdztFj7knXw7ZyiNr2sT9GZui25x/Ok1IzeKXjSxbB1L0iplC83VpNYxbYVEJY3uqHy0U6iZGIWt9gXw7AeHqy840u8zykwzWpvkUH3AKP0co2xgFhJYBUlaSaFXBOgkMYviZX2jnCRdUNHkJMX+BfBUgAP/TXYnfIyMR6IneK989CavozdiqN159K4fpSkf27KyFyTlBVAakqwTkVkQpTNP4f/KAvwSvstw+goj8xlDa4zRzFX2A3cEGEfvBTAEqjQ19HZMYIuYXohkw0TrRGUmdWeB4j/g6dk5/akbNMd8HCn3OEw9ZXPcR/vNNbTNMEp3FtWbISbwZEsSdfyiOeJ1uWs7KDM/8fZ78v3GX+DZ95/07Sk8c5y9SoK9qkE3/RJvdRK7V8beyWNv58j0NrD7ZXLbjigvvibeJbfjkOnnaO7v8QusHkxIgTWQLQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/faae6f0c2e555185e9dd495b1e963613/d9199/002-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/faae6f0c2e555185e9dd495b1e963613/8ff5a/002-01.png 240w,
/devHistoryBlog/static/faae6f0c2e555185e9dd495b1e963613/e85cb/002-01.png 480w,
/devHistoryBlog/static/faae6f0c2e555185e9dd495b1e963613/d9199/002-01.png 960w,
/devHistoryBlog/static/faae6f0c2e555185e9dd495b1e963613/07a9c/002-01.png 1440w,
/devHistoryBlog/static/faae6f0c2e555185e9dd495b1e963613/bd9eb/002-01.png 1442w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h2&gt;1. kube API Server&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;사용자가 직접 상호작용하는 단일 구성요소&lt;/li&gt;
&lt;li&gt;kubectl 명령어와 통신하는 서버&lt;/li&gt;
&lt;li&gt;kubeconfig 값으로 수신된 요청을 인증하고 요청의 승인 여부와 유효성을 확인하며 허용 제어를 관리&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;2. etcd&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;클러스터의 데이터베이스&lt;/li&gt;
&lt;li&gt;클러스터의 상태를 저장하는 역할을 한다.&lt;/li&gt;
&lt;li&gt;여기에는 모든 클러스터의 구성 데이터와 많은 동적 정보(클러스터의 일부인 노드, 실행해야 하는 Pod, 실행 위치)가 포함된다.&lt;/li&gt;
&lt;li&gt;사용자는 etcd와 직접 상호작용하지 않는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;3. kube-scheduler&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Pod의 요구사항을 평가하고 가장 적합한 노드를 선택하는 역할을 한다.&lt;/li&gt;
&lt;li&gt;노드의 자원 사용량을 모니터링 하기때문에 적합한 노드 선택이 가능&lt;/li&gt;
&lt;li&gt;kube-apiserver를 통해 etcd에 Pod생성 요청이 있는지 감시한다. (Watch 기능)&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;노드를 선택하는 방법&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;노드에 아직 할당되지 않은 Pod 객체 발견 &lt;/li&gt;
&lt;li&gt;모든 노드의 리소스를 확인하여 적합한 노드를 선택 &lt;/li&gt;
&lt;li&gt;해당 노드의 이름을 Pod 객체에 작성&lt;/li&gt;
&lt;li&gt;시스템의 또 다른 구성요소가 Pod를 시작&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;4. kube-controller-manager&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;컨트롤러 오브젝트들의 요구사항을 수행&lt;/li&gt;
&lt;li&gt;클러스터의 현재 상태가 원하는 상태와 일치하지 않을 때마다 kube-controller-manager는 원하는 상태를 달성하기 위해 변경을 시도&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;컨트롤러 종류&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ReplicaSet, Deployment, DaemonSet, Job, CronJob&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;5. Kubelet&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;각 워커 노드에서 클러스터 에이전트 역할을 한다.&lt;/li&gt;
&lt;li&gt;kube-apiserver 에 watch 를 걸어 자신의 노드이름이 붙은 Pod 생성 및 변경 요청에 대해 수행한다.&lt;/li&gt;
&lt;li&gt;Kubelet은 컨테이너 런타임을 사용하여 Pod의 컨테이너를 실행하고 Pod의 수명 주기를 모니터링하고 kube-apiserver에 다시 보고한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;6. kube-proxy&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;클러스터에서 Pod 간 네트워크 생성 및 연결을 유지&lt;/li&gt;
&lt;li&gt;DaemonSet으로 설치된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1&gt;✔️ Pod 생성 플로우&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;사용자가 Pod 생성 요청 → kube-apiserver 로 명령어 전달&lt;/li&gt;
&lt;li&gt;kube-apiserver는 etcd에 해당 Pod 정보를 저장&lt;/li&gt;
&lt;li&gt;kube-scheduler는 kube-apiserver를 통해 etcd에 새로 들어온 Pod 생성 요청을 체크하고, 노드들의 자원상태를 확인하여 적합한 노드를 선택 후 해당 Pod에 노드명 기재&lt;/li&gt;
&lt;li&gt;모든 노드의 kublet이 kube-apiserver 를 watch 하고 있다가 자신의 노드명이 붙은 Pod 생성 이벤트가 발생하면 해당 정보를 가져온다.&lt;/li&gt;
&lt;li&gt;kublet은 Container Runtime에게 해당 파드 생성 및 컨테이너 실행 요청을 함&lt;/li&gt;
&lt;li&gt;그리고 kublet은 kube-proxy에게 네트워크 생성 요청을 하게되고, kube-proxy는 새로 생성된 컨테이너가 네트워크 통신이 되도록 도와줌&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/9a3b5f0544137224fa5af5b796054097/28fe3/002-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 47.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABYlAAAWJQFJUiTwAAACR0lEQVQozzWSy2/aYBDE+f+l9tBbW/VQKTlUiSoljZqmaZQ0pHlgwJinMRhs/DYOGD8gzeXXhaSH0Ur7zY7mm92KYiSEyw1RuiHOnpn6Dnf1XxjWBHee7zCeRZhOhO0nJKsNj9kTsfCj5VrmXhAs1qTFXyrfHlx0K0Kf+rva7PX5fX9N33KZRiVDJ0Ez3B3aY59JmEu/EGxr9lpzzCDbCVcOr8fU1S71hkpT1WhpfaZBLoNr1EnETesSZdhh6K35rpoc1kbsX7dRRuI4LjDDF9Hxf8G9U43OwMRyPMypg25YmN5iR2qYIV9vr7hot9GdjBPFZL865NO5SmMc4CYFVpxhzzMx8Cr49c8MtWvQ7Rt0eluMMJwFHStHHefU9ILGqKBrFVypIeeKT22Q0p5Kz35BxyoF2S7TimLM8aMlQbRgJqHbQYL3WDIKnxm4G3FWMHBKerOS5njJfX++6+nS0+V96K4FG8mwZFXKUqruI/qi5D5MUaIVF7pNzbbojlV6vklYPrHcPHFmx7SilMGjuA6XdJMMZerSFBPteYoWpyRbwS/tKa04p+qlPPgpjVmMYjncahqKOcGRE/GzNR8edC4kU21eCHfFg7cUXkRdrkCXLHuiEeYbKgciqMUrqvJwLS6OtRFHPZs39Qnv6iZutiEsnvh43+NStr7l3rjCFbEj1eBs6PK2ZvC+OSHe3uHJKKArX9CCBdWhzQ9V57Sl8/muzfFghrPI8dKCA92jas8ZyLebXkJ1MOFna8hFx2BP6XOiOwTC+wcyqc6lReLfuQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/9a3b5f0544137224fa5af5b796054097/d9199/002-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/9a3b5f0544137224fa5af5b796054097/8ff5a/002-02.png 240w,
/devHistoryBlog/static/9a3b5f0544137224fa5af5b796054097/e85cb/002-02.png 480w,
/devHistoryBlog/static/9a3b5f0544137224fa5af5b796054097/d9199/002-02.png 960w,
/devHistoryBlog/static/9a3b5f0544137224fa5af5b796054097/07a9c/002-02.png 1440w,
/devHistoryBlog/static/9a3b5f0544137224fa5af5b796054097/29114/002-02.png 1920w,
/devHistoryBlog/static/9a3b5f0544137224fa5af5b796054097/28fe3/002-02.png 3446w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;hr&gt;
&lt;h1&gt;✔️ Deployment 생성 플로우&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Controller Manager Pod 내에 여러 컨트롤러들에 대한 기능들이 각각의 스레드 형태로 돌아가고 있다.&lt;/li&gt;
&lt;li&gt;사용자가 Deployment 생성 요청 → kube-apiserver로 명령어 전달&lt;/li&gt;
&lt;li&gt;kube-apiserver는 etcd에 해당 Deployment에 대한 정보를 저장&lt;/li&gt;
&lt;li&gt;Controller Manager Pod 내의 Deployment 스레드가 이를 감지하여 ReplicaSet 생성을 요청한다.&lt;/li&gt;
&lt;li&gt;Controller Manager Pod 내의 ReplicaSet 스레드가 이를 감지하여 replica 개수만큼 Pod 생성 요청을 한다.&lt;/li&gt;
&lt;li&gt;이후에 파드 생성 플로우로 진행한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/d1913241559172c9dfb4c04294f374e8/4faaa/002-03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 47.91666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABYlAAAWJQFJUiTwAAACYklEQVQozzWS228SWxTG+fdNfPDBxJiYmKPRJjV60mOobapCkVrKwAy3uTIDey7I3KBQoKX68DtLGx9W1to73/72t9a3KldOTnp9S7neU2x/MY8z7ONTxvqQMFsT5yvGYcpE7idxKrg7FjeClfxQP8TfunLUSnBUjqfmuGGG40xxv10RuBFBWDBs9TH6PkP/BwMvQWVbwnwneUNY7AjLW1T+EEm5pXJ4HtDWTbSOTkfvYQxG+OkatbynN1DYh6/kgzrjdM9ZX3F4afO2adJ05py3FdWaTa3tc9q0mKYbKv8cC4npo+IZgUqwvClBUoqCNV1/hdb7SrXxngtrTrUT8OK0y/NPGk0j4LzW5+jjJSe1DidnTVRSUHn3LaJtWDhjH8v1GdljvKhgpDYY/oaWXVAbxLS9Jd9HJZ87c1rdGT09RhtkNMwl9eGCi35CFCVUWnZOki7JiiWztCScF8zKjbT4EzveY0e3uMlDNkTxxTDDDLeYch6GO7zkjiD9xTT7KabcU2lIe664fDVf0U5X1GXwLRViTgZYszHJ5pbN/Z56XNBJr/GWonq+5OpHSd1VtMV5J7JwY4t0u6PypufTLzZ0ii3d7AY9LtGiGQ3doBv4TNayUrs9r40xVTdhuNih5VuMXN7IaLQ4p+3YMo4R4UpcPtA9NFH3+NLhZW/Kf7Ii1ZHiqa54Iu45iy3Xd/e80ixO3JiubMCj7zYvxZSj3phjU/GsF/7BTq5F4fEkYyCOHpohH4Tsiznh3J7yRgg+2NEf0G/Cj4JrxAvM4oaDoeK94XE2Cmg4ioOuw7+CjaWb/wF7ucX+yEggLAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002 03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/d1913241559172c9dfb4c04294f374e8/d9199/002-03.png&quot;
        srcset=&quot;/devHistoryBlog/static/d1913241559172c9dfb4c04294f374e8/8ff5a/002-03.png 240w,
/devHistoryBlog/static/d1913241559172c9dfb4c04294f374e8/e85cb/002-03.png 480w,
/devHistoryBlog/static/d1913241559172c9dfb4c04294f374e8/d9199/002-03.png 960w,
/devHistoryBlog/static/d1913241559172c9dfb4c04294f374e8/07a9c/002-03.png 1440w,
/devHistoryBlog/static/d1913241559172c9dfb4c04294f374e8/29114/002-03.png 1920w,
/devHistoryBlog/static/d1913241559172c9dfb4c04294f374e8/4faaa/002-03.png 2308w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;</content:encoded></item><item><title><![CDATA[Bean 초기화/ 소멸 방법 3가지]]></title><link>https://ssongey.github.io/history/posts/2022-07-30--001</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2022-07-30--001</guid><pubDate>Sat, 30 Jul 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;1. &lt;strong&gt;InitializingBean, DisposableBean&lt;/strong&gt; 인터페이스&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;이 인터페이스는 &lt;strong&gt;스프링 전용 인터페이스&lt;/strong&gt;이다. 해당 코드가 스프링 전용 인터페이스에 의존한다.&lt;/li&gt;
&lt;li&gt;초기화, 소멸 메소드의 이름을 변경할 수 없다.&lt;/li&gt;
&lt;li&gt;코드를 수정할 수 없는 외부 라이브러리에 적용할 수 없다.&lt;/li&gt;
&lt;li&gt;현재는 이보다 더 좋은 방법이 있기 때문에 거의 사용 되지 않는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;BeanTest&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;InitializingBean&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DisposableBean&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

    init &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;call initBlock&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    fun &lt;span class=&quot;token function&quot;&gt;initTest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;call initTest&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    fun &lt;span class=&quot;token function&quot;&gt;destroyTest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;call destroyTest&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// 의존관계 주입이 끝나면 호출&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;override fun afterPropertiesSet&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;initTest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

		&lt;span class=&quot;token comment&quot;&gt;// 스프링 컨테이너 종료시 호출&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;override fun destroy&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;destroyTest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/d6211b13cb4105c1ba8d392f97766abe/027f0/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 24.166666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAABYlAAAWJQFJUiTwAAAA1klEQVQY03WQWxbCIAxEuxc9aqFS3hQpdf+rGidVPv3IgYTMzYSpvRrylpCShzMey7Ig5oxrKbjW+g3mznvs+47WGiprEpn1EAK1CZ7vck597yg1IZcAv0Y8nwQKZNu+MAIuvDs2H72jMwQ8oOu6niaUUpjneQAzpxFoAh81osA4/ULBnQ5uzsHFiPdxoND5cBNZk7sx5gRqrTHJNAGWwgafuJpjXjETqtoLDwoFaBniaIAGTE5r7elUwJNMTFma+BcxYSMo0Z2lULNR/daRtUQoInHyLz5y+p8cbytjaAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/d6211b13cb4105c1ba8d392f97766abe/d9199/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/d6211b13cb4105c1ba8d392f97766abe/8ff5a/001-01.png 240w,
/devHistoryBlog/static/d6211b13cb4105c1ba8d392f97766abe/e85cb/001-01.png 480w,
/devHistoryBlog/static/d6211b13cb4105c1ba8d392f97766abe/d9199/001-01.png 960w,
/devHistoryBlog/static/d6211b13cb4105c1ba8d392f97766abe/07a9c/001-01.png 1440w,
/devHistoryBlog/static/d6211b13cb4105c1ba8d392f97766abe/29114/001-01.png 1920w,
/devHistoryBlog/static/d6211b13cb4105c1ba8d392f97766abe/027f0/001-01.png 2824w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;h2&gt;2. initMethod, destroyMethod&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;빈을 생성하기 위한 @Bean 어노테이션에 initMethod와 destroyMethod를 사용하여 지정&lt;/li&gt;
&lt;li&gt;스프링 빈이 스프링 코드에 의존하지 않는다.&lt;/li&gt;
&lt;li&gt;메소드의 이름을 자유롭게 변경할 수 있으며, 코드에 접근할 수 없는 외부 라이브러리에도 초기화, 종료 메소드를 적용할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token annotation punctuation&quot;&gt;@Configuration&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;WebConfig&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token annotation punctuation&quot;&gt;@Bean&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;initMethod &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;initTest&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; destroyMethod &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;destroyTest&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;
    fun &lt;span class=&quot;token function&quot;&gt;getBeanTest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;BeanTest&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;BeanTest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;BeanTest&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; val logger &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;LoggerFactory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getLogger&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;!!! bean check log !!!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    init &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        logger&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;call initBlock&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    fun &lt;span class=&quot;token function&quot;&gt;initTest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        logger&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;call initTest&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    fun &lt;span class=&quot;token function&quot;&gt;destroyTest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        logger&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;call destroyTest&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;2.2. 종료 메소드 추론&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;또한 destroyMethod에는 inferred라는 추론 기능이 추가되어 있다.&lt;/li&gt;
&lt;li&gt;일반적으로 종료 메소드의 이름으로 close 또는 shutdown을 많이 이용하기 때문에, close 또는 shutdown 함수가 존재하면 이를 소멸자 메소드로 인식하여 호출한다.&lt;/li&gt;
&lt;li&gt;이러한 추론 기능을 사용하고 싶지 않으면 destroyMethod=&quot;&quot; 처럼 destroyMethod를 공백으로 지정하면 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token annotation punctuation&quot;&gt;@Configuration&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;WebConfig&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;token annotation punctuation&quot;&gt;@Bean&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;initMethod &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;initTest&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    fun &lt;span class=&quot;token function&quot;&gt;getBeanTest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;BeanTest&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;BeanTest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;BeanTest&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; val logger &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;LoggerFactory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getLogger&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;!!! bean check log !!!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    init &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        logger&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;call initBlock&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    fun &lt;span class=&quot;token function&quot;&gt;initTest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        logger&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;call initTest&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;fun &lt;span class=&quot;token function&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 스프링 컨테이너 종료시 호출됨&lt;/span&gt;
        logger&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;call destroyTest&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;h2&gt;3. PostConstruct, PreDestroy&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;최신 스프링에서 가장 권장하는 방법이다.&lt;/li&gt;
&lt;li&gt;애노테이션 하나만 붙이면 되므로 매우 편리하다.&lt;/li&gt;
&lt;li&gt;패키지를 확인해보면 javax.annotation.PostConstruct이다.스프링에 종속적인 기술이 아니라 JSR-250이라는 자바 표준이므로 스프링이 아닌 다른 컨테이너에서도 동작한다,.&lt;/li&gt;
&lt;li&gt;컴포넌트 스캔과 잘 어울린다.&lt;/li&gt;
&lt;li&gt;외부 라이브러리에는 적용하지 못하기 때문에 외부 라이브러리를 초기화, 종료해야 한다면 @Bean 기능을 사용하면 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token annotation punctuation&quot;&gt;@Configuration&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;WebConfig&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;token annotation punctuation&quot;&gt;@Bean&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    fun &lt;span class=&quot;token function&quot;&gt;getBeanTest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;BeanTest&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;BeanTest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;BeanTest&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; val logger &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;LoggerFactory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getLogger&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;!!! bean check log !!!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    init &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        logger&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;call initBlock&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token annotation punctuation&quot;&gt;@PostConstruct&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;
    fun &lt;span class=&quot;token function&quot;&gt;initTest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        logger&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;call initTest&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token annotation punctuation&quot;&gt;@PreDestroy&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;
    fun &lt;span class=&quot;token function&quot;&gt;destroyTest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        logger&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;call destroyTest&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;h2&gt;4. 정리&lt;/h2&gt;
&lt;p&gt;보통은 @PostConstruct, @PreDestroy 을 사용하는걸 권장하지만, 외부 라이브러리 초기화/ 소멸시 처리해야 할 과정이 있다면, @Bean 의 InitMethod, destroyMethod를 사용하면 된다.&lt;/p&gt;
&lt;h3&gt;4.1. 만약 &lt;strong&gt;SIGKILL 시그널(&lt;/strong&gt;kill -9 {PID})&lt;strong&gt;로 종료가 되었다면&lt;/strong&gt;,&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;SIGKILL&lt;/strong&gt;은 프로세스를 즉시 종료 시킨다. 해당 시그널을 받으면 프로세스가 종료되기 전에 수행되어야 하는 종료 절차를 실행하지 않고 즉시 종료하므로 graceful shutdown을 위해서라면 해당 시그널을 통해 프로세스를 종료시키는 것은 피해야한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4.2. 호출 순서는?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;init&lt;/strong&gt; : @PostConstruct → InitializingBean 인터페이스 → @Bean initMethod&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;destroy&lt;/strong&gt; : @PreDestroy → DisposableBean 인터페이스 → @Bean destroyMethod&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/58087959a667ff91de6ffeeb64655605/763a5/001-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 19.583333333333332%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAxUlEQVQY0y2PWQ6DMAxEuUvV0iyQANkTUHv/Q03HqB8jy9uzZ+q9o/eBVANyyFiWFd47bKXgmRJejHMIeDuHnDOu60JhTSR54oz3nnsLtNaYxugYBOYWb6C1C9y6YqsVDy68YoTmsLIW6Q8cY9wSoIBEln1jDKbzPNk8UVpCyRX7tvNqRGgNmjIEz4S++UU4DhTm8l1ljKwHfi+SLx1dTL03tNoQy4F4xBv6/X7geX2mHcVhQytaqXtRQI2HRAIRm4o9iaIfDzCAP7YYuXwAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/58087959a667ff91de6ffeeb64655605/d9199/001-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/58087959a667ff91de6ffeeb64655605/8ff5a/001-02.png 240w,
/devHistoryBlog/static/58087959a667ff91de6ffeeb64655605/e85cb/001-02.png 480w,
/devHistoryBlog/static/58087959a667ff91de6ffeeb64655605/d9199/001-02.png 960w,
/devHistoryBlog/static/58087959a667ff91de6ffeeb64655605/07a9c/001-02.png 1440w,
/devHistoryBlog/static/58087959a667ff91de6ffeeb64655605/29114/001-02.png 1920w,
/devHistoryBlog/static/58087959a667ff91de6ffeeb64655605/763a5/001-02.png 2804w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;</content:encoded></item><item><title><![CDATA[동적 라이브러리 적용]]></title><link>https://ssongey.github.io/works/posts/2022-07-25--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2022-07-25--001</guid><pubDate>Mon, 25 Jul 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;이번에 사진 피처 추출 LIB를 프로젝트에 적용하게 되어 해당 작업에 대한 내용을 정리한다.&lt;/p&gt;
&lt;h2&gt;1. gradle 에 dependency 적용&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;files 함수를 사용하여 jar 파일 의존성 추가&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/f8ad65a45a537064a574b7d72bf01910/1c1a4/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 14.583333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAkklEQVQI11WOwQ6DMAxD+R7aNGkhbdlKJSS2SbvssP//Fq+wTYLDk5wottPdq8fGWhiXRIiqSCkhNvSvY4RGhSULY80Zc9Q9uufi8X6MeK0BtypY5hFzrZjKFTlnlFIQsyJOChkYHNwJJwTnCex/geIs8kjQQEhD+zAYiPftUOCcg7Ds7cT2az5AG21P3Gbu98APbd9fHyPcS84AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/f8ad65a45a537064a574b7d72bf01910/d9199/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/f8ad65a45a537064a574b7d72bf01910/8ff5a/001-01.png 240w,
/devHistoryBlog/static/f8ad65a45a537064a574b7d72bf01910/e85cb/001-01.png 480w,
/devHistoryBlog/static/f8ad65a45a537064a574b7d72bf01910/d9199/001-01.png 960w,
/devHistoryBlog/static/f8ad65a45a537064a574b7d72bf01910/1c1a4/001-01.png 1046w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;h2&gt;2. intelliJ에 동적 라이브러리 적용&lt;/h2&gt;
&lt;h3&gt;2.1. project settings 에 동적 라이브러리 적용&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Project Structure(&lt;code class=&quot;language-text&quot;&gt;command&lt;/code&gt; + &lt;code class=&quot;language-text&quot;&gt;;&lt;/code&gt;)  → Libraries → New Project Library → Java&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/bb57845b2785f5a2a3ace4862a243022/18872/001-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 608px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 64.16666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAABYlAAAWJQFJUiTwAAACp0lEQVQ4y2WTuW4UQRCG5y0AIUNAggUWYGR7j7mPnbNn59o5vDvr3bXXQIAcICdIEIBIOGwhQeCQByEwEiKDyAghv8tPTS8YGYJff3f16OuaqmrB6NnQrR4aV3QDoqKiIyvn1JXVM3XOrZX/JKimDc0iaM+BqOroKBq656RzCNfvWFtSFmA66/7zvWA4ERQz4JKNxhlkrsVe1DzK3oNpu1AMk2RhOJ5ANXsEls+y/pO5IJkhOqqHruajrXhoyS5Xm2KSwfiZahHUCaDZPjSCp+UIpkuXGg4lQLJcvpYMG0I+3EZWTdHPasT5GNV4F02MJUOIesCBhmkgiUPszGqUZYbNKsN8u0Y9ylEPB3w9Ivf9HoQwHWE4ucehjZJiQhlMOLDbAGULq/3HWN96iY3hIdTJW6xVh7idNzrgfqdY7G8NDiC0FB9WUCAupgizMToawwbF2irVz4w58Hr+AcuPPmJ17zPSZ19x9+EXLI0/4erWMa6Mj7FUL7yRoFBnoihGmg2QphkC1odC3VY1nbtEhd+gYl9Lp5BZBseP4LAISV4gKyp4YXSu28KN+BXE8XuY8yMYO0cQt97hJsVWktdYSd9gOXyBrpljb7KPsM+Q5jmiJEVEl5u2Q5C/M8m7fGF2gvX9H/Cen0J/+hPqk1Nc2j7B5Z1G33Fx+g1r9gzzMgILenDDhLJkcFnIR6iZ3cZlzVxk2LJKONku3PwB3MF9tHubaFsVeYUOrVtGCdG20WKMMvJhez69LBsqQZrZ5PAghOU08+pAEDUKBs0vVGBxQa8mgEQxSafZ0j16ig4034U13EQ/TnntWJzw2oW07ycZkkHBnUUJAXWGgEYkq2YoRnOEaU1DHvChlowQXeq2Fniw6hHVjhpXlBzkN0CqZZzl1JySAwMC/gK5w+++WrLG3gAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/bb57845b2785f5a2a3ace4862a243022/18872/001-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/bb57845b2785f5a2a3ace4862a243022/8ff5a/001-02.png 240w,
/devHistoryBlog/static/bb57845b2785f5a2a3ace4862a243022/e85cb/001-02.png 480w,
/devHistoryBlog/static/bb57845b2785f5a2a3ace4862a243022/18872/001-02.png 608w&quot;
        sizes=&quot;(max-width: 608px) 100vw, 608px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;동적 라이브러리 디렉토리 선택 및 적용 모듈 선택&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/79a2fb4f98d7333d2200a49cc80ea009/6244b/001-03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 446px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 41.66666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABYlAAAWJQFJUiTwAAABP0lEQVQoz53Py0rDUBAG4KMFW124cdGYpEnEnJykpGnS9DSX1gu6EIpab0UQBDe60qUg+Azim9S6Ke7cVBE3+ka/x4ArW7AuPmaYYYYZous6NEWGIWIQBEjTFEmSQNM0fPcmRXTDwJIXQjcppGIRkiRBluV/LcsWquKS4H6A6skV9ttbiOIEsqJALZWgqupoolcag1iUIt7chtNooR748MXbjNmwGINlsSy3bSfDbDtjihnTHI34zjLWKyGYW4PvuYh4iLhRQzPhiHkNSRSiGXOkUT2rxzyA61CUmYmy/RspdHowbp6xePGE6vkA84d9zOw+YG7vEbNCodNHfqeHvKj9KHTGI7nuC9jdB9Trd2zcfmLh7A3kYIjpoyGmhFz3dSLELIc4Pr1EtNoG9VJ4fA1efQWVsIWKiNTlsAT6R1/cEwUzLMPoLAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/79a2fb4f98d7333d2200a49cc80ea009/6244b/001-03.png&quot;
        srcset=&quot;/devHistoryBlog/static/79a2fb4f98d7333d2200a49cc80ea009/8ff5a/001-03.png 240w,
/devHistoryBlog/static/79a2fb4f98d7333d2200a49cc80ea009/6244b/001-03.png 446w&quot;
        sizes=&quot;(max-width: 446px) 100vw, 446px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/c6f14343c9dc05d5e2cee30aa6ad2ac4/38cea/001-04.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 678px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 51.25000000000001%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABYlAAAWJQFJUiTwAAACDElEQVQoz3WSy27TQBSG/RpINFtYwIJe47udOGnt2I7jNE16i9rSliYFFQkJiRJoqvYJAFVswuV52BQQQtAu2vIgHzMm5VKJxaf/n/8ce2bso/TCgPWZCno6w1THxbKK6I5LoTxDa3GZuYVF6nMt5pfa2VqqrOm2i+kW/8FwCih+waMoF56H7hcwRSgLlshdr0yhNI0j9NK7AvmwfKEx7DWGXmZKKQiJkhpxUmfaj6lUU/yoSlSrE8QJtUYzI4hrhKJH1pPZJuncPHHayLJU3ED2yI2USr1B1F4jqIYktQg/KBMLH8cVwtDPvGnp6IYqPof2G9vWMzX/8rploVitx6idAdrGe7ytd2irA9zNt9jrbzDWBjgbAyaXjpgQ3Exf/ocX3EhfMV5somjrrxnbPUbdu6B8eIHaO8PZP8fun6MJL9Xu/8jIdU8Z6Qi6VxDZ9e0zRisPUJzOEflnHzCfn1I5PMV4+o3S/gle/wSz953C3gm+yO88+sq1u5/IbX5mRCA1t/FxyDG5rS9MxPfFCYN5JpN7GGkXe4hZ+4OedIa6zUTYyZiKpHYZr+4wFu8wKhivPkT1IhTDNNF1NUO7gvwRUg1Tp5pEtNsLrKws02gkWGJ8bs8+wVw9wF474FZjF80LxQktB9V0yBv2L6S/ZJjJui3msOSHGXIWVdtjtNRkKlgkLxgrt8jbRX4ClPmOR0RiZWUAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 04&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/c6f14343c9dc05d5e2cee30aa6ad2ac4/38cea/001-04.png&quot;
        srcset=&quot;/devHistoryBlog/static/c6f14343c9dc05d5e2cee30aa6ad2ac4/8ff5a/001-04.png 240w,
/devHistoryBlog/static/c6f14343c9dc05d5e2cee30aa6ad2ac4/e85cb/001-04.png 480w,
/devHistoryBlog/static/c6f14343c9dc05d5e2cee30aa6ad2ac4/38cea/001-04.png 678w&quot;
        sizes=&quot;(max-width: 678px) 100vw, 678px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h3&gt;2.2. VM 옵션에 적용&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Run/Debug Configuration → VM options 필드에 java.library.path 적용&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;D&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;java&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;library&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;동적 라이브러리 경로&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;h2&gt;3. UnsatisfiedLinkError&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;동적 라이브러리가 제대로 적용이 되지 않았을 경우, 아래와 같은 UnsatisfiedLinkError 오류가 발생한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;java&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lang&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;/span&gt;UnsatisfiedLinkError&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; no xxxxx in java&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;library&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; 
at java&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;base&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;java&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lang&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;/span&gt;ClassLoader&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;loadLibrary&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;ClassLoader&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;java&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2429&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;~&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;na&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;na&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
at java&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;base&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;java&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lang&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;/span&gt;Runtime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;loadLibrary0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Runtime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;java&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;818&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;~&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;na&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;na&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
at java&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;base&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;java&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lang&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;/span&gt;System&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;loadLibrary&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;java&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1989&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;~&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;na&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;na&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;h2&gt;4. 기타 알게된 내용&lt;/h2&gt;
&lt;h3&gt;4.1. 동적 라이브러리 확장자&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;window : *.dll&lt;/li&gt;
&lt;li&gt;linux: *.so&lt;/li&gt;
&lt;li&gt;mac : *.dylib&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4.2. &lt;strong&gt;LD&lt;em&gt;LIBRARY&lt;/em&gt;PATH와 java.library.path&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;LD&lt;em&gt;LIBRARY&lt;/em&gt;PATH 환경변수는 ‘로더(Loader)‘가 공유 라이브러리나 동적 라이브러리를 찾아야 할 때 어떤 경로를 찾아가야 하는지를 지정하는 환경변수다. 실행 파일을 찾아가는 PATH 환경변수의 라이브러리 버전이라고 생각하면 된다.&lt;/li&gt;
&lt;li&gt;로더가 라이브러리를 로딩할 때 우선적으로 LD&lt;em&gt;LIBRARY&lt;/em&gt;PATH에 명시된 경로들을 찾아가면서 공유 라이브러리와 동적 라이브러리 파일을 찾게 되며, 그 다음에 표준 라이브러리 경로인 ‘/lib’과 ‘/usr/lib’을 찾게 된다.&lt;/li&gt;
&lt;li&gt;자바 애플리케이션을 실행할 때 공유 라이브러리 경로를 -Djava.library.path 옵션으로 주게 되는데, LD&lt;em&gt;LIBRARY&lt;/em&gt;PATH 환경변수로 경로를 지정한 경우 -Djava.library.path 옵션으로 입력한 것처럼 경로를 찾아서 라이브러리를 로드하게 된다.&lt;/li&gt;
&lt;li&gt;결론은, &lt;strong&gt;LD&lt;em&gt;LIBRARY&lt;/em&gt;PATH 로 OS에 적용하는것과 java 실행시 옵션을 주는것은 같은 역할을 한다.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Spring + Kotlin 멀티모듈 생성]]></title><link>https://ssongey.github.io/works/posts/2022-07-23--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2022-07-23--001</guid><pubDate>Sat, 23 Jul 2022 00:00:00 GMT</pubDate><content:encoded>&lt;br/&gt;
&lt;p&gt;이번에 본사 인프라에서 kep 인프라로 이전하게 되면서 Ruby on Rails 로 되어있는 프로젝트를 Kopring 으로 변경하기로 결정을 하였다.&lt;br&gt;
해당 프로젝트는 여러개의 서비스가 한 프로젝트에 모두 담겨 있는데, 멀티 모듈로 구성하면 좋을 듯 하여 코프링으로 멀티모듈을 구성하게 되었다.&lt;/p&gt;
&lt;h2&gt;✔️ 환경&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;SpringBoot &lt;code class=&quot;language-text&quot;&gt;2.7.2&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Kotlin &lt;code class=&quot;language-text&quot;&gt;1.6.21&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Gradle &lt;code class=&quot;language-text&quot;&gt;7.5&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;h2&gt;✔️ 구성 방법&lt;/h2&gt;
&lt;p&gt;현재 한 프로젝트 내에 여러 도메인의 서비스들이 존재한다.&lt;br&gt;
추후 서비스 단위로 외주를 주거나, 다른 팀으로 넘어갈때를 대비하여 아래와 같은 구조로 생각했다.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/713b8120d36e3c0d362079a38ef543a0/f793b/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 38.75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABYlAAAWJQFJUiTwAAABRElEQVQoz4VRO66CUBCl14SKzobWBVjYkNgQCmELFDRasAXCDtyAoXYLNAixMlrYaGmlMRijIf6iwHmZSS4xD1/eJJP7mTPnnjlXKssSFPf7Hdfrlfd5nqMoCl6pfjgcsN1u8X6/+f4zCXM+n7mPsNIn4ePxwO9Yr9cIggDj8RhhGOJbXC6X74RCIb38er1477ouJEniVBSFa2IK6qXzn4S32632+mQygeM4GAwG8DyPm0XPvwqJkM6kNE3TyhtSK3BUOx6POJ1Olac1QgEmn3RdR7/fh23bWK1WMAwDpmlC0zTM53PGjUYj9Ho9WJaF4XBYJxS++L6PRqMBVVXR6XSQJAlkWUa73eY1iqLK12aziVarhW63iyzLIIRVIz+fT/5RIplOp1gsFtjv95jNZnxHudvteOTNZsOYOI6xXC55fKHwB0cQKaJDgXi+AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/713b8120d36e3c0d362079a38ef543a0/d9199/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/713b8120d36e3c0d362079a38ef543a0/8ff5a/001-01.png 240w,
/devHistoryBlog/static/713b8120d36e3c0d362079a38ef543a0/e85cb/001-01.png 480w,
/devHistoryBlog/static/713b8120d36e3c0d362079a38ef543a0/d9199/001-01.png 960w,
/devHistoryBlog/static/713b8120d36e3c0d362079a38ef543a0/f793b/001-01.png 1404w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;h2&gt;✔️ 멀티 프로젝트 생성&lt;/h2&gt;
&lt;h3&gt;1. 프로젝트 생성&lt;/h3&gt;
&lt;p&gt;1.1. 프로젝트 생성은 spring initializer / kotlin + gradle 로 구성하였다.

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/20f8189a93f11e3b544020d30f2ff4de/75a80/001-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 51.66666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABYlAAAWJQFJUiTwAAABn0lEQVQoz41S207CQBT0g4zRoNx6b7d3sKhYCgU1Ud989AN89NOgrRVEX/wWyHh2wYiJEJtMN+d0dzoze/ZAz3K55Ave5+/opX0koyvEgxRxP0U3SdEb3lB/iIs4wUUvQZdwmQzQ7pxjOpthk2OPvxaLhSgmeY66rEHSDFSbMhTdRFMzobshDNuFajKqddQkhfapOKicYDzJsMmxIlyz50UBxTDheAFk3RAEmmWjFUUIow5sP4TlegLM81FXVGR5sZ1wPP1ELX6ClD7jIHwkQpt+YMF0PDhBa6VQ1QVkUl+pNTDJ8h0KyykUFhAJW1lljiB0icxrtaFaTNQ8kp2E34GW5StsN4BPhzVSo67ByWw/EEp1Zos4/qWwKEtopIrnxg8YtgPT9eFH5wiiM/inHTBSK9G33QoXK8IXCphZDnS6UW5L4xZ57bUpCg+yRWA+ZLLNrR/Xm3QpfylcF+Msw+FxVYwF3yxR+A1FExarTYl6DdHn4GO1f1ShsZlsz/BtPkdvMMTN3b0YZI4kHdE6EusPqH91i7PrB8zmH78G+wudtgztEFtoJQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/20f8189a93f11e3b544020d30f2ff4de/d9199/001-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/20f8189a93f11e3b544020d30f2ff4de/8ff5a/001-02.png 240w,
/devHistoryBlog/static/20f8189a93f11e3b544020d30f2ff4de/e85cb/001-02.png 480w,
/devHistoryBlog/static/20f8189a93f11e3b544020d30f2ff4de/d9199/001-02.png 960w,
/devHistoryBlog/static/20f8189a93f11e3b544020d30f2ff4de/75a80/001-02.png 1134w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;1.2. 상위 프로젝트의 src 디렉토리는 불필요하므로 삭제한다.

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/a6689334a024ef4a0ff33d2f5be554e4/84bf8/001-03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 50.83333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABYlAAAWJQFJUiTwAAABfElEQVQoz52STWsTURSG85uExjgfmWQyH/mYz8zkJpNAzEJBpBt/geC6qypddFm6FJSCP0VEsPgDMslCXEzQzuPNNC0I2hovvBw4l/Pcl/eeGrtTlmVVv30veHn2kaO3n3jz/guvK11y/O66nlxc8ur8M6cfvvLj59Vvs9tauwFe7ZrLfIUWPKEfzIinh3Qnh+iDx7cy/AUHlrybv6DYbP4OLMvr1/I8x3VNwshHiATH7aBqDZpNtZJhaChKnTSNKIrifoe5dNi2u9heRDKeEgxTWpaLapgoUmqrw4GiE6XjfYAOdi8kSgRBnNDzAjpOF6XZQmuZ1BVNAsUeQMvBHYSk44x4JDB3sP8DrlaYlo3uxfgiI4hinN6ApmlVMNVo7+/Q6vaw/SGhzCkcJjLHhL4f3kIfqnrl/N+AyyUdOdweSXdBKNcnxNu67HsyW5dHusGDegM/Ht4NvGmu12uy+YJoMkNMpqRbySxH2RSRzUjEpPqop8+es/nDHv4C2t1SYeAHCiYAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/a6689334a024ef4a0ff33d2f5be554e4/d9199/001-03.png&quot;
        srcset=&quot;/devHistoryBlog/static/a6689334a024ef4a0ff33d2f5be554e4/8ff5a/001-03.png 240w,
/devHistoryBlog/static/a6689334a024ef4a0ff33d2f5be554e4/e85cb/001-03.png 480w,
/devHistoryBlog/static/a6689334a024ef4a0ff33d2f5be554e4/d9199/001-03.png 960w,
/devHistoryBlog/static/a6689334a024ef4a0ff33d2f5be554e4/84bf8/001-03.png 1162w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;h3&gt;2. 서브 모듈 생성&lt;/h3&gt;
&lt;p&gt;2.1. core, api-server1, api-server2 모듈을 생성한다.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/c73923b15869d46fc09ffa6b1e477636/41d3c/001-04.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 490px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 64.99999999999999%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAABYlAAAWJQFJUiTwAAACv0lEQVQ4y22STW8bZRDHfYBvwA0oakIbaESbGsfeV++u19619927a69f4iROoSmtIkBc2krwGbhx4cgHoBWIIg4tt9Iv9WO8aaJW6uGnZ56Z0f+ZmWcat9yIpjOiqVk0LY99x+em5rDTMvhs32C30635vG3WfKFa9X0T29wv4hf+xvu7LrdnZ2xPHrAXrdjP73Ddm7MbrthLjtGmp+z4C7b7Fa3xCbfEd9Wdcjtd08xOaBdf8WE3571dhw86EY09vYsaT+hUJ7hxiSO2PhzjjWf00ymDrMLL5/TSqvaZQY7mp/SSCW4yFc7zm7ZP2+7RSEcmYRiSRAlhMiYQojRnFGcMo4x4XHL33n1Ov3lAVlZ1PM4Kyc3Fzs/zs5IojkiGBg3VNDFsFz0qMPwI1wuwvRH9YcQgiMUOMHs+Rs/DdH26wsV5SX+ILhqaaDU6Rhe98yVbx2fczCYU8YjJtCROQooiZX00xxvYaGoLw2hj6O9G1dp0ZHwNxbC4XvxC97s/aJ0+xfvhb+xv/8L9/hnK/T+5unjC9vLpJVvLJ2+xvfidrdUzdsY/o+jGpkKLT8vfsB79w41HzwkevyL68T+Sn14xePiSaycv+OjgOVcOX/DxanP+yydHbyD+K+uXovGrCOoyQxFsqTrF6oy8uscwlbYXa8LxnDCfMT9cM1kcMlutmS6P6vmplszL7qNZrxFbMR0UGZ8IdtlXFSbVMdPyjvxaKL8sazHwavwgxBsFOP0Brj+UD3TQuha6Zb+FapjngkotqJNLFVExIc1LEqGl6DJkk7ZmStxANW2pwhIxRwSc+l7HhY1v0+mloKKoeNKmtvyaSHZyFKekRSnVZozLaf3IRuQCVYT7w4CymjNbHmC5A5nfGxW2pcKkOsDbLGiSSoVFLRSI7QWysOOiFtK69qWg64/qhzZ5Vk9m+Lrl/wF98OW9QDoQwAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 04&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/c73923b15869d46fc09ffa6b1e477636/41d3c/001-04.png&quot;
        srcset=&quot;/devHistoryBlog/static/c73923b15869d46fc09ffa6b1e477636/8ff5a/001-04.png 240w,
/devHistoryBlog/static/c73923b15869d46fc09ffa6b1e477636/e85cb/001-04.png 480w,
/devHistoryBlog/static/c73923b15869d46fc09ffa6b1e477636/41d3c/001-04.png 490w&quot;
        sizes=&quot;(max-width: 490px) 100vw, 490px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/81fd6774adc250f3183f2ea9e939eea8/6568d/001-05.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 48.33333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABYlAAAWJQFJUiTwAAACC0lEQVQoz31SWWsTURTOv1GxbdLS1MyS2TNblmmMtM2YdFJEUPBdSvHZpUkrLn2Q2ie1gpBfk/8RiDOJWT/PvSGCuFz4uHfOzDnzLTelFhxoBRc67QyKE0CxS8ibNmTTgaxbUM0C0ts7aJ+dg63xeIzpdPoH5vM5UoIkIicJkDWNmk1IdgDR8iEaDiTTg6BZEBUNtzYyeHHaxnIt8K+V0ssNSG6dGPnQiIntl1AMduFVduET3FIFbrGMrCChc/6aN32PE8TJCMmQ4QdHnAwxnkyIYe0YmfJTiIUaVF2HYlh8qGG7kIgZY8dqa5ktvH1/gcFggP0wRCtqohFFOAjraEaH8IpFXH+9RsowVGiaTOxM5Emy5fpwiBH307R4TdYMbGbv4PjkGbrdLoolD7VqANdzoWoKDFNHZjONq6uPSDHT83qBs2Dmm45HcCkoGwbtrM6Grm9t42W7g16vR6H58PbuI6jW6KcF5PIqbqyl8eGSBuaNpekqsdEsGxbJZb6x82oYw22S/ObdBfr9Pu7uhzh6/AR7ByH5XUVQu8e//fyFJDM5DIwdKzKp7Lyqr95tEMPTzhkPJY5jjEYjDHkoQ9qHSJIEExYK82ZHlJGTFc5UUnUIJIGlmqV6VpD58831DJ6/Wl6bxeI/16b14CGldYR64/A3hM3oFxpRC5XGI1x++sabZrMZH/o3/ATVMOQt5nliUQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 05&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/81fd6774adc250f3183f2ea9e939eea8/d9199/001-05.png&quot;
        srcset=&quot;/devHistoryBlog/static/81fd6774adc250f3183f2ea9e939eea8/8ff5a/001-05.png 240w,
/devHistoryBlog/static/81fd6774adc250f3183f2ea9e939eea8/e85cb/001-05.png 480w,
/devHistoryBlog/static/81fd6774adc250f3183f2ea9e939eea8/d9199/001-05.png 960w,
/devHistoryBlog/static/81fd6774adc250f3183f2ea9e939eea8/07a9c/001-05.png 1440w,
/devHistoryBlog/static/81fd6774adc250f3183f2ea9e939eea8/6568d/001-05.png 1660w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;2.2. src를 제외하고는 불필요 하므로 삭제한다.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/6db8e21f1029bcca6557df9e1597079a/d99f2/001-07.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 336px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAABYlAAAWJQFJUiTwAAACBElEQVQ4y41UaW/TQBDNvwJix0d8xcfWcQ6nlMRxU9IjTYtCk54gJKJ+AAkhJNQv/NjHzMJWPVwpHzazx+zzmzdvUzNsBw2rCScIIbIuLNOCZtqwHE/u6zTn+G9tw2y68FoRNMOSZ09HjQ/9MEa708fNrz/ITq9xsVrh6uYz8u0dHJ+c4mx5jqPjORZnS7kuJ3vyI1WgNd6s0zAME2aaozE8gEgShIlAvWHCJeZBlMB2fYqxXCvmlYD8wxebfgstYut5Pi7X35CPdtHp5ej2B7JMzlFDXa4EVEmqBIO0KqYziG5OgH2SoifZvarrMu+NbuC11rgHewpa42SbQIIkRbF3AJ+Y2q6HKNmS0WHmcYJYpDKyFBkxZ9aVDPkC6yK22lh8v4NYrXF5zk35hF6+fd+U/cMjLD4uMZufyLnjBY/Kf1ayTk2puy3o7QFCYsI24dJUAx5e3qgp7MOIyvEprn/eYbw/w3BU4F0xlmUrQAZRo1JDtoxKVmJHaYe6HpKByTLkUda5ik0lQ9bPJQZJ1sOHqy/U3QHSrIP+4K00Np9xZ18CeAbIWlnEgD1YXt8iXN2iHA0xJeEn76cQ7Uwy3xhQ+18yv1ONxDaCGFm+A5M+wvvqTW8C9rgpVFoYC/nwv/74jfJwjnG5i6KcyL0qi7zI8GH3eG4SKzYuG54Z8j/Spgz/AqR1JmK9CDruAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 07&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/6db8e21f1029bcca6557df9e1597079a/d99f2/001-07.png&quot;
        srcset=&quot;/devHistoryBlog/static/6db8e21f1029bcca6557df9e1597079a/8ff5a/001-07.png 240w,
/devHistoryBlog/static/6db8e21f1029bcca6557df9e1597079a/d99f2/001-07.png 336w&quot;
        sizes=&quot;(max-width: 336px) 100vw, 336px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;h3&gt;3. root 프로젝트 settings.gradle.kts 파일 설정&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;settings.gradle.kts&lt;/strong&gt; 는 빌드 대상 프로젝트를 설정하는 파일이다.&lt;br&gt;
서브 모듈을 include 해주면 gradle 탭의 root 프로젝트 하위에 모듈이 표시가 된다.  &lt;/p&gt;
&lt;p&gt;3.1. settings.gradle.kts 파일 수정

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/31713c8de741e87fe65480052908597d/35890/001-08.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 35.416666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAABYlAAAWJQFJUiTwAAABGElEQVQoz52R206EMBRF51t8cmgLBVpgGArlfhuDmInx/39ke6hG39T4sHJ6ktPV3fZUtwP6YcY4LI6BsF2Dum+RmQtUppHkCVSqESmFMI6QFgXacUbZdGiGCWXbw04rmmnGSekE17xEZSxMbmCuFUkUdBZDX2LEWUSyCFESkkxChoL6FNP6hJk46iGuSdgdwjDW8IMAXHAwzsA5JxgYY989+6ziWHsIwgjjdsdw22C6CampkZU1FIVxQi4EvPMZnscI7wfoEJp7FBJ+/4x0uUPaBaKaHQ9J/SEUwncbXKpfOOYCulG33LC/vmHbX2DpDXNToai+hOLvQkroS4l2WrBuu/ucK4nyg/KfwkCGKGxLNCSxDiel+g4J3eORhS+pgwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 08&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/31713c8de741e87fe65480052908597d/d9199/001-08.png&quot;
        srcset=&quot;/devHistoryBlog/static/31713c8de741e87fe65480052908597d/8ff5a/001-08.png 240w,
/devHistoryBlog/static/31713c8de741e87fe65480052908597d/e85cb/001-08.png 480w,
/devHistoryBlog/static/31713c8de741e87fe65480052908597d/d9199/001-08.png 960w,
/devHistoryBlog/static/31713c8de741e87fe65480052908597d/07a9c/001-08.png 1440w,
/devHistoryBlog/static/31713c8de741e87fe65480052908597d/35890/001-08.png 1582w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;3.2. 같은 root 프로젝트와 같은 레벨에 생긴 모듈들은 모두 unlink를 해준다.

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/c2d1e40694da356f726f2e2a45939107/9cea8/001-09.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 47.08333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAABYlAAAWJQFJUiTwAAACFklEQVQoz42RS08TURiG+2MwhiDQltqWXu30wgzTDi0FWtoOLagkbpRbA7ZcpCjFBVUxuFIQjWGDkSZu2LjxL7WQsHk8c1ATd57kybs4b5583zm2o8+n7LUO2N0/YHuv9Q+Nl6+obTc5O//O/x5bpvSIHqeCI2QIxhgIJBkU3AlncMWnuO1VqTZasvzlrE11s8nyRpPF+gsW6s8lyxu7zC/UufjxUwiXTxnMH5J6fEJ6volabhApNlDMHRIzOwyk6iy1LqSwtrVDn8ON3e3HE4riDkRwBxW8cZ2egSE+HH/CZlZmCdyLYKTTxBIxNF1DG71BT+p4hr2s1epcXl5S39hEUUfJ5vKkxjJoKYNRgZGdZMg7zMcTISzOVPCFFSYKprhMEx3RUBIaMVUXqWJ3eVhcqdJut3myuIQ/rpLOF1D1pOwGI1FCSow+u5MjS5grFHF6fRjTJXQjTVzTicQS+MMRWbS73KxvPbtZWUwYjMbICuGkwMhkxXYK4WicfscQx5YwXzS56wuQFeLxyRwTuWlZCPwWOu56/gqra09xenyM6IaczBsI4RLDWHmrt4/3R8fYLIk17kjSkILhYFiWLDz+IL39g6zW1qVw//UbMqJfvv+AfMkkVyzJtJ5NF2/69ds5tpXVNcancsw+nMeszFEwy5TKFYoCc3ZO3OV5e/hOCq+uruh0OpJut0tXfNSf7Ii8vr7mF/qbo//mK1b7AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 09&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/c2d1e40694da356f726f2e2a45939107/d9199/001-09.png&quot;
        srcset=&quot;/devHistoryBlog/static/c2d1e40694da356f726f2e2a45939107/8ff5a/001-09.png 240w,
/devHistoryBlog/static/c2d1e40694da356f726f2e2a45939107/e85cb/001-09.png 480w,
/devHistoryBlog/static/c2d1e40694da356f726f2e2a45939107/d9199/001-09.png 960w,
/devHistoryBlog/static/c2d1e40694da356f726f2e2a45939107/9cea8/001-09.png 1278w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;⚠️  만약 unlink 를 안하면??&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;빌드를 시도할 경우 root 프로젝트의 &lt;strong&gt;하위 모듈이 빌드가 되지 않고&lt;/strong&gt;, 같은 레벨에 있는 모듈이 빌드가 된다.&lt;br&gt;
이는 파일명 자체에서도 확인할 수 있는데, 하위 모듈이 될 경우 해당 프로젝트 명은 콜론(:) 표시가 되어야 하는데, unlink를 하지 않은 api-server2의 경우 파일명 뒤에 프로젝트명에 콜론표시가 없다.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/b1f94d33f023b3b6e5aa6557e58c168f/67a79/001-11.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 38.75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABYlAAAWJQFJUiTwAAABMUlEQVQoz52RyW7CMBCGeZeqhziQjZgsQJw4TsBZSBNBN5VL3/8d/toOordK5fBpxiP704xnIQ4NqoNEWR8haomirMDlCcPnN/r3K7rXK9rLl4llN2GXF5Bth5yXyFSuYQUHU+eccywojZBsUsQ0QRptTQxoiDCJFRH8dQgvmHE9H86GIuQNvL0A5RIBO8DLarhlZ+oLzw9g20Rh3+NS5+Q3Xy5nVrru+AjECdtmwpq3sFKB54jjOeZ4okwL1yD6MbENxEBA7BvkhpJZlgXHdSG7HuPbB17GEcemMUiFGfkuNB3+jb63clxkvEI1TJD9gEq2SFmBeMeQZvn/hY4SMlGjG88YzxfV7UktimOrpI8JXd2hQHlUo6ptD+OEfhiQFeUjwvkPdTfJnhlSTTaPq+s/qD8Gmt/sMKAAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 11&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/b1f94d33f023b3b6e5aa6557e58c168f/d9199/001-11.png&quot;
        srcset=&quot;/devHistoryBlog/static/b1f94d33f023b3b6e5aa6557e58c168f/8ff5a/001-11.png 240w,
/devHistoryBlog/static/b1f94d33f023b3b6e5aa6557e58c168f/e85cb/001-11.png 480w,
/devHistoryBlog/static/b1f94d33f023b3b6e5aa6557e58c168f/d9199/001-11.png 960w,
/devHistoryBlog/static/b1f94d33f023b3b6e5aa6557e58c168f/67a79/001-11.png 1408w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;h3&gt;4. build.gradle.kts&lt;/h3&gt;
&lt;p&gt;많이 삽질한 단계…&lt;/p&gt;
&lt;p&gt;각각 모듈 내의 build.gradle.kts 에 설정을 해줘도 되지만, 관리를 편하게 하기 위해 &lt;strong&gt;root 프로젝트의 build.gradle.kts 파일에 모두 설정&lt;/strong&gt;하도록 하였다. (그래서 위 서브 모듈 생성시에 src를 제외하고 모두 지웠다.)&lt;/p&gt;
&lt;h4&gt;AS IS)&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;groovy&quot;&gt;&lt;pre class=&quot;language-groovy&quot;&gt;&lt;code class=&quot;language-groovy&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; org&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;jetbrains&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;kotlin&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;gradle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tasks&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;KotlinCompile

plugins &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token function&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string gstring&quot;&gt;&quot;org.springframework.boot&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; version &lt;span class=&quot;token string gstring&quot;&gt;&quot;2.7.2&quot;&lt;/span&gt;
	&lt;span class=&quot;token function&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string gstring&quot;&gt;&quot;io.spring.dependency-management&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; version &lt;span class=&quot;token string gstring&quot;&gt;&quot;1.0.12.RELEASE&quot;&lt;/span&gt;
	&lt;span class=&quot;token function&quot;&gt;kotlin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string gstring&quot;&gt;&quot;jvm&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; version &lt;span class=&quot;token string gstring&quot;&gt;&quot;1.6.21&quot;&lt;/span&gt;
	&lt;span class=&quot;token function&quot;&gt;kotlin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string gstring&quot;&gt;&quot;plugin.spring&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; version &lt;span class=&quot;token string gstring&quot;&gt;&quot;1.6.21&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

group &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string gstring&quot;&gt;&quot;com.example&quot;&lt;/span&gt;
version &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string gstring&quot;&gt;&quot;0.0.1-SNAPSHOT&quot;&lt;/span&gt;
java&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sourceCompatibility &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; JavaVersion&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;VERSION_17

repositories &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token function&quot;&gt;mavenCentral&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

dependencies &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token function&quot;&gt;implementation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string gstring&quot;&gt;&quot;org.springframework.boot:spring-boot-starter-web&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token function&quot;&gt;implementation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string gstring&quot;&gt;&quot;com.fasterxml.jackson.module:jackson-module-kotlin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token function&quot;&gt;implementation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string gstring&quot;&gt;&quot;org.jetbrains.kotlin:kotlin-reflect&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token function&quot;&gt;implementation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string gstring&quot;&gt;&quot;org.jetbrains.kotlin:kotlin-stdlib-jdk8&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token function&quot;&gt;testImplementation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string gstring&quot;&gt;&quot;org.springframework.boot:spring-boot-starter-test&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

tasks&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;withType&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;KotlinCompile&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	kotlinOptions &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		freeCompilerArgs &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;listOf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string gstring&quot;&gt;&quot;-Xjsr305=strict&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
		jvmTarget &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string gstring&quot;&gt;&quot;17&quot;&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

tasks&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;withType&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Test&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token function&quot;&gt;useJUnitPlatform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;TO BO)&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;groovy&quot;&gt;&lt;pre class=&quot;language-groovy&quot;&gt;&lt;code class=&quot;language-groovy&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; org&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;jetbrains&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;kotlin&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;gradle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tasks&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;KotlinCompile

plugins &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token function&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string gstring&quot;&gt;&quot;org.springframework.boot&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; version &lt;span class=&quot;token string gstring&quot;&gt;&quot;2.7.2&quot;&lt;/span&gt;
	&lt;span class=&quot;token function&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string gstring&quot;&gt;&quot;io.spring.dependency-management&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; version &lt;span class=&quot;token string gstring&quot;&gt;&quot;1.0.12.RELEASE&quot;&lt;/span&gt;
	&lt;span class=&quot;token function&quot;&gt;kotlin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string gstring&quot;&gt;&quot;jvm&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; version &lt;span class=&quot;token string gstring&quot;&gt;&quot;1.6.21&quot;&lt;/span&gt;
	&lt;span class=&quot;token function&quot;&gt;kotlin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string gstring&quot;&gt;&quot;plugin.spring&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; version &lt;span class=&quot;token string gstring&quot;&gt;&quot;1.6.21&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

allprojects &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	repositories &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token function&quot;&gt;mavenCentral&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

subprojects &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	apply &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token function&quot;&gt;plugin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string gstring&quot;&gt;&quot;org.springframework.boot&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;token function&quot;&gt;plugin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string gstring&quot;&gt;&quot;io.spring.dependency-management&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;token function&quot;&gt;plugin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string gstring&quot;&gt;&quot;kotlin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

	group &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string gstring&quot;&gt;&quot;com.example&quot;&lt;/span&gt;
	version &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string gstring&quot;&gt;&quot;0.0.1-SNAPSHOT&quot;&lt;/span&gt;
	java&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sourceCompatibility &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; JavaVersion&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;VERSION_17

	dependencies &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token function&quot;&gt;implementation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string gstring&quot;&gt;&quot;org.springframework.boot:spring-boot-starter-web&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;token function&quot;&gt;implementation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string gstring&quot;&gt;&quot;com.fasterxml.jackson.module:jackson-module-kotlin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;token function&quot;&gt;implementation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string gstring&quot;&gt;&quot;org.jetbrains.kotlin:kotlin-reflect&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;token function&quot;&gt;implementation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string gstring&quot;&gt;&quot;org.jetbrains.kotlin:kotlin-stdlib-jdk8&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

		&lt;span class=&quot;token function&quot;&gt;testImplementation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string gstring&quot;&gt;&quot;org.springframework.boot:spring-boot-starter-test&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

	tasks&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;withType&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;KotlinCompile&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		kotlinOptions &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
			freeCompilerArgs &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;listOf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string gstring&quot;&gt;&quot;-Xjsr305=strict&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
			jvmTarget &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string gstring&quot;&gt;&quot;17&quot;&lt;/span&gt;
		&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

	tasks&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;withType&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Test&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token function&quot;&gt;useJUnitPlatform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string gstring&quot;&gt;&quot;:core&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string gstring&quot;&gt;&quot;:api-server1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	dependencies &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token function&quot;&gt;implementation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string gstring&quot;&gt;&quot;:core&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string gstring&quot;&gt;&quot;:api-server2&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	dependencies &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token function&quot;&gt;implementation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string gstring&quot;&gt;&quot;:core&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;allprojects&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;root project 및 하위 프로젝트 모두에 대한 의존성 관리&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;subprojects&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;setting.gradle 에 include 된 프로젝트를 전부 관리&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;project&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;하위 프로젝트의 의존성 관리&lt;/li&gt;
&lt;li&gt;core 의 경우 공통 모듈이기 때문에 api-server1, api-server2 에 의존성 주입&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;h3&gt;5. application.yaml 설정&lt;/h3&gt;
&lt;p&gt;각 api 모듈들은 각 다른 포트로 실행되어야 하므로 port 를 다르게 지정해준다.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/f349392906e95a0b69e0397110eae405/bb2fd/001-12.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 26.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAABYlAAAWJQFJUiTwAAAA90lEQVQY03WP227CMBBE8zvEjuNr4lzIhUIkWlUoCFJKSFX6//8wtS0hlYc+HO2svbNjR8M44rT84HS943j9xuT1fA+8jhOG/QFN/xJ4Px9xuS2YPmecHZfbFz7mJfB2GFE1HaK638G2AzZ9h23fwtYdVNFAO1ReQUqNNOUQmUK5blG3G2ybArvGwtoCJrfIHNoYMJYisjYDdwbFGdaKQEkBU3VuSQpGiRtiTrPQC6mQCgnBKEqxclpBlS0IoYjjFSiliHRmIZRB4owxIe7yf7Q2kEqDCxECOOdP+LPIZDm4+1aSJC4lDkZfHzx6X/2LfDih9GnmL78bdKVMosvjEgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 12&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/f349392906e95a0b69e0397110eae405/d9199/001-12.png&quot;
        srcset=&quot;/devHistoryBlog/static/f349392906e95a0b69e0397110eae405/8ff5a/001-12.png 240w,
/devHistoryBlog/static/f349392906e95a0b69e0397110eae405/e85cb/001-12.png 480w,
/devHistoryBlog/static/f349392906e95a0b69e0397110eae405/d9199/001-12.png 960w,
/devHistoryBlog/static/f349392906e95a0b69e0397110eae405/bb2fd/001-12.png 1058w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;h2&gt;✔️ 공통모듈 의존성 테스트&lt;/h2&gt;
&lt;p&gt;core 모듈에 요청 로깅 필터 클래스 생성 후 빈으로 등록하여 각 api 모듈에서 로깅이 되는지 확인 한다.&lt;/p&gt;
&lt;br/&gt;
&lt;h3&gt;1. core 모듈에 RequestLoggingFilter 생성 후 Bean으로 등록&lt;/h3&gt;
&lt;p&gt;ReqeustLoggingFilter 클래스&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;kotlin&quot;&gt;&lt;pre class=&quot;language-kotlin&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; RequestLoggingFilter &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;OncePerRequestFilter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; accessLogger&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Logger &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; LoggerFactory&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getLogger&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ACCESS_LOGGER&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;doFilterInternal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;originalRequest&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; HttpServletRequest&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; originalResponse&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; HttpServletResponse&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; filterChain&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; FilterChain&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        filterChain&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;doFilter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;originalRequest&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; originalResponse&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        accessLogger&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;access log&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;WebConfig 클래스에서 bean 으로 등록&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;kotlin&quot;&gt;&lt;pre class=&quot;language-kotlin&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;&lt;span class=&quot;token annotation builtin&quot;&gt;@Configuration&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; WebConfig &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; WebMvcConfigurer &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;token annotation builtin&quot;&gt;@Bean&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;requestLoggingFilter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; FilterRegistrationBean&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;RequestLoggingFilter&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; filterRegistrationBeanRequest&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; FilterRegistrationBean&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;RequestLoggingFilter&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; FilterRegistrationBean&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;RequestLoggingFilter&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;token function&quot;&gt;RequestLoggingFilter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        filterRegistrationBeanRequest&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;RequestLoggingFilter&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; filterRegistrationBeanRequest
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;p&gt;이때 아래와 같이 ‘open’ 키워드를 사용하라는 오류가 발생한다.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/ff80f3949885d7107aba41d8c25101f7/c45c7/001-13.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 38.75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABYlAAAWJQFJUiTwAAABUklEQVQoz42R607CQBCF+zRKa2IqF+kixV52t3egBVoKFMLF+P5PcBwWjIaY4I8vM+fMTjKzo7lDE77HMGBtmOYLeq99dLpdokf6GbreIvRr/M7/0joMw4DGuiYCyRFKH47rQIYRfC7gCwHXHYFZfVgK6wJjCsasH19phj7lWqf9iDjLUG0/UW6OqDYHlOsdquaI5fbMiWqnS9zsUW8a1Ksay2av/PPbZU16tcK0KKD1TB0+TRhNcgTZBDKdgMdENFaIZEpeAUHeGRklRAwRZaom4rHyRBgrX3toGRDcRjXjqOYSZSExSSOMiwWS6YwaU7gigCfDK9EvbnUEzTB02O8+4nyNaf2BbL7FeNEgXezAaYLbhnto50t5QUL/d0BeNUjyUq0SZDMEaY4woZXiDDxM/oVmPOmwbEeN7/ocHl3Y8S7R9QVFieHIgTUYwnqz7/IFQOAfBtRnGCMAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 13&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/ff80f3949885d7107aba41d8c25101f7/d9199/001-13.png&quot;
        srcset=&quot;/devHistoryBlog/static/ff80f3949885d7107aba41d8c25101f7/8ff5a/001-13.png 240w,
/devHistoryBlog/static/ff80f3949885d7107aba41d8c25101f7/e85cb/001-13.png 480w,
/devHistoryBlog/static/ff80f3949885d7107aba41d8c25101f7/d9199/001-13.png 960w,
/devHistoryBlog/static/ff80f3949885d7107aba41d8c25101f7/c45c7/001-13.png 1346w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;코틀린에서는 기본적으로 클래스에는 &lt;code class=&quot;language-text&quot;&gt;final&lt;/code&gt; 키워드가 추가되며, 상속이 불가능하도록 되어있는데,&lt;br&gt;
Spring Boot 2.x 버전부터는 CGLIB Proxy 방식으로 Bean을 관리하고 있다. CGLIB Proxy는 Target Class를 상속받아 생성하기 때문에 &lt;code class=&quot;language-text&quot;&gt;open&lt;/code&gt; 으로 상속이 가능한 상태이어야 한다.&lt;br&gt;
때문에 &lt;code class=&quot;language-text&quot;&gt;all-open&lt;/code&gt; 플러그인이 필요하다.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/c26150d3a0bddef7c311fba3ed53afad/b4098/001-14.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 816px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 40.833333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABYlAAAWJQFJUiTwAAAA2UlEQVQoz3WS2QqEMAxF/f/v80lwxRdR3PctMydQ6XRmAuXGak5ubD15x33fiMzzLMuy6CK3YxxHGYZBwjAU3/clCAKpqkratn3qUc88HMehkL7vH52m6WmQJInkeS5FUSiY9+x3XSfneX4Dr+tSFwZCwbZtsu+7LpwARNkHRE7zD4f2yBQCBIxjNwCUZanfG+d2/YdDV01uFsG4uDTNfwLdDRdidF1XdRhFkYJR4Ez0BbTDhZm8rmsFpmkqcRxLlmV6OE3T6P//C/wH5xC4MkA5VUbGNVAb+AJ5yXBAHUEhywAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 14&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/c26150d3a0bddef7c311fba3ed53afad/b4098/001-14.png&quot;
        srcset=&quot;/devHistoryBlog/static/c26150d3a0bddef7c311fba3ed53afad/8ff5a/001-14.png 240w,
/devHistoryBlog/static/c26150d3a0bddef7c311fba3ed53afad/e85cb/001-14.png 480w,
/devHistoryBlog/static/c26150d3a0bddef7c311fba3ed53afad/b4098/001-14.png 816w&quot;
        sizes=&quot;(max-width: 816px) 100vw, 816px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;참고)&lt;br&gt;
&lt;a href=&quot;https://kotlinlang.org/docs/all-open-plugin.html#command-line-compiler&quot;&gt;All-open compiler plugin | Kotlin&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://jaeyeong951.medium.com/kotlin-class-%EC%82%AC%EC%9A%A9%EB%B2%95-24ee79062a96&quot;&gt;[kotlin] class 사용법&lt;/a&gt;&lt;/p&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;p&gt;build.gradle.kts 의 subprojects/ apply 블럭 내에 kotlin-spring 플러그인을 추가해준다.&lt;br&gt;
(kotlin-allopen 와 동일)&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/10ce86047e3dd5fef6de13d5d7627d67/46115/001-15.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 37.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABYlAAAWJQFJUiTwAAABUUlEQVQoz22Sy07DMBBF8zfgt53YcZzQR+iDik1ViQUbJPao/AH8+mXspq2ALo7H48h37oxTzRYj5stHxNQjtRZdFxFjpNhBaw2l1AUhBDjnfxDl/PytykLjaou69YhtU4RSSoUQWngfCI9AUUoFxthJiE2C4ix4Eq9yUtOF2W7EkkipRd8PaCOJxQaeiuQYOo86ODhvYJyGbQyslZCcUZGr0ypXlFpifdhhe9igTx7DQIJtgKklXNBooqEODEJyRE3Cls5cyRsaU+M1tJpaFrRoYzDun7HaPyH1HfphTg47WE+XIznzjmZoIAilFaSSBaVlyXOUU+uVI/s+Dnh4+UI8fCOs35FWr6jHN4jNEXJ7BF9nPmj/CRsWsCRirYUxV3KeqZTLFTSkTQVhaPjGQ+gAbuIFYTNdcZndSClvUnExvRa7O8HvCXaK7Ab/fpvf/AAY2P2JP9OiYwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 15&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/10ce86047e3dd5fef6de13d5d7627d67/d9199/001-15.png&quot;
        srcset=&quot;/devHistoryBlog/static/10ce86047e3dd5fef6de13d5d7627d67/8ff5a/001-15.png 240w,
/devHistoryBlog/static/10ce86047e3dd5fef6de13d5d7627d67/e85cb/001-15.png 480w,
/devHistoryBlog/static/10ce86047e3dd5fef6de13d5d7627d67/d9199/001-15.png 960w,
/devHistoryBlog/static/10ce86047e3dd5fef6de13d5d7627d67/46115/001-15.png 1290w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;h3&gt;2. 각 api 모듈에 controller 생성 후 테스트&lt;/h3&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/e508b31a62246b04c5669636864b2c8e/e0577/001-16.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 37.916666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABYlAAAWJQFJUiTwAAABUElEQVQoz22Sa26DMBCEuQ5+Y/wmgZBGrXr/A03HEEVVlB+fjLX27MyaYbt/Y79/YX38ol13xFxIRm4L9scPvm4r7vsNt/sDuTakUjGHCGMtcU88rPNwk8cQZ4/sLeZUEEg/7OcA5z1CzCjeIM7uaBRiOnDTBCkllFJEHvS9EBJDngw6MTfUdsFy3VDqgpQrJh/QvMJM8VwvaJcVdbke5+rS9xtay9jWEbUICgsKJosSFQUcO1tobY7OPcqc6DAp5MSG0cEyplL66Uz9+xanU7ocYnBIQXM2gXFnGKMgxhHaWIRSkOgw5wkxBXg6lXJkNPGGfDEo4+hQ4LFqXNqE1AqdGgqfglorrE2yztGwaWa9O+qX+9zeGcwRQyBYxUiM6hhZy9MhIysKWu6DU9BWw7LZ+QDiI0M4YnYRTTdPOJeJv0BMfFFnj9qrrs613/nEHydA/C7PJi+QAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 16&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/e508b31a62246b04c5669636864b2c8e/d9199/001-16.png&quot;
        srcset=&quot;/devHistoryBlog/static/e508b31a62246b04c5669636864b2c8e/8ff5a/001-16.png 240w,
/devHistoryBlog/static/e508b31a62246b04c5669636864b2c8e/e85cb/001-16.png 480w,
/devHistoryBlog/static/e508b31a62246b04c5669636864b2c8e/d9199/001-16.png 960w,
/devHistoryBlog/static/e508b31a62246b04c5669636864b2c8e/07a9c/001-16.png 1440w,
/devHistoryBlog/static/e508b31a62246b04c5669636864b2c8e/e0577/001-16.png 1796w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;api-server1, api-server2 모두 테스트시에 logging이 되지 않는다. 왜?&lt;/strong&gt;&lt;/p&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;h3&gt;3. ComponentScan 설정&lt;/h3&gt;
&lt;p&gt;프로젝트가 실행되면서 component scan을 하게되는데, 별도로 ComponentScan 관련 설정을 하지 않으면 @SpringBootApplication 이 정의된 곳이 base package 가 된다.&lt;/p&gt;
&lt;p&gt;따라서 각 &lt;code class=&quot;language-text&quot;&gt;@SpringBootApplication&lt;/code&gt; 가 설정되어 있는 클래스에 ComponentScan 설정을 해줘야 한다.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/561c41aea1539b5283ea7b658dad16b1/00e09/001-17.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 32.08333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABYlAAAWJQFJUiTwAAABCklEQVQY022Q/U4DIRDE73E8ju8Fehy1pk3T1hh9/7cZB9pUY/xjAmF/zOzudLx+4Xz9wOV6w+n2iW1/oF6xqxuipKEggsPxPJj3y4n8De3whto6155c1+SDIFgDrxVmpTHPMxQ1/5FxHqFLs778w73cz6m0ypSAfVNobcG2eUiKMMbAWA3rDDTDPNPrPqFtimznHFKOsNY+OWMWTJmGpQTUYmicsHLUlWNYdr3QSBNa1AyfWNsyaia3Cpk6OO/d4LqpXhSmmAsfPcGAslbksuOHFTkLHEd0zo1ufeRqJGJNfoQm/utcKQnO3znnLCZhIcaAEAKXKrzHh+ShOLoIvAvrPfyHk1/qHh7fSGy/Kh4gRK0AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 17&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/561c41aea1539b5283ea7b658dad16b1/d9199/001-17.png&quot;
        srcset=&quot;/devHistoryBlog/static/561c41aea1539b5283ea7b658dad16b1/8ff5a/001-17.png 240w,
/devHistoryBlog/static/561c41aea1539b5283ea7b658dad16b1/e85cb/001-17.png 480w,
/devHistoryBlog/static/561c41aea1539b5283ea7b658dad16b1/d9199/001-17.png 960w,
/devHistoryBlog/static/561c41aea1539b5283ea7b658dad16b1/07a9c/001-17.png 1440w,
/devHistoryBlog/static/561c41aea1539b5283ea7b658dad16b1/00e09/001-17.png 1854w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;다시 테스트를 해보면 api-server1, api-server2 모두 logging 되는것을 확인 할 수 있다.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/86cee71a19b5273a05a89885d9188e7e/c7bb6/001-18.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 21.666666666666668%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAABYlAAAWJQFJUiTwAAAA4UlEQVQY002Oy07DMBBF8y3gCAglTdM8HNtxHDtFFa8gUbHg///jMFFZsDi6c0czdyZbXldObxeeX1bS+Z0xLoR0xscTdkoYofeRbkPq/2jpbTNuvs66sJA5azHGcNWeun2irTp2u0eK4gGtNUXToPoeZQ1KvDIDt0JZ14yy5/2Ic5YwebIpBGl4QpjxwdMMB/TRogdNnCNuHLnXW5gldw4lXknAnYRV1Z55nv+IpJTItg96ub6plsXDsaTeN7RtK1cdXdeR2w9upm/57It8uAiizUrRf9LGH2qdJLxkX1X8AnZ4hjNOyuJ2AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 18&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/86cee71a19b5273a05a89885d9188e7e/d9199/001-18.png&quot;
        srcset=&quot;/devHistoryBlog/static/86cee71a19b5273a05a89885d9188e7e/8ff5a/001-18.png 240w,
/devHistoryBlog/static/86cee71a19b5273a05a89885d9188e7e/e85cb/001-18.png 480w,
/devHistoryBlog/static/86cee71a19b5273a05a89885d9188e7e/d9199/001-18.png 960w,
/devHistoryBlog/static/86cee71a19b5273a05a89885d9188e7e/07a9c/001-18.png 1440w,
/devHistoryBlog/static/86cee71a19b5273a05a89885d9188e7e/29114/001-18.png 1920w,
/devHistoryBlog/static/86cee71a19b5273a05a89885d9188e7e/c7bb6/001-18.png 1986w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/1c22d63ad9fbb68f6d96903ffe878c5e/19bb3/001-19.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 22.916666666666668%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAABYlAAAWJQFJUiTwAAABAklEQVQY011Qy07DMBDMpyBIqpKSEtux4+c6DxqQOCIhATf+/x+GddoTh/FY65n17FbL9o71ZcNle0NYZqTpgkArxpiZJziGDAmq8A0qZQwuwPoImlf2LKACvleRBYkIU2aRFRgHCykkTk8nGK1hvMdRD3gM/gp/Y35TXC++zH6iBEoJlbMWIQRGhNAdtDTonwXatoVSCmq0qIcBjXNoWFtQc9OauZcSKUYkbnTtEVCVoxRSIsjxDKNGKKlAmfafhTFotMGhNHQeDesPzMeug+gFT5d3P+0piROy8H/CMnJZQ04BZ7fgbv7BPaOOX3iI3zvX+gNd+IR7/eV9rhyih+DEf4oapio/j8+sAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 19&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/1c22d63ad9fbb68f6d96903ffe878c5e/d9199/001-19.png&quot;
        srcset=&quot;/devHistoryBlog/static/1c22d63ad9fbb68f6d96903ffe878c5e/8ff5a/001-19.png 240w,
/devHistoryBlog/static/1c22d63ad9fbb68f6d96903ffe878c5e/e85cb/001-19.png 480w,
/devHistoryBlog/static/1c22d63ad9fbb68f6d96903ffe878c5e/d9199/001-19.png 960w,
/devHistoryBlog/static/1c22d63ad9fbb68f6d96903ffe878c5e/07a9c/001-19.png 1440w,
/devHistoryBlog/static/1c22d63ad9fbb68f6d96903ffe878c5e/29114/001-19.png 1920w,
/devHistoryBlog/static/1c22d63ad9fbb68f6d96903ffe878c5e/19bb3/001-19.png 2066w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;p&gt;참고)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://bokyung.dev/2022/03/23/kotlin-gradle-querydsl/&quot;&gt;Kotlin + SpringBoot + JPA + Querydsl 멀티 모듈 프로젝트 설정하기&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://devs0n.tistory.com/m/50&quot;&gt;Kotlin Gradle Multi Module 적용하기&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://lannstark.tistory.com/149&quot;&gt;[Kotlin + Spring Boot + Querydsl] gradle multi project 구성하기&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://velog.io/@soyeon207/%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B6%80%ED%8A%B8-%EB%A9%80%ED%8B%B0-%EB%AA%A8%EB%93%88-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EB%A7%8C%EB%93%A4%EA%B8%B0&quot;&gt;[Spring] 멀티 모듈 프로젝트 만들기&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[[Spring] Kotlin Fuel]]></title><link>https://ssongey.github.io/spring/posts/2022-05-31--001</link><guid isPermaLink="false">https://ssongey.github.io/spring/posts/2022-05-31--001</guid><pubDate>Tue, 31 May 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; ■ Fuel &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The easiest HTTP networking library for Kotlin/Android.&lt;/li&gt;
&lt;li&gt;request, response, result 를 구조분해하여 편리하게 가져다 쓸 수 있다.&lt;/li&gt;
&lt;li&gt;Asynchronous 와 blocking 을 제공한다.&lt;/li&gt;
&lt;li&gt;async request 취소기능 제공&lt;/li&gt;
&lt;li&gt;Upload files 기능을 제공&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; ■ Async mode &lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;kotlin&quot;&gt;&lt;pre class=&quot;language-kotlin&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Using httpGet() over a String is giving us a Triple&amp;lt;Request, Response, Result&gt;.&lt;/span&gt;

&lt;span class=&quot;token string&quot;&gt;&quot;https://httpbin.org/get&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;httpGet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;responseString&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; request&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;is&lt;/span&gt; Result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Failure &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; errorData &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;error&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;errorData&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;is&lt;/span&gt; Result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Success &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

FuelManager&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;instance&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;basePath &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;https://httpbin.org&quot;&lt;/span&gt;
&lt;span class=&quot;token string&quot;&gt;&quot;/get&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;httpGet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;responseString&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; request&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; error&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; result
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;error &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//do something when success&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//error handling&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; ■ Blocking mode &lt;/span&gt;  &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;kotlin&quot;&gt;&lt;pre class=&quot;language-kotlin&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Using httpGet() over a String is giving us a Triple&amp;lt;Request, Response, Result&gt;.&lt;/span&gt;
    
&lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;request&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; result&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;https://httpbin.org/get&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;httpGet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;responseString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; ■ Result &lt;/span&gt;  &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;operation 의 결과 (success or failure) 를 포함하고 있는 functional-style data structure&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;kotlin&quot;&gt;&lt;pre class=&quot;language-kotlin&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;handler&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Request&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Response&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Result&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;ByteArray&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; FuelError&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; Unit&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;responseString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;handler&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Request&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Response&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Result&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;String&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; FuelError&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; Unit&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;responseJson&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;handler&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Request&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Response&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Result&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Json&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; FuelError&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; Unit&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; jsonObject &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; json&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;//JSONObject&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; jsonArray &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; json&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;//JSONArray&lt;/span&gt;


&lt;span class=&quot;token keyword&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;responseObject&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;deserializer&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ResponseDeserializable&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; handler&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Request&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Response&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Result&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; FuelError&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; Unit&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; ■ 무엇이 쉽나 &lt;/span&gt;  &lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; Adding Parameters &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;URL encoded style for GET and DELETE request&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;kotlin&quot;&gt;&lt;pre class=&quot;language-kotlin&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;Fuel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;https://httpbin.org/get&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;listOf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;foo&quot;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;foo&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;bar&quot;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;bar&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;url
&lt;span class=&quot;token comment&quot;&gt;// https://httpbin.org/get?foo=foo&amp;amp;bar=bar&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Support x-www-form-urlencoded for PUT, POST and PATCH&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;kotlin&quot;&gt;&lt;pre class=&quot;language-kotlin&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;Fuel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;https://httpbin.org/post&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;listOf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;foo&quot;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;foo&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;bar&quot;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;bar&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;also&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;it&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;also&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;it&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toByteArray&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// https://httpbin.org/post&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// &quot;foo=foo&amp;amp;bar=bar&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; Adding Request Body &lt;/span&gt;
use application/json&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;kotlin&quot;&gt;&lt;pre class=&quot;language-kotlin&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;Fuel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;https://httpbin.org/post&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;jsonBody&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;{ \&quot;foo\&quot; : \&quot;bar\&quot; }&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;also&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;it&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;response&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; Adding Progress callbacks &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Request progress&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;kotlin&quot;&gt;&lt;pre class=&quot;language-kotlin&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;Fuel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/post&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;/*...*/&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;requestProgress&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; readBytes&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; totalBytes &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; progress &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; readBytes&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toFloat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; totalBytes&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toFloat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Bytes uploaded &lt;span class=&quot;token interpolation variable&quot;&gt;$readBytes&lt;/span&gt; / &lt;span class=&quot;token interpolation variable&quot;&gt;$totalBytes&lt;/span&gt; (&lt;span class=&quot;token interpolation variable&quot;&gt;$progress&lt;/span&gt; %)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;response&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Response progress&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;kotlin&quot;&gt;&lt;pre class=&quot;language-kotlin&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;Fuel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/get&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;responseProgress&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; readBytes&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; totalBytes &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; progress &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; readBytes&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toFloat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; totalBytes&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toFloat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Bytes downloaded &lt;span class=&quot;token interpolation variable&quot;&gt;$readBytes&lt;/span&gt; / &lt;span class=&quot;token interpolation variable&quot;&gt;$totalBytes&lt;/span&gt; (&lt;span class=&quot;token interpolation variable&quot;&gt;$progress&lt;/span&gt; %)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;response&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; Using multipart/form-data(UploadRequest) &lt;/span&gt;  &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;kotlin&quot;&gt;&lt;pre class=&quot;language-kotlin&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;Fuel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;upload&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/post&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;FileDataPart&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;myfile.json&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;fieldname&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; filename&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;contents.json&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;response&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

Fuel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;upload&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/post&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;FileDataPart&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;myfile.json&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;files[]&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; filename&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;contents.json&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;FileDataPart&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;myfile2.json&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;files[]&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; filename&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;contents2.json&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;FileDataPart&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;myfile3.json&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;files[]&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; filename&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;contents3.json&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;response&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; Cancle an async Request &lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;kotlin&quot;&gt;&lt;pre class=&quot;language-kotlin&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; request &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Fuel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;https://httpbin.org/get&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;interrupt&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; request &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token delimiter variable&quot;&gt;${&lt;/span&gt;request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;url&lt;span class=&quot;token delimiter variable&quot;&gt;}&lt;/span&gt;&lt;/span&gt; was interrupted and cancelled&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;response&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// if request is cancelled successfully, response callback will not be called.&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Interrupt callback (if provided) will be called instead&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cancel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// this will cancel on-going request&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; Debug Logging &lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;kotlin&quot;&gt;&lt;pre class=&quot;language-kotlin&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; request &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Fuel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;https://httpbin.org/post&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; parameters &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;listOf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;foo&quot;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;foo&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;bar&quot;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;bar&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;key&quot;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;value&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cUrlString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// curl -i -X POST -d &quot;foo=foo&amp;amp;bar=bar&amp;amp;key=value&quot; -H &quot;Accept-Encoding:compress;q=0.5, gzip;q=1.0&quot; -H &quot;Device:Android&quot; -H &quot;Content-Type:application/x-www-form-urlencoded&quot; &quot;https://httpbin.org/post&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Asynchronous API&lt;/h3&gt;
&lt;p&gt;non-blocking asynchronous request 를 보통 사용한다고 하는데 이는 무엇인가?&lt;br&gt;
먼저 Async, Sync &amp;#x26; Blocking, Non-Blocking 의 차이를 살펴보자&lt;br&gt;
작업을 요청하는 클라이언트 : A&lt;br&gt;
작업을 수행해서 결과를 return : B  &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Sync &amp;amp; Async : 작업의 주체성을 누가 갖는가 =&amp;gt; A / B
Blocking &amp;amp; Non-Blocking : 로직의 흐름 =&amp;gt; 멈춘다. / 안 멈춘다.

Sync-Blocking : A 는 B 가 완료할 때까지 계속 기다린다.
Sync-Non-Blocking : A 가 작업의 주체성을 갖고 있으며, B 가 작업을 완료할 때까지 핑퐁하면서 완료 여부를 체크한다.

Non-Blocking : B 가 A 에게
Async-Blocking : A 가 넘겨준 콜백 함수를 B 가 실행하고 완료하는 것을 기다린다.
Async-Non-Blocking : A 가 B 에게 콜백 함수를 넘겨주고 A 는 자신의 일을 계속 진행하다가 B 가 작업 완료하면 A 가 넘겨 준 콜백 함수를 수행한다.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;fuel doc&lt;/h4&gt;
&lt;p&gt;&lt;a href=&quot;https://fuel.gitbook.io/documentation/core/fuel#using-multipart-form-data-uploadrequest&quot;&gt;https://fuel.gitbook.io/documentation/core/fuel#using-multipart-form-data-uploadrequest&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;fuel github&lt;/h4&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/kittinunf/fuel&quot;&gt;https://github.com/kittinunf/fuel&lt;/a&gt;
&lt;a href=&quot;https://github.com/kittinunf/fuel/blob/master/README-legacy.md&quot;&gt;https://github.com/kittinunf/fuel/blob/master/README-legacy.md&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://medium.com/swlh/is-fuel-an-alternative-for-retrofit-f81bd4505a87&quot;&gt;https://medium.com/swlh/is-fuel-an-alternative-for-retrofit-f81bd4505a87&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;webclient vs resttemplate&lt;/h4&gt;
&lt;p&gt;&lt;a href=&quot;https://tecoble.techcourse.co.kr/post/2021-10-20-synchronous-asynchronous/&quot;&gt;https://tecoble.techcourse.co.kr/post/2021-10-20-synchronous-asynchronous/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; ■ 제목입니당 &lt;/span&gt;
&lt;span class=&quot;title__sub2&quot;&gt; ■ 서브제목입니당 &lt;/span&gt;
&lt;span class=&quot;title__sub3&quot;&gt; ■ 서브제목2입니당 &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;This is &lt;span class=&quot;text-mark__green&quot;&gt;green color text&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;This is &lt;span class=&quot;text-mark__red&quot;&gt;red color text&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;This is &lt;span class=&quot;text-mark__blue&quot;&gt;blue color text&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;안녕&lt;/h1&gt;
&lt;h2&gt;안녕&lt;/h2&gt;
&lt;h3&gt;안녕&lt;/h3&gt;
&lt;h4&gt;안녕&lt;/h4&gt;
&lt;h5&gt;안녕&lt;/h5&gt;
&lt;p&gt;이미지
&lt;img src=&quot;./001-01.PNG&quot;&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;diff&quot;&gt;&lt;pre class=&quot;language-diff&quot;&gt;&lt;code class=&quot;language-diff&quot;&gt;&lt;span class=&quot;token deleted-sign deleted&quot;&gt;&lt;span class=&quot;token prefix deleted&quot;&gt;-&lt;/span&gt; hello
&lt;/span&gt;&lt;span class=&quot;token inserted-sign inserted&quot;&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt; green
&lt;/span&gt;&lt;span class=&quot;token diff bold&quot;&gt;&lt;span class=&quot;token prefix diff&quot;&gt;!&lt;/span&gt; orange
&lt;/span&gt;# gray&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[[Github] Github Actions]]></title><link>https://ssongey.github.io/etc/posts/2022-05-20--001</link><guid isPermaLink="false">https://ssongey.github.io/etc/posts/2022-05-20--001</guid><pubDate>Fri, 20 May 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h4&gt;참고&lt;/h4&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.github.com/en/actions&quot;&gt;https://docs.github.com/en/actions&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[[K8S] ingress apiVersion 변경]]></title><link>https://ssongey.github.io/works/posts/2022-04-30--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2022-04-30--001</guid><pubDate>Sat, 30 Apr 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;ingress 리소스파일을 kubectl로 apply 할때 아래와 같은 경고 메시지가 발생하였다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; 
use networking.k8s.io/v1 Ingress&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;p&gt;ingress apiVersion 중 extensions/v1beta1 이 1.14 버전부터 deprecated 되었으니,&lt;br&gt;
&lt;span class=&quot;text-mark__green&quot;&gt;networking.k8s.io/v1&lt;/span&gt; 을 사용하라는 경고였다.&lt;/p&gt;
&lt;p&gt;쿠버네티스 버전을 확인해보니 1.21 버전으로 확인이 되었다.

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/4f9d33bd33675a50a64608617a1d1af3/d9199/30-001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 12.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAkElEQVQI152NwQqCQBRFHxSOhqNjgjgLISrSVBR1aqn//1UnZj6hxYHLu/dxRM7CSQlJckFrHRCR/zFWY29XPu7Ltm2M40gURaRpSpZlxHGMMYaiKKjrOgj9zfdKKcqyDL3/8VmG98Dj/qRtX6zLStd1NE2Dcy7gJX3fM88z+75zHAdVVQXyPA/7aZqw1gbhD1lZSiIdAeQRAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;30 001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/4f9d33bd33675a50a64608617a1d1af3/d9199/30-001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/4f9d33bd33675a50a64608617a1d1af3/8ff5a/30-001-01.png 240w,
/devHistoryBlog/static/4f9d33bd33675a50a64608617a1d1af3/e85cb/30-001-01.png 480w,
/devHistoryBlog/static/4f9d33bd33675a50a64608617a1d1af3/d9199/30-001-01.png 960w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;ingress apiVersion 변경 후에 다시 apply를 하니 serviceName, servicePort 필드를 해석할 수 없다는 오류가 발생하였다.&lt;br&gt;
확인해보니 정의하는 부분이 변경되어 아래와 같이 적용하였다.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/e66072e9a835ae24cbcf19829a297361/913b9/30-001-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 59.166666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAABYlAAAWJQFJUiTwAAACl0lEQVQoz41TS08TYRTtL2BhxdBpS+fZeTLTKUMptTUgCepGSbQtGPxdjQFaKLDDwnRKBBVUEhJ+ADsDLtixBZTw6PHOBzG6Y5KTOzM5Ofec794vgns+NzddbG34mJt9j7n5ecz/g3q9jlqthoODA0R+Hv5Asz6LemMBjUbjP4TklZUVXF1d4abbxeuXLyBwD8HzPJLJ5F+E3z09PYwfaX1YhcRFoUg8+vv7Cbek8D0Wi8GyLJyfnTGX09NvYWsSTF2FJCtIp9MMmq4jlUqx5hG/HcDU0vBsg5EUIqiqyiDLMkqlEs7uBKuVCgwlhWFbwYCugIsnkIjHWfPe3l4sLy+ToO9DlUUiqcgNpCGKIuJECl2GDnO5HC4vL5ngVLWMx7aIrG1CEgUWNYQkSYhGo1hcXERk3W/D1QQ8GbKQVmSIAhHJvkCV4zgUCgXs7e1hf38fMzPvGNd1LEpDcdUQKovcR82bzWYo6ENTRBQ9IqUppkKxiRQSeYGc5/M4OTnB6ekpKtUpOAqP556BPLl0TYKhUTILMp390m3kNmRJxPigibGsgSwNIWsY8CwTGU3F6EgeFxcXLPKbchkqOS+6BsaHdAy5Djwvh0HHhpKIo7lEgkEQQNc0jLgZPBuzMVp0iZihWDYMXcNEqYjf5+dMsExD0ensRlwLE8PkjKplO8jYNuRkAs3QYau1hmScg0UT9UwJTx0eo44IjSI/osmFjX7dCVaqVeJJsAdsFAYtJphMCbAokcqnbiMfHx8jnPRWJ8B2p41vdBt2Oj6+bn7EF/q3Q/X6+hpdWuxXk5MQY320FTIbTt7godKZm7RqiegD1BcWELnv1QsFv+/uor3Wwqe2j01/HTvBGrY3OvgctOGvruLw6Ah/AJkAIFbKUZcyAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;30 001 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/e66072e9a835ae24cbcf19829a297361/d9199/30-001-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/e66072e9a835ae24cbcf19829a297361/8ff5a/30-001-02.png 240w,
/devHistoryBlog/static/e66072e9a835ae24cbcf19829a297361/e85cb/30-001-02.png 480w,
/devHistoryBlog/static/e66072e9a835ae24cbcf19829a297361/d9199/30-001-02.png 960w,
/devHistoryBlog/static/e66072e9a835ae24cbcf19829a297361/07a9c/30-001-02.png 1440w,
/devHistoryBlog/static/e66072e9a835ae24cbcf19829a297361/913b9/30-001-02.png 1822w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;</content:encoded></item><item><title><![CDATA[[Shell] 자주 사용하는 문법]]></title><link>https://ssongey.github.io/history/posts/2022-04-30--001</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2022-04-30--001</guid><pubDate>Sat, 30 Apr 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; ■ 자주 사용하는 문법 정리 &lt;/span&gt;
&lt;span class=&quot;title__sub2&quot;&gt; 1. null 체크 &lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; -z &lt;span class=&quot;token variable&quot;&gt;$1&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt;
        &lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;null input&quot;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;fi&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[[Shell] /dev/null로 출력 버리기]]></title><link>https://ssongey.github.io/hisoty/posts/2022-04-29--001</link><guid isPermaLink="false">https://ssongey.github.io/hisoty/posts/2022-04-29--001</guid><pubDate>Fri, 29 Apr 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;/dev/null 에 전송된 데이터는 버려지므로 출력이 불필요한 경우는 /dev/null에 출력을 지정하는게 좋다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# 표준 출력만 무시&lt;/span&gt;
$ script.sh &lt;span class=&quot;token operator&quot;&gt;&lt;span class=&quot;token file-descriptor important&quot;&gt;1&lt;/span&gt;&gt;&lt;/span&gt; /dev/null

&lt;span class=&quot;token comment&quot;&gt;# 표준 오류 출력만 무시&lt;/span&gt;
$ script.sh &lt;span class=&quot;token operator&quot;&gt;&lt;span class=&quot;token file-descriptor important&quot;&gt;2&lt;/span&gt;&gt;&lt;/span&gt; /dev/null

&lt;span class=&quot;token comment&quot;&gt;# 표준 출력, 오류 모두 무시&lt;/span&gt;
$ script.sh &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; /dev/null &lt;span class=&quot;token operator&quot;&gt;&lt;span class=&quot;token file-descriptor important&quot;&gt;2&lt;/span&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token file-descriptor important&quot;&gt;&amp;amp;1&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 표준 출력, 오류 각각 다른 파일로 저장&lt;/span&gt;
$ script.sh &lt;span class=&quot;token operator&quot;&gt;&lt;span class=&quot;token file-descriptor important&quot;&gt;2&lt;/span&gt;&gt;&lt;/span&gt; fail.log &lt;span class=&quot;token operator&quot;&gt;&lt;span class=&quot;token file-descriptor important&quot;&gt;1&lt;/span&gt;&gt;&lt;/span&gt; success.log&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&quot;title__sub3&quot;&gt;■ 파일 설명자&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;0 : 표준 입력&lt;/li&gt;
&lt;li&gt;1 : 표준 출력&lt;/li&gt;
&lt;li&gt;2 : 표준 오류 출력&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[[Docker] 이미지 삭제시 conflict 오류 발생]]></title><description><![CDATA[dependent child images로 인한 오류]]></description><link>https://ssongey.github.io/errors/posts/2022-04-29--001</link><guid isPermaLink="false">https://ssongey.github.io/errors/posts/2022-04-29--001</guid><pubDate>Fri, 29 Apr 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; ■ 문제 &lt;/span&gt;&lt;br&gt;
docker 이미지 삭제시에 아래와 같은 오류 발생&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ docker rmi {image id}
Error response from daemon: conflict: unable to delete {image id} (cannot be forced)
- image has dependent clid images&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; ■ 원인 &lt;/span&gt;&lt;br&gt;
image id 를 특정하게 되면 보이지 않은 많은 여러 태그들 또한 같이 선택이 되기 때문&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; ■  해결 &lt;/span&gt;&lt;br&gt;
image-name:tag 로 특정 이미지만 삭제하도록 한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;$ docker rmi &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;image-name&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;:&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;tag&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[[Spring] application.yml 정리]]></title><link>https://ssongey.github.io/spring/posts/2022-04-28--001</link><guid isPermaLink="false">https://ssongey.github.io/spring/posts/2022-04-28--001</guid><pubDate>Thu, 28 Apr 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; ■ JPA 관련 필드 &lt;/span&gt;  &lt;/p&gt;
&lt;h4&gt;■ spring.jpa.&lt;span class=&quot;text-mark__blue&quot;&gt;database-platform&lt;/span&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;JPA 데이터베이스 플랫폼 지정&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;■ spring.jpa.&lt;span class=&quot;text-mark__blue&quot;&gt;open-in-view &lt;/span&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;OSIV(Open Session In View)는 웹 요청이 완료될 때까지 동일한 EntityManager를 갖도록 해줍니다.&lt;/li&gt;
&lt;li&gt;스프링부트에서 OSIV가 기본값으로 true인데, 성능과 확장상 면에서 안좋다고 해서 false로 설정을 껏습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;■ spring.jpa.&lt;span class=&quot;text-mark__blue&quot;&gt;show-sql&lt;/span&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;콘솔에 JPA 실행 쿼리를 출력합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;■ spring.jpa.hibernate.&lt;span class=&quot;text-mark__blue&quot;&gt;format_sql&lt;/span&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;콘솔에 출력되는 JPA 실행 쿼리를 가독성있게 표현합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;■ spring.jpa.hibernate.&lt;span class=&quot;text-mark__blue&quot;&gt;ddl_auto&lt;/span&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;데이터베이스 초기화 전략을 설정&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;none&lt;/td&gt;
&lt;td&gt;아무것도 실행하지 않음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;create&lt;/td&gt;
&lt;td&gt;SessionFactory가 시작될 때 기존테이블을 삭제 후 다시 생성&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;create-drop&lt;/td&gt;
&lt;td&gt;create와 같으나 SessionFactory가 종료될 때 drop을 실행&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;update&lt;/td&gt;
&lt;td&gt;변경된 스키마만 반영(제거는 하지 않음)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;validate&lt;/td&gt;
&lt;td&gt;엔티티와 테이블이 정상적으로 매핑되었는지만 확인(다르면 예외 발생)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; ■ DB 관련 필드 &lt;/span&gt;  &lt;/p&gt;
&lt;h4&gt;■ logging.level.org.hibernate.type.descriptor.sql&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;SQL에서 물음표로 표기된 부분( bind parameter )을 로그로 출력해서 확인할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;■ spring.datasource.initialization-mode&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;alwasy로 설정해야 외장 DB 초기화 가능&lt;/li&gt;
&lt;li&gt;설정하지 않으면 기본으로 never로 설정: Embedded DB 사용 -&gt; ex. HSQL, H2, Derby&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;■ spring.datasource.data&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;sql 파일 경로를 지정하면 지정된 파일의 스크립트를 실행&lt;/li&gt;
&lt;li&gt;ex. spring.datasource.data=classpath:member.sql, book.sql&lt;/li&gt;
&lt;li&gt;기본값은 classpath:schema.sql, classpath:data.sql&lt;/li&gt;
&lt;li&gt;DB 종류에 따라 다른 스크립트를 사용하려면 spring.datasource.platform을 해당 DB종류(ex. mysql, posgresql)로 설정하고 schema-mysql.sql, data-mysql.sql과 같이 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; ■ 예제 &lt;/span&gt;
&lt;span class=&quot;title__sub2&quot;&gt; ■ mysql 기준 &lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;server&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;shutdown&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; graceful

&lt;span class=&quot;token key atrule&quot;&gt;spring&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;banner-mode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; off
  &lt;span class=&quot;token key atrule&quot;&gt;datasource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; jdbc&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;mysql&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;//&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;host&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;port&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;/&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;db&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;?&lt;/span&gt;useSSL=false&lt;span class=&quot;token important&quot;&gt;&amp;amp;authcommit=false&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;username&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;uername&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;password&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;password&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;driver-class-name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; com.mysql.cj.jdbc.Driver
  &lt;span class=&quot;token key atrule&quot;&gt;jpa&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;database-platform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; org.hibernate.dialect.MySQL5InnoDBDialect
    &lt;span class=&quot;token key atrule&quot;&gt;database&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; mysql
    &lt;span class=&quot;token key atrule&quot;&gt;open-in-view&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;false&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;show-sql&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;false&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;hibernate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;ddl-auto&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; none
    &lt;span class=&quot;token key atrule&quot;&gt;properties&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;hibernate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;format_sql&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;host&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;port&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;database&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;

&lt;span class=&quot;token key atrule&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;level&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; DEBUG&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; ■ h2 기준 &lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;spring&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;h2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;enabled&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; /test
  &lt;span class=&quot;token key atrule&quot;&gt;datasource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;jdbc-url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; jdbc&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;h2&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;mem&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;default
    &lt;span class=&quot;token key atrule&quot;&gt;driver-class-name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; org.h2.Driver
    &lt;span class=&quot;token key atrule&quot;&gt;username&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; sa
    &lt;span class=&quot;token key atrule&quot;&gt;password&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; sa
  &lt;span class=&quot;token key atrule&quot;&gt;jpa&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;database-platform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; org.hibernate.dialect.H2Dialect
    &lt;span class=&quot;token key atrule&quot;&gt;database&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; h2
    &lt;span class=&quot;token key atrule&quot;&gt;hibernate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;ddl-auto&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; create&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;drop
    &lt;span class=&quot;token key atrule&quot;&gt;generate-ddl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;defer-datasource-initialization&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[[K8S] 컨트롤러]]></title><description><![CDATA[대세는 쿠버네티스]]></description><link>https://ssongey.github.io/history/posts/2022-04-10--001</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2022-04-10--001</guid><pubDate>Sun, 10 Apr 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; 1. Controller &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;서비스를 관리하고 운영하는데 도움을 준다.&lt;/li&gt;
&lt;li&gt;아래 기능들을 제공한다.

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/4beec172275f8b72b7b840cad4ffc261/4b7ac/10-001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 51.25000000000001%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABYlAAAWJQFJUiTwAAACJ0lEQVQozz2SCU/bQBCF/f//QKX+BVQVgdSIqqgtIlVogXCkCJPLieM4cXyu7ytfJ4Ziabyr3dk3770ZTaUuSebje2P83ZwyVdRVRVWWEjl1LfuqJk49VLohzQOixKaoUvYgdyWN5DdNS9Pu0WSllZ8a/8Hsf5Z1QLHVKYIVVabkQSWgNUmuCOKIUAqmUYD/1McefqNwDZRE7K+J3DVaXbeUWUbm2rQHNp4lSSvKJKSWQlVXvWa5GzG27xhv7tjtTGJrjDKfySILw75lub5mZvTRpn8H6KMfWMLKcV2M5Q3GeoQf+iK9fgdc7B55tm55sYdsLZ1W7DhITbwZM3PAYnXFZPIT7eLLEWdfj7h9uGI2nfC93+P84pTFct758iq5YuWPMNwH5rshKnZo8liUpSSyXzo3mM5QmP5GiwKPMAzE8Jji4FVaEKuUoig67w6Ah8jLhEKiqsu385qylLuuaVl3XjUVWlYp8iIk2j4R2SIlCdiLxFY69r8hh8iLhDQLX8+ahvDlF8vLI9RkQCVvuqmQIhpvXzi+xhycEi2GhIkjTCMBat5Bu7GQOIDVaUDjzqlzGStnRpNJbtt046a9TPvo9+fEGx2hiLW5Z/B8zHx9z77lTXJJnEQEQYDnKjxnzPXjCTP7CS/Q2VgjHCckTVM0x5/j7KZkSoxWLhsZj+GshykWtG+AZVkQRh6GqfOp94GNu6Q/POHyqieMpWHbKcdnHzFWOv8A2jru44tAPy4AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;10 001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/4beec172275f8b72b7b840cad4ffc261/d9199/10-001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/4beec172275f8b72b7b840cad4ffc261/8ff5a/10-001-01.png 240w,
/devHistoryBlog/static/4beec172275f8b72b7b840cad4ffc261/e85cb/10-001-01.png 480w,
/devHistoryBlog/static/4beec172275f8b72b7b840cad4ffc261/d9199/10-001-01.png 960w,
/devHistoryBlog/static/4beec172275f8b72b7b840cad4ffc261/07a9c/10-001-01.png 1440w,
/devHistoryBlog/static/4beec172275f8b72b7b840cad4ffc261/29114/10-001-01.png 1920w,
/devHistoryBlog/static/4beec172275f8b72b7b840cad4ffc261/4b7ac/10-001-01.png 3444w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; 1.1 Auto Healing &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;파드에 문제가 생기거나 또는 파드를 스케줄링하는 노드가 다운이 될 경우 컨트롤러가 인지하여 새로운 노드에 파드를 재생성&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;종류: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ReplicationController&lt;/li&gt;
&lt;li&gt;ReplicaSet&lt;/li&gt;
&lt;li&gt;StatusfulSet&lt;/li&gt;
&lt;li&gt;DaemonSet&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; 1.2 Auto Scaling &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;파드의 리소스 상태가 limited 되었을 경우 컨트롤러가 인지하여 자동으로 파드를 한개 더 생성&lt;/li&gt;
&lt;li&gt;부하분산 및 파드가 죽지 않도록 함&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;종류: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;HPA&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; 1.3 Software Update &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;여러 파드에 대한 업그레이드를 지원한다.&lt;/li&gt;
&lt;li&gt;업그레이드 도중 문제 발생시에 롤백도 지원한다.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;종류:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Deployment&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; 1.4 Job &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;일시적인 작업이 필요할 경우 파드를 생성하여 작업을 수행하고, 완료 후에는 자원을 반납한다.&lt;/li&gt;
&lt;li&gt;효율적인 자원 사용이 가능&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;종류:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CronJob&lt;/li&gt;
&lt;li&gt;Job&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; 2. Replication Controller/ ReplicaSet &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Replication Controller는 deprecated 되었고, 대체로 ReplicaSet을 사용한다.&lt;/li&gt;
&lt;li&gt;둘다 template, replicas 기능을 가지고 있다.&lt;/li&gt;
&lt;li&gt;ReplicaSet에는 selector 기능이 추가되었다.&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; 2.1. Template  &lt;/span&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/018ce6a8d275e1367934ed65ffb5107a/60b6a/10-001-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 30.41666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAAAsTAAALEwEAmpwYAAABW0lEQVQY02WQS2vbQBRG8/93he67K6V0VyjULRRS0pSkKcapHXv0tKRoJLmeeCSNHpadk7FassmFDwbucPjOPWtNxWGnUGliE9E/bDCmxHQVXdfhuT5ZltP3PWG45naxYp1ItmpHGOd4fkhZ6nF/+n+mc5+b81f8/voa8f0t8fQjUs5wkx+0bc3cXRImkX23iOUS13HYbreYuiawwCQtRtBpPwKNVvxZfCK4myDFFbF3w76qGGrDvt/j+A7+OqCuaqLAs41X1sDQ2MhCsXBiC2tG2AjcVBHX1x8oSp/p6jOB/IVIL5n6X+j2htzqCiFQSpEXOXMxR2tN2zT8VZqlE9E0xsL+K683t3xbvcHJfnLpvWeWTJjFEy7cd1TmgcNwZBiGMXlRWOAdMpNUZYkua9wgHU9wUm5bC+TIv3nkxRyPj8+w4TCMqpnMSFNJeWppG7mhRLgh97Jgpw1PJt6+dQHQ+KYAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;10 001 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/018ce6a8d275e1367934ed65ffb5107a/d9199/10-001-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/018ce6a8d275e1367934ed65ffb5107a/8ff5a/10-001-02.png 240w,
/devHistoryBlog/static/018ce6a8d275e1367934ed65ffb5107a/e85cb/10-001-02.png 480w,
/devHistoryBlog/static/018ce6a8d275e1367934ed65ffb5107a/d9199/10-001-02.png 960w,
/devHistoryBlog/static/018ce6a8d275e1367934ed65ffb5107a/07a9c/10-001-02.png 1440w,
/devHistoryBlog/static/018ce6a8d275e1367934ed65ffb5107a/60b6a/10-001-02.png 1559w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;컨트롤러와 파드는 label과 selector로 연결이 된다. (서비스와 동일)&lt;/li&gt;
&lt;li&gt;컨트롤러를 만들때 template에 파드 내용을 저장하고, 컨트롤러에서 파드를 재생성 할 경우 해당 template 내용을 참고한다.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;파드의 버전을 업데이트 하는 방법&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;먼저 template의 파드 내용을 업데이트 한 후, &lt;/li&gt;
&lt;li&gt;기존에 연결되어 있는 파드를 다운&lt;/li&gt;
&lt;li&gt;업데이트된 template로 파드 재생성 &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; 2.2. Replicas  &lt;/span&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/b45a6f1ef35221375a6e481be3c6b5e4/a8a6f/10-001-03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 42.083333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB20lEQVQoz0WRW0/bQBCF8+f71se+96WiQipIvQBFUKhUFBAJEBJydRKMEzuO43W8tteO44SvGxepK420O6M5+s7ZipIC6VkE7gvLuUUiHLJUkYYeKrB170XPTOLAKd+ZitlstxiDAdWbGo/tASPTpj+y8BaCinLH2LUT6kefeTo/IOxVWSURidVicX9GS/ceT/ax/nxHNn+hlh7bVzAMg/uHBsPhCMuasAwlcRxTkeMG0fUe5sF7ZscfkLVD0lginy4Y7b1DXHxk3vtG5+GQcX1fO5iyBazhELPTRXgLwiBAKUWSJFTCaR//4ZjJ70+4118QzXNWaUI4usOu7iPuj5j0zmg3vmLoexL+I5xPJ7Sbt8yDOWmalnSlYJ4X5Otci8SkkdALC/JMlRSLkckqW7PdwDrR2a3WFMVWV4HvedxeXWH0B0TRTuxNMIxdZOIgoynhrsJn0lXEptjgNB6JhU+UzvTcRsoXVBZSrAtivdx2DMYz/ZnhshQrM+w5l3Rmp/Rcbcv+Scf9gbvsl1S7k28yOvYphnfJk32EHbR51fi+79Md9JjMbS0el7Z3OVaEdAii/+XLCbFastYUea6jWGVvsxlCO4hUUBLulrv6U+7qd7SaLZ5NEyEEfwGA7UylVoXXFAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;10 001 03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/b45a6f1ef35221375a6e481be3c6b5e4/d9199/10-001-03.png&quot;
        srcset=&quot;/devHistoryBlog/static/b45a6f1ef35221375a6e481be3c6b5e4/8ff5a/10-001-03.png 240w,
/devHistoryBlog/static/b45a6f1ef35221375a6e481be3c6b5e4/e85cb/10-001-03.png 480w,
/devHistoryBlog/static/b45a6f1ef35221375a6e481be3c6b5e4/d9199/10-001-03.png 960w,
/devHistoryBlog/static/b45a6f1ef35221375a6e481be3c6b5e4/07a9c/10-001-03.png 1440w,
/devHistoryBlog/static/b45a6f1ef35221375a6e481be3c6b5e4/a8a6f/10-001-03.png 1516w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;replicas 만큼 파드가 관리된다.&lt;/li&gt;
&lt;li&gt;pod를 따로 정의하지 않고 ReplicationController만 정의하게 되면, 정의된 template 내용으로 replica 개수 만큼 파드를 자동 생성해준다&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; 2.3. Selector &lt;/span&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/450d1802d2298971102c7b3008591fda/b67f3/10-001-04.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 29.583333333333332%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABYlAAAWJQFJUiTwAAABLElEQVQY04WOXUvCYBiG/b+ddRYRdFD/oLMgooOEEDGJ6iBGJRt+t5Zm+TFN1OnC9J2bbn5dTS2CSLrhOnhuuC+eAH7m8/mSRTyjQF45JX17jPkiMWoV8cpxpnqKRuKa0t05zqvMpBLHfVOZTqd8OxYJ/Ahny2JQjXEZ3yQob/CoHeBVVLxshMlDFDsRQihnqzsbxn2W/hf2dQUptcdFegdNPcTVNZxUmGEm6hNZMsr68mQIOycx+xL9IVwV44mL3TcxayUc0cFyTFqdEs1OGWvUxXEFrXadD6uDO3ZYzebrP+x5TaLVfU4yW8SMIwq9K0JPuwTVbbRuhO5QJ1u8ofKexHKNhWuhW/+h7fUoi3uqQqYuMrREjppQ0C2ZhqVhDPLUB0mfBGLU5vf+E9pJu7lUhBsPAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;10 001 04&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/450d1802d2298971102c7b3008591fda/d9199/10-001-04.png&quot;
        srcset=&quot;/devHistoryBlog/static/450d1802d2298971102c7b3008591fda/8ff5a/10-001-04.png 240w,
/devHistoryBlog/static/450d1802d2298971102c7b3008591fda/e85cb/10-001-04.png 480w,
/devHistoryBlog/static/450d1802d2298971102c7b3008591fda/d9199/10-001-04.png 960w,
/devHistoryBlog/static/450d1802d2298971102c7b3008591fda/b67f3/10-001-04.png 1338w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Replication Controller의 경우 label 이 동일할 경우만 연결이 된다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;label의 key와 value 중 하나라도 값이 다를 경우 연결하지 않는다&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ReplicaSet의 경우 matchLabels 와 matchExpressions 을 제공한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub3&quot;&gt; 2.3.1 Match Labels &lt;/span&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/2d8b90afea081a137fcadeb70e3cc3a5/47218/10-001-05.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 29.583333333333332%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABYlAAAWJQFJUiTwAAABOElEQVQY04WOy0sCARCH/T87dO9W0KFTt0CILkWHhOhx8KCQIRIKPTRZynZ9v9FUdFcrwsdu666r+7UqEQTSD4ZhPmY+xoUT27YXNY/ZK5IWTondH9MphjCUKq20n3LiklLUSz16jVaKYdUExg2J6dTixzGP61c4WwC1GedK2MATXec55cZspAjFNvFE1hBje+iCn/GLD0v0YeQj/wtHLYl4+oDbwj753DnjZpGn7CHhvJuqdIIpBTGyN+hSAK3wwGw2WyVcgsnUZDjsIr+WnC4z1BV6coVOLYM6ktHMAc1OnQ9nx7B05mc29uoPB6ZCoLHLWXKLO+WIfD+It7jDRW4b8dPLu15GqoepvD3SN9pz2yrhEuiTIa1RgvaXiKxm6Kll2qpIWxNR1IIzl+hoSYdJDMZd/t5/A2mzt/IPVOX1AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;10 001 05&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/2d8b90afea081a137fcadeb70e3cc3a5/d9199/10-001-05.png&quot;
        srcset=&quot;/devHistoryBlog/static/2d8b90afea081a137fcadeb70e3cc3a5/8ff5a/10-001-05.png 240w,
/devHistoryBlog/static/2d8b90afea081a137fcadeb70e3cc3a5/e85cb/10-001-05.png 480w,
/devHistoryBlog/static/2d8b90afea081a137fcadeb70e3cc3a5/d9199/10-001-05.png 960w,
/devHistoryBlog/static/2d8b90afea081a137fcadeb70e3cc3a5/47218/10-001-05.png 1344w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Replication Controller 의 selector 와 같이 label이 동일할 경우 연결을 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub3&quot;&gt; 2.3.2 Match Expressions &lt;/span&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/6b49105750db439606fd497427ef893e/913a1/10-001-08.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 33.75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAABYlAAAWJQFJUiTwAAABxklEQVQozx2RS2/aUBBG+a2VsuuP6KLddFOpuy6qLqooUtNnWpGkAqoSIAmv2DwMmJhrGxNjsLF5Yx46vWWkM4tZzOh8k/AtC9+0iKcB22XEIZpIQoZCZ2x22IXuke08gN2auakiqmn28zH/a2UpiPtfbGY+spF4LP+hW8owtZssPEGklwj1Ms2bK7TsJZNOWc7KLL0e7GNmnQKdwgW7aHhcuDaKdLKfWUbywHZJ4jz/nI/ZE5rqewL9hrP0CafpZ9zenfIt+ZvL9DWFuzSeaOBP+jTMInVRQnfbjGYuWl+RPNCwVNbzIYlG6weq9pVBN09ka9Tr5yi1M3TlGrWSR29V6DaLRK5gNh9hBya218GNHKJVSD8Q2AMVZ2ITL0Yk3LDNo1UkXFmEmz6GU8YaVlnEHttdgGnVWe9DYqnDfstCy/GQTbKcTY/Kh0GLWuoTnvsEsczwQ+E1b69ekTe/c29f8ObnC95lXqJ5f6VGmy+pJNVeldU6YLUMETLDSiWFM7LYHLY4vTKqkqHrGBxWAQnHHzAIhoynI/yphzN2JQMmUs8JbIR8lDUWHORDnlyNSi9HTeRoiALOsEHVyFK3b1GMPAvf4B9atfRvSW3DHQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;10 001 08&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/6b49105750db439606fd497427ef893e/d9199/10-001-08.png&quot;
        srcset=&quot;/devHistoryBlog/static/6b49105750db439606fd497427ef893e/8ff5a/10-001-08.png 240w,
/devHistoryBlog/static/6b49105750db439606fd497427ef893e/e85cb/10-001-08.png 480w,
/devHistoryBlog/static/6b49105750db439606fd497427ef893e/d9199/10-001-08.png 960w,
/devHistoryBlog/static/6b49105750db439606fd497427ef893e/07a9c/10-001-08.png 1440w,
/devHistoryBlog/static/6b49105750db439606fd497427ef893e/913a1/10-001-08.png 1476w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;label의 key와 value를 좀 더 상세하게 컨트롤할 수 있다.&lt;/li&gt;
&lt;li&gt;operator에는 Exists, DoesNotExist, In, NotIn 이 존재한다.&lt;/li&gt;
&lt;li&gt;잘 사용하지 않는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; 2.4. ReplicationController에서 ReplicaSet으로 변경방법 &lt;/span&gt;  &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;아래 명령어로 연결된 pod는 지우지 않고 ReplicationController만 삭제&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;$ kubectl delete replicationcontrollers replication1 --cascade&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;false&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;pod가 지워지지 않았는지 확인&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ReplicaSet 생성&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; apps/v1
&lt;span class=&quot;token key atrule&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; ReplicaSet
&lt;span class=&quot;token key atrule&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; replica2
&lt;span class=&quot;token key atrule&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;replicas&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;selector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;matchLabels&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;cascade&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;false&quot;&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;cascade&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;false&quot;&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;#아래 스펙내용은 기존 ReplicationController 와 동일하게&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;containers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; container
    &lt;span class=&quot;token key atrule&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; kubetm/app&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;v1&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; 2.5. ReplicaSet 샘플 &lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; apps/v1
&lt;span class=&quot;token key atrule&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; ReplicaSet
&lt;span class=&quot;token key atrule&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; replica1
&lt;span class=&quot;token key atrule&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;replicas&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;#파드개수를 replicas 만큼 유지를 시킨다.&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;selector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;matchLabels&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; web &lt;span class=&quot;token comment&quot;&gt;#동일한 라벨링 된 파드와 연결이 된다.&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;ver&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; v1 &lt;span class=&quot;token comment&quot;&gt;#만약 template 아래 labels에 존재하지 않는 라벨을 사용할 경우 에러 발생(ex. ver: v3)&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; pod1 &lt;span class=&quot;token comment&quot;&gt;#ReplicaSet이 해당 템플릿으로 Pod를 생성하면 &quot;pod1&quot;로 파드명이 만들어지지 않고 임의의 파드명으로 생성된다.&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; web
        &lt;span class=&quot;token key atrule&quot;&gt;ver&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; v1
        &lt;span class=&quot;token key atrule&quot;&gt;ver&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; v2
    &lt;span class=&quot;token key atrule&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;containers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; container
        &lt;span class=&quot;token key atrule&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; kubetm/app&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;v1
      &lt;span class=&quot;token key atrule&quot;&gt;terminationGracePeriodSeconds&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; apps/v1
&lt;span class=&quot;token key atrule&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; ReplicaSet
&lt;span class=&quot;token key atrule&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; replica1
&lt;span class=&quot;token key atrule&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;replicas&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;selector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 
    &lt;span class=&quot;token comment&quot;&gt;#matchLabels, matchExpressions 두 조건 모두 들어갈 수 있다. or 조건이다. (matchLabels or matchExpressions)&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;#template 아래 labels에 존재하는 라벨만 사용가능&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;matchLabels&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 
      &lt;span class=&quot;token key atrule&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; web
      &lt;span class=&quot;token key atrule&quot;&gt;ver&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; v1
    &lt;span class=&quot;token key atrule&quot;&gt;matchExpressions&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token key atrule&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; type&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;operator&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; In&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;web&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token key atrule&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; ver&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;operator&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Exists&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; web
        &lt;span class=&quot;token key atrule&quot;&gt;ver&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; v1
        &lt;span class=&quot;token key atrule&quot;&gt;location&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; dev
    &lt;span class=&quot;token key atrule&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;containers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; container
        &lt;span class=&quot;token key atrule&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; kubetm/app&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;v1
      &lt;span class=&quot;token key atrule&quot;&gt;terminationGracePeriodSeconds&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; 3. Deployment  &lt;/span&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/88ce1a0d4ee56f6bb0c5891141343292/dd507/10-001-13.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 35.833333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAABYlAAAWJQFJUiTwAAABKElEQVQoz42RyU4CQRRF+WY/woV7Fy7ElXFIcEhciBqJsECZRQW7QRRIoBtikKHpqaqP1QiGuGkrqdykct/JfbdiLE8QBAuVUiCEiysklmtju3OmrkfeGJGqv/Fkjpl7PoGUyieUX/7Ohhr7C/QVbDDT0cwq3YmOMW1S6z9S7FVoD3uMZg6e7y9AITC8kcBC54Sz+y0q7QSvZpLT7CYZLY7jfy48K1AIjUwo7Qmj9zRG85pO8ZxBOcmsm8PqFhCei1S+ddi/gNXnA5L5Heq5Pcxsgkbjjo9aCmv8hav6WyWM6PBHwwTI5ZsAp9XG1TSMfImXm1v6hRK23sDSdJXYi04YBGHZPr5UP+kLyqld9o83KF9uMzyM07tK8JA5opW+UNs4CDW3DvwG5PgT1lJVnHUAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;10 001 13&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/88ce1a0d4ee56f6bb0c5891141343292/d9199/10-001-13.png&quot;
        srcset=&quot;/devHistoryBlog/static/88ce1a0d4ee56f6bb0c5891141343292/8ff5a/10-001-13.png 240w,
/devHistoryBlog/static/88ce1a0d4ee56f6bb0c5891141343292/e85cb/10-001-13.png 480w,
/devHistoryBlog/static/88ce1a0d4ee56f6bb0c5891141343292/d9199/10-001-13.png 960w,
/devHistoryBlog/static/88ce1a0d4ee56f6bb0c5891141343292/07a9c/10-001-13.png 1440w,
/devHistoryBlog/static/88ce1a0d4ee56f6bb0c5891141343292/dd507/10-001-13.png 1528w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ReplicaSet 기능을 포함하며 배포/ 버전업데이트에 도움이 되는 컨트롤러&lt;/li&gt;
&lt;li&gt;Deployment에 RelicaSet에 대한 정보를 같이 기입한다&lt;/li&gt;
&lt;li&gt;Deployment를 적용하면 ReplicaSet을 생성 하게되고, 이 ReplicaSet이 replica 개수만큼 파드를 만들게 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; 3.1. ReCreate &lt;/span&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/a9c5774d39e119310a50a21a4795dfa4/88820/10-001-09.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 37.083333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAABYlAAAWJQFJUiTwAAABe0lEQVQoz32RW2/TQBCF/f//AA888gBvSAghgZCKqKCNErXQKiW0zmJix44dO7aT+La79tfBEZcnRppZHe3umXNmnPaY0x0ydH2k6zraqjzhphLcCi7ojjs6wVprhmH4bzpNnpItb9jeT9FCYO1AspiRulcjgek08d0lubqht/2fj/xKCUFjPSU4SeGRH+KRSBtDmiiK/V8cr+fsy4RyH5DmHr9jpJAG//KNCt1owiZ3pTsYKd7yM9tM0ctbbTTKPacoI6LCxd/O0UNPddihbq+Y/PT4lmXUtqEyFY1pcGxvRI0Re2acoTadYIsRdW3bYqwe762cwoWKLzifPOXD2RNUdsncf8e1+5Lp9+ess1uxvAsoZQlW5BshzcsYP/REVYk1VmyGhFFAFPscZYHhesZ8+ozwyxuKYIFavEfNXrBZvCVLXRwVfCXJVmJ5EFU9QfyAHy2p60awZRXdEacRwWbJJj3NsKpqri9e8ePja9afzkge5jLjFft6xyP85hGoi2OtDgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;10 001 09&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/a9c5774d39e119310a50a21a4795dfa4/d9199/10-001-09.png&quot;
        srcset=&quot;/devHistoryBlog/static/a9c5774d39e119310a50a21a4795dfa4/8ff5a/10-001-09.png 240w,
/devHistoryBlog/static/a9c5774d39e119310a50a21a4795dfa4/e85cb/10-001-09.png 480w,
/devHistoryBlog/static/a9c5774d39e119310a50a21a4795dfa4/d9199/10-001-09.png 960w,
/devHistoryBlog/static/a9c5774d39e119310a50a21a4795dfa4/07a9c/10-001-09.png 1440w,
/devHistoryBlog/static/a9c5774d39e119310a50a21a4795dfa4/29114/10-001-09.png 1920w,
/devHistoryBlog/static/a9c5774d39e119310a50a21a4795dfa4/88820/10-001-09.png 2564w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;v1의 파드를 모두 삭제시킨 후 v2의 파드를 실행&lt;/li&gt;
&lt;li&gt;다운타임이 발생&lt;/li&gt;
&lt;li&gt;별도의 자원 사용량이 필요없음&lt;/li&gt;
&lt;li&gt;상세플로우&lt;br&gt;
1.기존 ReplicaSet의 replica를 0으로 변경&lt;br&gt;
2.기존 파드 삭제&lt;br&gt;
3.(다운타임 발생)&lt;br&gt;
4.새 ReplicaSet 생성&lt;br&gt;
5.파드생성&lt;br&gt;
6.서비스와 연결됨  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Recreate Deployment 리소스파일&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; apps/v1
&lt;span class=&quot;token key atrule&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Deployment
&lt;span class=&quot;token key atrule&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; deployment&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;selector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;matchLabels&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; app
  &lt;span class=&quot;token key atrule&quot;&gt;replicas&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;strategy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Recreate &lt;span class=&quot;token comment&quot;&gt;#type 설정&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;revisionHistoryLimit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;#삭제하지 않고 유지 할 ReplicaSet 개수, 기본값은 10&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; app
    &lt;span class=&quot;token key atrule&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;containers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; container
        &lt;span class=&quot;token key atrule&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; kubetm/app&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;v1
      &lt;span class=&quot;token key atrule&quot;&gt;terminationGracePeriodSeconds&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; 3.2. Rolling Update &lt;/span&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/c5fb1ce173e6af2c3783796df774e4a8/1439b/10-001-10.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 39.166666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABYlAAAWJQFJUiTwAAABlUlEQVQoz12Q2W7bMBBF9f8f1Lc+FAXaAEFdx/USL3JkazNFWYtN7ZJPSaYtgg4wAA/v8PKSTlPVqDyjKgv6rqepGlSR672crussG+2uZ7qupakNl+/cGm4/cIMz9h3Z25LCf2UYekbd+XlD7q2YDI8jRbCzM2PXME4PyvDA1X1haGvGB9zjI+lhzthWOMZVSZ8mu2izgb7vUReXKt5RN8qmVvHhD9+1PqCiLVX4SqsNe32mEkeUv6JttKGXzMhrgSmT5pwuuJYedSWI8j1B+BMpt3o4JSr2hPELl+AH7T3AlTMCf0Z4fqavInbxE86l2KKajMdkDAeEPlTWCZN+2qQvSG4uRaXTT5PV5c0jv/nUSiC0JqX+juuRrrkSZRscG+3xnm7Q8c36b/3Pdv2Bx2H6xyaQKecUrSlVaoWHThWIHcvDV86XjR0Ikz2r4zfbodgj84DF/guuP7d6mkfM1p/5Pv/EMVjgiPSEqgv7RJMyyQK8aInIzvZWY3CK17al1vJbwlv4i0i6Vi9uUmsrfLFBXD1+A7yQXzl9DJMVAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;10 001 10&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/c5fb1ce173e6af2c3783796df774e4a8/d9199/10-001-10.png&quot;
        srcset=&quot;/devHistoryBlog/static/c5fb1ce173e6af2c3783796df774e4a8/8ff5a/10-001-10.png 240w,
/devHistoryBlog/static/c5fb1ce173e6af2c3783796df774e4a8/e85cb/10-001-10.png 480w,
/devHistoryBlog/static/c5fb1ce173e6af2c3783796df774e4a8/d9199/10-001-10.png 960w,
/devHistoryBlog/static/c5fb1ce173e6af2c3783796df774e4a8/07a9c/10-001-10.png 1440w,
/devHistoryBlog/static/c5fb1ce173e6af2c3783796df774e4a8/29114/10-001-10.png 1920w,
/devHistoryBlog/static/c5fb1ce173e6af2c3783796df774e4a8/1439b/10-001-10.png 2562w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/3a1b12b6c63a94a3d333c573ccb6d9d2/09262/10-001-14.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 34.166666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAABYlAAAWJQFJUiTwAAABdklEQVQoz22R30/aUBTH/f/jw15MXKYPi9tMnEZNlGxhTFARq1g6ITC0pShl1goUaR2lP+7H2xIfjJ57bs6559zzzffe74IQgtTiOCYMY0iky+D7AednKlXTpnLjYDyGCFkPQ5H1RZLmEXGSZPMvOAvzRF6S9Ul4hz7QsHyDwbSDoh+h9Os0hz0qVpWO22I0u8EYNrC8NtPoURIRbwHTlXrXVcnVPnBubtAeFMipi2jWNl7Y5bD1iWJzhc74mJ+XSxRay4ym/YxpOvyaYQYKA/OYdv0L18pn3NMNHvQS/l2D+L+L2fxO8/IrveIqo0aesVEhGNvMCYq3T06D3a9x0d5FVdbRC+tY+hmO+YeJ3aOubVHTNnGqO/TNEn+7eZ48m+R9wLkoLzbxI9TfOe6VfW7zO1x9W2NYPuKhfEhkO7ieya1TJUgC+ffiPVHmgMEskHuanY2rIj/KH7lW9/BODtC1Eqr6i/E/k5nnEvoesyiWKsevAJ8BXqoIiINvCc0AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;10 001 14&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/3a1b12b6c63a94a3d333c573ccb6d9d2/d9199/10-001-14.png&quot;
        srcset=&quot;/devHistoryBlog/static/3a1b12b6c63a94a3d333c573ccb6d9d2/8ff5a/10-001-14.png 240w,
/devHistoryBlog/static/3a1b12b6c63a94a3d333c573ccb6d9d2/e85cb/10-001-14.png 480w,
/devHistoryBlog/static/3a1b12b6c63a94a3d333c573ccb6d9d2/d9199/10-001-14.png 960w,
/devHistoryBlog/static/3a1b12b6c63a94a3d333c573ccb6d9d2/07a9c/10-001-14.png 1440w,
/devHistoryBlog/static/3a1b12b6c63a94a3d333c573ccb6d9d2/09262/10-001-14.png 1896w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;v1 파드가 그대로 유지되면서 v2의 파드를 하나 생성&lt;/li&gt;
&lt;li&gt;v2의 파드가 제대로 생성이 되었으면 v1의 파드를 하나 삭제&lt;/li&gt;
&lt;li&gt;그 후 다시 v1 파드 삭제, v2 파드 생성 행위를 replica 개수 만큼 반복&lt;/li&gt;
&lt;li&gt;하나 추가 생성된 파드만큼의 자원 사용량이 늘어남&lt;/li&gt;
&lt;li&gt;다운타임이 발생하지 않음&lt;/li&gt;
&lt;li&gt;상세플로우&lt;br&gt;
1.Deployment의 template 변경&lt;br&gt;
2.새 ReplicaSet 생성 (새로운 template 적용)&lt;br&gt;
3.새 ReplicaSet의 replicas를 1로 하여 v2 파드 생성&lt;br&gt;
4.v2 파드가 서비스와 연결됨&lt;br&gt;
5.기존 ReplicaSet의 replicas 개수를 하나 줄여 v1 파드 하나 삭제
6.새 ReplicaSet의 replicas 개수를 하나 늘려 v2 파드 생성 후 서비스와 연결
7.v1 파드의 개수가 0이 될때까지 5-6반복&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;어떻게 새로 생성된 파드들은 새로 생성된 ReplicaSet을 구별하나?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Deployment는 여러 ReplicaSet을 만들고, 각각의 ReplicaSet은 자신의 파드를 구별하기 위해 추가적인 라벨과 셀렉터를 붙인다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;RollingUpdate Deployment 리소스파일&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; apps/v1
&lt;span class=&quot;token key atrule&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Deployment
&lt;span class=&quot;token key atrule&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; deployment&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;selector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;matchLabels&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; app2
  &lt;span class=&quot;token key atrule&quot;&gt;replicas&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;strategy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; RollingUpdate &lt;span class=&quot;token comment&quot;&gt;#type 설정&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;minReadySeconds&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; app2
    &lt;span class=&quot;token key atrule&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;containers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; container
        &lt;span class=&quot;token key atrule&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; kubetm/app&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;v1
      &lt;span class=&quot;token key atrule&quot;&gt;terminationGracePeriodSeconds&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; 3.3. Blue/Green &lt;/span&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/b7e7b8c10bc85464092f860eab6e9eec/3c2d4/10-001-11.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 47.91666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABYlAAAWJQFJUiTwAAACU0lEQVQozx2SSXPaQBCF9f9vuaV8SG65pOI4ju0QHG/EoTAGg9hsI8SOQEJCO9oQXwamamqmel736/d6JHMxJgwc4iQiy/asVir6tE/g24SeSWzpmMaExaSH51gCa7E1NWxzwWzYxF3rhFubYL0gckwko31PHLiiWEa22+MvB+jNIqFtEBpz1u0y7uwVo32DtxwSuSa6XMIWBHr9D2a/QRr5GK1/WGob6bleJInDY8FcFNSNKeWnC3xvg+cuabbPRNcKT7Uiy9WQOPJ4kb8y19q0noqo7zX2+xy5+4PBsIz05eaWOI1J0xTyPcpixsnlBbbvY4UzCvJHRsaAT79E8lIjSF3OGx9QjAZnhd/UOjI5UOic0BhdIz00XoTUVHSXss9zJiuNQqXMNo5xtxpV5QzNnFKoVhm+9XC8NRXlGzPrnVKlQleuE3gOz6OfDLQakqy63NVmvE4igm1CliYo85Cb5xnNgc/GF2RZjO7sqLQN/rb6LG1fxBIsP6P+5lBq9hkbm6NK6VFecFke05skeEEsZGe0BganDwryMMJ0YtF9gulmNNWAq9oVivZ+tMcV+O44ofhyT0OtsstypFpvcpRLnorBpERCalddE0WRcCYTrIkApryPDF6VKYHjicEkwp6M4dym/TbBsx32GcfBSoWKgh9G7HY7kZwRi4Kff35HnU45rDhJYA+nt0UeGrVj7EB6WNfVMuelO3HL6Qwe8QMP6fBw0J6IxMOO44j5qoHnW8LPnYiJH5DsWOhdjI0qsPkxlolTt/poxuuRoDMo4fsu/wHsbuCmWrduvgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;10 001 11&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/b7e7b8c10bc85464092f860eab6e9eec/d9199/10-001-11.png&quot;
        srcset=&quot;/devHistoryBlog/static/b7e7b8c10bc85464092f860eab6e9eec/8ff5a/10-001-11.png 240w,
/devHistoryBlog/static/b7e7b8c10bc85464092f860eab6e9eec/e85cb/10-001-11.png 480w,
/devHistoryBlog/static/b7e7b8c10bc85464092f860eab6e9eec/d9199/10-001-11.png 960w,
/devHistoryBlog/static/b7e7b8c10bc85464092f860eab6e9eec/07a9c/10-001-11.png 1440w,
/devHistoryBlog/static/b7e7b8c10bc85464092f860eab6e9eec/29114/10-001-11.png 1920w,
/devHistoryBlog/static/b7e7b8c10bc85464092f860eab6e9eec/3c2d4/10-001-11.png 2092w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;다양한 방법으로 Blue/Green 배포를 할 수 있음(deployment 자체로 제공하진 않음)&lt;/li&gt;
&lt;li&gt;v1 파드를 그대로 유지하면서 v2의 파드를 replica 개수만큼 생성  &lt;/li&gt;
&lt;li&gt;서비스의 label을 v2로 변경&lt;/li&gt;
&lt;li&gt;문제 발생시 다시 서비스의 label을 v1으로 변경 (문제발생시 서비스의 라벨만 변경하면 되니 롤백이 쉬움)&lt;/li&gt;
&lt;li&gt;문제가 없을 경우 기존 v1 파드 삭제&lt;/li&gt;
&lt;li&gt;순간적으로 변경이 되기 때문에 다운타임이 발생하지 않음&lt;/li&gt;
&lt;li&gt;자원 사용량은 기존의 2배가 필요&lt;/li&gt;
&lt;li&gt;상세플로우&lt;br&gt;
1.새로운 template 및 라벨이 적용된 새 ReplicaSet 생성
2.새 ReplicaSet에 의해 v2 파드가 생성됨&lt;br&gt;
3.서비스에 적용된 라벨을 새로운 파드의 라벨로 변경&lt;br&gt;
4.문제가 없을 경우 기존 v1 파드 및 ReplicaSet 삭제&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;어떻게 새로 생성된 파드들은 새로 생성된 ReplicaSet을 구별하나?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Deployment는 여러 ReplicaSet을 만들고, 각각의 ReplicaSet은 자신의 파드를 구별하기 위해 추가적인 라벨과 셀렉터를 붙인다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Blue/Green ReplicaSet 리소스파일&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; apps/v1
&lt;span class=&quot;token key atrule&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; ReplicaSet
&lt;span class=&quot;token key atrule&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; replica1  &lt;span class=&quot;token comment&quot;&gt;# -&gt; replica2로 변경하여 배포 (새로운 ReplicaSet 생성됨)&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;replicas&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;selector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;matchLabels&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;ver&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; v1 &lt;span class=&quot;token comment&quot;&gt;# -&gt; v2로 변경하여 배포&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; pod1
      &lt;span class=&quot;token key atrule&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;ver&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; v1  &lt;span class=&quot;token comment&quot;&gt;# -&gt; v2로 변경하여 배포&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;containers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; container
        &lt;span class=&quot;token key atrule&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; kubetm/app&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;v1  &lt;span class=&quot;token comment&quot;&gt;# -&gt; 업데이트할 이미지로 변경하여 배포&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;terminationGracePeriodSeconds&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Blue/Green Service 리소스파일&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; v1
&lt;span class=&quot;token key atrule&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Service
&lt;span class=&quot;token key atrule&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; svc&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;selector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;ver&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; v1 &lt;span class=&quot;token comment&quot;&gt;# -&gt; v2로 변경하여 배포 (새로운 파드로 연결)&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8080&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;protocol&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; TCP
    &lt;span class=&quot;token key atrule&quot;&gt;targetPort&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8080&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; 3.4 Canary &lt;/span&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/f3f8599f6079eefdbf0f8c4d9540a93b/a7115/10-001-12.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 42.91666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAABYlAAAWJQFJUiTwAAACDUlEQVQozy2SW1PaUBSF8/9/QV867UvbBzu9jLYqaNWC1ooKKIhgNQhBI0kgycnl5MbXk2Bmzkz2PmetvfZeWzO9gCCW5FmKH8U8OB5OECGlrE6W55SfHcZM3QBXvUmShCxNVSww/ajCpyouj2YPmqTlAwWUocC63sN7uiNyTMz2HlIsKsJ4qeJOjXA5x58MsG5OWN63eT6vk8gIq9dgMe6hNa7+sipyxZ4Ry5ifp/s8mhPcwOH7yQZB5K0VejbfGrvEsWAw6fH7usb18IrD3/Xq/qhbo6930LZbZ+RFplIrklTy8eAXQ2OKSBa0xvvIJKoA5tLhfb1OGEfo1g395z+c9ftsHR1W93v9r3THp2i7F21EnHDce+TZ9vhwcMhoZmDMAzp3tppXVgGeFjbvdvfxhMsqrVIcd7tsHjWq/53ODzp6Cy2MJCKUnA3GmI6PL8Kq/emLUng7VgrXhK6IefPlktZowbaa27+Zzq3u8PbzOb3pCxvNTwpvoa2KFVm2Llk6pzqnUAaVcy2D/NXlLC+Yqw6GlydMdNVVJNQ8M4zhiPurJrY9rYRpIliqlcnV/NJqTazFE34YqiLK9dL9bK0wSRNc18S4vSB05hQFRFJgTIa0mzUs81EVzdAeZl2lhmq3pLL/uLup2pmpXLHew1dCz59zcLmJFUhFVigRoBttdlp1Ri9LLvpbiMDnPzzjm/9O//kvAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;10 001 12&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/f3f8599f6079eefdbf0f8c4d9540a93b/d9199/10-001-12.png&quot;
        srcset=&quot;/devHistoryBlog/static/f3f8599f6079eefdbf0f8c4d9540a93b/8ff5a/10-001-12.png 240w,
/devHistoryBlog/static/f3f8599f6079eefdbf0f8c4d9540a93b/e85cb/10-001-12.png 480w,
/devHistoryBlog/static/f3f8599f6079eefdbf0f8c4d9540a93b/d9199/10-001-12.png 960w,
/devHistoryBlog/static/f3f8599f6079eefdbf0f8c4d9540a93b/07a9c/10-001-12.png 1440w,
/devHistoryBlog/static/f3f8599f6079eefdbf0f8c4d9540a93b/29114/10-001-12.png 1920w,
/devHistoryBlog/static/f3f8599f6079eefdbf0f8c4d9540a93b/a7115/10-001-12.png 2186w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;불특정 다수 테스트&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;v1 파드를 그대로 유지하면서 v2 파드를 생성하는데, v2 파드도 기존 서비스와 연결되도록 라벨링&lt;/li&gt;
&lt;li&gt;그럼 서비스로 들어오는 일부의 트레픽은 v2 파드로 보내어 테스트 진행&lt;/li&gt;
&lt;li&gt;문제 발생시 v2 파드의 컨트롤러의 replica를 0으로 변경&lt;/li&gt;
&lt;li&gt;문제가 없을 경우 v2파드의 개수를 늘리고, v1파드의 개수를 줄여가며 배포 진행 (불특정 다수 테스트)  &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;특정 타겟 테스트&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;각 버전별로 서비스를 생성후 Ingress Controller를 이용하여 유입되는 트레픽을 url로 나누어 테스트&lt;/li&gt;
&lt;li&gt;문제가 없을 경우 v2 파드의 개수를 늘리고 url 원복하여 배포&lt;/li&gt;
&lt;li&gt;자원 사용량은 종료시키는 v1과 새로 생성하는 v2 파드 개수에 따라 늘어남&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; 4. DaemonSet  &lt;/span&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/b9e28b4a721401f69083c00e7f248dd6/1fa90/10-001-15.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 44.166666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAABYlAAAWJQFJUiTwAAAB+klEQVQoz2WSQXOaUBSF/f/brrrppH+gq07qNG2TWKsYjBKMWDGCIKggiEEBAfXrk2k3zZ25m/fmnXPfd26tSLYUsUcaOMShx36fkuc5ZVFQlgV5eeIYWmjqR9TOFebwmrXRwBxPcF2fS53PZ/5V7SgeFXlGuHawrBdWqxVpmlIIwUtfBHPPQJLf0X94z1T7jD3+ymxqsvSjt4KBoRCYGrIu0VTqdB+/EUVhdXk8ndhEG/RJn5mhMdH7mMaQl4kuppsLw/yt4N7ViF2d3lDm5u4TzU6dtTXEF+KZb+Islny5r/NLlvjRvuOu3aDZkOhIXYFnX4mchOD5b9eO1STQ01rcS9cMBh1Cb04SLsiTmN1ujzNfsFmtcWcuC9vGc+Z4y6VAdeD/qpUVwwOj0TNtqUFPueV1u6kuy7KkuLi9OowGV6jyB6xRndBsYOsTwXxBvE+Itq+CeyLCLKilh4JdljOdTbCFs2W/sN0lVRgXsyTN8MTZaHTDeHiDPe1i6DKOaQi+W0LRquUi6QaxCLMWBz6OdFt9W5sHBHFOsJwJ6GY1pevYNLvfUJQestLiQZF47Kqo6jNZluEubX4+fKfVbTDQZMFQrMwhcDmLRINNRJKkxJHPNgoqQV+sUbvZEmyfkaUOj70+T32VwdOwWq9kFzMe/WY6mRL6Hn8Az4uXfJjCwVUAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;10 001 15&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/b9e28b4a721401f69083c00e7f248dd6/d9199/10-001-15.png&quot;
        srcset=&quot;/devHistoryBlog/static/b9e28b4a721401f69083c00e7f248dd6/8ff5a/10-001-15.png 240w,
/devHistoryBlog/static/b9e28b4a721401f69083c00e7f248dd6/e85cb/10-001-15.png 480w,
/devHistoryBlog/static/b9e28b4a721401f69083c00e7f248dd6/d9199/10-001-15.png 960w,
/devHistoryBlog/static/b9e28b4a721401f69083c00e7f248dd6/07a9c/10-001-15.png 1440w,
/devHistoryBlog/static/b9e28b4a721401f69083c00e7f248dd6/29114/10-001-15.png 1920w,
/devHistoryBlog/static/b9e28b4a721401f69083c00e7f248dd6/1fa90/10-001-15.png 2118w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ReplicaSet과 다르게 노드의 자원상태와 상관없이 모든 노드에 파드가 한개씩 생긴다.&lt;/li&gt;
&lt;li&gt;한 노드에 1개 이상의 DamonSet 파드를 띄울 수는 없지만, nodeSelector를 이용하여 제외할 노드를 선택할 수 있다.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;hostPort를 사용하면 (service의 노드포트 설정) + (externalTrafficPolicy: Local) 옵션을 준 것과 동일하다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;externalTrafficPolicy: Local 옵션은 요청한 NodeIP에 있는 Pod로 트래픽을 전달한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;모니터링, 로그수집 등 모든 노드에 들어가야하는 서비스들을 구성할때 사용.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; apps/v1
&lt;span class=&quot;token key atrule&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; DaemonSet
&lt;span class=&quot;token key atrule&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; daemonset&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;selector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;matchLabels&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; app
  &lt;span class=&quot;token key atrule&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; app
    &lt;span class=&quot;token key atrule&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;nodeSelector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;#node를 선택할 수 있다.&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; centos
      &lt;span class=&quot;token key atrule&quot;&gt;containers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; container
        &lt;span class=&quot;token key atrule&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; kubetm/app
        &lt;span class=&quot;token key atrule&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;containerPort&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8080&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;hostPort&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;18080&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;#hostPort 옵션 적₩&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; 5. Job &lt;/span&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/0116a39c7865f0fdbf53e54fd1227d05/76435/10-001-16.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 41.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABYlAAAWJQFJUiTwAAABdElEQVQoz3WRbWviQBSF/f//o7AflrIgCoWyJC1dNY3GxGisMS/NmNiNRqg1mkbN00TWhe7WC8O5nA/PnJlTK4qCaiotiiPF8XjS0jn5+/ULWTwhX/lcmjOjmtp5r8x9yalQlW63O9K3Lel6zW6zId28kabpP2dDnuefoLW/CfcZO19laUocoiGeeMKa/MTtq8SeiwgE4WxOFIalhsxESPAsWCWrr4HHfMerJTFX62ydDk5gYozrBNMhWZYjZj6O0BlPJ7i+T/jbI4imJMnyf+BpPWQItYl9953F8B7bM+iPG1hWl3ARM7BbaG6d7uAR40llFN0yEDcskuhSwozU7RAbt7xXSRwD3WwwMR95Lf9vZKtoToO29qv0dRzPYmybLMrLvgbu30n9XplOJo9G9PQWknKNMezyskxo9yQetAYPLZlW+55+v4eqKsznFxKeWz78aV3TDX5cfcOVpVPzA8NEVbrI8h3NZhNFUeh0yhfFnxN+AD4YVXYJ7tYCAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;10 001 16&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/0116a39c7865f0fdbf53e54fd1227d05/d9199/10-001-16.png&quot;
        srcset=&quot;/devHistoryBlog/static/0116a39c7865f0fdbf53e54fd1227d05/8ff5a/10-001-16.png 240w,
/devHistoryBlog/static/0116a39c7865f0fdbf53e54fd1227d05/e85cb/10-001-16.png 480w,
/devHistoryBlog/static/0116a39c7865f0fdbf53e54fd1227d05/d9199/10-001-16.png 960w,
/devHistoryBlog/static/0116a39c7865f0fdbf53e54fd1227d05/07a9c/10-001-16.png 1440w,
/devHistoryBlog/static/0116a39c7865f0fdbf53e54fd1227d05/76435/10-001-16.png 1742w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;어떤 컨트롤러를 사용했냐에 따라 파드의 lifecycle이 달라진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; 5.1. Pod &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;컨트롤러를 사용하지 않고 파드로만 띄웠을 경우, 노드 또는 파드 장애시에 복구가 되지 않는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; 5.2. ReplicaSet &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;노드 또는 파드 장애시에 파드를 새로 생성한다. (Recreate)&lt;/li&gt;
&lt;li&gt;파드가 일을 하지 않을 경우에 파드를 재시작해준다. (Restart)&lt;/li&gt;
&lt;li&gt;지속적인 서비스가 요구될때 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Recreate vs Restart 
- Recreate는 파드를 재생성하여 IP나 파드명이 변경이 된다. 
- Restart는 파드를 재생성하지 않고 안의 컨테이너만 재시작한다.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; 5.3. Job &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;프로세스가 일을 하지 않을 경우 파드를 종료시킨다. (Finish)&lt;/li&gt;
&lt;li&gt;이때 종료는 파드 삭제가 아닌 자원을 사용하지 않는 상태를 의미한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; batch/v1
&lt;span class=&quot;token key atrule&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Job
&lt;span class=&quot;token key atrule&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; job&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;completions&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;parallelism&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;activeDeadlineSeconds&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;restartPolicy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Never
      &lt;span class=&quot;token key atrule&quot;&gt;containers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; container
        &lt;span class=&quot;token key atrule&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; kubetm/init
        &lt;span class=&quot;token key atrule&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;sh&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;-c&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;echo &apos;job start&apos;;sleep 20; echo &apos;job end&apos;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;terminationGracePeriodSeconds&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; 5. CronJob &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;주기적인 시간에 따라 Job을 생성하는 컨트롤러&lt;/li&gt;
&lt;li&gt;대체로 Job은 CronJob으로 특정시간에만 작동하도록 사용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;#v1.22&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; batch/v1
&lt;span class=&quot;token key atrule&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; CronJob
&lt;span class=&quot;token key atrule&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; cron&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;job
&lt;span class=&quot;token key atrule&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;schedule&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;*/1 * * * *&quot;&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;jobTemplate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;restartPolicy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Never
          &lt;span class=&quot;token key atrule&quot;&gt;containers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; container
            &lt;span class=&quot;token key atrule&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; kubetm/init
            &lt;span class=&quot;token key atrule&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;sh&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;-c&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;echo &apos;job start&apos;;sleep 20; echo &apos;job end&apos;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;terminationGracePeriodSeconds&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;---&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#v1.15&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; batch/v1beta1
&lt;span class=&quot;token key atrule&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; CronJob
&lt;span class=&quot;token key atrule&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; cron&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;job&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;schedule&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;20,21,22 * * * *&quot;&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;concurrencyPolicy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Replace
  &lt;span class=&quot;token key atrule&quot;&gt;jobTemplate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;restartPolicy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Never
          &lt;span class=&quot;token key atrule&quot;&gt;containers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; container
              &lt;span class=&quot;token key atrule&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; kubetm/init
              &lt;span class=&quot;token key atrule&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;sh&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;-c&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;echo &apos;job start&apos;;sleep 140; echo &apos;job end&apos;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;terminationGracePeriodSeconds&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[[K8S] kubectl 자주 사용하는 명령어]]></title><link>https://ssongey.github.io/history/posts/2022-04-04--001</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2022-04-04--001</guid><pubDate>Mon, 04 Apr 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; ■ 오브젝트 생성/변경 &lt;/span&gt;
&lt;span class=&quot;title__sub2&quot;&gt; ■ Create &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;같은 이름의 오브젝트가 존재할때 생성이 안됨&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;title__sub3&quot;&gt; 1. Yaml 파일로 생성 &lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;$ kubectl create -f &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;yaml 파일&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub3&quot;&gt; 2. ConfigMap 생성 &lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# file-c.txt 라는 파일로 cm-file라는 이름의 ConfigMap 생성&lt;/span&gt;
$ kubectl create configmap cm-file --from-file&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;./file-c.txt

&lt;span class=&quot;token comment&quot;&gt;# key1:value1 라는 상수로 cm-file라는 이름의 ConfigMap 생성&lt;/span&gt;
$ kubectl create configmap cm-file --from-literal&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;key1&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;value1

&lt;span class=&quot;token comment&quot;&gt;# 여러 key:value로 cm-file라는 이름의 ConfigMap 생성 &lt;/span&gt;
$ kubectl create configmap cm-file --from-literal&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;key1&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;value1 --from-literal&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;key2&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;value2&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub3&quot;&gt; 2. Secret 생성 &lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# file-s.txt 라는 파일로 sec-file라는 이름의 Secret 생성&lt;/span&gt;
kubectl create secret generic sec-file --from-file&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;./file-s.txt

&lt;span class=&quot;token comment&quot;&gt;# key1:value1 라는 상수로 sec-file라는 이름의 Secret 생성&lt;/span&gt;
kubectl create secret generic sec-file --from-literal&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;key1&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;value1&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; ■ Apply &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;기존에 같은 이름의 오브젝트가 존재할때 업데이트 됨&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;$ kubectl apply -f &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;yaml 파일&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; ■ Create/Apply 상태 확인 &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;생성/업데이트 된 오브젝트 상태 확인&lt;/li&gt;
&lt;li&gt;결과(성공 또는 실패)가 나올때까지 해당 명령어는 계속 수행중 상태가 됨&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;$ kubectl rollout status &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;오브젝트&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;/&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;오브젝트명&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; -n &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;네임스페이스명&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
$ kubectl rollout status deployment/fifi-app -n dev&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; ■ 오브젝트 조회 &lt;/span&gt;
&lt;span class=&quot;title__sub2&quot;&gt; ■ Get &lt;/span&gt;
&lt;span class=&quot;title__sub3&quot;&gt; 1. 파드 내용 조회 &lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# 파드리스트 조회&lt;/span&gt;
$ kubectl get pods -n &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;namespace명&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# 좀 더 많은 내용 출력&lt;/span&gt;
$ kubectl get pods -n &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;namespace명&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; -o wide

&lt;span class=&quot;token comment&quot;&gt;# 특정 파드만 조회&lt;/span&gt;
$ kubectl get pod &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;파드명&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; ■ Describe &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;상세 내용 출력&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;title__sub3&quot;&gt; 1. 파드 내용 상세 조회 &lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;$ kubectl describe pod &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;파드명&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; -n &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;네임스페이스명&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub3&quot;&gt; 2. 디플로이먼트 내용 상세 조회 &lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;$ kubectl describe deployment &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;디플로이먼트명&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; -n &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;네임스페이스명&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub3&quot;&gt; 3. namespace의 resourcequota&amp;#x26;limitrange 상세 조회 &lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# nm-3의 Namespace에 있는 ResourceQuota들의 상세 조회&lt;/span&gt;
$ kubectl describe resourcequotas --namespace&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;nm-3

&lt;span class=&quot;token comment&quot;&gt;# nm-5의 Namespace에 있는 LimitRange들의 상세 조회&lt;/span&gt;
$ kubectl describe limitranges --namespace&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;nm-5&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; ■ 오브젝트 삭제 &lt;/span&gt;
&lt;span class=&quot;title__sub2&quot;&gt; ■ Delete &lt;/span&gt;
&lt;span class=&quot;title__sub3&quot;&gt; 1. 파드 삭제 &lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# 파일이 있을 경우 생성한 방법 그대로 삭제&lt;/span&gt;
$ kubectl delete -f ./pod.yaml

&lt;span class=&quot;token comment&quot;&gt;# Pod 이름 지정&lt;/span&gt;
$ kubectl delete pod pod1&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;span class=&quot;title__sub3&quot;&gt; 2. ReplicationController 삭제 &lt;/span&gt;
연결된 pod는 지우지 않고 ReplicationController만 삭제
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;$ kubectl delete replicationcontrollers &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;ReplicationController명&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; --cascade&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;false&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; ■ 오브젝트 컨테이너 &lt;/span&gt;
&lt;span class=&quot;title__sub3&quot;&gt; ■ Exec &lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Container 들어가기&lt;/span&gt;
$ kubectl &lt;span class=&quot;token builtin class-name&quot;&gt;exec&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;파드명&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; -it /bin/bash

&lt;span class=&quot;token comment&quot;&gt;# Container가 두개 이상 있을때&lt;/span&gt;
$ kubectl &lt;span class=&quot;token builtin class-name&quot;&gt;exec&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;파드명&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; -c &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;컨테이너명&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; -it /bin/bash&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; ■ Deployment Rollback &lt;/span&gt;
&lt;span class=&quot;title__sub3&quot;&gt; 1. rollout 히스토리 확인 &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;deployment 생성/적용시 —record=true 옵션을 넣으면 CHANGE-CAUSE 필드에 명령어가 표시됨

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/f491f82f9efe922dd09492c0f31e2b19/c4451/04-001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 40%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABYlAAAWJQFJUiTwAAAA4UlEQVQoz62SWWvEMAyE7dx3SR5Dl5JtznUgdZMl//+XTTOClBb60OthsISsz4MstdgXvN7v6PoBdllgxhFmGPCQZlBKQWsF13U/yfd9keM4knueJ7HWGuo2TjDThMvlEXZd8dz3eLpe4QS+AH8skhnwxdkYpGn6rUZx81WNlhlEUYR931EUxe+cnQqC4H+BBNA+wdZaZFn2NyABJ9AcMyzLUtwyZy1JEjk52ziOEYahzJs5a+cfvCvPcwHyAh12XYflWJ+qqjDPM9bj56lt2zAd29A0Deq6lsfbtgX7PwLfAP1rsjIqoTkXAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;04 001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/f491f82f9efe922dd09492c0f31e2b19/d9199/04-001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/f491f82f9efe922dd09492c0f31e2b19/8ff5a/04-001-01.png 240w,
/devHistoryBlog/static/f491f82f9efe922dd09492c0f31e2b19/e85cb/04-001-01.png 480w,
/devHistoryBlog/static/f491f82f9efe922dd09492c0f31e2b19/d9199/04-001-01.png 960w,
/devHistoryBlog/static/f491f82f9efe922dd09492c0f31e2b19/07a9c/04-001-01.png 1440w,
/devHistoryBlog/static/f491f82f9efe922dd09492c0f31e2b19/c4451/04-001-01.png 1450w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;$ kubectl rollout &lt;span class=&quot;token function&quot;&gt;history&lt;/span&gt; deployment &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;디플로이먼트명&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; -n &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;네임스페이스명&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
$ kubectl rollout &lt;span class=&quot;token function&quot;&gt;history&lt;/span&gt; deployment deployment-1 -n dev&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub3&quot;&gt; 2. 롤백 &lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# 바로 이전 버전으로 변경&lt;/span&gt;
$ kubectl rollout undo deployment &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;디플로이먼트명&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; -n &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;네임스페이스명&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
$ kubectl rollout undo deployment fifi-app -n dev

&lt;span class=&quot;token comment&quot;&gt;# 원하는 리비전으로 번경 (마지막 리비전이 현재 리비전)&lt;/span&gt;
$ kubectl rollout undo deployment &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;디플로이먼트명&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; -n &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;네임스페이스명&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; --to-revision&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;리비전번호&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
$ kubectl rollout undo deployment deployment-1 -n &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;네임스페이스명&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; --to-revision&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; ■ Label &lt;/span&gt;
&lt;span class=&quot;title__sub3&quot;&gt; 1. node에 라벨 추가/삭제 &lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;#os=centos 라벨 추가&lt;/span&gt;
$ kubectl label nodes &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;노드명&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;라벨키&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;라벨벨류&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
$ kubectl label nodes k8s-node1 &lt;span class=&quot;token assign-left variable&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;centos

&lt;span class=&quot;token comment&quot;&gt;#라벨 삭제&lt;/span&gt;
$ kubectl label nodes &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;노드명&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;라벨키&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;-
$ kubectl label nodes k8s-node1 os-&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[[K8S] 기본 오브젝트]]></title><description><![CDATA[대세는 쿠버네티스]]></description><link>https://ssongey.github.io/history/posts/2022-04-02--001</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2022-04-02--001</guid><pubDate>Sat, 02 Apr 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; 1. Pod &lt;/span&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/6c42acfc822b288d1ca9645f368f7017/71ba4/02-001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 41.66666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABYlAAAWJQFJUiTwAAAB00lEQVQozz2SW2+bQBBG/f9/SR/ah1ZqK6WxlDR10jRVE8cYsI0Bx1yMAYMvwC4Xn25Qm4eRdr/ZOfvtzgyElFSyQdQtRSU5nipOpejjWFS9VsqaQqioBF3XYq9jZrZPFKeURYFUDCEEdV0zqNRmvtqiLTzm3oa7pwm3j8/cP+vc/tG5/jlmsvCxgh1evIdzp84G/HjQ2W63VFX1Fq/ggWwkj/oDo9vvbAuXfRcSHZZY4ZgwjXCDFXbgEp08vDRUvDPrMMV+2RDHyZuzV2DvsKgKotLiJFIsbYzvLCi7iESYBLarNI3VRCPLHbzMo2vPan1AtwLclxDP80iSRAHL/8ASu7zGbb7wS//MSPvEb/8b5vGCyfodZvSBmdKnyyHWxqJtzkjl6slY46w8XNfBsizyPKdpGgalSprpHc/BBV+Hl3y8ueH98IrR4grjMGSyu+TJf+Bueo+2tGnbDqGeZywDtNkK03JZ2ltW7knleoeShZuyfMkJowNrP8QwDWZzR3WxIt41xJkg2Uuyo1BFTf9f92OH2cLBMHSmU50s++fwWFY4XkigRqBuW3b7PckuJ80yNTbq1q6hUZBXkKwltSqqVTf9TdqPT5jk+MGhd9h1NX8Ba3xRph8GFpcAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;02 001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/6c42acfc822b288d1ca9645f368f7017/d9199/02-001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/6c42acfc822b288d1ca9645f368f7017/8ff5a/02-001-01.png 240w,
/devHistoryBlog/static/6c42acfc822b288d1ca9645f368f7017/e85cb/02-001-01.png 480w,
/devHistoryBlog/static/6c42acfc822b288d1ca9645f368f7017/d9199/02-001-01.png 960w,
/devHistoryBlog/static/6c42acfc822b288d1ca9645f368f7017/07a9c/02-001-01.png 1440w,
/devHistoryBlog/static/6c42acfc822b288d1ca9645f368f7017/71ba4/02-001-01.png 1870w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;한 파드내에서 같은 포트의 컨테이너를 가질 수 없다.&lt;/li&gt;
&lt;li&gt;두 컨테이너 container1과 container2 는 한 호스트로 묶여 있다.&lt;/li&gt;
&lt;li&gt;때문에 같은 파드의 각 컨테이너 내에서 다른 컨테이너로 접근시에 localhost 으로 접근할 수 있다.&lt;/li&gt;
&lt;li&gt;파드 생성시에 고유의 아이피가 할당 된다.&lt;/li&gt;
&lt;li&gt;이 아이피는 클러스터 내에서만 접근이 가능하며 외부에서는 접근이 불가능하다.&lt;/li&gt;
&lt;li&gt;파드 재 생성시마다 IP가 계속 바뀐다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; v1
&lt;span class=&quot;token key atrule&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Pod
&lt;span class=&quot;token key atrule&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; pod1
  &lt;span class=&quot;token key atrule&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; web &lt;span class=&quot;token comment&quot;&gt;# 서비스, 디플로이먼트 등 매핑을 위한 라벨링&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;containers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; container
    &lt;span class=&quot;token key atrule&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; kubetm/app&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;v1
    &lt;span class=&quot;token key atrule&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;containerPort&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8080&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;terminationGracePeriodSeconds&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# 파드 삭제시 기본적으로 30초 후에 삭제가 되는데, 파드를 바로 삭제하기 위한 설정 &lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; 2. Label &lt;/span&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/06e421128776350b6f3032bb3578f7a2/00e09/02-001-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 32.08333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABYlAAAWJQFJUiTwAAABc0lEQVQY00WP227TUBBF8/994icqVSoiCKjEQwUSbUrcAnUa17n4Ft9zQuzYPr4nLKzwwMMe7VnS7JkZvcznzHWNtEioOkkzKJMJTf/fd8eKQy5Z2xFeEFMUkr7vyfKS59cNi7WLZbsDzxnpjsbXn7e8vX3HL+sBO/jORLlhs31itbnnXvmIL1SSLONRNbEdl6qqaNuWvCiZ6S76ykaI7ZmP4txn5jwy/jJGdRSscMrk6QZn+4O198Dd9AOb+Jmub1lZEUvDIcsO58C6bpgtXFw/Jk2Soa8Zue4LyrcrPl1eoCrXLJRL7q4vMGbv0ZQrJuM3WNpnqrYhjPd4fkhVlvRdR9M0LMwAbeURx+JfoBzKbnjn1fPRg4hUFpxOHdXeQywn7IwpbS4o65blMLy2Q6I4Js9zjseeaJucuRA7pJSM0iFsvlgxVTVEXlF3PX+Ari4o9+GgaPByWHJiuztgOCGmaRAE4fnKWKR4ocC0JbvfFX8Blq+3NQcvEWYAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;02 001 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/06e421128776350b6f3032bb3578f7a2/d9199/02-001-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/06e421128776350b6f3032bb3578f7a2/8ff5a/02-001-02.png 240w,
/devHistoryBlog/static/06e421128776350b6f3032bb3578f7a2/e85cb/02-001-02.png 480w,
/devHistoryBlog/static/06e421128776350b6f3032bb3578f7a2/d9199/02-001-02.png 960w,
/devHistoryBlog/static/06e421128776350b6f3032bb3578f7a2/07a9c/02-001-02.png 1440w,
/devHistoryBlog/static/06e421128776350b6f3032bb3578f7a2/00e09/02-001-02.png 1854w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;라벨은 파드뿐만 아니라 모든 오브젝트에 달 수 있다&lt;/li&gt;
&lt;li&gt;보통은 파드에 많이 사용&lt;/li&gt;
&lt;li&gt;목적에 따라 오브젝트들을 분리하고, 서비스로 연결하기 위함(묶어서 사용하기 위함)&lt;/li&gt;
&lt;li&gt;라벨은 key와 value로 선언한다&lt;/li&gt;
&lt;li&gt;한 파드에 여러개의 라벨을 달 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; 3. Node Schedule &lt;/span&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/f416109bda2a23b1347b3abdb1a440cf/7e318/02-001-03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 27.083333333333332%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAABYlAAAWJQFJUiTwAAABNElEQVQY0zWQ207CUBRE+///4rO+GCWxCApSCsW2ll5OW7E3qGAv9GCWJyTuZL3MJDM7o5VlRVGUOB8uTvDG17dNOxT833kYCJKCNKto2o5BSqXJqy5/L4TKi+IdXddyPp/RjI3LaGpw+6ijLwws12JqLLh/mjC3HFVWMJ9v8N5tmqqgqw9XWsXwc1SBOV4Q07YNgyrRHsYj7vQ7Xt0xQb5l9p5wM1rzsnIx3S1VmmCbDsbCJg4E1S6jSHeKhFoE7Pc1ayciDENOpxNamrtEOws/2VDVKdFnqYIEztYny3KO+wqhgmeTJZ614dMPyUVMFvjUaUzf96xsgecLmuYHbWVPmC3H6M8GxnLN1nNZmib6dIZhrjgcDtTHBpFmiCigLAukVPupLaW8cLlIhHoiVn7fd/wB8zBt3VKVqQcAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;02 001 03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/f416109bda2a23b1347b3abdb1a440cf/d9199/02-001-03.png&quot;
        srcset=&quot;/devHistoryBlog/static/f416109bda2a23b1347b3abdb1a440cf/8ff5a/02-001-03.png 240w,
/devHistoryBlog/static/f416109bda2a23b1347b3abdb1a440cf/e85cb/02-001-03.png 480w,
/devHistoryBlog/static/f416109bda2a23b1347b3abdb1a440cf/d9199/02-001-03.png 960w,
/devHistoryBlog/static/f416109bda2a23b1347b3abdb1a440cf/07a9c/02-001-03.png 1440w,
/devHistoryBlog/static/f416109bda2a23b1347b3abdb1a440cf/7e318/02-001-03.png 1892w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;파드는 여러 노드들 중에 한 노드에 올라간다.&lt;/li&gt;
&lt;li&gt;노드에 올라가는 방법으로는 2가지가 있는데, 한개는 스케줄러가가 자동으로 선택하는 방법과 직접 명시해주는 방법이 있다.&lt;/li&gt;
&lt;li&gt;직접: 노드에 라벨을 달고 파드 생성시에 선택&lt;/li&gt;
&lt;li&gt;자동 : 생성할 파드의 필요 리소스 사용량에 따라 노드 스케줄러가 판단하여 노드를 지정&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; 4. Service &lt;/span&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/793fa54572d1401fd4e34b5259a7100d/41870/02-001-04.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 26.666666666666668%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAABYlAAAWJQFJUiTwAAABRUlEQVQY0x2QO0/CYBSG+a0OLixu/hIXYzRB4yDoJMHEyyJqU6Att16+UkppC9hCuToYQx4/Orw5w8n7nvc5Bd2bY41X9INlLlOqN8qoNWPO7lWual0+rBRnvMDRFNovDwhdwR5ndEWCUhe8KwFNPZL+jMLBPJxtGEzWeJPD3ODGa8LFL0fHRS5vKkzX+3x3UbrjtvKI4YSM0j/coc2n5lAfLLHiLSJaUej6S7zpjwzZ5mEHeVOp2Y7iySnnpTLRai+bL7guV6m+KhgiliV2kmRO3RCoDRXDHuNEawpmFOMnLn4aSPQl7UFGx5PYXoJmBpjeFD/OEEFC3wlomx59P80DbXmk1RuhGEPa8kgeaIQ9PgZ3aOEbivXNzZPDdU3wXLf4Ui0amouqCRq6K//kovdDdPubljlBs2cSP6HjpojJFlMW+gffs1637OolgAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;02 001 04&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/793fa54572d1401fd4e34b5259a7100d/d9199/02-001-04.png&quot;
        srcset=&quot;/devHistoryBlog/static/793fa54572d1401fd4e34b5259a7100d/8ff5a/02-001-04.png 240w,
/devHistoryBlog/static/793fa54572d1401fd4e34b5259a7100d/e85cb/02-001-04.png 480w,
/devHistoryBlog/static/793fa54572d1401fd4e34b5259a7100d/d9199/02-001-04.png 960w,
/devHistoryBlog/static/793fa54572d1401fd4e34b5259a7100d/07a9c/02-001-04.png 1440w,
/devHistoryBlog/static/793fa54572d1401fd4e34b5259a7100d/41870/02-001-04.png 1788w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;서비스도 파드와 마찬가지고 자신의 Cluster IP를 가지고 있다.&lt;/li&gt;
&lt;li&gt;서비스와 연결된 파드들은 서비스의 Cluster IP를 통해서 접근이 가능하다.&lt;/li&gt;
&lt;li&gt;파드는 언제든지 죽을 수 있고 재 생성이 될 수 있는 오브젝트이기 때문에 파드의 IP는 신뢰성이 떨어진다.&lt;/li&gt;
&lt;li&gt;서비스는 사용자가 건들지 않으면 삭제되거나 재생성되지 않는다.&lt;/li&gt;
&lt;li&gt;때문에 서비스 IP를 사용한다&lt;/li&gt;
&lt;li&gt;서비스에서 파드의 접근을 도와주는 방식은 크게 3가지가 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; 4.1. Cluster IP &lt;/span&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/32158fc8fd5e7117891aa309b2b1219a/7ca1f/02-001-05.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 30.83333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABYlAAAWJQFJUiTwAAABWElEQVQY0z2Q626bQBSE/f7vUvUJKlX5UffiNMQxMcFgTGKb+x2WhcX5shC1K50/M2fnzMxqur1TVDV7y8J2HOq2Y1QT/16UVvw1PZI0Q0pJ3/fLjOOwcN5bRJblDMOgsZGVkCNhWvJsH3kwLU7niKKRtP3I7X0+1mI8n4jj+L+gEGIRPPgxfwyby+W64DO/eg1zdm6I6Ubs9j6GfcE6l5i2R1ZUiF7ycrwSJ6l2IRm1k9nNNCl9PMVyz9RVpQXlp2AjBjxNfNue+HK34+sPCyOSeEGDGBS9XrLcQIsGOmK5TJIkNE1NWXfY3pWqKlBq+BSsuxHnNeZuY/B9/YvNwebn/T3rzQNpXnK7TTy9nLV7B9/36URH27b6c0/VdOydC55XUBZicbmau4rymkfb4vfWxA2PrI0tT+6BTvei1EgQ50v51zAjjrol+hxbKaX7rwiiWuO9xhQfpO7BCUWkrtsAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;02 001 05&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/32158fc8fd5e7117891aa309b2b1219a/d9199/02-001-05.png&quot;
        srcset=&quot;/devHistoryBlog/static/32158fc8fd5e7117891aa309b2b1219a/8ff5a/02-001-05.png 240w,
/devHistoryBlog/static/32158fc8fd5e7117891aa309b2b1219a/e85cb/02-001-05.png 480w,
/devHistoryBlog/static/32158fc8fd5e7117891aa309b2b1219a/d9199/02-001-05.png 960w,
/devHistoryBlog/static/32158fc8fd5e7117891aa309b2b1219a/07a9c/02-001-05.png 1440w,
/devHistoryBlog/static/32158fc8fd5e7117891aa309b2b1219a/7ca1f/02-001-05.png 1890w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;외부에서 접근이 불가능하다.&lt;/li&gt;
&lt;li&gt;서비스가 트레픽은 분산시켜 Pod에 연결해준다.&lt;/li&gt;
&lt;li&gt;type 은 기본적으로 ClusterIP 이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;171.96&lt;/span&gt;.10.17:9000/health_check&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; 4.2. Node Port &lt;/span&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/80cfd850e17929772d350d619151d60d/e8950/02-001-06.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 30.83333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABYlAAAWJQFJUiTwAAABVElEQVQY0z2R206DQBCG+/4Po4mJ8cILLzw0Go2trRJaoRxbYKEKUmCh7eeAh0k2k+zs/PPtP6OmbYkShesHrGPF4Xik6zr2+z2NbvE3Gdk2R2tNK2//ztKNMS2fLMuGWtM0Qx7VusN0Eh6mJjfjCa8LnyBriLY1uu2YGi6240tDTVXLqSppbHgXQWsVUBT5IFZLrc+jSgSNleJ2ZnF6M+f88Z0XO2bhyWQh9dYp4SZBi2ArBD1F/4Mg2uIGsQwohwH/gj3h+P6Ji6szDMdjujQ4vzzh5XXJEbD9mInhEasPlHxdpSm78osky3meu4RBzm7Xk/8K9p6F4ZqH8T0b8dATL2+v74iTlD58IZy+2Vj2avCyLMuBpvjaMTM9ZvMIa1mK5z/0Iy0G/0VZy2V3IFHpsKS60eRFOSxGpZ+kaSUUmsO+I1KfzE0HY+EQRh9Sy8TPgm/CdMIoT8lM8gAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;02 001 06&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/80cfd850e17929772d350d619151d60d/d9199/02-001-06.png&quot;
        srcset=&quot;/devHistoryBlog/static/80cfd850e17929772d350d619151d60d/8ff5a/02-001-06.png 240w,
/devHistoryBlog/static/80cfd850e17929772d350d619151d60d/e85cb/02-001-06.png 480w,
/devHistoryBlog/static/80cfd850e17929772d350d619151d60d/d9199/02-001-06.png 960w,
/devHistoryBlog/static/80cfd850e17929772d350d619151d60d/07a9c/02-001-06.png 1440w,
/devHistoryBlog/static/80cfd850e17929772d350d619151d60d/29114/02-001-06.png 1920w,
/devHistoryBlog/static/80cfd850e17929772d350d619151d60d/e8950/02-001-06.png 2000w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cluster IP의 특징을 모두 가지고 있다.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;모든 노드에 같은 Port가 할당이 된다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;주의할 점은 타겟 Pod가 있는 노드들에만 Port가 할당되는 것이 아니라 &lt;span class=&quot;text-mark__red&quot;&gt;모든 노드에 Port가 할당된다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;할당된 NodeIP:Port 들이 해당 서비스로 연결이 된다.&lt;/li&gt;
&lt;li&gt;외부에서 NodeIP:Port 로 접근이 가능하다.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;nodePort 값은 옵셔널이고, 생략할 경우 자동으로 할당된다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Node Port의 범위 : 30000~32767&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;외부에서 Node1 IP: Port 로 접근을 했을 경우&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Node1에 있는 Pod로 연결되지 않고,&lt;/li&gt;
&lt;li&gt;해당 서비스와 연결되어 있는 노드들 중 하나에게 트래픽을 전달한다.&lt;/li&gt;
&lt;li&gt;externalTrafficPolicy: Local 옵션을 사용하면 요청한 NodeIP에 있는 Pod로 트래픽을 전달한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;순서&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class=&quot;text-mark__green&quot;&gt; External -&gt; NodeIP:Port -&gt; Service -&gt; Pod &lt;/span&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; 4.3. Load Balancer &lt;/span&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/40433749d7668e1b99e7b674b6a83e81/7e318/02-001-07.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 33.75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAABYlAAAWJQFJUiTwAAABf0lEQVQozz2Re2+bQBDE/f2/T9WHEzmpVLVRlIY6tTEuj0ADxrzOGDie7q/HNc1K88/t7czs7MILM9abPYbp4h8LimpA1ANtP3E6N1huRJoVdF2r0GkMQ8+5lkSJUD1B0zTqbWAcRxaWX3D3fcvywWRlBliHGi86kwiJKGuM7TNJmmnCtm2RUmrCJC9Z7wJcL6Asy1ehgcVy9ZVPX5bcPH7j1nhiZdzw7uM1661D1w9sfr3w+yWkV4R9/8/hOA7kp4pHJRbHR+3wjdC2Ha4+vGe/N8mzlM+rK+7v7jkpVdn1OP6RIMqo1IoaVa1cNnpl046Ik1SRSb2BJkRV1o7ceinXVsQub/hf8wfTOfDw5PAchMSpIMtzcoW5t3MiTOtAUcxxvDrMxJmy6UjLBtMN2boBYZxqB3PItnK4sTwC3+ckKrV2/wbbjzF+evxY+0ThiWlSRxmnSQ/CH60QHHMNUVYMKqtZORO1urgkS+dL9zrDeU62vepLlWGtD3W5XPgLs8kNCEOO9mEAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;02 001 07&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/40433749d7668e1b99e7b674b6a83e81/d9199/02-001-07.png&quot;
        srcset=&quot;/devHistoryBlog/static/40433749d7668e1b99e7b674b6a83e81/8ff5a/02-001-07.png 240w,
/devHistoryBlog/static/40433749d7668e1b99e7b674b6a83e81/e85cb/02-001-07.png 480w,
/devHistoryBlog/static/40433749d7668e1b99e7b674b6a83e81/d9199/02-001-07.png 960w,
/devHistoryBlog/static/40433749d7668e1b99e7b674b6a83e81/07a9c/02-001-07.png 1440w,
/devHistoryBlog/static/40433749d7668e1b99e7b674b6a83e81/7e318/02-001-07.png 1892w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Node Port의 특징을 모두 가지고 있다.&lt;/li&gt;
&lt;li&gt;로드밸런서가 트래픽을 분산시켜 연결되어 있는 노드에게 전달한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; ■ Sample Service Yaml &lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; v1
&lt;span class=&quot;token key atrule&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Service
&lt;span class=&quot;token key atrule&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; svc&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;selector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;             &lt;span class=&quot;token comment&quot;&gt;# Pod의 Label과 매칭&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; pod
  &lt;span class=&quot;token key atrule&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;9000&lt;/span&gt;          &lt;span class=&quot;token comment&quot;&gt;# Service 자체 Port&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;targetPort&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8080&lt;/span&gt;    &lt;span class=&quot;token comment&quot;&gt;# Pod의 Container Port&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; ClusterIP&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; NodePort&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; LoadBalancer  &lt;span class=&quot;token comment&quot;&gt;# 생략시 ClusterIP&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;externalTrafficPolicy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Local&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Cluster    &lt;span class=&quot;token comment&quot;&gt;# 트래픽 분배 역할&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;h4&gt;Referenece&lt;/h4&gt;
&lt;p&gt;Kubernetes Service&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://kubernetes.io/docs/concepts/services-networking/service/&quot;&gt;https://kubernetes.io/docs/concepts/services-networking/service/&lt;/a&gt;  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Kubernetes NodePort vs LoadBalancer vs Ingress?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://medium.com/google-cloud/kubernetes-nodeport-vs-loadbalancer-vs-ingress-when-should-i-use-what-922f010849e0&quot;&gt;https://medium.com/google-cloud/kubernetes-nodeport-vs-loadbalancer-vs-ingress-when-should-i-use-what-922f010849e0&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; 5. ConfigMap, Secret &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;image 별로 환경변수값을 정의하는것은 비효율적이므로 외부에 환경 변수를 담기위해 ConfigMap과 Secret을 사용한다.&lt;/li&gt;
&lt;li&gt;key와 value로 정의하여 사용 &lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; 5.1. ConfigMap vs Secret &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ConfigMap은 일반적인 값, Secret은 보안적인 값을 저장(패스워드/ 인증키)&lt;/li&gt;
&lt;li&gt;Secret 값을 넣을때 base64 인코딩을 해서 값을 넣어야 한다는 규칙을 가지고 있다.&lt;/li&gt;
&lt;li&gt;Secret 값은 파드로 주입이 될때 자동으로 base64 디코딩이 되어 컨테이너 내 환경변수에 세팅이 된다.&lt;/li&gt;
&lt;li&gt;일반적인 값들은 쿠버네티스 DB에 저장이 되는데, Secret 값은 메모리에 저장이 된다. (메모리에 저장되기 때문에 보안에 유리)&lt;/li&gt;
&lt;li&gt;ConfigMap의 경우 key, value 값을 무한하게 넣을 수 있는데 반해, 한 Secret당 최대 1M까지만 저장이 가능하다.&lt;/li&gt;
&lt;li&gt;Secret은 메모리에 넣어두기 때문에 많이 만들게 되면 시스템 자원에 영향을 미치게 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; 5.2. 상수를 환경변수에 정의하여 사용 &lt;/span&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/72d85b283c8c81283ab89ba8e4c8e88d/d3b46/02-001-08.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 29.166666666666668%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABYlAAAWJQFJUiTwAAABTklEQVQY032Q3ZaaQBCEff/3yE3yDrnYJCd/a9asWX+iougsIMgADjjDDPBlJLlOn1Onuy+6qqsmvzcbjkJwVQrh++EQUlYV1jmcR9f19P3g0TMMvnt0fr6XSAqm8x15nmOMGTF5eJrz9uGReZiQJgm752+I5Q9aJdGtI8uvHiVNXWOtI/V7LisvZEfCx+ctRSFpW/uXcJHkvPn8nS/7wH/UEK8+IWbv0TKm1panl5DlasvlknHThumvA7v9EX1rKK8NwfFMml1Q3uFIOPQG10l/nBK+btkEG1RzwXtEm5b5+sQpPqHqaiRcBRFxnPz7qmW2PPHiBaMoQmvNxPU3Pq4WvPv6k/16Srr+QKkEDNBaiywVRVlgWjNaLio1Zlb7CDqf8TkrmS1CxGuM9QIT1zlknXKuYuQ1QlYCY29j8F3f8b+6E94Fg2NClqWj5T+oasSt3d9BiQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;02 001 08&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/72d85b283c8c81283ab89ba8e4c8e88d/d9199/02-001-08.png&quot;
        srcset=&quot;/devHistoryBlog/static/72d85b283c8c81283ab89ba8e4c8e88d/8ff5a/02-001-08.png 240w,
/devHistoryBlog/static/72d85b283c8c81283ab89ba8e4c8e88d/e85cb/02-001-08.png 480w,
/devHistoryBlog/static/72d85b283c8c81283ab89ba8e4c8e88d/d9199/02-001-08.png 960w,
/devHistoryBlog/static/72d85b283c8c81283ab89ba8e4c8e88d/07a9c/02-001-08.png 1440w,
/devHistoryBlog/static/72d85b283c8c81283ab89ba8e4c8e88d/d3b46/02-001-08.png 1690w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;파드 생성시에 해당 파드에 정의된 ConfigMap, Secret 값을 가져와서 컨테이너 내 환경변수에 세팅을 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; 5.3. 파일을 환경변수에 정의하여 사용 &lt;/span&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/59fffe4b02e39a15ce13eae77dc0186d/11a8f/02-001-09.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 52.916666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABYlAAAWJQFJUiTwAAACQklEQVQoz12TyXLTYBCE/fTceAVegAsXuLgIFeKAszghON7iRbJlyZK1WJu1yx8jmYQq/qquKUnz9/T0jDqqqtK/vsbQNvieA6ea73cjboYKg8cnHh5/4QchJyDLC5pjexGDZ4WlqhNFEVmWvaFjmCbfbgZcP40YvCzx04yrwQsX9wsmoxHjh5/s1nPqJCDP85Zw74Zc3k6ZLVQhDEmShDRNW3TCLOdDf8z77oB3X27ojte8nso32Pz4xOTiI2r/M3mWtu+DKGH4ssXYmdi23RI16lrCVKr6YYR9cNm6Ku7RIEwtgsRi+PuR7WZF7LvEgSctnxVmImKxNluY1p4gCP4pLMqzL1kZ4FcLkspD0Sc4gSE+9dCsORQZpzyiKEvqk7h5qlC3NnNFR1ktUVT1zctOXpwJk8pB8W8ZjnVeZkvUhY6VjfCK+ZsFr4R1XWHuPaYro205Fh+LIn9VWLbJaeWzcC/pP13Ru+/Su+3yrH/FyxWaEdcy/Sb3JISlxObyaG7QG8yZLrZtgWZonTCOCOID0TGS9fCJE580j8mrlCQ9CsRsGUb61/S6FuKilPZSLMfneaoync5Q1fVZob7bsdtLBWvHVtuiCRzbIfADaceR3XTxBIfDgePxSFVVgpIgjHkYrRlOVuxtt1XXEsaSFKdhqyaOY7kUt+Y2Cf+jEL8bwiYWeYZuetzJDzCeKZimdR7KSqRqO5WNJlHTWC6X8vG8X67rYsla7EW9I8+mZbVFGw+blsPoKN652HtT8qx2wf8A23g6TLhCm00AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;02 001 09&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/59fffe4b02e39a15ce13eae77dc0186d/d9199/02-001-09.png&quot;
        srcset=&quot;/devHistoryBlog/static/59fffe4b02e39a15ce13eae77dc0186d/8ff5a/02-001-09.png 240w,
/devHistoryBlog/static/59fffe4b02e39a15ce13eae77dc0186d/e85cb/02-001-09.png 480w,
/devHistoryBlog/static/59fffe4b02e39a15ce13eae77dc0186d/d9199/02-001-09.png 960w,
/devHistoryBlog/static/59fffe4b02e39a15ce13eae77dc0186d/11a8f/02-001-09.png 1272w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;파일을 통으로 ConfigMap에 넣어 사용할 수 있다.&lt;/li&gt;
&lt;li&gt;파일명이 key, 파일 내용이 value가 된다.&lt;/li&gt;
&lt;li&gt;명령어를 이용하여 파일을 secret으로 만들 경우, 자동으로 base64 인코딩이 되므로 2중 인코딩이 되지 않도록 주의하자.&lt;/li&gt;
&lt;li&gt;파드 생성시에 해당 파드에 정의된 ConfigMap, Secret 값을 가져와서 컨테이너 내 환경변수에 세팅을 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; 5.3. 파일 마운트의 경우 &lt;/span&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/570fb2ece37f538c002f3044d41f0d1e/f32b7/02-001-10.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 48.75000000000001%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABYlAAAWJQFJUiTwAAACBUlEQVQoz52S23PSYBDF+dt91v/B8bGPfVArdqZjrVXEQlOu4VZIQkKAQELut5+bYEef3ZkzSb7db3POnm0UZUmFEmpkec7fkPOyrN+KopBcVp8lScpc27I0dmzsPYHvk6ZpjcbjY5eewD1IwnOlvkAZTmkpKvOlwe3dHfraIk4z0rwgzVLCKOFxpDGePHM8usRxTBRF9bOxWpvcKGOa7SeaD320o89oseG6PUN9XrMcdpgqPzHnQwp/TyIsKnzrzOmrS3Rtha4bBEEgzBMa1ink9acWb5ptXl1+5aI95t+wutfMbi5QPrxDf2iSZcJUsNBsdGuPtT0QC7uqWd0wEpp+EOIcHazDEidY44YWXmyz1Gf0+0+4kguD0/misCtlLDvHrVmqk6qmj2EYZ8l5cTYhzjycTCXjiG6rGNsp42mP++5nmZlHETiUyUnY5eRinHfyuXuY8aOr0lGGaCLd8zwaL64G6R4z7DKYmLS6czw3FvdT1mlLWIVnz8XxSm4tO01YicujmYluWCwWc2zbrhpmdbGfbZl4H7m6/8Lb91d8Hyis7CcG7iVpEdU7VTV8kaybe25/TVis1pjWRhhq+LI+jbjaH/ljlIQcfEvmt63hnCwc+T4EG1mZpK5J/tRWO1lJ7gxWdHozcVlnt9udZ8h/RDXDXPZxs3PFZQfH2XMSdtUofgM+8PDG7DhOVgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;02 001 10&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/570fb2ece37f538c002f3044d41f0d1e/d9199/02-001-10.png&quot;
        srcset=&quot;/devHistoryBlog/static/570fb2ece37f538c002f3044d41f0d1e/8ff5a/02-001-10.png 240w,
/devHistoryBlog/static/570fb2ece37f538c002f3044d41f0d1e/e85cb/02-001-10.png 480w,
/devHistoryBlog/static/570fb2ece37f538c002f3044d41f0d1e/d9199/02-001-10.png 960w,
/devHistoryBlog/static/570fb2ece37f538c002f3044d41f0d1e/f32b7/02-001-10.png 1136w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;원본 파일과 마운트가 되어 있으므로, &lt;span class=&quot;text-mark__red&quot;&gt;ConfigMap이 수정이 되면 바로 반영이 된다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;이게 5.2과 가장 큰 차이점이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; 6. Volume &lt;/span&gt;
&lt;span class=&quot;title__sub2&quot;&gt; 6.1. emptyDir &lt;/span&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/68ffa9bd1a8d45d4e4d29510aa947228/7161f/02-001-11.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 61.24999999999999%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAABYlAAAWJQFJUiTwAAACRUlEQVQoz5WT64vaUBDF/f//ln4ohVLoh8J2l7JV10dM1GjiqvHGPEyieZmX/nqN3VIolHbgEG6Ye+6ZmTOd6/XKv+IWpyRHWwrMzR7/EHDOc6qqoigKmqahw3/GMc7pq2tmizVpkpBlGbkkPZ/P1HVNp5asVVNTyUNRli3K6u1c/fxXtbjl3r43hbbj4ToOQgiOx2OrsCUUtuDx4YnBqMepsohrwdZV2XgqycVqETcWYWGS5BFl2TBZWCgLmSdcgiAgSbP24ZbQCwWTzRdW4TMxMyJUvGaMX+r4+RIrUnBTnbBecMz8tmzXPTAYLlhOZ2jDIbuVSR6f7j2MMgcnWGOYc7S5VLZds4q+ERVb7L2DqutsrB1hKogyl2sjB2PbjBQTRVli6Aah55L7HrUsu+PHW4YvQx4+SXzuMnyeobgfCGodIS/2lSHGasUhWxNk4k4oe9cdGvRfNPrdPpoyJtrbNLLsjp/sULyPiOiV+eErPesdI+89uv+I6Q2Y2d8x3BdeZUvCdN+WvLekwu8K5mjMvNfDnk3JDz7N5ULnKH31urJYLkymms50ukTsPMIwJskKrjLpItE0l3b6jXREKhWOtQ2jiYE+X3Jw9veSb0NJpI8cz0fsXXb2Hu8QSvOmRKeY/Fy0ZG84l3fz+pbguSsHoi4x5zqGOiG0tm2O9GHdSm2u8pLchtaXdf0HSrkNlVR5Lc6sVZ3B0wChqWyVESdjQSGnXP/aFLlVv6/X3+IiCVPXY2Pu8HY2J9ehCA6UclNuwn4A4u2IxsRNS4gAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;02 001 11&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/68ffa9bd1a8d45d4e4d29510aa947228/d9199/02-001-11.png&quot;
        srcset=&quot;/devHistoryBlog/static/68ffa9bd1a8d45d4e4d29510aa947228/8ff5a/02-001-11.png 240w,
/devHistoryBlog/static/68ffa9bd1a8d45d4e4d29510aa947228/e85cb/02-001-11.png 480w,
/devHistoryBlog/static/68ffa9bd1a8d45d4e4d29510aa947228/d9199/02-001-11.png 960w,
/devHistoryBlog/static/68ffa9bd1a8d45d4e4d29510aa947228/7161f/02-001-11.png 1182w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;container 들끼리 데이터 공유를 하기 위해 volume을 사용&lt;/li&gt;
&lt;li&gt;최초 해당 볼륨이 생성될때 항상 비어있기 때문에 emptyDir로 명칭한다.&lt;/li&gt;
&lt;li&gt;pod 안에 생성이 되기 때문에 파드 생성시에 만들어지고, 삭제시 없어짐&lt;/li&gt;
&lt;li&gt;해당 볼륨에는 일시적인 사용목적에 의한 데이터를 넣는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; 6.2. hostPath &lt;/span&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/ebe8232c0ca11b573d653f582c5c16b1/08485/02-001-12.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 33.33333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAABYlAAAWJQFJUiTwAAABg0lEQVQoz3WQ2W7aQBiF/f4P0zeIUtSWIMAUiPctHpvV8YYXbMekXwdUqRdVRzo3c3SW/yjvWUZzvVJVNW3TUdctfd8z3m7cuSRNaa8d17Zj/Phk6EfGccQTZ6LdgepScpX6YRgeUAIhyMsLQkRkaU7gvZHn+UPk+AGB/D+cTkSRIJMBd3TSwI8SRHykyDNp2P41nE10Xp5NtrqKsXtmsv5CuHMfDQ3NZzoxWM117HDB2n3C3amUZU6SVai64HDOSYuaVAaVZYmiznQpcFmtVTT/hY3xRBw5fMiGpu7xc26zWZl4noMIPVxrKy9IuVwa1hsbSzfIz8nj7DsU0zExfnxjtfyKFS/Q/e8cjqE0vEmTiPXSZrHYompTXu0ptq+SFzltXrBVDcyNRiLDhj87Km+hILQdIuET7CxcYZAVGaf3lOXylfnMxDIFYu9IbkMQWzR1RXpM0DSPcxzTyM37sqDvOhT+86q6oZCbdEP/D/fr8yYNSqJwT+R7JPs9l/OJD9nwN/a8BawWBBGNAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;02 001 12&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/ebe8232c0ca11b573d653f582c5c16b1/d9199/02-001-12.png&quot;
        srcset=&quot;/devHistoryBlog/static/ebe8232c0ca11b573d653f582c5c16b1/8ff5a/02-001-12.png 240w,
/devHistoryBlog/static/ebe8232c0ca11b573d653f582c5c16b1/e85cb/02-001-12.png 480w,
/devHistoryBlog/static/ebe8232c0ca11b573d653f582c5c16b1/d9199/02-001-12.png 960w,
/devHistoryBlog/static/ebe8232c0ca11b573d653f582c5c16b1/07a9c/02-001-12.png 1440w,
/devHistoryBlog/static/ebe8232c0ca11b573d653f582c5c16b1/29114/02-001-12.png 1920w,
/devHistoryBlog/static/ebe8232c0ca11b573d653f582c5c16b1/08485/02-001-12.png 2014w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;한 호스트 즉, 노드의 path를 볼륨으로 사용 &lt;/li&gt;
&lt;li&gt;pod에서 해당 노드의 path를 마운트하여 사 용하므로 pod가 삭제가 되어도 노드에 있는 데이터는 삭제되지 않는다.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;다만 파드가 재 생성될때 다른 노드에 생성이 될 수 있으므로 기존 노드에 사용하던 볼륨을 마운트 할 수는 없다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;사용자가 직접 각 노드의 볼륨들을 마운트 시키면 된다.&lt;/li&gt;
&lt;li&gt;하지만, 쿠버네티스가 하는게 아니라 사용자가 직접 작업을 하므로 실수가 발생할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;파드 자신이 할당되어 있는 호스트(노드)의 데이터를 읽거나 쓸때 사용한다.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;hostPath Type&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DirectoryOrCreate : 실제 경로가 없다면 생성&lt;/li&gt;
&lt;li&gt;Directory : 실제 경로가 있어야됨&lt;/li&gt;
&lt;li&gt;FileOrCreate : 실제 경로에 파일이 없다면 생성&lt;/li&gt;
&lt;li&gt;File : 실제 파일이 었어야함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; 6.3. PVC/PV &lt;/span&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/3a570b0153cd4c78f8ff27cacfe52527/84ee5/02-001-13.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 45.833333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAABYlAAAWJQFJUiTwAAACJElEQVQozz2SWW/TQBRG89N55wXxyAOiQuIFKBVNN9E2TddQkz1N49iOnXiNt3jJ5tL2MGklNLq6M/feOfpm9JVm+ZI4e41ZviKc5Th+TJQuXs6byJcFcb7+P+eKvjONCJKcZFGQvvQ3swtKIzdHtnIUJ0d15nTVKRfSPX0jFrU5upsxjTKGhsfISVHsOTctleptn57scT/0aXYnyFqM5SWUjGlG817nZ3mfRk97hfgF9a5K+eCIzsDAFmp6soEyCaic33BaqTI0Z7jGHLlpIF10cUfiZdYG6Lto075QecFgPOTOWNFSM64aY06vB/S0GZqTcNLJ+Vzu8v7TEduVEdIgpNUeE6drqmfXnBxeYk4iAQwslLCBnp0hhwNu1DmH1xYfvpzyqx7R1AssP+V2EFOpTziuKVy2Hfpmzlhq45/sUZcaXFWvsG0B1AKNQXKG+vAVJWpR7RVs/y7YOjT5XnugercQwIz+OEXqjvmxs0t57wDZXlDZ3mX37RuCYIhnjgQwpiTbFi2zQ9u9RHYMav2UvduA41bKvhQhyQl2kHPUSPi40+LdVoVv5zZ1OUYdTelrOp1RD20ywRj7lLxoiW7GDBWT2p8uim4JO6xwA/Hpfohi2HhhysYNhiuyGdCRTVF3MfQAQ0B1bYqqOrjejNJqLfyVCBWeh2GaeEHMqihIslzsIxEh0Szl8fGvqGUEUUwYx/hhzFLcfRbr6fnpJa+KNf8A3CKIVYiO1acAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;02 001 13&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/3a570b0153cd4c78f8ff27cacfe52527/d9199/02-001-13.png&quot;
        srcset=&quot;/devHistoryBlog/static/3a570b0153cd4c78f8ff27cacfe52527/8ff5a/02-001-13.png 240w,
/devHistoryBlog/static/3a570b0153cd4c78f8ff27cacfe52527/e85cb/02-001-13.png 480w,
/devHistoryBlog/static/3a570b0153cd4c78f8ff27cacfe52527/d9199/02-001-13.png 960w,
/devHistoryBlog/static/3a570b0153cd4c78f8ff27cacfe52527/84ee5/02-001-13.png 1076w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;파드에 영속성 있는 볼륨을 제공하기 위한 오브젝트&lt;/li&gt;
&lt;li&gt;실제 필요할때 다시 공부&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; 7. Namespace/ ResourceQuota/ LimitRange&lt;/span&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/8538cef1c0e44910a18723a66d98cf30/0940f/02-001-15.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 47.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABYlAAAWJQFJUiTwAAACYUlEQVQozz2T2W7TUBCG/XpcIHFRJCTgLeANuOKiCKkVIMQFFBXRBgpVuqeFtjQtDVkakqiQlTQhaeK4duIlXpKPsUFY+j3njOef4/lnjqKbDiPbxRoH/2G7Ph3VoNrq0+gMxPboDAx+yTrEyHExbQfLGWNYY8IcQ9sTrodSrl/QaF9Qqp9RrGUFOVTjSgJdBkMLbWSLtSOSFu5NSXKlUUvvclHNcJKvkTgtcZQvoEqcMuirdLp1jnMfOMzEOM2vMjJ7hM90EhAEPpMgCHf/AI6hUk2uclFOCq9K4qQg3KQcaKI0LzX6uinkKBZNd6i3NSntEtOyCHw/StruDqg0ezQ7HVzfi2IDywhff4lymO1KybGdJOunRTqax9jzOc6es7SZYjmxRqHeYmhN8f2ATydF3u18Y2Ejzl5BpZD/QWplHrV2TKaqc+/pFtlyG8XxpvSufIyRLzpNcMZhiZ6IDF3VRBe/IX5f/jTEQcljMzOmWNGpN1VMUzQ2rChZqLXyvWHyau0rG7kGiXSJinTUn0zZzl4yH9tnPVPjuFCWjnp0r1xiOYP3RV2gEc9rdCotLjWTNztxWv0+yuxWnmuPt5l5cciNhxvM7ebomxZ3Fw65/nyfW/OfuTUbp9jucd5WmXl7xJ2NDLcFN5eTZGtt0j/7PFhM0ejqKL8HQxYPUjxa2WHpMCdajqJGpKstnmzuM/dxjy+FBq4Iro/GvNzOcf9ZLMLrxBma4Ug/wimYRD1QTBliRwbVshzGMpi2G8jgejhibRnayC+BpnwzRV/Xn4puchlEO0/WlvCHwg+hywX5AyDk0ylKGU6SAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;02 001 15&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/8538cef1c0e44910a18723a66d98cf30/d9199/02-001-15.png&quot;
        srcset=&quot;/devHistoryBlog/static/8538cef1c0e44910a18723a66d98cf30/8ff5a/02-001-15.png 240w,
/devHistoryBlog/static/8538cef1c0e44910a18723a66d98cf30/e85cb/02-001-15.png 480w,
/devHistoryBlog/static/8538cef1c0e44910a18723a66d98cf30/d9199/02-001-15.png 960w,
/devHistoryBlog/static/8538cef1c0e44910a18723a66d98cf30/0940f/02-001-15.png 1154w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;클러스터에서 사용할 수 있는 리소스는 한정적이기 때문에 네이스페이스별로 리소스를 한정하여 사요하도록 하는 오브젝트&lt;/li&gt;
&lt;li&gt;ResourceQuota는 Namespace 뿐만 아니라 Cluster 전체에 부여할 수 있는 권한이지만, LimitRange의 경우 Namespace내에서만 사용 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; 7.1. Namespace &lt;/span&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/d2184de7167f2ae556ef4307d1e23a03/541fe/02-001-16.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 31.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABYlAAAWJQFJUiTwAAABf0lEQVQY0yXQS3OaABSGYf//vquuMt20zbSTNjPJUK0JNhFFJUq9gdwERTAgDGK8kOQtSc/M2T7fOV+l2Ca85Cmb0Gc6mWIaFmkUorZueGj/IfEN7EXEj/qQaneBE+54m+L4xGLVZhnKTNV72qLAoFWn0tHOEYdn6FYNVbqmd/+dJHQYyzdo3VvylYa1TLgUJ9QVvwSf/oOnnOv2Ry7uPhAvZRythqv/piLb32joZxgzgcDsYmi3ZJHHsCViqhL7tYHrJwhNA2myIUiLd/B4esY0AzR1hiIrdCSZflehEkRHVo8nRlOPhqTQlIeEqyWd5hX9xiWZ2cNapFxUR9z1/PLN7Tt4OBVMPI2xN0U0Tb42BWrjv1RmZT8zL0ZZbPjU+smXnkAYR/QHv8oVyF0VK8j4/KAjjkK8VdnhS8GpeC6DLGzXYjCfUe0LyGYJZrsD2e5IvN1jrec4jx55nhEYKpEzYh/PWacHFDtC15fEbgDblNe3M30fbBMsA1wPkpR/Lkitbkz6nwMAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;02 001 16&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/d2184de7167f2ae556ef4307d1e23a03/d9199/02-001-16.png&quot;
        srcset=&quot;/devHistoryBlog/static/d2184de7167f2ae556ef4307d1e23a03/8ff5a/02-001-16.png 240w,
/devHistoryBlog/static/d2184de7167f2ae556ef4307d1e23a03/e85cb/02-001-16.png 480w,
/devHistoryBlog/static/d2184de7167f2ae556ef4307d1e23a03/d9199/02-001-16.png 960w,
/devHistoryBlog/static/d2184de7167f2ae556ef4307d1e23a03/07a9c/02-001-16.png 1440w,
/devHistoryBlog/static/d2184de7167f2ae556ef4307d1e23a03/541fe/02-001-16.png 1654w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;한 네임스페이스 안에서 같은 종류의 오브젝트들은 같은 이름을 가질 수 없다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;에러: 파일 배포 실패 (pods “podName” already exists)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;타 네임스페이스의 자원과 분리가 되어 관리가 된다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;파드의 라벨링으로 서비스와 연결을 하는데, 서로 다른 네임스페이스에 있을 경우 연결이 되지 않는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;네임스페이스 삭제시, 그 안의 자원들도 모두 삭제가 된다.&lt;/li&gt;
&lt;li&gt;각 네임스페이스의 파드의 IP끼리는 기본적으로 통신은 되지만, network policy 오브젝트를 이용하여 막을 수 있다.  &lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; 7.2. ResourceQuota &lt;/span&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/534f5e6bbda09e7bedb9a587caf3937a/9c1e6/02-001-17.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 30.41666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABYlAAAWJQFJUiTwAAABX0lEQVQY002QC4vaQBRG8/9/Tyl9gFhWi4vWuFmNNY/NY81jYmJinppUT4cUlg58zFy4c+6ZUfImIK18mltG2dxwgoyn2YKv3yc43juWn/C6f+N4DKjrCm2ro5su7lFQXEpEHKO+bDmlGW3borwlS34HM9LapigqdDtkOntmMp0TRALdCllt9oRBQNM0aJqGZdlk4iTrliiK+LVWiSS46zqU09klTExpl1CkKRsnkgYWhmFQlhVl3SFOZ4a+Hw3W6ma0LYSQxjWpvLPb7fA8dzwrG/+Vlb3m3HoU8km7eM+zseA91xF5zv/r/mdA8xJUS36FZRJKu1z2qKqK7/vjAGVifmbufsLN5ySRx9T4xur4Baf6QZSn/0D3+8d+labXaydzpR8GOmn9tN6yeNEpLxcUM1pixgtEeaBuKg7hEiP6iZutpHE5gh6PxwdwGHqZYUwv4bfbDTsQHGwHIWL+AtyOu5c5egJQAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;02 001 17&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/534f5e6bbda09e7bedb9a587caf3937a/d9199/02-001-17.png&quot;
        srcset=&quot;/devHistoryBlog/static/534f5e6bbda09e7bedb9a587caf3937a/8ff5a/02-001-17.png 240w,
/devHistoryBlog/static/534f5e6bbda09e7bedb9a587caf3937a/e85cb/02-001-17.png 480w,
/devHistoryBlog/static/534f5e6bbda09e7bedb9a587caf3937a/d9199/02-001-17.png 960w,
/devHistoryBlog/static/534f5e6bbda09e7bedb9a587caf3937a/07a9c/02-001-17.png 1440w,
/devHistoryBlog/static/534f5e6bbda09e7bedb9a587caf3937a/9c1e6/02-001-17.png 1734w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;네임스페이스의 자원한계를 설정하는 오브젝트&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;리소스쿼타가 지정된 네임스페이스에 파드를 생성할때는 꼭 스펙 명시를 해야한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;하지 않을 경우 해당 네임스페이스로 pod 생성이 되지 않는다.&lt;/li&gt;
&lt;li&gt;에러: must specify limits.memory, requests.memory&lt;/li&gt;
&lt;li&gt;limitRange에 default가 설정되어 있을 경우에는 상관없다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;현재 namespace에 사용된 requests 를 넘는 파드 생성 요청시 오류가 난다.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;주의할 점은 ResourceQuota 생성 전에 이미 파드가 만들어져 있으면, 해당 파드들에게는 영향이 가지 않는다&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;따라서 ResourceQuota 생성 전에 파드들을 지우는게 안전하다.&lt;/li&gt;
&lt;li&gt;그렇지 않을 경우, ResourceQuota 설정보다 over하여 네임스페이스에 파드들이 생성된다. &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;제한 가능한 항목&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Compute Resource: cpu, memory, storage&lt;/li&gt;
&lt;li&gt;Objects Count: Pod, Service, ConfigMap… 등 k8s 버전이 높아짐에 따라 제한할 수 있는 오브젝트가 늘어남&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; 7.3. LimitRange &lt;/span&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/305473c5ef43ec665cf2c7dc4f67450a/94cea/02-001-18.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 39.166666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABYlAAAWJQFJUiTwAAABl0lEQVQoz32SeW+bQBDF+f6fp1LTQ1UrRUorN0nrK9jlMGCTNeDFnAs28OuaOP2r7Uizh3b2zZs3Y6Bt6Af+acNA07Z0XXe9DvTX+FgWTKY2juMipaTVcUamUtJiz6mraE/n8SFJEvK8GD9ewIQQVFU9gl2zjOvhWPK4cImiSL9XNE2D8eB95qf/lrhYchAJXx8XfLn7zpPl60QVzk4Q7QWqrkeWXd/r/QWwrBS2JyjKkrquUEphLMM5M/+erA44JhIvlGx2CWGUUdaKH6bF2g/ZypxKNaxdwXRpEwRbzucTlrcn0En3Yq9Ba4xb+yNTcYNsVuRVw93DLe8+veGXu6ZWLWF8YLaytF4pvWZo+xGm5XFM5cjY3UasHEGwjUmPGUZaxJqNQ15IZJ5wY35gEr5nl8+RWc0302VhbSiKUjM6jzpegHpd+qB9o4Emsw0r+5nnSGJc9E2S+EWDVrGJnggOcw7ljtO555jlWr9q7OBrp/8MQN/haXmm5nZk2Chd8sB/RuavUzRc/XLu8cMEU7OLNbtSN+c3LmpfMdY9jS8AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;02 001 18&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/305473c5ef43ec665cf2c7dc4f67450a/d9199/02-001-18.png&quot;
        srcset=&quot;/devHistoryBlog/static/305473c5ef43ec665cf2c7dc4f67450a/8ff5a/02-001-18.png 240w,
/devHistoryBlog/static/305473c5ef43ec665cf2c7dc4f67450a/e85cb/02-001-18.png 480w,
/devHistoryBlog/static/305473c5ef43ec665cf2c7dc4f67450a/d9199/02-001-18.png 960w,
/devHistoryBlog/static/305473c5ef43ec665cf2c7dc4f67450a/07a9c/02-001-18.png 1440w,
/devHistoryBlog/static/305473c5ef43ec665cf2c7dc4f67450a/29114/02-001-18.png 1920w,
/devHistoryBlog/static/305473c5ef43ec665cf2c7dc4f67450a/94cea/02-001-18.png 1940w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;파드가 네임스페이스에 들어올 수 있는지 체크&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;설정값&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;min: 최소 메모리값&lt;/li&gt;
&lt;li&gt;max: 해당 네임스페이스로 들어올 수 있는 파드의 최대 메모리 값&lt;br&gt;
-&gt; Pod1의 경우 limit memory값이 5Gi이므로 생성이 불가능한다.&lt;/li&gt;
&lt;li&gt;maxLimitRequestRatio: request값과 limit값의 최대 비율&lt;br&gt;
-&gt; Pod2의 경우 reuqest와 limit의 비율이 3을 넘어가므로 생성이 불가능한다.&lt;/li&gt;
&lt;li&gt;defaultRequest/ default: 스펙이 없는 pod가 들어올 경우 해당 값으로 세팅이 된다.&lt;br&gt;
-&gt; Pod3의 경우 스펙이 없으므로 default 스펙을 따라간다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[[K8S] ingress 인증서 교체]]></title><link>https://ssongey.github.io/works/posts/2022-01-27--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2022-01-27--001</guid><pubDate>Thu, 27 Jan 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; ■ 도메인에 적용되어 있는 인증서 확인 방법 &lt;/span&gt;
&lt;span class=&quot;title__sub2&quot;&gt; 1. openssl로 인증서 확인 &lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;$ openssl s_client -showcerts -connect &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;ip&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;:443 -servername &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;domain-name&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; 2. pem 인증서 디코딩 사이트에서 확인 &lt;/span&gt;
&lt;a href=&quot;https://www.sslcert.co.kr/tools/certificate-crt-decoder&quot;&gt;https://www.sslcert.co.kr/tools/certificate-crt-decoder&lt;/a&gt;&lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; ■ 인증서 교체 &lt;/span&gt;  &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;인증서는 secret에 넣어 ingress 리소스 파일에 tls secret name을 매핑하는 방식을 사용했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; 1. 인증서 다운로드 및 key 파일 암호화 풀기 &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;인증서 갱신 또는 재발급 후 인증서/키파일 다운로드&lt;/li&gt;
&lt;li&gt;키파일이 암호화가 걸려있을 경우 복호화&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;$ openssl rsa -in &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;key파일&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; -out &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;output 파일명&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
Enter pass phrase &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;key파일&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt; pass phrase 입력
writing RSA key&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; 2. secret 생성 &lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# secret 생성&lt;/span&gt;
$ kb create secret tls &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;secret-name&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; --key &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;key파일&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; --cert &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;pem파일&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; -n &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;namespace&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# yaml 파일 생성&lt;/span&gt;
$ kb create secret tls &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;secret-name&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; --key &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;key파일&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; --cert &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;pem파일&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; -n &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;namespace&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; --dry-run&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;client -o yaml &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; secret.yaml&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; 3. secret 확인 &lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;$ kb get secret -n dev

NAME                       TYPE                                  DATA   AGE
secret-name                kubernetes.io/tls                     &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;      7d20h&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; 4. ingress resource 수정 후 적용 &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;■ ingress resource에서 secretName 수정 후 적용&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
spec:
  tls:
  - hosts:
    - example.foo.com
    secretName: &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;secret-name&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;■ ingress 적용&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;$ kb apply -f ingress.yaml&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;■ 인그레스 목록 확인&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;$ kb get ing -n dev

NAME           CLASS    HOSTS                       ADDRESS         PORTS     AGE
ingress-name   &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;none&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;   onepass-app.dev.kakaoi.ai   &lt;span class=&quot;token number&quot;&gt;10.183&lt;/span&gt;.xx.xx    &lt;span class=&quot;token number&quot;&gt;80&lt;/span&gt;, &lt;span class=&quot;token number&quot;&gt;443&lt;/span&gt;   7d19h&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;■ ingress 상세 내용 확인 &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;$ kb describe ing &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;ingress-name&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; -n &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;namespace&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

Name:             ingress-name
Namespace:        namespace
Address:          &lt;span class=&quot;token number&quot;&gt;10.183&lt;/span&gt;.xx.xx
Default backend:  default-http-backend:80 &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;error: endpoints &lt;span class=&quot;token string&quot;&gt;&quot;default-http-backend&quot;&lt;/span&gt; not found&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
TLS:
  wild-dev-kakaoi-ai terminates onepass-app.dev.kakaoi.ai
Rules:
  Host                       Path  Backends
  ----                       ----  --------
  onepass-app.dev.kakaoi.ai  
                             /   fifi-app:80 &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;192.168&lt;/span&gt;.46.228:8080&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;h4&gt;참고&lt;/h4&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/kubernetes/ingress-nginx/blob/main/docs/troubleshooting.md&quot;&gt;ingress troubleshooting&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[[Subject] title]]></title><link>https://ssongey.github.io/subject/posts/2022-01-01--001</link><guid isPermaLink="false">https://ssongey.github.io/subject/posts/2022-01-01--001</guid><pubDate>Sat, 01 Jan 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; ■ 제목입니당 &lt;/span&gt;
&lt;span class=&quot;title__sub2&quot;&gt; ■ 서브제목입니당 &lt;/span&gt;
&lt;span class=&quot;title__sub3&quot;&gt; ■ 서브제목2입니당 &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;This is &lt;span class=&quot;text-mark__green&quot;&gt;green color text&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;This is &lt;span class=&quot;text-mark__red&quot;&gt;red color text&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;This is &lt;span class=&quot;text-mark__blue&quot;&gt;blue color text&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;안녕&lt;/h1&gt;
&lt;h2&gt;안녕&lt;/h2&gt;
&lt;h3&gt;안녕&lt;/h3&gt;
&lt;h4&gt;안녕&lt;/h4&gt;
&lt;h5&gt;안녕&lt;/h5&gt;
&lt;p&gt;이미지
&lt;img src=&quot;./001-01.PNG&quot;&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;diff&quot;&gt;&lt;pre class=&quot;language-diff&quot;&gt;&lt;code class=&quot;language-diff&quot;&gt;&lt;span class=&quot;token deleted-sign deleted&quot;&gt;&lt;span class=&quot;token prefix deleted&quot;&gt;-&lt;/span&gt; hello
&lt;/span&gt;&lt;span class=&quot;token inserted-sign inserted&quot;&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt; green
&lt;/span&gt;&lt;span class=&quot;token diff bold&quot;&gt;&lt;span class=&quot;token prefix diff&quot;&gt;!&lt;/span&gt; orange
&lt;/span&gt;# gray&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[레디스 동시성 이슈]]></title><link>https://ssongey.github.io/works/posts/2021-12-05--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2021-12-05--001</guid><pubDate>Sun, 05 Dec 2021 00:00:00 GMT</pubDate><content:encoded>&lt;br/&gt;
&lt;p&gt;이번에 진행하게된 프로젝트에서 레디스 동시성 이슈에 대한 문제에 부딪혔다.&lt;br&gt;
기존에는 어떤 방식을 사용했고, 어떻게 수정을 했는지에 대해 기록한다.&lt;/p&gt;
&lt;br/&gt;
&lt;h2&gt;✔️ 이슈내용&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;레디스에 넣은 key 값이 expired 되었을 경우 특정 로직을 수행하는 기능이 있다.&lt;/li&gt;
&lt;li&gt;만료된 키에 대한 이벤트는 Keyspace notifications 을 이용하였고, 이 이벤트는 레디스의 Pub/Sub으로 이벤트를 이용하게 된다.&lt;/li&gt;
&lt;li&gt;즉, 서버에서 &lt;em&gt;`__keyevent@&lt;/em&gt;__:expired`* 를 구독하고 있다가, 레디스 내의 키가 expired 가 되면, 서버에서 이벤트를 받아 처리하는 구조이다.&lt;/li&gt;
&lt;li&gt;여기서 문제가 발생하는데, 서버가 1대 일 경우에는 문제가 없지만, &lt;strong&gt;여러대의 서버일 경우에 모든 서버가 이벤트를 받아 처리하므로 중복처리가 발생&lt;/strong&gt;하게 된다.&lt;/li&gt;
&lt;li&gt;만약 expired 가 발생할 경우 알람이 발생하도록 로직이 구현되어 있다면, 서버 대수만큼 알람이 발생하게 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;h2&gt;✔️ 기존방식&lt;/h2&gt;
&lt;p&gt;기존에는 아래와 같은 로직으로 되어 있었다.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/04d8a6c46e37deb9da362b94090707b6/ebf47/001-1.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 688px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 197.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAoCAYAAAD+MdrbAAAACXBIWXMAABYlAAAWJQFJUiTwAAADqklEQVRIx6VXaXPaSBTk//+r1NY6W9nEZWLj2FwOQqATIXTP6Oj0GwROsvsBKaqa0sGo9d50v37DRKkaZugGqqhQlwqN0mgqzfvy/Pwy54YxuYLlJdooQuK6OFgWou0WTXSETtJBoO+AaQ4kCQ5hCGe3g+s4aNIU+niCqtuBgD1odUoJmsJ/26AKQtSndGTKHFoGX247wPMCZFyCpoV5PhhQXipIQkJSCoJ+/PQZIVPN+TwnSYMABawk2JapBpXCjus4Xa5gHY+ItMZ3Ps/5u74x9YlMzBiFnxdA2+L7eo3l66s5qyxDQOmk/L2+GVDSYgS7LMeG7L6uV1i8vWHO8bpcwmLEGX+/GfBy4RHQYzQHXq/9AE6aIaTA95RTWdU3k3MFbBhBwzPIrOd4KAjUUX/NGNlciBGWhdnp0zOCKGaqZ/b1UMCKQ1KTlH2Ou+lX2KcTgrIy7JcDQN9ZLkuEvo/lYoE9yVmvVghY195glntAr5dNQaks5nOkZBddNxzwPeXMvCziNiyLBk3K2aB1/IWUU196272LMD7rbxQpV3Pg6Cibj3f/MOUMbdONM4erFglwpCk8P3+D74fmXo0FrCnigB4Y0mDliOMYruufo/8/QuTZ7+PCsoBFFHIizP50FEXBjxxQcR0lWq1bM1d8UomtiWdK7+HZ3BPLRLjfO3h8fCRoBIv9RKJ0pbccDljSIByWYsI1TSn+NCsQMvKa/aah+BPH5Tkx/Uea3CQn+mz2jIeHBwM6nU5xf3+Pp6cncz2bzfDy8oLNZgvb3mGz3eHfD3+hZr9RqsIj5zQNPYAyU2wZE0nhcDjyBcukmHKigJ/4dXlBIpYI5ZC5MkQJ9TE2UXYsTTlr3l9JkfXJmIrn+SyOjgXTmrOkHlOPvDXreCHEXEsn5KiEjP76J5a1+bKAynoqpQz4iSnUdfcL2CAd1v1X5vOFAfsjHV5SERDRX06z0APN9T+ASp9r2rJsCPum+Y8FFKuvVYOOEa7YRrO+luX5KHNw2aQcDmlMH758gR2faLoVdrS1Ug1oUqaNluc2qpoGe7p2RA36rJpSK9h5Ps6xpZfIYW82cGwb7n4PMoSwqti8Rji2zdRcMnskiPTkgEACtmEljHbsSxtdW1uzWfpzx6awZTsnRiBVM3o7dzXMWGwoxsPfd0hYgmbDOQqw3xJ39LW6ZunRrqSewV6t+IHhW+L+H0BziBgVJbN+g2YLaMWSKPDhm/YrqIKmfFpZT35A5cP/VvwAqqUfMXr1shEAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 1&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/04d8a6c46e37deb9da362b94090707b6/ebf47/001-1.png&quot;
        srcset=&quot;/devHistoryBlog/static/04d8a6c46e37deb9da362b94090707b6/8ff5a/001-1.png 240w,
/devHistoryBlog/static/04d8a6c46e37deb9da362b94090707b6/e85cb/001-1.png 480w,
/devHistoryBlog/static/04d8a6c46e37deb9da362b94090707b6/ebf47/001-1.png 688w&quot;
        sizes=&quot;(max-width: 688px) 100vw, 688px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;아직까지는 큰 문제는 없었다고 하지만, 만약 아래와 같은 상황이 발생한다면 장애로 이어지게 된다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;한 host에서 2개 이상의 pod가 뜬다면&lt;/li&gt;
&lt;li&gt;deployment 의 replica 감소 등으로 레디스에 등록된 서버가 죽는다면&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;h2&gt;✔️ 수정된 방식&lt;/h2&gt;
&lt;p&gt;찾아보니 레디스에서 &lt;code class=&quot;language-text&quot;&gt;setnx&lt;/code&gt; 명령어를 활용하는 방법이 현재 상황에 가장 알맞아 보였다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Redis의 setnx 명령어는 key값이 존재하지 않으면 데이터를 set하는 atomic한 명령어이다. &lt;/li&gt;
&lt;li&gt;이 명령어를 활용하여 개발자가 직접 Lock 프로세스를 구현할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;보통은 spin lock 으로 구현을 하는데 (lock 점유를 루프로 시도), 현재 나의 경우는 점유가 되어 있으면 skip 을 하면 되기 때문에 레디스 부하없이 쉽게 해결이 가능했다.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/ba3e60e94d470fdd45e17e2263eb6494/5fd3e/001-2.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 594px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 202.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAApCAYAAAA1bQl+AAAACXBIWXMAABYlAAAWJQFJUiTwAAAD+ElEQVRIx51WyZLbNhTU/3+MnYOTSm6xneSWsTOrFmskitTCVSQlbgCpTj+IVM1UchDEqlcEQaL5ln4NjJpGw5hqzb0uazSD1QqN7nD55gobXcAOBXQYoktTtElC26MNI6jsYAU6Ml6oDmrnA12H+XIJ1/Pw9PKCpirREbS29pAeqH2GLo5R07uD76MIAugohqKn8kM7wCHsomLoR8xfJtDHEo1Yn1trQCUmuSLAer2Fbk9mrCzALoCyqGIui6pBUTb4/fNXZCxSyTkx1Vzv5Ujz44wUmaYZgkZhVxPw7zt4xyN8Pi/zA7YEb+ntNcUZyYdpVWNHAGc+x3Q6QcCiOKz2fDZDUddwmdf2ylyOND/c08OwLFEeDgbs7u7O3KuiQK013Pxo56EAelx8AlDqFj6pU7YtNJ8zpbAiua8GlIJI4l0uGuzbbA6PXpln5vDAYqlrQx6q3HFBR9qIJ97Kw6kfd9JFNlUeBnVvwr1v3+9R0+vL3C3EFmtJ5gMp8vHjTwjDWFr7/DMBl54fxvK9EJ9R1JIKaYheQM4hc1JzIggiWgC5Yvb1joIh704noxvmh3JJOuqYakQ6oayoSDmafWrkbiQLSlZ5tXKx3+8NkNyjKEKWZXBdD563wXbr890eL+MpnPsHQUfOnzuTMVpymKFBUUwugMulYwDW6zXDDendDnmew3FWHAfGe98PMZ7MsPz+j/E0pXZOJhO04j4bQFHq3oUsC0NOnk6d8XSz2Zq8DOG2/MaELJwkeBsnRM0NUBMl55DfFkUWZuTe4+MT/54bEPnZUJB3RemV6cyM7vI8+r/Su+7aWgf/Q+y2J3bDrlgxbyXFtZMwLTXRtJ64HVOtE5rcP3z6BdskNT0uz4XRxCsBxYOEXBqzYjErFVNdVhSHsGkQ0UQXHea1s1ObCilVRbj1/PgIl1q4ohWkkVwiEFfrofGQYflVRT508EnWhMTe0+OaHtcsvcNOuFq+RGBlCxizdTbUxC3V+1U4yB+sixILerexUeyhyrqXKOHZbPoDb3dDrW6QL9MtPUU23EalK2zB3gEeyT9R5pzh//zrb4jYKUd6K3NWR5FhkxLa+NyofG6j968L3rkTMo8OVcS7ZZMSDsqVsCA56eIsFtQ99jfnhk3KwsMKUQ+45slru9lg8fpKEIX2DaCVhxOGHDLESGnsSJ+EJA9IIZedYkXsYZD3BUlJ8ieKqHBTLLctyjDQPUVUf/oatPBm2lzO2PTo65c/UFC+1Jv5G87YR+iAss6N5uHPvyjxPs/YIRrZ0aw7RfdnbF4VqfLw/ExSn6uu/eAGQFlgztgJNM/UqetCkY8ddfF8xm5vzGF/rm5ZXSVjniJsc/gvBzxtIbfp/6YAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 2&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/ba3e60e94d470fdd45e17e2263eb6494/5fd3e/001-2.png&quot;
        srcset=&quot;/devHistoryBlog/static/ba3e60e94d470fdd45e17e2263eb6494/8ff5a/001-2.png 240w,
/devHistoryBlog/static/ba3e60e94d470fdd45e17e2263eb6494/e85cb/001-2.png 480w,
/devHistoryBlog/static/ba3e60e94d470fdd45e17e2263eb6494/5fd3e/001-2.png 594w&quot;
        sizes=&quot;(max-width: 594px) 100vw, 594px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;코드는 아래와 같다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;kotlin&quot;&gt;&lt;pre class=&quot;language-kotlin&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;doHandleMessage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;message&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Message&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; key &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;message&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;lock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;key&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token comment&quot;&gt;// 로직 수행&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;finally&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token function&quot;&gt;unlock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;key&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;lock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;key&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; String&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Boolean &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; redisTemplate&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;opsForValue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setIfAbsent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;key&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;lock&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;unlock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;key&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; String&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; redisTemplate&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;delete&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;key&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;p&gt;참고로, 스핀락을 구현해야하는 상황이면 Lettuce 라이브러리보단 Redisson 라이브러리를 사용하는게 더 낫다..!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[[작업로그] CURL 을 이용하여 API 속도 체크]]></title><description><![CDATA[CURL -w option format]]></description><link>https://ssongey.github.io/works/posts/2021-09-24--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2021-09-24--001</guid><pubDate>Fri, 24 Sep 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;타 서비스 이용중에 API 타임아웃이 빈번하게 발생하여 해당 API 에 대한 응답 소요시간을 CURL 을 이용하여 체크하게 되었다.&lt;br&gt;
서버 연결 소요시간 및 응답 소요시간을 각각 측정하는 옵션을 사용했다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;$ curl -sS -w &amp;quot; \
time_connect: %{time_connect} \
time_appconnect: %{time_appconnect} \
time_pretransfer: %{time_pretransfer} \
time_starttransfer: %{time_starttransfer} \
total_time: %{time_total}\n&amp;quot; \
-k -X POST https://test.com -o /dev/null&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt;&lt;span class=&quot;text-mark__green&quot;&gt;time_connect&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;tcp 연결하는데 걸리는 시간&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt;&lt;span class=&quot;text-mark__green&quot;&gt;time_appconnect&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ssl handshake 소요 시간&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt;&lt;span class=&quot;text-mark__green&quot;&gt;time_pretransfer&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;HTTP인지 HTTPS인지에 따라 time&lt;em&gt;connect 또는 time&lt;/em&gt;appconnect와 거의 동일&lt;/li&gt;
&lt;li&gt;이 값의 유일한 목적은 서버가 바이트 전송을 시작하는데 걸린 시간을 계산하기 위함이다&lt;/li&gt;
&lt;li&gt;TTFB를 위한 준비단계로 보면 된다&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt;&lt;span class=&quot;text-mark__green&quot;&gt;time_starttransfer&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;서버가 응답을 준비하는데 걸린시간&lt;/li&gt;
&lt;li&gt;TTFB(Time To First Byte)&lt;/li&gt;
&lt;li&gt;클라이언트가 처음으로 byte를 받은 시간이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
순서대로 curl이 시작된 이후 &lt;span class=&quot;text-mark__red&quot;&gt;누적&lt;/span&gt;이 된다.&lt;br/&gt;
따라서 &lt;span class=&quot;text-mark__red&quot;&gt;time_starttransfer - time_pretransfer&lt;/span&gt; 값이 실제 서버 처리 시간으로 볼 수 있다.
&lt;p&gt;참고&lt;br&gt;
&lt;a href=&quot;https://speedtestdemon.com/a-guide-to-curls-performance-metrics-how-to-analyze-a-speed-test-result/&quot;&gt;https://speedtestdemon.com/a-guide-to-curls-performance-metrics-how-to-analyze-a-speed-test-result/&lt;/a&gt; &lt;br/&gt;
&lt;a href=&quot;https://yfkwon.tistory.com/42#recentEntries&quot;&gt;https://yfkwon.tistory.com/42#recentEntries&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[[작업로그] ObjectMapper로 String to Object 는 불가하다]]></title><link>https://ssongey.github.io/works/posts/2021-08-24--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2021-08-24--001</guid><pubDate>Tue, 24 Aug 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;이번에 RestTemplate 세팅을 하면서 req/res 로깅을 하도록 구성을 했다.&lt;br&gt;
req/res 의 경우 당연히 Object(Null 포함)라 생각했기 때문에
ObjectMapper 클래스의 &lt;span class=&quot;text-mark__red&quot;&gt;readValue 메소드&lt;/span&gt;를 이용하여&lt;br&gt;
map 객체로 변환하였다.&lt;/p&gt;
&lt;p&gt;테스트에서는 별 문제 없이 잘 작동하는 듯 하였으나…&lt;br&gt;
&lt;span class=&quot;text-mark__red&quot;&gt;응답값이 Json 포맷의 문자열이 아닐 경우&lt;/span&gt; 즉, 일반 문자열 일 경우, 오브젝트로 변환 시 아래와 같은 오류가 발생하였다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;com.fasterxml.jackson.core.JsonParseException: Unrecognized token &amp;#39;hello&amp;#39;: was expecting (JSON String, Number, Array, Object or token &amp;#39;null&amp;#39;, &amp;#39;true&amp;#39; or &amp;#39;false&amp;#39;)
 at [Source: (byte[])&amp;quot;hello world&amp;quot;; line: 1, column: 7]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;그래서 아래와 같이 테스트를 진행해봤다.
&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt;case1) readValue 메소드를 이용하여 string to object&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;val stringData &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;hello world&quot;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    objectMapper&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;readValue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;stringData&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toByteArray&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;java&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;success 1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;error1 [stringData] : &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;message&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;//에러 발생!!!&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;1번 케이스의 경우 에러가 발생했다.&lt;br&gt;
readValue 메소드 내의 코드를 보니 JsonParser를 생성하는걸로 봐선 Json 포맷만 가능한걸로 보인다.&lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt;case2) writeValueAsString 메소드를 이용하여 object to string&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;val stringData &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;hello world&quot;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    objectMapper&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;writeValueAsString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;stringData&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;success 2&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;//성공!!!&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;error2 [stringData] : &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;message&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;2번 케이스의 경우는 에러가 발생하지 않았다.&lt;br&gt;
writeValueAsString 메소드에서는 param으로 받은 object를 serialize 하여 이를 문자열로 반환하기 때문에 정상적으로 작동한 것으로 보인다.&lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt;&lt;span class=&quot;text-mark__blue&quot;&gt;결론적으로,&lt;/span&gt;&lt;/span&gt;&lt;br&gt;
req의 경우에는 모두 DTO 클래스로 정의를 했기 때문에 readValue 메소드를 이용하여 map 객체로 변환하였고,&lt;br&gt;
res의 경우에는 DTO 클래스 또는 string 객체로 정의 했기 때문에 &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;kotlin&quot;&gt;&lt;pre class=&quot;language-kotlin&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;&lt;span class=&quot;token function&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;it&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; StandardCharsets&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;UTF_8&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;을 이용하여 String 객체로 로깅하였다.&lt;/p&gt;
&lt;p&gt;그런데 생각해보니.. ES를 이용하여 로깅수집을 하고 있기 때문에 type 검사 후에 string 또는 map 으로 변환하는게 가장 좋을 듯 싶다.&lt;br&gt;
추후에 다시 수정해야겠다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[따라하며 배우는 MySQL on Docker 실습]]></title><link>https://ssongey.github.io/history/posts/2021-05-16--001</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2021-05-16--001</guid><pubDate>Sun, 16 May 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; # Summary &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Docker 환경에서 MySQL Master-Replication 구성&lt;/li&gt;
&lt;li&gt;Orchestrator를 이용한 HA 구성&lt;/li&gt;
&lt;li&gt;ProxySQL을 이용한 Proxy Layer 구성&lt;/li&gt;
&lt;li&gt;Prometheus와 Grafana를 이용한 모니터링 구성&lt;/li&gt;
&lt;li&gt;Docker compose를 통한 일괄 서비스 배포&lt;/li&gt;
&lt;li&gt;Swarm Mode를 통한 확장 가능한 구성&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; # Master, Slave Replication 구성 &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/fb12e6a568e1d0468940c55ef0e7661b/ae2f8/001.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 50.83333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABYlAAAWJQFJUiTwAAACGUlEQVQoz4VSW28SQRTe/6Ox2mKRe0EpC7vsdfbCglwWaKENsRZSmrTGBDU+qC8+qVGbJmrir/z8ZoKPxoeTPXP2zDnfZbTx2Rrzi2sE4xOkZxcYLJaYnl9itrrC5PkaVn8KbzRDruUjc2jjYcP5Z+zrLjSzN4E7PMZh2EcrSdGIBjD4NbtjnkeoODFqXoJs0/3vQBmabD5wOrhT0bFTM4lE8LLHbZ7aWDB95AzBesA8RKEtI0DJClG2QxSZF7c1hVCkc1xu3uLj528YP1sRhcGLHps81bRT9fCoZaMe2KqeZ+QMn8td3K3IpT7/eyjZkQKitUn5dH3NgV9xRO3qokuKHdyvWQgmMW5+DvDlVqcULS5z8eBJm1LE2Lzv4+qNRZQm7lXbXERmEqGculu3kCH/vBkgmi5gcUnJ6kCPHbz+MMfmXQR30INIT1GxuzB7Nr7/WODTjQtvKNDuzaBHfSL1oZXtGAduooYppxhSE2nCbl0aEZFeSHMStOKhMqhgRqQakoXAY78PwVcgDa3yn1a0ZHOHTduBNKBIPWReIA1JP6vb2CeTvBVhj2wkEjk4b1BD6pc1AuZCgdCOzlf49fsW8+USObroujEcwi8R+V8H5QJL9OD7XVQZqsYo8UnZPIvwKcoEpZ5NPDnGi1cv0YwSVEg9bTro+AlyRJ6R2jKyvDzkwLRhQSe1vW29wP4hh474tOqUQ9b/AC6phmvy+G8pAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/fb12e6a568e1d0468940c55ef0e7661b/d9199/001.png&quot;
        srcset=&quot;/devHistoryBlog/static/fb12e6a568e1d0468940c55ef0e7661b/8ff5a/001.png 240w,
/devHistoryBlog/static/fb12e6a568e1d0468940c55ef0e7661b/e85cb/001.png 480w,
/devHistoryBlog/static/fb12e6a568e1d0468940c55ef0e7661b/d9199/001.png 960w,
/devHistoryBlog/static/fb12e6a568e1d0468940c55ef0e7661b/07a9c/001.png 1440w,
/devHistoryBlog/static/fb12e6a568e1d0468940c55ef0e7661b/29114/001.png 1920w,
/devHistoryBlog/static/fb12e6a568e1d0468940c55ef0e7661b/ae2f8/001.png 2496w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; Volume 디렉토리 생성 &lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;mkdir -p /db/db001/data /db/db002/data /db/db/003/data \
mkdir -p /db/db001/log /db/db002/log /db/db003/log \
mkdir -p /db/db001/conf /db/db002/conf /db/db003/conf

chmod 777 -R /db&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; my.cnf 설정 &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;my.cnf 의 permission은 644로 수정&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;title__sub3&quot;&gt; 1. db001 설정 &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;master 설정&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;#my.cnf&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;mysqld&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
log_bin                     &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; mysql-bin
binlog_format               &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ROW
gtid_mode                   &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ON
enforce-gtid-consistency    &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
server-id                   &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;
log_slave_updates
datadir                     &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; /var/lib/mysql
socket                      &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; /var/lib/mysql/mysql.sock

&lt;span class=&quot;token comment&quot;&gt;# Disabling symbolic-links is recommended to prevent assorted security risks&lt;/span&gt;
symbolic-links              &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;

log-error                   &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; /var/log/mysql/mysqld.log
pid-file                    &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; /var/run/mysqld/mysqld.pid

report_host                 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; db001

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;mysqld_safe&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
pid-file                    &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; /var/run/mysqld/mysqld.pid
socket                      &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; /var/lib/mysql/mysql.sock
&lt;span class=&quot;token function&quot;&gt;nice&lt;/span&gt;                        &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&quot;title__sub3&quot;&gt; 2. db002 설정 &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;slave 설정, read_only 값 추가&lt;/li&gt;
&lt;li&gt;server-id, report_host 유일값으로 수정&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;#my.cnf&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;mysqld&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
log_bin                     &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; mysql-bin
binlog_format               &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ROW
gtid_mode                   &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ON
enforce-gtid-consistency    &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
server-id                   &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt; 
log_slave_updates
datadir                     &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; /var/lib/mysql
socket                      &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; /var/lib/mysql/mysql.sock
read_only

&lt;span class=&quot;token comment&quot;&gt;# Disabling symbolic-links is recommended to prevent assorted security risks&lt;/span&gt;
symbolic-links              &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;

log-error                   &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; /var/log/mysql/mysqld.log
pid-file                    &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; /var/run/mysqld/mysqld.pid

report_host                 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; db002

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;mysqld_safe&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
pid-file                    &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; /var/run/mysqld/mysqld.pid
socket                      &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; /var/lib/mysql/mysql.sock
&lt;span class=&quot;token function&quot;&gt;nice&lt;/span&gt;                        &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;db003 설정&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;slave 설정, read_only 값 추가&lt;/li&gt;
&lt;li&gt;server-id, report_host 유일값으로 수정&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;#my.cnf&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;mysqld&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
log_bin                     &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; mysql-bin
binlog_format               &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ROW
gtid_mode                   &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ON
enforce-gtid-consistency    &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
server-id                   &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;300&lt;/span&gt;
log_slave_updates
datadir                     &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; /var/lib/mysql
socket                      &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; /var/lib/mysql/mysql.sock
read_only

&lt;span class=&quot;token comment&quot;&gt;# Disabling symbolic-links is recommended to prevent assorted security risks&lt;/span&gt;
symbolic-links              &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;

log-error                   &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; /var/log/mysql/mysqld.log
pid-file                    &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; /var/run/mysqld/mysqld.pid

report_host                 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; db003

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;mysqld_safe&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
pid-file                    &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; /var/run/mysqld/mysqld.pid
socket                      &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; /var/lib/mysql/mysql.sock
&lt;span class=&quot;token function&quot;&gt;nice&lt;/span&gt;                        &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Container 생성&lt;/h2&gt;
&lt;h2&gt;Bridge Network 구성&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;container 의 network alias를 사용하기 위해 bridge network를 구성한다.&lt;/li&gt;
&lt;li&gt;container가 재시작되어 Ip가 변경되더라도 문제가 발생하지 않는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;docker network create --driver bridge db-bridge&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Master Container 생성&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;docker run -i -t --name db001 -p &lt;span class=&quot;token number&quot;&gt;13306&lt;/span&gt;:3306 &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
--net db-bridge --net-alias&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;db001 &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
-v /db/db001/data:/var/lib/mysql &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
-v /db/db001/log:/var/log/mysql &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
-v /db/db001/conf:/etc/percona-server.conf.d &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
-e &lt;span class=&quot;token assign-left variable&quot;&gt;MYSQL_ROOT_PASSWORD&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;root&quot;&lt;/span&gt; -d percona:5.7.30&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Slave Containers 생성&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;docker run -i -t --name db002 -p &lt;span class=&quot;token number&quot;&gt;13307&lt;/span&gt;:3306 &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
--net db-bridge --net-alias&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;db001 &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
-v /db/db002/data:/var/lib/mysql &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
-v /db/db002/log:/var/log/mysql &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
-v /db/db002/conf:/etc/percona-server.conf.d &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
-e &lt;span class=&quot;token assign-left variable&quot;&gt;MYSQL_ROOT_PASSWORD&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;root&quot;&lt;/span&gt; -d percona:5.7.30

docker run -i -t --name db003 -p &lt;span class=&quot;token number&quot;&gt;13308&lt;/span&gt;:3306 &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
--net db-bridge --net-alias&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;db001 &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
-v /db/db003/data:/var/lib/mysql &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
-v /db/db003/log:/var/log/mysql &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
-v /db/db003/conf:/etc/percona-server.conf.d &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
-e &lt;span class=&quot;token assign-left variable&quot;&gt;MYSQL_ROOT_PASSWORD&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;root&quot;&lt;/span&gt; -d percona:5.7.30&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Container 생성 확인&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;docker &lt;span class=&quot;token function&quot;&gt;ps&lt;/span&gt; --format &lt;span class=&quot;token string&quot;&gt;&quot;table {{.ID}}&lt;span class=&quot;token entity&quot; title=&quot;\t&quot;&gt;\t&lt;/span&gt;{{.Names}}&lt;span class=&quot;token entity&quot; title=&quot;\t&quot;&gt;\t&lt;/span&gt;{{.Status}}&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Replication 설정&lt;/h2&gt;
&lt;h3&gt;Replication user 생성(db001)&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;docker &lt;span class=&quot;token builtin class-name&quot;&gt;exec&lt;/span&gt; -it -uroot db001 &lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt;
mysql -uroot -p

mysql&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; create user &lt;span class=&quot;token string&quot;&gt;&apos;repl&apos;&lt;/span&gt;@&lt;span class=&quot;token string&quot;&gt;&apos;%&apos;&lt;/span&gt; identified by &lt;span class=&quot;token string&quot;&gt;&apos;repl&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
mysql&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; grant replication slave on *.* to &lt;span class=&quot;token string&quot;&gt;&apos;repl&apos;&lt;/span&gt;@&lt;span class=&quot;token string&quot;&gt;&apos;%&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Replication 설정(db002, db003)&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;docker &lt;span class=&quot;token builtin class-name&quot;&gt;exec&lt;/span&gt; -it -uroot db002 &lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt;
mysql -uroot -p
mysql&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; change master to &lt;span class=&quot;token assign-left variable&quot;&gt;master_host&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;db001&apos;&lt;/span&gt;, &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
        &lt;span class=&quot;token assign-left variable&quot;&gt;master_user&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;repl&apos;&lt;/span&gt;, &lt;span class=&quot;token assign-left variable&quot;&gt;master_password&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;repl&apos;&lt;/span&gt;, &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
        &lt;span class=&quot;token assign-left variable&quot;&gt;master_auto_position&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
mysql&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; start slave&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
mysql&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; show status&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;G&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1&gt;Orchestrator를 이용한 HA 구성&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;master 가 장애가 났을 경우, 자동으로 failover가 되도록 구성&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Orchestrator Container 실행&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;docker run -i -t --name orchestroator -h orchestrator &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
--net db-bridge --net-alias&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;orchestrator
-p &lt;span class=&quot;token number&quot;&gt;13000&lt;/span&gt;:3000 -d openarkcode/orchestrator:latest&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Orchestrator를 위한 mysql user 생성&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;orchestroator 를 위한 mysql user를 생성하는데, &lt;/li&gt;
&lt;li&gt;db container의 IP대역 확인하여 user의 host로 사용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;docker inspect --format &lt;span class=&quot;token string&quot;&gt;&apos;{{.NetworkSettings.Networks.db-bridge.IPAddress}}&apos;&lt;/span&gt; db001

&lt;span class=&quot;token number&quot;&gt;172.18&lt;/span&gt;.0.2&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;db001에서 mysql user생성&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;docker &lt;span class=&quot;token builtin class-name&quot;&gt;exec&lt;/span&gt; -it -uroot db001 /bin/bash
mysql -uroot -p

mysql&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; create user orc_client_user@&lt;span class=&quot;token string&quot;&gt;&apos;172.%&apos;&lt;/span&gt; identified by &lt;span class=&quot;token string&quot;&gt;&apos;orc_client_password&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
mysql&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; grant super, process, replication slave, reload on *.* to orc_client_user@&lt;span class=&quot;token string&quot;&gt;&apos;172.%&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
mysql&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; grant &lt;span class=&quot;token keyword&quot;&gt;select&lt;/span&gt; on mysql.slave_master_info to orc_client_user@&lt;span class=&quot;token string&quot;&gt;&apos;172.%&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;HA 구성&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://%7Bdocker_host_ip%7D:13000/web/clusters&quot;&gt;http://{docker_host_ip}:13000/web/clusters&lt;/a&gt; 접속&lt;/li&gt;
&lt;li&gt;Clusters &gt; Discover 에서 instance 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;db001, 3306 입력 후 submit&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Cluster &gt; Dashboard 에서 확인&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Auto FailOver를 위한 Orchestrator의 설정 변경&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;docker &lt;span class=&quot;token builtin class-name&quot;&gt;exec&lt;/span&gt; -it orchestrator &lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;vi&lt;/span&gt; /etc/orchestrator.conf.json

  &lt;span class=&quot;token string&quot;&gt;&quot;RecoverMasterClusterFilters&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;*&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;,
  &lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;.
  &lt;span class=&quot;token string&quot;&gt;&quot;PromotionIgnoreHostnameFilters&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;db003&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;, //db003 은 승격되지 않는다.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;orchestrator 재시작&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;docker restart orchestrator&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1&gt;ProxySQL을 이용한 Proxy Layer 구성&lt;/h1&gt;
&lt;h2&gt;ProxySQL Container 실행&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;mkdir&lt;/span&gt; -p /db/proxysql/data /db/proxysql/conf
&lt;span class=&quot;token function&quot;&gt;chmod&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;777&lt;/span&gt; /db/proxysql /db/proxysql/data /db/proxysql/conf&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;conf 파일 생성&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;conf 디렉토리에 proxysql.cnf 파일 생성&lt;/li&gt;
&lt;li&gt;파일 permission 은 644&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;#proxysql.cnf&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Container 실행&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;docker run -i -t --name proxysql -h proxysql &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
--net db-bridge --net-alias&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;proxysql &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
-p &lt;span class=&quot;token number&quot;&gt;16032&lt;/span&gt;:6032 -p &lt;span class=&quot;token number&quot;&gt;16033&lt;/span&gt;:6033
-v /db/proxysql/data:/var/lib/proxysql &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
-v /db/proxysql/conf/proxysql.cnf:/etc/proxysql.cnf &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
-d proxysql/proxysql&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;ProxySQL Admin 접속&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;mysql -h127.0.0.1 -p16032 -uradmin -pradmin --prompt &lt;span class=&quot;token string&quot;&gt;&quot;ProxySQL Admin&gt;&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;테스트 환경 구성&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;테스트 데이터베이스 생성&lt;/li&gt;
&lt;li&gt;어플리케이션에서 사용한 유저 생성&lt;/li&gt;
&lt;li&gt;proxysql용 모니터링 user 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;docker &lt;span class=&quot;token builtin class-name&quot;&gt;exec&lt;/span&gt; -it -uroot db001 &lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt;
mysql -uroot -p

mysql&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; create database testdb default character &lt;span class=&quot;token builtin class-name&quot;&gt;set&lt;/span&gt; utf8&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
mysql&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; create user appuser@&lt;span class=&quot;token string&quot;&gt;&apos;%&apos;&lt;/span&gt; identified by &lt;span class=&quot;token string&quot;&gt;&apos;appuser&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
mysql&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; grant select, insert, update, delete on testdb.* to appuser@&lt;span class=&quot;token string&quot;&gt;&apos;%&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
mysql&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; create user &lt;span class=&quot;token string&quot;&gt;&apos;monitor&apos;&lt;/span&gt;@&lt;span class=&quot;token string&quot;&gt;&apos;%&apos;&lt;/span&gt; identified by &lt;span class=&quot;token string&quot;&gt;&apos;monitor&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
mysql&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; grant replication client on *.* to &lt;span class=&quot;token string&quot;&gt;&apos;monitor&apos;&lt;/span&gt;@&lt;span class=&quot;token string&quot;&gt;&apos;%&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
mysql&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; flush privileges&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;proxysql&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;hostgroup에 db서버 정보 입력
— write group : 10, read group : 20&lt;/li&gt;
&lt;li&gt;app user 정보 입력&lt;/li&gt;
&lt;li&gt;쿼리 룰 정보 입력&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;mysql -h127.0.0.1 -P16032 -uradmin -pradmin --prompt &lt;span class=&quot;token string&quot;&gt;&quot;ProxySQL Admin&gt;&quot;&lt;/span&gt;

ProxySQL Admin&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; insert into mysql_servers&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;hostgroup_id, hostname, port&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; values &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&apos;db001&apos;&lt;/span&gt;, &lt;span class=&quot;token number&quot;&gt;3306&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
ProxySQL Admin&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; insert into mysql_servers&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;hostgroup_id, hostname, port&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; values &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&apos;db001&apos;&lt;/span&gt;, &lt;span class=&quot;token number&quot;&gt;3306&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
ProxySQL Admin&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; insert into mysql_servers&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;hostgroup_id, hostname, port&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; values &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&apos;db002&apos;&lt;/span&gt;, &lt;span class=&quot;token number&quot;&gt;3306&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
ProxySQL Admin&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; insert into mysql_servers&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;hostgroup_id, hostname, port&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; values &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&apos;db003&apos;&lt;/span&gt;, &lt;span class=&quot;token number&quot;&gt;3306&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
ProxySQL Admin&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; insert into mysql_replication_hostgroups values &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;, &lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&apos;read_only&apos;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# app &lt;/span&gt;
ProxySQL Admin&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; insert into mysql_users&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;username, password, default_hostgroup, transaction_persistent&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; values &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;appuser&apos;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&apos;apppass&apos;&lt;/span&gt;, &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;, &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

ProxySQL Admin&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; insert into mysql_query_rules&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rule_id, active, match_pattern, destination_hostgroup&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; values &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&apos;^SELECT.*FOR UPDATE$&apos;&lt;/span&gt;, &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
ProxySQL Admin&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; insert into mysql_query_rules&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rule_id, active, match_pattern, destination_hostgroup&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; values &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;, &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&apos;^SELECT&apos;&lt;/span&gt;, &lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;


ProxySQL Admin&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; load mysql servers to runtime&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
ProxySQL Admin&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; save mysql servers to disk&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[[작업로그] Dto to Entity에 대한 고민]]></title><link>https://ssongey.github.io/works/posts/2021-04-20--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2021-04-20--001</guid><pubDate>Tue, 20 Apr 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;요즘 FMS 프로젝트에 대한 리펙터링을 열심히 진행하고 있다.&lt;br&gt;
그 중 가장 초점을 맞추고 있는 작업은 Request/Response 객체로 사용되고 있는 Entity를 Dto로 바꾸는 것이다.&lt;br&gt;
그래서 Dto to Entity, Entity to Dto 의 편리성을 위해 Mapstruct 를 도입하였고, 큰 문제가 없이 수월한 작업을 예상했는데&lt;br&gt;
역시나.. 모든 리펙토링은 많은 고민이 필요하구나를 다시한번 느끼게 된다.  &lt;/p&gt;
&lt;p&gt;오늘 고민한 내용은 다음과 같다.&lt;br&gt;
연관관계(FK)가 많은 Entity를 생성할때 &lt;span class=&quot;text-mark__green&quot;&gt;모든 FK 객체는 어떻게 채울 것인가?&lt;/span&gt;&lt;br&gt;
DTO가 가지고 있는 &lt;span class=&quot;text-mark__green&quot;&gt;각 매핑 ID로 모두 조회&lt;/span&gt;를 해야하나?  &lt;/p&gt;
&lt;br&gt;
&lt;p&gt;일단, 간단하게 프로젝트를 구성하여 테스트를 했다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;생성요청 DTO 클래스에는 customerId (FK) 값이 존재한다.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DTO 클래스 안에 DTO to Entity 메소드가 존재한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Case1) customerId 로 repository에서 select 한 Customer 객체를 추입받는다&lt;/li&gt;
&lt;li&gt;Case2) customerId 필드만 넣어 Customer 객체 생성을 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token annotation punctuation&quot;&gt;@NoArgsConstructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;access &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AccessLevel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;PRIVATE&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ReservationDto&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;token annotation punctuation&quot;&gt;@Getter&lt;/span&gt;
    &lt;span class=&quot;token annotation punctuation&quot;&gt;@NoArgsConstructor&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CreateReq&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Long&lt;/span&gt; customerId&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PassengerType&lt;/span&gt; passengerType&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; usages&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; luggage&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;//case1. customer id로 repository에서 select 한 값을 주입 받아 entity 에 주입&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ReservationPassenger&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;toEntity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Customer&lt;/span&gt; customer&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;ReservationPassenger&lt;/span&gt; reservationPassenger &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ReservationDtoMapper&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;INSTANCE&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toReservationPassengerEntity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            reservationPassenger&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setCustomer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;customer&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; reservationPassenger&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;//Case2. id로 customer id 객체 생성 후 entity 에 주입&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ReservationPassenger&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;toEntity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;Customer&lt;/span&gt; customer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Customer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;customerId&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;token class-name&quot;&gt;ReservationPassenger&lt;/span&gt; reservationPassenger &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ReservationDtoMapper&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;INSTANCE&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toReservationPassengerEntity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            reservationPassenger&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setCustomer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;customer&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; reservationPassenger&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt;case1. customer id로 repository에서 select 한 값을 주입 받아 entity에 주입&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ReservationPassenger&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;toEntity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Customer&lt;/span&gt; customer&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;ReservationPassenger&lt;/span&gt; reservationPassenger &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ReservationDtoMapper&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;INSTANCE&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toReservationPassengerEntity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    reservationPassenger&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setCustomer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;customer&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; reservationPassenger&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 호출 메소드 로직&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;createReservation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;ReservationDto&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;CreateReq&lt;/span&gt; req&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// customer id로 select&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;Customer&lt;/span&gt; customer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; customerRepository&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;findById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getCustomerId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;orElseThrow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;IllegalArgumentException&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;ReservationPassenger&lt;/span&gt; reservationPassenger &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toEntity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;customer&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;ReservationPassenger&lt;/span&gt; saved &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; reservationRepository&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;reservationPassenger&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;그래.. 이게 정석이겠지,&lt;br&gt;
그런데 Entity의 연관관계가 많으면? 저렇게 객체를 가져와서 매핑해야 하나?&lt;br&gt;
실질적으로는 ID만 필요로 할 뿐인데?&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt;case2. customerId 필드만 넣어 Customer 객체 생성을 한 후 entity에 주입&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ReservationPassenger&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;toEntity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Customer&lt;/span&gt; customer&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;Customer&lt;/span&gt; customer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Customer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;customerId&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;ReservationPassenger&lt;/span&gt; reservationPassenger &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ReservationDtoMapper&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;INSTANCE&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toReservationPassengerEntity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    reservationPassenger&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setCustomer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;customer&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; reservationPassenger&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 호출 메소드 로직&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;createReservation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;ReservationDto&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;CreateReq&lt;/span&gt; req&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;ReservationPassenger&lt;/span&gt; reservationPassenger &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toEntity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;ReservationPassenger&lt;/span&gt; saved &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; reservationRepository&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;reservationPassenger&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;헉! DB에는 문제없이 잘 매핑이 된다!&lt;br&gt;
그럼 존재하지 않는 ID를 넣으면 어떻게 되지?&lt;/p&gt;
&lt;br&gt;
&lt;p&gt;오~ 역시&lt;br&gt;
could not execute statement; SQL [n/a]; constraint 오류가 발생한다.&lt;br&gt;
똑똑하구로..  &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: 
Referential integrity constraint violation: &amp;quot;FKT1K88T0M3HKQGVYFI365S5KV8: 
PUBLIC.RESERVATION_PASSENGER FOREIGN KEY(CUSTOMER_ID) REFERENCES PUBLIC.CUSTOMER(ID) (2)&amp;quot;; SQL statement:&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;p&gt;물론 매핑 ID의 검증을 위해 첫번째 방법이 당연하다는건 알지만,&lt;br&gt;
매핑 ID의 검증이 필요 없는 경우는 두번째 방법을 써도 되지 않을까?  &lt;/p&gt;
&lt;p&gt;좀 더 나은 방법이 없는지 더 고민 해봐야 겠다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[넷마스크, 서브넷 마스크, 브로드 캐스트]]></title><link>https://ssongey.github.io/history/posts/2021-03-10--001</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2021-03-10--001</guid><pubDate>Fri, 19 Mar 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; # 넷마스크 (netMask) &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;네트워크 주소 부분의 비트를 1로 치환한 것이 넷마스크이다.&lt;/li&gt;
&lt;li&gt;IP 주소와 넷마스크를 AND연산을 하면 네트워크 주소를 얻을수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/9d02d9980b541e79dc05a7c6d8b66761/51800/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 50%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABJ0AAASdAHeZh94AAABSklEQVQoz2VR2arCQAyd//8fwTctiEifBCkutChobV1qtZvW7dyeYHToDRyyTTJJjsH7DZFGv9Vu5Ha7oa5rPJ/PT/qXezweqKpKdDtnJPAJauL1emEymcB1XQRBgM1mg8PhgPV6jdVqhdPphO02lKawagljd1e53+9wHAedTgf9fh/D4RCe52EwGAiWyyWS4/E7oS1Gf+B61+tVVlXNmO0r2nkFz/NtmCRJs8YWURQhjmPxaSu48n6/F5vvdrudxLQmDEOUZflrWBQFLpeL6DzP5T6E+pyAfpZlUsgpi0afz2dBmqYysbHJoGYxm4xGI/R6PcxmMyGH9mKxEL/b7WI8HiNtyGnf0bSPKj83DVlMInzfx3w+F5uM06c9nU5l2n+k2KsSuiqZtklRXwmhT5sbEWzOmNHbMMjGCvp6H4IFhN7LfkObmh/+ASA++4hO91bHAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/9d02d9980b541e79dc05a7c6d8b66761/d9199/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/9d02d9980b541e79dc05a7c6d8b66761/8ff5a/001-01.png 240w,
/devHistoryBlog/static/9d02d9980b541e79dc05a7c6d8b66761/e85cb/001-01.png 480w,
/devHistoryBlog/static/9d02d9980b541e79dc05a7c6d8b66761/d9199/001-01.png 960w,
/devHistoryBlog/static/9d02d9980b541e79dc05a7c6d8b66761/51800/001-01.png 1196w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; # 서브넷 마스크(subnet mask) &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CIDR 이후(현재) subnet mask만 쓰고 있기 때문에 넷마스크와 서브넷마스크를 딱히 구분하진 않는다.&lt;/li&gt;
&lt;li&gt;IP주소 뒤에 붙은 /24 같은 것들은 서브넷 마스크의 bit 수를 의미한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;192.168.0.3/24
IP주소       : 192.168.0.3 
서브넷 마스크 : 255.255.255.0
2진수        : 11111111.11111111.11111111.00000000
256개의 호스트 주소를 사용할 수 있다.

192.168.0.3/25
IP주소       : 192.168.0.3 
서브넷 마스크 : 255.255.255.128
2진수        : 11111111.11111111.11111111.10000000
128개의 호스트 주소를 사용할 수 있다.

192.168.0.3/26
IP주소       : 192.168.0.3 
서브넷 마스크 : 255.255.255.192
2진수        : 11111111.11111111.11111111.11000000
64개의 호스트 주소를 사용할 수 있다.

192.168.0.3/23
IP주소       : 192.168.0.3 
서브넷 마스크 : 255.255.254.0
2진수        : 11111111.11111111.11111110.00000000
512개의 호스트 주소를 사용할 수 있다.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; # 브로드 캐스트(broad cast) &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;특정 네트워크에 속하는 모든 호스트들이 갖게 되는 주소. &lt;/li&gt;
&lt;li&gt;네트워크에 있는 클라이언트 모두에게 데이터를 보내기 위함.&lt;/li&gt;
&lt;li&gt;해당 네트워크에 속하는 모든 IP 주소 가운데 맨 마지막 IP주소&lt;/li&gt;
&lt;li&gt;계산방법 : 서브넷 마스크의 ‘0’인 부분을 모두 1로 바꾼다.&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/69c94c09e6211d3e6775008c743cdfb7/0098c/001-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 775px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 58.333333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAABJ0AAASdAHeZh94AAAB/0lEQVQoz01Th5ajMAzk/z/vSnb3Nhua6c3GtADJ3MiBvfN781wkpJFGePu+o6pqKKUwThPWdcO2bZD3x+OBYRiQFwWW+533p3sTu0BrjSzLkKapsy/LHV5VN3j/+MSPn7+gkgxZXqBkgrpp0DQtgjDE78sbYpW4xGVZMUHpfG43n7YLLm/vSDP5roIXRvErS5YzU4a269wexQpRFKFtO2ZeMIwjLNkKY2sHJlAkwCR1jZi+KWNobeD1NNphhDa922fSlg9Mb93bNC9Yt921Yt1e2Hg3fe8CyC4kemvZshmesQxGmANVoxGpDH6k4IcKTWcQRAn+XG+4BTGut+DwSRHEibOPM0lMizt7+84mUwCBnIWhIbOO2bUxjq2wO/3OXVhJO8RHfDsKJC3xwPV8Ph1k3dfVldF12kHOUuLj+VJYlJagHQPWFLRtWxewoYhStvflR1QydvQ/v3yELCXNS4S8S1mCumWv7ATdD64tssu7+CSciqsfQqU5Wt0fohzCOCEOMVphqF/lSLNPDOPk9prMao6V/m7PS1RX8v9LBtocJUg5ouQ8Tyg43DIiORmJTYZa+ib+55Lh9vphwglLCO28rFEQWVEhOUoRJQcqOXKM7Dgj4SB/Iy0Q86eomw5eJ5S/YVmKZg//OUufKjqKTQKfUBz+gD+F9FKCRc6vxV9Ugo/8hNe03wAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/69c94c09e6211d3e6775008c743cdfb7/0098c/001-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/69c94c09e6211d3e6775008c743cdfb7/8ff5a/001-02.png 240w,
/devHistoryBlog/static/69c94c09e6211d3e6775008c743cdfb7/e85cb/001-02.png 480w,
/devHistoryBlog/static/69c94c09e6211d3e6775008c743cdfb7/0098c/001-02.png 775w&quot;
        sizes=&quot;(max-width: 775px) 100vw, 775px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;</content:encoded></item><item><title><![CDATA[[작업로그] MHA Failover, RollChange 테스트]]></title><link>https://ssongey.github.io/works/posts/2021-03-03--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2021-03-03--001</guid><pubDate>Wed, 03 Mar 2021 00:00:00 GMT</pubDate><content:encoded>&lt;br&gt;
&lt;p&gt;MySQL MHA 테스트에 대한 작업 로그를 기록한다.  &lt;/p&gt;
&lt;br&gt;
&lt;p&gt;시나리오&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Failover&lt;/li&gt;
&lt;li&gt;Failback&lt;/li&gt;
&lt;li&gt;Roll Change&lt;/li&gt;
&lt;li&gt;MHA Manager 기동&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt;■ 1. Failover&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;#1번서버  &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ifconfig로 VIP up 확인 (master 확인)    &lt;/li&gt;
&lt;li&gt;
&lt;p&gt;MySQL 종료 &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shellscript&quot;&gt;&lt;pre class=&quot;language-shellscript&quot;&gt;&lt;code class=&quot;language-shellscript&quot;&gt;$ /usr/local/mysql/bin/mysqladmin -uroot -p shutdown&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;Ifconfig 로 VIP down 확인&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;#2번 서버&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;VIP up 확인&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;MySQL Slave 상태 확인, empty 이면 정상적으로 failover 완료&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sql&quot;&gt;&lt;pre class=&quot;language-sql&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;mysql&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;show&lt;/span&gt; slave &lt;span class=&quot;token keyword&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt;■ 2. Failback&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;수동작업 진행&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;#2번 서버&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Data Dump&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shellscript&quot;&gt;&lt;pre class=&quot;language-shellscript&quot;&gt;&lt;code class=&quot;language-shellscript&quot;&gt;$ mysqldump -u root -p --all-database &amp;gt; dump.sql&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Master Status 확인&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shellscript&quot;&gt;&lt;pre class=&quot;language-shellscript&quot;&gt;&lt;code class=&quot;language-shellscript&quot;&gt;mysql&amp;gt; show master status;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;#1번 서버&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;MySQL 기동&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shellscript&quot;&gt;&lt;pre class=&quot;language-shellscript&quot;&gt;&lt;code class=&quot;language-shellscript&quot;&gt;$ /usr/local/mysql/bin/mysqld_safe --user=mysql &amp;amp;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;dump import&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shellscript&quot;&gt;&lt;pre class=&quot;language-shellscript&quot;&gt;&lt;code class=&quot;language-shellscript&quot;&gt;$ mysql -u root -p &amp;lt; dump.sql&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Slave 등록&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shellscript&quot;&gt;&lt;pre class=&quot;language-shellscript&quot;&gt;&lt;code class=&quot;language-shellscript&quot;&gt;// 해당 쿼리문은 MHA.log에 기록되어 있음
mysql&amp;gt; change master to master_host=[#2번서버 HOST], master_port=[PORT], 
master_user=[replication db user], master_password=[replication user password],
master_log_file=[#2번 서버의 master log file], master_log_pos=[#2번 서버의 master log pos];&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Slave 시작 및 확인&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shellscript&quot;&gt;&lt;pre class=&quot;language-shellscript&quot;&gt;&lt;code class=&quot;language-shellscript&quot;&gt;mysql&amp;gt; start slave;
mysql&amp;gt; show slave status;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;이중화 되었는지 데이터 확인&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt;■ 3. Roll Change&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;#2번 서버&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Failover가 실행되면 MHA manager는 자동 종료되며, masterha_default.failover.complete 파일이 생성됨.&lt;/li&gt;
&lt;li&gt;Roll 변경 전 해당 파일 삭제 필요&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;masterha_master_switch 실행&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shellscript&quot;&gt;&lt;pre class=&quot;language-shellscript&quot;&gt;&lt;code class=&quot;language-shellscript&quot;&gt;masterha_master_switch --master_state=alive --conf=/etc/mha.cnf --orig_master_is_new_slave --interactive=0&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;VIP down 확인 &lt;/li&gt;
&lt;li&gt;
&lt;p&gt;slave 상태 확인&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shellscript&quot;&gt;&lt;pre class=&quot;language-shellscript&quot;&gt;&lt;code class=&quot;language-shellscript&quot;&gt;mysql&amp;gt; show slave status;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;#1번 서버&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;VIP up 확인&lt;/li&gt;
&lt;li&gt;master 및 slave 상태 확인&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt;■ 4. MHA Manager 기동&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;#2번 서버&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;MHA Manager 현재 상태 확인&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shellscript&quot;&gt;&lt;pre class=&quot;language-shellscript&quot;&gt;&lt;code class=&quot;language-shellscript&quot;&gt;$ /usr/bin/masterha_check_status --conf=/etc/mha.conf&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;MHA Manager 기동&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shellscript&quot;&gt;&lt;pre class=&quot;language-shellscript&quot;&gt;&lt;code class=&quot;language-shellscript&quot;&gt;$ nohup /usr/bin/masterha_manager --conf=/etc/mha.cnf &amp;amp;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[[작업로그] WCA, WVA 서비스 설치 스크립트 만들기]]></title><link>https://ssongey.github.io/works/posts/2021-02-22--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2021-02-22--001</guid><pubDate>Mon, 22 Feb 2021 00:00:00 GMT</pubDate><content:encoded>&lt;br&gt;
&lt;p&gt;이번에 다른 부서에서 사온 제품 2개에 대한 설치 매뉴얼 검토중에 작업 단순화가 필요하다고 느꼈다.&lt;br&gt;
이에 불필요한 작업 제거 및 설치 단순화를 하여 설치 스크립트를 생성하는 목적으로 이 작업을 진행하여 되었다.&lt;br&gt;
이 작업을 진행하면서 배운 내용이나 기록이 필요한 내용을 정리한다.  &lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt;■ 1. 수작업 최소화&lt;/span&gt;
&lt;span class=&quot;title__sub2&quot;&gt;1.1. Cloud, On-Premise 둘다 OS는 데비안 계열을 사용&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ubuntu 18.04 에서 진행&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt;1.2. 두 제품에 대한 리펙토링을 진행하기 전까지 JAVA8, Tomcat8 사용&lt;/span&gt;
tomcat major 버전이 fix 이므로 8버전의 latest 파일을 받아 아래 파일들을 수정한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;1.2.1. context.xml&lt;/b&gt;&lt;br&gt;
— datasource 설정  &lt;/li&gt;
&lt;li&gt;&lt;b&gt;1.2.2. server.xml&lt;/b&gt;&lt;br&gt;
— 최대 2개의 WAS 서비스를 사용하므로 &lt;span class=&quot;text-mark__green&quot;&gt; port 를 동적으로 설정&lt;/span&gt;  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/3d14480d82b7fb44b2423b96a57fe1a5/29492/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 522px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 28.750000000000004%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABJ0AAASdAHeZh94AAABAUlEQVQY00WRa5KEMAiE5zg75okhiRpj1dbe/0y9gDXOD8Sk0h/QvHiNSNGDqCBIjhQQU4AP3nLMd6ScUGsFMyPLfxZdLgnECUneLcsC5xxef9eKua8Yx4bWO7gXULsflk5yJgF7KZrQWrNQYNA7igaOUvwB7iL+PQlzS7jODb03lLoa0KpnL906CxUomHKWrpIV0ql0Gu+dQV9BDl2EW01gcjJSwb7vBq0bgxtjOzpKk25bwbgOK0pEZo92qZY8QK36816eoHXFOU+DzjkxxsA4B7iKFRzBO9m4CggSb9Eo6BlZP5/QSx1FfVLzNRNl6cDLAqKAdDn3MnQRlL7effT/M827uUwjAHMAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/3d14480d82b7fb44b2423b96a57fe1a5/29492/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/3d14480d82b7fb44b2423b96a57fe1a5/8ff5a/001-01.png 240w,
/devHistoryBlog/static/3d14480d82b7fb44b2423b96a57fe1a5/e85cb/001-01.png 480w,
/devHistoryBlog/static/3d14480d82b7fb44b2423b96a57fe1a5/29492/001-01.png 522w&quot;
        sizes=&quot;(max-width: 522px) 100vw, 522px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;1.2.3. catalina.sh&lt;/b&gt;&lt;br&gt;
— &lt;span class=&quot;text-mark__green&quot;&gt;java system properties 설정&lt;/span&gt;&lt;br&gt;
— http 포트가 8080 일 경우,&lt;br&gt;
 — 8005 -&gt; ${port.shutdown}&lt;br&gt;
 — 8009 -&gt; ${port.ajp}&lt;br&gt;
 — 8443 -&gt; ${port.https} 가 된다.  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/a463a5f1f2799ad66ea082705e23a975/dc333/001-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 938px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 17.916666666666668%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAABJ0AAASdAHeZh94AAAAzElEQVQY002Py07DMBBF8yc0NHHsxI+xY6e0RRFIrNjw/19zGIJUdXF072yuznS+CiEFohQlk7UHzUlWBqn4KMctcSF4RwwzfrFEPx89Bo/xgSEkhpjp4ltjzhlTd0y5ULQXESSv2NQYy41xvWNjxM06pGPODU+MGE1zpKErHzu23Xi5/9C3Tzbt17rxvl7Y54TLO6frN/32hZGNrEbOnTFT/2B6cKILrWDV6KyGfy+K9qovtlyoKbEuC1FtF+2jGk5qY+3/4GRfD8wTv0O9eelDVkBRAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/a463a5f1f2799ad66ea082705e23a975/dc333/001-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/a463a5f1f2799ad66ea082705e23a975/8ff5a/001-02.png 240w,
/devHistoryBlog/static/a463a5f1f2799ad66ea082705e23a975/e85cb/001-02.png 480w,
/devHistoryBlog/static/a463a5f1f2799ad66ea082705e23a975/dc333/001-02.png 938w&quot;
        sizes=&quot;(max-width: 938px) 100vw, 938px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt;■ 2. Service 등록&lt;/span&gt;
&lt;span class=&quot;title__sub2&quot;&gt;2.1. 서비스파일 생성&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shellscript&quot;&gt;&lt;pre class=&quot;language-shellscript&quot;&gt;&lt;code class=&quot;language-shellscript&quot;&gt;[Unit]
Description=WCA WAS
Requires=mysqld.service
After=network.target mysqld.service

[Service]
Type=forking
Environment=WCA_LIB=/opt/penta/wca-libs
Environment=SERVICE_PORT=8080
Environment=CATALINA_HOME=/opt/tomcat-wca
Environment=JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
Environment=LD_LIBRARY_PATH=/opt/penta/wca-libs:$LD_LIBRARY_PATH

User=autocrypt
Group=autocrypt

ExecStart=/opt/tomcat-wca/bin/startup.sh
ExecStop=/opt/tomcat-wca/bin/shutdown.sh

Restart=always

[Install]
WantedBy=multi-user.target&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Requires vs After&lt;/b&gt;&lt;br&gt;
— &lt;a href=&quot;https://stackoverflow.com/questions/40593242/systemd-using-both-after-and-requires&quot;&gt;https://stackoverflow.com/questions/40593242/systemd-using-both-after-and-requires&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Environment&lt;/b&gt;&lt;br&gt;
— User를 설정하더라도 bash_profile이나 기타 &lt;span class=&quot;text-mark__green&quot;&gt;쉘/유저 기반의 환경 변수는 먹지 않는다.&lt;/span&gt;&lt;br&gt;
— 따라서 해당 프로퍼티를 사용하여 환경 변수를 설정한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Restart&lt;/b&gt;&lt;br&gt;
— 해당 서비스가 강제 종료되었을 경우 재시작에 대한 정책이다.&lt;br&gt;
— systemctl 로 종료했을 경우는 작동하지 않는다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;WantedBy&lt;/b&gt;&lt;br&gt;
— [install] 은 “systemctl enable [service name]” 으로 서비스 등록 시 이용하는 섹션이다.&lt;br&gt;
— WantedBy 는 이 서비스가 어떤 전제조건 하에서 실행되는 지를 결정한다.&lt;br&gt;
— multi-user.target 은 runlevel 3 환경이 모두 구동되었을 때를 의미한다.&lt;br&gt;
— &lt;span class=&quot;text-mark__blue&quot;&gt;run leval (리눅스시스템의 실행레벨)&lt;/span&gt;&lt;br&gt;
 ▶ init 0 : halt, 시스템 종료&lt;br&gt;
 ▶ init 1 : Single user mode, 관리 모드로 root 계정만 사용 가능&lt;br&gt;
 ▶ init 2 : Multiuser, without NFS (The same as 3, if you do not have networking)&lt;br&gt;
 ▶ init 3 : Full multiuser mode, default level&lt;br&gt;
 ▶ init 4 : unused, 사용하지 않는 실행레벨, 커스텀레벨로 사용 가능&lt;br&gt;
 ▶ init 5 : X11, X윈도우 환경으로 실행된 멀티유저 실행모드&lt;br&gt;
 ▶ init 6 : reboot  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt;2.2. 기타 설정 및 서비스 활성화 스크립트 생성&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;각 Step 별로 블럭지어 실패 시 메시지 출력 및 종료하도록 구성&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/2a40559cff525bbf32826ed963af32c2/47730/001-03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 428px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 51.66666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABJ0AAASdAHeZh94AAABpklEQVQoz3VS2W7jMAzMr8SHLkvyIfl24mYD7P//0ZRk07RYYB8GpDjUiKR4yVODaXaI0WBOGbkf0EePoWvRtxEd+V0M5Ac5T0PGSDmJeM5NfYC2BZQuoU2Jy9o5dIOGdZVcjKGBDwYhNmjZbwyidwjeCqJv0AUvsei9xJQpRIxFL1YVqDW/cEVoLdIY0VYFtrJC4xXWY8KQPOZlIBuQx5ZyqPrBYdkauKaG1iz4JXrhco0tRXBIEY/nHcfc4u/ZY1oD9hCwTQPOx4Hz48CT+PNjx+Ox47hl3O4dOupScVEsaLhUQqWuaGkej+eJdR+R1x6jqpGVwn5bsG0TjvuG/VgwryPuJwmeB+XfsFD1Sr8qHI0mIU9zq2FojtyCdeTbCoaSJEatc5x9hn3BNUrA/lswaZoBtWwEBZGlgAW+kmvheEaSQ5csPeY4Ln4t52/R1wwLOaTs8OfZIyUn67HmmWwiO6Gl9eG1Sl0n3JJGLJnaZ5uYt/S5V1waekXLpxQYsqVBRyGl5deH/Qv9q2L9XplXy72u8P3TTKr3CvxH7Bf3Y8v3Hn4CKQkvjR6008AAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/2a40559cff525bbf32826ed963af32c2/47730/001-03.png&quot;
        srcset=&quot;/devHistoryBlog/static/2a40559cff525bbf32826ed963af32c2/8ff5a/001-03.png 240w,
/devHistoryBlog/static/2a40559cff525bbf32826ed963af32c2/47730/001-03.png 428w&quot;
        sizes=&quot;(max-width: 428px) 100vw, 428px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;서비스 활성화 Step&lt;br&gt;
— service 파일 활성화 명령어 : $ systemctl enable {service 파일명}&lt;br&gt;
— daemon reload 명령어 : $ systemctl daemon-reload  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/5d8236538d4cabf795efc722db79b89f/242e2/001-04.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 703px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 40%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABJ0AAASdAHeZh94AAABPElEQVQoz3WR2XaEIBBE/ZNZHJVVEMFtxpm85P8/qVKYmOPJ8nAPDTTVVHfR9wJdp9G1Dq3V8M5AqRuq5oyGyOaERpxRiyuq+vLFeeNWnQ4xc5oLCiFKPigRk0K0DYKzGENC8h6qv+M0vHOdWEhiGHsS0PcWIVos97TtUzR4rC2MqVHUzZWCV160mJJD8Eycxo0wzjDzC3Fe8HiMWJ8LmSnUoQuGWHhv4JxAHyUknRX5m5lxilvyNEe83ijwTBQJuM8B6xoxLwPS0BFPNxpKV98286dyK/Ja5H5l5ZyYxR7rxMdZQDP2myWl2RYm78Uz2ZWQn+6OcaFVBaEpygOpSihZMc57roJ34radHR/vHAvsFHWeGoNh5FDYXGcNWiPh2hxrWKM4ffVL7D84ZVYSl82WkOWfVXeLf/Hz7gO0xPDAWquT1AAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 04&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/5d8236538d4cabf795efc722db79b89f/242e2/001-04.png&quot;
        srcset=&quot;/devHistoryBlog/static/5d8236538d4cabf795efc722db79b89f/8ff5a/001-04.png 240w,
/devHistoryBlog/static/5d8236538d4cabf795efc722db79b89f/e85cb/001-04.png 480w,
/devHistoryBlog/static/5d8236538d4cabf795efc722db79b89f/242e2/001-04.png 703w&quot;
        sizes=&quot;(max-width: 703px) 100vw, 703px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;스크립트 생성하면서 리눅스 파일 시스템 계층 구조에 맞게 설정 등의 디렉토리를 구성하였다.&lt;br&gt;
▶ &lt;a href=&quot;https://ko.wikipedia.org/wiki/%ED%8C%8C%EC%9D%BC%EC%8B%9C%EC%8A%A4%ED%85%9C_%EA%B3%84%EC%B8%B5%EA%B5%AC%EC%A1%B0_%ED%91%9C%EC%A4%80&quot;&gt;리눅스 파일 시스템 계층구조 표준 위키피디아&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;h4&gt;github&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/eunyoung-autocrypt/bash-scripts&quot;&gt;https://github.com/eunyoung-autocrypt/bash-scripts&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[linux 다중명령어 차이점 (&& || ; |)]]></title><link>https://ssongey.github.io/history/posts/2021-02-19--001</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2021-02-19--001</guid><pubDate>Fri, 19 Feb 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; ■ Double Ampersand (&amp;#x26;&amp;#x26;) &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;첫번째 명령이 &lt;span class=&quot;text-mark__green&quot;&gt;정상 종료&lt;/span&gt; 했을 경우 두번째 명령 수행&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/22210d8b9d2d6beb24bdeb169cd12fb2/c0388/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 542px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 20.833333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAABJ0AAASdAHeZh94AAAAu0lEQVQY02WQWQ6DMAxEOUpZylL2sCSBBAr9q6re/zZTO0itUD+ssSbW+DneNEvoqce6amy7hVQdpnlA0+YYZYt+qNH1NURXYhgb8gQp+w35lZs/vAZFmcCbjIQxI6xVmCkozULEiY8kDVxx/6vg30/904xnFg1DYQvp/lihNBOOaEXxJZFKOBom4V50lXtT6qBl+mt8cYu8mcIMUW6bwZ2Kw1/vpyPmr+BTrNXI86ujz24RaeT06MPTVR+Ysn2kz98hiQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/22210d8b9d2d6beb24bdeb169cd12fb2/c0388/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/22210d8b9d2d6beb24bdeb169cd12fb2/8ff5a/001-01.png 240w,
/devHistoryBlog/static/22210d8b9d2d6beb24bdeb169cd12fb2/e85cb/001-01.png 480w,
/devHistoryBlog/static/22210d8b9d2d6beb24bdeb169cd12fb2/c0388/001-01.png 542w&quot;
        sizes=&quot;(max-width: 542px) 100vw, 542px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; ■ Double Vertical Bar (||) &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;첫번째 명령이 &lt;span class=&quot;text-mark__green&quot;&gt;에러&lt;/span&gt; 일 경우 두번째 명령어 수행&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/6478f6305036b7db497650824d24ea6a/3ddad/001-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 545px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 20%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAABJ0AAASdAHeZh94AAAAr0lEQVQY00WOQRKDIAxFPYrtVEEEEXVEBad24aK9/33SJJS6+MMPyX9JEaKHGGd4HgEOlBs0yoA2gr3pGpQE26tUG4k9Cb1r+W8YDXvnNKi2gmIL8wV8RQ7REAFt3zKssw1Yq34ghGJNkATTDBbyziquCzcEBoi7h/fnhH1f0C9A/fM8MJwuIEi+dpw6BtLCWpQJ6NcJwx42hK7ryKGsRj1Y5Gm4Fjeo6vL/ZlGd+19zVnxzOx3NxQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/6478f6305036b7db497650824d24ea6a/3ddad/001-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/6478f6305036b7db497650824d24ea6a/8ff5a/001-02.png 240w,
/devHistoryBlog/static/6478f6305036b7db497650824d24ea6a/e85cb/001-02.png 480w,
/devHistoryBlog/static/6478f6305036b7db497650824d24ea6a/3ddad/001-02.png 545w&quot;
        sizes=&quot;(max-width: 545px) 100vw, 545px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt;■ Pipe (|)&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;첫번째 명령어 결과를 사용하여 두번째 명령어 수행&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/68813033d8e7bae6013c56801171b352/a1aa0/001-03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 533px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 20.833333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAABJ0AAASdAHeZh94AAAAw0lEQVQY00WP/Q6CMAzEeRM/EkSBbWxzbA4BjWiM7/8+Z1uN/nHpLW1/txZ5iBinhHk+4bbMSMkhJo/ONvBHLbKuhaV3CAamq6F0hdB3NFOjj5340FtovUcxnBOmOQtwuV8J6H9A6xQBmi+wRasq8dxzXsNRnwM5ZFdtRASMOI8fTQRliDa1LCt9EM8QbQ6om1IC2DOUQVx5lmHVfotilN9lXK4DFjo50snP1wMjBYXewHqFnIMslbv1X+Xq6z+VYQx9AzjYfalgRI+CAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/68813033d8e7bae6013c56801171b352/a1aa0/001-03.png&quot;
        srcset=&quot;/devHistoryBlog/static/68813033d8e7bae6013c56801171b352/8ff5a/001-03.png 240w,
/devHistoryBlog/static/68813033d8e7bae6013c56801171b352/e85cb/001-03.png 480w,
/devHistoryBlog/static/68813033d8e7bae6013c56801171b352/a1aa0/001-03.png 533w&quot;
        sizes=&quot;(max-width: 533px) 100vw, 533px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt;■ Semicolon (;)&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;한 라인에서 여러 명령어를 수행할때 사용&lt;/li&gt;
&lt;li&gt;순차적으로 수행하며, &lt;span class=&quot;text-mark__green&quot;&gt;오류가 발생하더라도 다음 명령어는 계속 수행&lt;/span&gt;된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/b51f4b95340bc2c1735b2d7a753dd762/89a37/001-04.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 532px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 24.166666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAABJ0AAASdAHeZh94AAAA20lEQVQY021QW5KEIBDjJvsaFRXwASgiolW7979StpupmY+p+Uh1oOl0goi7B+P370Q6VuILwmZh3UDVYbYGyzqX8xYdhrGjO401zHB+RIy+cJ4xpoU4jkBCAUcOGKcet+oDdfP1Fo38RlV/vr2X7U+p4rx25LyRwwvM2ZVfJkyzhvUDVUXuTFmmjaTeSFyVyuAE3GvkXVjsacGeVlwk5kggn5HEM0KwRZx7vEjpBl1flVjMzdASOmgt0av66VbwAP9NSgEbCbALRY94oO1u9Oge5zHAkV/xiM34B+oamyzaX7T3AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 04&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/b51f4b95340bc2c1735b2d7a753dd762/89a37/001-04.png&quot;
        srcset=&quot;/devHistoryBlog/static/b51f4b95340bc2c1735b2d7a753dd762/8ff5a/001-04.png 240w,
/devHistoryBlog/static/b51f4b95340bc2c1735b2d7a753dd762/e85cb/001-04.png 480w,
/devHistoryBlog/static/b51f4b95340bc2c1735b2d7a753dd762/89a37/001-04.png 532w&quot;
        sizes=&quot;(max-width: 532px) 100vw, 532px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;</content:encoded></item><item><title><![CDATA[[Linux] sed 명령어 정리]]></title><link>https://ssongey.github.io/works/posts/2021-02-18--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2021-02-18--001</guid><pubDate>Thu, 18 Feb 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt;sed ?&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;문자열 변환 편집기&lt;/li&gt;
&lt;li&gt;원본은 변경없이, 변경된 결과를 출력  &lt;/li&gt;
&lt;li&gt;i 옵션으로 변경된 결과를 원본파일에 덮어쓸 수 있다.&lt;/li&gt;
&lt;li&gt;e 옵션으로 정규식 사용이 가능하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt;치환(substitute)&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# AAA를 BBB로 변환. 단, 원본파일을 바꾸지 않고 표준출력만 한다.
$ sed &amp;#39;s/AAA/BBB/&amp;#39; list.txt

# 탭문자를 엔터로 변환
$ sed &amp;#39;s/\t/\ /&amp;#39; list.txt &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt;삭제(delete)&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# AAA 문자가 포함된 줄을 삭제하여 출력
$ sed &amp;#39;/AAA/d&amp;#39; list.txt

# AAA 문자가 있는 줄만 지우지 않는다.
$ sed &amp;#39;/AAA/!d&amp;#39; list.txt 

# num 1,2 라인 삭제 
$ sed &amp;#39;1,2d&amp;#39; list.txt

# 공백라인 삭제
$ sed &amp;#39;/^$/d list.txt&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[init vs systemd]]></title><link>https://ssongey.github.io/history/posts/2021-02-10--001</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2021-02-10--001</guid><pubDate>Wed, 10 Feb 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;이번에 서비스 등록할때 “/etc/init.d, /usr/lib/systemd/system 디렉토리 밑에 모두 서비스 스크립트를 생성해야하나?” 라는 의문점이 생겨 두개의 차이를 찾아보게 되었다.&lt;br&gt;
결론은 systemd 로만 등록하였다. &lt;/p&gt;
&lt;h3&gt;#. systemd?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;위키피디아 &lt;a href=&quot;https://ko.wikipedia.org/wiki/Systemd&quot;&gt;https://ko.wikipedia.org/wiki/Systemd&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;#. init?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;위키피디아 &lt;a href=&quot;https://ko.wikipedia.org/wiki/Init&quot;&gt;https://ko.wikipedia.org/wiki/Init&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;#. 차이점&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.tecmint.com/systemd-replaces-init-in-linux/&quot;&gt;왜 init이 systemd로 바뀌어야 하는가&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;init의 한계를 극복하기 위해 만들어진 새로운 시스템 관리 아키텍처로 systemd 가 나옴&lt;/li&gt;
&lt;li&gt;To start less&lt;br&gt;
— init : boot 시 많은 서비스를 실행&lt;br&gt;
— systemd : boot 시 필요한 최소한의 서비스를 실행, 필요시 서비스 실행&lt;br&gt;
&lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/3ec0684f822a17da1a279c6b805e2370/b6c94/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 78.33333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAACXBIWXMAABYlAAAWJQFJUiTwAAADC0lEQVQ4y2WUWVMTQRSF86N90ioQFBJCmExCwpYgxPJPWJYoIipVSjAEQjYg+z77AvhwPN1ZTJUPp2aqq+fMd+693YHqfQMDzYBhWrAcR8p2XJi2DZ1rhmXDsiyUq/fIXpVRa3XhuN7cPkfuEzJNE4H+SEPfoJnronjbQKFaR75UQ63d45qHkelQNnqDIZp9DQYNKrU2rso15Klqow2TxjrXuyMDAcPx0NJ9jJwn5Ktd/C63kS21UG6OMLKf0DUfYLqPcDwPbeMBuvsHN7WB3Cd0Ux9gaD+ib1GGg4Buu+jwRXN9XN21cVltcmODhn3+xOdGDwafgqJjeDD9J1zfdXBerCN7U8fVbQea84AhNTF00NYZi6SX1ZY0uyjVUWr0+WePhA5M7xFDXcd6IoVgJIZk6hC7B++kttIZhKNJvAqryF6XxoQt3eMfHpGrdsaRi00ZS0TpGD4saWggFEtheS0KJZmGunMAdfsAytY+VjY2sRiMsmkTwzGhLwlzleYcoU9Cd2yo6QjGdmio0DCF2M6+lHhfIfVCMIJsvjgh1Bz5sYibLTbwq1BD4b6LAevX1SeGjByK7UrC6FYa8d0DKZWEqxFBqJCwOCXkeDDyJSPnKuPIhUnkrunPDMPxNF6H4zLq5t5bKkPKQwSVJJZCsfnILkfE59iwy5UWIzckoYzMzk4jjwnnIm/v05yEG3ESbvwz7NBQtF4Y5spNGfuuo8m1njk1NLAW3yOhKk0Se4dSSmIPQTZlKfRfUyaGkrCJ6ymhOUeokpAfKgl2efvNTCus4cKqgvNZU6Y15JCK0bkot3Bd62FgP8xqOCJhkIZLIQUbnEd1EjcqxiYSpyEj5+dqKCPfCrNx5Jv6eGx6c4ThTY7Iuiprl0hlOOAZ2elQNMHaqnM1NFz0eGzEcZo2RcTuiXWOjsXjJgZ7gcP7/OUqu5qgSZLN2MQan4ur63j2Yhk/cwUENMNEX7Mw0G3eMIOZmt2RXBPSeYUNeSsdnXzHh08n+Pz1B46/neH49Ey+fzw+xfujL7irt/AXXl1KI7/UWhgAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/3ec0684f822a17da1a279c6b805e2370/d9199/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/3ec0684f822a17da1a279c6b805e2370/8ff5a/001-01.png 240w,
/devHistoryBlog/static/3ec0684f822a17da1a279c6b805e2370/e85cb/001-01.png 480w,
/devHistoryBlog/static/3ec0684f822a17da1a279c6b805e2370/d9199/001-01.png 960w,
/devHistoryBlog/static/3ec0684f822a17da1a279c6b805e2370/b6c94/001-01.png 1429w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;ul&gt;
&lt;li&gt;And to start more in parallel&lt;br&gt;
— init : 1 부터 5의 처리를 순서대로 진행&lt;br&gt;
— systemd : 각 처리에는 의존관계가 정의되어 있고, 병렬로 실행하여 시간 단축&lt;br&gt;
&lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/3dad55492581d3e21a792711ced53518/85053/001-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 60.83333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAABYlAAAWJQFJUiTwAAABGklEQVQoz62T2W6DQAxF+f8PRBC1lFIe2DPsDJuTa+RoIEnpQy1ZntjW8XVmsL6+f6goFHVdR23bcuz7ns/yu6pKunz45H4GlGY5DcPANfRJP1wpRVZd1zTPM43jyLFpGirLcpfrug1+vSrSerwPqBiKCBCiCLBQgK3ryrEoCgrDkEwTsOM4BAG2bXOf67oURRHHLMu4x8IEE4gVoNDMaa0ZKqqwBYbGccxnDEEvWE/ANE3J9/1dDjBATfM8j1WZ9hIIFZj6DogcfFmWx1n6XgKTJOHpZ0CxUyAU4j/5DXgE/YvCo78F4pbxQI+3/GegvEOxPM8pCIJdbpomVnlmYFm4UXlj0z1CHdYepy2HmnwF2+rDQ7HpqIF1Axe3qbQXv7hRAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/3dad55492581d3e21a792711ced53518/d9199/001-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/3dad55492581d3e21a792711ced53518/8ff5a/001-02.png 240w,
/devHistoryBlog/static/3dad55492581d3e21a792711ced53518/e85cb/001-02.png 480w,
/devHistoryBlog/static/3dad55492581d3e21a792711ced53518/d9199/001-02.png 960w,
/devHistoryBlog/static/3dad55492581d3e21a792711ced53518/85053/001-02.png 1225w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;h3&gt;#. 명령어 비교&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;자동시작 등록/해제&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# init
$ chkconfig [service명] on|off

# systemd
$ systemctl enable|disable [service명]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;유효/무효 확인&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# init
$ chkconfig [service명] --list

# systemd
$ systemctl is-enabled [service명]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;실행/종료/상태확인&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# init
$ /etc/init.d/[service명] start/stop/status

# systemd
$ systemctl start|stop|status [service명]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;강제종료&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# init
$ /etc/init.d/[service명] status (pid 확인 후)
$ kill [PID]

# systemd
$ systemctl kill [service명]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;h3&gt;#. 기타 systemd 명령어&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# 유효화 되어 있는 Unit 표시
$ systemctl list-units

# 설치되어 있는 Unit 표시
#   enable : 자동 시작 설정 활성화
#   disable : 자동 시작 설정 비활성화
#   static : 단독으로 자동 기동 할 수 없음
$ systemctl list-unit-files&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[@Value 사용 시, required a bean of type 'java.lang.Boolean' that could not be found. @value]]></title><link>https://ssongey.github.io/errors/posts/2021-02-10--001</link><guid isPermaLink="false">https://ssongey.github.io/errors/posts/2021-02-10--001</guid><pubDate>Wed, 10 Feb 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span style=&quot;background-color:#ed5f65; color:#ffffff; margin-bottom: 5px; padding: 10px; font-weight: 600&quot;&gt; 무엇이 문제였나? &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;@Value 어노테이션을 이용하여 application.properties 변수 접근 시 아래와 같은 오류 발생&lt;/li&gt;
&lt;li&gt;소스코드&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/b4ef91bb056d36b9221105b015849587/d9217/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 904px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 10.416666666666668%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAACCAYAAABYBvyLAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAaklEQVQI123MQQ7CMAxE0Z6ndhpIYkcNKQjU+1/pY1iwYjF6s/rLeaychzKb8rSVMe/Mx4tmjnvHQrPQnZSVdFE0y3e/vwk5b4gIy60J0wS/CqOEfafvg1oaVjutRLB6aGxJEZW/048RfAMMlD8TIVPjSwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/b4ef91bb056d36b9221105b015849587/d9217/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/b4ef91bb056d36b9221105b015849587/8ff5a/001-01.png 240w,
/devHistoryBlog/static/b4ef91bb056d36b9221105b015849587/e85cb/001-01.png 480w,
/devHistoryBlog/static/b4ef91bb056d36b9221105b015849587/d9217/001-01.png 904w&quot;
        sizes=&quot;(max-width: 904px) 100vw, 904px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;에러 발생&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/95944d595f58a430eafe70e15b889be5/e332b/001-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 14.583333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAABYlAAAWJQFJUiTwAAAARElEQVQI12PQ19f/D8J6enr/YWwDAwMUtqGhIYY4Nj7IDAZdXV0wAxmjWwLTCKFRLUZXzwCy3cAA01aQJIytpaVFNAYAuhhcMMzv6VAAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/95944d595f58a430eafe70e15b889be5/d9199/001-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/95944d595f58a430eafe70e15b889be5/8ff5a/001-02.png 240w,
/devHistoryBlog/static/95944d595f58a430eafe70e15b889be5/e85cb/001-02.png 480w,
/devHistoryBlog/static/95944d595f58a430eafe70e15b889be5/d9199/001-02.png 960w,
/devHistoryBlog/static/95944d595f58a430eafe70e15b889be5/07a9c/001-02.png 1440w,
/devHistoryBlog/static/95944d595f58a430eafe70e15b889be5/29114/001-02.png 1920w,
/devHistoryBlog/static/95944d595f58a430eafe70e15b889be5/e332b/001-02.png 1929w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br&gt;
&lt;p&gt;&lt;span style=&quot;background-color:#ed5f65; color:#ffffff; padding: 10px; font-weight:600&quot;&gt; 원인이 뭔데? &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;의존성 주입 방식 중 필드 주입 방식(@Autowired 사용) 은 권장하지 않는 패턴이기 때문에 @RequiredArgsConstructor 를 사용하여 생성자 주입방식을 사용했었다.&lt;/li&gt;
&lt;li&gt;final 이 붙었기 때문에 자동으로 생성자 생성시 필요 필드가 되어버렸다.&lt;/li&gt;
&lt;li&gt;해당 변수는 스프링에서 관리하는 Bean이 아니기 때문에 의존성 자동 주입이 될 수 없다.&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;p&gt;&lt;span style=&quot;background-color:#ed5f65; color:#ffffff; padding: 10px; font-weight:600&quot;&gt; 이렇게 해결했다! &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;final 제거&lt;/li&gt;
&lt;li&gt;immutable 한 변수가 아닌데… 다른 방법도 찾아서 정리해 놔야곘네…&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[[작업로그] Mysql Index 미생성 이슈]]></title><link>https://ssongey.github.io/works/posts/2021-02-04--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2021-02-04--001</guid><pubDate>Thu, 04 Feb 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;현재 프로젝트중인 사이트에서 에이징 테스트 중에 DB 서버 CPU 사용량이 점차 증가하여 사용율이 90%까지 올라가는 현상이 발생했다.&lt;br&gt;
결론적으로는 index를 생성하지 않아 select가 많은 특정 테이블에서 약 50만건 데이터를 계속해서 full scan 하여 해당 현상이 발생되었다.&lt;/p&gt;
&lt;h3&gt;#. 이를 위해 무엇을 확인했나?&lt;/h3&gt;
&lt;h4&gt;#1. slow query 확인&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;1초 이상 수행되는 쿼리 검출&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sql&quot;&gt;&lt;pre class=&quot;language-sql&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; leaf_cert 
&lt;span class=&quot;token keyword&quot;&gt;where&lt;/span&gt; actor&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;MO&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;and&lt;/span&gt; cn&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;KREVPABCDEF0052&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;and&lt;/span&gt; valid&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;and&lt;/span&gt; last_issued&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; 

&lt;span class=&quot;token keyword&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; leaf_cert leafcert0_ 
&lt;span class=&quot;token keyword&quot;&gt;where&lt;/span&gt; actor&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;CPS&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;and&lt;/span&gt; valid&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;and&lt;/span&gt; last_issued&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;h4&gt;#2. 조건절로 사용되는 컬럼의 cardinality 와 선택률&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;위의 쿼리문 확인 결과, leaf_cert 테이블에서는  &lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color:green; font-weight:500&quot;&gt;cn&lt;/span&gt; 컬럼은 cardinality 가 높다&lt;br&gt;
— 1년마다 인증서 갱신이 되면 동일 cn의 row 가 발생, 인증서 폐지 시 동일 cn으로 row가 발생할수 있다.  &lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color:green; font-weight:500&quot;&gt;last_issued&lt;/span&gt; 컬럼은 cardinality가 낮지만 선택률이 낮다.&lt;br&gt;
— 값은 true 또는 false 이다.&lt;br&gt;
— 한개의 row만 true 이다.   &lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color:green; font-weight:500&quot;&gt;actor&lt;/span&gt;가 CPS 일 경우 선택률이 낮다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;- cardinality  
    -- 값의 균형을 나타냄  
    -- 모든 레코드에 다른 값이 들어있으면 cadinality 가 높다.  
    -- 높을 수록, 즉 값이 평균치에서 많이 흩어져 있을수록 좋은 인덱스 후보이다.  

- 선택률  
    -- 테이블 전체에서 몇 개의 레코드가 선택되는지를 나타냄  
    -- 선택률이 낮을 수록, 즉 한 번의 선택으로 레코드가 조금만 선택되는 것이 좋은 후보이다.  &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;h3&gt;#.인덱스 생성&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;create index idx__cn on leaf_cert(cn);
create index idx__last_issued on leaf_cert(last_issued);
create index idx__vaild on leaf_cert(valid);&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;#.근데?&lt;/h3&gt;
&lt;p&gt;확인해보니 에이징 테스트 셋이 잘못됐었다..&lt;br&gt;
운영시 실제로는 cn 컬럼의 데이터가 중복 발생 할 경우가 낮아 cn의 cadinality는 높아야 하는데…&lt;br&gt;
테스트 셋을 300개만 생성하여 테스트를 하니 동일 cn으로 생성/폐지가 계속 발생하게 되었다.&lt;/p&gt;
&lt;p&gt;폐지가 계속 발생되는 테스트이다보니… cn은 cardinality 가 낮아지고, 폐지 여부 컬럼인 valid 가 선택률이 낮게 되었다.
어쩔 수 없이 valid 컬럼에 인덱스를 추가 생성했다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;create index idx__valid on leaf_cert(valid);&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;h3&gt;테스트 결과&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;결론적으로 CPU 사용량 및 응답속도에서 약 65~75% 의 개선 효과가 관찰됨.&lt;/li&gt;
&lt;li&gt;인덱스 작업 전 CPU 사용량

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/4ba4f99899220e04996580bc1b4eb2c9/098c1/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 28.750000000000004%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABYlAAAWJQFJUiTwAAAA30lEQVQY001Q0W7EIAzr///WtodNp33Gbr2HrVAKlAA+k5GpICsiDo6T5XtdEVNEkYJaK1pvaO2C3v5zlbDjQoTfd4QQ8ON2HCkhxojFOw85C/gLVSqkULgIo6FoHLlj29g8IeWk8cynIqeMQg0VFCbKQZIdSyRhkTkF38att0/c3j/w9vIK/+sgVkMI+T9BER2h9T7H6+gT9tYc7/F44P51V4itZ6JTI9H1UjhSomXd39zbyA30yy5zpgPCzskRhxnl+XcYUMGNewk+wDmnhepsivSL29HQBKzmymM6fAJJxtUUqw5dHwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/4ba4f99899220e04996580bc1b4eb2c9/d9199/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/4ba4f99899220e04996580bc1b4eb2c9/8ff5a/001-01.png 240w,
/devHistoryBlog/static/4ba4f99899220e04996580bc1b4eb2c9/e85cb/001-01.png 480w,
/devHistoryBlog/static/4ba4f99899220e04996580bc1b4eb2c9/d9199/001-01.png 960w,
/devHistoryBlog/static/4ba4f99899220e04996580bc1b4eb2c9/07a9c/001-01.png 1440w,
/devHistoryBlog/static/4ba4f99899220e04996580bc1b4eb2c9/098c1/001-01.png 1578w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;li&gt;인덱스 작업 전 응답시간

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/70721dc15ae9d6e7dfc8f97b6e2b1c62/891d5/001-03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 30.83333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABYlAAAWJQFJUiTwAAABaUlEQVQY002QSUtCYRiF748K2pSlJbVqWvQDIiIaNBsoi6BltJF21aZF1C8IIZTMKRWHNC2TLFRCHK5DF83hDqfvvha4eDgf532/88LhFEVC5buDTKEBodlFqy0SkiRDlmWU6220OxKqQof8xo+IriiRly00oSgKmi0RNTbvdCVwgII830IsXadgNVSlK8q0mMoJ+Mw3EE7VkMwIiH/U4Y3z8L1UcHWXhT1UxLUthxt7jv5wsXQNu2cJmC8S2DtPYNUSxYrlCYbTGBZPIlg4DmP+KIDZAz+mzD5M7/swse3B5I4X+k0PtEY3NOsu6ExuXFoz4G4f8xhYcpA5tOYkHf5DY3BhhKHdcEOnYurpOAsaM/VURb/VC55hRzmrL4/B5QeMGl0EBbChqv1e/+zfV990gIWrx+cOWeBXqQlbsEhdOCIl3DM8zzypO1YmnNEy9eaMluBn3VGHCR6B1wpCb1VE32sIJqu09wt5sHdaqnp+sAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/70721dc15ae9d6e7dfc8f97b6e2b1c62/d9199/001-03.png&quot;
        srcset=&quot;/devHistoryBlog/static/70721dc15ae9d6e7dfc8f97b6e2b1c62/8ff5a/001-03.png 240w,
/devHistoryBlog/static/70721dc15ae9d6e7dfc8f97b6e2b1c62/e85cb/001-03.png 480w,
/devHistoryBlog/static/70721dc15ae9d6e7dfc8f97b6e2b1c62/d9199/001-03.png 960w,
/devHistoryBlog/static/70721dc15ae9d6e7dfc8f97b6e2b1c62/07a9c/001-03.png 1440w,
/devHistoryBlog/static/70721dc15ae9d6e7dfc8f97b6e2b1c62/891d5/001-03.png 1520w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;ul&gt;
&lt;li&gt;인덱스 작업 후 CPU 사용량

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/44bb4660498f26b26e3993eba8f22549/bd82c/001-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 27.916666666666668%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABYlAAAWJQFJUiTwAAAA3klEQVQY03VQ0W7CMAzM/3/eRkDT9jgElLHSpk0cp8lhh5QJaVg6xbbO9l3M936Pvu8RQkCMEcuyvERK6QmX64hhGCrOv1c452B0GRGhlAKNV8tyznWJ5kVyrUkExAaiCGaGYSFp5EbKsvg/6EFdpkOpHdGeyrhLQa2NWl2SEPQ6N2i+9ta+HOPR4bixeLcWu90WHLnN8GPWVLnOI7gZPMs/Th5RXj9OIK3XnidM3Q8ObxZ2s8XXxydm5chclPkK4ZnucIT3AadTJ1YS1lBb5WHmbosiIYqaP0564mjcAEit1Hc3TLztAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/44bb4660498f26b26e3993eba8f22549/d9199/001-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/44bb4660498f26b26e3993eba8f22549/8ff5a/001-02.png 240w,
/devHistoryBlog/static/44bb4660498f26b26e3993eba8f22549/e85cb/001-02.png 480w,
/devHistoryBlog/static/44bb4660498f26b26e3993eba8f22549/d9199/001-02.png 960w,
/devHistoryBlog/static/44bb4660498f26b26e3993eba8f22549/07a9c/001-02.png 1440w,
/devHistoryBlog/static/44bb4660498f26b26e3993eba8f22549/bd82c/001-02.png 1585w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;li&gt;인덱스 작업 후 응답시간

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/6cbf1f4c05306f02c3a609ebaa0c2682/6bfbb/001-04.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 31.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABYlAAAWJQFJUiTwAAABEUlEQVQY001Q20rDQBTMz/qgiCi1iiD4AYIX6g0R/Baf+qZJG/0HQzVtc9lLNhnPnDTShWFn55yZPbtRZTxC2wLoUNYNjAuwgnzt4Juer0qP2jZwPvSa7ORd16GovfZUpsG68ohKEVhsQosstyilUNugnDr5z8qJsQ8keCnBQF5mpIdheeEQFZXTdCLLDQopkH//GjH1+mJp1cAQTjogyBBLCSk302mgsR796jSATa18gRHDoNvN81r9GiinzsUv4KKPnmiaLjC6n+HkcY6ju5nys+cUp08pjh/mGAnGUhvLzp7zl0/s38QKanvXsfbtXL6rN3qLM+xefeiBgds4nGydJ4OWbNWT//3gNsHF6xf+AGQYrA7BJ8qIAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 04&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/6cbf1f4c05306f02c3a609ebaa0c2682/d9199/001-04.png&quot;
        srcset=&quot;/devHistoryBlog/static/6cbf1f4c05306f02c3a609ebaa0c2682/8ff5a/001-04.png 240w,
/devHistoryBlog/static/6cbf1f4c05306f02c3a609ebaa0c2682/e85cb/001-04.png 480w,
/devHistoryBlog/static/6cbf1f4c05306f02c3a609ebaa0c2682/d9199/001-04.png 960w,
/devHistoryBlog/static/6cbf1f4c05306f02c3a609ebaa0c2682/07a9c/001-04.png 1440w,
/devHistoryBlog/static/6cbf1f4c05306f02c3a609ebaa0c2682/6bfbb/001-04.png 1514w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;h3&gt;느낀점&lt;/h3&gt;
&lt;p&gt;이번 프로젝트를 진행하면서 많은 경험을 하는것 같다.&lt;br&gt;
실 운영 상황에 맞게 테스트 셋을 만들었어야 했고, 미리 index 작업을 했었어야 했다.&lt;br&gt;
놓쳤던 부분이 많았다.  &lt;/p&gt;
&lt;p&gt;특히 인덱스 부분에서는 50만개 full scan 정도야 했는데… 이로인해 응답속도지연과 cpu 사용률이 문제가 되다니…&lt;br&gt;
DB를 너무 신뢰했던거 같다.
반성한다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[엔티티 매핑]]></title><description><![CDATA[자바 ORM 표준 JPA 프로그래밍 강의 복습]]></description><link>https://ssongey.github.io/history/posts/2021-01-28--001</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2021-01-28--001</guid><pubDate>Thu, 28 Jan 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt;@Entity&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;JPA는 내부적으로 replication 등을 쓰기 때문에 동적으로 생성할 수 있어야 한다.&lt;/li&gt;
&lt;li&gt;따라서 기본 생성자가 필요하다. (public 또는 protected)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; 데이터베이스 스키마 자동 생성&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DDL을 애플리케이션 실행 시점에 자동 생성&lt;/li&gt;
&lt;li&gt;데이터베이스 방언을 활용해서 데이터베이스에 맞는 적절한 DDL 생성&lt;/li&gt;
&lt;li&gt;운영 장비에는 절대 create, create-drop, update 사용하면 안됨.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;스테이징과 운영 서버는 validate 또는 none 사용&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;hibernate.hbm2ddl.auto=create&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/8bafaeaffae4ad205fd8c890ee4ef0e2/f6b72/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 615px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 49.583333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABYlAAAWJQFJUiTwAAABgklEQVQoz11Si5KDIAzk/7+wY0+tT1Twrah9pdlYbm6OmSgkZHeToJLbjaIoovv9Tu/3m/q+pzSBL6YkTakoCrGmacRS9mVZRtdrQFVd0zAMvL9SHMektSbVdR21bUvP51NsWRaaxpFGtmEYaZ5nsW3baF1XAThjvZyP45B8GGIKHyT2fUfWtnLZWkPGmO+lnkAKdmMtGVZpGiPqsM/znIEd+aVqDtR1Q5YBkAQCY/jMYACap0lIAI52gOy8cxJaJnGsHu1Chcq5lRMmejwe4oQi9MoDCBmUMQD8zjkmaqWagePGWOk/wIChsiylkIeCfshQWJUfQsegKKmqtPiwn6ZZzqgGpDn7AYT1er2g0AkYmg4mP4R5XmRAKBnx844TVYj7PBnidFb4VZhREARSFhZ6mrNP60pURGEoylBJWRYU8jlJEvFpXcozKkst1cGUrx9y930XZuc2UXwc++/7RBzmE32Oj+EeTN34QTbccL8wiMvl8lX3wz0qxY/Ev3+//p8/5ef6IzEOONcAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/8bafaeaffae4ad205fd8c890ee4ef0e2/f6b72/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/8bafaeaffae4ad205fd8c890ee4ef0e2/8ff5a/001-01.png 240w,
/devHistoryBlog/static/8bafaeaffae4ad205fd8c890ee4ef0e2/e85cb/001-01.png 480w,
/devHistoryBlog/static/8bafaeaffae4ad205fd8c890ee4ef0e2/f6b72/001-01.png 615w&quot;
        sizes=&quot;(max-width: 615px) 100vw, 615px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; 매핑 어노테이션 정리&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Date 클래스 사용시 만 @Temporal 사용, &lt;/li&gt;
&lt;li&gt;LocalData, LocalDateTime을 사용할때는 생략&lt;/li&gt;
&lt;li&gt;@Transient 는 주로 메모리상에서만 임시로 보관하고 싶을 때 사용

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/45f929eac456dc1de9fca946ff0503e6/17602/001-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 597px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 52.083333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABYlAAAWJQFJUiTwAAABN0lEQVQoz5VS2W7DMAzL/3/gCjRt7tRZlvs+y4kq8jBgWDoDhC1ZlilKVuD7SJIEiTEYxwlcnuvC9Tx4gmma8Z9ldV2Htm3RdS2WZcW6rqiqCn3fg3f7vmsg/e/AMsLsK8uQCYqiUCcZm4dRXxxFMCbB8/nEtm36wV+wWGqapoqiKPURz2VZKtMiz3VnwrcYOo6jjCJhQs3CMERT16LdhE6kKMtKmfbDoElPGfLhNI6qFzHIw0ccyyefyPNMP4vFpp/rNCGTjJLw0Ie0m6aRBL3653nSBtXCmjvvl2X5FVpyEAQq+tFNlhVFIULxs1QypAyMq+Wj07F5sZh/gAzpZ5lkRVloH6PE/TgfNmPJ0nLud/gy3LfbTZnqYHvuC+LnfpcY27a1adfrFRw1vrlcPsCm0mYllO0buVwCrbPX+lgAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/45f929eac456dc1de9fca946ff0503e6/17602/001-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/45f929eac456dc1de9fca946ff0503e6/8ff5a/001-02.png 240w,
/devHistoryBlog/static/45f929eac456dc1de9fca946ff0503e6/e85cb/001-02.png 480w,
/devHistoryBlog/static/45f929eac456dc1de9fca946ff0503e6/17602/001-02.png 597w&quot;
        sizes=&quot;(max-width: 597px) 100vw, 597px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; 기본 키 매핑&lt;/span&gt;
&lt;span class=&quot;title__sub2&quot;&gt; 기본 키 매핑 어노테이션 &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;@Id &lt;/li&gt;
&lt;li&gt;@GeneratedValue (전략은 AUTO가 기본)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; 전략 종류 &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;IDENTITY : 데이터베이스에 위임, MYSQL  &lt;/li&gt;
&lt;li&gt;SEQUENCE : 데이터베이스 시퀀스 오브젝트 사용, ORACLE&lt;br&gt;
— @SequenceGenerator 필요&lt;/li&gt;
&lt;li&gt;TABLE : 키 생성용 테이블 사용, 모든 DB에서 사용, 잘 사용하지 않음&lt;br&gt;
— @TableGenerator 필요&lt;/li&gt;
&lt;li&gt;AUTO : 방언에 따라 자동 지정, 기본 값&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;title__sub3&quot;&gt; IDENTITY 전략 특징 &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;주로 MySQL, PostgreSQL, SQL Server, DB2에서 사용 (auto_increment)

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/c9462d753e49bf719891215f260515da/b04e4/001-04.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 888px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 24.583333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAABYlAAAWJQFJUiTwAAAA0UlEQVQY05WQyW7DMAxE/TFBo82yFitarMR2kxQ99f//ZkplB9JLDw8cjKQhqe7ny2NJHGmUyJZj5w3qvCCmhMEMEJL/i+5cHZJhcFo8Aqf5kwIzeq3B+BZcNNiNV/3qXf1OGwc/MqTMsRXURbWDDfEBqSSF9lC9Ii2oyot+1qvfN60aEp21HhOFfR8lDkVgXQasq8W+WkxlQikHzPMJ3o8Iu0iNy2X6Rq57hBBRQkX0GaMLFOgsjGKIVtDqnB46BLrsrYOmSRitcv+ft1X/8H8BLxubKHOhWtMAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 04&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/c9462d753e49bf719891215f260515da/b04e4/001-04.png&quot;
        srcset=&quot;/devHistoryBlog/static/c9462d753e49bf719891215f260515da/8ff5a/001-04.png 240w,
/devHistoryBlog/static/c9462d753e49bf719891215f260515da/e85cb/001-04.png 480w,
/devHistoryBlog/static/c9462d753e49bf719891215f260515da/b04e4/001-04.png 888w&quot;
        sizes=&quot;(max-width: 888px) 100vw, 888px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;title__sub3&quot;&gt; SEQUENCE 전략 특징 &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;주로 Oracle, PostgreSQL, DB2, H2 에서 사용 (auto_increment)&lt;/li&gt;
&lt;li&gt;INSERT SQL 실행 후에 id 값을 알 수 있으므로 &lt;span class=&quot;text-mark__red&quot;&gt;해당 전략에서는 persist(add) 시점에 즉시 SQL이 수행&lt;/span&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/de9bd811bec00e9fc75ed4ca8edf2692/6acbf/001-05.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 36.66666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAABYlAAAWJQFJUiTwAAABSElEQVQoz11R206EMBTkY1ygLZSWQqHcFtwNa6Jmo4n//ynjABujPkwGTulcDtEyS5wnidAKOBcTCUonIDNCCQiZ7ryDs1Qkf7CdH3y8R8ZIaJ2i61rc758YhoDLuiCMAaU3aEa3ww8ljTSKQsNYg8JoWLLWOTRnusj3syhXCkoI1JXHbX3H7eUDr29fFF54sUA/DZiWZ0znmbMZfT+haTuKu0OwOEx2pknUWAmnJWwu4Zm28oFokeUZxKOWoqmUEiqTrCaQpDHnMeL0ic+nf5UpOI6SlQUdUrqeyPGernTVjk3clJZzVmUqW5ZMxXPj4KxDlqmfXUdaK9ZVaD1Fg8G6zrheJkzjgjYMmK8LfF+j5W4D0Z87DHOPtmMT61GVNfLfgnl21G0K7pGpmm6CrwMsEySsJRQr59tf5oXsAXVgq71/8xDb+BuHONvGjbZcJgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 05&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/de9bd811bec00e9fc75ed4ca8edf2692/d9199/001-05.png&quot;
        srcset=&quot;/devHistoryBlog/static/de9bd811bec00e9fc75ed4ca8edf2692/8ff5a/001-05.png 240w,
/devHistoryBlog/static/de9bd811bec00e9fc75ed4ca8edf2692/e85cb/001-05.png 480w,
/devHistoryBlog/static/de9bd811bec00e9fc75ed4ca8edf2692/d9199/001-05.png 960w,
/devHistoryBlog/static/de9bd811bec00e9fc75ed4ca8edf2692/6acbf/001-05.png 1001w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; 연관관계 매핑&lt;/span&gt;
&lt;span class=&quot;title__sub2&quot;&gt; 1) 단방향 연관관계 &lt;/span&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/89701b59782fe88fa50841f4d6a9d476/6fcb6/001-06.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 13.333333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAABcRAAAXEQHKJvM/AAAArklEQVQI1zWOyQqFMAxF/f9vcmUXDpviAEW6UBAHxKl1oeJwXxN4gZBFknOPp7VGXddYloV72zZM08Q9DMNHu3meTd/3uVIKSZK8VVXBGIPjOLDvO9Z1Rdd1SNMUHh01TcMHtLyui2fbtnBhHz07mMmyLBdCwPf9tygKDn+eh6EuEFJKBEEAL45jjOPIRgT7l7WWzD+azsBEUZQ7GMIwfMna2eM8T9z3zdCyLNnyB21+281pw44SAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 06&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/89701b59782fe88fa50841f4d6a9d476/d9199/001-06.png&quot;
        srcset=&quot;/devHistoryBlog/static/89701b59782fe88fa50841f4d6a9d476/8ff5a/001-06.png 240w,
/devHistoryBlog/static/89701b59782fe88fa50841f4d6a9d476/e85cb/001-06.png 480w,
/devHistoryBlog/static/89701b59782fe88fa50841f4d6a9d476/d9199/001-06.png 960w,
/devHistoryBlog/static/89701b59782fe88fa50841f4d6a9d476/07a9c/001-06.png 1440w,
/devHistoryBlog/static/89701b59782fe88fa50841f4d6a9d476/6fcb6/001-06.png 1523w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Member 와 Team 의 관계는 n:1&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;text-mark__red&quot;&gt;Member(n)에 Team(1)에 대한 FK가 들어간다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/82c81a0e165f16fcc110de4070cea69d/27e9a/001-07.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 55.00000000000001%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABYlAAAWJQFJUiTwAAABRElEQVQoz5VSSU4DMRCcT4Hb+xbPPiEsQSQSEhLi/08oehwFidMkh3Jf7HIt3fRJYswS0UkkQ0jeoXQTnI9QSoGIIKX8m1togmEiJvOM7AnBKexKRIy2El4v3kzoLKFlhc8jYT8pTHPCPDp0haCkgBB0l8rGaLYbJEoSyMmj7RcY42GcQcgOPrp/1jcJvZXoWeHLIDD3AfO8R9v26NsOiT/QVt2VZWOUxJrjmDSKV1yO4gg6WK3Z8oVM3ZOhXH+XGim3yDtGLqwsVQzDUKe1hu/QTQU16+HYdmaFKV6gWZ1kgnUSl/L4eClHCLFpnRUSloXw8y1wPgl8fT5g4pan+RUxZVguJ3e8RjuPkMK2QsUZDlzKaVF459VZ5oLjxxFvhzMO4xNnSHDBwnpTybcJ+ViLqag5rZb5IUlopevjuotXbFj+BTAfdwzk6J+0AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 07&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/82c81a0e165f16fcc110de4070cea69d/d9199/001-07.png&quot;
        srcset=&quot;/devHistoryBlog/static/82c81a0e165f16fcc110de4070cea69d/8ff5a/001-07.png 240w,
/devHistoryBlog/static/82c81a0e165f16fcc110de4070cea69d/e85cb/001-07.png 480w,
/devHistoryBlog/static/82c81a0e165f16fcc110de4070cea69d/d9199/001-07.png 960w,
/devHistoryBlog/static/82c81a0e165f16fcc110de4070cea69d/27e9a/001-07.png 1253w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; 2) 양방향 연관관계와 연관관계의 주인 &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/82994e919072969ac58ce85f26bb482e/d4b10/001-08.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 14.583333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAABcRAAAXEQHKJvM/AAAAsklEQVQI1zVPywqDQBDz/3+nJw/iSUoVVDx4WXyAug4+1kcFPdhNd5Z2IAxkQpJxxnGEEAJd16FtW2zbhnVdQUTo+/7D3LIsz6ZpgjiOEYbhLaW0un3f7S7LElEUWR+nrmvkeY55njFNE87zxHVdGIYBfPsZvpIkCVzXhe/7N/OGs1oGm3mehzRN4RghGUNSSpFJIwAWx3GQaSTN7V1V1aMoiiDLMm5z/4O11uDhcOb4sy9Xl9nWvP387AAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 08&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/82994e919072969ac58ce85f26bb482e/d9199/001-08.png&quot;
        srcset=&quot;/devHistoryBlog/static/82994e919072969ac58ce85f26bb482e/8ff5a/001-08.png 240w,
/devHistoryBlog/static/82994e919072969ac58ce85f26bb482e/e85cb/001-08.png 480w,
/devHistoryBlog/static/82994e919072969ac58ce85f26bb482e/d9199/001-08.png 960w,
/devHistoryBlog/static/82994e919072969ac58ce85f26bb482e/d4b10/001-08.png 1394w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
     &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;연관관계의 주인은 외래키의 위치를 기준으로 정해야함&lt;/li&gt;
&lt;li&gt;주인이 아닌쪽은 읽기 전용&lt;/li&gt;
&lt;li&gt;주인이 아니면 mappedBy 속성으로 주인 지정&lt;/li&gt;
&lt;li&gt;여기서는 Member.team 이 연관관계의 주인이 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/12a145746b2afb751f6adaabafcb2dcc/bce1e/001-09.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 29.166666666666668%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABcRAAAXEQHKJvM/AAABSElEQVQY02WPzWrDMBCE/VTxSpYsWXbkPzm2E4ceCrn0ZAqCPm0CPpc+Q2vCVHGhFHr4GHYXZmYjVzIYRdBKIjM5eJKAMXYPgIhuY0cXV9Gr5GyWUs2cizns53APyjb9S1RkDPWeUFqJqkyRJIQ4pmAYlNhSGvZu8xCaxjBGQekUjOgR+gv9maOyILRVgqp2MJlClqeQSmwNY6JFJOzaWAph8qss1VoYWkPYGtoF/U9kNUNrOPa5RWEsUim2lynemi6C03Uf2ulUfCqdrzo1K+d8DWHBlNY4jn/Y7TaNmpowDoSD2yHLHi9LJILfQ0twIRat+cfpaDCdCvR9j6fzBXXlkBsBa3Po7IFBXlgopRB1FcPzSJiOGabpjMGdICW/q2AuU3GTUr60nXvrx8HXdeu7evS2aHxluG8q6xvX+7p1/jAcvbWl/wYfsMGQJfFvyQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 09&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/12a145746b2afb751f6adaabafcb2dcc/d9199/001-09.png&quot;
        srcset=&quot;/devHistoryBlog/static/12a145746b2afb751f6adaabafcb2dcc/8ff5a/001-09.png 240w,
/devHistoryBlog/static/12a145746b2afb751f6adaabafcb2dcc/e85cb/001-09.png 480w,
/devHistoryBlog/static/12a145746b2afb751f6adaabafcb2dcc/d9199/001-09.png 960w,
/devHistoryBlog/static/12a145746b2afb751f6adaabafcb2dcc/07a9c/001-09.png 1440w,
/devHistoryBlog/static/12a145746b2afb751f6adaabafcb2dcc/bce1e/001-09.png 1696w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; 2) 양방향 연관관계 주의 &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;순수 객체 상태를 고려해야 상항 양쪽에 값을 설정

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/1b3d68050c0b6dfe020b518f504c9966/2e367/001-10.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 45.416666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAABcRAAAXEQHKJvM/AAACb0lEQVQoz1WPy08TURTG79K9O/0HTFp2MJ2ZznSmM/fOoy2lFXfGGGI00Y1CH6AJxEAjiBIQiRYf8Q8wsaELTUzEFyDSdgoincICkyaYdoEuZMW0HO80kcTFL9/JzXfO/T50cHCQ29vby+3v/6L6M1ev13ONRiPnOE4OAPKUM41GHdVqtVK1aoNt281KpeJqm+3t7ba6b7u7u4DS6UFIpdOQSiUhnUrA4NAQJBKJY5LJZGB45DaKdEeteO85iMXjzVjUhNjZOJimARhjIIS0cWfkFyVHVrATkGRHEHwOwzJOh9d76PF4XMDr9XIBKYiCCraIbgDRzSYmGASBB5ZlgWGY/0CRaAzMUBjCVHWdgEZkuqQfSQHxiOd5EESR74n3Ik03LQroRqh9ECsiaIYBUiAAHMcdgxQVN1WMmxiTZjAoNxVVphp0qNHx+/1uCi4ciSIVk2IoHIFwd8+hYYZaRNdammG2ZFlucRzbYjmOKteiVVTQ2lUMoMcBE92tBaqqgpuQmsTuWBxhTd9y27heerQNDQGiKALvfvwvIVbV17qq5g1C8qam5QWWyfNMV57r6lzgfcwbmtCjBBUkSfIroig2ZY36iiLPFtmuzqLA+oo8wxT9PqbIsj4bDcw8uXhl/MHkpcz0aGr2WebmoxeZa5NzY4NzzyduTGcTq9+rJ+ZfLqDL/alTF26NTfWNjD89PzT6uH9yNjtw72G2b/hO9vrETPZq5v788N2pDrS8vvnlk/UNPpc34f1aCRZXC7C8sQVLdF6yNn6XK9WTK9Y6suyd0+8K5T+LhTIsFtbh7coa5St8KNHd0gZ8pNg/atxfBw9136rWU9YAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 10&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/1b3d68050c0b6dfe020b518f504c9966/d9199/001-10.png&quot;
        srcset=&quot;/devHistoryBlog/static/1b3d68050c0b6dfe020b518f504c9966/8ff5a/001-10.png 240w,
/devHistoryBlog/static/1b3d68050c0b6dfe020b518f504c9966/e85cb/001-10.png 480w,
/devHistoryBlog/static/1b3d68050c0b6dfe020b518f504c9966/d9199/001-10.png 960w,
/devHistoryBlog/static/1b3d68050c0b6dfe020b518f504c9966/2e367/001-10.png 1066w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;li&gt;연관관계 편의 메소드를 생성하자&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token annotation punctuation&quot;&gt;@OneToMany&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;mappedBy &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;member&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Member&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; memberList &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ArrayList&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;addMember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Member&lt;/span&gt; member&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// 양반향 연관관계 매핑&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;memberList&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;member&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    member&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;updateTeam&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;양방향 매핑시에 무한 루프를 조심하자&lt;br&gt;
— ex) toString(), lombok, JSON 생성 라이브러리&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[영속성 관리 - 내부 동작 방식]]></title><description><![CDATA[자바 ORM 표준 JPA 프로그래밍 강의 복습]]></description><link>https://ssongey.github.io/history/posts/2021-01-25--001</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2021-01-25--001</guid><pubDate>Mon, 25 Jan 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; #JPA에서 가장 중요한 2가지 &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;객체와 관계형 데이터베이스 매핑&lt;/li&gt;
&lt;li&gt;영속 컨텍스트 (매커니즘)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; #Entity Manager Factory 와 Entity Manager &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Factory에서 Entity Manager 생성&lt;/li&gt;
&lt;li&gt;Manager에서 DB Connection을 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/796220b97cd1d89e69e4bab3f897de77/56e36/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 60%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAABYlAAAWJQFJUiTwAAABaUlEQVQoz3WSWa+CQAyF5///Nd94wBAEF5BFVEQ2l2hvvt6UcBcnaWamy+k5nXHv91tYp9NJjsej1HUt5/NZDd9qtZLlcilRFGnM4pfLRfPJYYGDOQOsqkoTm6bRZHbunufJYrEQ3/e1GEDiGGfq/gWkuOs6GYZB+r6frG1buV6vGs+yTMIwVLYAAYr/IyCFgAA8N3ywKctSgiBQUBSY/I+AsIEhNo6j3O93KYpC4jjW4sPh8EMF+X9miAOzQdMZORTnea7yLG5jMDWAG6AtBwhOmCAJsPV6rbJ44f1+r3FjT6MkSSY/BJ7Pp+6ocoDw/BSYHALs3HmIzWajPlghHR8E7EvRwL6Qm/85kukECxpRkKapsqaBjWe73eo4AMJMITgOgLlkwCjgIZCONBoBvtvt1IdxhhUjYz0eD3m9Xt+SAbEZ3W433bnPfci3HTCYMwb7NtOj2AEmvCjsfhsznO8AIhUVAM+/zRdQw42UZm+aQwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/796220b97cd1d89e69e4bab3f897de77/d9199/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/796220b97cd1d89e69e4bab3f897de77/8ff5a/001-01.png 240w,
/devHistoryBlog/static/796220b97cd1d89e69e4bab3f897de77/e85cb/001-01.png 480w,
/devHistoryBlog/static/796220b97cd1d89e69e4bab3f897de77/d9199/001-01.png 960w,
/devHistoryBlog/static/796220b97cd1d89e69e4bab3f897de77/07a9c/001-01.png 1440w,
/devHistoryBlog/static/796220b97cd1d89e69e4bab3f897de77/56e36/001-01.png 1750w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; # 영속성 컨텍스트 &lt;/span&gt;&lt;/p&gt;
&lt;ul&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;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/6cdcc3d9ecfda713e2edfeb4ecea79be/21482/001-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 42.91666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAABYlAAAWJQFJUiTwAAABc0lEQVQoz31Sy5KCQAzk/z/Ci/oFHvwArfLi6yC+KBWkSlhFAXnJAPYmWcfaw7pT1TUJkzRJJ8bz+cSnMxwO0ev15G61Wmi324ii6M9YzWNop65ruZumkYeqqjAYDNDv94Ww2+2i0+ngfD7LO8dpcJ6GEJZlidFohOl0ivV6jfF4jNVqhfl8juVyiclkIj5jNpsJTNPEdruF7/tI0/Rd5bvCPM9RFIWQa5uRZRmSJBFoO47jt/94PAgllKp+COtXyXXdUJs1/jscxwRpmhFZTj9XKJUiMoXgesXtFsL4Ik0sy8J+v8fhcIBtO1JhFMW4cxVkH+hbSMO4UtJut4PjOBRny805jmMjDEMhNTzPx2azJWxIEwuLhYlLEOB+T0Qbz/NwPLq4UQL7moyJXNeltyPBofg7IpLC4OkqmmiSpKIZn/o1aZ7g6XQSOyW9uHKOZ52L4iFt6/Yvl0C6MD7t0+/91OukXnoxIWvJpFxEnhfic8w3YGWq05VFy/EAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/6cdcc3d9ecfda713e2edfeb4ecea79be/d9199/001-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/6cdcc3d9ecfda713e2edfeb4ecea79be/8ff5a/001-02.png 240w,
/devHistoryBlog/static/6cdcc3d9ecfda713e2edfeb4ecea79be/e85cb/001-02.png 480w,
/devHistoryBlog/static/6cdcc3d9ecfda713e2edfeb4ecea79be/d9199/001-02.png 960w,
/devHistoryBlog/static/6cdcc3d9ecfda713e2edfeb4ecea79be/21482/001-02.png 1350w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; # 엔티티의 생명주기 &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class=&quot;text-mark__red&quot;&gt;비영속 (new/transient) &lt;/span&gt;
— 영속성 컨텍스트와 전혀 관계가 없는 새로운 상태&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;text-mark__red&quot;&gt;영속 (managed)&lt;/span&gt;
— 영속성 컨텍스트에 관리되는 상태&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;text-mark__red&quot;&gt;준영속 (detached)&lt;/span&gt;
— 영속성 컨텍스트에 저장되었다가 분리된 상태&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;text-mark__red&quot;&gt;삭제 (removed)&lt;/span&gt;
— 삭제된 상태&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/98c14163f5b2716eb8e8d530b04856f8/36eca/001-03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 71.66666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAABYlAAAWJQFJUiTwAAABR0lEQVQ4y4WTba+CMAyF+f8/Dr4bXkRARUF5U1DQ3jxLRoA7pEmzjXZn57TFEoN9v99xrapK0jSV6/Uq9/tdPp/PLGdp1hbg7XaTIAiUn89n6ft+jJlAfwJqNofDQS6Xyyy+ylAHp66BkGjbtux2O2maRp3zPJ/lLh8wMtT2eDwUoO/7Ute1kp9lmRFwZPh+v6XrOnm9XmqFnb6oDbnIXivP1K2yLJWU/X6vWADE5TAM5XQ6qUbQEM5RFI215Jvruv9riCxGg9qwwlgbe+JxHIvneephQMnVK6zIwdu2Xe/ytC6oYA6nDx2PR/UQDUMJ+6IozF3WYCQkSTJjxZBjqOEhx3HUN+KcLVNhNSBDDBuSkcseH4ZhlEkOMRSsSl6OAiy15OfzqZrHN3zzT5kyZIRgR9e5TN1g9XNstv5l2OgGMJ8moOmdP2MRQbjgo7ZpAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/98c14163f5b2716eb8e8d530b04856f8/d9199/001-03.png&quot;
        srcset=&quot;/devHistoryBlog/static/98c14163f5b2716eb8e8d530b04856f8/8ff5a/001-03.png 240w,
/devHistoryBlog/static/98c14163f5b2716eb8e8d530b04856f8/e85cb/001-03.png 480w,
/devHistoryBlog/static/98c14163f5b2716eb8e8d530b04856f8/d9199/001-03.png 960w,
/devHistoryBlog/static/98c14163f5b2716eb8e8d530b04856f8/07a9c/001-03.png 1440w,
/devHistoryBlog/static/98c14163f5b2716eb8e8d530b04856f8/36eca/001-03.png 1526w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// 비영속&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;Member&lt;/span&gt; member &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Member&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
member&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;100L&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
member&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setUserName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;member1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;//영속&lt;/span&gt;
entityManager&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;persist&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;member&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;//회원 엔티티를 영속성 컨텍스트에서 분리, 준영속 상태&lt;/span&gt;
entityManager&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;detach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;member&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;//객체를 삭제한 상태(DB에서 삭제)&lt;/span&gt;
entityManager&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;remove&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;member&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; # 영속성 컨텍스트의 이점 &lt;/span&gt;
&lt;span class=&quot;title__sub2&quot;&gt;1) 1차 캐시&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1차 캐시는 한 트랜젝션에서만 허용된다.&lt;/li&gt;
&lt;li&gt;성능보다는 매커니즘에 이점에 있다.&lt;/li&gt;
&lt;li&gt;1차 캐시에서 조회

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/5a9d8c885d4d60229e8c8f111bfc1075/b5a09/001-04.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 50%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABYlAAAWJQFJUiTwAAABRElEQVQoz22S646CQAxGef838ycxJqgo3rgoXlFAjfptTrMlmN0mzZR2OP2mM4F+7fP5mGPn81m73U7H41GHw0Fpmmq9Xmuz2XzFWZZZve/Bf0BAl8tFbduqrmtNJhONRiNFUaTpdNrF8/nc6jh79/u9Agf1gafTyVSy8Xa76fF46Pl86n6/q2ka+5kY9z3kDaie9RX2gTjHK8tSq9VKs9nMRpLn+V/g+/0WDozVZ1hVlSm5Xq/abrcGGY/HBgI+GAwUhqGKorDxdEDUJElig14sFlbkB7pTI08dIOoYPDlmGcexXQ5NvxS+Xi9zZsWKCn4ECHy5XFoD1LCi2JuS4zQdkOPRDQV05pgoGQ6HnSoUuHERNHajBpC8PRsSyHbpGJ2A8+ZQy2WgihhFODFO3mdO/HXLbjwbh/kx3R3Y/2ZlBAj5Adv49Wnk6xpZAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;1차 캐시에서 조회&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/5a9d8c885d4d60229e8c8f111bfc1075/d9199/001-04.png&quot;
        srcset=&quot;/devHistoryBlog/static/5a9d8c885d4d60229e8c8f111bfc1075/8ff5a/001-04.png 240w,
/devHistoryBlog/static/5a9d8c885d4d60229e8c8f111bfc1075/e85cb/001-04.png 480w,
/devHistoryBlog/static/5a9d8c885d4d60229e8c8f111bfc1075/d9199/001-04.png 960w,
/devHistoryBlog/static/5a9d8c885d4d60229e8c8f111bfc1075/b5a09/001-04.png 1360w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;li&gt;데이터베이스에서 조회

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/89ad050cd24740b61c36a3eb4c014aef/0486e/001-05.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 43.75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAABYlAAAWJQFJUiTwAAABN0lEQVQoz3WS0Y6CQAxF+f9Pw/hgQgwqgoCIighBQFCgu6fJGNxkm5QZSjm97Ywlv/Z+v+V+v0tZlurX61VOp5OkafrlJqcoCl2xaZpkbhaPtm01uWka3R+PR1mv17LdbmW/38tut5PNZqOQ5/OpeXme/w9E4ePxkNfrpcCu66Tve6nr+qMKkIERnwPnbpF0OBzEdV1VlCSJAuI4Vg+CQMIwVKWMoqqqL+Bfs1AFbLlcim3b+vPlctEiwABEUSSLxUK/MT/T8jAM2hGrUastoxKIORBgqOOdls0ciZv2syzTfyh2u920AG5RjQAg5sg7JwqEw+EbygASA0ARYCijw/P5rK5AkhzH0UTP87R9rgxuqpJsYigEtlqtxPd9dWIfhWYOJHMgtGr2KMTZG0c9OazjOOoNmdsPg0mnQoY7iNQAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;데이터베이스에서 조회&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/89ad050cd24740b61c36a3eb4c014aef/d9199/001-05.png&quot;
        srcset=&quot;/devHistoryBlog/static/89ad050cd24740b61c36a3eb4c014aef/8ff5a/001-05.png 240w,
/devHistoryBlog/static/89ad050cd24740b61c36a3eb4c014aef/e85cb/001-05.png 480w,
/devHistoryBlog/static/89ad050cd24740b61c36a3eb4c014aef/d9199/001-05.png 960w,
/devHistoryBlog/static/89ad050cd24740b61c36a3eb4c014aef/07a9c/001-05.png 1440w,
/devHistoryBlog/static/89ad050cd24740b61c36a3eb4c014aef/29114/001-05.png 1920w,
/devHistoryBlog/static/89ad050cd24740b61c36a3eb4c014aef/0486e/001-05.png 2008w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
       &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; 2) 동일성 보장 &lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Member&lt;/span&gt; a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; entityManager&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Member&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;member1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;Member&lt;/span&gt; b &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; entityManager&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Member&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;member1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token class-name&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 동일성 비교 true&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; 3) 트랜잭션을 지원하는 쓰기 지연 (transactional write-behind) &lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;EntityManager&lt;/span&gt; entityManager &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; entityManagerFactory&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createEntityManager&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;EntityTransaction&lt;/span&gt; transaction &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; entityManager&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getTransaction&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;//엔티티 매니저는 데이터 변경 시 트랜잭션을 시작해야 한다.&lt;/span&gt;
transaction&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

entityManager&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;persist&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;memberA&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
entityManager&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;persist&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;memberB&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//여기까지 INSERT SQL을 데이터베이스에 보내지 않는다.&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;//커밋하는 순간 데이터베이스에 INSERT SQL을 보낸다.&lt;/span&gt;
transaction&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;commit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br/&gt;
&lt;ul&gt;
&lt;li&gt;entityManager.persist(memberA/B);

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/6a39605d2fbb606cce225caafc123e1f/c2d9c/001-06.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 115.41666666666669%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAXCAYAAAALHW+jAAAACXBIWXMAABYlAAAWJQFJUiTwAAACaElEQVQ4y23VCU8rMQwE4P3/Pw6QoOK+b2jLfR9Bn6VZpa9vJbPdxBl7xo4Zvr6+2sPDQ7u/v2/Pz89lj4+P7eDgoG1tbbXd3d22t7dX77Ozs9rj//T0VL+Z5/f3t97D5+dngXF6eXkZ7ejoqG1vb7f9/f0C3NjYqCD87u7uRlsC9CcgwF9fX9t8Ph+dmb3b29vaCwt2fn5eAQLIhpOTk7a5uVn0dnZ2Cuj6+rodHx+XWUMVi9lsVr8B+S0Y//4Zbm5uih5DDS0mI860Auabra6ulgwABQ5lGb+9vbVBmj5CezqdNkGY7/f393IEbA2YDFOcANtzdiwKA+AwR4ccRpumvh0kkd8Yydi5BAM+pG36KqN6eXnZLi4uSjMgAIADoOva2tpYdc/Hx0eDtQQY+jJlKis6YJnKAvjp6WkBCrBQlADSxOG+F31HK8/Pz0/Ro+v393cFCODYNgDTEjmcmxNLhflEfGBk6QErQ5Es0getGOerq6sFs6YgjA/amCwAWgDY06UjfTS83mQKATB3vb81C4A2UPQOqLcgaNlDEwNUI0ko03RBQxv6S6vQSETtolW8AdFPoGicO85/ScPJZFLXyTRZWVkpbaIZQG/ggOxllNkLg3RAZRjKek7E9Bc69qzLGgPU7Qsss9xltFP5Ic4pRn9HUU3Dc/atUIeHhwXe32WAdZdT5QDKipNDBqzqahNauiEOob2+vl7rskNXQMksAcb6MU8vATLSBDI/BYiG49ULYA/Wj7NMErQcBmoKxTIPx6I4DDBz71/LcFDpCC9bhbO29D/FIVFVL1fqf5ZRxi8GsG9szx8Kyszrvr6KQgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 06&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/6a39605d2fbb606cce225caafc123e1f/d9199/001-06.png&quot;
        srcset=&quot;/devHistoryBlog/static/6a39605d2fbb606cce225caafc123e1f/8ff5a/001-06.png 240w,
/devHistoryBlog/static/6a39605d2fbb606cce225caafc123e1f/e85cb/001-06.png 480w,
/devHistoryBlog/static/6a39605d2fbb606cce225caafc123e1f/d9199/001-06.png 960w,
/devHistoryBlog/static/6a39605d2fbb606cce225caafc123e1f/c2d9c/001-06.png 1326w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;li&gt;transaction.commit();

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/79ccf2f419dc41d24a05841bf2285535/7ef4c/001-07.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 57.91666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAABYlAAAWJQFJUiTwAAABbklEQVQoz3WTjaqCQBCFff8nCwyCIMuCQksts1/NCsSJ78CEdLkLw46zZ8+cmR2DqqqsaRp7PB623+9tPp/L1uu1LZdLWywWirdtK9ztdtPO6vv+zx4cj0eBn8+nlWUpAgg3m42tViuL41jx9/stTF3XsiHRcAXn81lAskL8er10mUvX69Xu97t2cKfTSeYKu64Tnuq4I4UoQSVBgBDhE+Py5XKROenhcNA5C2yapjabzXSOoGA6nao0LhMAjNEr1BF3cvrtqlFHgqIo1CZXHuBA4L0BzDeq8P0xiHmC3W4nZXme23g8tiiKRC5CsuPQeBQkSSKf0kjgSjHvKzHvoRORUCVnWaZMk8nEttut/DAMbTQaqRzvqV+AmDHyVpAYUnBfQoIQcYA6ZhDjzAmHZfsD4POyrl5jQz8gRA1AdmaPvqAYIGROOBzs36WxcfkoA0wfiUE8HHqMmfsd7KF9FWKUhyL/9tivESfJf3/KB7DJj3oMb8FgAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 07&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/79ccf2f419dc41d24a05841bf2285535/d9199/001-07.png&quot;
        srcset=&quot;/devHistoryBlog/static/79ccf2f419dc41d24a05841bf2285535/8ff5a/001-07.png 240w,
/devHistoryBlog/static/79ccf2f419dc41d24a05841bf2285535/e85cb/001-07.png 480w,
/devHistoryBlog/static/79ccf2f419dc41d24a05841bf2285535/d9199/001-07.png 960w,
/devHistoryBlog/static/79ccf2f419dc41d24a05841bf2285535/07a9c/001-07.png 1440w,
/devHistoryBlog/static/79ccf2f419dc41d24a05841bf2285535/7ef4c/001-07.png 1748w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; 4) 변경 감지 (Dirty Checking) &lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;EntityManager&lt;/span&gt; entityManager &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; entityManagerFactory&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createEntityManager&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;EntityTransaction&lt;/span&gt; transaction &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; entityManager&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getTransaction&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;//영속 엔티티 조회&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;Member&lt;/span&gt; memberA &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; entityManager&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Member&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;memberA&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;//영속 엔티티 데이터 수정&lt;/span&gt;
memberA&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setUsername&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;hi&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
memberA&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setAge&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;//커밋하는 순간 데이터베이스에 UPDATE SQL을 보낸다.&lt;/span&gt;
transaction&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;commit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/f948d2a79296874c2fcb74192171d7ed/37c35/001-08.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 60.83333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAABYlAAAWJQFJUiTwAAABgklEQVQoz22S646CUAyEef83wx+GaEy8i1dURBDvN7r5JukucT1JpUI7M53TYLfbGbHf7y3Pc1ssFjYcDm08HitGo5HFcWxZluk7ddS/32/jVFVl9ROkaWpFUdj1erX7/W6bzcYmk4nNZjOBkxNlWSoul4sAX6/Xd0BYiSRJBMJztVpJCU+aIUEpgOv12hBRB6xHMJ/PVYyK5XKp4B3A5DRDNJ1O9Q4CiPz8UzgYDKzf78uv0+mk0RmL/Hw+2/F4FKgrxks8RS3gHKyill55yBhcBEp7vZ4I3FsKaXg8HiICCKUohgA7AIaIZ8CP++jjUowKB6WR96hEud84QtrttuoOh4PIpNAZu92ubbdbFYZhKKXkzWZT/1EDICLoYyr8xS6sgUgKaWJFAEMRSn3/yDudjrVaLRG7QvwCBDu4GNTdbrc/QF8HX24uC1BGjaLIGo2GwPEUQF/sz/N7KUinAQKU+HL7fvK/PvLz+fy+hxRhOuOSAwABuSuvB9/55vv3uYc/z36HbbdVIcAAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 08&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/f948d2a79296874c2fcb74192171d7ed/d9199/001-08.png&quot;
        srcset=&quot;/devHistoryBlog/static/f948d2a79296874c2fcb74192171d7ed/8ff5a/001-08.png 240w,
/devHistoryBlog/static/f948d2a79296874c2fcb74192171d7ed/e85cb/001-08.png 480w,
/devHistoryBlog/static/f948d2a79296874c2fcb74192171d7ed/d9199/001-08.png 960w,
/devHistoryBlog/static/f948d2a79296874c2fcb74192171d7ed/07a9c/001-08.png 1440w,
/devHistoryBlog/static/f948d2a79296874c2fcb74192171d7ed/37c35/001-08.png 1810w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt; 5) 지연 로딩 (Lazy Loading) &lt;/span&gt;  &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;추후 뒤에서 다시 정리&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; # 플러시 &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;영속성 컨텍스트의 변경 내용을 데이터베이스에 반영&lt;/li&gt;
&lt;li&gt;플러시가 발생되면 1차 캐시에 있는 정보가 사라지는게 아니라 쓰기 지연 SQL 저장소에 있는 SQL이 실행된다.&lt;/li&gt;
&lt;li&gt;JPQL을 사용하면 자동으로 flush가 날라가고 해당 쿼리가 실행된다.&lt;/li&gt;
&lt;li&gt;트랜잭션이라는 작업 단위가 중요! (커밋 직전에만 동기화 하면 된다.)&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;</content:encoded></item><item><title><![CDATA[Git Repository 이동]]></title><link>https://ssongey.github.io/works/posts/2021-01-23--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2021-01-23--001</guid><pubDate>Sat, 23 Jan 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;생각보다 레파지토리 이동 작업을 많이한다..&lt;br&gt;
commit 등의 이력까지 같이 이동하는 방법이다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;git clone --mirror [기존 리파지토리 주소]

cd [기존 리파지토리 명].git

git remote set-url --push origin [신규 리파지토리 주소]

git push --mirror&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[[작업로그] CI/CD 구축 #5]]></title><description><![CDATA[sonarqube 설치 및 pipeline 작성]]></description><link>https://ssongey.github.io/works/posts/2021-01-23--002</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2021-01-23--002</guid><pubDate>Sat, 23 Jan 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; Sonarqube ? &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;20개 이상의 프로그래밍 언어에서 버그, 코드 스멜, 보안 취약점을 발견할 목적으로 정적 코드 분석으로 자동 리뷰를 수행하기 위한 지속적인 코드 품질 검사용 오픈 소스 플랫폼 &lt;/li&gt;
&lt;li&gt;중복 코드, 코딩 표준, 유닛 테스트, 코드 커버리지, 코드 복잡도, 주석, 버그 및 보안 취약점의 보고서를 제공.&lt;/li&gt;
&lt;li&gt;sonar scanner에게 정적 분석 관련 데이터 제공&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; 정적분석을 위한 Sonarqube 설치 &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://hub.docker.com/_/sonarqube/&quot;&gt;https://hub.docker.com/_/sonarqube/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt;1. host 설정&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;sonarqube 내부에 Elasticsearch 를 사용하고 있기 때문에 필요 설정이 있다

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/7a24aa1ce8afd1f2e94e6157c789e279/e619b/002-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 787px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 38.75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAAAsTAAALEwEAmpwYAAABFElEQVQoz5WS6XKDMAyE/f5P2XaSkHAYXxiDIRutSDNp/8UzHysLRiemsw6npkXT9srX6YLztcX3ucHgPHju9zsff5Tsu/CrT9ukKcOHeBATnKjzAcPoENOEsizK8tIVpSyYhWkuwoxMzbP6zBgSWpfQ+UOHkNH7CVcbcBsjWuvRjUHvrYvquwweYWKAokGZiMrAhlU1vUXvgtJJAOujkMBkltWKnzZxcdL3XqpPOSNKh078rJDHsC0rs2KrQYKzdWbe9x21VqxP6j/Uvx4s66p3ztVwJjFlzPOimazj/Lza27Zjq5vodug72zvHd1UwTsr/Od9ks51uu5etk1LWVwWfYLiZIHMZJXDORefAX4CZa/2cB6aQbL0or2ucAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/7a24aa1ce8afd1f2e94e6157c789e279/e619b/002-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/7a24aa1ce8afd1f2e94e6157c789e279/8ff5a/002-01.png 240w,
/devHistoryBlog/static/7a24aa1ce8afd1f2e94e6157c789e279/e85cb/002-01.png 480w,
/devHistoryBlog/static/7a24aa1ce8afd1f2e94e6157c789e279/e619b/002-01.png 787w&quot;
        sizes=&quot;(max-width: 787px) 100vw, 787px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# max_map_count ?
This file contains the maximum number of memory map areas a process may have. Memory map areas are used as a side-effect of calling malloc, directly by mmap and mprotect, and also when loading shared libraries.
While most applications need less than a thousand maps, certain programs, particularly malloc debuggers, may consume lots of them, e.g., up to one or two maps per allocation.
The default value is 65536.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt;2. DB 및 Volumes 설정 내용 &lt;/span&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/5ab97f9516fe199f8f2313f58a223c46/0f67e/002-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 921px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 58.333333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsTAAALEwEAmpwYAAABT0lEQVQoz5VSCW6EMAzM/7/Zll2uHJBwB9fjEHZXQqhFGtkGfIzH6utR0bNuyXY94dn3/QS9+VfxFdRPWVMYxpTwx+e2YNlo8mEgPww0jJP4vQ+nxTs0BDqOp3m5baZAtagaarSl1rjT1rDWkbadADG+GddJYcd58JEPaPbXbSOFj6D94D0WZSN+gZibANhvslrw/cS/bGtDBQP53cEogrK2aSrp2vujuz/jPsAywkRumMj6kSz7Nswcz+SnhcZle1EG3ao1Mu62RYoxigXwLsb9X+KoPAn2lPeRdwfrWYxNmiWs60oLA/5lwcDqVqw00JpPQeAL2LeHCFhPzYw6HuJqUoXTSIuvmbo+E6FaVt24npsYKdyYVyOww7TvRRXuq+GfAUxoOEnE6dMq8mngHpGAHWekHcfPglAUZ4HEnJysl8lwBZgWFPFtWdZbcX4BkPCjJeTqvfkAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/5ab97f9516fe199f8f2313f58a223c46/0f67e/002-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/5ab97f9516fe199f8f2313f58a223c46/8ff5a/002-02.png 240w,
/devHistoryBlog/static/5ab97f9516fe199f8f2313f58a223c46/e85cb/002-02.png 480w,
/devHistoryBlog/static/5ab97f9516fe199f8f2313f58a223c46/0f67e/002-02.png 921w&quot;
        sizes=&quot;(max-width: 921px) 100vw, 921px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt;3. Compose 파일 작성&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;sonarqube develop edition 버전 설치 (trial 라이센스 문의 함)&lt;/li&gt;
&lt;li&gt;embedded db : postgres 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;version: &amp;quot;3.7&amp;quot;
services:
  db:
    image: postgres
    container_name: sonar-postgres
    restart: always
    environment:
      POSTGRES_USER: sonar
      PASTGRES_PASSWORD: sonar
      TZ: Asia/Seoul
      POSTGRES_HOST_AUTH_METHOD: trust
    volumes:
      - ~/docker-volumes/sonar-postgres/postgres:/var/lib/postgresql/data
  
  sonarqube:
    image: sonarqube:8.6.1-developer
    container_name: sonarqube
    restart: always
    environment:
      SONARQUBE_HOME: ./
      SONARQUBE_JDBC_USERNAME: sonar
      SONARQUBE_JDBC_PASSWORD: sonar
      SONARQUBE_JDBC_URL: jdbc:postgresql://db:5432/sonar
    depends_on:
      - db
    ports:
      - 10002:9000
    volumes:
      - ~/docker-volumes/sonar-postgres/sonarqube/data:/opt/sonarqube/data
      - ~/docker-volumes/sonar-postgres/sonarqube/extensions:/opt/sonarqube/extensions
      - ~/docker-volumes/sonar-postgres/sonarqube/logs:/opt/sonarqube/logs
      - ~/docker-volumes/sonar-postgres/temp:/opt/sonarqube/temp&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt;4. 서비스 기동&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ docker-compose -f sonarqube-compose.yml up -d&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; 정적분석을 위한 Sonarqube 프로젝트 생성 및&lt;/span&gt; &lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt;1. Sonarqube 프로젝트 생성&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;10002 포트로 접속 후 로그인 &amp;#x26; 프로젝트 생성

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/1ec4e0187cad189410f134a4520be1a9/eea79/002-05.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 502px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 77.91666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAACXBIWXMAABJ0AAASdAHeZh94AAAB7UlEQVQ4y51U2ZKbMBDk//9r31K1VCWEG4MtcUqAkMBHkupIwnYZZ3ezyUMzYhjaPT2DnbZtEQQB4ji2kRCCNE0RmXvfB6EU8zxjmiZIKf8KhzFmycIwtCiK4k7ueR7quoZSyhJ+Bo7UxcuyWByPR6vm8f5fyFZCI1VtZT8XvdXae8+cRrfkuq5u7xviMEJFSwzDaIuFEJiEfvEeV5j8LGcc1RFiEluFXHRIyhRFVaDuK6iLgjzrX75IfZY2PuP084R0TOHWLi7L5aFDTdgNmpAmyEiGXbkDZRSVJqacguiziSZX8tKCdAQVrxBVEcImBG8ZzGBXhdcpZ1mqkaHYF8jzHZIksRNPr/kojmyMdT4IfLtS+S4HLYjNd11nbbAe9pyDEoq2aS14x9AzDjHqgmk135xX7x7PAly/a3K3TbAt102F16+v+B758GMfaZ6iYQ1GOWKYBgzybQgpLNFt4mvUCrnstB8xsjJDq8/ql4K4CIynEeP5TwynAfOPGR7z8EJecFLnzaQdxhn25QEHjT3VIAXKprQK34NRxwUHEwxKqs1OOsYLMY5214Z+sL6YPTT+fQRDdCPbfsv9iC9BDjc5oOW6nfnqizb4Qzyo2igc9NR2tEFetuiNsqeCz/7L3BWay6JVLbP6L4Jn/AZCFrnpIWYSSAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002 05&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/1ec4e0187cad189410f134a4520be1a9/eea79/002-05.png&quot;
        srcset=&quot;/devHistoryBlog/static/1ec4e0187cad189410f134a4520be1a9/8ff5a/002-05.png 240w,
/devHistoryBlog/static/1ec4e0187cad189410f134a4520be1a9/e85cb/002-05.png 480w,
/devHistoryBlog/static/1ec4e0187cad189410f134a4520be1a9/eea79/002-05.png 502w&quot;
        sizes=&quot;(max-width: 502px) 100vw, 502px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    
&lt;br&gt;&lt;/li&gt;
&lt;li&gt;프로젝트 토큰 생성

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/dcd094aa105fa8673ecc2a2b2322129a/e619b/002-06.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 787px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 32.08333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABJ0AAASdAHeZh94AAAAyUlEQVQY052QSW7DMAxFff+T5QrdBgZaI7asyRY1+Zdku8jgbELgix+U9CRyuHyNuE4GtG8IIYKIcBwHeu8PaqLWXurPGsbFY3aRYQHOOXjvFfhpDLKkXDHNBtYHbCmDSkNpHflf4v1O+DFBz0rIo2caZCm1YVktVucR94RcuT3+JCeV+EgFk4269y4UKKbVqi1ba2GMQYgRiWeZkijpXDOrt6qZ6K6es/pSyl/LMkgpLAxyDJQ53ozF97wyeHsE8GU6AUoWoLB+AYqV1dx35lX0AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002 06&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/dcd094aa105fa8673ecc2a2b2322129a/e619b/002-06.png&quot;
        srcset=&quot;/devHistoryBlog/static/dcd094aa105fa8673ecc2a2b2322129a/8ff5a/002-06.png 240w,
/devHistoryBlog/static/dcd094aa105fa8673ecc2a2b2322129a/e85cb/002-06.png 480w,
/devHistoryBlog/static/dcd094aa105fa8673ecc2a2b2322129a/e619b/002-06.png 787w&quot;
        sizes=&quot;(max-width: 787px) 100vw, 787px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    
&lt;br&gt;&lt;/li&gt;
&lt;li&gt;을 하면 아래와 같이 sonar scanner 를 사용하기 위한 설정 방법이 나온다.

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/bf81404469ad3593a0cd1a85abd3233d/c65fa/002-04.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 40.833333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAIAAAB2/0i6AAAACXBIWXMAAA7DAAAOwwHHb6hkAAAA5UlEQVQY032Pa27DIBCEuf+VeoRGiZp/VlvXJDwSm4cxScCAcZe4rdoqySexrAQ7s4MGe/LexxhzztMd8pTHNDrvtNKUUsYYVCEE4nIwxpRjTH7InOd/IBB+o+3T+vWojD45bZ2yLqRpfsgih2JMxXgYFntrLURIKcUQliaEAAY3JRC8NU2DMd4Duz37hhICwTjjhBDOefcLITrKD62Q4By1UpC+7/vz+eK8H2/h/3Jx5WMZ3mFcv9f4CvhIKRWw1HJ/NT+AWdsJpfsyDOvV9cfLdvu8Wq03m6qqrrvdRQpxOLZS609PVcbRJnviqQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002 04&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/bf81404469ad3593a0cd1a85abd3233d/d9199/002-04.png&quot;
        srcset=&quot;/devHistoryBlog/static/bf81404469ad3593a0cd1a85abd3233d/8ff5a/002-04.png 240w,
/devHistoryBlog/static/bf81404469ad3593a0cd1a85abd3233d/e85cb/002-04.png 480w,
/devHistoryBlog/static/bf81404469ad3593a0cd1a85abd3233d/d9199/002-04.png 960w,
/devHistoryBlog/static/bf81404469ad3593a0cd1a85abd3233d/c65fa/002-04.png 1434w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt;2. Scanner 설정 및 실행&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;build.gradle에 plugin 추가 후&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;plugins &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  id &lt;span class=&quot;token string&quot;&gt;&quot;org.sonarqube&quot;&lt;/span&gt; version &lt;span class=&quot;token string&quot;&gt;&quot;3.0&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;scanner 를 실행하면&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;./gradlew sonarqube \
  -Dsonar.projectKey=Test-Proj \
  -Dsonar.host.url=http://HOST:10002 \
  -Dsonar.login=***********************&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;정적분석 결과가 표시된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/3adf418ed240c4d33879ddf364d05ad9/951a4/002-07.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 56.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABJ0AAASdAHeZh94AAABx0lEQVQoz31TzU4UQRjsI+HCjSuPoO/BEZ9tozcSD55Eohev+grGGE0AXRKMuLsz/f8z3VNW9wwbFgmTVDrTPV1f1VffCKcToowYLQBPJCB4jxACxnHEWApKyUTBEBSCW8Pajueeq4VUCr026JVBSgPEux/v8fLLKyy+LrD4tsDp91Msb5boNx0/0rjdSHT8WPGi0hqalyfotielnM9MOxfHn46xd7YH8UZAvBbYf7uPn+tf0MohxABPpZnqUqKTGB+Fcw7eSBitIE4+v8DB2QGOPhzh8PwQzz8+wx+7IlGm5YLpGfHUM+SM7CVsJbzeXONidYHL1WVbr9ZXVBbZo0hVcerjHSr1/fcZzQHbYwjhDK0ZWjN+ixgTFUbknHcvDkML5yFhC4wBmdrD1lglt1CEp0LrQ0u79g6zskhLnnsDie/2CotWR6XXsOQSuiWn59TqytGgQmn9f2o6O4W0Q8g+12C60EGZh4R1ZZVIVcanRoh7sWgfW7GcyzamSloL6KgeIZxnLUXP2euw/MtRcKENt7J+ZjAw5ha/17qlWwv02rajOug7hNVutV3/At8wWaxp1z4lKhmSQwym7Yd5Dmtf00BXxuAfwdhBAMiGlFcAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002 07&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/3adf418ed240c4d33879ddf364d05ad9/d9199/002-07.png&quot;
        srcset=&quot;/devHistoryBlog/static/3adf418ed240c4d33879ddf364d05ad9/8ff5a/002-07.png 240w,
/devHistoryBlog/static/3adf418ed240c4d33879ddf364d05ad9/e85cb/002-07.png 480w,
/devHistoryBlog/static/3adf418ed240c4d33879ddf364d05ad9/d9199/002-07.png 960w,
/devHistoryBlog/static/3adf418ed240c4d33879ddf364d05ad9/951a4/002-07.png 1355w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt;Pipeline 작성&lt;/span&gt;
&lt;span class=&quot;title__sub2&quot;&gt;1. Test Stage&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;테스트 코드를 수행한다.&lt;/li&gt;
&lt;li&gt;테스트 실패 시 테스트 결과 게시 및 PR comment &amp;#x26; decline api 전송 후 파이프라인을 종료한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;stage (&amp;#39;Test&amp;#39;) {
    sh &amp;#39;&amp;#39;&amp;#39;
    {
        ./gradlew test \
        &amp;amp;&amp;amp; curl -X POST -u &amp;quot;$USER&amp;quot; $COMMENT_URL -d &amp;#39;{&amp;quot;content&amp;quot;: {&amp;quot;raw&amp;quot;: &amp;quot;[TEST] SUCCESS&amp;quot;}}&amp;#39; -H &amp;#39;Content-Type: application/json&amp;#39; &amp;gt; /dev/null 2&amp;gt;&amp;amp;1 \
        &amp;amp;&amp;amp; echo [TEST] SUCCESS;
    }||\
    {
        ssh -ir ~/.ssh/v2g_srv $V2G_DEV_SERVER bash -c &amp;quot;&amp;#39;mkdir -p /docker-volumes/nginx/html/failed-test/$SOURCE_BRANCH&amp;#39;&amp;quot;;
        scp -ir ~/.ssh/v2g_srv ./build/reports/tests/test $V2G_DEV_SERVER:/docker-volumes/nginx/html/failed-test/$SOURCE_BRANCH;
        curl -X POST -u &amp;quot;$USER&amp;quot; $COMMENT_URL -d &amp;#39;{&amp;quot;content&amp;quot;: {&amp;quot;raw&amp;quot;: &amp;quot;[TEST] FAIL&amp;quot;}}&amp;#39; -H &amp;#39;Content-Type: application/json&amp;#39; &amp;gt; /dev/null 2&amp;gt;&amp;amp;1;
        curl -X POST -u &amp;quot;$USER&amp;quot; $DECLINE_URL -d &amp;#39;{&amp;quot;content&amp;quot;: {&amp;quot;raw&amp;quot;: &amp;quot;[TEST] FAIL&amp;quot;}}&amp;#39; -H &amp;#39;Content-Type: application/json&amp;#39; &amp;gt; /dev/null 2&amp;gt;&amp;amp;1;
        echo [TEST] FAIL;
        exit 1;
    }
    &amp;#39;&amp;#39;&amp;#39;
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt;2. Jacoco &amp;#x26; SonarQube Analysis &amp;#x26; Quality Gate&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;테스트 성공 시 coverage 측정 및 정적분석 진행 후 Quality Gate 결과 확인&lt;/li&gt;
&lt;li&gt;Qulicy Gate 실패 시 PR comment &amp;#x26; decline api 전송 후 파이프라인을 종료한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;stage (&amp;#39;Jacoco &amp;amp; SonarQube Analysis &amp;amp; Quality Gate&amp;#39;) {
    withSonarQubeEnv(&amp;#39;sonarqube&amp;#39;) {
        sh &amp;quot;./gradlew jacocoTestReport sonarqube&amp;quot;
    }
    
    def qg = waitForQualityGate()
    if (qg.status != &amp;#39;OK&amp;#39;) {
        sh &amp;#39;&amp;#39;&amp;#39;
            curl -X POST -u &amp;quot;$USER&amp;quot; $COMMENT_URL -d &amp;#39;{&amp;quot;content&amp;quot;: {&amp;quot;raw&amp;quot;: &amp;quot;[QualityGate] FAIL&amp;quot;}}&amp;#39; -H &amp;#39;Content-Type: application/json&amp;#39; &amp;gt; /dev/null 2&amp;gt;&amp;amp;1;
            curl -X POST -u &amp;quot;$USER&amp;quot; $DECLINE_URL -d &amp;#39;{&amp;quot;content&amp;quot;: {&amp;quot;raw&amp;quot;: &amp;quot;[QualityGate] FAIL&amp;quot;}}&amp;#39; -H &amp;#39;Content-Type: application/json&amp;#39; &amp;gt; /dev/null 2&amp;gt;&amp;amp;1;
            echo [TEST] FAIL;
            exit 1;
        &amp;#39;&amp;#39;&amp;#39;
    } else {
        sh &amp;#39;&amp;#39;&amp;#39;
            curl -X POST -u &amp;quot;$USER&amp;quot; $COMMENT_URL -d &amp;#39;{&amp;quot;content&amp;quot;: {&amp;quot;raw&amp;quot;: &amp;quot;[QualityGate] SUCCESS&amp;quot;}}&amp;#39; -H &amp;#39;Content-Type: application/json&amp;#39; &amp;gt; /dev/null 2&amp;gt;&amp;amp;1;
        &amp;#39;&amp;#39;&amp;#39;
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt;3. Approve PullRequest&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;해당 PR에 대한 승인 API 전송 후 파이프라인 종료&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;stage (&amp;#39;Approve PR&amp;#39;) {
    timeout(time: 1, unit: &amp;#39;MINUTES&amp;#39;) {
        sh &amp;#39;&amp;#39;&amp;#39;
            curl -X POST -u &amp;quot;$USER&amp;quot; $APPROVE_URL;
            echo Approve PullRequest;
        &amp;#39;&amp;#39;&amp;#39;
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;p&gt;&lt;a href=&quot;https://eunyoung-autocrypt.github.io/devHistoryBlog/works/posts/2021-01-18--001&quot;&gt;&gt; [작업로그] CI/CD 구축 #1 - CI/CD 시나리오&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://eunyoung-autocrypt.github.io/devHistoryBlog/works/posts/2021-01-18--002&quot;&gt;&gt; [작업로그] CI/CD 구축 #2 - Docker, Docker Compose 설치&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://eunyoung-autocrypt.github.io/devHistoryBlog/works/posts/2021-01-18--003&quot;&gt;&gt; [작업로그] CI/CD 구축 #3 - BitBucket 설정 및 Jenkins 설치&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://eunyoung-autocrypt.github.io/devHistoryBlog/works/posts/2021-01-21--001&quot;&gt;&gt; [작업로그] CI/CD 구축 #4 - Jenkins Item 등록 및 Pipeline 작성&lt;/a&gt;  &lt;/p&gt;</content:encoded></item><item><title><![CDATA[JPA 왜 쓰는가?]]></title><link>https://ssongey.github.io/history/posts/2021-01-23--001</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2021-01-23--001</guid><pubDate>Sat, 23 Jan 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; # SQL 중심적인 개발의 문제점 &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SQL 중심적인 개발을 진행해오고 있다.  &lt;/li&gt;
&lt;li&gt;객체를 DB에 넣기 위해 SQL 의존적인 개  발을 할 수 밖에 없다.&lt;/li&gt;
&lt;li&gt;CRUD SQL 개발에 대해 무한반복 작업을 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt;패러다임 불일치&lt;/span&gt;
&lt;span class=&quot;title__sub2&quot;&gt; 객채와 관계형 데이터베이스의 차이&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;ol&gt;
&lt;li&gt;상속&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;연관관계&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;데이터 타입&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;데이터 식별 방법&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/ec6fe5c8b206f6933c67712a7fafeae4/d3b46/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 51.25000000000001%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABYlAAAWJQFJUiTwAAABUElEQVQoz3WR64rCMBCF8/5vJQiKYhdE9I+CrdpqvVK13qpn+80SicIGpp0mpyffzLgo+tFgMNDjUYn1er3e8d8KNd86V5alrtdrbfhQVVV6Pp8mIifY9+G/eXvjUEPuQneMt9utNpuNuMjf/k1zu92U57nW67Xu9/uHxvGAioVRr9fTbDZTURR2a2jmdfP5XFEUabVa6Xw+fxqGhIfDwcTcvNvt/u3hcrnUZDIx/fF4/Oiju1wudoABpVD2fr+3UqD0pKfTSePxWIvFwkym06mSJLHzOI4NhH/daDRSq9XScDg0UaPRsLIpp9PpqNlsKssyO+v3+5Zj3G63jRKzbrdrOS1zngoiBgEpfWEfUoJzP3WCqtCGuZ/0u4cYpmlmwaTjOKmNy3dvirpMhpXX5FCmaWpElMrEIQXEhRPElBt5Q+inzCKHhP1QBz3xp6/0C9fEATQkSv+BAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/ec6fe5c8b206f6933c67712a7fafeae4/d9199/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/ec6fe5c8b206f6933c67712a7fafeae4/8ff5a/001-01.png 240w,
/devHistoryBlog/static/ec6fe5c8b206f6933c67712a7fafeae4/e85cb/001-01.png 480w,
/devHistoryBlog/static/ec6fe5c8b206f6933c67712a7fafeae4/d9199/001-01.png 960w,
/devHistoryBlog/static/ec6fe5c8b206f6933c67712a7fafeae4/07a9c/001-01.png 1440w,
/devHistoryBlog/static/ec6fe5c8b206f6933c67712a7fafeae4/d3b46/001-01.png 1690w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt;객체 모델링 Album 저장 방법&lt;span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;ol&gt;
&lt;li&gt;객체분해&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;각 객체 저장&lt;br&gt;
2.1) insert into item…&lt;br&gt;
2.2) insert into album..  &lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt;Album 조회 방법&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;ol&gt;
&lt;li&gt;각각의 테이블에 따른 Join SQL 작성&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;각각 객체 생성 및 매핑&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;…복잡&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;그래서 DB에 저장할 객체에는 상속 관계를 안쓴다.
객체답게 모델링을 할수록 매핑만 늘어난다.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt;자바 컬렉션에 저장/조회 하면?&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;list&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;album&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;Album&lt;/span&gt; album &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; list&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;albumId&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;Item&lt;/span&gt; item &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; list&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;albumId&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;정리 계속…&lt;/p&gt;</content:encoded></item><item><title><![CDATA[SSH Key]]></title><link>https://ssongey.github.io/works/posts/2021-01-22--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2021-01-22--001</guid><pubDate>Fri, 22 Jan 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;#. SSH Key란?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;서버에 접속 할 때 비밀번호 대신 key를 제출하는 방식이다. &lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;#. 동작 방법&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;클라이언트가 서버에 SSH 연결을 요청한다.&lt;/li&gt;
&lt;li&gt;서버는 랜덤 챌린지(랜덤 데이터 스트링)를 생성해 클라이언트에게 보낸다.&lt;/li&gt;
&lt;li&gt;클라이언트는 서버로 부터 받은 챌린지(C)를 자신이 가지고 있는 private 키로 암호화해서 암호화 된 메시지를 서버로 보낸다.&lt;/li&gt;
&lt;li&gt;서버는 클라이언트에서 받은 암호화 된 메시지를 public 키로 해석한 후 그 결과를 2단계에서 자신이 클라이언트에게 보낸 랜덤 챌린지와 일치하는지 확인한다. (public 키로 해석할 수 있는 메시지는 그 쌍이 되는 private 키를 가진 사람만이 만들 수 있기 때문) 일치하면 클라이언트가 인증된 것이다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/12e5141213fcf1ef39927aeadfaff0ba/59000/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 917px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAABJ0AAASdAHeZh94AAAA40lEQVQY03WQbY+CMBCE+f9/7xI9z3gxcIhCTwrFvrfjbhs+SrKZpd15dtLm5SK0j1A2gntlA2lATAkhpqLIGZ++lOv1PtGwaTEesw5YSfl/I6iinpWLoZlcKe2VitmHhKfSVBuUdhW4aI9zO6BtW1xuAobSGs8gD+3qknlzkC9XluzFd71Y8dN1+Lp+49xPkARtHovB4XrH6bfDsePDOsymAiPQIDUmZcsZB9j12EucBom/WUNMAtO/RGMp0bhaHAZVhjhhzvVhXIglmSAY17gajBTgTgsYyt4b9Qx0ztMTBLwB4HSC3tOl0HoAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/12e5141213fcf1ef39927aeadfaff0ba/59000/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/12e5141213fcf1ef39927aeadfaff0ba/8ff5a/001-01.png 240w,
/devHistoryBlog/static/12e5141213fcf1ef39927aeadfaff0ba/e85cb/001-01.png 480w,
/devHistoryBlog/static/12e5141213fcf1ef39927aeadfaff0ba/59000/001-01.png 917w&quot;
        sizes=&quot;(max-width: 917px) 100vw, 917px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;#. 패스워드 없이 ssh 연결&lt;/h3&gt;
&lt;h4&gt;#1. key pair 생성 [Client Side]&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;default 로 생성 시 ~/.ssh/id&lt;em&gt;rsa , ~/.ssh/id&lt;/em&gt;rsa.pub 로 생성됨&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;$ ssh-keygen&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;파일 설명   &lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;파일명&lt;/th&gt;
&lt;th&gt;설명&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;id_rsa&lt;/td&gt;
&lt;td&gt;private key, 서버에 패스워드 없이 접속할때 해당 key를 사용한다&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;id_rsa.pub&lt;/td&gt;
&lt;td&gt;public key, 접속하려는 서버의 authorized_key 에 등록하면 된다&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;#2. 접속하려는 서버에 public key 등록 [Server Side]&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ cat id_rsa.pub &amp;gt;&amp;gt; ~/.ssh/authorized_keys&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;#3. 접속확인 [Client Side]&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ scp -i ~/.ssh/id_rsa [타겟파일] [서버계정]@[서버HOST]:~/&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;h5&gt;#ps. 관련 디렉토리, 파일 퍼미션&lt;/h5&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_rsa
chmod 644 ~/.ssh/id_rsa.pub  
chmod 644 ~/.ssh/authorized_keys
chmod 644 ~/.ssh/known_hosts&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[[작업로그] CI/CD 구축 #4]]></title><description><![CDATA[Jenkins Item 등록 및 Pipeline 작성]]></description><link>https://ssongey.github.io/works/posts/2021-01-21--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2021-01-21--001</guid><pubDate>Thu, 21 Jan 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt;1. Jenkins Item 생성 (Pull Request)&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;pipeline 선택

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/12a2bc787d353b4201c6980d1c078589/1e088/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 840px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 73.75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAABJ0AAASdAHeZh94AAACQklEQVQ4y42Sy47TQBBF/ZH8AJ/Ali9gzYIlW3Ys2YDYREgjHpPJTFAmGScQ24ndtttuP9qvkFyq2nYYNIyEpZPqcjtV91a3pesGuumg65Zi26+HPC+r/yYjyqqGtRMRJhdfMFss8Xl6ja9XNxRnmM4XEGmOIMmIIcpsyB/iS4U4K2AFUYzlnY2t68Hb+3B3ewOvRSQRxhI+NQ1kipAaPIagoklewhJxgqW9xvqng4AKSJUjTjNDlCiDkAn8ODV/egxWL1lhQb5T3UEV+i9S6jaiioF8oHgIf5eXmgrmCtPLCdztBjZZX6/X8DwPVaUNdV2f11VVGbQuCX2P0tC2DayqJMl3nxCJPXY0O9u24TgOPNc1hXfeDtvttl/TvkPved+lmfN7d8ijKEJDt8Sq2xZp9QsxDT8IApRlaVQxTdMMCknZvZzjuB7puo4UUkH2fbPaIKQOXLChe8kbo72q+lNIny3rc6MxHo9HHA4HWFyZnzRNjXy25vs+JCmO4xhCCBOZIBDGGr+LwsiI4O/CMIRSqlfY0E+h6bbnOYqiMHBX7sacTiccT0ejgB/O/wXv95bpisxXP3C7sjGff8dsdo3FYoHl8hbT6RUEdWf1DCuRUiJNEqM4JJWsmOGchVg8bJxaoM1Rq5BsO1CZMtckyzLDqJzXoxOO476Bcp61pescLz9c4vnbC7x49w2Bkuja/hTZAjOe6pg/jimY4dmbCZ68eo+nrz9iE+zJUm+HbURm8DGSwWZvNewPh+Ngm0fBTX8DSXxuCo2ZUx0AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/12a2bc787d353b4201c6980d1c078589/1e088/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/12a2bc787d353b4201c6980d1c078589/8ff5a/001-01.png 240w,
/devHistoryBlog/static/12a2bc787d353b4201c6980d1c078589/e85cb/001-01.png 480w,
/devHistoryBlog/static/12a2bc787d353b4201c6980d1c078589/1e088/001-01.png 840w&quot;
        sizes=&quot;(max-width: 840px) 100vw, 840px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;ul&gt;
&lt;li&gt;Build Trigger에서 generic Webhook Trigger를 선택한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/b7aaf19c6c7610288e3e81807ee675ca/f8915/001-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 748px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 47.91666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABJ0AAASdAHeZh94AAABTklEQVQoz52S226DMBBE+f9PbMM1wfhuQC3iEmm6u8FR+lK1fVjZYPvszNhF3TRQfY+6bjDPM+73O7Ztw77vMq7r+qcqeoJxNQROKWEcR0zTJOOyLP8B3kQdA7uug7UWIQR472VDVvrbKq7XK6qqRtu2Us55GGMIbMBrvVICzvZfD79+PxU2vYPRSg7fxHqNEKMssuWfbL+C8rwIZE1r/bTqnBO7ipS1FEN1eUddVRJJeblILGVZSuO398faMGiJRoAxJiRSFM8KwQt4pAvqXcLNT+hsgkkzHdpwHAf2Y39kyxnnCE6VBd+sP3Pj0ZHSQRsoglkfMVhSaxwczccxyUvgmmjOez4+l295FpHUWOuetg3BmoFiIEDwZN9yIyfFTfOFdYoah0mUHvIS1mw5kioCDgOssQLVpMo7gvN/Bp/Z5nx51KQ6hChqDYGzwi8M6Pj5FTNbtgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/b7aaf19c6c7610288e3e81807ee675ca/f8915/001-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/b7aaf19c6c7610288e3e81807ee675ca/8ff5a/001-02.png 240w,
/devHistoryBlog/static/b7aaf19c6c7610288e3e81807ee675ca/e85cb/001-02.png 480w,
/devHistoryBlog/static/b7aaf19c6c7610288e3e81807ee675ca/f8915/001-02.png 748w&quot;
        sizes=&quot;(max-width: 748px) 100vw, 748px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt;2. webhook token 설정&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;BitBucket 에서 설정했던 token 값을 넣는다.

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/12d9fb97aec68c7607403df32b73ccf5/22475/001-06.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 14.583333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAABJ0AAASdAHeZh94AAAAZ0lEQVQI15WOSQrAIBRDvf8dFRGcikNF96mxA5SuunjkJ5BPRCkFrTX03n8xxni4fYwRwhgD5xxSSouc84szz5+cZe89QgjY5s1R1loIKRWUUtBar8cM7VQuJ7XWB/r9Uj68YY8LmR//TuJjPxbLEwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 06&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/12d9fb97aec68c7607403df32b73ccf5/d9199/001-06.png&quot;
        srcset=&quot;/devHistoryBlog/static/12d9fb97aec68c7607403df32b73ccf5/8ff5a/001-06.png 240w,
/devHistoryBlog/static/12d9fb97aec68c7607403df32b73ccf5/e85cb/001-06.png 480w,
/devHistoryBlog/static/12d9fb97aec68c7607403df32b73ccf5/d9199/001-06.png 960w,
/devHistoryBlog/static/12d9fb97aec68c7607403df32b73ccf5/22475/001-06.png 1039w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt;3. Parameters 정의&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;request payload 에서 사용할 값들을 정의한다.&lt;/li&gt;
&lt;li&gt;bitbucket webhook 에 대한 각 이벤트 request payload는 &lt;a href=&quot;https://support.atlassian.com/bitbucket-cloud/docs/event-payloads/&quot;&gt;여기&lt;/a&gt; 에서 볼 수 있다. 근데.. 난 보기 불편하다.  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt;3.1. parameter catch 방법 선택&lt;/span&gt; &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;아래와 같이 paramters를 캐치할 수 있는 폼이 있는데, 해당 hook은 POST method 형식이므로 맨 첫번째를 선택한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/3c194c47a2980c25c706517b4754ab68/1ac29/001-03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 36.66666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAIAAACHqfpvAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAA3klEQVQY03WNYW+GIAyE/f9/cW+yBScoitAWkOqXnZhlS5Y9udRy3sGQzLiM42o+d2uV6GRWiCBqRM8C5/Exr5zV+4Z5ngNZt7FwziRMknOt+ajlOGprUGkHHKnl9mtFJpVctqBPORrj3l7z67W9f9BkxTpxLru5zEvXDAc+W/yyCO/G5GnSWu8yi2whEPGB10qB7gX0IzZIG5I313kBHLQzpJSWTowxhIDJzDAx6QZfxlVPunX0myERLd7vMeIJ1VP/4Xfnpywi+x5TB8u6bn7xlFIIuDA+ZkwRsb/lL8rMjh6lnhsuAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/3c194c47a2980c25c706517b4754ab68/d9199/001-03.png&quot;
        srcset=&quot;/devHistoryBlog/static/3c194c47a2980c25c706517b4754ab68/8ff5a/001-03.png 240w,
/devHistoryBlog/static/3c194c47a2980c25c706517b4754ab68/e85cb/001-03.png 480w,
/devHistoryBlog/static/3c194c47a2980c25c706517b4754ab68/d9199/001-03.png 960w,
/devHistoryBlog/static/3c194c47a2980c25c706517b4754ab68/1ac29/001-03.png 1022w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt;3.2. 사용할 변수들을 정의한다.&lt;/span&gt; &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Variable : 변수로 사용할 이름  &lt;/li&gt;
&lt;li&gt;Expression : payload에서 사용 할 값  &lt;/li&gt;
&lt;li&gt;JSONPath : payload가 json으로 들어오므로 해당 값을 선택한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/30f7cd78d215eb1127cffec34d0e0a9e/51ed8/001-04.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 67.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAABJ0AAASdAHeZh94AAABPUlEQVQ4y6VSW3KDMAz0/e+WW0AJCQ+/wAbCbLUGZ2jayWTox45l2ZK1u1Z1XaNpGnRdjxjjKYQxQF8uCM5BWWuxriuWZcE0TacxFAXiOEI56WqMkZcmzPN8GgsgjWeoqrqCTc/SfSKEtKphGDDKqKT8rwl3yVTXdWnCnHhemLf4mNv0im+1VG3bpoY0x4qWjqvg3ltos8Wdoc4WQWix6B11VZalNLLw3oP0uRLGj3Be5JCc9VueBcep/5yQr4Zd0GMcw4gg6xCmBMbUOoMPHPcEa1VZlKiqCldB+VWhvrdC00DrHr02aIR6ozf6/F4Z1F5r/SPHpup2uz1NyW4d8XgIPvwBiXLWjOKzcTYlxbtZPP+4oRZaLPTepcLUaI/znma9uplN+OWysS4Jnk3JlxgfBY+7Kfks/4rXr/QN2gw/pS2DBKoAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 04&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/30f7cd78d215eb1127cffec34d0e0a9e/d9199/001-04.png&quot;
        srcset=&quot;/devHistoryBlog/static/30f7cd78d215eb1127cffec34d0e0a9e/8ff5a/001-04.png 240w,
/devHistoryBlog/static/30f7cd78d215eb1127cffec34d0e0a9e/e85cb/001-04.png 480w,
/devHistoryBlog/static/30f7cd78d215eb1127cffec34d0e0a9e/d9199/001-04.png 960w,
/devHistoryBlog/static/30f7cd78d215eb1127cffec34d0e0a9e/51ed8/001-04.png 1021w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt;3.3. 정의한 변수들&lt;/span&gt; &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;1. SOURCE_BRANCH  
  -- PR 타켓 branch  
  -- expression: $.pullrequest.source.branch.name

2. COMMENT_URL
  -- pipeline에서 정의한 stage 수행 시 comment 기록를 위한 url  
  -- expression: $.pullrequest.links.comments.href

3. DECLINE_URL
  -- pipeline에서 정의한 stage 실패 시 PR decline을 위한 url  
  -- expression: $.pullrequest.links.decline.href

4. REPO_URL
  -- git repository url 
  -- expression: $.pullrequest.destination.repository.links.html.href&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt;4. Pipeline 작성&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;맨 아래 pipeline을 작성하는 폼이 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/8c85c8f1306974665d393124dcc29696/aa61c/001-07.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 27.916666666666668%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABJ0AAASdAHeZh94AAAAdElEQVQY062P0Q7DIAhF+f8/dYvWFVoVrbdi0oe9bd1ITggPXA7knINqQUoJOeevsb2LMmYKIaCU8hfqECPv/bykqreptaK1hmcUUIxxBu57etP/FGaGfWliD7+ALPmX6r1PO6MfB2h5rVhZ7iMClm30bfYTmLTUGzTvHgwAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 07&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/8c85c8f1306974665d393124dcc29696/d9199/001-07.png&quot;
        srcset=&quot;/devHistoryBlog/static/8c85c8f1306974665d393124dcc29696/8ff5a/001-07.png 240w,
/devHistoryBlog/static/8c85c8f1306974665d393124dcc29696/e85cb/001-07.png 480w,
/devHistoryBlog/static/8c85c8f1306974665d393124dcc29696/d9199/001-07.png 960w,
/devHistoryBlog/static/8c85c8f1306974665d393124dcc29696/aa61c/001-07.png 1065w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br&gt;
&lt;ul&gt;
&lt;li&gt;아래와 같이 작성한다.&lt;/li&gt;
&lt;li&gt;예제는 Develop Branch PR 로 한다.&lt;/li&gt;
&lt;li&gt;그 외 3개 시나리오에 대해선 github에 정리하자.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;node {
    withCredentials([usernameColonPassword(credentialsId: &amp;#39;bitbucket-auth-id-pw&amp;#39;, variable: &amp;#39;USER&amp;#39;)]) {
        stage (&amp;#39;Clone&amp;#39;) { //clone 타켓 branch  
            try {
                git branch: &amp;#39;$SOURCE_BRANCH&amp;#39;, credentialsId: &amp;#39;bitbucket-auth-id-pw&amp;#39;, url: &amp;#39;$REPO_URL&amp;#39;
            } catch(e) {
                sh &amp;#39;&amp;#39;&amp;#39;
                    curl -X POST -u &amp;quot;$USER&amp;quot; $COMMENT_URL -d &amp;#39;{&amp;quot;content&amp;quot;: {&amp;quot;raw&amp;quot;: &amp;quot;[CLONE] FAIL&amp;quot;}}&amp;#39; -H &amp;#39;Content-Type: application/json&amp;#39;;
                    curl -X POST -u &amp;quot;$USER&amp;quot; $DECLINE_URL -d &amp;#39;{&amp;quot;content&amp;quot;: {&amp;quot;raw&amp;quot;: &amp;quot;[CLONE] FAIL&amp;quot;}}&amp;#39; -H &amp;#39;Content-Type: application/json&amp;#39;;
                    echo [CLONE] FAIL;
                    exit 1;
                &amp;#39;&amp;#39;&amp;#39;
            }
        }
        
        stage (&amp;#39;Build&amp;#39;) { //테스트 없이 소스코드 빌드 ( 컴파일 오류 체크 ), 실패 시 해당 PR comment 등록 및 decline
            sh &amp;#39;&amp;#39;&amp;#39;
            {
                echo [BUILD - BACKEND]
                chmod +x ./gradlew
                ./gradlew clean build -x test \
                &amp;amp;&amp;amp; curl -X POST -u &amp;quot;$USER&amp;quot; $COMMENT_URL -d &amp;#39;{&amp;quot;content&amp;quot;: {&amp;quot;raw&amp;quot;: &amp;quot;[BUILD] SUCCESS&amp;quot;}}&amp;#39; -H &amp;#39;Content-Type: application/json&amp;#39; &amp;gt; /dev/null 2&amp;gt;&amp;amp;1 \
                &amp;amp;&amp;amp; echo [BUILD] SUCCESS;
            }||\
            {
                curl -X POST -u &amp;quot;$USER&amp;quot; $COMMENT_URL -d &amp;#39;{&amp;quot;content&amp;quot;: {&amp;quot;raw&amp;quot;: &amp;quot;[BUILD] FAIL&amp;quot;}}&amp;#39; -H &amp;#39;Content-Type: application/json&amp;#39;;
                curl -X POST -u &amp;quot;$USER&amp;quot; $DECLINE_URL -d &amp;#39;{&amp;quot;content&amp;quot;: {&amp;quot;raw&amp;quot;: &amp;quot;[BUILD] FAIL&amp;quot;}}&amp;#39; -H &amp;#39;Content-Type: application/json&amp;#39;;
                echo [BUILD] FAIL;
                exit 1;
            }
            &amp;#39;&amp;#39;&amp;#39;
        }
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;p&gt;&lt;a href=&quot;https://eunyoung-autocrypt.github.io/devHistoryBlog/works/posts/2021-01-18--001&quot;&gt;&gt; [작업로그] CI/CD 구축 #1 - CI/CD 시나리오&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://eunyoung-autocrypt.github.io/devHistoryBlog/works/posts/2021-01-18--002&quot;&gt;&gt; [작업로그] CI/CD 구축 #2 - Docker, Docker Compose 설치&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://eunyoung-autocrypt.github.io/devHistoryBlog/works/posts/2021-01-18--003&quot;&gt;&gt; [작업로그] CI/CD 구축 #3 - BitBucket 설정 및 Jenkins 설치&lt;/a&gt;  &lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://eunyoung-autocrypt.github.io/devHistoryBlog/works/posts/2021-01-23--002&quot;&gt;&gt; [작업로그] CI/CD 구축 #5 - sonarqube 설치 및 pipeline 작성&lt;/a&gt;  &lt;/p&gt;</content:encoded></item><item><title><![CDATA[Junit Test Reports]]></title><link>https://ssongey.github.io/works/posts/2021-01-20--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2021-01-20--001</guid><pubDate>Wed, 20 Jan 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Junit 테스트를 진행하다가 Failure 케이스가 존재하는 경우 아래와 같은 로그를 보게 되었다.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/6d0cdac14613a87ee0ffeb9d3c5968c2/1843f/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 36.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAIAAACHqfpvAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAA5UlEQVQY03WO626EIBCFfZltVRjuIKAWEdBN+/7v0zH7o9l2m3w5mduZnM5aMXmlDUOUBmO5UoCFVJTLEciNkBuFd2D9XzrvTc5Lbdt5L6jHmVtDti0vcbbLbEM0zgnGhxdmvEtb3Ev6/DrakUtNpaRa03nf931NecZtjNZNCrP8itCFaHE3L25ZvQ9m8tpYYZ3wXmPL+UDp68yX2QLxnDpGpCCM9fj7B/qGF+wf52WeJDgJqIr2CgYNI07pMwQfPYrnebemkFJcP0IIujpVNd8lIEWxonk1ohnUq0Atmj04NPd8/AY1wFL/P0v4tgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/6d0cdac14613a87ee0ffeb9d3c5968c2/d9199/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/6d0cdac14613a87ee0ffeb9d3c5968c2/8ff5a/001-01.png 240w,
/devHistoryBlog/static/6d0cdac14613a87ee0ffeb9d3c5968c2/e85cb/001-01.png 480w,
/devHistoryBlog/static/6d0cdac14613a87ee0ffeb9d3c5968c2/d9199/001-01.png 960w,
/devHistoryBlog/static/6d0cdac14613a87ee0ffeb9d3c5968c2/1843f/001-01.png 1186w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br&gt;
&lt;p&gt;해당 경로의 index.html 을 열어보니 아래와 같이 테스트에 대한 결과를 화면으로 출력해주고 있었다.&lt;/p&gt;
&lt;h4&gt;#. Test Summary&lt;/h4&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/1c1ae9bc0ea373a7bb5223d4599639eb/20982/001-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 778px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 55.00000000000001%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABJ0AAASdAHeZh94AAABY0lEQVQoz41STW+CQBDl//+Ytid77MGLF28mUiRVIkiNGNkPEFjgdWYqBltN+5KXncH1zZuZ9bIsw3K5RBRFCIJ3YoDDIQOj73vhgJt89H0ML89zhGGIJEnoXEnMRQaBR8KP4N27xHHbtkLn3DWu6xpVVUncdx3Mdgu1XkNvNlDERmt4Hf1wPp+hKWF0dNlaey2Qn04iwEjTnXTg2g4tCWe+j2gywfrpGfvFAuX+81uQqxZFKX/imMcg7lonMRdkFEUBYwx9J8fk9kAiyWyGeDpFOp+T4J5aZicXchtMcUonc5if5KOYzyL9lLaZNo7hqKBXk33dOBii5VboctM0aEaz41zm9mM5d5fyoQxeFj5e/RBvmxiWhBOqyM/neDxKm6tVgF2aXgVveOlqyL2KZqFoLpoWYcsSJZGXwrMbljNs+t4T+uWwJAcn2iRv2RgtsVKKzlwWMMZf7d68w0cYt/cfh19rVVdFKWJjbgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/1c1ae9bc0ea373a7bb5223d4599639eb/20982/001-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/1c1ae9bc0ea373a7bb5223d4599639eb/8ff5a/001-02.png 240w,
/devHistoryBlog/static/1c1ae9bc0ea373a7bb5223d4599639eb/e85cb/001-02.png 480w,
/devHistoryBlog/static/1c1ae9bc0ea373a7bb5223d4599639eb/20982/001-02.png 778w&quot;
        sizes=&quot;(max-width: 778px) 100vw, 778px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h4&gt;#.  실패된 테스트 로그&lt;/h4&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/0753597752e7388ed3cc2d170bfcfa6c/60b3a/001-03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 53.75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABJ0AAASdAHeZh94AAABZklEQVQoz52T3W6DMAyFef/X6UP0YndVL6qpLS0UKP+wQflJ4czHa7ZpYr1YpKM4cfzFDsYJwxDn8xme56EsKxhjMI4jzP2u9jzPWBp/7TsM6vseXdep2rbV9TAMKgbO0wRzu8GIn7KwJagCb3KYTgI5mqbBJJAsTZFmmQKj9RruaoV0u30OlEhMLE1mZjb9mJmh2uLPdzskmw3K/f45sOoHpK2Uau6fbyfBBDFbzo9IzLI/iZ/z/IAtyXlNc7x4AcL3BlVZoJXyUyk1jmNkUi4zXfogv/WV4ZgkGKMI3eUCU7/hv4NQXu7wA/DhYwGzhSKBX69XJLK+yCVBEGimRVGoaFOswtp5nkvLldohDh+dBxl8PB5xOBy0J33fx+l0guu6ureXj0E/1xT9vJji8xBa1/U3kJkQxMMMJoyXcM+CWAEzZ3ZVVWm72U6wvaxA0hlogyn+PQQzO9qEc6YItk/BeIKtPgAPok1cvm1l0AAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/0753597752e7388ed3cc2d170bfcfa6c/d9199/001-03.png&quot;
        srcset=&quot;/devHistoryBlog/static/0753597752e7388ed3cc2d170bfcfa6c/8ff5a/001-03.png 240w,
/devHistoryBlog/static/0753597752e7388ed3cc2d170bfcfa6c/e85cb/001-03.png 480w,
/devHistoryBlog/static/0753597752e7388ed3cc2d170bfcfa6c/d9199/001-03.png 960w,
/devHistoryBlog/static/0753597752e7388ed3cc2d170bfcfa6c/60b3a/001-03.png 1179w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br&gt;
&lt;h4&gt;#.  테스트 클래스 별 정의된 테스트 메소드 및 성공/실패 여부&lt;/h4&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/d1513632408c426cb237abef6b636a2c/966a0/001-04.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 944px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 66.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAABJ0AAASdAHeZh94AAAB3klEQVQ4y31T23KcMAzd//+cvLcP+YPMpJ3NQ1q2m8CyCzY2xsbGcCKZS9hkpprRWJbs4yMdOFRVhePxiCzL8Pr6B0opfLVpmu59HGdf9usZtoNzjkAaSCkhhEBDsdY6OdestbT2+J+tYAlwpJe89xiGARzzys65EEI6zODMnK+5uoZ8eYGkrvTphJHO3jHkoOs6hKVgjAHX+r5PMdv1ekVRFCnW5zP+/fyBvw8PKJ+eEOnhO8A9wxgjnO3SyjlumevMNASPkR+/XFD9/oXb8zMEMR2p9g1wc0oGyg/L4DnH4LzuBoaJcqswe9ESILfFCr9RK4YYPWZnZIpmRiKdaEZ5niN/zzfQvQBf9xwfZhXdxtIzKyqwCKy60mpjOU4zqPd9+irC0i5jsHCJodACucghO4lhjKkltpu84Vy+oaiLVBNGwIf58zHWIL++09xj2qtWoazLpWVvUKgLWmc2BknNXqMyFWpTI47xrj0X6Nt1nz+ADRaCHp0BXYuyuaAjwBiH7VBrNWpdQbbiO6B3aIz8BOy7bX+wRkPeqOUyh6O5rJdMQ3/NtYCqSvTU6rhT0rsOWtw2QEcYRi2APga0fYvO2+0SO7dlfAfTG2hiOxD7tRbojiWW694PPt1n+wDBMPQirXYkVQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 04&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/d1513632408c426cb237abef6b636a2c/966a0/001-04.png&quot;
        srcset=&quot;/devHistoryBlog/static/d1513632408c426cb237abef6b636a2c/8ff5a/001-04.png 240w,
/devHistoryBlog/static/d1513632408c426cb237abef6b636a2c/e85cb/001-04.png 480w,
/devHistoryBlog/static/d1513632408c426cb237abef6b636a2c/966a0/001-04.png 944w&quot;
        sizes=&quot;(max-width: 944px) 100vw, 944px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h4&gt;#. 모든 테스트 성공 시&lt;/h4&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/9c6b010fa7ff66551cb168b79f3abf8e/669eb/001-05.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 34.166666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAABJ0AAASdAHeZh94AAAA+klEQVQoz31Sy27DIBD0/1+TP2o/oCdffOghTl0njnm/bMOUxSVKVSUrjVjYYRgWmnmeMQwDzuceWmvUSCnd8xhjmRNiiv/qj9F476GNgckIIeybsgBhWRakmMAtR/vdoh1b6KBfC67rCudcISilsG0bpJRlJOfeBXRTh8PbAcf3I3revxbMpZ3wey1yRmLVJZWZZeiuXYHy6i5Y8ThvPpnAx9cI6Txu1ymLxT8nPnPyjNOcLiNOtwluCVBGIayhFKif1tqSCyHg/N4Wzvne25wzxgqPgnMGlR+10VZCGp4dSggrykhXpd7WjfRwtQ01J9CvIB6tSyML/wcSryHglTU8SAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 05&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/9c6b010fa7ff66551cb168b79f3abf8e/d9199/001-05.png&quot;
        srcset=&quot;/devHistoryBlog/static/9c6b010fa7ff66551cb168b79f3abf8e/8ff5a/001-05.png 240w,
/devHistoryBlog/static/9c6b010fa7ff66551cb168b79f3abf8e/e85cb/001-05.png 480w,
/devHistoryBlog/static/9c6b010fa7ff66551cb168b79f3abf8e/d9199/001-05.png 960w,
/devHistoryBlog/static/9c6b010fa7ff66551cb168b79f3abf8e/669eb/001-05.png 1244w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br&gt;
&lt;p&gt;이번 CI/CD 구축에서 테스트 실패시 해당 html를 제공하도록 해도 괜찮을꺼 같다.&lt;/p&gt;
&lt;br&gt;
&lt;h4&gt;ps. junit test reports 경로 수정 방법&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;build.gradle 의 test 블록에 reports destination 지정&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/b49da05e0edb8c734b11e6d6f00aa5e9/fdaf8/001-06.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 674px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 20%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAABJ0AAASdAHeZh94AAAAqElEQVQY00WQWQKEIAxD5zQqW4sbCHr/a2UCOs7HI2mBlvLJx4rzSmjaSHkmC3wY4fxAbm2xb3HLh+lR5uj/jPjE2SHXjOM6SUE6Cb3TACMeluqCgX28VYGJQvVdncp9hnEv2Jbt2LHXgr3kXjBftTfYyoE57WyYYFOCKRWycAqvyF6wRk6yxLdg+L1Q1SBGA314vU4IMkKoXm7aJeHoSqR/xdC/oiv3vmlNe+YXHlFVAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 06&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/b49da05e0edb8c734b11e6d6f00aa5e9/fdaf8/001-06.png&quot;
        srcset=&quot;/devHistoryBlog/static/b49da05e0edb8c734b11e6d6f00aa5e9/8ff5a/001-06.png 240w,
/devHistoryBlog/static/b49da05e0edb8c734b11e6d6f00aa5e9/e85cb/001-06.png 480w,
/devHistoryBlog/static/b49da05e0edb8c734b11e6d6f00aa5e9/fdaf8/001-06.png 674w&quot;
        sizes=&quot;(max-width: 674px) 100vw, 674px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;</content:encoded></item><item><title><![CDATA[Jacoco]]></title><link>https://ssongey.github.io/works/posts/2021-01-20--002</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2021-01-20--002</guid><pubDate>Wed, 20 Jan 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;#. Jacoco ?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;수행되는 테스트가 작성된 코드를 얼마나 커버하는지를 체크해주는 라이브러리이다.&lt;/li&gt;
&lt;li&gt;테스트코드를 돌리고 그 커버리지 결과를 눈으로 보기 좋도록 html이나 xml, csv 같은 리포트로 생성한다. &lt;/li&gt;
&lt;li&gt;테스트 결과가 내가 설정한 커버리지 기준을 만족하는지 확인하는 기능도 있다. &lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;#. Jacoco 적용&lt;/h3&gt;
&lt;h3&gt;#. jacoco plugin 추가&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;plugins 블록에 id ‘jacoco’ 를 추가하면

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/4cf97c6c68806932e326f680b7612370/9128f/002-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 603px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 22.916666666666668%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAABJ0AAASdAHeZh94AAAAz0lEQVQY012QUXLDIAxEfZkULIGNsQF7MGnSTu5/pK1gaJL24w1Iuyyg4XbPyDnAO4axCpPVf7DSqxg3YvKM2REMXWD4Amc05u6jSYGFIR0ryr4hK42TCJ+a8CU8FOMu6zlKT424+gXfR0LJETksKMGjMOMmnqt4Ao+NIaQFeV9xSuDBhFVurULqhpVrrZFIYyMFNxPi7hHl3DyN8Kyap+pRGLbosItYeqCRZ1OHO69at7GQfLdS9/89A5uPJtSgim1z+0U17TnHN2wPf9crP/ImmXGiUwLkAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/4cf97c6c68806932e326f680b7612370/9128f/002-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/4cf97c6c68806932e326f680b7612370/8ff5a/002-01.png 240w,
/devHistoryBlog/static/4cf97c6c68806932e326f680b7612370/e85cb/002-01.png 480w,
/devHistoryBlog/static/4cf97c6c68806932e326f680b7612370/9128f/002-01.png 603w&quot;
        sizes=&quot;(max-width: 603px) 100vw, 603px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;ul&gt;
&lt;li&gt;jacocoTestReport 와 jacocoTestCoverageVerification task가 gradle verification 항목에 추가된다.&lt;/li&gt;
&lt;li&gt;주의 해야 할 점은 생성된 두 개의 task는 test 가 먼저 실행된 다음에 실행이 되어야 한다.

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/8b4fb606554b582708bb9ef257bbc454/2b41d/002-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 338px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 103.33333333333331%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAVCAYAAABG1c6oAAAACXBIWXMAABJ0AAASdAHeZh94AAACY0lEQVQ4y51UyVLcMBD1bzHM4t2WtViyPQuQsEyKJVQlOeTAgalUTvwOU8kHvnTLDJBKASaH55Zl+el195OCw5t7fNhscfDjN9rv91jd/IL+tkX1dQv5Hwjyg1uY9U/IqzvML++gP26QHWyQrnoky9vH8RAEe/sj5EUOIQTM2SVEbeEah9oaWGchZYn98Wgwgv1phKJSKKSBOlojVzWkrhFnBcazGJMw8XEoiDBEVlZEqKGPL5Bri0ppIswxmswIIS2MPHjz3fgleMJSKghS5tbXKE0DZWp616ib1o+ZmNf1pOHbhF5hpWGOz1GQwkLIhzmFitJP8gKzOH2T7ImwED3h2WeqoUXpiaim1CBtGxjriLT0SgcRFpWEICXu9IoUclOMV7M3phqOpz6+O+Wc0ixXx8hIKddtGiX/LB6cMqcoFPnu0zV12UETYZRmpGw6mOgvQq+OfFifXCCjmJNibgY3Z1e3oaQPhBURPvlQqr4hzwkHp8w/MKFxLZrzL0iFpiPXQBrqMM2xR9+lkB87447iHKZb+fTZSoxJGA+uH3MEz3dmi1TG+XNdUdqCysBHrz+Cr2PHEzzfgT+YdglpWyJTvq7e3LXzR5HLwMexbjpvdttybLz54zR/UtijV6jcnEzufEO4+9zxkrxZCEVj6S0W0c9hkiFKcn8r8TuXxhNOIrqiGDHXKoRdrKBpZ2lIneXGOLiug5sv0Mw7pCXdjzPqfEhZheEjJlHkeQLRkYJWgGPRlDg8P8VyfYTFyeJxrofwcbf2JQSxyJCqEklF8kUKQTe1sFQvpx/msj5WWQ/xOv4Af80HA4bIjgkAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/8b4fb606554b582708bb9ef257bbc454/2b41d/002-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/8b4fb606554b582708bb9ef257bbc454/8ff5a/002-02.png 240w,
/devHistoryBlog/static/8b4fb606554b582708bb9ef257bbc454/2b41d/002-02.png 338w&quot;
        sizes=&quot;(max-width: 338px) 100vw, 338px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;#. jacoco version&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;toolVersion 을 다음과 같이 명시한다&lt;/li&gt;
&lt;li&gt;버전 정보는 &lt;a href=&quot;https://www.eclemma.org/jacoco/&quot;&gt;여기&lt;/a&gt; 에서 확인한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/de2aee50a53307fb7daaedd85574e913/0e2fe/002-03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 285px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 27.083333333333332%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAABJ0AAASdAHeZh94AAAAyklEQVQY022Qaw6CMBCEuYtR+4BSCrUYqvEZiJjo/S8zbmtRSfzxZdLNdnZ2s8ZquNbAuQp2o1E3KpIX6w+FYqQsaiTU1Ryp3r2Z32/RDxcMwxmX6wFdZ8ncgIsFSi2gSg6Zr5J5UjLVNECFIUl1zt6GQi4xET4G7bzDeO8jt7GPw44nj8dzhPcbNI62EhwnJrHjAkcm4CSHoJRZu21iku9qa3pLWFvC1AUqk0c1taKa/vTGlJSqSkznyVxbzwwn05D2H7+DZ3dMhi9fSZt5aPE/VwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002 03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/de2aee50a53307fb7daaedd85574e913/0e2fe/002-03.png&quot;
        srcset=&quot;/devHistoryBlog/static/de2aee50a53307fb7daaedd85574e913/8ff5a/002-03.png 240w,
/devHistoryBlog/static/de2aee50a53307fb7daaedd85574e913/0e2fe/002-03.png 285w&quot;
        sizes=&quot;(max-width: 285px) 100vw, 285px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h3&gt;#. jacocoTestReports 설정&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;jacocoReport task는 html, csv, xml 형태로 커버리지 측정 결과를 알려주는 역할을 한다.&lt;/li&gt;
&lt;li&gt;report 포맷 및 경로를 지정한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/2f5254803b51e83928f54503290c8812/27524/002-04.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 646px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 33.33333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAABJ0AAASdAHeZh94AAABBUlEQVQoz3WQa26DMBCEuUvVxE+M7WAblxAqJZFQ73+e6dqEhKrtj09jwWp2dpqYHM7TgGW5kiY4r6FbtqKPFdUS+jfb3P7dmE4gRIf5c8SQe+KEECwCLfKaw6hiWMzZ36aV9X81LB+lOoDxN1incb3NuBHL1x2T6zAc2b8JX6asLi1zzfM8oqQtFXyMsdJrgZ7TwmeSVwVyx7awGDdbBwXrFKZLxkhmpc9pzhjGgAt1bFOEGBJEzjCelnKOMxeV+pYKzqr15M7KmrDomi5UHUlj8kiUWgcP2XuIcEJnNBJnyGSUxEo0CtpwNKW/lh5bUiHffyAVKc0oUv1A6QMEnblHPq78BkSJ2MyMSdHsAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002 04&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/2f5254803b51e83928f54503290c8812/27524/002-04.png&quot;
        srcset=&quot;/devHistoryBlog/static/2f5254803b51e83928f54503290c8812/8ff5a/002-04.png 240w,
/devHistoryBlog/static/2f5254803b51e83928f54503290c8812/e85cb/002-04.png 480w,
/devHistoryBlog/static/2f5254803b51e83928f54503290c8812/27524/002-04.png 646w&quot;
        sizes=&quot;(max-width: 646px) 100vw, 646px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h3&gt;#. jacocoTestCoverageVerification&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;커버리지 검증 수준을 정의.&lt;/li&gt;
&lt;li&gt;이 부분에서 jacoco의 report 검사하여 설정한 최소 수준을 달성하지 못하면 task는 실패를 한다.&lt;/li&gt;
&lt;li&gt;여러 수준의 정의를 violationRules 에서 다수의 rule 에 정의하여 사용할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;jacocoTestCoverageVerification {
  violationRules {
    rule {
      //해당 rule의 활성화 여부를 boolean으로 나타낸다
      //default는 true
      enabled = true
        
      // 측정의 큰 단위
      element = &amp;#39;CLASS&amp;#39;

      // rule 적용 대상을 package 수준으로 정의
      // 아무런 설정을 하지 않는다면 전체 적용
      //includes = []
        
      // rule의 상세 설정을 나타내는 block
      limit {

        // 커버리지 측정의 최소 단위
        // 이 때 측정은 java byte code가 실행된 것을 기준으로 counting 된다
        // counter 종류 
        //  - CLASS : 클래스 내부 메소드가 한번이라도 실행된다면 실행된 것으로 간주
        //  - METHOD : 클래스와 마찬가지로 METHOD가 한번이라도 실행되면 실행된 것으로 간주
        //  - LINE : 한 라인이라도 실행되었다면 측정, 소스 코드 포맷에 영향을 받는 측정방식
        //  - BRANCH : if, switch 구문에 대한 커버리지 측정
        //  - INSTRUCTION : jacoco의 가장 작은 측정 방식(바이트 코드), LINE과 다르게 소스 코드 포맷에 영향을 받지 않는다.
        counter = &amp;#39;LINE&amp;#39;

        // 측정한 counter의 정보를 어떠한 방식으로 보여줄지 정한다
        // value 종료
        //  - TOTALCOUNT: 전체 개수
        //  - MISSEDCOUNT: 커버되지 않은 개수
        //  - COVEREDCOUNT: 커버된 개수
        //  - MISSEDRATIO: 커버되지 않은 비율. 0부터 1 사이의 숫자로, 1이 100%
        //  - COVEREDRATIO (default): 커버된 비율. 0부터 1 사이의 숫자로, 1이 100%
        value = &amp;#39;COVEREDRATIO&amp;#39;

        // count값을 value에 맞게 표현했을때 최소 값을 나타낸다
        // 이 값으로 jacoco coverage verification의 성공여부를 판단 (0.00~1.00)
        minimum = 0.60
      }
    
      // verify 에서 제외할 클래스를 지정 (패키지 레벨 경로)
      excludes = []
  }
    
  rule {
      ...
  }
}
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;#. finalizedBy&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;test task를 먼저 실행한 다음 jacoco task 가 실행되어야 한다.&lt;/li&gt;
&lt;li&gt;test -&gt; jacocoTestReport -&gt; jacocoTestCoverageVerification&lt;/li&gt;
&lt;li&gt;위 순서대로 task가 실행되도록 finalizedBy 를 적용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/329f0148d0e1ca1336cdce6af5b6cebe/5f4af/002-05.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 665px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 55.41666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABJ0AAASdAHeZh94AAABYElEQVQoz5WSWXKDMBBEuYwBrYC1IMCATSjHSe5/ns5IxHacr/DxaiSBuqZbk7XhCN82aI5yw6iE1CWEKhJyB1ndCCxvM263BZ9fV0ydw2INWsHQMQYnSqg9goo64eIAIfOEFBtalagIvbdDYzWsq2FsRbVCVXOoqkwf99pNgs438JTj+TJiXWc4XyN2/Z/L8b+/ZNFmtKwrlg6mqaNMJ7x/rJiDRSi3H6V+rUr94S74VC9ShqGzmOcB6/WC0R3R5ZRpzFbFekgIWnPqkMc7P7w8ym8bjvIMnaFRIrHewNJI9b1FQ+LcG8KiriQ8ZwiEF1t1WlD2DNmWBUPd8CTYDw7n80Bd9lguJxJzFENA1XrwLoD3HayWGGmkZsYxRDiHbWSKI4vZtcHgNLY40cWG8nBlDssK2JI6puqpxn3L4j7fLOviQbJ9t5zGhJSjcCKu4/zpV5TazmNNrh48HyV2+A2pF1KQcKpR3wAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002 05&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/329f0148d0e1ca1336cdce6af5b6cebe/5f4af/002-05.png&quot;
        srcset=&quot;/devHistoryBlog/static/329f0148d0e1ca1336cdce6af5b6cebe/8ff5a/002-05.png 240w,
/devHistoryBlog/static/329f0148d0e1ca1336cdce6af5b6cebe/e85cb/002-05.png 480w,
/devHistoryBlog/static/329f0148d0e1ca1336cdce6af5b6cebe/5f4af/002-05.png 665w&quot;
        sizes=&quot;(max-width: 665px) 100vw, 665px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h3&gt;#. 테스트 실행 및 결과 확인&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;테스트 실행&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ ./gredlew test&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;ul&gt;
&lt;li&gt;결과&lt;/li&gt;
&lt;li&gt;coverage 66% 로 0.60 를 넘어 verification pass 했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/7d1a450cd93f90f06aab59b91b1456b5/f470a/002-06.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 45.833333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAABJ0AAASdAHeZh94AAABg0lEQVQoz2WSC2+jMBCE8/9/YUiAViQNuUIDBr+9MLe7qGpPZ2nlh+TPMzs+PR53PD5uGIY/IMpcBaUcRZlAhZBzRkpJ5//r3/NTXb+jaTp0XY95trDWwXuPZV3wHJ8YXiOmadKa51nr9/57rXsz49TUAZdrQVVFnM8B4xhZVYGLDjfToTc9nw2sMMKuK5ZlwcqztRbGGDjndO2c1fWpbSIDCdUl4X4vfHHDvm/Ytg0ydtoxvQbQXhBjVPUxBLUq+1J+2lHE8lsbca0LrteEps4IgRRIRAwlJL4o9mXEGBQYGJgYFoJXmIBlllKFFSs8Vwltm7GY38ANme2v3J+SGcBAgQXvtQVBlWZ96ABGAQZWlzmUhK9RkjpAhdNWIIOXz0+scw/LfQ0+aK9EnfdOQapYbbPC7s2ibTzeW4tp9GoT2PT7HGDC/PxAIr4kYXEAnoHOH2GIXSn9NoflpJYvl4xHX2BmglkIJUra/CpDza0D1RXi9IJlu5KuJC5pfwelreD6C2xntQ/YqcT3AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002 06&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/7d1a450cd93f90f06aab59b91b1456b5/d9199/002-06.png&quot;
        srcset=&quot;/devHistoryBlog/static/7d1a450cd93f90f06aab59b91b1456b5/8ff5a/002-06.png 240w,
/devHistoryBlog/static/7d1a450cd93f90f06aab59b91b1456b5/e85cb/002-06.png 480w,
/devHistoryBlog/static/7d1a450cd93f90f06aab59b91b1456b5/d9199/002-06.png 960w,
/devHistoryBlog/static/7d1a450cd93f90f06aab59b91b1456b5/07a9c/002-06.png 1440w,
/devHistoryBlog/static/7d1a450cd93f90f06aab59b91b1456b5/f470a/002-06.png 1443w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
     &lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/4982ec242d73aa4ce13f1922e92d5ae4/9de76/002-07.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAABCAYAAADeko4lAAAACXBIWXMAABJ0AAASdAHeZh94AAAARElEQVQI1y3JywqAIBQA0f7/N01XBYK3+9BsEmpxYGC2sldymeQ8SGlwnDdzPvTeUVXMjNYa7r4YstpM17sQESLif58XJbBNPS/DvG0AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002 07&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/4982ec242d73aa4ce13f1922e92d5ae4/d9199/002-07.png&quot;
        srcset=&quot;/devHistoryBlog/static/4982ec242d73aa4ce13f1922e92d5ae4/8ff5a/002-07.png 240w,
/devHistoryBlog/static/4982ec242d73aa4ce13f1922e92d5ae4/e85cb/002-07.png 480w,
/devHistoryBlog/static/4982ec242d73aa4ce13f1922e92d5ae4/d9199/002-07.png 960w,
/devHistoryBlog/static/4982ec242d73aa4ce13f1922e92d5ae4/9de76/002-07.png 1423w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
     &lt;/p&gt;
&lt;br&gt;</content:encoded></item><item><title><![CDATA[[작업로그] CI/CD 구축 #1]]></title><description><![CDATA[CI/CD 시나리오]]></description><link>https://ssongey.github.io/works/posts/2021-01-18--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2021-01-18--001</guid><pubDate>Mon, 18 Jan 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt;#. CI/CD 구축 사용 도구 &lt;/span&gt;
&lt;span class=&quot;title__sub3&quot;&gt;1. Jenkins&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CI (Continuous Integration) / CD (Continuous Deploy) 도구&lt;/li&gt;
&lt;li&gt;BitBucket webhook 이벤트 발생 시 test &amp;#x26; build &amp;#x26; deploy 를 진행&lt;/li&gt;
&lt;li&gt;Pipeline 기술을 이용하여 stage 정의&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;title__sub3&quot;&gt;2. Gradle&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;빌드 툴&lt;/li&gt;
&lt;li&gt;Jacoco plugin / Sonarqube scanner plugin 을 사용하여 코드 분석&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;title__sub3&quot;&gt;3. SonarQube&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sonarqube Scanner 에게 정적 분석 관련 데이터 제공&lt;/li&gt;
&lt;li&gt;정적 코드 분석 및 버그, 코드 스멜, 보안 취약점 발견 등 코드 품질에 대한 검사 및 리포팅&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;title__sub3&quot;&gt;4. Nginx&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;테스트 결과 게시&lt;/li&gt;
&lt;li&gt;릴리즈 파일 이력관리&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt;#. CI/CD 인프라 구조 &lt;/span&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/948efee936cbc0f956d0d863ad3f6757/c587f/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 56.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABYlAAAWJQFJUiTwAAABxUlEQVQoz41SW2+bMBTm/z/sb2x7mbRK60uVh2U3ZVX3MmVV1y5K06AQwBewwWAD345N6JLmZUaWZePz3XyiYRhwPPz+vyZ9fdeDZQyr1Qq5kPBIkQfpuw5dXeElOF7uj0j9WO6WmN/OsX5YY5/uw1kAFLrG2+t7CCkhOIcxBhOUcw4dETrXhbXve6RpCs44EpEg1wz+ck2CngFr67DYcFRVBcEyGCXBiPFu8QmmMcjpTEgeiqy1ASCo7Mk4Ebm2CS4D4Cj/3Noj5XL55jVqo2Bdg1JLZDwh0poIGMqigDQtvsc5fuwlHniJjtRHxyDeapZlUGWJgiajCJRSQZVXJwsRbPszTdPf2XIiKhSRiBHQM20eN4FRVxr8kGFDVpPdDnEcQ2sdCNvWQggBU9djvl5EP7pzTRPIotv73/iy+Ia71Z8Ty5ay0bp6fgg/GirKyUGaM5gsQfvrBvXyBma7hqM7Pr7oicJ/9e4CcZaGoql49vErLi5nZGM4aZVpyO0T8sVn6J/XAbA//A8ZZqr693KH4qvZHO8/XKG17qzh/WVRWOQKKEm1sWNLHQCHs4b1qzFNyHJSfAqI0JcNvXJLgI4ebTr/C1szUWKnEy69AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/948efee936cbc0f956d0d863ad3f6757/d9199/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/948efee936cbc0f956d0d863ad3f6757/8ff5a/001-01.png 240w,
/devHistoryBlog/static/948efee936cbc0f956d0d863ad3f6757/e85cb/001-01.png 480w,
/devHistoryBlog/static/948efee936cbc0f956d0d863ad3f6757/d9199/001-01.png 960w,
/devHistoryBlog/static/948efee936cbc0f956d0d863ad3f6757/07a9c/001-01.png 1440w,
/devHistoryBlog/static/948efee936cbc0f956d0d863ad3f6757/c587f/001-01.png 1863w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt;#. 전략 &amp;#x26; 정책 &lt;/span&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/8ee2fa43bb72811f18043932d8222247/719d0/001-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 52.916666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABYlAAAWJQFJUiTwAAABJUlEQVQoz42SiW7EIAxE9/8/s1U3ByGQQA7CMTXHZqMo2RbJ4pB5Gnv8YIyBcw5rLeIKIcBYB+cDpnVDI2foxWDdLEJOSDkxrtZDKQWtNZxz6cFT4jAZzMaBDxOeTKLhElKv5cs9LAHPDxEo6HMEMqnR9iNqPtJ5IpWuMD8oDKcSPJUq1LID607uMZLyP4GvwxEodQbWvcZPK/HsRizW73l3cQ0MWaFeHVqhUDGBitTxccZ9596Ma4UEXEhhxRW+G4Gvuqddklkr1HwKeovT4G8VErAvPexJVcOHFMmc0svoet2JfKcKOpqGzfl7oCDQbDw6cjYDhjQ+k3FlcN5RPPrQw4PCBIzqhE5zaJOKYsAxCvqyh3Ef5zzYsZRoShyfzYV/ufwLMK9eUu7wWB4AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/8ee2fa43bb72811f18043932d8222247/d9199/001-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/8ee2fa43bb72811f18043932d8222247/8ff5a/001-02.png 240w,
/devHistoryBlog/static/8ee2fa43bb72811f18043932d8222247/e85cb/001-02.png 480w,
/devHistoryBlog/static/8ee2fa43bb72811f18043932d8222247/d9199/001-02.png 960w,
/devHistoryBlog/static/8ee2fa43bb72811f18043932d8222247/07a9c/001-02.png 1440w,
/devHistoryBlog/static/8ee2fa43bb72811f18043932d8222247/719d0/001-02.png 1779w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/071090d580d07e9ebc312f5038dafdca/913b9/001-03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 42.91666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAABYlAAAWJQFJUiTwAAABK0lEQVQoz32S6W6EMAyEef9nbPt7F0jKkfuaTsKxS4XWkgWyk8/2ON00TRj7HpOUQCmoVvi988O0MbDWIueMlBJijGeuCyHAMRm8q6gzcQut8ZwgpcA4CiilMM8zhBAv4PETedqnAhtYMWXcWjAoTiPqGU7RvYd3Dppg7O00YIU8B1YVEtZ5KBuQ2VEFr9ph0RaLMtDanN2vjCnrsRrH+3lXq2xA4xO+vn8gxQi1LjzkqU9pB4ffBY9+QM+CcrUNxhQeYmZsxLMfIRZzBYaYsRDiOLfjv3Fx0ysyZjSloBzMhV2KCvU8VyWqvsVLg3bH9uqIiYk6ZvabVoE6cQvHmnbYu6jlFd8LdUfFi9WxUmya9sPQNpmPLX94Uhfg/+fRuuY783WT9PdLn+wPzSzDyDHvJ7QAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/071090d580d07e9ebc312f5038dafdca/d9199/001-03.png&quot;
        srcset=&quot;/devHistoryBlog/static/071090d580d07e9ebc312f5038dafdca/8ff5a/001-03.png 240w,
/devHistoryBlog/static/071090d580d07e9ebc312f5038dafdca/e85cb/001-03.png 480w,
/devHistoryBlog/static/071090d580d07e9ebc312f5038dafdca/d9199/001-03.png 960w,
/devHistoryBlog/static/071090d580d07e9ebc312f5038dafdca/07a9c/001-03.png 1440w,
/devHistoryBlog/static/071090d580d07e9ebc312f5038dafdca/913b9/001-03.png 1822w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/af3edb4efaee229fdf616b051ba4698c/a8979/001-04.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 47.91666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABYlAAAWJQFJUiTwAAABBElEQVQoz41SWa6DMAzk/sekZXsfWQgN2ad2oBWVHrSWRg7YntjjNFJKjOMIpRS01m9vjME8z3DOga2U8hMaLhyGoaLv+0rO4P9Mbq39IDwzDnG0EUKg67pKNk1TJWvbtnYZY6zJOSWUnC87xX5Zw0UhhIpEhex5TEbOCT5E3CeJxa7wSiBRfqLilMvmd6zOU35Ggy8W6RI1/kF2dyz9DVkLwKhPzBJBKyIkDa9F3sb1RsPNGmm1KAQ48gfwd3brtpRzkTdNWIbF0jiHhZSDf53za8tfCWPAIkY8SEMmP1tI3mOXhKVuOOAhBghJY3t/qjUv5MeRI1Zraofeby/hP/Br4Zon4TURw0SrZHsAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 04&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/af3edb4efaee229fdf616b051ba4698c/d9199/001-04.png&quot;
        srcset=&quot;/devHistoryBlog/static/af3edb4efaee229fdf616b051ba4698c/8ff5a/001-04.png 240w,
/devHistoryBlog/static/af3edb4efaee229fdf616b051ba4698c/e85cb/001-04.png 480w,
/devHistoryBlog/static/af3edb4efaee229fdf616b051ba4698c/d9199/001-04.png 960w,
/devHistoryBlog/static/af3edb4efaee229fdf616b051ba4698c/07a9c/001-04.png 1440w,
/devHistoryBlog/static/af3edb4efaee229fdf616b051ba4698c/a8979/001-04.png 1828w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/49312ac45583be900ed3664bf014dff6/2858a/001-05.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 50.83333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABYlAAAWJQFJUiTwAAABeElEQVQoz4VS227DIAzt/3/bXiftorVJ2i5tCgkNhEACnNlE6TpNW5GMAZvj48vGWgulFPq+z/JrpUWNvUa/P0AdazghMUmJSP9S2yKFsLimhA1v3nsMw5BlHMeb8D3GuCBS4KB7jH6GkAqjHRHIFq5XJOe+AfkwTROMMTdhINbMOK7R6c3T3foJF9GhUxpKW5hG/ATk7dFij0SMQelxupdtibbYo9sf0ZcVnBkwzYER/wdk22qPpKyj0hCwHixmSpffZtrSXeCccqC0uGZcS0f0+czNug+WiMGkNYzq0TUSuu2gZYuhU3DUsEAsqeALoCbHsiyzFEWB3W6Huq5zLdfIURvMhz1kdcbnS4H2Y4vz6xvUrsJwknDVkZuxADIzSWPA48NaCJFZhrUhOeeYP0R678QFoj5DnhpcLzRCxM5TwEBZPGzKap8J3BGgtROenxrqtMbId6qrsY5q6/KIbe6L/5csBGMW7wKq9ysG4+AJkFlxJikufl+uQAsIgRxX/wAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 05&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/49312ac45583be900ed3664bf014dff6/d9199/001-05.png&quot;
        srcset=&quot;/devHistoryBlog/static/49312ac45583be900ed3664bf014dff6/8ff5a/001-05.png 240w,
/devHistoryBlog/static/49312ac45583be900ed3664bf014dff6/e85cb/001-05.png 480w,
/devHistoryBlog/static/49312ac45583be900ed3664bf014dff6/d9199/001-05.png 960w,
/devHistoryBlog/static/49312ac45583be900ed3664bf014dff6/07a9c/001-05.png 1440w,
/devHistoryBlog/static/49312ac45583be900ed3664bf014dff6/2858a/001-05.png 1877w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt;#. 구성 시나리오 &lt;/span&gt;
&lt;span class=&quot;title__sub2&quot;&gt;통합 시나리오&lt;/span&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/73867a58ea2ae036522119c39dcadaaf/d0e8e/001-06.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 46.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAABYlAAAWJQFJUiTwAAABQklEQVQoz3WS3W6DMAyF+/6P09eYtMtd92JS1wKFhPw74cw2paWdZumIkITP9jEHay2maYIxBuM4ous6OOcgsSyLSiKEgNbay/52tu1JHIZhwPV6Rd/3+rxcLqr9ZUl6PB7hnUcpBD26n9daQUQPqAIFIEDR+XzWSuVS4wtUC4wdYWerH+UUkXKA4igjlwIf8xMo2W+3m7YsrYskicCJCjJFBZeaubqIwXjMfkZJAZXBzkzoh+kJxD8R2bOfnr3lyig65JwVYvoOVDJanLFwhQv7Sm5SCxS4N/gh6YZbmV3grridLENaPWs5KkgrKmvrxInQ6jqUd9h+Yls0BlSuqElllVCD5b2ClrwmEMn5wn6/tPwO/vr8wPfphJQSkrNIwa9r79a16LF28GzPHw/3wEH+yXnWiZdNbEXZv99FVBE52S84Y777d+1BfwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 06&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/73867a58ea2ae036522119c39dcadaaf/d9199/001-06.png&quot;
        srcset=&quot;/devHistoryBlog/static/73867a58ea2ae036522119c39dcadaaf/8ff5a/001-06.png 240w,
/devHistoryBlog/static/73867a58ea2ae036522119c39dcadaaf/e85cb/001-06.png 480w,
/devHistoryBlog/static/73867a58ea2ae036522119c39dcadaaf/d9199/001-06.png 960w,
/devHistoryBlog/static/73867a58ea2ae036522119c39dcadaaf/07a9c/001-06.png 1440w,
/devHistoryBlog/static/73867a58ea2ae036522119c39dcadaaf/d0e8e/001-06.png 1883w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt;시나리오1. Feature Branch 에서 PR 발생&lt;/span&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/910d434322f3c529c5fa8adc657565af/e4611/001-07.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 63.74999999999999%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAABYlAAAWJQFJUiTwAAACIElEQVQ4y21Ta2vbMBT1//+SPxLYx62w0bIN1nWfBh2UDZamCbHjpx6WLMmWzq5kJ03JDPKVdHSPju4jA30hBPjg4xRN02Cz2eC0f2kRLY3z+hJbvmzemA8FH7Ber7FarRLonMM4jhF9JV8cp2lK40R6wrP4Ix44AouywG7/AiFEAo0x0Fq/UROmMdE6a2AJvyYME8LIYHSOwXA4b5OD9/PteujRD4LUjGntB5lw7Tzt26tnZ05vUR8+gh3vEPQTqZ1gnCbFFlOIhBaDVbDOYqQQmEFj1ALPuxyHiv1HIalz/AGi/obi5QF2aNFJSc+R2Oclfm8LeCI3rILl1fJsh0lxjH13rXCfH/D05zuG9gfY8y2M2GJXdBQGUqgoFLx+jSEpDaNZkuJhRTsn9ERKI3NugM7vEQ6fEPYfAPl4JojJMpycqKSSkzOJ9EwoSSGpDRcqs2iNlggmx3T8Al99JRU5cWg6ZDANfCaKTpQoT/ELS/n45YJwEcdUNpNfYiB+we9uEKrP8ygpUfxxVnWqQ9MnVfOCmmHJ+jmGPWuhRAdrR1hVwO5vYaufcGIH2/2FUw3FqoGTLZyhDBs1r3tG5wUGiuPAShjJZoV379a4v3kP2StIym7b1mCCLBPgUoNxspyjqmoIwsuyBKfCb+sGinx8bFt6YWwCay2yY9Wg7ViqeqVUco6dwhmDJCuW0XXdcmFLxDOu+j61pyOi2FFx/g+QUO9YtZ0mgAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 07&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/910d434322f3c529c5fa8adc657565af/d9199/001-07.png&quot;
        srcset=&quot;/devHistoryBlog/static/910d434322f3c529c5fa8adc657565af/8ff5a/001-07.png 240w,
/devHistoryBlog/static/910d434322f3c529c5fa8adc657565af/e85cb/001-07.png 480w,
/devHistoryBlog/static/910d434322f3c529c5fa8adc657565af/d9199/001-07.png 960w,
/devHistoryBlog/static/910d434322f3c529c5fa8adc657565af/e4611/001-07.png 1298w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt;시나리오2. Feature Branch 에서 Merge 발생&lt;/span&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/b10927f7e5be89c513d1e97116eb1a8b/d4377/001-08.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 63.74999999999999%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAABYlAAAWJQFJUiTwAAACMklEQVQ4y2VT227UMBDNp/MJvCDxzEMlfgAkBEIqWnqhUASiFbQUdnvZm5PYceJr7MPYSehKG2nky8wcz8w5KWKMiDEg0Jq+5fwc1xeHeT9eIT5usv0/7/rGr5g2oXeIluHgxXM8e/okhcJaD+dc3k+JU7rzHp5sAp38RW9rmOYndH2O5eIU94uvsPU3cnlo46CV2imOEv3wgLOWzOwDOlOi4z+gxCVkeYqu+gAnzuDkZQZVWkNqgT4M1QQtM2Bre0hl99rOLbveU8JwaeV3CHYIXR3Bywu0cg1tFbVu4ckMVexVg/ntEkvG9ytMhGjXoaGgFWuh2znYwyGs+ILbmxl+Xx0jeAUjGFW+HVqneQcl4Nt6H3C+qvDrnuYoGUTJqIIadzfHAD9Bv51BL97l1nOi7WiGQ5t9H2j21UjYI2hhrSM2abhOgyLIE8gUIhHTsyPoP69pDpvMbqSYBDoBWkkVJnXszLFI1A/SoIHTrEJKGuURo0G/niGUn+ikBr3qNtWU/WF8IO60XewKGEROHFkkYQ538grh7hVi+ZGqPkNsHwZf7oRMj12NCi1kzdBJDkO6sklbTUmSqeBannXmjYBdnsDzayLlL/qO5VaT37YN4VXQfEsc8Py3FW9eHuDz+7dopITqOrCyhBACVVXllYsGQnbYljVkZ7Bab9A0EhXFadJoCCGbMSYXVGwYATRNPijSGK9rSiAQzvOaTJLVdYW2lSgJSNLjyZ/+ojT/ZGrc/wMAzO14At46GAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 08&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/b10927f7e5be89c513d1e97116eb1a8b/d9199/001-08.png&quot;
        srcset=&quot;/devHistoryBlog/static/b10927f7e5be89c513d1e97116eb1a8b/8ff5a/001-08.png 240w,
/devHistoryBlog/static/b10927f7e5be89c513d1e97116eb1a8b/e85cb/001-08.png 480w,
/devHistoryBlog/static/b10927f7e5be89c513d1e97116eb1a8b/d9199/001-08.png 960w,
/devHistoryBlog/static/b10927f7e5be89c513d1e97116eb1a8b/d4377/001-08.png 1294w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt;시나리오3. Develop Branch 에서 PR 발생&lt;/span&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/0fedb173c925694aaa072abc5475e713/610c0/001-09.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 63.74999999999999%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAABYlAAAWJQFJUiTwAAACJUlEQVQ4y21T227UMBDN/7/2I4rEOw8I0QIPqOIFBIWigrbby26SzeZmO77E9uHY3ZRFxZJjZ3zmzJkZuwBHjBEhhLRFWZa4vr7GYn9aj+ZiP8Ysozh2Cj7g9PQUJycn2WathXMzEuJ4pjHPc56L78JTpE8IHnY2KKsttuUGxph8mFY9SXpYTkengDjbrNI5y4Dm/4QJaJyGdhOcN/nfM0gaortCV72DaD4CXpBbJwmQNkBM9lnaOWVLMu8f5Yfooa0iscXMsko1QvZfYLpPmMcrGNVhngTWdxtsdv1zhWmTlCmSeNYwpaGMhNUCdw8lft/VCMNXmO0Z7PoVor5FJC5MA2bZPSe8rVr8vO9gZQsrGN25XOzoHbwaYEc6mQoYfyBszxH6b9nRew8ztrlN8Yi0cHQ2hnVh2pFREcNTPQKRZmj+/o+/EMozYgxrzFsgSMjA8aiORWCkdD2yg50QEvESMSnRkg2eHm22g79/jai+89wgpEyM+lfho5JDl0ICiMONDU82LDZ2N1YfEG5Zy/It7SXx8oA9KBRdAzX27LTLSu2wY932cJK2SWWb7uqcutETTHMJXV7A7C+Z8pa1H6D7HWP2WVjx5uULfH5/jrbvIcYRTbPHw8MmTyFkforDkOxNXquqQtt1aNoB9W7Px1Bh37aYJp2DF3XTYiCR1poEAqvVCuv1Gjc3K9R1TSBV8SyvfDlKqYydqH7iXkp5+OejYJZ/AKS176JumPi1AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 09&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/0fedb173c925694aaa072abc5475e713/d9199/001-09.png&quot;
        srcset=&quot;/devHistoryBlog/static/0fedb173c925694aaa072abc5475e713/8ff5a/001-09.png 240w,
/devHistoryBlog/static/0fedb173c925694aaa072abc5475e713/e85cb/001-09.png 480w,
/devHistoryBlog/static/0fedb173c925694aaa072abc5475e713/d9199/001-09.png 960w,
/devHistoryBlog/static/0fedb173c925694aaa072abc5475e713/610c0/001-09.png 1295w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br/&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt;시나리오4. Develop Branch 에서 Merge 발생 (자동)&lt;/span&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/a3f9a27e29fccc504fb781d549523317/ffaa5/001-10.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 63.33333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAABYlAAAWJQFJUiTwAAACG0lEQVQ4y21T22obQQzd/3/zZ9TQD0gppSk0EFoolBLoBYOxnXjX3st4d+6XU0nOOi7pwlgaaXQkHckV6CulIOfMKg6HA1arFWb7tSRF9Mv92vf8VddBORcs3yyxWCzEFkJAjBEF5VUg22NMl9jZX/FPzgkheuybJ2x3G0zjJE7nHIwxL9XQu2L2QDKULMI7+39AvrhgYQM9zI4tkoQ/YydMViHxvXjk+hMwPcD4QPbwqm1p2QeHlKIYckmwXiMkTyAM6Olu5E1MlHhYIda3WP/5jN3m4d8K6VRcDQPooIVD7x20m6idEdvHBr/We2QCd8MB4dRRkS1ye4+0v0XYvKNwizJXyYCbusPPbQ8/tfBjj0iDCDGg0El6gFPtC4eUuMQzJckPsOsbwNcXQJZVoGlZIr4Qh8UoZv4CkJlbBiSbBBFYcVp81D3c7g6l//YMmAVUOORpCoC3cq4zJhpKIf7ERruazekczD71G3n/kTSPeSwy5fS81Mi0c26ad+QsE9tGaVPM5C+0YudF7ZG31Hb/BRi+E501Kq16mFHRFINUKuSPHaJWCM7IAodTe7bRwKLViKT7cUAgiuzjHWz9Fa79gWwbVB/eLnH//gZqHGUgvMjHtkXdNFBKoes69H2Pjs7heJQ7S6VO6I4tJQzENfEZeP0Sqn1Dj3qaJm09V6m1xjAMEjhSEgadDwPPchxPUCS99/IXNYZ2l/S/JRPxnjOkKoQAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 10&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/a3f9a27e29fccc504fb781d549523317/d9199/001-10.png&quot;
        srcset=&quot;/devHistoryBlog/static/a3f9a27e29fccc504fb781d549523317/8ff5a/001-10.png 240w,
/devHistoryBlog/static/a3f9a27e29fccc504fb781d549523317/e85cb/001-10.png 480w,
/devHistoryBlog/static/a3f9a27e29fccc504fb781d549523317/d9199/001-10.png 960w,
/devHistoryBlog/static/a3f9a27e29fccc504fb781d549523317/ffaa5/001-10.png 1299w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;a href=&quot;https://eunyoung-autocrypt.github.io/devHistoryBlog/works/posts/2021-01-18--002&quot;&gt;&gt; [작업로그] CI/CD 구축 #2 - Docker, Docker Compose 설치&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://eunyoung-autocrypt.github.io/devHistoryBlog/works/posts/2021-01-18--003&quot;&gt;&gt; [작업로그] CI/CD 구축 #3 - BitBucket 설정 및 Jenkins 설치&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://eunyoung-autocrypt.github.io/devHistoryBlog/works/posts/2021-01-21--001&quot;&gt;&gt; [작업로그] CI/CD 구축 #4 - Jenkins Item 등록 및 Pipeline 작성&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://eunyoung-autocrypt.github.io/devHistoryBlog/works/posts/2021-01-23--002&quot;&gt;&gt; [작업로그] CI/CD 구축 #5 - sonarqube 설치 및 pipeline 작성&lt;/a&gt;  &lt;/p&gt;</content:encoded></item><item><title><![CDATA[[작업로그] CI/CD 구축 #2]]></title><description><![CDATA[Docker, Docker Compose 설치]]></description><link>https://ssongey.github.io/works/posts/2021-01-18--002</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2021-01-18--002</guid><pubDate>Mon, 18 Jan 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; 1. Docker 설치 &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt;1-1. Docker 설치 및 구동 확인&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;docker 설치에 필요한 패키지 설치&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;$ sudo apt update &amp;amp;&amp;amp; sudo apt install \
    apt-transport-https \
    ca-certificates \
    curl \
    software-properties-common&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;도커의 공식 GPG 키와 패키지 저장소 추가&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo add-apt-repository \
   &amp;quot;deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;docker ce 설치&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ sudo apt update &amp;amp;&amp;amp; sudo apt install docker-ce&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;docker 구동 확인&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ sudo systemctl status docker&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt;1-2. docker 명령어 실행 시 오류&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;docker 설치 완료 후 명령어 실행 시 아래와 같은 permission 오류가 발생한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/a396beb12c4b5d6f9ed71738732e2ff2/18539/002-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 6.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAABCAYAAADeko4lAAAACXBIWXMAABJ0AAASdAHeZh94AAAAQklEQVQI1yWIWw6AMAzDuBFo7R4pZRoSu/+RAisfUWxv43Y+c8QWXx10r4QpAWVtEmyWaWdmg3wtxS+H/a2Ug6I7X0PQIVYbqdQGAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/a396beb12c4b5d6f9ed71738732e2ff2/d9199/002-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/a396beb12c4b5d6f9ed71738732e2ff2/8ff5a/002-01.png 240w,
/devHistoryBlog/static/a396beb12c4b5d6f9ed71738732e2ff2/e85cb/002-01.png 480w,
/devHistoryBlog/static/a396beb12c4b5d6f9ed71738732e2ff2/d9199/002-01.png 960w,
/devHistoryBlog/static/a396beb12c4b5d6f9ed71738732e2ff2/18539/002-01.png 1074w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;/var/run/docker.sock 파일을 확인하면 root 사용자, docker 그룹일 경우에만 read/ write 권한이 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/d0830f4f5264bf45ba72d75fcd903ab3/8710b/002-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 567px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 8.75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAACCAYAAABYBvyLAAAACXBIWXMAABJ0AAASdAHeZh94AAAAbUlEQVQI1z2NWQ6DMAxEORFqHRJncfbC/W80BEvlY/RGerJnG7OgdUGpEefVlX3kl0/mry7XcP19zXAH4aDPotFO3x3WELYkDmR2OCY9FmHMNVJbRExOx3IJmjEf7yE+wFuL6Hj1iMRenyUOuAFk1UOSZn5deAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/d0830f4f5264bf45ba72d75fcd903ab3/8710b/002-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/d0830f4f5264bf45ba72d75fcd903ab3/8ff5a/002-02.png 240w,
/devHistoryBlog/static/d0830f4f5264bf45ba72d75fcd903ab3/e85cb/002-02.png 480w,
/devHistoryBlog/static/d0830f4f5264bf45ba72d75fcd903ab3/8710b/002-02.png 567w&quot;
        sizes=&quot;(max-width: 567px) 100vw, 567px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt;1-3. 해결방법&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;파일 권한을 666 으로 줘도 되지만, 현재 사용 계정을 docker group으로 묶는게 낫다고 판단했다.&lt;/li&gt;
&lt;li&gt;만약 동일하게 permission 오류가 난다면 세션을 재시작해보자.&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;ul&gt;
&lt;li&gt;현재 사용자 docker 그룹에 추가&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ sudo usermod -a -G docker [현재계정]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;계정이 속한 그릅 확인&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# 현재 사용자가 속한 그룹 확인
$ groups

# [사용자 아이디]가 속한 그룹 확인
$ groups [사용자 아이디]  &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt; 2. Docker Compose 설치 &lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;다운로드&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ sudo curl -L &amp;quot;https://github.com/docker/compose/releases/download/1.24.0/docker-compose-$(uname -s)-$(uname -m)&amp;quot; -o /usr/local/bin/docker-compose&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;실행 권한 부여&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ sudo chmod +x /usr/local/bin/docker-compose&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;p&gt;&lt;a href=&quot;https://eunyoung-autocrypt.github.io/devHistoryBlog/works/posts/2021-01-18--001&quot;&gt;&gt; [작업로그] CI/CD 구축 #1 - CI/CD 시나리오&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://eunyoung-autocrypt.github.io/devHistoryBlog/works/posts/2021-01-18--003&quot;&gt;&gt; [작업로그] CI/CD 구축 #3 - BitBucket 설정 및 Jenkins 설치&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://eunyoung-autocrypt.github.io/devHistoryBlog/works/posts/2021-01-21--001&quot;&gt;&gt; [작업로그] CI/CD 구축 #4 - Jenkins Item 등록 및 Pipeline 작성&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://eunyoung-autocrypt.github.io/devHistoryBlog/works/posts/2021-01-23--002&quot;&gt;&gt; [작업로그] CI/CD 구축 #5 - sonarqube 설치 및 pipeline 작성&lt;/a&gt;  &lt;/p&gt;</content:encoded></item><item><title><![CDATA[[작업로그] CI/CD 구축 #3]]></title><description><![CDATA[BitBucket 설정 및 Jenkins 설치]]></description><link>https://ssongey.github.io/works/posts/2021-01-18--003</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2021-01-18--003</guid><pubDate>Mon, 18 Jan 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt;1. BitBucket Webhook 설정&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Repository -&gt; Pepository settings -&gt; Webhooks -&gt; Add Webhook&lt;/li&gt;
&lt;li&gt;Push Webhook 설정&lt;br&gt;
— URL : &lt;a href=&quot;http://JENKINS-HOST/generic-webhook-trigger/invoke?token=build-test-wh-push&quot;&gt;http://JENKINS-HOST/generic-webhook-trigger/invoke?token=build-test-wh-push&lt;/a&gt;&lt;br&gt;
— token 값이 중요!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/f7419e7d08cb45e23f57fa11bf769a55/6e9ba/003-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 731px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 80.41666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAIAAACZeshMAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABlUlEQVQoz41Sy3KCQBD0e/M5Wmq8+Q055Z6qpOIhx1SqFMuICgrssss+eZkG4jNq7IJhKejp6Zlp8UR9e9E64mmaaq1tmhZFsb0PrTimc3fh+2vAdRee5yFFWZbFKcpyWwU8jsnWWkopUhBC8KgPURSR6pXSIAhxCAkLYrUhggtzQt6fkNVak2WZ0hWMNjDyT9nHZHCgM5lMps7UcZz53A13QDF5nl8lF0UO2dHovdNuDwaDfr/f6/W63S5ip9MZDodKqUbjAtlozRkdb7Kp61MSoWZ7irNunZeNiGFxnogdOOeIUspbnvM8i1mM34wxYRRicp63gs/lconGV6b+yP6SyxpFLY3yMC1IJUkC2SYKkSglpRBKGyas1OmBbKyBCEaM/4zRQRDUK9Nggxubg6RYFXQ0r9F4PHjGBzRcKEtjVqnJyrOpgRHWtQhc2AIU0YztQMYnQgnTW8Eif+XCLdZLq4oGlNc8H3d7tmZPb+OvmZ/ULYdlxhiSYrFvkZt+Pn+4D4+vL5++NKlN83vX8yIuVrvHD821mDozEdyqAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;003 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/f7419e7d08cb45e23f57fa11bf769a55/6e9ba/003-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/f7419e7d08cb45e23f57fa11bf769a55/8ff5a/003-01.png 240w,
/devHistoryBlog/static/f7419e7d08cb45e23f57fa11bf769a55/e85cb/003-01.png 480w,
/devHistoryBlog/static/f7419e7d08cb45e23f57fa11bf769a55/6e9ba/003-01.png 731w&quot;
        sizes=&quot;(max-width: 731px) 100vw, 731px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pull Request Webhook 설정&lt;br&gt;
— URL : &lt;a href=&quot;http://JENKINS-HOST/generic-webhook-trigger/invoke?token=build-test-wh-pr&quot;&gt;http://JENKINS-HOST/generic-webhook-trigger/invoke?token=build-test-wh-pr&lt;/a&gt;&lt;br&gt;
— 역시 token 값 중요!  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/c29316ea81ce16f403423c39ba9a239a/ace37/003-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 666px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 124.16666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAZCAYAAAAxFw7TAAAACXBIWXMAABJ0AAASdAHeZh94AAACfElEQVQ4y5VV2ZKjMAzk//9t3+eo2oQQjoSAuW/QqgVmDAkzs1Sp7IBpuqWWYqVZSSc3pOCRUF1XVJYlVVVF0zTRb679OStRik5nm1zPI/d6Jdu26eI4Atr3PXVdJ6vse94PA8fI+4GGcVxBNbCFF5IkoaIoKE1TyrKM97nscT9b7sVxTCpRpLKC4qymUJVU1N0z4J5+27YSAMzznFNQ0chM9EsSYLYAPEk20bEih3VdCyNhmOUid2CpZow7uRp3A4hDANS50RfumwFAk4TJ0jJpN01DKbP6G03keCGVnEs82wNu5O8UWuYPLaPkCidLUeZI1xSgeN/ZZwUcOE84DLsg7vcbPUL2p+9T+HiQ57n8kURe1DaChWAf2GhlKGC7ZEM6GOV5IZaZi5NJ5RHIszRA3VJWtlQ1/RYQAIoNDpsgKq5yEATkM7vb7SarH/iyehxQgHfghtlmzZouy6xQ1+FhRx0fQAdpRkjF3DUcDKAZIgCMD6yAZkLxoGCGcTnS1WNGnDcfqx8Ic6hQLP+7vrZeNTlSEsWKoijiDxTSz5CmC4YLv9eKm62395HeY1B8fH6K5FcX5Nr2Wew1jsP6rsHwi+W0vPAFtv3o7IyRVUR0ZlAoeJJsHsaKnLmuK3kzjT8uZwCi2FpwQbysHRfuCVCDYoTBJgEfxOGQTX6/36nmqppn9/19CAjb+L5HztUR4AsPXtjm1cjajK8jQJgWVYR0PXzBYjuynuMQED18Pp3J4b8Dk9F0MFgPGM4VbZnIn8tAvutwwtU6E38CeykZgD130UfQsBcdmTQbBT/8Cx5XOc9kQKCyilm+6or/AoT/3t/e6MaA82RpfgX4D/TUpUlGdVAqAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;003 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/c29316ea81ce16f403423c39ba9a239a/ace37/003-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/c29316ea81ce16f403423c39ba9a239a/8ff5a/003-02.png 240w,
/devHistoryBlog/static/c29316ea81ce16f403423c39ba9a239a/e85cb/003-02.png 480w,
/devHistoryBlog/static/c29316ea81ce16f403423c39ba9a239a/ace37/003-02.png 666w&quot;
        sizes=&quot;(max-width: 666px) 100vw, 666px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt;2. Jenkins 설치&lt;/span&gt;
&lt;span class=&quot;title__sub2&quot;&gt;1. Compose 파일 작성&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;jenkins 는 docker 기반으로 설치를 진행하였다.&lt;/li&gt;
&lt;li&gt;추후 테스트 도구 확장을 위해 docker-compose 파일을 생성하여 서비스 기동 시켰다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;# jenkins-compose.yml
version: &amp;quot;3.6&amp;quot;
services:
    jenkins:
        image: jenkins/jenkins
        container_name: jenkins
        ports:
            - 10000:8080
            - 50000:50000
        volumes:
            - ~/docker-volumes/jenkins:/var/jenkins_home&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt;2. 서비스 기동&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;compose 파일 실행 전 volume 디렉토리를 생성한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ mkdir ~/docker-volumes/jenkins
$ docker-compose -f jenkins-compose.yml up -d&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt;3. Jenkins 기동 시 permission 오류&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;위에 compose 파일 실행 전 volume 디렉토리를 생성하지 않으면 아래와 같은 permission 오류가 난다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/f4014ee034b2108d9754029a0e6a29f1/6da96/003-05.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 922px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 13.750000000000002%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAABJ0AAASdAHeZh94AAAAiElEQVQI102OWQ7CMAxEexoEVGR1FqclQu39zzTYiRD9eHI8M7azfI43eq84z46UHTzdYNwDzq+w7inMauxV+6P6lSXvFZQsDlncGsn7hUgGuXhUjqhVYEKpYfRa9XApQTIBLDPcEtqWhrfcE2GNHrQzkrKVYSga+jEHJ+qxHMnZj2WqaUY/9gU6MmCdiiPj5QAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;003 05&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/f4014ee034b2108d9754029a0e6a29f1/6da96/003-05.png&quot;
        srcset=&quot;/devHistoryBlog/static/f4014ee034b2108d9754029a0e6a29f1/8ff5a/003-05.png 240w,
/devHistoryBlog/static/f4014ee034b2108d9754029a0e6a29f1/e85cb/003-05.png 480w,
/devHistoryBlog/static/f4014ee034b2108d9754029a0e6a29f1/6da96/003-05.png 922w&quot;
        sizes=&quot;(max-width: 922px) 100vw, 922px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Host에 생성된 volume 디렉토리 owner 가 root 이기 때문에 오류가 발생하였다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/c965f23a31fbf8d5b4e2ae164292c448/508ef/003-06.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 578px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 19.583333333333332%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAABJ0AAASdAHeZh94AAAA0UlEQVQY0yVQ7ZKEIAzzVW5u51BPwQ9AUFHEdXdm7/2fJ1fqj0yhJGlDcT53xGPFtnloo2Bsh2Fsuea71gojQZuOqoRSFSRBdTWjlRUaWd5oBYrXO7HhslgW2KmH8yOcuzFTPxuYacAaJlgaZG3maOIOPKD5faBm/KBI54ZA282zYcFB5nfPIaWAnMCTeD8CPn8XvS/Y40ycnGxB00uIpoaoHhDlF4rnFRFJeKSVza5XJGPHkfkrdk/nHifx0hnI/N7c0wI5jeg1vgeHSkmUZPgP1CeCp2AMXCsAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;003 06&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/c965f23a31fbf8d5b4e2ae164292c448/508ef/003-06.png&quot;
        srcset=&quot;/devHistoryBlog/static/c965f23a31fbf8d5b4e2ae164292c448/8ff5a/003-06.png 240w,
/devHistoryBlog/static/c965f23a31fbf8d5b4e2ae164292c448/e85cb/003-06.png 480w,
/devHistoryBlog/static/c965f23a31fbf8d5b4e2ae164292c448/508ef/003-06.png 578w&quot;
        sizes=&quot;(max-width: 578px) 100vw, 578px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;해결방법은&lt;br&gt;
— 이미 생성된 volume 디렉토리 owner 를 현재 사용자로 변경하거나&lt;br&gt;
— compose 파일 실행 전 volume 디렉토리를 먼저 생성하면 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# 서비스 기동 후 : permission 오류 해결
$ sudo chown 현재사용자:현재사용자 -R ~/docker-volumes/jenkins

# 서비스 기동 전 : ~/docker-volumes/jenkins 디렉토리 생성
$ mkdir ~/docker-volumes/jenkins&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt;3. Jenkins 세팅&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt;1. Unlock Jenkins&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;jenkins 웹페이지 접속 시 아래와 같이 init password를 등록하라고 나온다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/07f30343b241b9e43a76622e74ab3972/d2a60/003-03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 807px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAABJ0AAASdAHeZh94AAACG0lEQVQ4y51Ty67aMBTke/sR/Y/uuuvuSghRNgipqMt2UaksKqhogCTk4TgPkvBIMj1jSGoqXVWqpYnt2D6eM3M8cl0X+/0eSZIgiiL8q3Vdh7ZtDTi258SoKAporRGGITzPQ1VVyLLM9GVZ4nQ6mXXuu1wuBnVdG1yvVzRN84QRP2maYjabYTqdYj6fYzweY7VaYblcmn8vLy9YLBaYTCZQSpkLeSbPc5zlAraBIT+8lSlzExHH8TDnYY6DIMButzP98XgU+Aik9zwXWtb7NuLndrtBxRGOvm8YMH0eZOBQekrhOA42mw3W6zV+bnfY7lyDtYwPno9OiA0Br7cGoS4QKY0gDOCTAQMqCShGHcQ4R9hpYax0Ap0VSIsSOi/MOC9OhtQQsG07nKsz6lOJWjZVglo2nTkXM3KVIBOUqZiV5Q9kKEVDGleLgTRoCEi6dZzgnKSoI4UqjE1vIP9LmWfeEcmvPZSkqJw9tHNAHstecbsTQn1J3VOW6IHoZtKRtDSNSDVUwvRSeKLtQcTfio6ujAORgdAPAwkGGxiydBIxg4a0D3HZ9zXJ8mDPmmxEK67xTGvV31NAlo0vNxN0ly5TGxYzg/VFbb+WHva/J4ZkY4My2Pj7Rdi4CuubVEpLDe3bbPSVb1wU4e33aqNp2qe3Pnpt458DdxavrUmy+LaN8PGrg0/f3XvK/9vah27vFz/w5t1nvP3wBb8BKDl/rIm3aMgAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;003 03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/07f30343b241b9e43a76622e74ab3972/d2a60/003-03.png&quot;
        srcset=&quot;/devHistoryBlog/static/07f30343b241b9e43a76622e74ab3972/8ff5a/003-03.png 240w,
/devHistoryBlog/static/07f30343b241b9e43a76622e74ab3972/e85cb/003-03.png 480w,
/devHistoryBlog/static/07f30343b241b9e43a76622e74ab3972/d2a60/003-03.png 807w&quot;
        sizes=&quot;(max-width: 807px) 100vw, 807px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;해당 디렉토리를 볼 필요 없이 jenkins 로그를 확인하면 password를 볼 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ docker logs jenkins&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/56f5155c887fc791e0267fe5f412d82f/66caf/003-07.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 853px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 36.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAIAAACHqfpvAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAA4klEQVQY022Qa04DMQyEcxpatk7iZGPnTfkNKlyDA1DB8XGyWlokpE/WKNFkJla1cW3xntZT72mfsT/lnAPAA+gj6MNE9EGbo+piKFQrt8pFxNTbi0VOpk45oAOLJ/QgwrkxhzmdcyiBKnOL20w95hLOzzWlUCpJBTET4xosRy+Co2NGYx/VF8Cn0deBuVrzbc2HPoFdEBe5trjYKfbCN0byO7nLipfVvokI+Ir6hZwkxORHzghxuZBUkDrew2bbUFRJ2s45CJXibXk8diEfyeuv4R5V5Mt/kZ2VnZnJMf1v/gF2lFbG15/m5wAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;003 07&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/56f5155c887fc791e0267fe5f412d82f/66caf/003-07.png&quot;
        srcset=&quot;/devHistoryBlog/static/56f5155c887fc791e0267fe5f412d82f/8ff5a/003-07.png 240w,
/devHistoryBlog/static/56f5155c887fc791e0267fe5f412d82f/e85cb/003-07.png 480w,
/devHistoryBlog/static/56f5155c887fc791e0267fe5f412d82f/66caf/003-07.png 853w&quot;
        sizes=&quot;(max-width: 853px) 100vw, 853px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt;2. Jenkins 플러그인 설치&lt;/span&gt;
&lt;span class=&quot;title__sub3&quot;&gt;2-1. Jenkins 기본 플러그인 설치&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/42474c208e53f2cfab8498d7b84b2841/eafa0/003-04.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 939px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 53.75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABJ0AAASdAHeZh94AAAB6klEQVQoz21TaXPaQAz1//9J+ZxpG5oLcEMNPrAhvq/1CT54lRSGzCT1zBtptdqnt1pZM00Tu90Oy+UShmGI5djxeBR/tVpB13W4rgv+LpfLDV8/jmmcuN1usV6v4TgONpsNEVp4930pZNAeF/I8D/M8YxxHTNMkYF/WI69HIdXG4YyZNuf5I2mmjQv7kjiQzyQDzuczuq5DXddiu7YVv2ka8juJCWGsGhRtj7zuUJItmg5p1YDjUVkjUTUGUvDteoSJik1SkNSSGLnyoxPgbm3j3vBw/5dgHPDsRvDrE9yyhRGkSPMCOrWEW8CwqTU+taQ/nUSZUhWKohTF2hMdvtMdPNgBrLwRuKqH3w7wiHQX5cgoefP2RmQmHVYoyxJVVQlZ09SyLq4xTQ9z7KsTnLKDVbSwiw5m3hIamOT/eU9QkgLuVUt9qyolYOIsy5CmqYAVclxb7EP8JHU/LF9ULvYRHij2m+xrUGB1TJDQQYtenq96oNd2XQ+2ZdHLHxAGAaIohiJ1XFD75cZ4iSo8ByVeQnUDrx8Zbog4zehQJIjj+BvCMEJF/RPChePjyYsJ0dV+gtW/EiH3MEkSulr2AVIcxwl8UsfzyuD+9X0P7XNAp/9glGHmcZhnwvUP4ZnkFy2VEqJhGG7j9A8rKjyMK6B01QAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;003 04&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/42474c208e53f2cfab8498d7b84b2841/eafa0/003-04.png&quot;
        srcset=&quot;/devHistoryBlog/static/42474c208e53f2cfab8498d7b84b2841/8ff5a/003-04.png 240w,
/devHistoryBlog/static/42474c208e53f2cfab8498d7b84b2841/e85cb/003-04.png 480w,
/devHistoryBlog/static/42474c208e53f2cfab8498d7b84b2841/eafa0/003-04.png 939w&quot;
        sizes=&quot;(max-width: 939px) 100vw, 939px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;title__sub3&quot;&gt;2-2. BitBucket 연동 관련 플러그인 설치&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;jenkins 관리 &gt; 플러그인 관리 &gt; Bitbucket 검색 후 아래 두개 설치하면 된다.&lt;br&gt;
— Generic Webhook Trigger&lt;br&gt;
— Bitbucket Plugin  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/78457f0184f1f35521a67870ab9e486f/6f92b/003-08.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 40%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABJ0AAASdAHeZh94AAABgUlEQVQoz5WSXWsTQRSG97965aW/xAtBKIJIkX7ZUFtaRBQvvCtCBaUh2Xw0iel+Znf2y9md2WSfzm5M73rhwDPnzDuHw3uGse5mcybTGf2Bzes377j+ccN8sWR6N2exvMdxPO6fxMVxfTw/wPV8wlWEdfnpCwcnZ7zdP+TZ8xe8fLXH+6Me+wcfODT6Se/8SY5Pz+l9vOTi6jNnF1d8/fYdazxb8vN3n5tft52rFns0NkwYmji0xwzs0T+2eavtGAy359v+gPFkioVZWSHxQoG/isnzgs2maWW2+/+trqHMQ2LfJg5GrDybJJo9kokFRbLgb7o0dU6HkgG6Cg0B61qyaRq01jTGiLWu1+RFRixCRLoyDmNqlaN3VBlVmaKqlgxVbuPuTquya6aURtc1ltI1UZLxx4twgpjUjFxWqkOW1WO+o63XxoTW6y6WVWXqSrIsR0qJVZuHEknSfQHX9YjjuDunaYoQgiiKjCY6PTIURUFlmpSlpDaOGjNuS5u3PACXFU5+uEPJVAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;003 08&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/78457f0184f1f35521a67870ab9e486f/d9199/003-08.png&quot;
        srcset=&quot;/devHistoryBlog/static/78457f0184f1f35521a67870ab9e486f/8ff5a/003-08.png 240w,
/devHistoryBlog/static/78457f0184f1f35521a67870ab9e486f/e85cb/003-08.png 480w,
/devHistoryBlog/static/78457f0184f1f35521a67870ab9e486f/d9199/003-08.png 960w,
/devHistoryBlog/static/78457f0184f1f35521a67870ab9e486f/07a9c/003-08.png 1440w,
/devHistoryBlog/static/78457f0184f1f35521a67870ab9e486f/6f92b/003-08.png 1501w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt;3. Jenkins Credential 등록&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;credential 는 보통 ssh로 등록하는데, &lt;/li&gt;
&lt;li&gt;해당 시나리오의 경우 comments 등록이 필요하여 CI용 bitbucket 계정을 생성 후 등록하였다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;title__sub3&quot;&gt;#. Jenkins Credential 등록 방법&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;jenkins 관리 &gt; Manage Credentials&lt;/li&gt;
&lt;li&gt;아래 그림 부분에 마우스 오버 시 작은 화살표가 생기는데, 그거 클릭하면 ‘add credential’ 버튼이 생긴다.&lt;/li&gt;
&lt;li&gt;또는 global 클릭 후 좌측에 add credential 버튼을 클릭하면 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/d58c52fc6a629b9e42e078f0632b8424/2a195/003-09.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 620px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 31.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAIAAABM9SnKAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABGUlEQVQY042OXUuDYBiG/bO1TFyNMkyiNSgb21qGG9oQYeyog/5DQQedVLjUTWFBW6XlVJjadK8fvQ7qpA66uHi4uQ8ebkSSJFVRnkYj0zSGAxgVVZFfxuNXN9A+AvnNM2dRlmVp9gcIw/J0jWE5oX0uHlWbh8cntWarwbQabKfeFqpnnVNO7F1cQnmxxwndH3mhixBUpYAT5D5NlWmstLu+SaIbO2tFKIHi2/BiRWKPPChTFRQtreJEYekKtgVFPH8WRaHjzZ/fXRAn+cLviWmax9SZTm6upatbW1YjAOafOXEc57MXYAEASJIkhsa/TFIQhpPh4PGh37+/03RdVVVd1wzDgI+R7B94QTB1XNt17SWWZfm+D/svvUIhFwHjDqwAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;003 09&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/d58c52fc6a629b9e42e078f0632b8424/2a195/003-09.png&quot;
        srcset=&quot;/devHistoryBlog/static/d58c52fc6a629b9e42e078f0632b8424/8ff5a/003-09.png 240w,
/devHistoryBlog/static/d58c52fc6a629b9e42e078f0632b8424/e85cb/003-09.png 480w,
/devHistoryBlog/static/d58c52fc6a629b9e42e078f0632b8424/2a195/003-09.png 620w&quot;
        sizes=&quot;(max-width: 620px) 100vw, 620px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;‘bitbucket-auth-id-pw’ 라는 이름의 jenkins에서 사용할 bitbucket 계정을 등록하면 된다.  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/52d9c35b5d1872aa037edc86cef70587/27524/003-10.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 646px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 99.58333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAABJ0AAASdAHeZh94AAABS0lEQVQ4y6VUS1LEIBTMnTyFO8/kCVx4D8ulnzO4cvYuZpOYDxACCZC076EZZyxnJmGo6oJQxUt3v4asLEso1SKEAO/9bh7HMQlZXddoGoG2bSGVgpQSSiq4n+JrkWmtIYRApzsYa8HfXdfR3ybwmKbfeQkyPpznOQQxm+UynHMRwzBEzN9nJfNhYwxYOvvZNE1cRyuIeVXR/uf3Pis5K5n/2vd9ZDHLOzUWSa6qCnlREFMbaZ9icFbyPitep3T2QLK1hnIoY2TYzzUd/Veypahw9tjwJV1cLJnnff+SC3JTGGu7eVQyZ1CRfyx9Rt8PCKkMvXcwnSEfVSwsRBPXISQW5LvLOSzyArrVO8nJHlqSp4mhJh/5tsyNSS74pxWXx+bpfYuHtw+8bLb0BobLg31994yr20fc3L9CWXfwBqaMbKTDnqiufUiP4QvK7yPSmiaAsAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;003 10&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/52d9c35b5d1872aa037edc86cef70587/27524/003-10.png&quot;
        srcset=&quot;/devHistoryBlog/static/52d9c35b5d1872aa037edc86cef70587/8ff5a/003-10.png 240w,
/devHistoryBlog/static/52d9c35b5d1872aa037edc86cef70587/e85cb/003-10.png 480w,
/devHistoryBlog/static/52d9c35b5d1872aa037edc86cef70587/27524/003-10.png 646w&quot;
        sizes=&quot;(max-width: 646px) 100vw, 646px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;a href=&quot;https://eunyoung-autocrypt.github.io/devHistoryBlog/works/posts/2021-01-18--001&quot;&gt;&gt; [작업로그] CI/CD 구축 #1 - CI/CD 시나리오&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://eunyoung-autocrypt.github.io/devHistoryBlog/works/posts/2021-01-18--002&quot;&gt;&gt; [작업로그] CI/CD 구축 #2 - Docker, Docker Compose 설치&lt;/a&gt;  &lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://eunyoung-autocrypt.github.io/devHistoryBlog/works/posts/2021-01-21--001&quot;&gt;&gt; [작업로그] CI/CD 구축 #4 - Jenkins Item 등록 및 Pipeline 작성&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://eunyoung-autocrypt.github.io/devHistoryBlog/works/posts/2021-01-23--002&quot;&gt;&gt; [작업로그] CI/CD 구축 #5 - sonarqube 설치 및 pipeline 작성&lt;/a&gt;  &lt;/p&gt;</content:encoded></item><item><title><![CDATA[[작업로그] MySQL Optimize]]></title><link>https://ssongey.github.io/works/posts/2021-01-15--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2021-01-15--001</guid><pubDate>Fri, 15 Jan 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;요청사항&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Replication 이 적용된 두 서버의 DB 의 몇몇 테이블 스페이스가 달라요. 확인 해주세요.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;확인&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;DB 데이터 파일이 존재하는 디렉토리에서 데이터파일 사이즈 확인 결과 두개의 로그파일 사이즈가 달랐다.&lt;/li&gt;
&lt;li&gt;ibd 파일 위치: my.cnf 파일안에 data 경로 &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/1166e33cedb8d49085d6c6d7e0452df1/d10dd/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 26.666666666666668%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAIAAADKYVtkAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABAklEQVQY0yWOW1ODMBhEI1dFKaRJIPkgEK5DvbRQ2qQMT44+Ofr//46Mvp3ZnZ2z6HQ8ruv6+vYy64u+ab0YczPaXCtVfn68f/98VUoty3J4Pozjab5M53m66uvGXdegh+BRCMBBIGIMeJ8RKim9dz2EUN934zRuwEVGnsI8xnkcZzFWLAkcZ8sRIbRpWqCkAqgBGikVF/5fNwzDzRjf8+u6ZoSIJJGcFwB5mjq2fWdZKNztsiwnYbhpc8bKNE2iiATBNu66zmjtum5RKk5Iw0WVpK2AFjKJceT7KIrislQ5pTXnKuWVEL2UkrL/2/N8tixbFsUeY0Epp5ufSRDAmGc7vwosIA5Pzsj0AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/1166e33cedb8d49085d6c6d7e0452df1/d9199/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/1166e33cedb8d49085d6c6d7e0452df1/8ff5a/001-01.png 240w,
/devHistoryBlog/static/1166e33cedb8d49085d6c6d7e0452df1/e85cb/001-01.png 480w,
/devHistoryBlog/static/1166e33cedb8d49085d6c6d7e0452df1/d9199/001-01.png 960w,
/devHistoryBlog/static/1166e33cedb8d49085d6c6d7e0452df1/07a9c/001-01.png 1440w,
/devHistoryBlog/static/1166e33cedb8d49085d6c6d7e0452df1/d10dd/001-01.png 1749w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;혹시몰라 mysql 접속 후 data+index 사이즈를 확인했지만 현상은 동일했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/9c11b3a612210fc31318553d024fff7c/7b857/001-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 13.333333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAl0lEQVQI102NzQ6DIBAGF38Ao6QKiHiql3opSfVm3//BvgKtpodJdjeTWXKjw+xn+B/Wjui6DkoptG0LIkIIT7yPI94VJjfBORddH10LKSWEEOCcZ5eGQcNoA2NMltJeliWqqsokaV0f2LcNjWigtUZ/62FHm2fG2Dd0IqTIH1Kkrusr8s9yXxBeAcQJPDopkiiK4nLO8Adwm0S3VOEI6wAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/9c11b3a612210fc31318553d024fff7c/d9199/001-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/9c11b3a612210fc31318553d024fff7c/8ff5a/001-02.png 240w,
/devHistoryBlog/static/9c11b3a612210fc31318553d024fff7c/e85cb/001-02.png 480w,
/devHistoryBlog/static/9c11b3a612210fc31318553d024fff7c/d9199/001-02.png 960w,
/devHistoryBlog/static/9c11b3a612210fc31318553d024fff7c/07a9c/001-02.png 1440w,
/devHistoryBlog/static/9c11b3a612210fc31318553d024fff7c/29114/001-02.png 1920w,
/devHistoryBlog/static/9c11b3a612210fc31318553d024fff7c/7b857/001-02.png 1941w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/818033cf5db223ac14ee081057d25709/2463a/001-03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 13.333333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAkklEQVQI11WNSw6DMBBDE5KQZIHykWCIVLqgVyi7sin3P5NhRlXVLp6sGVu2mmkGQxfTOCGljGEYhJQSjDE4jjce64paKmgiybfWkHOG9x4hhEsDXN9DlStUa5Uyhk0usdai54BS2PcXltsiI7UUKSIiudnXWosKMUY45wRe+xo/bM8N432EMhrOOvl1Xfdf9OEEhwJEyoyJtcgAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/818033cf5db223ac14ee081057d25709/d9199/001-03.png&quot;
        srcset=&quot;/devHistoryBlog/static/818033cf5db223ac14ee081057d25709/8ff5a/001-03.png 240w,
/devHistoryBlog/static/818033cf5db223ac14ee081057d25709/e85cb/001-03.png 480w,
/devHistoryBlog/static/818033cf5db223ac14ee081057d25709/d9199/001-03.png 960w,
/devHistoryBlog/static/818033cf5db223ac14ee081057d25709/07a9c/001-03.png 1440w,
/devHistoryBlog/static/818033cf5db223ac14ee081057d25709/29114/001-03.png 1920w,
/devHistoryBlog/static/818033cf5db223ac14ee081057d25709/2463a/001-03.png 1937w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br&gt;
&lt;ul&gt;
&lt;li&gt;확인해보니 각 DB는 알아서 Optimizer 가 돌기 때문에 사이즈가 조금 씩 다를 수 있다고 전달 받았다.&lt;/li&gt;
&lt;li&gt;그래서 실질 적으로 해당 테이블에 optimize 를 진행해보았다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# 명령어
mysql&amp;gt; optimize table [테이블명] &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;수행결과 (innoDB의 경우 아래와 같은 결과가 나옴, 오류가 아니라 수행이 완료 된 것임)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/e3921141d0e7aacd52d03f8b67c79cce/0fb99/001-04.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 35.416666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAABYlAAAWJQFJUiTwAAABA0lEQVQoz4VR2XKDMAw02MbGMjYBwtC0Sf//K7eSOCadPvRhR8fI0u7aTNMEIkLOGSkl9H2vsZSiedd1Cu/9lQustb/Qti2cczDzPGMYhqu5RwviA/5YpMf4aIw98lBAfNAY8wdt28DIsDyS7e+QxxJDiMqYKGtP8si9d3bOOlgmIXvMsiy4jSMkTrcJYsHIda0j1nXFkAeEGA9JXmvKpDaJslqrspc3RMz88fjEtm34ej55wZ3zD9x50cwHvl8vlbuzi3DMIKVe5TVNc1kk+WmZ0UEuRFoIQSHUpS8SKdGRx2tGrJAZ73arziifpZJLLSqxjpVjUdmd3z9E/DkZ/Qdh+QMMC5kcxOq8wQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 04&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/e3921141d0e7aacd52d03f8b67c79cce/d9199/001-04.png&quot;
        srcset=&quot;/devHistoryBlog/static/e3921141d0e7aacd52d03f8b67c79cce/8ff5a/001-04.png 240w,
/devHistoryBlog/static/e3921141d0e7aacd52d03f8b67c79cce/e85cb/001-04.png 480w,
/devHistoryBlog/static/e3921141d0e7aacd52d03f8b67c79cce/d9199/001-04.png 960w,
/devHistoryBlog/static/e3921141d0e7aacd52d03f8b67c79cce/0fb99/001-04.png 965w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
     &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;실제 ibd 사이즈도 동일해졌다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/996908a178de1752b4dc86abb70ea7ee/5df5d/001-05.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 46.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAIAAAC9o5sfAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABYklEQVQozy2S227bMBBE2eoa24oRR3slqSZOjKAtEMmu8v+/1qGchR4o7Q7PcKiQ8uQpuSuLmnvMmYi6rgshfH2t8zLXdRNjQktUiZlEsMZit9uFHNPkMQk7UTabVLu2raoK4nW9Lde5aZqU06+UPtzfRC5mf/LExyMGwkvKZ/Mz8QvRu+rr83P1o9RdPM93cozmkdmZokpk6ZqmiOHBBO9szCA/DY9D1z9svXX99zl/1nXt0JoBC8ab6jvO93iU3T64O6xeiF+JLmq/kcHT6fAtvs3L0mxkK2TB0YA555xVh76HOLIqghiJRMVTHIVBu5OXK8RtLolGsTKGYRhR08MwBCSJhoogZDcbx7Ha6juwLe2UMmZMVSAWgdm2LdcRIpTYR8p3NcMzDIeq+onW7XZFYCCntF0VCjOi05QQwWG/L2SIheGItsaErZqm2P67Vd8/FDH2xY+Q9OQnGoHnvu//A3ngL356jFa1AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 05&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/996908a178de1752b4dc86abb70ea7ee/d9199/001-05.png&quot;
        srcset=&quot;/devHistoryBlog/static/996908a178de1752b4dc86abb70ea7ee/8ff5a/001-05.png 240w,
/devHistoryBlog/static/996908a178de1752b4dc86abb70ea7ee/e85cb/001-05.png 480w,
/devHistoryBlog/static/996908a178de1752b4dc86abb70ea7ee/d9199/001-05.png 960w,
/devHistoryBlog/static/996908a178de1752b4dc86abb70ea7ee/07a9c/001-05.png 1440w,
/devHistoryBlog/static/996908a178de1752b4dc86abb70ea7ee/5df5d/001-05.png 1572w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br&gt;
&lt;p&gt;테이블 최적화에 대한 몇 개의 글을 찾아보았다.
아래를 참고하자&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://hyunki1019.tistory.com/52&quot;&gt;https://hyunki1019.tistory.com/52&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://fliedcat.tistory.com/80&quot;&gt;https://fliedcat.tistory.com/80&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[[intelliJ] FAILURE: Build failed with an exception]]></title><link>https://ssongey.github.io/errors/posts/2021-01-13--001</link><guid isPermaLink="false">https://ssongey.github.io/errors/posts/2021-01-13--001</guid><pubDate>Wed, 13 Jan 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;문제&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;intelliJ에서 테스트 코드 수행 시 아래와 같은 오류 발생&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/5e63cc39794cc2d4b0162c7fcc03319f/e1b78/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 22.499999999999996%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAABYlAAAWJQFJUiTwAAAA00lEQVQY022QXW7DMAyDc51YtiT/JXGCrd39D8UxboHuYQ8fKEg2aXn5yY5vN/SUJhYFGiMROLGpcdYqr5mRxDqEAAnr1PXNcnnGsIxDEwapvHgb16Ro6qjKMFWqoyTDxnonjWeCRISYIPIKuFl66Sj1QCO97tjbgc1pZAr1BvMCN0fyjXVlWJxmneExOVatSNTKfmF/OccXzuuJcjxejCfqeKCfhLNby3bBGOgk0HiNyvXW/1cefefLGnKu8FymGr8hSJrrTOSDvFcUodn9j0T+8AtwQptQxZdhjgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/5e63cc39794cc2d4b0162c7fcc03319f/d9199/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/5e63cc39794cc2d4b0162c7fcc03319f/8ff5a/001-01.png 240w,
/devHistoryBlog/static/5e63cc39794cc2d4b0162c7fcc03319f/e85cb/001-01.png 480w,
/devHistoryBlog/static/5e63cc39794cc2d4b0162c7fcc03319f/d9199/001-01.png 960w,
/devHistoryBlog/static/5e63cc39794cc2d4b0162c7fcc03319f/07a9c/001-01.png 1440w,
/devHistoryBlog/static/5e63cc39794cc2d4b0162c7fcc03319f/e1b78/001-01.png 1809w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;원인&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;intelliJ 업데이트로 인해 발생&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;h3&gt;해결&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;settings -&gt; Build, Execution, Deployment -&gt; Build Tools -&gt; Gradle 에서 Run tests using 에서 IntelliJ 선택&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/bed2403e634c94fdb74b92fa838bc7f0/38a65/001-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 65.83333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABw0lEQVQoz0VSy27bMBD0bzW2RXIfXFKkJMuJo8SNgVx66xcUKHroj3co2Q0wWlCH2dmd2Z2mytY7jk6iFwtirMYxiaUgEQ9UUjt66gJ3gY6eDy5s2A3zG1Cm11TPZCNb0ZTFMgiBNYh6EjzAdCSeBb9otGFXTu+pXo5cO65eJ4o9pKDvWLcuqABb4mgPrG9LUL724+J1PISi5UVS9UQgilnMxfrakAt28azAqt8qsJsv1+flY5iXVJ9jP3MsWl+1Lj5OLpBr03KrWNhztz02YOw43vLpk8rVpUXqh/TPOv+wy08aPkl0Xb4Z9qhGEabq3TC7/i63P6iy/Mq3vzp+f9p/O3QOaMtjwsAPSBdkHYHuZJhcpouXevCJ4six33f+4GjvqMOS8LxBg8JFZBnX5FARRNxJPht8yshpIjuRguzQFcJZLcdkan2q2YpJ4iBb4PeorL7U01seL42ZmmEgQzZ0/uR5IMmOxzgU6bOPqeMn57+ORPszokILKLecNW/KaKw4NRIK+ERaehoeF3Inc5rBx4XsfQ7xa2wAx9DuLOZYBth+PztZz27NvI3dTwv46AL8V25rQwQjrD63VX14XPgd/wChgdPeG9/OtAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/bed2403e634c94fdb74b92fa838bc7f0/d9199/001-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/bed2403e634c94fdb74b92fa838bc7f0/8ff5a/001-02.png 240w,
/devHistoryBlog/static/bed2403e634c94fdb74b92fa838bc7f0/e85cb/001-02.png 480w,
/devHistoryBlog/static/bed2403e634c94fdb74b92fa838bc7f0/d9199/001-02.png 960w,
/devHistoryBlog/static/bed2403e634c94fdb74b92fa838bc7f0/38a65/001-02.png 1075w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;</content:encoded></item><item><title><![CDATA[[Jenkins] hudson.plugins.git.GitException: Failed to fetch from repo]]></title><link>https://ssongey.github.io/errors/posts/2021-01-12--001</link><guid isPermaLink="false">https://ssongey.github.io/errors/posts/2021-01-12--001</guid><pubDate>Tue, 12 Jan 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;문제&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;jenkins에 webhook 이벤트 발생 후 아래와 같은 오류 발생&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/a2eeda97627cd166d8333bf4d7ededd9/ad00e/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 57.50000000000001%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAABYlAAAWJQFJUiTwAAABP0lEQVQoz4WTjW7DIAyEef83jZIQ/iEhiccZuSNdpyKdDO34duZc5ZyjbdvIGMPSWpO1lszWztpQcIGiT61GSiGzcipUmupRCeu+bxaW8t7Tuq4MA3jVKy3Lwmd8V2vtf3z/Xhz1LxACSPYAwr2xvZZSaN93llweYSIGos0RiAq3aB2wGFq7KdF5nvRtKVwAQKAAYQ+HIQR2dBzHHyfXdX98AgY679gNAHDsnOWzwFARQMk7hwHlmB9n6NiP3nLwHeRdl2vCm4lG8HhGYLJ/tbzMLdHNkl40LXMLpAk1xvQC5pwfochn2F/X9QhH4bFjjG3WIs+ct82h7U4RRp/D2NtMmcOBs9dT1OcsKsBksCUMVAQ1zzNN08RVRkmcjYmPY6QQBIASCL9p20P4Z3AgkvbeZ3CEqveL32bt069kXD/v6qaYCDFi9wAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/a2eeda97627cd166d8333bf4d7ededd9/d9199/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/a2eeda97627cd166d8333bf4d7ededd9/8ff5a/001-01.png 240w,
/devHistoryBlog/static/a2eeda97627cd166d8333bf4d7ededd9/e85cb/001-01.png 480w,
/devHistoryBlog/static/a2eeda97627cd166d8333bf4d7ededd9/d9199/001-01.png 960w,
/devHistoryBlog/static/a2eeda97627cd166d8333bf4d7ededd9/ad00e/001-01.png 1366w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;원인&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;origin에 있는 특정 브랜치 삭제 후 fetching이 되지 않아 오류 발생&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;h3&gt;해결&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;프로젝트 &gt; 구성 &gt; 소스관리 &gt; Additional Behaviours 에서 Wipe out repository &amp;#x26; force clone 추가 후 재빌드 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/52b7b0614fc9d3fd6c927f0cb84d6c5b/efc66/001-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 885px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 28.750000000000004%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABYlAAAWJQFJUiTwAAAA9UlEQVQY022Q3WrDMAyF8/5PNNhbrNCEtKTQNLEdJ7Hjv91snEna3DHYxeFIsi19VmOMgXMO8zxjGAZxay2maYbWWvJxHCWuPk2TyBiN4wgIuSCEgHXf0XjvEWOkg0Mac86+0yFr2zas6ypubXUr4npMCeXjE+8lw9Hbxmgj05RSYFpuyI2WZZFH7DWu4jsihqD8/vqC28MIWPNL456E3LjrWvR9j65tcT5/x5cL6XoVUqYTcrvgfjrh7aYQaECTCJnF3Vk8VRG1WVYctJda5x1VPQm9k28eOSMFL2sTQu88MhVLKeIxJtlNojj/I773R1z/ib8AH+DEVl3IiWsAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/52b7b0614fc9d3fd6c927f0cb84d6c5b/efc66/001-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/52b7b0614fc9d3fd6c927f0cb84d6c5b/8ff5a/001-02.png 240w,
/devHistoryBlog/static/52b7b0614fc9d3fd6c927f0cb84d6c5b/e85cb/001-02.png 480w,
/devHistoryBlog/static/52b7b0614fc9d3fd6c927f0cb84d6c5b/efc66/001-02.png 885w&quot;
        sizes=&quot;(max-width: 885px) 100vw, 885px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/d52e2ac6758d9a0aa8a9a2f70d2a11d1/00a4e/001-03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 389px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 112.91666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAXCAIAAACEf/j0AAAACXBIWXMAAA7DAAAOwwHHb6hkAAAB+klEQVQ4y52U27KTMBSGef97b3wMZ3S8sKNe6Nhddym0m9buHrZtOSUkIYSEUAK4wHa80lL/+SeTkPnWCisHi2cZwjgII4STopdSKkY4ikEIPlLKYJgkBKy1hll9lXU4nb5PnYfJdPI4y7IM5oQQ86fl1HbchTe13c1u78wXM3fhuE8ASCkhwQU2pm5AbWdTm87GNG372zBXg5qLz1Wn89WWLLmpqlxIDeHASheyULnSqoAOBGv/Luvd6hUXBAWYRAkOcBKS+BifXgKKKRji/wtmMoUFKqlUXrR3yvK2MSN0Pp5vvT2Mm7q5A+YcQ93Ks6mMgdbU9R2wM34fhwdvhw5+8mMfEpZ3+ZtB+S1BcVWWVQV7VPet6fdoWObXbyY+kQfENgHdRWmmynYwbT2ucR6iOorlMSjDCDqNVEMz27PR8e1oM3Z8d/lsr/yxXa3Wbf/ft+Fvy6+p7YnVWm/34nmfzb06jIbC+uPnHGGUyjDhudQhTg84G7ps9mlUJonQZ0wyCQccDrXSQ+Ev7k/KJEMk53l7LXR/zW7vtuXMXnJRwEXTgxP+gTfeA6eYxDRjWUq5SIXgglMuc1XcCmctJh+S6JTilMEdRAQwljDSdwiiN2B/N+WcwsKVPquyGniqL/BqPkFReAxZEFEfpVVVd4UaWLDuDWv/U78AnyY1UZ18mAEAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/d52e2ac6758d9a0aa8a9a2f70d2a11d1/00a4e/001-03.png&quot;
        srcset=&quot;/devHistoryBlog/static/d52e2ac6758d9a0aa8a9a2f70d2a11d1/8ff5a/001-03.png 240w,
/devHistoryBlog/static/d52e2ac6758d9a0aa8a9a2f70d2a11d1/00a4e/001-03.png 389w&quot;
        sizes=&quot;(max-width: 389px) 100vw, 389px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;해당 옵션은 webhook 이벤트 발생 시 마다 작업 공간 clean 후 clone 하므로 유지시켜야 할 파일이 있을 경우 백업 또는 이동이 필요하다.  &lt;/li&gt;
&lt;li&gt;소스 빌드가 완료 됐으면 해당 옵션 제거한다.&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[[bash] 파일 데이터로 CURL 요청]]></title><link>https://ssongey.github.io/works/posts/2021-01-11--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2021-01-11--001</guid><pubDate>Mon, 11 Jan 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;시나리오&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;test-csv.csv 파일 한줄 씩 리드&lt;/li&gt;
&lt;li&gt;”,” 로 split &lt;/li&gt;
&lt;li&gt;API POST 데이터 생성&lt;/li&gt;
&lt;li&gt;API 요청 &lt;/li&gt;
&lt;li&gt;결과&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;#. test-csv.csv&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;emaid1,pcid1
emaid2,pcid2&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;#. Script File&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shellscript&quot;&gt;&lt;pre class=&quot;language-shellscript&quot;&gt;&lt;code class=&quot;language-shellscript&quot;&gt;#!/bin/bash

COUNT=0
while read LINE;
do
    # IFS 는 입력필드 구분자
    # ${vStr[0]} , ${vStr[1]} 로 사용
    IFS=&amp;#39;,&amp;#39; read -ra vStr &amp;lt;&amp;lt;&amp;lt; $LINE

    COUNT=$(($COUNT + 1))
    DATA=&amp;quot;{\&amp;quot;emaid\&amp;quot;: \&amp;quot;${vStr[0]}\&amp;quot;, \&amp;quot;pcid\&amp;quot;: \&amp;quot;${vStr[1]}\&amp;quot;}&amp;quot;

    echo RequestData${COUNT} : ${DATA}

    curl -H &amp;quot;Content-Type: application/json&amp;quot; \
            -d &amp;quot;${DATA}&amp;quot; \
            -w &amp;quot; - status code: %{http_code}, sizes: %{size_request}/%{size_download}\n\n&amp;quot; \
            -X POST http://192.168.250.79:15000/api/v2/mo/contractById

done &amp;lt; test-csv.csv&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;#. 결과&lt;/h4&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/67e3bded05121ec06cec9ed8df587faf/13566/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 491px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 23.333333333333332%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAABYlAAAWJQFJUiTwAAAA+klEQVQY002Qa3KDMAyEOUqHlBDAwYAxNq+ACZC297/PVtKkM/3hsR5rWd9G3z8HwnNG2Gbsx4qqzlE3d7y+nghhgrUatqskP6ivqxy+N5gfPbw3cL7FsgykqaHuKSIesqyjiEKYoXUGXSts9IHzDR1DDxsMk5eargqMU4fWVnCO6qMT3S2Lkd5iRHmRoFBX8J3ln9S4yK1UKnWOM+r96SSn81+fv3OOo/MMWAmNfz/eyI3Rgi/IhMvbnK8N+76QHUo2ehAmU3XOEOFAm3ZiR8RBP1g05JvvW/Gh1DkJLGpCZ28sDaxNiZG03GPvGN20pQxkXZJ84JrG+AXTW6B8W40xgAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/67e3bded05121ec06cec9ed8df587faf/13566/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/67e3bded05121ec06cec9ed8df587faf/8ff5a/001-01.png 240w,
/devHistoryBlog/static/67e3bded05121ec06cec9ed8df587faf/e85cb/001-01.png 480w,
/devHistoryBlog/static/67e3bded05121ec06cec9ed8df587faf/13566/001-01.png 491w&quot;
        sizes=&quot;(max-width: 491px) 100vw, 491px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;</content:encoded></item><item><title><![CDATA[[작업내역] Nginx 설치]]></title><link>https://ssongey.github.io/works/posts/2021-01-08--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2021-01-08--001</guid><pubDate>Fri, 08 Jan 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;폐쇠망에서 nginx를 설치하게 되어 rpm 으로 진행하였다.(CentOS 7)&lt;/p&gt;
&lt;h3&gt;#. RPM 다운로드&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://nginx.org/packages&quot;&gt;http://nginx.org/packages&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;# 금일 기준 stable version : 1.18
$ wget http://nginx.org/packages/centos/7/x86_64/RPMS/nginx-1.18.0-2.el7.ngx.x86_64.rpm&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;#. RPM 설치&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;$ sudo rpm -Uvh nginx-1.18.0-2.el7.ngx.x86_64.rpm&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;#. 서비스 파일 확인&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;$ll /usr/lib/systemd/system/nginx.service&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;#. systemctl daemon 재시작&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;$ systemctl daemon-reload&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;#.정상적으로 Service가 등록되었는지 확인&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;$ systemctl status nginx&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/46f8981038741dae8052239f07066caf/705cc/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 21.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAABJ0AAASdAHeZh94AAAAuUlEQVQY01WPWw6DIBBF3UkfqeIDRFCggkj3v6lbZmKa9ONkZgIc7jRH3nGeESmvCFFjTwZniSgfIuG9r9DLiMVMDPXj1EIqwfXV3tCJx4/Gh5UfxcMgnrZWi5Q8fDBYN804b7A5XVkYkhLGSqi5xyQ7rlIKNDEF7NEh15SlHAjBYqsSYtYDpyKpMfLqZ1ireHZ+qVJ1CQdO3cx64kNaM+c3y/0llarnJPSALlNPn9Dcdvc/aF3RP/EFwd19EeYdjFIAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/46f8981038741dae8052239f07066caf/d9199/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/46f8981038741dae8052239f07066caf/8ff5a/001-01.png 240w,
/devHistoryBlog/static/46f8981038741dae8052239f07066caf/e85cb/001-01.png 480w,
/devHistoryBlog/static/46f8981038741dae8052239f07066caf/d9199/001-01.png 960w,
/devHistoryBlog/static/46f8981038741dae8052239f07066caf/705cc/001-01.png 1071w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h3&gt;#. 필요시 방화벽 해제&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;firewall 구동 확인&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ firewall-cmd --state&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;http, https 서비스에 대해 해제/제거&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# 해제
$ sudo firewall-cmd --permanent --add-service=http
$ sudo firewall-cmd --permanent --add-service=https

# 제거
sudo firewall-cmd --permanent --remove-service=http
sudo firewall-cmd --permanent --remove-service=http

# --permanent : 영구적으로 실행 (default zone에 등록 : /etc/firewalld/zones/public.xml)
# --add-service : 해당 서비스를 추가
# --remove-service : 해당 서비스를 삭제&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;특정 port로 방화벽 해제/제거&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# 해재
$ sudo firewall-cmd --permanent --add-port=80/tcp

# 제거
$ sudo firewall-cmd --permanent --add-remove=80/tcp&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Intellij run configurations에 docker-compose 등록]]></title><link>https://ssongey.github.io/works/posts/2021-01-06--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2021-01-06--001</guid><pubDate>Wed, 06 Jan 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h4&gt;#.1. docker-compose.yml 우클릭 후 Create docker-compose.yml.. 선택&lt;/h4&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/dc786e113454ee04fc6e7a332de7326c/17602/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 597px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 92.91666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAATCAIAAAAf7rriAAAACXBIWXMAAA7DAAAOwwHHb6hkAAACu0lEQVQ4y21UaYvUQBDNHxEEQUR0Z3bdcY50+k7fnWNmbw+8XUUU/4jg6Bf/rS8Zj3URHk1RXVWv6lUnRbc+ym3b9msXo1AaqJgQ2lRcVlRwqQjjixWZL1eH8wUpl4ouWblQjPDltCDpZE7tgvuVDCsRiE61Cz4mKuSQzwROuoNQFVeEK147ZfzB/qRY5IvDsp4u9d6MTx7y/ZXenJzZkAgTJeU4/wUnlLuYVW1m81WxOT2PTQsIXeMOPNr60LTWRyb01XzYTGplXEiN1GZWzou8OfMxA7j4E+pTk7seTuMhRA0/wFVtQ4RzZDJ7k73i1TlxqUM1ECIfzLlfp7ZDbQyJBLqbnAkYCAB2bU+n02Jz1PjUhtygnjIWDKByMcGDcv8Zm0s0Lmtz8OBBYU+ehoyZQR5Bi2gwuJRT0/KxkR3tVVCutHUTMOejM+wG0cjXxiEaVyhnXCQj7ZB/DUxgqCG5Pz41PkAhNyjR+ZRR2AVIFeBB59doySge2h6SU7cZNEzZxkEzWVvoFHOLKXCiKURfTYYH8VB7MpkWLmMlyY7bGrQVCptMbQ9VYAPXBIMHewbNdH9ahG6dxkcy7LbtU9Pn9TFsPDLkY8+QgIwq7qYdG5EMWxSqwOhkvMC5q81UjeWBfGg+NiG16AhPGg+byRo2TiqGRRQhRKkgs3ceZrLB8cQglnPWeWudCQlXlnFWkpXUojYaEIJXlBe35fEd1twt3c1DdWOf35qb+sn79vHndPYxX3yKpx9wto8+w5Dda9G+Fs0A2byi0hYHMs2En1F9fyHuPawmVTCXP7rLb93b7ebddxj95XZ9uW3ebP3LrX3+dcCLrX32hdVNQSmrGMAZF1g+3j8pF94ba7Wxuq5lWS5/gSwrWjJGBtASKcXfL+43QtNDJ6yLD1r++gEAJURWxng8h4jvFpr/BA/hNBLBLtiYAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/dc786e113454ee04fc6e7a332de7326c/17602/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/dc786e113454ee04fc6e7a332de7326c/8ff5a/001-01.png 240w,
/devHistoryBlog/static/dc786e113454ee04fc6e7a332de7326c/e85cb/001-01.png 480w,
/devHistoryBlog/static/dc786e113454ee04fc6e7a332de7326c/17602/001-01.png 597w&quot;
        sizes=&quot;(max-width: 597px) 100vw, 597px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h4&gt;#2. configuration 설정&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;server 는 디폴트로 생성&lt;/li&gt;
&lt;li&gt;compose 파일이 선택되어 있는지 확인&lt;/li&gt;
&lt;li&gt;빌드 옵션 추가&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/a57ebb514687b63c91bdb6804845978e/38cea/001-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 678px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 102.08333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAIAAAAC64paAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAB/ElEQVQ4y4WUi27bMAxF/VtLrBcpkpKdh5OtKbp1XfYL2/8Du7KTdCiSDTggqMSXpChKXUoDSdVSxYpYzVqsjlJqtirtR9iB1WCBDRtYF6n30SfuktWkha0Mu33Z7YfpULe7XCq+iCyIxWKshcQSyJqt+SwlEHebrCNLJd2XzV5tJzZm8Sx9JJcY39EsRqBAGSxLrSNs95ryd8onqt9s/5roaeVOfUiJmTKgxCgBoMiFxcemZnGgc5JzyuD0qf/ah59a3kjeWM9iPyKFq9KlVsuiDyiEpdOsFV1hDT4GF7BRE9OZxUGGDyCtjduYpfNZg5Yg6ljg+yxUB8Bocqkg3wNiHEE3ZN2iSWKD2FZLSVxZBhYWpccgf0Lmz6yTjeim+Wg+1ZAs0rH32cVVSP0D1j6CbvCx5HG0EYeEEpq1eiIhF9aPxQsdhyg+Zh95Jl999z9lE0cMDUYPh97aA2dgnKHV5Xj/5o54mZv1JRV2Elauseyq4Zpd3ZZXmvjm3YicMYywaR7J5s/2Q/LWsPW9kDf+UXYTL7Pebl+pWod2E5ttY4Sli+lu0Muer+ExtHSb+9tN6ANdudftR1Ev4C/vZ97zvzdsuagPxLEn6/W41oNjvASCx6C1MCscT7lbXpZ7yfHW+JUe0svv8PzL2WE3TdOXJ0z1djoen57RqT+lwjkMeZBSwgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/a57ebb514687b63c91bdb6804845978e/38cea/001-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/a57ebb514687b63c91bdb6804845978e/8ff5a/001-02.png 240w,
/devHistoryBlog/static/a57ebb514687b63c91bdb6804845978e/e85cb/001-02.png 480w,
/devHistoryBlog/static/a57ebb514687b63c91bdb6804845978e/38cea/001-02.png 678w&quot;
        sizes=&quot;(max-width: 678px) 100vw, 678px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h4&gt;#3. run&lt;/h4&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/97f750235e5257a73de1a0d44f61faa8/409e6/001-03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 385px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 19.166666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAIAAAABPYjBAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAt0lEQVQI1zXN4W6DMAwEYF6rJLEd2wRRCnVZyyAtbKq0t9jDL+s06ftxf+6u8iH6JHqU5yFch/2u3YemTdI96q5tCQ9uNilSBp4Uv8CfRq5bZUlVKbvErcnuiD+/bbyudrmNNvXDYtNil/lst/Fs3bGPDQ+yCdiqda+p6SqP5ICQKDuYuXtHzsQryYJczoscJZPMAWcPbx62g28IayLAWMqxcBhDmfCAAeEFX/4zIfwiIIByFv9aP5b7Qf9afeldAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/97f750235e5257a73de1a0d44f61faa8/409e6/001-03.png&quot;
        srcset=&quot;/devHistoryBlog/static/97f750235e5257a73de1a0d44f61faa8/8ff5a/001-03.png 240w,
/devHistoryBlog/static/97f750235e5257a73de1a0d44f61faa8/409e6/001-03.png 385w&quot;
        sizes=&quot;(max-width: 385px) 100vw, 385px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h4&gt;#4. docker daemon 설정&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;아래와 같이 connection refused 가 발생하면 4.1 로 간다&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/9e64406bf721be57f24901a6ae1d3cbc/38af3/001-04.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 894px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 37.083333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAABJ0AAASdAHeZh94AAAAyUlEQVQoz5WR2xLCIAxE+S5rSAgttaMP6qOXL/Hy6yuh9dapjj6cYRPCwg5OUwKLgNhDQoBoKLoiQuWlh3iavDfLK2tEbFr4EOF8WqHZnbA8ntEdLljsL0i7K3y3H0zD0/gHnKYO0m7B7QbUGGtQ2oK0A0kotxZE86pDrUMd84wWiuYAR1H6l4zx/nGAtUao0yQS66d5MczFPIsx/8R8i1x5fhQzkhfNXw9+utRJbIZoNsAF61lM65uWrDX/osWz/t3MtPVs5v7LNwX+9bsCoYt9AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 04&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/9e64406bf721be57f24901a6ae1d3cbc/38af3/001-04.png&quot;
        srcset=&quot;/devHistoryBlog/static/9e64406bf721be57f24901a6ae1d3cbc/8ff5a/001-04.png 240w,
/devHistoryBlog/static/9e64406bf721be57f24901a6ae1d3cbc/e85cb/001-04.png 480w,
/devHistoryBlog/static/9e64406bf721be57f24901a6ae1d3cbc/38af3/001-04.png 894w&quot;
        sizes=&quot;(max-width: 894px) 100vw, 894px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h4&gt;#4.1 docker - settings&lt;/h4&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/c793a25d05797c5b451ef38fc61023e1/38070/001-05.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 451px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 94.58333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAATCAIAAAAf7rriAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAC/klEQVQ4y31Sa08TURDt3yEBIi190fIKWmpaKcW+xMbwCBLwgxqNiV/4NwZoKAJiWz9IRBBNjAlNILRgu9vudt8tLd3u9rl1tgsKgp6c3DvJzpkzM3dVSDJxEo/xZ3kig7E0dZY/lerVRq1ymfVqucQXm9egisaR3ejPQ5T+dpD8EcdieC6VFVFOgPM3EVZI4MwN4n1CeH8sBr6ibz7Hg9/xD8dCOM5H4qXQUVFhOFZcPzjbOSIhW5KuigvF0mlRSBP0STKF4lQynYkexo4RjC/X+XKtRTlg2Cxo/3Yui0K1ImY5NoUmUSSBYbhQ4ptS47KL1KjncjlJuiYWBKFcLnMsi+E4y7KZTIYgqUK+kM8XSIoiCILnS41GI5vN3iyuVCo4lsYzOEmSqXQqnU4jSQRFUY7j8vm8KIj/E4MzTVNgDhkESZ7mcjRNg6coitB8rVaD6lDohm0rYpZhMziexjA0lYJCigcY1mXIN9SFKvWrOBeTJIHhmDwwQSQRhKYZRdloAQLo/5/OFEXhGEZRJExerVbBpHEBUELefnR/eXFpfW1tZWVldXX17dsgnOdieVqCKPJFQK2F6gXgK4iXl5b9c1P3nI6XL175/Q8tFofVam9tu+UM08p5kqQYSheAGMSBQMDqtHseeKenJvz+cafTMzbmVpxFmBlB0EQiwTAsCGC9SvPKCZ0Hg8HnT595PR6374nD6Zmbezw7O6vieR708MLQNstxsHP4mcAKdqW0LT9YswkTTkxO+ny+8UczLo97ugWV0hXHMvDCDM3Awlm4GLYkiMpKlYTNzc3R0VGv1+u673S7XCMjjrt2h+rL3t7Hra1wOBwKR0KhsIJ3GxvhSGRnd/fT9vaSjMWFhYX5+XmbzWZp4Y5leLDfrNKo9VqNUa8zGXQmvd7cYq+xp99g6NPpzVqtqb29q62to6NT3dWlNehNA/1DA32DZqNJb59Rdbar1bd03V2GbrVMjdqo6e7RaP5Qp+sFQhWdztRj7LNabMO3rUO9g3rP61/hCothRVbv4QAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 05&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/c793a25d05797c5b451ef38fc61023e1/38070/001-05.png&quot;
        srcset=&quot;/devHistoryBlog/static/c793a25d05797c5b451ef38fc61023e1/8ff5a/001-05.png 240w,
/devHistoryBlog/static/c793a25d05797c5b451ef38fc61023e1/38070/001-05.png 451w&quot;
        sizes=&quot;(max-width: 451px) 100vw, 451px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h4&gt;#4.2. Expose daemon on… 선택 후 도커 재시작&lt;/h4&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/acf12d6fb13a3046b0f0f3da6a4a4085/f4281/001-06.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 71.66666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAIAAACgpqunAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABN0lEQVQoz8WR3UrEMBCF+77e+yyC+BQ+hdeK6G5ttfmdJM1/0m7xwqRbXRCRxRvhYzgccsJwpgGAAWHrfMpzTNNGzOfQPJHIKAheEMBAgZIgU/kq5BTShk8nvbKF7x/YsO/xrqVtV0C7Fu9fSNuRfTciYhkYCpaJIk4Q7gkvCzYOUY4ZHzBgCohwRCRhmksD0gplhVxRZnU2GHhEY56b596QfuCvA+sH3HZiwF4oB9JBnRZGDSZInUaTlKmzCh2tr2u/ycylBqE4yNE446pvnDcuFLRLys0+ri3m6VujTQ+JMsEYp5QrpY1xWls92jqrNkfG0VRnpbzZwnPOKU1Hvm4QPvus+pdThZDPvOoP4T8n/zdcujmfFFNKeZryPOUp5+ZwWM5hOSwxLxDe7x7t5Q26uGZXt/wDf5kU5ySYqu4AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 06&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/acf12d6fb13a3046b0f0f3da6a4a4085/d9199/001-06.png&quot;
        srcset=&quot;/devHistoryBlog/static/acf12d6fb13a3046b0f0f3da6a4a4085/8ff5a/001-06.png 240w,
/devHistoryBlog/static/acf12d6fb13a3046b0f0f3da6a4a4085/e85cb/001-06.png 480w,
/devHistoryBlog/static/acf12d6fb13a3046b0f0f3da6a4a4085/d9199/001-06.png 960w,
/devHistoryBlog/static/acf12d6fb13a3046b0f0f3da6a4a4085/f4281/001-06.png 1016w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;</content:encoded></item><item><title><![CDATA[Docker 기반 Remote Debugging 개발 환경 설정]]></title><link>https://ssongey.github.io/works/posts/2021-01-06--002</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2021-01-06--002</guid><pubDate>Wed, 06 Jan 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;#. 작업 구성&lt;/h3&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/6d12ea3a3581d40219bf4223a9aa4bd3/80d71/002-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 625px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 72.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAABJ0AAASdAHeZh94AAABw0lEQVQ4y41TC8+bMAzs//+F67SuU6uWtnwNEEogD7j5DGF01aRFssDJ+XJ+ZIfNCiGg6zqM47juTdOkxsX9+/2OoihgjMHtdlOfX++9YnYExxg16HQ6Yb/f6yGDU0oraf4+n09cr1dUVaVk/L9cLnDOzYQkYyBtq4Q+Fcf4hzQEXpTeVOcz8jBOCefAiGEYNGUqpO+6F65y+/f9N/w8/EBtW6RxkvNBFTLttm0Vm7PaZYe3EJTrMSbZt09MvcXLPBC7BrEq4Ks7hBNGUifWWquxb4RZ4bikMqcr+2kUYknR9xidRWhKBPdCEOzxeMThcFBSrg9CW9cwX1/6besGQ9/DtxXGrsbt/Au2aTDpJMz4oXfo3Vwe+rQ3wurxQHk+w0jXjIyFe4mSwc2ql+JHwU0SRF9V+24+W7JaCbcd2664gFZfsDFKeaQUyTskqSublEW9Kcx11DHKe0tdnaSfSCLGlIlhd1tpCCeD6j5qyMEsy1KN3U6iZLBGVNSoirN03CDaUupq9BLi+GJ6uYxEH4Q0bmbTPT8P8pqyDHZYnhhV8dXkh7CmnFPNr2VrfgHlGufhpyp+/zYlzM/sX7Zt2P9gfwP3oEUykOCXmgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/6d12ea3a3581d40219bf4223a9aa4bd3/80d71/002-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/6d12ea3a3581d40219bf4223a9aa4bd3/8ff5a/002-01.png 240w,
/devHistoryBlog/static/6d12ea3a3581d40219bf4223a9aa4bd3/e85cb/002-01.png 480w,
/devHistoryBlog/static/6d12ea3a3581d40219bf4223a9aa4bd3/80d71/002-01.png 625w&quot;
        sizes=&quot;(max-width: 625px) 100vw, 625px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h3&gt;작업 내용&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/eunyoung-autocrypt/docker-practice.git&quot;&gt;git repository 이동&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;#1. WAS Dockerfile&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;FROM openjdk:8-jdk

# 환경 변수 및 작업 경로 설정
ENV WCA_LIB /usr/local/wca_libs
ENV CATALINA_HOME /usr/local/tomcat
ENV PATH $WCA_LIB:$CATALINA_HOME/bin:$PATH
ENV LD_LIBRARY_PATH $WCA_LIB:$LD_LIBRARY

COPY docker/lib/lib.tar.gz $WCA_LIB/
RUN tar -zxf $WCA_LIB/lib.tar.gz -C $WCA_LIB/
RUN mkdir -p &amp;quot;$CATALINA_HOME&amp;quot;
WORKDIR ${CATALINA_HOME}

# 패키지 설치 wget은 톰캣 설치 파일 다운로드 위한
RUN apt-get update;
RUN apt-get install -y --no-install-recommends
RUN apt-get install -y gnupg dirmngr
RUN apt-get install -y wget ca-certificates

# 톰캣 바이너리 다운로드 및 압축해제
ENV TOMCAT_VERSION 8.5.61
RUN wget http://apache.mirror.cdnetworks.com/tomcat/tomcat-8/v${TOMCAT_VERSION}/bin/apache-tomcat-${TOMCAT_VERSION}.tar.gz;
RUN tar -xf apache-tomcat-$TOMCAT_VERSION.tar.gz  --strip-components=1;

# 불필요 파일 삭제 후 webapps 디렉토리 새로 생성
RUN find . -name &amp;quot;*.bat&amp;quot; -exec rm -rf {} \;
RUN rm -rf *tomcat*.tar.gz;
RUN mv webapps webapps.org
RUN mkdir webapps

# war 파일 복사
COPY build/libs/ROOT.war $CATALINA_HOME/webapps

# tomcat conf 파일 복사
COPY docker/tomcat-conf/* $CATALINA_HOME/conf/

# 컨테이너에서 사용할 포트 (서비스 포트, remote debugging 포트)
EXPOSE 8080 5000

# debugging 모드 시 필요 환경 변수
ENV JPDA_ADDRESS=5000
ENV JPDA_TRANSPORT=dt_socket

# 설정 완료 후 실행
#CMD [&amp;quot;catalina.sh&amp;quot;, &amp;quot;run&amp;quot;]
CMD [&amp;quot;catalina.sh&amp;quot;, &amp;quot;jpda&amp;quot;, &amp;quot;run&amp;quot;]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;h4&gt;2. DB Dockerfile&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;FROM mysql:5.7.32
#FROM mariadb:10.4.10

# my.cnf 파일 복사
ADD ./mysql-conf/my.cnf /etc/mysql/conf.d/my.cnf&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;h4&gt;3. docker-compose.yml&lt;/h4&gt;
&lt;p&gt;&lt;a href=&quot;/devHistoryBlog/history/posts/2021-01-06--001&quot;&gt;Docker-Compose 내용 정리&lt;/a&gt; &lt;/p&gt;
&lt;br&gt;
&lt;h4&gt;4. IntelliJ 원격 디버깅 설정&lt;/h4&gt;
&lt;p&gt;&lt;a href=&quot;/devHistoryBlog/works/posts/2020-12-29--001&quot;&gt;IntelliJ 설정 확인&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Docker-Compose 내용 정리]]></title><link>https://ssongey.github.io/history/posts/2021-01-06--001</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2021-01-06--001</guid><pubDate>Wed, 06 Jan 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;Docker-Compose&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Define and run multi-container application with Docker.&lt;/li&gt;
&lt;li&gt;여러 개의 컨테이너를 동작시키기 위해 도커 어플리케이션을 정의하고 실행하는 도구&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;docker-compose.yml&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;컨테이너 실행에 사용되는 옵션과 컨테이너 간 의존성을 모두 docker-compose.yml 파일에 적어두고, docker-compose 명령어를 사용하여 컨테이너를 실행 및 관리&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/63637afeecc8e3d76b6e1cec00dc77d5/3fe45/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 699px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 106.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAVCAYAAABG1c6oAAAACXBIWXMAABJ0AAASdAHeZh94AAACF0lEQVQ4y51UWXbjMAzLbWasXaKW2Fk6978UhqRdJ+1r0qYffLIkCwJIUIeyXEHzCUsnnDhSbfApw1r7qziUuaP0ihoMlmzgrcE0TTDG6A8yvhKHUjtSqXDOoY2IQAGxRqQeEIqH8w7WvMKQ2gZoccwWS3HwwfFaQWLpwvYz46eAmQEzA8okB4sLWQwGbq1hzAsKkYYo+AnoxpB0MpIwNOiN0PqAC5HZchpCUBBluh18BLrlkHbJb5VZVs9sHRdqQnQTQkxIuSCm9AOGDJgZ0FgHihb/msWVZb+RwbklzKMrWMp5B3xeFAVcqyy5O5NDjitD74Oykz35+b5AxvD4/j3dvg95lyxJtyCqOC4XjOXMNjqic5wub7x22lnGuIa4IGxj3JphZ+jFhyy5lqwS851M+fkdQNIje5ltVfjyfY3nW5X7bpvAJi68QXyJAE3T30+dsEnepK/ypw+pOJTGkvkmx4CeKy3SnfN73l7uZRoDuTJ1ZnetVovxZ/q+Zx/ZZzV2JjVs4U4RUIorO+89GzuosWXUuV/Hp8bWHLLEGldjn8lqkeQiqbrktGiL8rw2LZrk8fYafQEoANLLgzxG8wjpLpixhLw8Xr6T1wfkxtJ8bWzplFySPrAh8KHo98MCpoBhDevs94A1OZyPHcuyqNduXfG4ME9aj4vBko81gXJUsN+92JJsTrxIFIZzy9xy8/p8qSdfi//aIYP1RuutOAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/63637afeecc8e3d76b6e1cec00dc77d5/3fe45/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/63637afeecc8e3d76b6e1cec00dc77d5/8ff5a/001-01.png 240w,
/devHistoryBlog/static/63637afeecc8e3d76b6e1cec00dc77d5/e85cb/001-01.png 480w,
/devHistoryBlog/static/63637afeecc8e3d76b6e1cec00dc77d5/3fe45/001-01.png 699w&quot;
        sizes=&quot;(max-width: 699px) 100vw, 699px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h4&gt;version&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;docker-compose.yml 파일의 첫 줄에는 파일 규격 버전을 적는다. &lt;/li&gt;
&lt;li&gt;파일의 규격에 따라 지원하는 옵션이 달라진다. &lt;a href=&quot;https://docs.docker.com/compose/compose-file/compose-versioning&quot;&gt;참고&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;1| version: &amp;quot;3.1&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;services&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;실행하려는 컨테이너들을 정의&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt; 2| services:
 3|   ca-db:
       ...
18|  ca-was:
       ...&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;image&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;베이스 이미지를 지정&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;4| image: mariadb:10.4&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;build&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;도커파일을 이용하여 베이스 이미지 지정&lt;/li&gt;
&lt;li&gt;도커 파일의 경로나 이름이 다르면 아래와 같이 지정&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;5| build:
6|   context: ./docker
7|   dockerfile: Dockerfile.db&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;restart&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;재시작 옵션&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;8| restart: always

# no : 
    container를 재시작 시키지 않는다. (default)  
# on-failure[:max-retries] :
    container가 정상적으로 종료되지 않은 경우(exit code가 0이 아님)에만 재시작 시킨다. 
    max-retries도 함께 주면 재시작 최대 시도횟수를 지정할 수 있고, 테스트 서버 등과 같은 리모트에 설정하면 좋을 것 같다.  
# always : 
    container를 항상 재시작시킨다. 
    exit code 상관 없이 항상 재시작 된다.
# unless-stopped : 
    container를 stop시키기 전 까지 항상 재시작 시킨다.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;environment&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;docker run 명령어의 —env, -e 옵션과 동일, 환경변수&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt; 9| environment:
10|   MYSQL_ROOT_PASSWORD: flatron123!
11|   MYSQL_DATABASE: webca&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;volumes&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;DB의 데이터를 로컬에 저장&lt;/li&gt;
&lt;li&gt;sql을 /docker-entrypoint-initdb.d/ 에 저장하면 DB가 start 될 때 sql 문을 순차적으로 실행한다&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;12| volumes:
13|   - ./ca-db-data:/var/lib/mysql
14|   - ./docker/mysql-conf/init.sql/:/docker-entrypoint-initdb.d/&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;ports&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;HOST:CONTAINER 형식으로 호스트로 들어온 포트를 해당 컨테이너의 포트로 포워딩&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;15| ports:
16|   - 3333:3306&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;depends_on&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;서비스 간 의존 관계를 지정&lt;/li&gt;
&lt;li&gt;명시된 컨테이너가 먼저 생성되고 실행&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;26| depends_on:
27|   - ca-db&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[도커와 기존의 가상화 기술과의 차이를 통한 컨테이너 이해]]></title><description><![CDATA[따라하며 배우는 도커와 CI환경 강의 복습]]></description><link>https://ssongey.github.io/history/posts/2021-01-02--001</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2021-01-02--001</guid><pubDate>Sat, 02 Jan 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;#. 하이퍼바이저 기반의 VM 구조&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;하이퍼바이저에 의해 구동되는 VM은 각 VM마다 독립된 가상 하드웨어 자원을 할당받는다.&lt;/li&gt;
&lt;li&gt;논리적으로 분리 되어 있어 한 VM에 오류가 발생해도 다른 VM으로 퍼지지 않는다는 장점이 있다.

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/b8ecd51a61f731a26976525442c72c68/5caea/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 64.16666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAABJ0AAASdAHeZh94AAAB5UlEQVQ4y22T627bMAyF/f4Ps3Uv0RZY/y7Blvwa4CS+3y+y5XD8GKsYggogLInk4eGhHG3bJs/mvZfT6STDMAiL83PM/X7/0qJ5nsU5J33fS9d14hZnQOM42hc/1jatTNNke3wkf7UiwLzfpKoqDZysOkCcKcB5VqCyrIzpsizm575t20dxNfbrukoU6KdJagAsGAAI63C+3RLxeywggE/KNstzSdJMZiVGMWPo3KwJN8mL4pNB0zQGSCL7+HKRXu8XjacA4JP6p7aRoa5lVp8xDILXyii9Xj81A4REfHyTOJZO2/K7BCgYf/yUw8s3Ofz4Ln/fXmVDQwOgat9Jl6aWQCVYwpb9otYmN5kYksaSA2Dx57fE769yeX+T/PBLPFMOz2DV6c7KqlSmWZaZhnleSIEMCohvVTA0RCYKObUOebpeFu10RUMcKwetOqkWlVqhQtNyWZY2XRLxLao1Ej1ehjcpkIo4npRp6PYWGhyq4aiOYX8GDGUcBxtGeb1YDH6Sw7PJtXiqUrGnSMQGWzTI6ZeWEJ12eUZeq6KX02nO4+PPQVsA6eJ8PsvxeJRaOzBAKkCZNossN9qAhumz6CDVZ0USi5jQ8vM+IpkN1er97eH832CKttaJsrMpa17470Nx7v4B8dTuaAG0grgAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/b8ecd51a61f731a26976525442c72c68/d9199/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/b8ecd51a61f731a26976525442c72c68/8ff5a/001-01.png 240w,
/devHistoryBlog/static/b8ecd51a61f731a26976525442c72c68/e85cb/001-01.png 480w,
/devHistoryBlog/static/b8ecd51a61f731a26976525442c72c68/d9199/001-01.png 960w,
/devHistoryBlog/static/b8ecd51a61f731a26976525442c72c68/5caea/001-01.png 996w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;h3&gt;#. 도커 VS 기존 가상화 기술(VM)&lt;/h3&gt;
&lt;h4&gt;#1. 공통점&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;도커 컨테이너와 가상 머신은 기본 하드웨어에서 격리된 환경 내에서 애플리케이션을 배치하는 방법&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;#2. 차이점&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;vm과 비교했을 때 컨테이너는 하이퍼바이저와 게스트 OS가 필요하지 않으므로 더 가볍다.&lt;/p&gt;
&lt;h5&gt;#2.1. 도커 컨테이너에서 돌아가는 애플리케이션은&lt;/h5&gt;
&lt;/li&gt;
&lt;li&gt;컨테이너가 제공하는 격리 기능 내무에 샌드박스가 있지만, 여전히 같은 호스트의 다른 컨테이너와 동일한 커널을 공유한다.&lt;/li&gt;
&lt;li&gt;컨테이너가 전체 OS를 내장할 필요가 없는 결과, 매우 가볍고 일반적으로 약 5-100MB 이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;#2.2. 가상머신&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;VM 내부에서 실행되는 모든 것은 호스트 운영체제 또는 하이퍼바이저와 독립되어 있다.&lt;/li&gt;
&lt;li&gt;게스트 OS를 부팅하여 어플리케이션을 실행하기 때문에 무겁다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/459af3404c9060b9e2104252a608888a/748b0/001-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 868px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 71.66666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAABJ0AAASdAHeZh94AAAB50lEQVQ4y1WU2Y7CMAxF8/9/NyMeGAmomC5Quq9pK8CT45LCRHLjJDf29ZKaJLlIlmUyTZNMdhI7WpV5mmUcx1WfF2nqRuIolvP5V+fgFEgQBHK9XsVau4npuk6qspK6rmXoB8nzXPVxGKUsSxUwOLTOIfPiHCzLogbmeZa+7xXTd70YDp7PpxoYhkHu97uCMQ748XjoPudqxDHGAIY5B0ck3EM3MABASFVVSdu2Kk3TKtOu7VTwDnswTdNs7LlXFuUaWVWLybNcF0VRbCBy2jqDRV6sOk7cOk1TuaU3dcSd7JYpHhvoiMG6B2DU63gDvDFyuOPhqIWA1el4UmE/DCM5HA6SJIkYDrmAgS25bkbYwwHsCFtxrzSQr94JumJcFBTXkHQGMx5ogyiKlKUf2j6uop/ryLUOeBz7oW3Dhr+AFxjikSJQSWXSrYzR2QNPZOCpvt8jEkPpEQrwWRzfj7SKNwbOn2kBCwq46uAgo30I0IfLnF5TieNY15tB14vonF0uFz1P4kRnhGbXxuYDXfVerC2A4O3fK3gViicJW79HyOCYSYMWBc9hGMrP/ke+v75lt9vJfr/XV6Ev4PVSeFEMUhH+hsqQFPnCgjP6Q3AF0YS/3urkWGAMAPPn3hszvX8o1m4/lj+Yoi+QcA0zuAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/459af3404c9060b9e2104252a608888a/748b0/001-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/459af3404c9060b9e2104252a608888a/8ff5a/001-02.png 240w,
/devHistoryBlog/static/459af3404c9060b9e2104252a608888a/e85cb/001-02.png 480w,
/devHistoryBlog/static/459af3404c9060b9e2104252a608888a/748b0/001-02.png 868w&quot;
        sizes=&quot;(max-width: 868px) 100vw, 868px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;#. 도커&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;카카오톡 컨테이너와 노션 컨테이너는 커널을 공유하고 있다.&lt;/li&gt;
&lt;li&gt;각 컨테이너는 실행 프로그램 및 필요한 양만큼의 리소스에 대해 격리가 되어 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/a6203456312d4ec94a4f3b5da6048abb/91f10/001-03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAABJ0AAASdAHeZh94AAACJklEQVQ4y2VUiW7bMAzN/3/a0C7LNmwDgrRZGwxp4kM+dFGW30j6WIwJICQ/UdTjI+UdMEJGHgZc3l7w9csz+rYGBQvX1wg8hxhBbJEtpYTbvcCnp8+4ftzhfIRpLbre6d4O80gU4WyDOzufz6+4Xq+MBb5vABGhLEveu+uhSAPKqkZVVajrGs55+EDbgDF4ZmFBDPZ9x2YVG1JQZs5ZWGt1LQGJEoL3jDt4H2BdYAKE3ThOKQ8DcYCe50HTzznzocCXOMUezXGAEGn9luCWsXHMzHAJmIhv7HSTOH2ZY3BsVteSjhqzkMM+RJVCTDTurVcSm5QTOV0vrMecmG3Uddd1aupLwiwvR5HZXzWUlBeQYphTzsw2aSpSlEReMdEuhKAshF18TJn9VUMpysIm50EDpjTM6Q2zhsz8Pw3jrGGaq06KSQuuDDk/NsJ2ZIYXbFyloJQX6dchmIydpCAaSMqNKdC20jK9WtvU8G4pFK0mTWyadvUzTYOm7aeinE4nbuQzfv38ge/f9jgej3h+esJ+v8fl/bf2oaRZVSUaPjjOBXh7v6jP4XDAy+uZg3bqpxoKfdHCWQNT31Hc/qAsruiaQjXUPrNTY6sft03NAT5uhT6/sm7QdnYKuD49dgxzb0lVhf5SWZmni8ep77jFJmzrtwkooAAyhIkxzdqTsvd4sZiMG79tY8yK06YP+WP5m3h+nxJ0fQkh/Kvw/C1+0uiLDILJ3l/hepEXGjfEBAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/a6203456312d4ec94a4f3b5da6048abb/d9199/001-03.png&quot;
        srcset=&quot;/devHistoryBlog/static/a6203456312d4ec94a4f3b5da6048abb/8ff5a/001-03.png 240w,
/devHistoryBlog/static/a6203456312d4ec94a4f3b5da6048abb/e85cb/001-03.png 480w,
/devHistoryBlog/static/a6203456312d4ec94a4f3b5da6048abb/d9199/001-03.png 960w,
/devHistoryBlog/static/a6203456312d4ec94a4f3b5da6048abb/91f10/001-03.png 992w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;#.도커 컨테이너를 격리시키는 방법&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;컨테이너와 호스트에서 실행되는 다른 프로세스 사이에 벽을 만드는 리눅스 커널 기능인 Cgroup과 네임스페이스를 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/e2068bae7be87e83caeb468a821e8a83/ee455/001-04.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 863px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 31.666666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABJ0AAASdAHeZh94AAABIUlEQVQY0z1RCXKDMAzk/48LnRLKDTFhwpFyHzkg2XqVNJ7xSJbk1a5kKKUQBiGCIMDtdsPj8cC2bVjXVSxvP81I1BGe68Ky9jhXZzyfT2zrK0/Lf/O8wMjzHFEYwTS/oA4K/w1ofc9HWZa4Xq/IsgxFUeB0ylHkBaZpQtd16Lsebdt+fAPvk8SJsExTzcTz4DquXDIgYK6BxmFEWZTSyNE5c2dKDQGrskJTNzDq3xqpSrHXUqxvC3EcY6cL7b0tTKMowjAM4rtasm3bcH4cDejoEXgCTmUkxKYG5bKIrFjAd+AHAswm/Hg8ZgI6z7NIpc98puOcO2O0Qz/A+OjvezRNI/Q5C77JfhxHdG2HZVleC3svgku73+9iZYE6flku+AM6aL7A2LFOYwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 04&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/e2068bae7be87e83caeb468a821e8a83/ee455/001-04.png&quot;
        srcset=&quot;/devHistoryBlog/static/e2068bae7be87e83caeb468a821e8a83/8ff5a/001-04.png 240w,
/devHistoryBlog/static/e2068bae7be87e83caeb468a821e8a83/e85cb/001-04.png 480w,
/devHistoryBlog/static/e2068bae7be87e83caeb468a821e8a83/ee455/001-04.png 863w&quot;
        sizes=&quot;(max-width: 863px) 100vw, 863px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;</content:encoded></item><item><title><![CDATA[컨테이너가 생성이 되는 방법]]></title><description><![CDATA[따라하며 배우는 도커와 CI환경 강의 복습]]></description><link>https://ssongey.github.io/history/posts/2021-01-02--002</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2021-01-02--002</guid><pubDate>Sat, 02 Jan 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;컨테이너 이미지&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;이미지는 응용 프로그램을 실행하는데 필요한 모든 것을 포함하고 있다.&lt;br&gt;
- 1. 컨테이너가 시작 될 때 실팽되는 명령어&lt;br&gt;
- 2. 파일 스냅샷 (디렉토리나 파일을 복사 한 것)  &lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;이미지로 컨테이너 만드는 순서&lt;/h3&gt;
&lt;h4&gt;#1. Docker 클라이언트에 docker run &amp;#x3C;이미지&gt; 입력&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ docker run helloworld&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;#2. 도커 이미지에 있는 파일 스냅샷을 컨테이너 하드 디스크에 옮겨 준다&lt;/h4&gt;
&lt;h4&gt;#3. 이미지에서 가지고 있는 명령어 (컨테이너가 실행될때 사용될 명령어)를 이용하여 앱 실행&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;3.1. 명렁어 실행 &lt;/li&gt;
&lt;li&gt;3.2. 커널을 통해 앱 시작 &lt;/li&gt;
&lt;li&gt;3.3. 프로세스 작동&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt; 
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/418a7084f26730d69bb6634600412a3a/c6671/002-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 58.333333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAABJ0AAASdAHeZh94AAACBklEQVQoz22Ti3KjMAxF+f//6zYhaWgI74AJ2GAwj7tXTtqd6dYzwtiMrqQjEYBr33ds2+Z3f37dyb7uK9ZthZzc6pBmCcJTCNU2/n5ZF2/bvnnfQB7GGCilME0Tfi4zaHS6R9d3aCny6FraA6MdKOS8uWXGSlEvOAwD8jxHHMeo6xp2mjFTeJstMBvciwTxR4j4+I74Evlv/6/9X4ZpmiJJEpzOZ/x5e6NABl3ncL3CzsiSQVum6PIrhk5hHC1tZODpadZCkupZxbIsCNq2RVNVyG839KrGajXGwXyznGZxdHQwmOzo76qiRHQ64RpFuF5jlFXJIIMXD7TWMDT3KmWjx8AMns3aPPDRaAyqhH3UnvOjqSmao4oOqG4RG6SgTY95nhEcDgccjkeUZelLWdaVwC2+um8nC8MmqPzmRfvsgo5IJv3waIr4wqZq3zTnHIIyy5Aw9U+aiLqhw0hWu7O+aGEzsVEdSxY8U31D3TTMyHBXiKJPNDw3qnmW3HJcajKUsZHxWRjFqAqLpuhkyLVElmb4ILNzeERyCZGz3IGcNYPd6SvYpGzBEfQ8jK9OPW0kC/c9Dh3nrmUGOccq4zR0vfYBJNuiKBCGJ1ZWoChzjyyQP+SnffGT1QkrApdui8n7vb77gW8fCllOcQb9ZojfxlR+u5eg5agIR8EhJo7jawp+W38Bjpqa/lRoYNEAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/418a7084f26730d69bb6634600412a3a/d9199/002-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/418a7084f26730d69bb6634600412a3a/8ff5a/002-01.png 240w,
/devHistoryBlog/static/418a7084f26730d69bb6634600412a3a/e85cb/002-01.png 480w,
/devHistoryBlog/static/418a7084f26730d69bb6634600412a3a/d9199/002-01.png 960w,
/devHistoryBlog/static/418a7084f26730d69bb6634600412a3a/c6671/002-01.png 1129w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;</content:encoded></item><item><title><![CDATA[도커 이미지 생성]]></title><description><![CDATA[따라하며 배우는 도커와 CI환경 강의 복습]]></description><link>https://ssongey.github.io/history/posts/2021-01-02--003</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2021-01-02--003</guid><pubDate>Sat, 02 Jan 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;#. 도커 파일(Docker file)이란?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;도커 이미지를 만들기 위한 설정 파일이며, 컨테이너가 어떻게 행동해야 하는지에 대한 설정들을 정의해 주는 곳&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;h2&gt;#. 도커 파일 만드는 순서&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;베이스 이미지를 명시해준다. (파일 스냅샷에 해당)&lt;/li&gt;
&lt;li&gt;추가적으로 필요한 파일을 다운 받기 위한 몇가지 명령어를 명시 (파일 스냅샷에 해당)&lt;/li&gt;
&lt;li&gt;컨테이너 시작시 실행 될 명령어를 명시 (시작시 실행 될 명령어에 해당)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/66104116bbd13b57537dd50c355885b4/00e65/003-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 327px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 138.33333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAcCAYAAABh2p9gAAAACXBIWXMAABJ0AAASdAHeZh94AAAC7klEQVRIx6WVay9jURSGz+8nIfEHfCERPvgiDBPRDC3BmCnq2tadaukNVVpds57FPtk9Ts0wK1nZl7P22uvy7vcEEpFOp2Pj2dmZ5HI52d/fl0KhIAcHB5LNZm19fX3dZetLwKavLy8v9mF2dlamp6dNk8mkTExMyOTkpExNTcna2prZYBs9H0gPqdVq8vT0FK7b7bY5QJ+fn3sdk+D09NRSOz4+lnw+b3p0dCTsn5yc2Jw9vjNHfVv3jZJQmoC6EIlL1dXGpfMvgu39/b0FEOCdDVK6urqy2+7u7kwxcs0pFotyeXkZ2hweHpqDUqlkTpvNptkGhIzs7u7K+Pi4jI2NyerqqiwuLkoqlZLBwUHp7++XmZkZGRgYsKYMDQ1JX1+fjXNzc3a+0Wi8OqQmRIc8Pj5awbmt1WoZPPhOdDc3NwYbImdNpNjhyJ3tcujX8CsSOnQpp9Npq8nGxobktWZ7e3syPz9vaVMC9ldWVmRpaUlub2+7cPguQj6Uy2XD3rluVqpVqWtKWQVwUeFwvr1tWuDV7OxIU5vl0BDr0NXwM+Ic9XTIB0b/Rbi17UWe2IcR0tHPRCXeGOuQTRpC0TOZjNUSaABo1oxxRBAbIcYI3RseHpaRkRHZ2tqyrrIeHR21Tv8t6tAhkVW1q0R1cXFhETkSADqAGaLgiQF0IkdZ+80MHWLsSLOi0KnX61KpVGxe4yJV1sCKi8tvNlzE/J1DInTgNrBGU/L4kGfHQdIE3A7gXQ6N51SJ5IeydEJJ4JfWLK0N+r28bPOcEsfCwoKklLkhDV4OznjfsRHSmLaSQkNrU9E67qyvS15fRnZzU3LaoLzWMq1zCJSD8Cd1jI0wdPhW4JaO35SSvus7Tmp0GX1qP7XjiUTCWNkJNf/QYRQKnQhjR9moZw3pMjfDxtxKWoy+wn3+HMjA2HQ9NkJIEmhU3yDykToboONnEP4C/Pp9VhyJIA8PD68/KVIGhyy+qvgA6JQj8G/6X0X+AEBZP3kAY4V4AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;003 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/66104116bbd13b57537dd50c355885b4/00e65/003-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/66104116bbd13b57537dd50c355885b4/8ff5a/003-01.png 240w,
/devHistoryBlog/static/66104116bbd13b57537dd50c355885b4/00e65/003-01.png 327w&quot;
        sizes=&quot;(max-width: 327px) 100vw, 327px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h3&gt;#. 베이스 이미지란?&lt;/h3&gt;
&lt;ul&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;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/0fb726fdcb867d7d6542669f00e1f265/2ad15/003-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 801px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 54.166666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABJ0AAASdAHeZh94AAABgElEQVQoz41S2W7CQAzM//9aEYgjAZKoJJQckBvIwenuTLvRqk+1ZK3Xa4/H9lqPx0Nut5vc73fqfD4X3/fl/X7LMAx8ez6fvENwvl6v0TZPiFVVlbRtS03TVKIokjiOpSwr6bpOrternM9nBqMgikBhazBTLSToqkmSUKMolqZpxoSyLFlQg0D6vifzv2Ih8XK5UHV1aNe1ZIaCRVEQAO3rMeCEz2QNPxlq2e/31CAIparrkSHYmYxOp5PsgoBxcZzQhw4RQ4aYFS4Ah7ZK4UNFgMGnmZjsOPvfuJEhnKiI2WVZRoaHQ6R8sL8U2A+g3jR+BWx9h+o7WBIQbDAvzCrPc0nUtouilEzZCMT2Z7OZuK4r6/VaptOpLJdL2rZty2KxEMdxJAxDsbAMCFh8TCYMsG2H89GCr7XdbgmIRIB7nkdAAG82G+ahSwIe06MK9lSQL6uVrZJd2X3uCIB3/WXQLmbXGXMzt8+W0Sr+WZ4X0tQN2WBR8GG2tdo2AP8r37loSjRqxNgAAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;003 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/0fb726fdcb867d7d6542669f00e1f265/2ad15/003-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/0fb726fdcb867d7d6542669f00e1f265/8ff5a/003-02.png 240w,
/devHistoryBlog/static/0fb726fdcb867d7d6542669f00e1f265/e85cb/003-02.png 480w,
/devHistoryBlog/static/0fb726fdcb867d7d6542669f00e1f265/2ad15/003-02.png 801w&quot;
        sizes=&quot;(max-width: 801px) 100vw, 801px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br&gt;
&lt;h2&gt;#. 도커 파일로 이미지 생성&lt;/h2&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/97dcc3ccddb4c6c99d52e3c8420d20c0/681f1/003-03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 899px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 14.583333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAABJ0AAASdAHeZh94AAAAiElEQVQI1z1OywoDIQzc//9NodYa1/qM4GHqpLCHEDLPXDln5DujfAvmnKilglhKCTFG48aY6K0/XKsNqgu9d8OppVdVcUkUOOcgIpjHGN4BSRK89/AvD/IMpZml8RNPwbDQWqsFhRCw98Y6JRcJCrlJUszWZ06QTjV89PH/6sxay24+wU2egT+swOW1Fa4LfAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;003 03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/97dcc3ccddb4c6c99d52e3c8420d20c0/681f1/003-03.png&quot;
        srcset=&quot;/devHistoryBlog/static/97dcc3ccddb4c6c99d52e3c8420d20c0/8ff5a/003-03.png 240w,
/devHistoryBlog/static/97dcc3ccddb4c6c99d52e3c8420d20c0/e85cb/003-03.png 480w,
/devHistoryBlog/static/97dcc3ccddb4c6c99d52e3c8420d20c0/681f1/003-03.png 899w&quot;
        sizes=&quot;(max-width: 899px) 100vw, 899px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h3&gt;#1. 도커 파일 생성&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;기본적 토대 &lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# 베이스 이미지를 명시
# 태그를 안붙이면 자동적으로 가장 최신것으로 다운
FROM &amp;lt;이미지이름&amp;gt;:&amp;lt;태그&amp;gt;

# 도커이미지가 생성되기 전에 수행할 쉘 명령어
RUN &amp;lt;command&amp;gt;

# 컨테이너 시작시 실행 될 파일 또는 명령어
CMD [&amp;quot;excutable&amp;quot;]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;#2. 도커 파일 빌드&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;build 명령어 : 해당 디렉토리 내에서 명시된 도커파일을 찾아 도커 클라이언트에 전달&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/22a6be0fb508ea74e82a764e3a170473/e3829/003-04.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 31.666666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAIAAABM9SnKAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAvUlEQVQY033QSW7DMAwFUJ3GcU2JkyZ6kO32/oeqHKSoswnx8D+XBF070/6TlqbJfJl9NuA0epq6gONnjouRNbIt5IVsxzIDBs/BU+8HhgHxcRdu3JfqkGyI9co0j6ogOAlPQk8M5O/8C/R0oCXEldRQFyERJCZRlmuYOyX8Q8IIHJ76gq5kOAoeWY7M3zmchc6Mje7owrQRrQiIw//Z6x7rSrH6uvK8R2tqm5Y5pirZYlcs1iXlKoAjvD/sF+1hQ96YODVUAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;003 04&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/22a6be0fb508ea74e82a764e3a170473/d9199/003-04.png&quot;
        srcset=&quot;/devHistoryBlog/static/22a6be0fb508ea74e82a764e3a170473/8ff5a/003-04.png 240w,
/devHistoryBlog/static/22a6be0fb508ea74e82a764e3a170473/e85cb/003-04.png 480w,
/devHistoryBlog/static/22a6be0fb508ea74e82a764e3a170473/d9199/003-04.png 960w,
/devHistoryBlog/static/22a6be0fb508ea74e82a764e3a170473/e3829/003-04.png 1077w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;도커 이미지에 이름 부여 (-t : tagging)&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;$ docker build -t &amp;lt;나의 도커 아이디&amp;gt;/&amp;lt;저장소/프로젝트&amp;gt;:&amp;lt;버전&amp;gt; ./&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/d40ac82d92fd3f1ad6d0fc341e893484/eb4a1/003-05.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 34.583333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAIAAACHqfpvAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAA00lEQVQY033QTY7DIAwFYE4DJGBjbP4TNZ2R5v5XGtqmVTYz4pPlt3gsrLaj719bne8Y959DGntyntCTB7T/U1Ir953aiH1P+x1Scegf5eAAzdPf5TVGzc1IN9K09BmBvA+zD/MLQIdoruBCOUk6DZOazsNKtixzGikm1ckyr4RLDB/uRI5QIXHijWVwbDlQCVxCrBQq0UuheIrSAviwvkBYVE7ulmmksNcpjkKdfYel4TrN5WJG+77CY6rbd8ndSXF1YNsgJo3ReLQezZN9O+P1YL9Ve03f7kXBHgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;003 05&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/d40ac82d92fd3f1ad6d0fc341e893484/d9199/003-05.png&quot;
        srcset=&quot;/devHistoryBlog/static/d40ac82d92fd3f1ad6d0fc341e893484/8ff5a/003-05.png 240w,
/devHistoryBlog/static/d40ac82d92fd3f1ad6d0fc341e893484/e85cb/003-05.png 480w,
/devHistoryBlog/static/d40ac82d92fd3f1ad6d0fc341e893484/d9199/003-05.png 960w,
/devHistoryBlog/static/d40ac82d92fd3f1ad6d0fc341e893484/eb4a1/003-05.png 1083w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;</content:encoded></item><item><title><![CDATA[JVM 분석 툴]]></title><link>https://ssongey.github.io/works/posts/2020-12-31--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2020-12-31--001</guid><pubDate>Thu, 31 Dec 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;#1. JPS&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Java Virtual Machine Process Status Tool&lt;/li&gt;
&lt;li&gt;JVM 프로세스 표시&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;// PID, 메인 메소드의 args 표시
$ jps -m 

// PID, jvm 파라미터 표시
$ jps -v&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/606d55ea709aec7b00e1db5f9a698485/3f8cf/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 16.249999999999996%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAABJ0AAASdAHeZh94AAAAjUlEQVQI11WO2Q6DIBRE/Zu2iUsVrCwKyOL//9HIkPTBhwNDuPdkOmNX+GCRi0cpATE5hHOH8+ZBqDOcYz6cxvqbIdep8sW89BBywiIGdDzsviFlj+s6karwjAdKzSS2HOu/a0KilMA4fdAPLwzj+0ETasOWpjUjXKI018Z8M2sjsamlIeTYWlHwl/ImN7d0Y6bnJPHsAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/606d55ea709aec7b00e1db5f9a698485/d9199/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/606d55ea709aec7b00e1db5f9a698485/8ff5a/001-01.png 240w,
/devHistoryBlog/static/606d55ea709aec7b00e1db5f9a698485/e85cb/001-01.png 480w,
/devHistoryBlog/static/606d55ea709aec7b00e1db5f9a698485/d9199/001-01.png 960w,
/devHistoryBlog/static/606d55ea709aec7b00e1db5f9a698485/3f8cf/001-01.png 1293w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;#2. JMAP&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;JVM 프로세스의 메모리 맵 표시&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;#2.1. heap 메모리 사용 현황에 대한 요약 정보&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;$jmap -heap &amp;lt;PID&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/e3ebc5805eef55d29ea1f806757ca33f/68e9c/001-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 654px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 145.83333333333331%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAdCAYAAACqhkzFAAAACXBIWXMAABJ0AAASdAHeZh94AAADBElEQVRIx42W6WLaQAyE/TBt2gDm9AHG5rDBHCFp3/9lVH1alkJYSH4o62B7dqQZaR1Vi5nUzUJW67kU80zmGraWmf5WynI1t3t+LeapzIpUsnxs13k+kukssUjSgUT7w0ZOp51s27Xs9o3sNZrNUhrdhN8AT7OhxXgSSy/+dRdx//flOiqrqbGBaVnltmu1nMlyWdgDr50fFp3uT+n2Xm4AroG4JqJ8Ola6E0f/fJ1PJ7Z6ZpmmNRh2bl58FFGpzKgP7OZlLpWuy1UhdV3JQllSlzQbSX/wegcY2iDiYVjkWuTMwr3sHyBVIsQmCAjIm4qCMMe3Vj4+jpYyIADDejjqXurXi1/uxLgB5A+2QVXSzrL/9SIQDftgJ1frTBZaJjYJMhzojdP7wdghyq0dXk39P39PlkW7q+WkGez3tTEOitJXNvitbipj9vnBWZFIs10ZMOl7AX1d71IGZKMvbNTMpDdJ4hshrlm7l9waUv0C2O4a7ZJaY2OW8d6jM2BEOba66VqtRDbvHwfbKJR2xE7btjaWiMNKapOkL6NxbIYH5HDcGiDenKoLHtoGhl5JVgBG494l5SQd2jDgnvfnU9tUC9fLFBogwteHIC0iJEKQIephByZNUbjRRLsBitfIwA8G1kfMLoC8RN1KOkLZUS/GF2KwCWKRAaWgfmTwbEhE3IQlrFC23a0NFEAAEAKxGGcb/T1RsR6Z2vWyym8dcNobMCB+LpL+deeE5mFQZbw30xFO+oCSMtahd2PAAhPmISDFp4aYGYuQanPuGljGgRef1hAQAEmVzugPOpfW8mfIV1P6LmUKDxvfaqa6MmQwfE75S8BYmdDLpEy7AY5dTBytox8G306ZI8DZo3T2UVBvZNL2hu72fn7P2KOzmdfayxzWnNPYaHE+vJjkHAlsnKvqwy9OP1MZ46Zq7EkyMDBA3ddEKe35A4B5eXzb2XPe2MFeBpD6IQoM8SOGxoPUtHc28/VJ+Mzg9uXgJk6utZyZurSZ/8ax/1eFuC+M3JR39gpP7H8Vh5vqNP4baAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/e3ebc5805eef55d29ea1f806757ca33f/68e9c/001-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/e3ebc5805eef55d29ea1f806757ca33f/8ff5a/001-02.png 240w,
/devHistoryBlog/static/e3ebc5805eef55d29ea1f806757ca33f/e85cb/001-02.png 480w,
/devHistoryBlog/static/e3ebc5805eef55d29ea1f806757ca33f/68e9c/001-02.png 654w&quot;
        sizes=&quot;(max-width: 654px) 100vw, 654px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h4&gt;#2.2. 객체 타입 별 사용 내역&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;$jmap -histo:live &amp;lt;PID&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/679ddd85c15c253c61840fa681e2e7a0/ddc81/001-03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 837px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 40%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABJ0AAASdAHeZh94AAABNklEQVQoz12SV3LDMAxEdZg4trpE9d6Vcv/7bLBQ6PH4A0NABJYPO3LqJkfblWjbAlVlUJQJ8iJG15eo6kzPfqgkNyirVMLIfaJ9tpdnlkWIEw9Oll9JUaYiXCBJfYTRQ4VK+cZ7Dvn+Da73oeFJ7vlX7srpB58aQXiHk5pQBVmc56rDrL++N4xjo/RNm8sDlZDWGKdGe/iQUgptFLsy/1AQx/yjhvLxOBeYLNQGCk5zi3kdsO8T9mNG3WRITYA8j3Vtrk8bLsG7FbwIWSwyTC/Y8PN7qOA4dZiXHqvcMdhDYQpwdbsq53VlI+jWt20bdZWLcH+uTAF6SjH6zN73eBISmYQ02Aq63k3Xn6ZWvaOHo+Ss+fgrkQ0r7NBoUlB4FUES0B96xlVJNc8dBqElKX+fV4H3+ANJ/QA2tLReEQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/679ddd85c15c253c61840fa681e2e7a0/ddc81/001-03.png&quot;
        srcset=&quot;/devHistoryBlog/static/679ddd85c15c253c61840fa681e2e7a0/8ff5a/001-03.png 240w,
/devHistoryBlog/static/679ddd85c15c253c61840fa681e2e7a0/e85cb/001-03.png 480w,
/devHistoryBlog/static/679ddd85c15c253c61840fa681e2e7a0/ddc81/001-03.png 837w&quot;
        sizes=&quot;(max-width: 837px) 100vw, 837px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h5&gt;참고) [C, [I, [B 이란?&lt;/h5&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/2e6fbdc0096ef686e2a9338f1f0eef4a/3a737/001-04.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 897px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 72.08333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAABJ0AAASdAHeZh94AAABaElEQVQ4y5VTi5KDIAz0/3+zM9UKCAhaH21z2Wgctb3OXWZ2ACGbzYKF9w35ECjERK5p6Ha7UZtaejweNM8zTdP0hnEcD+vX60UI5BR+JbHGUM2w1lJd12R4jr2qqijGSPf7nfq+p67rNuAboCGEMQYhaTjZOcejk7Vzzfbde085ZUopUdu2AsyFOGcZc040DAMVgduFGpBBGQjMqtCsivWMKkdH3odNcWZStA6LVkIrhMCeSIE1ClnrtuLL2gop2oaPz+eTCbkdEGoiVFhrtpbtWmixwb0Vgh0gh89QWeAQWtBWQFherzLHhQDG1DJCYVmWcgY+orsQopABuP0CNwMfcAjkMHtkc/W2YbQ+H4zzvIyfQm4Zk8TVLpeL+IFERGZiVP0t4NkeB8LlTQ3bQd1UJedkwYn4qJDVwDP1AhvwBxao4n3iJ7VHhfyO8Pud/dgr/BZvhHjl+gt9a/kfhFmewTfCvyr8AV7ZPfAq0C2/AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 04&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/2e6fbdc0096ef686e2a9338f1f0eef4a/3a737/001-04.png&quot;
        srcset=&quot;/devHistoryBlog/static/2e6fbdc0096ef686e2a9338f1f0eef4a/8ff5a/001-04.png 240w,
/devHistoryBlog/static/2e6fbdc0096ef686e2a9338f1f0eef4a/e85cb/001-04.png 480w,
/devHistoryBlog/static/2e6fbdc0096ef686e2a9338f1f0eef4a/3a737/001-04.png 897w&quot;
        sizes=&quot;(max-width: 897px) 100vw, 897px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[L 은 class 또는 interface 즉, any non-primitives(Object)&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;#2.3. gc 대기중인 클래스 목록 확인&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;$jmap -finalizerinfo &amp;lt;PID&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;#2.4. 덤프 파일 생성&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;파일 확장자는 일반적으로 .hprof 를 사용&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;힙 메모리의 크기가 GB 단위로 크다면, 분석할 덤프 파일 크기도 GB 단위로 늘어남&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;jmap -dump:[live,]format=b,file=&amp;lt;dump filename&amp;gt; &amp;lt;PID&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;h3&gt;#3. JHAT&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Java Heap Analyzer Tool&lt;/li&gt;
&lt;li&gt;힙 메모리 분석 툴&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;입력한 포트(기본은 7000)로 덤프파일이 분석된 웹페이지가 구동&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;$ jhat [-port] &amp;lt;dump filename&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[[작업로그] JVM OutOfMemory Error 분석]]></title><link>https://ssongey.github.io/works/posts/2020-12-31--002</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2020-12-31--002</guid><pubDate>Thu, 31 Dec 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;팀에서 서비스하고 있는 제품 중, 아이맘 택시 서비스에서 아래와 같은 현상이 발생 되었다.&lt;br&gt;
당시, 해당 프로세스의 메모리 사용량이 8G를 넘고 있었고(평균 1G), CPU 사용량도 90% 이상이 넘고 있었다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GC Overhead

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/e94feaf13307b0fd9b0f8c28a469fa43/fe238/002-10.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 15%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAABJ0AAASdAHeZh94AAAAhElEQVQI13WOQQ7CIBREuY2aFNRCEwRrgdLW3v9A45/WroyLl/mBzMso192QS4/3WrEsBWMdNqY57zklIaNKjuMLKUVYZ9BaonFvmy2PW5nrBUMKmEVGCeVFipQz+UZ48y/EDuz8Q2lzFmHcF3zXsXhIuOrZe3hv8QgOVpZxCXuNPv3wAfPEY983+fF0AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002 10&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/e94feaf13307b0fd9b0f8c28a469fa43/d9199/002-10.png&quot;
        srcset=&quot;/devHistoryBlog/static/e94feaf13307b0fd9b0f8c28a469fa43/8ff5a/002-10.png 240w,
/devHistoryBlog/static/e94feaf13307b0fd9b0f8c28a469fa43/e85cb/002-10.png 480w,
/devHistoryBlog/static/e94feaf13307b0fd9b0f8c28a469fa43/d9199/002-10.png 960w,
/devHistoryBlog/static/e94feaf13307b0fd9b0f8c28a469fa43/fe238/002-10.png 1401w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;li&gt;JDBC Connection Pool Error

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/21af5a2a6906aa3f25fc1efccceb6cfb/2eb79/002-11.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 28.333333333333332%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABJ0AAASdAHeZh94AAAA6klEQVQY02WQUZaDIBRDWc3MaWu1ioKIAmp19r+iDHlqf/qR80DkkkSl2WNeJmz7jPUdsiL8aDFOFiE6DN7ADS1618r6UAfbN2i7CrotZV5SBKZ5xJ6ByxpEfjQCJMjYWtSZ12ceoArV6/4lFeKAmDz2v0VgdMtv7y1hCodDOqYrro1txBXBxfP3Syrmy3TIyEuGEUoQZzjPKK4pl6PXTYGyuuFR/AjkmgKkI7rZstgfQYwb0yDOeqdzX1o65KQ6U38607qUPV2zBsVLhBDK6HxgPffbfsSmxGk+v/6ZzzRMOIUejX7mDh/4B46bx3U4ZIpuAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002 11&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/21af5a2a6906aa3f25fc1efccceb6cfb/d9199/002-11.png&quot;
        srcset=&quot;/devHistoryBlog/static/21af5a2a6906aa3f25fc1efccceb6cfb/8ff5a/002-11.png 240w,
/devHistoryBlog/static/21af5a2a6906aa3f25fc1efccceb6cfb/e85cb/002-11.png 480w,
/devHistoryBlog/static/21af5a2a6906aa3f25fc1efccceb6cfb/d9199/002-11.png 960w,
/devHistoryBlog/static/21af5a2a6906aa3f25fc1efccceb6cfb/2eb79/002-11.png 1256w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;li&gt;Java heap Out of memory

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/d95cbb210fde1c7f2b63144bf9a46a33/77abb/002-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 12.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAABJ0AAASdAHeZh94AAAAjklEQVQI11WOWRKCMBBEuYqWCIZFKERD9gD3v1I7My6lH69myXSni3UL2PYIrnn1CNEiZ/fqg5GaeCb4xnkt6GVCf1UYxoZo0XYVur5GEaIhgRWRp0PrHkjJihELY7Jfw8/OhwVaT1BNCaVKqRd1Egp+TG9RoN6QIe9+00T6lBPd5gHzfZREVX0UztXhjyeB/GKXo0LK/gAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/d95cbb210fde1c7f2b63144bf9a46a33/d9199/002-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/d95cbb210fde1c7f2b63144bf9a46a33/8ff5a/002-01.png 240w,
/devHistoryBlog/static/d95cbb210fde1c7f2b63144bf9a46a33/e85cb/002-01.png 480w,
/devHistoryBlog/static/d95cbb210fde1c7f2b63144bf9a46a33/d9199/002-01.png 960w,
/devHistoryBlog/static/d95cbb210fde1c7f2b63144bf9a46a33/77abb/002-01.png 1305w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;ul&gt;
&lt;li&gt;현재 내가 진행하고 있는 프로젝트가 아니라.. 로그만으로는 분석이 힘들어 &lt;a href=&quot;/devHistoryBlog/works/posts/2020-12-31--001&quot;&gt;jvm 분석 툴&lt;/a&gt;을 사용하여 아래와 같이 모니터링을 하였다.&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;h3&gt;#1. 모니터링 스크립트 만들기&lt;/h3&gt;
&lt;h4&gt;#1.1. 사용 리소스 모니터링&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;해당 서비스의 메모리, cpu 사용률 및 부하 감지를 위한 서비스, DB 포트 연결 개수 모니터링&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shellscript&quot;&gt;&lt;pre class=&quot;language-shellscript&quot;&gt;&lt;code class=&quot;language-shellscript&quot;&gt;#!/bin/bash

LOG=log_res_mn
while [ true ]
do

        echo `echo \[;date;echo \]` &amp;gt;&amp;gt; $LOG
        echo `echo netstat 8000 cnt \[;netstat -na | grep 8000 | wc -l;echo \];` &amp;gt;&amp;gt; $LOG
        echo `echo netstat 3306 cnt \[;netstat -na | grep 3306 | wc -l;echo \];` &amp;gt;&amp;gt; $LOG
        ps -eo pid,rss,size,vsize,pmem,pcpu,time,cmd --sort -rss | grep NAMU | head -n 1 &amp;gt;&amp;gt; $LOG
        #ps -eo pid,rss,size,vsize,pmem,pcpu,time,cmd --sort -rss | head -n 5 &amp;gt;&amp;gt; $LOG
        echo ------------------------------------------------------------------------ &amp;gt;&amp;gt; $LOG
        sleep 1;
done;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;#1.2. 해당 프로세스 PID의 메모리 사용 내용&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;jmap -histo:live [PID] 명령어를 이용&lt;/li&gt;
&lt;li&gt;해당 프로세스에서 사용하고 있는 클래스 별 사용 내역 (인스턴스 개수, 사용된 메모리 크기)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shellscript&quot;&gt;&lt;pre class=&quot;language-shellscript&quot;&gt;&lt;code class=&quot;language-shellscript&quot;&gt;#!/bin/bash

LOG=log_mn_jvm
while [ true ]
do
        PID=`sudo jps -v | grep &amp;quot;\-Xmx2048m&amp;quot; | awk &amp;#39;{print $1}&amp;#39;`
        echo `echo \[;date;echo \]` &amp;gt;&amp;gt; $LOG
        sudo jmap -histo:live $PID | head -n 10 &amp;gt;&amp;gt; $LOG
        echo ------------------------------------------------------- &amp;gt;&amp;gt; $LOG
        sleep 5;
done;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;h3&gt;#2. 모니터링 결과&lt;/h3&gt;
&lt;p&gt;** 해당 결과는 새벽에 오류 재연을 한 것이므로 오류 상황보다 CPU 점유율이 낮게 나왔다. ** &lt;/p&gt;
&lt;h4&gt;#2.1. 오류 발생 전&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;기본 사용 메모리, cpu

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/a32f5708df6f6d955e6607d28bc438db/59822/002-04.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 916px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 7.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAACCAIAAADXZGvcAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAY0lEQVQI11WNSwqAMAxEPYqt0ETtJ2mbShU3XsL738ToThgew7zFDNKoSFy9c2gQpxksooV/HJiPFuDtDkZApRn6ufVe90MSryUtN8WrpiyUS+DspbEqzoHU6l5i27gKafT1AcX2FT2GuiWgAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002 04&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/a32f5708df6f6d955e6607d28bc438db/59822/002-04.png&quot;
        srcset=&quot;/devHistoryBlog/static/a32f5708df6f6d955e6607d28bc438db/8ff5a/002-04.png 240w,
/devHistoryBlog/static/a32f5708df6f6d955e6607d28bc438db/e85cb/002-04.png 480w,
/devHistoryBlog/static/a32f5708df6f6d955e6607d28bc438db/59822/002-04.png 916w&quot;
        sizes=&quot;(max-width: 916px) 100vw, 916px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;li&gt;인스턴스 개수

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/d7ea364e590d1cdea7313d37ba5120ce/c67d4/002-03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 723px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 27.916666666666668%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABJ0AAASdAHeZh94AAAA/klEQVQY02WRx47DMAxE/SPBprh3yS3uceJD/v+HZjkEVpc9DEiNoMciL04esG2Jtq1Qmww8q9cUMDZHUcYaeaYfhFenKL7/k5floV62XY3jveqjVLz9NWNeBlhboKpTASfIi0hVVokWCqObExmMXpoF8IMfB6QZCZT5+7OJXyl4mnvMomV9St6px845WT9YjGOLRnIFks4Du4oEGCc+tn3Cuo3q8zHzeem1ABvgeEnqO5HDKEAf98dFq3y/p9sNuzvPHV1v8DoWAU7YBPoRj3fHsUqxUiF/4+rI3AX3wg9hdeb02Bkf1CbXaGSXtimlQI3h2aiX5YF2RvEvCP8Flhu5xh0l9PcAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002 03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/d7ea364e590d1cdea7313d37ba5120ce/c67d4/002-03.png&quot;
        srcset=&quot;/devHistoryBlog/static/d7ea364e590d1cdea7313d37ba5120ce/8ff5a/002-03.png 240w,
/devHistoryBlog/static/d7ea364e590d1cdea7313d37ba5120ce/e85cb/002-03.png 480w,
/devHistoryBlog/static/d7ea364e590d1cdea7313d37ba5120ce/c67d4/002-03.png 723w&quot;
        sizes=&quot;(max-width: 723px) 100vw, 723px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;h4&gt;#2.2. 오류 발생  후&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;문제 발생 시점부터 약 20초간 확 증가된 메모리 사용량

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/2d8bf4767dc95258800bb9326e0bb556/b7877/002-08.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 891px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 26.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAIAAADKYVtkAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAu0lEQVQY0zVPCW4EIQzjNz12kpALGKbHdtX+/0s1VJWiyLFsY8oZ/BPypZQhkVXtYHlRowhRPXCOM8wJGHsBoz9gLmWGvKW8u4xuMHsw8TOkkbrMehung6x6M2f7d26Bl49h3zMf3eeM1i2bSoWO2lgevH9dDSSYSPHVDptxZo9ypd6Hf2ZtGJizSn115+zmvsrPq7dthnPFrXayzM3LcH4Y3Y061DvyoCeUhAIpqIdEkMC7M+/Bz1HbfgFAPDsUDxWudwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002 08&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/2d8bf4767dc95258800bb9326e0bb556/b7877/002-08.png&quot;
        srcset=&quot;/devHistoryBlog/static/2d8bf4767dc95258800bb9326e0bb556/8ff5a/002-08.png 240w,
/devHistoryBlog/static/2d8bf4767dc95258800bb9326e0bb556/e85cb/002-08.png 480w,
/devHistoryBlog/static/2d8bf4767dc95258800bb9326e0bb556/b7877/002-08.png 891w&quot;
        sizes=&quot;(max-width: 891px) 100vw, 891px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;li&gt;해당 시점의 인스턴스 상태

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/94a63512ca1b5551c1ba6a2dc2d8cae7/d4c13/002-06.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 825px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 25.416666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAIAAADKYVtkAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAA5ElEQVQY01WNXW6DMBCEuUmSAv7BXmwTGztAgokTICSqVKnvvf8tulVfWunb0exoR5tBzSpJlKp8aABoD3zr2mTVAKwSJWUHQveUvf0Fc2whGQ6vCgn0cjmhXwx8pfgZ3Cw5YQfOc7xm/xGirH/LUnGK5ZqneQLNtZGPNQ29P3UudG4Yu9DZguzzH3Z5uUMl+FwSDjQ717zlRSvp+y12WnjgH0uaez8PYYvDczo/Yz86PVoVnZ5ag/4WLCoWs7ugqSJR0ofVV6BR0JdvZgNLU69HtVq1NIDr3UhMEPSbMy9/3LT8BtTNOfy8kS7WAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002 06&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/94a63512ca1b5551c1ba6a2dc2d8cae7/d4c13/002-06.png&quot;
        srcset=&quot;/devHistoryBlog/static/94a63512ca1b5551c1ba6a2dc2d8cae7/8ff5a/002-06.png 240w,
/devHistoryBlog/static/94a63512ca1b5551c1ba6a2dc2d8cae7/e85cb/002-06.png 480w,
/devHistoryBlog/static/94a63512ca1b5551c1ba6a2dc2d8cae7/d4c13/002-06.png 825w&quot;
        sizes=&quot;(max-width: 825px) 100vw, 825px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;ul&gt;
&lt;li&gt;GC가 돌아 약 25초간 cpu 사용량 쭉 증가 후 약 40초간 유지&lt;/li&gt;
&lt;li&gt;그 후 점차 감소

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/f44b9b470a0d2e584d497f3b55e1c871/1cfc2/002-09.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 900px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 26.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAIAAADKYVtkAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAtklEQVQY00WPQXJDMQhDfZzf5tsYYbDzk006WfT+J6pwFp1hYCGeEGW4zonhPRY8OkazdvxqvUw6TuCcy6iq3oAKqxi7Wx0uhQJHwqEeChe0rxcIN1gjExMs6TelV2Lt04kUCmsmdj0ij0S39v02ebqai1m7X76uQdIYauSZ7EM8UIhFxhaGj4B5Rzt+tD6GcIkwybUs4Z2Fm3TZsJYEtuWn8ud6vPt5t6osnJG5uuh/bN3Pc/kPYT87OkXNaAMAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002 09&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/f44b9b470a0d2e584d497f3b55e1c871/1cfc2/002-09.png&quot;
        srcset=&quot;/devHistoryBlog/static/f44b9b470a0d2e584d497f3b55e1c871/8ff5a/002-09.png 240w,
/devHistoryBlog/static/f44b9b470a0d2e584d497f3b55e1c871/e85cb/002-09.png 480w,
/devHistoryBlog/static/f44b9b470a0d2e584d497f3b55e1c871/1cfc2/002-09.png 900w&quot;
        sizes=&quot;(max-width: 900px) 100vw, 900px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;h4&gt;#2.3. 소스 검토&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;해당시간에 발생된 request url 검사 후 해당 로직 검토를 하였더니
Document 테이블에서 가져오는 row수가 1,713,561건 인것을 발견하였다.&lt;/li&gt;
&lt;li&gt;해당 비즈니스 로직에 대한 이해도가 없어 왜 이런 상황이 발생이 됐는지는 모르겠지만,
select 최대 row를 강제할 수 있는 방법을 찾아 팀 코드 컨벤션으로 정해야겠다.&lt;/li&gt;
&lt;li&gt;좋은 경험 했다!!!!!!!&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[jmap 사용 시 main java.lang.reflect.InvocationTargetException 발생]]></title><link>https://ssongey.github.io/errors/posts/2020-12-31--001</link><guid isPermaLink="false">https://ssongey.github.io/errors/posts/2020-12-31--001</guid><pubDate>Thu, 31 Dec 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;문제&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;jmap 사용 시 아래와 같은 에러 발생&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/83305625508723f528d6122dc0e3d346/38a65/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 71.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAABJ0AAASdAHeZh94AAAByklEQVQ4y22TaZaCQAyEOYqDssoiq8i+qMx4//tkUsF2xOFHvU73a75U0kFrmoKatqCyyqmqc0qzEzmuQbZzIMvWyTC/yLSU9Ld4kWHuyHiu2Gtx7FPECkKXkiSgU3Sko2cxbP+E6W8wfQVdJ1ukZfmJsjyijJ0B5geOODT58sHYidawNdB29lKJwxUJECVfrx217YU8zxTraRpSwGDI922B/4fqm23QGgb1fcUZ9vzhjiw+rOtCzvquopydGwbO9U0oWgOHFr4HsOtKcYj+Oe6BS7bpXMQUJz4/UMj99binpvR1WdfyfGslDU5+Hje6zyODEgFNnGD+nmgcG0IFSPL5Ic7UuYohDePS9SWPTSYwHOKhAA9Pruy3nHxCXw4vZcrzdyasgNccYy4xk7LnRxuGmpNW8nCYBCSCPsHi0D0a4ghlosTbfaDH407zPEl8vfWi/glFAlSDZAmmIXRW/dSQCY8wMAwap1bgIo5bfjT8PcoVHEJ4LCW1x6ohKC6pwOBEgV5Q1n0exCHu4T56naSBrDFPB/42TAT2UjKsizuWlMauhmcMjVND+TkSByjr3/j4f7H8y8iWn2NZxX60uFAlLfGyf3+ALf0CkM20kM3qUooAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/83305625508723f528d6122dc0e3d346/d9199/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/83305625508723f528d6122dc0e3d346/8ff5a/001-01.png 240w,
/devHistoryBlog/static/83305625508723f528d6122dc0e3d346/e85cb/001-01.png 480w,
/devHistoryBlog/static/83305625508723f528d6122dc0e3d346/d9199/001-01.png 960w,
/devHistoryBlog/static/83305625508723f528d6122dc0e3d346/38a65/001-01.png 1075w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;원인&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;기본적으로 설치한 jdk에는 debugging이 포함되어 있지 않다.&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;h3&gt;해결&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;openjdk-8-dbg 설치&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/cdde29de0ca668497ea58f8972332365/7608e/001-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 735px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 59.583333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAByklEQVQoz01R246dMAzkU9rlkENCrnZuQLicXa2qSu1D+/8f02F5qTSyBhF7xuOuVt5aZbIgahq0eSo1jLIf5UOqQU3iOfaD+H5DAM+34asCHWdTFo86rwmdHN2kxagG/JPycY+Y9FOb8f+qlLiafRhykbXoZcml8rqknKnOscxxacVYKScxmTGQsU4ZwEgiA3eP4Vv36foPFp8sfmYTk0/J50Ilhz2Ho/DKbiFbyKDNe32PAECITbfaxx7HM8kzG2im5C79HH6x/zPn35H+1vyDPcSdU84qeAHQj+067d98HnwSXBQyi9HN8Fxohj5kM2011cwhGAra+8n5CZXYIrxuMr0n4cOTaAqkiTT6ASyGR7CHQSl6CzV7LQxizDiOvZR9F6LYXlxXt+3lPNdtr62VbV9Azlc7TsQYMChlXyrhFsgFFXe5bHse1sPlRW9HPva1tbq20raCp3XmeYkpB0SIEbCAK1yh5gCCv50j0Q6C8rJx29O8xrVlwAesp65F2HCyHG1MkHU3QYV+5+PQXr42V5tZDjO30LbL+et9e703KOMpPH8hXPqVcI6cQRiBDak6TjpdxvgejKe3DlI1dvThsgAvtx183vwfVieLR1gcnOsAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/cdde29de0ca668497ea58f8972332365/7608e/001-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/cdde29de0ca668497ea58f8972332365/8ff5a/001-02.png 240w,
/devHistoryBlog/static/cdde29de0ca668497ea58f8972332365/e85cb/001-02.png 480w,
/devHistoryBlog/static/cdde29de0ca668497ea58f8972332365/7608e/001-02.png 735w&quot;
        sizes=&quot;(max-width: 735px) 100vw, 735px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;설치 후&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/d0f60ef54a0f5e2154e3b338a0d25dd3/7cb89/001-03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 563px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 170.41666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAiCAYAAABfqvm9AAAACXBIWXMAABJ0AAASdAHeZh94AAAEKklEQVRIx5WW65LaOBCF/SKbTYbhahtjbIO52MbcmdnUpPL+79Lpr42IIUxV9keXJCQdnb6cxt66yGW3L6UsF5JmE8lmsczmU5mrMa82S13HslzNZLHMhPPheCD9wTcZjl6l1/92Zx4X6notq/Vc8kUqhQIvV5mBsd6wp2DxNJBo4kscBxKE/T+AboBc2NQru7zdVTcm1WZlYLAZDDvy2v3XrPPK+FW6vQbAjTdAXh1HQ5nEMBhJEPRtbWymobnVef1iF5vLL5+yM8CZujbPpxanubIkdvM8ucUyTSNjn82mkugcwEdWd4AuEUk6NlaM0yS0mBmw7o/8rgH179g9zl+ugAoQx765O00aMNxnk5h1e1/NiNv95Zc7ILfnZbOJJWC331hSDoeN7HUeaRwB5GAU6WMazyYxTUIYnbXBvbEyI7OAltXSMpwoU1/dhBmA4Xhoe8RwmkT2QJpObE2Y2qAeL3N4t9eSWaYy0qwasytYf/AiYwXc6IOn897OleVSPanleNyJr1XxO/sKyGswrLeFZRtmgPWvcWGkkFFSvS3tLGop1DZ1cQdmgBOljEp4GVe7FrcG0BkM02RsKoFAGA6Ee/Ek0POPgJphpLVW0KrSOJa5Agyk0/nHwDGrACSn7vl+T/xRV8JgINF4JBN9oNdTMJj2cFkPwxCZFQpWb9dW3BR0mkXKOjQ2eLDXCrBz6i6VQEyJ7UDjPNRHUJVHIR+OW/n48S7nt4OcL3uzslpYkQOKYo7HWv77fpEfP78rWGUPrNYzoUpCjTGaxzwW1CIsXafJF4myGtmLftCzQndnFipDfnMWXMEYMS+33hdb/XEJmbnNtnGZPQfizJi1QL1aW9d2V8hF3UUt62JuCUKCDrzNpG3PHvYQP7FAcrCkKdBdmBM7jDDQ0hzDNtNHxlY2211pamFzrvG7XJNDsR80GR8f7/L2frTkHc87Tc65EYGef2Ts8XKj5aW1q6ZRVHI8ba1EWMMQdRAKzvI4iWuHIQivgIBw+KQvw5SDsLTmqiWzUH1zoZ1ZZ+043hgSM5hQZ2SZZkuScJUyWmt8SdBnSWnm/bbLI7tIEvyga38DKALGuEvWefQZoHP1DpCeBkMSQHyQGnIkthhgjP8LECa4yP8LqiCuxDDJokY1Wgl/DYjL6LbSzMEM10/X0iBJ7k/+rwFhRKOkgcKExFgD1XXzJZF/Cvg0KbQq6go21B9JoFweFdDY86ZwB8jrsKOQAYMZ7gJeaChYn3SPBoIHlBBtrc3wrg455NRAuyIhgL+p/Mh8pRWA7LDzpZEkUkT/bendlMKCTBqoHqKoAaQWCw0F8YSV+7pgTkimT+JqgLNZ8y1ImZAE953DN491ax1JFB9OsMdcJ7+5G7YarH0UcVn/uLMstm8Z5jkXkwaQLs3Ib/l1jhlQ0ALU+S/z/i3MY0G5hwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/d0f60ef54a0f5e2154e3b338a0d25dd3/7cb89/001-03.png&quot;
        srcset=&quot;/devHistoryBlog/static/d0f60ef54a0f5e2154e3b338a0d25dd3/8ff5a/001-03.png 240w,
/devHistoryBlog/static/d0f60ef54a0f5e2154e3b338a0d25dd3/e85cb/001-03.png 480w,
/devHistoryBlog/static/d0f60ef54a0f5e2154e3b338a0d25dd3/7cb89/001-03.png 563w&quot;
        sizes=&quot;(max-width: 563px) 100vw, 563px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;</content:encoded></item><item><title><![CDATA[Docker? 및 명령어 정리]]></title><link>https://ssongey.github.io/history/posts/2020-12-30--001</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-12-30--001</guid><pubDate>Wed, 30 Dec 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;#. 도커는 무엇인가요?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;컨테이너를 사용하여 응용프로그램을 더 쉽게 만들고 배포하고 실행할 수 있도록 설계된 도구 이며, 컨테이너 기반의 오픈소스 가상화 플랫폼이며 생태계&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;#. 컨테이너란?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;코드와 모든 종속성을 패키지화하여 응용 프로그램이 한 컴퓨팅 환경에서 다른 컴퓨팅 환경으로 빠르고 안정적으로 실행되도록 하는 소프트웨어의 표준 단위&lt;/li&gt;
&lt;li&gt;컨테이너 안에 다양한 프로그램, 실행환경을 컨테이너로 추상화하고 동일한 인터페이스를 제공하여 프로그램의 배포 및 관리를 단순하게 해준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;#. 컨테이너 이미지&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;코드, 런타입, 시스템 도구, 시스템 라이브러리 및 설정과 같은 응용 프로그램을 실행하는 데 필요한 모든 것을 포함하는 가볍고 독립적이며 실행 가능한 소프트웨어 패키지&lt;/li&gt;
&lt;li&gt;도커 이미지는 프로그램을 실행하는데 필요한 설정이나 종속성을 갖고 있으며, 도커 이미지를 이용해서 컨테이너를 생성하며(이미지의 인스턴스) 도커 컨테이너를 이용하여 프로그램을 실행&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/fe627eb7e3afb044becde90e18397f07/7960f/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 54.58333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABYlAAAWJQFJUiTwAAABy0lEQVQoz4WRX3OaQBTF/f5fxDz0sZNp08QG/7QmoxK1acegAisCCixGXCKCnFwWEtt00j78Zu8uew/n7qk1xw782QC5oyJdvo+whsjs017WVh/pooeM1gO7xcGbosZdhmx+jdxo4Ujk72G2idMeVKdGBynrImM3SOctZM4YNWyY/Aj2nfj22/onRcOhItXb2GvX2Ho2+GYLPwgR8TXS1S/UUs6Q64p0ALNTOWn/JbifKjRBp4TuZXoLwp5AeAy7tQnhTJC6P1HLuIGDNUAcrrDzFhDcxd6+x1FvysZSpC0Fc/nDkuJ5CpGIegqEo5HgPQkGOlLnB0S8Bw8CROIJ8WqKRGuUI86aEjFpvNbF+dNDA9s1wyYMwX0fu8Cmkclh4huYfD2DelHH8MsZxlfEZR07EoDVfR05mSlvnqGDeDGSLmPnAYINS4dJYCAYnoOPPmOtnkuC0SfppGgsxpOCNHJCZ4l02JQOo8DFJoopmAjikVehhJTygpqWNycqZ7lJsJIXcQnVGSWt968wVxXody2qL5HQ01HKZpUyXaTHfwFV6v/CUz9iqtShEXb3AzK3EHy0cbRucVz239D7T90DnAHg3gErwukj8zU8A72EIZyWtIoIAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/fe627eb7e3afb044becde90e18397f07/d9199/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/fe627eb7e3afb044becde90e18397f07/8ff5a/001-01.png 240w,
/devHistoryBlog/static/fe627eb7e3afb044becde90e18397f07/e85cb/001-01.png 480w,
/devHistoryBlog/static/fe627eb7e3afb044becde90e18397f07/d9199/001-01.png 960w,
/devHistoryBlog/static/fe627eb7e3afb044becde90e18397f07/7960f/001-01.png 1274w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;#. 도커 명령어 모음&lt;/h3&gt;
&lt;h4&gt;#. 컨테이너&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# 동작중인 컨테이너 확인
$ docker ps

# 정지된 컨테이너 확인
$ docker ps -a

# 컨테이너 삭제
$ docker rm [컨테이너 id], [컨테이너 id] 

# 컨테이너 모두 삭제
$ docker rm `docker ps -a -q`

# 중지된 모든 컨테이너 삭제
$ docker container prune

# 실행중인 컨테이너에 명령어 전달, interactive, terminal : 명령어 실행 후 터미널 계속 유지
# docker exec {-it} &amp;lt;컨테이너 아이디&amp;gt; &amp;lt;명령어&amp;gt;

# 해당 컨테이너의 ssh 접속
$ docker exec -it &amp;lt;컨테이너 아이디&amp;gt; sh

# 실행 시 volume 잡기, 맥에선 -v $(pwd):/usr/src/app
$ docker run -p 3000:3000 -v /usr/src/app/node_modules -v %cd%:/usr/src/app [이미지 아이디]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;#. 이미지&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;# 이미지 확인
$ docker images
$ docker image ls

# 이미지 삭제, 강제옵션 -f
$ docker image {-f} rm [이미지id], [이미지id]
$ docker rmi {-f} [이미지id], [이미지id]

# 이름없는 모든 이미지 삭제
$ docker image prune&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;#. docker 리소스정리&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;# 중지된 모든 컨테이너, 사용되지 않은 모든 네트워크, 하나 이상의 컨테이너에서 사용되지 않는 모든 이미지를 삭제
$ docker system prune -a&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;#. dockerfile 빌드&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;$ docker build {-f dockerfile} {-t tag} [context 폴터위치]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;#. docker compose 실행/종료&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;$ docker-compose up {-d --build}
$ docker-compose down&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[SpringBoot Remote Debugging]]></title><link>https://ssongey.github.io/works/posts/2020-12-29--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2020-12-29--001</guid><pubDate>Tue, 29 Dec 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;#1. 서버 설정&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;아래 옵션을 추가한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;-Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=15001,suspend=n&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;실행 시 15001 포트로 접속하여 디버깅을 진행할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/5fe1d9489dc311a1e0ae9c977489749c/e8d6f/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 30.83333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAIAAABM9SnKAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAA3ElEQVQY013Oa26EMAwEYK4CXTAQB2In5AEEyO7971RvUaVtpU+j+eGJUj09vZIrgS/PJVjJ05s90EyKjIqkPWFgjKzDT0l2Yt0zgqhYD7MC0mAQZtVJIjTQ1S3UHdSPrn7AH+0v6ZXhkRckp8lq62bR9Q0MX/2t/yj/NRVb5QKyLO3kPflAxIgaFHY31Df4pBCmeajykbbNS15l23afz7WUnHOM65LWZc8xRGvdZAgNqdmMYlStkHer8szHkeToKvtxpvPaVtnsIb3HTpZCig8cJSMvnt7fdBOz/gZJtULxDJxyxgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/5fe1d9489dc311a1e0ae9c977489749c/d9199/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/5fe1d9489dc311a1e0ae9c977489749c/8ff5a/001-01.png 240w,
/devHistoryBlog/static/5fe1d9489dc311a1e0ae9c977489749c/e85cb/001-01.png 480w,
/devHistoryBlog/static/5fe1d9489dc311a1e0ae9c977489749c/d9199/001-01.png 960w,
/devHistoryBlog/static/5fe1d9489dc311a1e0ae9c977489749c/e8d6f/001-01.png 1273w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;#2. IntelliJ 설정&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;서버와 동일한 프로젝트에서 아래와 같이 debug configuration 을 적용한다.&lt;/li&gt;
&lt;li&gt;Remote 선택 후&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/6b73711184f0309304decf191e376d99/a76f4/001-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 586px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 63.33333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAABJ0AAASdAHeZh94AAACLElEQVQ4y4WT2Y4SURCG+230xgw7Aw297900NPuigswGjKIyIrM5MDCJCeqFmVfwPX+rz0QSA+jFl6pT6fq7qk4dztHq0GwHtufDKRRh2C50y2G+6XhwKK7oBnhBQk6UN3YfHC/YkFQdsmZANSxKNiEq2sYPxcIPs3nxL9F9cKbjbBIESYZCwrZXQIbPU0xAnmK1ZpvFwsozOeHfFYYtGrYH1y+jWK4hqDZQCKobfIrVmh24xTIcP6Dq9U21OyssN1/DCxossd5+hWqjTaJNlOst8juo0LlUqcN0fVheCRqNQqSqJVmBuAOu2u3BqRTB50Q2y3B+oqIikc7gIJZAJJ5kRBMpxJNpvIgf4lkkjedRIrIN17v5htHVEpezGT5cTHF8NsDJ2fCJwRCngxHzz8fvMRydw3s5AF89hVg/g1Dbhvt1u8Lj3Qqz+QLz+xWuv8yxWD7gfvWA6ewSk+kMF8Tk02dc3dzi8vqW/fgjnXfBqU6Jbs+FJOYhSyJUhYab55FMJRCLRxGNRZmNRA8onmc3ydpPHRLpLbhRf4nh20eMj9cY9tcY9dbotxZQez9gESbjO8w3P+E2xtANnUQVWqfdcO86Vzg++oqT7gJH3SV6zTt0ggmUzj301hwaiWtk1fYKVuUUmq7R2ux/LVzRs1B2TASGhiJRsQ0I1HKWPwRPPNkMMpkUienQTJvt4V5B2TdhBQFseru2X4JZKEHSwrcrs9b+kKVzKPY/wd9NSuqtIFOczwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/6b73711184f0309304decf191e376d99/a76f4/001-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/6b73711184f0309304decf191e376d99/8ff5a/001-02.png 240w,
/devHistoryBlog/static/6b73711184f0309304decf191e376d99/e85cb/001-02.png 480w,
/devHistoryBlog/static/6b73711184f0309304decf191e376d99/a76f4/001-02.png 586w&quot;
        sizes=&quot;(max-width: 586px) 100vw, 586px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Debugger mode 선택, Host, Port를 넣어 실행하면 &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/bf9ede622887815e59e64e5aef1d3446/ee3fb/001-03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 63.74999999999999%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABDUlEQVQoz5WSiW6DMAyG81xrIT5zglq67f1fZU4Q3UUmTfpkxQm+fuM0plQXChE17NAvgHVGRgmGJzWXNKKoC+urxIrEHsiYPV4HTPYK9Dwbzmu2hO+oG8kDOEzwMjcuZ/GXGb667h7iI6YtpAq0khSgSnxj9T3LqItrf3KPXN7Kck95y+UWc0aupKuNRzIbyGeIl2zWaV20LFprs7lKLmK2VM1FU+nChBNC8qwOOeChnuFJPLJv6ekpzAn9yZnuwMIxx7pqzOa2LHZJYhWsyWG8Be8C2EfQa06Ac1+JHaZjMSMctRl6w8itz8639Y6xyvs+4GBvhA6avMPK/b/5HOzvPn8Gd4XCYcO/gj8ALZzHFwHdPNMAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/bf9ede622887815e59e64e5aef1d3446/d9199/001-03.png&quot;
        srcset=&quot;/devHistoryBlog/static/bf9ede622887815e59e64e5aef1d3446/8ff5a/001-03.png 240w,
/devHistoryBlog/static/bf9ede622887815e59e64e5aef1d3446/e85cb/001-03.png 480w,
/devHistoryBlog/static/bf9ede622887815e59e64e5aef1d3446/d9199/001-03.png 960w,
/devHistoryBlog/static/bf9ede622887815e59e64e5aef1d3446/ee3fb/001-03.png 1144w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;아래와 같이 접속 성공 시 “Connedted to the target VM” 이 뜨고, 종료 시 “Disconnected” 가 출력된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/abcc1ad6da716a9387bc7981e134912b/65654/001-04.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 872px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 17.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAABJ0AAASdAHeZh94AAAAqElEQVQY01WKWQ6DIBRF2Y/DjynwmEGtnY1J97+VWyGVtB8nd2SX54rHuuG1vTFf77AhwfgI89Wad7SL1Zfs/3P+spBGpGnG+XJDSBOUtlDGVpWkYX2AjwnaOpA2BS6pqJAKghRIGZyEBONcwFoLIoKUEkoRtNY7qmjuMzFGLMuCaRzhnCvdsQshIDjHMAxgbdsi03UdDn/kpmmqZvq+L+Tud8//4vftA7XUhXREJYxtAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 04&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/abcc1ad6da716a9387bc7981e134912b/65654/001-04.png&quot;
        srcset=&quot;/devHistoryBlog/static/abcc1ad6da716a9387bc7981e134912b/8ff5a/001-04.png 240w,
/devHistoryBlog/static/abcc1ad6da716a9387bc7981e134912b/e85cb/001-04.png 480w,
/devHistoryBlog/static/abcc1ad6da716a9387bc7981e134912b/65654/001-04.png 872w&quot;
        sizes=&quot;(max-width: 872px) 100vw, 872px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;</content:encoded></item><item><title><![CDATA[프로젝트 gradle version 확인 및 업데이트]]></title><link>https://ssongey.github.io/works/posts/2020-12-29--002</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2020-12-29--002</guid><pubDate>Tue, 29 Dec 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;#1. gradle version 확인&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;gradle -&gt; wrapper -&gt; gradle-wrapper.properties 안에 해당 프로젝트의 gradle 버전이 명시되어 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/53cfd7050d50b717a08c7004b88dc4a2/077b7/002-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 25.416666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAIAAADKYVtkAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAy0lEQVQY013MCWrDMBAFUN2mjWyN5GhJHCvWPg51sAhd7n+UOnYLpZ/HH4aBIbXO97mkHEspiDnjNPjsR5vc1Y5W90oZyf+E/eJckM/H7bFExDBNCTHmko/KDMd2kK3SvNMcBKMH+oPSF0pft1438lXfPpapJIfJYwopRWVOVrJBMqm7TgouYAcCOgERmAMWgKm2JXWudXkvoXgbknU4emlOHJ7Z+zk48I3goAHUZv1G9Dle3K33d3OddY+XsxdSUdrsGvo/B9rs1uM3XN4/Ix4wDLIAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/53cfd7050d50b717a08c7004b88dc4a2/d9199/002-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/53cfd7050d50b717a08c7004b88dc4a2/8ff5a/002-01.png 240w,
/devHistoryBlog/static/53cfd7050d50b717a08c7004b88dc4a2/e85cb/002-01.png 480w,
/devHistoryBlog/static/53cfd7050d50b717a08c7004b88dc4a2/d9199/002-01.png 960w,
/devHistoryBlog/static/53cfd7050d50b717a08c7004b88dc4a2/077b7/002-01.png 1166w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;#2. gradle version 변경&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;// gradlew wrapper --gradle-version {변경 할 버전 정보}
$ gradlew wrapper --gradle-version 4.5.1&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[[MariaDB] Prepared statement needs to be re-prepared]]></title><link>https://ssongey.github.io/errors/posts/2020-12-24--001</link><guid isPermaLink="false">https://ssongey.github.io/errors/posts/2020-12-24--001</guid><pubDate>Thu, 24 Dec 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;문제&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;프로젝트 실행 시 아래와 같은 에러 발생&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Cause: java.sql.BatchUpdateException: Prepared statement needs to be re-prepared&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;원인&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;로컬에 너무 많은 DB/테이블 생성으로 인한 table definition cache 부족&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;해결&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;table_definition_cache 값 변경&lt;/li&gt;
&lt;li&gt;Default 값은 400&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;변경방법1) 쿼리문 (DB 재시작 시 기본세팅으로 변경됨)&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;MariaDB [(none)]&amp;gt; SHOW VARIABLES LIKE &amp;#39;table_definition_cache%&amp;#39;;
+------------------------+-------+                              
| Variable_name          | Value |                              
+------------------------+-------+                              
| table_definition_cache | 400   |                              
+------------------------+-------+                              
1 row in set (0.001 sec)                                        
                                                                
MariaDB [(none)]&amp;gt; SET GLOBAL table_definition_cache = 600;     &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;변경방법2) my.cnf 수정&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;[mysqld]
table_definition_cache = 400&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;h4&gt;Table Definition Cache?&lt;/h4&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/3dc7c44443e52de17abae57abb369f6f/c1b63/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 40.833333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABJ0AAASdAHeZh94AAABIklEQVQoz6VQ2XKDMAzk/78xM6TNNBwGAjY+sdlKgpQ+9K2aWe8iC3mlarUW0+uFedHQZoVZV3gfsO+7oJSCnDN24kJc8ka5LHkG1+R86YpOqL5HT1C9Iu7wfH5BKYW2bTEMI7qOeJrRjAvacUY/LVLP94zm2QizmYo7f35+4PF4UJFCwwUE1txMXhY35GQHiIgv54yfKdhhSgm3201ecM4d9uWHY2SO4zzVfn39FVWmndR1jXt9F8sxRvwnZORhGLBoA+c9IjkOMWGNGT4VhK2IjtulPTHDnjqceqOpqvcAo7boaOHGGGgXMdgEEzIWv2G0xwNvrcP2S2do0pNLyNJwP/Yy24DZOITgyVmGIyTaJ2t2ytpJviCeeXfmpYZccnwDu0lvFq6+paQAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/3dc7c44443e52de17abae57abb369f6f/d9199/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/3dc7c44443e52de17abae57abb369f6f/8ff5a/001-01.png 240w,
/devHistoryBlog/static/3dc7c44443e52de17abae57abb369f6f/e85cb/001-01.png 480w,
/devHistoryBlog/static/3dc7c44443e52de17abae57abb369f6f/d9199/001-01.png 960w,
/devHistoryBlog/static/3dc7c44443e52de17abae57abb369f6f/c1b63/001-01.png 1200w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;cf) &lt;a href=&quot;https://mariadb.com/kb/en/server-system-variables/#table_definition_cache&quot;&gt;https://mariadb.com/kb/en/server-system-variables/#table_definition_cache&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[[MariaDB] 현재 status 확인 방법]]></title><link>https://ssongey.github.io/works/posts/2020-12-22--002.md</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2020-12-22--002.md</guid><pubDate>Tue, 22 Dec 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;#. mysqladmin 명령어로 상태 출력&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;// -i5 : interval 5s
$ mysqladmin -i5 status -u root -p
Enter password: 
Uptime: 10578  Threads: 1  Questions: 4809  Slow queries: 589  Opens: 1321  Flush tables: 1  Open tables: 348  Queries per second avg: 0.454

# Uptime : MySQL server 시삭된 후 현재 시간 (초 단위)
# Threads : 현제 DB 서버에 연결된 유저수
# Questions : 서버 시작후 지금까지 요청된 쿼리수
# Slow queries : mysql 설정파일에 슬로우쿼리의 쿼리시간 이상을 가진 요청수
# Opens : 서버가 시작된 후 현재까지 열렸던 테이블수
# Open tables : 현재 열려 잇는 테이블 수
# Queries per second avg : 평균 초단 쿼리수&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[[MariaDB] SlowQuery 설정 및 확인]]></title><link>https://ssongey.github.io/works/posts/2020-12-22--001.md</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2020-12-22--001.md</guid><pubDate>Tue, 22 Dec 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;Slow Query(슬로우쿼리)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Slow Query(슬로우쿼리)는 지정된 시간보다 실행하는데 오래걸리는 쿼리에 대한 log&lt;/li&gt;
&lt;li&gt;특정 작업이 오래 걸린다면 로그를 통해 원인을 파악이 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;h3&gt;#. 설정 확인&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;slow query log 설정 상태 확인&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# slow query 설정 정보
mysql&amp;gt; show global variables like &amp;#39;slow%&amp;#39;;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/c9a4118eaae557a4491e4650e3480b65/e4c9a/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 591px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 40.416666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABYlAAAWJQFJUiTwAAABT0lEQVQoz21S2ZKCMBDkS/ZSCQuIBIRwhUNRd///g3qnp7TKKvehK6mkp6enk2C9zLjezjidPMa5l/2Cvq/RCbx36H2DcWxwrHJMc4dFeNzzLLcJ5mXAIBwTfSH63iCoXQEnaNoS3Hd9JQUHWJuiqi3artI7W+xRlESmQrZIdSU3TUMVo2jg2qN0cDivo4qd10mJJBzyWLvT/T6LkCQhkpQwuqb7SDnGfCpfHVZ1rg7okm6cs+gHpw4OeaKO4mQnxeYVWaSc6D6uCrL4ejvhIln+/F4kowGruKQICZPkGsdbbHfv2IUfL6BTCpo7AteUmJZeR10Wr+6mqVPXzKyRSMaxxShnizyAlwgG4TAmnpXHDOHzyBRspYj5NfeVLzdLExbxnjmxkA34OIyD4BlX8zwyX9bLF2jFkWbYFCLUYpYv4sUZM95s3/4d94GHGPEHNrr9XMWXytgAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/c9a4118eaae557a4491e4650e3480b65/e4c9a/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/c9a4118eaae557a4491e4650e3480b65/8ff5a/001-01.png 240w,
/devHistoryBlog/static/c9a4118eaae557a4491e4650e3480b65/e85cb/001-01.png 480w,
/devHistoryBlog/static/c9a4118eaae557a4491e4650e3480b65/e4c9a/001-01.png 591w&quot;
        sizes=&quot;(max-width: 591px) 100vw, 591px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# 소요시간 확인
mysql&amp;gt; show global variables like &amp;#39;%long_query_time%&amp;#39;;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/e075030c0255aaa2bda14dffa54a6b21/2c288/001-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 684px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 26.666666666666668%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAu0lEQVQY03WQ6Q6CQAyEeRWPKKgcK+zCHlwKvv8bjW0TIxH8Mdl02v3SaTQ+WrCcN+iHgNA2oq535HdoO0u9WmpjFKzTqHRBvkNHPa59qOHpf3I5ImpsKUVgk6RNgSxPCGBRqCvSNJbBc7xfKU4OoqVHwEpAvBW/zmsodZONhjGgqnIZPJ13KyB7v35kakUgI0BNkTj6vUwlyjQPsJRg+ekD+aeIQXwnVmhrPKce82uge3qk2Tfu1oZbegNkC5wGraiZLQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/e075030c0255aaa2bda14dffa54a6b21/2c288/001-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/e075030c0255aaa2bda14dffa54a6b21/8ff5a/001-02.png 240w,
/devHistoryBlog/static/e075030c0255aaa2bda14dffa54a6b21/e85cb/001-02.png 480w,
/devHistoryBlog/static/e075030c0255aaa2bda14dffa54a6b21/2c288/001-02.png 684w&quot;
        sizes=&quot;(max-width: 684px) 100vw, 684px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# 로그파일 저장 방법 (FILE / TABLE)
mysql&amp;gt; show global variables like &amp;#39;%log_output%&amp;#39;;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/ab24097d71c08c59a8d7996770dbbcb2/6114d/001-03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 623px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 30.83333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABYlAAAWJQFJUiTwAAAA0UlEQVQY041QWw7CMAzrUXiuHSBgjz422rLBuP+RTBIBEgIkPqw0ruukVsOYMN0GnGJAyj24D10rNVN/nTKsq+RuvCT40JLWCzcMkfgOI2ljCjDlCsr5SpqYvBj1J0fiowh9qLHdFSRcotys3vDkNtu1gHtjFlBNu38YWXS9RU9gjs/WHqFJVOj5B77xWgztgb7gZCM2LfQMVb3D5ZplkDbLnwbfoPhRJjPOJeVAm7WYprPEwINMuXgZ/gNVN3vJinPj6nxNIUfarhGON/7XjHEHdK65zCJc8o8AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/ab24097d71c08c59a8d7996770dbbcb2/6114d/001-03.png&quot;
        srcset=&quot;/devHistoryBlog/static/ab24097d71c08c59a8d7996770dbbcb2/8ff5a/001-03.png 240w,
/devHistoryBlog/static/ab24097d71c08c59a8d7996770dbbcb2/e85cb/001-03.png 480w,
/devHistoryBlog/static/ab24097d71c08c59a8d7996770dbbcb2/6114d/001-03.png 623w&quot;
        sizes=&quot;(max-width: 623px) 100vw, 623px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;#. 설정 방법&lt;/h3&gt;
&lt;h4&gt;#1. my.cnf 파일 설정 및 재기동&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;파일 설정&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# 3초 이상 소요된 쿼리를 테이블에 기록
[mysqld]
slow_query_log=1
long_query_time = 3

log_output = TABLE
log_slow_queries       = /var/log/mysql/mysql-slow.log&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;재기동&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ /etc/init.d/mysqld restart&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;h4&gt;#2. 쿼리문 사용 (편하다…, 재기동시 날라간다…)&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# 해당 값(초) 이상의 로그 기록
mysql&amp;gt; set global long_query_time = 3;

# 슬로우쿼리 활성 여부 (0 = 비활성 / 1 = 활성)
mysql&amp;gt; set global slow_query_log = 1;

# 로그파일 저장 방법 변경
mysql&amp;gt; set global log_output = &amp;#39;TABLE&amp;#39;;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;h3&gt;#. 로그 확인&lt;/h3&gt;
&lt;h4&gt;#. mysql.slow_log 테이블 확인&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;mysql&amp;gt; select sleep(3);

mysql&amp;gt; select * from mysql.slow_log\G&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/4aae148b1988ba271b336ed8e2299443/c7dcc/001-04.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 641px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 65.41666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAABYlAAAWJQFJUiTwAAABoklEQVQ4y42TZ3LCQAyFfZE0bNxxwQ3jXuiTcP/TKHoiZEKAhB8aeWd3Pz/paZWuK2kYamragsoyk5wtIqqbpeQo9qmsFrJeFglHKt/D2NA8mpHrGuR6Js04HEcnBRBA276iqs7lu6qX1DJYoNmc8mVCXV/KuulOGZHyXpz4HAElaUh+YJNiWqqo6Flly4ebJpfDq3UnUdcLUYXv3X5F+8OagsAh3Xgj25lehGVrpOjGRP6w2QzUs8qGYR3n948drTc9HY8HyVkWUsgler5NpjWhqf4q0N+hYCMIHRpXrSjspbRCIF1fM3hPB1aFc9r0hS+dQIY5uRkKmomSAVhzWegVmo1NlHCO3xfvQRU09uwmegWlDjt3XdLkKm4CAUOUVS65baHQO11gw2CaYap3S7wCOq4ugO1uFENgTMxqVe1JlKFvUPswUNWe2XJdxgYzWPMsLvJYhhhgzGbKDkvfHgGi4TPf4t6d5g6vAhAYg70gdHlUrG8j/gsFqgCCyxjazXag8etZAXQu+a9RuVCIi3A6ij1+PoFkKCzYcax/gh6BfgJfwJT1wH5ERgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 04&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/4aae148b1988ba271b336ed8e2299443/c7dcc/001-04.png&quot;
        srcset=&quot;/devHistoryBlog/static/4aae148b1988ba271b336ed8e2299443/8ff5a/001-04.png 240w,
/devHistoryBlog/static/4aae148b1988ba271b336ed8e2299443/e85cb/001-04.png 480w,
/devHistoryBlog/static/4aae148b1988ba271b336ed8e2299443/c7dcc/001-04.png 641w&quot;
        sizes=&quot;(max-width: 641px) 100vw, 641px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br&gt;
&lt;h4&gt;#. /var/log/mysql/mysql-slow.log 파일 확인&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;아래와 같은 형식으로 로그파일에 기록됨&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# Query_time : 쿼리 처리시간  
# Lock_time : lock이 걸린 횟수  
# Row_sent : 조회 결과 Row 수  
# Rows_examined : 조회 대상 ROW 수  

# User@Host: DB_유저[DB_유저] @ server_hostname [서버IP]
# Query_time: 0.000599  Lock_time: 0.000163 Rows_sent: 3  Rows_examined: 86
SET timestamp=1489118717;
select count(*)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
2021.02.01. 오늘 slow query 찾아보다가 내용이 부실해서 추가함...</content:encoded></item><item><title><![CDATA[Grep AND, OR, NOT 사용 명령어]]></title><link>https://ssongey.github.io/works/posts/2020-12-20--002</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2020-12-20--002</guid><pubDate>Sun, 20 Dec 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;#1. AND&lt;/h3&gt;
&lt;h4&gt;#1.1. pipe를 이용해 여러번 사용&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;cat test.txt | grep pattern1 | grep pattern2&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;#1.2. -E 옵션 사용&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;순서가 pattern1 다음 pattern2 가 매치되는 라인 &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;$ grep -E grep &amp;quot;pattern1.*pattern2&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;순서가 상관 없으려면&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;$ grep -E grep &amp;quot;pattern1.*pattern2|pattern2.*pattern1&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;h3&gt;#2. OR&lt;/h3&gt;
&lt;h4&gt;#2.1. -e 옵션 사용&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;$ cat test.txt | grep -e pattern1 -e pattern2&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;#2.2. -E 옵션 사용&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;$ cat test.txt | grep -E &amp;quot;pattern1|pattern2&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;h3&gt;#3. NOT&lt;/h3&gt;
&lt;h4&gt;3.1. -v 옵션을 이용&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;cat test.txt | grep -v pattern1 | grep -v pattern2&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;p&gt;(사용로그)&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;$ cat log | grep -E &amp;quot;Done createContract \[[0-9]{4,5}\]&amp;quot; -B32 | grep -E &amp;quot;Request|controller| \[[7-9]{1}[0-9]{2}| \[[0-9]{4,5}\]&amp;quot;
$ cat total2.log | grep -B25 &amp;quot;Done renewContract&amp;quot; | grep -E &amp;quot; \[1[5-9]{1}[0-9]{2}| \[[2-9]{1}[0-9]{3,4}\]| \[[1-9]{1}[0-9]{4}\]| \[[7-9]{1}[0-9]{2}&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[리눅스 명령어를 이용한 시스템 모니터링하기]]></title><link>https://ssongey.github.io/works/posts/2020-12-20--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2020-12-20--001</guid><pubDate>Sun, 20 Dec 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;#1. uname: 시스템과 커널의 정보&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;$ uname -a
Linux V2G-Dev-Server 5.4.0-1034-azure #35~18.04.1-Ubuntu SMP Thu Dec 10 09:13:52 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

# [Linux] : 커널 명
# [V2G-Dev-Server] : 호스트 명
# [5.4.0-1034-azure] : 커널 릴리즈 정보
# [#35~18.04.1-Ubuntu SMP Thu Dec 10 09:13:52 UTC 2020] : 커널 버전
# [x86_64] : 머신 하드웨어 이름
# [x86_64] : 프로세서 종류
# [x86_64] : 하드웨어 플랫폼
# [GNU/Linux] : 운영체제&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;h3&gt;#2. top: 운영체제 작업 내역 모니터링&lt;/h3&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/e77a778d1624d604f10cb27d89a5eefc/d7542/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 810px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 86.66666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAYAAADdRIy+AAAACXBIWXMAABJ0AAASdAHeZh94AAACmklEQVQ4y22UWVPbUAyF/VO6zECA7E7sLN4SO4HQJZAEmJZ22iEQSKBM+/8fVH1yTDMdHjS+vro6OjrSvU6v70kQdmSYRtLttqTTce2/12+Lr+so7km311Jry2AYCudZR3FX/U1pNMtSqZakXNlXK4kzPh7agTSLJU56BhBGXclGiVos2XigyUJJ9Z8voINBYASC0LfzHSUCYLV2IA5sPL8htcaRMswZ1euH0nSrEilw22voumLB/cCTVrsux5PUKugHvrHcL72Tvf23Zs7N8oes1yuzh/WdbDb38ut5I3erG9t7fHyQla5X90vbw37/ebazrJe3P+Xpaf1izvnss1xcnqvNZDo9lY+fJnJ9fSWXV3P5qt/54ky+ff8ipx9GMptP1X8ii4szs/liatKMMJUGc9ArTvrWCLdVFVdLSlWfRPfQidL4IgNnkQcZKB9Jjsp7WuobKxtz0Gw0TgwQPXwVmKw062SSWTLWvgJxljNF42hkR3Wvq/4Y3XbIRDdh12rXjEGsAXQTpnQehm31FQwBxLJRPgHEMj502iky0Uk6mM9eV5JBqBYYg2Eai+fVJVQQAEP1kwzN0kxl0bGDjAEyQ4NhsAPYzFkxb7rPIMPQgLYMkYdkVIHW6AwgeuYMNYDSAfP8pgUwvJTFYSrYBcyrigww0Fk8OHxvYKZhAUgg3QMQcADjbXYCreQtIAOd2G3JAdGPpljJsAGQDbdVM8CinOJ2WFMMsLdTct+Y57en9q8pZCMTARgB6IY2+F5juKthUQU9eAHEkW2z7ZYURh3bMw3/A6Rh9lBsm4f+1hSEJ6B4JHAQCMOiKclrDNXPPiPmKjteGmNI0ERvRP7u6Ruoc1cMc6Gj3RRuiIIwl3y5DPhJwhtavIl/AYIFRncOvUqRAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/e77a778d1624d604f10cb27d89a5eefc/d7542/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/e77a778d1624d604f10cb27d89a5eefc/8ff5a/001-01.png 240w,
/devHistoryBlog/static/e77a778d1624d604f10cb27d89a5eefc/e85cb/001-01.png 480w,
/devHistoryBlog/static/e77a778d1624d604f10cb27d89a5eefc/d7542/001-01.png 810w&quot;
        sizes=&quot;(max-width: 810px) 100vw, 810px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h4&gt;#2.1. CPU&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;User값이 높다면, 사용자 코드를 수행하는데 시간이 오래 걸린다면 내부적으로 계산을 많이 하고 있다는 것 &lt;/li&gt;
&lt;li&gt;System값이 높다면, 시스템에 의해 사용되고 있는 시간이 오래 걸린다면 프로세스들이 시스템 호출 또는 I/O가 많다고 할 수 있음 &lt;/li&gt;
&lt;li&gt;idle의 값이 항상 0이라면 CPU를 100% 사용하고 있다는 것을 의미&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;[us] : 사용자가 사용중인 사용률
[sy] : 시스템이 사용중인 사용률
[ni] : 프로세스 우선순위를 기반으로 사용되는 사용률(사용자 공간에서 사용됨)
[id] : 아무 일도 하지 않는 여유률
[wa] : 입출력을 기다리는 프로세스 사용률
[hi] : 하드웨어 인터럽트 사용률
[si] : 소프트웨어 인터럽트 사용률
[st] : 가상화 환경에서 손실률&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;h4&gt;#2.2. PROCESS&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;[PID] : 프로세스 ID
[USER] : 프로세스를 실행시킨 사용자 ID
[PR] : 프로세스의 우선순위
[NI] : NICE 값, 마이너스를 가지는 값이 우선순위가 높음
[VIRT] : 가상 메모리의 사용량(SWAP+RES)
[RES] : 현재 페이지가 상주하고 있는 크기
[SHR] : 가상 메모리 중 사용중인 메모리를 제외한 잔여 가상 메모리
[S] : 프로세스의 상태
[%CPU] : 프로세스가 사용하는 CPU의 사용률
[%MEM] : 프로세스가 사용하는 메모리의 사용률
[TIME+] : 프로세스가 CPU를 사용한 시간
[COMMAND] : 실행된 명령어&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;h4&gt;#2.3. 프로세스의 정렬 방법&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;[SHIFT + M] : 메모리 사용률 정렬
[SHIFT + N] : PID 기준 정렬
[SHIFT + P] : CPU 사용률 정렬
[SHIFT + T] : 실행시간 기준 정렬
[SHIFT + R] : 정렬 기준변경 (오름차순인 경우 내림차순으로, 내림차순인 경우 오름차순으로 변경)

[u] : 사용자 명 입력 시 해당 사용자의 프로세스만 표시

[1] : CPU Core 개수 만큼 표시&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;h3&gt;#3. free&lt;/h3&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/73cd2a356a713f3ee226b98bc619c1be/cab8c/001-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 744px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 12.083333333333332%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAACCAYAAABYBvyLAAAACXBIWXMAABJ0AAASdAHeZh94AAAAcElEQVQI1x2Oaw7DMAiDe5luXTLyThqolN3/VB7hB7JB1oePPhLGnTG5Qp6O9RPUFvRWsBYjJodcCPes8N+X5fa0nsDSVaPl5RmmB0tDyh7OnwjRKZBB9FaQN78hpQZ7tDO7wFQ4hUt9tp3ixwps4B8hdD/LLMaJYQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/73cd2a356a713f3ee226b98bc619c1be/cab8c/001-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/73cd2a356a713f3ee226b98bc619c1be/8ff5a/001-02.png 240w,
/devHistoryBlog/static/73cd2a356a713f3ee226b98bc619c1be/e85cb/001-02.png 480w,
/devHistoryBlog/static/73cd2a356a713f3ee226b98bc619c1be/cab8c/001-02.png 744w&quot;
        sizes=&quot;(max-width: 744px) 100vw, 744px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;[total] : 설치된 총 메모리 크기 / 설정된 스왑 총 크기
[used] : total에서 free, buff/cache를 뺀 사용중인 메모리. / 사용중인 스왑 크기
[free] : total에서 used와 buff/cahce를 뺀 실제 사용 가능한 여유 있는 메모리량 / 사용되지 않은 스왑 크기
[shared] : tmpfs(메모리 파일 시스템), ramfs 등으로 사용되는 메모리. 여러 프로세스에서 사용할 수 있는 공유 메모리
[buffers] : 커널 버퍼로 사용중인 메모리
[cache] : 페이지 캐시와 slab으로 사용중인 메모리
[buff/cache] : 버퍼와 캐시를 더한 사용중인 메모리
[available] : swapping 없이 새로운 프로세스에서 할당 가능한 메모리의 예상 크기. (예전의 -/+ buffers/cache이 사라지고 새로 생긴 컬럼)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;참고) &lt;a href=&quot;https://www.whatap.io/ko/blog/37/&quot;&gt;https://www.whatap.io/ko/blog/37/&lt;/a&gt;&lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;#4. vmstat: 시스템 정보 모니터링&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;시스템 작업, 메모리, 페이징, 블록장치의 I/O, CPU상태 등을 확인&lt;/li&gt;
&lt;li&gt;vmstat [delay [count]]를 사용하면 실시간으로 상태 확인 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/f06f8b5b17cef1388d3a548d4524408f/5e3a3/001-03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 763px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 12.916666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAABJ0AAASdAHeZh94AAAAmklEQVQI1yWOWRLCMAxDexcoJfvSJF1goLQzcP8TCdv90ER2kid1Pmj4oGDsDdM8opQA5++wboA2PXmF2iLu6iL7EDWUviJlizYl+XfODjEZdFr3AmTwTMDaEvLoRGPxsm9TlgCGhWjkzHRXahQIa14KFlK3rBXH8cL3t2P7PLGTf2+P88FaJJ1h0pjCeQ4Uwu3ZGztIKBfg1n/TAF1vgdDDJgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/f06f8b5b17cef1388d3a548d4524408f/5e3a3/001-03.png&quot;
        srcset=&quot;/devHistoryBlog/static/f06f8b5b17cef1388d3a548d4524408f/8ff5a/001-03.png 240w,
/devHistoryBlog/static/f06f8b5b17cef1388d3a548d4524408f/e85cb/001-03.png 480w,
/devHistoryBlog/static/f06f8b5b17cef1388d3a548d4524408f/5e3a3/001-03.png 763w&quot;
        sizes=&quot;(max-width: 763px) 100vw, 763px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h4&gt;#4.1. procs&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;[r] : CPU에서 대기중인 프로세스의 수를 의미, r의 개수가 CPU의 개수의 2배를 넘는다면 CPU의 성능을 올려줘야 함&lt;/li&gt;
&lt;li&gt;[b] : 인터럽트가 불가능한 sleep 상태에 있는 프로세스의 수 (I/O 처리를 하는 동안 블록 처리된 프로세스), b의 수치가 높은 경우라면 CPU가 계속 대기상태로 있다는 의미이므로 디스크 I/O를 확인해 볼 필요가 있다&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;h3&gt;#5. iostat: CPU, 디스크 입출력 상태 모니터링&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;평균 CPU부하 와 디스크 I/O의 세부적인 내용을 확인&lt;/li&gt;
&lt;li&gt;iostat [delay [count]]를 사용하면 실시간으로 상태 확인 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/7c15d14f463f1b5977e3b45ae7a9f9dc/ef6b9/001-04.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 832px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 26.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAABJ0AAASdAHeZh94AAAA5UlEQVQY01VQWXKFMAzjMC0lkMXZSVg6r/e/k56gy/R9aGTHtmRn2PaK42x4fO3kFftRse0F52dD7wneL1j0O0I0qMyFubETGuOYLGsjArlUf78PuQibNdKaEbJHLBGZcW4Fa69INd2ISXCuCdp8/OESML/8gyGx0YmCFkNoSLBw0d0GEi3hkYqHsNaISPOrP5GtUy8GF4btsVCEBZ6lHc+pncMKgVuZ0hhP8G2DjhE2B0g/YKPAk423FBlfN5T89r3+5UBBFXgW/2V2BirW20iJxywOsxdMuWOx8923iOXcCP1P8AmZmJxU+sHKAQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 04&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/7c15d14f463f1b5977e3b45ae7a9f9dc/ef6b9/001-04.png&quot;
        srcset=&quot;/devHistoryBlog/static/7c15d14f463f1b5977e3b45ae7a9f9dc/8ff5a/001-04.png 240w,
/devHistoryBlog/static/7c15d14f463f1b5977e3b45ae7a9f9dc/e85cb/001-04.png 480w,
/devHistoryBlog/static/7c15d14f463f1b5977e3b45ae7a9f9dc/ef6b9/001-04.png 832w&quot;
        sizes=&quot;(max-width: 832px) 100vw, 832px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h4&gt;#5.1. Device&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;[tps] : 디바이스에 초당 전송 요청 건수
[kB_read/s] : 디바이스에서 초당 읽은 데이터 블록 단위
[kB_wrtn/s] : 디바이스에서 초당 쓴 데이터 블록 단위
[kB_read] : 디바이스에서 지정한 간격 동안 읽은 블록 수
[kB_wrtn] : 디바이스에서 지정한 간격 동안 쓴 전체 블록 수&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;h3&gt;#6. df: 디스크 모니터링&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;파일시스템 별 전체공간, 사용중인 공간, 여유 공간 표시&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;h3&gt;#7. du: 디렉토리 용량&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;특정 파일이나 디렉토리 용량 확인&lt;/li&gt;
&lt;li&gt;du -s [파일이나 디렉토리] 를 사용하면 해당 파일이나 디렉토리 용량 확인(-s만 적을 경우 현재 디렉토리) &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/5b3e4335a12c338a628ada3e7ae7638f/b23ad/001-05.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 519px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 44.583333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAABJ0AAASdAHeZh94AAABIElEQVQoz5VS2W6DQAzkR9q0hPsMZLkhgFL6/3803XEEQrRC6oM13t3x2GMwxqlHVee4qwRllSPLI4lbFiK/J0hSH+ktkJyYpAHixINlX2A7Hxs67idcz4QxzcMmpIpUiihG5B2LKcqcyHMQ2oIM8oiefxVR4/k1om4UijLDskzo+lIXx3qiWBpwIp7LKhNRClCQbwzWquIGP7BegsOjQa6J5vUN/VChaZV0o5XVju3s85e99d2y3wU3y8v3rEd29eGKx9himnuZwHFNIfwnZEKK0J6lO7ddCaVS6bgnHYvOcqMbam05Fiu0z31wVyQcxf5qcAxjfj4Qxa4Qu77COHYy6brLVWDf4EzUoEiqfweSwsiVr0WhMHJ+Fb92ez7hDyIrDh6iu2SSAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 05&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/5b3e4335a12c338a628ada3e7ae7638f/b23ad/001-05.png&quot;
        srcset=&quot;/devHistoryBlog/static/5b3e4335a12c338a628ada3e7ae7638f/8ff5a/001-05.png 240w,
/devHistoryBlog/static/5b3e4335a12c338a628ada3e7ae7638f/e85cb/001-05.png 480w,
/devHistoryBlog/static/5b3e4335a12c338a628ada3e7ae7638f/b23ad/001-05.png 519w&quot;
        sizes=&quot;(max-width: 519px) 100vw, 519px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;</content:encoded></item><item><title><![CDATA[[작업로그] Jenkins/Bitbucket 연동]]></title><link>https://ssongey.github.io/works/posts/2020-12-15--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2020-12-15--001</guid><pubDate>Tue, 15 Dec 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Jenkins/Bitbucket 연동&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;이번에 JIRA를 사용하면서 Bitbucket을 사용하게 되었다.
이에 따라 Jenkins/Github 에서 Jenkins/Bitbucket 으로 변경하는 작업을 하였다. &lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;#1. Jenkins에 Bitbucket 플러그인 설치&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Jenkins 관리 -&gt; 플러그인 관리&lt;/li&gt;
&lt;li&gt;Bitbucket 설치&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/28f8c7d0444a57476faeebd0a27468f4/25be5/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 44.583333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAABYlAAAWJQFJUiTwAAABQ0lEQVQoz5WRy26DMBBF+c1mQ1btBviB/EWkflqkLNi1TYFAeBgbjG1uPdM6jcSmtXQ0PMaH4TrKshRpluFpt0Mcx9jv90y4juPf653vORwOOJ1OOJ/PyPMcr8cjkucXpGmKJEkQSalgFov/LK01M8/z5l006wXGWDjnsK4rhBCoqhpt16OuG4xSgj46TZNn9hLN/cYYhsX+edu2GMcR0bd3ZRmtZVlQlgUulw80TYVhaJlR9H7DwEhCCqgHaBAWkihAyzmLaSwhujfPO5T49PdE4aUllK+zLKCnK4xuYOba1xsPQvCEj0JtHJpOohfK/475c64UCWW6ETq3ousH3NqOGwhqVkrdMWbx/Y5zD9mHTDdCqnQgV38gtFkvmn+FajhdEtJma81Ptfe6EVrrUN86FFXjgx5ZSkJ6H6YJkz0SMvwCCZeihXnwY9cAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/28f8c7d0444a57476faeebd0a27468f4/d9199/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/28f8c7d0444a57476faeebd0a27468f4/8ff5a/001-01.png 240w,
/devHistoryBlog/static/28f8c7d0444a57476faeebd0a27468f4/e85cb/001-01.png 480w,
/devHistoryBlog/static/28f8c7d0444a57476faeebd0a27468f4/d9199/001-01.png 960w,
/devHistoryBlog/static/28f8c7d0444a57476faeebd0a27468f4/07a9c/001-01.png 1440w,
/devHistoryBlog/static/28f8c7d0444a57476faeebd0a27468f4/25be5/001-01.png 1893w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h3&gt;#2. Jenkins Item 구성&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;프로젝트 -&gt; 구성 -&gt; 소스 코드 관리 및 빌드 유발 수정&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/0a2bc141922315315b9fc8bebe58d443/61100/001-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 64.99999999999999%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAABYlAAAWJQFJUiTwAAABKUlEQVQ4y6WT226DMBBE+f/fpAKM8f0KRdru4FBFaZU09OFokW3G4/W4s9aS1ppKKbRtG63reomN+dxW6rRxFGKkWuvLn7DmGYXpjLEEl957mqaJ5nkmY8wBnKMq1WrkjR8JIVBOkYQyNGlPHQYw4ZyjYRhICEHLsnwjGcGb4Fsp9SsLqjYszoIQwu5weS+EhafTe8c/4HE5SxJ9Tz5E6nBUiAK4G8fxODoEMYcTPMMD/nfsP8j4QN3pDLtBNKV0cPbnLxyivF45FoSQ5B7BDSZyzm+DyCWuIeUmCLF93zmHiEd9GY9H1lsNmWOjcJNSNofcgzOPbwnyemTQxoJgtx6il+gH7F9xmEul0fKRJQLJtwpRuPzPE0yZHTrbXgpuFbd79S3n2hx+AUw96iw5ny3tAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/0a2bc141922315315b9fc8bebe58d443/d9199/001-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/0a2bc141922315315b9fc8bebe58d443/8ff5a/001-02.png 240w,
/devHistoryBlog/static/0a2bc141922315315b9fc8bebe58d443/e85cb/001-02.png 480w,
/devHistoryBlog/static/0a2bc141922315315b9fc8bebe58d443/d9199/001-02.png 960w,
/devHistoryBlog/static/0a2bc141922315315b9fc8bebe58d443/07a9c/001-02.png 1440w,
/devHistoryBlog/static/0a2bc141922315315b9fc8bebe58d443/29114/001-02.png 1920w,
/devHistoryBlog/static/0a2bc141922315315b9fc8bebe58d443/61100/001-02.png 1949w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Repository URL&lt;br&gt;
— git clone 주소 &lt;/li&gt;
&lt;li&gt;Credentials&lt;br&gt;
— Add 누른 후 bitbucket 계정 및 패스워드 입력&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/4d6918891dbb1df70add0197117aee37/e751c/001-03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 56.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABYlAAAWJQFJUiTwAAABPUlEQVQoz6WR2VLCMBSG8/4vZK1A1TpY0NtqN2XoEge6LzADvfjNSYmjjoKMF98kTXq+nIU9PFqwZlNMJoZggum9hdF4DF3XoV3qMM07XI3GMIxrzOZzaBcabm5NhGGEMIoFah1gT44N+9mG7wfwPB+u52GxWCCKYyyXIeI4GYKkIMIyDOXK+duPsODlFY7jIAgCuK4L27aFJEbTNNhsNpLtlth+Qd19h/GEI01T5HmO9Xot90Rd19jv9+j7XjCs9L3b7Y7CiqKQwSQryxJZlkk5vUZZKugfOjslZW3bohUBSZKA5CRbrVbygaqqQPdKSKWeFNaHDCLRaBoEiTnnUkznXdd9oOTHYPSyKpkypJJVZuruHBhZKZiyysQw/tr8X0vORVaFGIacshA21NN/wKpaNLxpJbQn4ee+ncs7OSo+pxVvAP4AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/4d6918891dbb1df70add0197117aee37/d9199/001-03.png&quot;
        srcset=&quot;/devHistoryBlog/static/4d6918891dbb1df70add0197117aee37/8ff5a/001-03.png 240w,
/devHistoryBlog/static/4d6918891dbb1df70add0197117aee37/e85cb/001-03.png 480w,
/devHistoryBlog/static/4d6918891dbb1df70add0197117aee37/d9199/001-03.png 960w,
/devHistoryBlog/static/4d6918891dbb1df70add0197117aee37/e751c/001-03.png 1123w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Build 에 Execute Shell 내용 추가&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/d7630d4ec06ed4681a88476b12fd6025/e332b/001-04.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 26.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAjElEQVQY053Q7QrDIAwFUN//Rddav7UatXAXLR1jY1D24xBDopgIpRSstcg5/68U7MHDaQMhpcTyWBBjAlFB721qraHWesvopZSgVwmR+DDEtLOMtJcZC1V+uL+MS+/5l+Pgn2aIEAK899iUhtxOKzPG4qrdYZ3jGCCMdbxDN8c9R6CJiFB4N5fP/JcnN1WDB/nMvdgAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 04&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/d7630d4ec06ed4681a88476b12fd6025/d9199/001-04.png&quot;
        srcset=&quot;/devHistoryBlog/static/d7630d4ec06ed4681a88476b12fd6025/8ff5a/001-04.png 240w,
/devHistoryBlog/static/d7630d4ec06ed4681a88476b12fd6025/e85cb/001-04.png 480w,
/devHistoryBlog/static/d7630d4ec06ed4681a88476b12fd6025/d9199/001-04.png 960w,
/devHistoryBlog/static/d7630d4ec06ed4681a88476b12fd6025/07a9c/001-04.png 1440w,
/devHistoryBlog/static/d7630d4ec06ed4681a88476b12fd6025/29114/001-04.png 1920w,
/devHistoryBlog/static/d7630d4ec06ed4681a88476b12fd6025/e332b/001-04.png 1929w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h3&gt;#3. Bitbucket Webhook 설정&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Repository 선택 후, Repository settings -&gt; Webhooks 에 들어가면 webhook 설정을 할 수 있다&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/39a93592d0b4bccbd86952ef9f5fe9d6/0fcea/001-05.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 851px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAABYlAAAWJQFJUiTwAAACdUlEQVQ4y5VUt44UQRScPyMj5AtIiEEiRpiID+ADSAmQCIghRJdwwkQkcGZvdrxpM94W9Xr29i5AJ9Gjpx7TW11Vr3q93bMX2H34iMi2CMIUpbaomw4Na54XaGNhq5rvWvT9gGVZIGNd13+W5z9/Cf/de4S2wX6foFQWTds7wGEccbHb43wXYB8mbkNt67sBVWlQFoYLG1iWNjWUrhygsNGmQqEMilJKk22Du4YXZhaXocLZVY400ygInuUaVd26BQt33cbqrmVdMEzTZguVtN2wKXL3PRlSYkkGaV46NsJMwFouEAnDOCHivW4nDP2MYZix0tswzmhDiiDKcOlHnFMkWQkvJZuccrJik1MfAGVHGZY+Pvms8OqkwJtvGm9/WpzrDjkJXAUJoiR3JYA7P4aXZApxWh5LwG4Dqm7C008l7p38xoPTCzz6eYUvtMkUCiGBhGmSFQfgAl5eiNwN9DoyN4ArqnbG4+8B7n89w0OCvf6TwA6j8zpMlZMdEigmMT92kpVrgkiW7t5meO2h7sdjNcOEiU3xY41dpBAQRFUjSpauJ3ib1MLRFfni4xGQ1zyzCYyPNGKeZoLNGFkS8n4Y0HGWdxIxWeuJsdKpLdDdUbJEQBbkZYWc3wxPi2EKLIMt4ZbTI+vkuSIJYyso5tgTD4RlTsm3PRTAZVlR2oE+Tk6+sNjm7f5m3tjNnL1rqWJqxvg09Klyoe1clyWjCS0Rj8XPqm54cqyTKp5bbi7vxQYh40mHQrKMGM54HyNhmcMPxBtDST27KudamMg7AZA/jnGc3LMwmw/fPMWzqxlSsw9hggjaD2DYedlRzu/pj1/4n/EXR2h4AqpZxiEAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 05&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/39a93592d0b4bccbd86952ef9f5fe9d6/0fcea/001-05.png&quot;
        srcset=&quot;/devHistoryBlog/static/39a93592d0b4bccbd86952ef9f5fe9d6/8ff5a/001-05.png 240w,
/devHistoryBlog/static/39a93592d0b4bccbd86952ef9f5fe9d6/e85cb/001-05.png 480w,
/devHistoryBlog/static/39a93592d0b4bccbd86952ef9f5fe9d6/0fcea/001-05.png 851w&quot;
        sizes=&quot;(max-width: 851px) 100vw, 851px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/dccd55dcb806a231fe9a3c1e102d381a/6dd26/001-06.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 45.416666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAABYlAAAWJQFJUiTwAAABdklEQVQoz4VSW27EIBDL/S9UtWfoRy9QqVK1eUB4QwIkWXeGZFdqf4rk8Ajy2B664eUNUllYH5FzxWOsOWNZM47jaNh3xo7/RtcLDR8SYlqJpAD3e/uhZgElBVJKcM7Be48QApwPiDFiWZZfSGnBtm3oxGyaQucTrHWk5iT8+BR4ff+CsgGlZFJPKAW57ucdKny/cI5z7pRxmC/LWpvnhe/J4LO32PZzz0pZQa2FChTsFAOPUmtTXbeD7h7oZm2htEOIC5TST8KaV/oetKcM6cwYg2maMBJ4Vkq1s0hWZ5swTDOs8+jYrjK+5eip0oOQ8zLWNmXcDEvrcRwhhISUkkhF24eYoP1KhQRlbckyKZSUoyeFmZtyZcFNSBR2S+dSOAxjUyiEwMSgNStUbkE/Tq1odxs1ydWkJtAzWZ/tZ4Ur7VkdE7LFvu8bhmG40Ddn0iTc+pGKarbsyXukYCMR5CdhIbVslxvAhEzOz+UvuClprc06v4QfUKC2ciPk+yAAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 06&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/dccd55dcb806a231fe9a3c1e102d381a/d9199/001-06.png&quot;
        srcset=&quot;/devHistoryBlog/static/dccd55dcb806a231fe9a3c1e102d381a/8ff5a/001-06.png 240w,
/devHistoryBlog/static/dccd55dcb806a231fe9a3c1e102d381a/e85cb/001-06.png 480w,
/devHistoryBlog/static/dccd55dcb806a231fe9a3c1e102d381a/d9199/001-06.png 960w,
/devHistoryBlog/static/dccd55dcb806a231fe9a3c1e102d381a/07a9c/001-06.png 1440w,
/devHistoryBlog/static/dccd55dcb806a231fe9a3c1e102d381a/6dd26/001-06.png 1597w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Webhook 을 추가하여 아래와 같이 입력한다.
— URL : &lt;a href=&quot;http://%7Bjenkins_host%7D/bitbucket-hook&quot;&gt;http://{jenkins_host}/bitbucket-hook&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/e41e1197e413cce9490629e489b9dfe1/d67ca/001-07.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 714px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 82.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAYAAADdRIy+AAAACXBIWXMAABYlAAAWJQFJUiTwAAACFElEQVQ4y5VUyY7bMAzN/6OnfsAc+gM99NTD/ETRAEmRZaZJ7XiRJcuLLG+vJDtxPEkatAIIepEeH8lHLV4DhWOk4ZxH23o0TYOu68BrHMd/svNeXovXnweEpwhRFCEMQhwOR2it8T/rDCaAaZJAZRkS8jFZlil6ThGdTvItTVPxCXmlUsQqR6wrhGkBbd27TARwGAb0fQ/23nuxxjnUdS3f5zYM5Hm/nBnofbwFnFNvmj9AzCgkhlzPc5BrG8fhJl0BnKPzxtxovOw22O9fsN/tsN1ssF7/wHK5xGq1wnq1xna7QVVVN42bAHlxymVhkZga66OhGgYo6RAfLMvyxuZKuGF4Xs7VsHWHo3LENINvW6rXpYYM0r4B3ZPVu5SZCdes9Q2qwiBVSjrNclL0/CsIYIyRII/kMzWF6ycM6EBRFAKiMy2yYaA4TiRVZupIBWKNR+Va1E17Ydj3HQFY6S4DMbC1hXRaayOAzNZQs1izrFFmyYHbjsDbnt77C0OOyJEZkKPy+FVFLkA8McyUQdSbwOM4nvay91Qiltu5SVPKDGxtTvSpKUlJgDw1mYDyYY4+sJEappTJZBBm8z91mT9Ya4V+UTXQSYBTGEpTeBxz+id1fTDnU1Pm0impyJ+eV3j6+h1hYpCZYkqPa8z26NZZXF8/eeXx4fM3fPyyhC49nO/vMrkW9CTsv11D9wCuge7t/w1fhipfrG1UjAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 07&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/e41e1197e413cce9490629e489b9dfe1/d67ca/001-07.png&quot;
        srcset=&quot;/devHistoryBlog/static/e41e1197e413cce9490629e489b9dfe1/8ff5a/001-07.png 240w,
/devHistoryBlog/static/e41e1197e413cce9490629e489b9dfe1/e85cb/001-07.png 480w,
/devHistoryBlog/static/e41e1197e413cce9490629e489b9dfe1/d67ca/001-07.png 714w&quot;
        sizes=&quot;(max-width: 714px) 100vw, 714px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Webhook History&lt;br&gt;
— Enable History 버튼을 클릭하면 아래 그림과 같이 해당 Webhook에 대한 History 내역을 볼 수 있다.&lt;br&gt;
— Webhook 추가시에 URL을 bitbucket-webhook으로 잘못적어 403 에러가 계속 났었다.. 404 에러로 좀 해주지…&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/a0a6bad0f7c04756414d2d1baf14418d/e35ec/001-08.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 861px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 98.75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAABYlAAAWJQFJUiTwAAACf0lEQVQ4y32U63KbMBCFef8X6K++QR+gL9Bp3f6IHdpJZ5J0cjE2FwnE1RiET3cXFHyJw8yOEEhH356V5AWbEM8vAcIwxHazkbbrOgzD8G5Ya0/a8/ByY6CUQpzEiKMYURQhjmMkSQKdptJypPTO4+S71hKKQ77F0nJ4/GO73QoZR1VVaJoGu91ubCmaukbb7uRbXTcyZnyv6b2UflmOrVcUhZAlE5WjybJMKGR1TaQ6Q6JS5DT+cDjg2uO5iSyiaSKnGxEp4/N3XrAkqrxqqW3FJxa8Fl4QjAXJSLAs51Q4NX6/9lyj9IL1Gk9PT2DhDXnJZNb2JxPPAwdcJ8zzXCrLlJyiS+mj54APPBT/slREhsGCtXiPrYm8qmoZJHvMDmj7PUV7QshPGEZURDMKOkK3mVmMg4vE1Lu2lX+5Nvj5fINfrzcysSdbeBGeo02FTVJg3/XweB8xZd/3E+VBBvFC7Od+v5fJlSmxeF1isb0VQSvZjJSm3CFOK9Kwl4RjelYWcYS8wROlETze4d/XL+hpqw1sxXT8tKlnwpIIlVYT4XwmzXQkmbCmE6CoX93dIfr8CW0USlmcoCPsHOH5hcAe8olhcun3HRSZnv3xUd3/FTFLAG68IsIgzt/3kIMF3QkaBXsYojT+CqV/M1X+zMPMeVhcesjiigj5GFqqZE//lMmR+UsUv5cjoZ0JdX7sId0S7NVc5eFt28yEHVIaV96u0NwuT/y78FBuGyJhwmNBPd193O+6PVmQ4+Xep0r747Y5EmTCrSouBY9THq+uWdBQyg8PKzw+Li8Es6JBqEsa57bNUcquKG8pU589TOkY5ovvqH58G4tiT4sSTRv7P6JZCMHKyuoQAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 08&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/a0a6bad0f7c04756414d2d1baf14418d/e35ec/001-08.png&quot;
        srcset=&quot;/devHistoryBlog/static/a0a6bad0f7c04756414d2d1baf14418d/8ff5a/001-08.png 240w,
/devHistoryBlog/static/a0a6bad0f7c04756414d2d1baf14418d/e85cb/001-08.png 480w,
/devHistoryBlog/static/a0a6bad0f7c04756414d2d1baf14418d/e35ec/001-08.png 861w&quot;
        sizes=&quot;(max-width: 861px) 100vw, 861px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;</content:encoded></item><item><title><![CDATA[[작업로그] Jenkins Timezone 변경]]></title><link>https://ssongey.github.io/works/posts/2020-12-15--002</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2020-12-15--002</guid><pubDate>Tue, 15 Dec 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;[작업로그] Jenkins Timezone 변경&lt;/h2&gt;
&lt;p&gt;jenkins 실행 파일에 아래 option을 추가하라는 가이드가 많았다. &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token assign-left variable&quot;&gt;JENKINS_JAVA_OPTIONS&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;-Dorg.apache.commons.jelly.tags.fmt.timeZone=Asia/Seoul&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;p&gt;jenkins 실행파일을 보니 java 옵션으로 줘도 괜찮겠다 싶어서 아래 처럼 진행하였다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;실행파일 위치 : /etc/init.d/jenkins&lt;/li&gt;
&lt;li&gt;do_start 함수 안에 java 명령어에 ‘-Duser.timezone=Asia/Seoul’ 옵션 추가&lt;/li&gt;
&lt;li&gt;jenkins 재시작&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/45e1ff8f71978a000439a17c234e5d45/fbfd6/002-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 51.25000000000001%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABJ0AAASdAHeZh94AAABcklEQVQoz32SW27dMAxEvZYWTWyLot6P2DdJEWT/W5qO7MToTZF+DGhY1PCI5KQlQKPHoorVGoijooMEg9WtWOzCs+U+2hmP849L8/ITRh4OTWWvKNsGrRtCTsi9wWUP52eIfTySRvyqT4Ov55N0mr2+wb+9I91u6K/PiD1ASGO9gSXl0Ei2Qzr/V1PeO8rzjkzS2BJCVPjiT8rsjqjUMJdvaO8Ih2F92dBedgQSmkrjmqCtUaNIRiJxqqepBjlI5INW7L2m2CLCvkH23wg1oHYPPyg5GJ/8QayMwv7a8c1hWbZDvnn+lLIgN16oHbY2GgmUlZSXHBPc6CUnb7yyr4Pi4Z5OT12GIStczYdZbqQKK03Ww9A4gRm9Ye+s/LrMrgH9pauHnnvoeqXaMZT8lBFzgKfs8UzHPT2frcmdA3LLRfYPoesdfr/BbTeUUrDFhKfIZaeZyQWSIhd99DDze/xjkTAW38Mwz0SeB0VMBo6F/gBx6jTd1asdcwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/45e1ff8f71978a000439a17c234e5d45/d9199/002-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/45e1ff8f71978a000439a17c234e5d45/8ff5a/002-01.png 240w,
/devHistoryBlog/static/45e1ff8f71978a000439a17c234e5d45/e85cb/002-01.png 480w,
/devHistoryBlog/static/45e1ff8f71978a000439a17c234e5d45/d9199/002-01.png 960w,
/devHistoryBlog/static/45e1ff8f71978a000439a17c234e5d45/fbfd6/002-01.png 1357w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shellscript&quot;&gt;&lt;pre class=&quot;language-shellscript&quot;&gt;&lt;code class=&quot;language-shellscript&quot;&gt;// jenkins 재시작
$ /etc/init.d/jenkins restart&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h5&gt;참고로 -D 옵션은 아래와 같다&lt;/h5&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/fba7da07c29b9431aca841d0b9dcf8f9/48c0e/002-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 440px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 13.333333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAABJ0AAASdAHeZh94AAAAn0lEQVQI101OSQ6DMBDjKRVbNhICWQphiaj6/y+5yZx6sDSe8dhuJiOQjog7J1zXBucNtt3juhNS8pBqhJpGcNFByL7wgfDPteGkE3JAw0VPD7OVmDSj2cyiQJLhbBV04SFanCUwxAXvzeE4I91XpzGMLzDeYWQtmppQBekIpZmDXRR8sNiL+PPNyHmn9s9z0r4GVM3qDJWo7RhvybDiB/dFXWhNX9+XAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/fba7da07c29b9431aca841d0b9dcf8f9/48c0e/002-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/fba7da07c29b9431aca841d0b9dcf8f9/8ff5a/002-02.png 240w,
/devHistoryBlog/static/fba7da07c29b9431aca841d0b9dcf8f9/48c0e/002-02.png 440w&quot;
        sizes=&quot;(max-width: 440px) 100vw, 440px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
     &lt;/p&gt;
&lt;h4&gt;jenkins 시스템 설정 정보 보는 방법&lt;/h4&gt;
&lt;p&gt;&lt;a href=&quot;http://%7Bjenkins_host%7D/systemInfo&quot;&gt;http://{jenkins_host}/systemInfo&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[grep - Binary file (standard input) matches]]></title><link>https://ssongey.github.io/errors/posts/2020-12-14--001</link><guid isPermaLink="false">https://ssongey.github.io/errors/posts/2020-12-14--001</guid><pubDate>Mon, 14 Dec 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;문제&lt;/h3&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/1dbdc78a582b310f98bc5b9a5b7b4af3/6da96/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 922px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 8.75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAACCAYAAABYBvyLAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAeklEQVQI1y2MWw6DMAwEuUsfFAKCAKGA1KDGhAS4/3m2sdUPa2dW8mbx8PD7F7StcGRh1wUfO8E5C/p7PzQYTAMzttBdnVILV3UuPr47THOPVitkIW4IkXCcHjExj/L4HgjXFTAvBq/iJs+qeqJUj5S5OPdFeZeej/kHGOxBjjNkT78AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/1dbdc78a582b310f98bc5b9a5b7b4af3/6da96/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/1dbdc78a582b310f98bc5b9a5b7b4af3/8ff5a/001-01.png 240w,
/devHistoryBlog/static/1dbdc78a582b310f98bc5b9a5b7b4af3/e85cb/001-01.png 480w,
/devHistoryBlog/static/1dbdc78a582b310f98bc5b9a5b7b4af3/6da96/001-01.png 922w&quot;
        sizes=&quot;(max-width: 922px) 100vw, 922px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;grep 명령어 시 “Binary file (standard input) matches” 에러 발생&lt;/p&gt;
&lt;h3&gt;원인&lt;/h3&gt;
&lt;p&gt;로그파일 grep 할때 텍스트 파일로 인식하지 않고 Binary file 로 인식&lt;/p&gt;
&lt;h3&gt;해결&lt;/h3&gt;
&lt;p&gt;-a 혹은 —text 옵션 추가&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;$ cat server.log | grep -E &amp;quot; \[[0-9]{4}\]&amp;quot; -a
or
$ cat server.log | grep -E &amp;quot; \[[0-9]{4}\]&amp;quot; --text&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[tcpdump 패킷 분석]]></title><link>https://ssongey.github.io/works/posts/2020-12-12--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2020-12-12--001</guid><pubDate>Sat, 12 Dec 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;성능 테스트 중에 솔루션 내에서 DB insert/select 할 때 소요시간이 오래 걸리는 현상이 발생되었다.&lt;br&gt;
데이터가 많이 쌓인것도 아닌데..&lt;br&gt;
해당 부분이 솔루션 문제인지, 네트워크 문제인지 DB 문제인지 확인을 위해 tcpdump를 분석하였다.  &lt;/p&gt;
&lt;h3&gt;#. 사용 툴&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;WireShark&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;h3&gt;#. tcpdump file out 명령어&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;DB 서버에 tcpdump를 떠서 WAS 서버에서 오는 모든 패킷에 대해 파일로 저장하도록 함.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shellscript&quot;&gt;&lt;pre class=&quot;language-shellscript&quot;&gt;&lt;code class=&quot;language-shellscript&quot;&gt;$ sudo tcpdump -w host {WAS_HOST} tcpdump.pcap&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;h3&gt;#. 파일 분석&lt;/h3&gt;
&lt;h5&gt;1. Update 쿼리 요청&lt;/h5&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;        RequestQuery    : Seq(192795), Len(8228), Ack(313141)   
[WAS] ---------------------------------------------------------&amp;gt; [DB]
 (WAS) : 쿼리 요청한다.
         내가 보냈던 총 데이터 길이(seq)는 192795였고, 지금 보내는 데이터 길이는 8228 이야. 
         그리고 너(DB)한테 받은 총 길이는 313141(ack) 이야. &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/40c6597054d0340c1adf0bff9bc50cfb/f5209/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 46.666666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAABcRAAAXEQHKJvM/AAABpUlEQVQoz43OW3OaUBSGYf7/L+pFpkmnaR1RiyhuQAmiKAdBq3L0gG+2JNNJp7noxTPfXmvvBUsZuTa//BG9+VDS+Dnt0fOG6KFJf6GjzgcYG5uB1WFo/mDi9DBmapuaeKarPzGUqbsD9MhE8dyC8ShmpEcMBj7fn+Vw38eZHhFGiqp6ONaBccdlpgWsrT2+2LXpyrnu44Tek8DWQmyxRYmCGL0/whgKxMjC0AxmwmE+nUsenrSKdizTjOhQs60a0uJKml9aSXZiI6XZma1MJTZN9C8PGF+/IR4esbt9dFWu31GZjgX+xCKZuiTLgMRbtVI/5FDU7IvTP5TtJmEsB23bYb0KKc835AIUl7fMTleO+1zK/siOBaXsFx+U75R9lqNbDpOZx2wRMF9vWIYpC8mPd+zLC0XD208+yM+fU37vdlhC4L44BOsVURgQhyHbJGGbJtRVya25crte/nbvfULZJBsmwuTFdSmriuZ243yRA9C619em+S+NpNR5jqdpLHSdvedxiuNWJbcsg6A911HU5r2u3+/vvXtdyncnea7kd4qy5BWV1p4ekEKEKwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/40c6597054d0340c1adf0bff9bc50cfb/d9199/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/40c6597054d0340c1adf0bff9bc50cfb/8ff5a/001-01.png 240w,
/devHistoryBlog/static/40c6597054d0340c1adf0bff9bc50cfb/e85cb/001-01.png 480w,
/devHistoryBlog/static/40c6597054d0340c1adf0bff9bc50cfb/d9199/001-01.png 960w,
/devHistoryBlog/static/40c6597054d0340c1adf0bff9bc50cfb/f5209/001-01.png 1061w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br&gt;
&lt;h5&gt;2. Update 쿼리 요청에 대한 ACK&lt;/h5&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;        Ack             : Seq(313141), Len(0), Ack(201023)
[WAS] &amp;lt;--------------------------------------------------------- [DB]  
 (DB) : 응 받았어, Ack 보낸다.
        너(WAS)한테 내가 313141 까지 보냈고, 너한테 받은 총 길이는 201023(192795+8228) 이야&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/5d761a50404eb6c44d85bf6f7a0c155f/48ca3/001-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 37.916666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABcRAAAXEQHKJvM/AAABjUlEQVQoz52R2Y7TQBBF/f9fg8QDjwODmGw2yTjxFq/tNeMlIYljlMr0relxgDeExJGO6pZafdVSa16awfQDWGGMhWXhu+3AESmCvIRu2dhEMaKiwmq1RBiEiNUehxGSOIGtznV9AdN8hue6CFSXtrUPMBYZLLPGw4OF+TSCudwh2p4xfQqxNEokzhH6JwPxTEDMUyTKVM/hPnr4+uEbJh9nsD878NQ9zdr4bFsBu07Mq5XDnpdwHBUskooDP+VI5bxouar23LU9d13PbXvmrj5x+/KDi6werXcHrl+OrD1/eSTraULOdErOZEbefEH2uM9IrDdUWjady4ou3Z4ubUd909Jlf6DhSnShG/28vY4OKg/XG2kTYyON9Vau3ViKqpNFc5Lpbj+a10eZFo0sk1LmcSELNbMol7usls3xKusTKa+/pFEtDHzOUsFNU/PrjUbvgP8HzVW/4wcB0ixDpqyqCmVZ/snDMOAdKXHn9/wLmud5/K4q5iRJOAxDFkKwKuK+71lKeX8vMPov3gCxOlC9dDy1OQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/5d761a50404eb6c44d85bf6f7a0c155f/d9199/001-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/5d761a50404eb6c44d85bf6f7a0c155f/8ff5a/001-02.png 240w,
/devHistoryBlog/static/5d761a50404eb6c44d85bf6f7a0c155f/e85cb/001-02.png 480w,
/devHistoryBlog/static/5d761a50404eb6c44d85bf6f7a0c155f/d9199/001-02.png 960w,
/devHistoryBlog/static/5d761a50404eb6c44d85bf6f7a0c155f/48ca3/001-02.png 1084w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br&gt;
&lt;h5&gt;3. Update 쿼리 요청에 대한 응답&lt;/h5&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;        Response OK     : Seq(313141), Len(52), Ack(201023)
[WAS] &amp;lt;--------------------------------------------------------- [DB]  
 (DB) : 요청한거 응답이야.
        너(WAS)한테 내가 313141 까지 보냈었고, 쿼리 받은거 수행한 결과야(52)
        그리고 너한테 받은 길이는 201023 야&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/ded9b6e9e3f66f71a5bc4c4392572600/26a94/001-03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 54.58333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABcRAAAXEQHKJvM/AAAB0UlEQVQoz5WRa2+iUBCG+f8/aZNN2mxtXbuteEFElDsIFrkI3tD6dGTTTfphN+4kT2bO5PAy5x3FCzPscIVhBy2qbqKZDl68bhnoc9xlihu9MbV8lumGcFUQvV0pmcwdRjOLmRPgyB3Ft/aYWs64n6AJnXuDl67LYlLimTu6D3Pmeokzljsdi1jfEGlFy7W+9rrfBgx/mCykp2izNY+qT6fv8ST5+5PB/bOFaqwZmTl3vQW/tAR1ENCX2pzIa8Zxy0wYvjg83A156ui8ylkJbY9B5yda75XJc5/BY4+ZOsJ4HbIYatgjndBySfKKbHtkXR/JhHzbUBzO5PvTH7L6gJKEIXNtjDWdEiwWpGFA4ntEtsXK90mjiMKxqRyH2nMppV/JeR/HNM2R5nCgOf7mdDyibKoKY2bi+QGrt5S/xuUifNZfUps/UYqiYCrTWZaF53kEMlUsf4+XS5bRknWacjqdvnz4r1CyPMcwDBG0ZUoRFAv8IGhFN5tK2LSC7+/vN6EkMokxmeC7LnVZshMLtiLS7PecxZOziDVNczNKKaYbqtoupEwSdlnGZbeD6zPrGkT0f0LJRVDXdSJ5YrJasRWxSoRKoRZ/L7LF1jtZyi18ANCXO6kPTsNYAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/ded9b6e9e3f66f71a5bc4c4392572600/d9199/001-03.png&quot;
        srcset=&quot;/devHistoryBlog/static/ded9b6e9e3f66f71a5bc4c4392572600/8ff5a/001-03.png 240w,
/devHistoryBlog/static/ded9b6e9e3f66f71a5bc4c4392572600/e85cb/001-03.png 480w,
/devHistoryBlog/static/ded9b6e9e3f66f71a5bc4c4392572600/d9199/001-03.png 960w,
/devHistoryBlog/static/ded9b6e9e3f66f71a5bc4c4392572600/26a94/001-03.png 1102w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br&gt;
&lt;h5&gt;4. Commit 쿼리 요청&lt;/h5&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;        RequestQuery     : Seq(201023), Len(11), Ack(313193)
[WAS] ---------------------------------------------------------&amp;gt; [DB]  
 (WAS) : Commit 해줘.
         너(DB)한테 내가 201023 까지 보냈고, 지금 보내는 데이터 길이는 11 이야.
         그리고 너(DB)한테 받은 총 길이는 313193(313141+52) 이야. &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/fc2bcdd76811f57ff3aa60c60310cf46/07a6a/001-04.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 51.25000000000001%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABcRAAAXEQHKJvM/AAABtUlEQVQoz6WRW4vaUBSF8/9/UWn7UmildsYYczEacz+JUXPTxHGMxnw9Y4tQKGWgC76z1t7sh80+ip34zHMHfW1jrBdMhYkaGyxKD6cOUIWBuV3iHiK0zGYhe6smxpH1qhHMKx81tTALF1tmJfLOOPOW5x8pll7x+ZPFRGZtskV4PeNRhPq0IQsG1C8u0awmlfOJ1dxdGAdGH02+fpgxG8UojpOh6T4TbcXMDPg2NlBnHqYd43o7mV3ZD3HdDUvNIZZ9sUgk4p4TW275JDcc65jPc5Q8jliOvxNo0zv+VCXUNWJDR1gGa3tO4a5oi5zu9MLl9fTw663nOtzoh4EeicxKvtng2TbB0iENAva7HU1RUm22HPKcpizZZxvaOKYOQ1oh2IcRLyLhfDzSdRe68/k3HcqhaVg4Dr4cTrOMS98/6K5X+tvAm369f2r4C8qxbQh8706ayJuImGydcqgr6qq8+/XS8V4p622JNl9hOgFhVuKnOfG2wk92hOuCQNbb/Yn9qac+XSX9P1GSbMfEsNEXLrvDC8cLtOcbx2540HY3mtf+XShvv5VaJkKfUXiuXPrG/+gn1zvtU0sGThkAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 04&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/fc2bcdd76811f57ff3aa60c60310cf46/d9199/001-04.png&quot;
        srcset=&quot;/devHistoryBlog/static/fc2bcdd76811f57ff3aa60c60310cf46/8ff5a/001-04.png 240w,
/devHistoryBlog/static/fc2bcdd76811f57ff3aa60c60310cf46/e85cb/001-04.png 480w,
/devHistoryBlog/static/fc2bcdd76811f57ff3aa60c60310cf46/d9199/001-04.png 960w,
/devHistoryBlog/static/fc2bcdd76811f57ff3aa60c60310cf46/07a6a/001-04.png 1095w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br&gt;
&lt;h5&gt;5. Commit 쿼리 요청에 대한 ACK&lt;/h5&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;        Ack             : Seq(313193), Len(0), Ack(201034)
[WAS] &amp;lt;--------------------------------------------------------- [DB]  
 (DB) : 응 받았어, Ack 보낸다.
        너(WAS)한테 내가 313193 까지 보냈고, 너한테 받은 총 길이는 201034(201023+11) 이야&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/38aa863f5ff3924606115afea00c70ed/7798c/001-05.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 31.666666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABcRAAAXEQHKJvM/AAABH0lEQVQY04WP6W6CQBSFef8natKYdE3rVisqi8AgjBTENgXcUfk6oqn/2pv5cu7MyT2ZqzkfCcNIMJCCN9+m65nYqcSeSbrCxPuKGQYOThwg5hEindb0lffujTCli63mrQuaJ6Gt5/SMFY+tmKfODN3aYImKB3U3xiV6M8btZ4hBgacX+MMlrTuX+xud14bNS8Pi+dao0eJJiNFsM+71MTvdWv3BiMCwkKZNqjbIiiXL1Zbl+kq+WNWc+tVm94uWRlMcXYWYJpHnMpdSqccsmPCpvFwIFqovTviCzTyl3JeU5Y59edZyd0XL8hzbdQnklPV2y6Gq2B+PlIcDFeeq1Js6F6o/0QoVaFkWvvpJGIYkSUKaprVm3xlHFX4N/Z8fzxO/aoyab7YAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 05&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/38aa863f5ff3924606115afea00c70ed/d9199/001-05.png&quot;
        srcset=&quot;/devHistoryBlog/static/38aa863f5ff3924606115afea00c70ed/8ff5a/001-05.png 240w,
/devHistoryBlog/static/38aa863f5ff3924606115afea00c70ed/e85cb/001-05.png 480w,
/devHistoryBlog/static/38aa863f5ff3924606115afea00c70ed/d9199/001-05.png 960w,
/devHistoryBlog/static/38aa863f5ff3924606115afea00c70ed/7798c/001-05.png 1183w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br&gt;
&lt;h5&gt;6. Commit 쿼리 요청에 대한 응답&lt;/h5&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;        Response OK     : Seq(313193), Len(11), Ack(201034)
[WAS] &amp;lt;--------------------------------------------------------- [DB]  
 (DB) : 요청한거 응답이야.
        너(WAS)한테 내가 313193 까지 보냈었고, 쿼리 받은거 수행한 결과야(11)
        그리고 너한테 받은 길이는 201034 야&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/2ed98b1ccd05e8ac35cb710aa87595c5/cec12/001-06.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 57.91666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAABcRAAAXEQHKJvM/AAAB90lEQVQoz52R6W6bQBSFef8Xan9FVZq0XjHgBTC7MdgsXhLvlPrrxcmPJlLbqCN9OneZOXc0o+jxBD0foqYag4V+007cZ7Q2b3STPlpuMN5YqEsNoxxJbDKWXqOj1YReqqIXQ4arMUq2BM89YRglrnOk1YoYDDIc+0C+gKHUG5Yp2PaeNIE8g+ZcQxMbwxWdXsJAy1Es90hPL/jajuhK4fPdmC/ffDqDJbZ35qEz47EbY8mw9leHcT9lKgNsPceW/Y7E7Xubu0992g8uiuduZcKCbj8QTbl/nNDqeBijBUGwp6eG0gtx7RXadxtP9sysgsjMCYVY6nrb4fFOZSB9ZR7EqC2ViTa5YfQMrKFFOA0JbF8ICIU4eyLf/aA81BT7VyQvdhXF8wvZ0xklCSNMbYRtjHEnNr7pEDk+7tjCk3zmBkSiiRsROxFz0WgasPBmFMUTq33Fand+5YKy3mxwPY9ZPCMrcv64qjNc3vGzlsb1DcpmvZbfswl8nyRJ2MiAsizZ7XZst1sO+z3X6/Xdsd+4vs2VxsCTG/piOJ/P5SMCsiy7mTeapoub+c30AyhpmtamadZRFNXH0+mF47E+HA71SeKGqqrqy+XyIZS1vN202yXUdZ7jWJhzyf/ylv9YyqYsVX86VfM0Vdd5rl6rSqWuVbn+f/ELqAB8wkLJFAkAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 06&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/2ed98b1ccd05e8ac35cb710aa87595c5/d9199/001-06.png&quot;
        srcset=&quot;/devHistoryBlog/static/2ed98b1ccd05e8ac35cb710aa87595c5/8ff5a/001-06.png 240w,
/devHistoryBlog/static/2ed98b1ccd05e8ac35cb710aa87595c5/e85cb/001-06.png 480w,
/devHistoryBlog/static/2ed98b1ccd05e8ac35cb710aa87595c5/d9199/001-06.png 960w,
/devHistoryBlog/static/2ed98b1ccd05e8ac35cb710aa87595c5/cec12/001-06.png 1187w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;#. 파일 분석 결과&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;5번과 6번 소요시간이 약 10초 이상 딜레이된 것이 발견되었다.&lt;/li&gt;
&lt;li&gt;솔루션 및 네트워크 문제는 아닌것으로 판단되어 DB 기술지원 업체에 문의하였다.&lt;/li&gt;
&lt;li&gt;DB 로그를 DB 테이블에 쌓고 있었다는 답변이 왔다…&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;h5&gt;참고) wireShark 필터 사용 내역&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Arrival Time&lt;br&gt;
— frame.time &amp;#x3C;= “Dec 11, 2020 20:44:58.877172000”&lt;/li&gt;
&lt;li&gt;Sequence&lt;br&gt;
— tcp.seq eq 184381&lt;/li&gt;
&lt;li&gt;mysql query target table&lt;br&gt;
— mysql.field.org_table eq “ccp”&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[[Linux] 리소스 모니터링 오픈소스]]></title><link>https://ssongey.github.io/history/posts/2020-12-09--001</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-12-09--001</guid><pubDate>Wed, 09 Dec 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h4&gt;Zabbix&lt;/h4&gt;
&lt;p&gt;&lt;a href=&quot;https://www.zabbix.com/download&quot;&gt;https://www.zabbix.com/download&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Graphite&lt;/h4&gt;
&lt;p&gt;&lt;a href=&quot;https://logz.io/blog/grafana-vs-graphite/&quot;&gt;https://logz.io/blog/grafana-vs-graphite/&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[[작업로그] DB Data Migration]]></title><link>https://ssongey.github.io/works/posts/2020-12-08--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2020-12-08--001</guid><pubDate>Tue, 08 Dec 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;#. 동일한 구조의 테이블 또는 다른 구조의 테이블에  select 한 내용을 insert 하는 방법&lt;/h3&gt;
&lt;h4&gt;1. select 한 내용의  전체 컬럼 insert&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;select 테이블과 insert할 테이블의 구조가 일치해야 한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sql&quot;&gt;&lt;pre class=&quot;language-sql&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;INSERT&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;INTO&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;조건&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;2. 원하는 컬럼만  select 해서 insert&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;특정 컬럼을 직접 선택해서 insert하는 방법&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sql&quot;&gt;&lt;pre class=&quot;language-sql&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;INSERT&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;INTO&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;column1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; colum2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; colum3&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; 
&lt;span class=&quot;token keyword&quot;&gt;SELECT&lt;/span&gt; column1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; colum2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; colum3 &lt;span class=&quot;token keyword&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;조건&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;br&gt;
&lt;h3&gt;#. 조건에 따라 값을 지정해주는 Case 문&lt;/h3&gt;
&lt;h4&gt;1. 여러 조건 비교&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sql&quot;&gt;&lt;pre class=&quot;language-sql&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;//Case&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//    WHEN 조건1 THEN 출력1 &lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//    WHEN 조건2 THEN 출력2&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//    ELSE 출력3&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//END&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;SELECT&lt;/span&gt; 
    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; 
        &lt;span class=&quot;token keyword&quot;&gt;when&lt;/span&gt; sal &lt;span class=&quot;token operator&quot;&gt;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;and&lt;/span&gt; sal &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;E&apos;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;when&lt;/span&gt; sal &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;and&lt;/span&gt; sal &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2000&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;D&apos;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;when&lt;/span&gt; sal &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2000&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;and&lt;/span&gt; sal &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3000&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;C&apos;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;when&lt;/span&gt; sal &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3000&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;and&lt;/span&gt; sal &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4000&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;B&apos;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;when&lt;/span&gt; sal &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4000&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;and&lt;/span&gt; sal &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5000&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;A&apos;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; sal_rank 
&lt;span class=&quot;token keyword&quot;&gt;FROM&lt;/span&gt; table_name&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;h4&gt;2. 특정 컬럼의 값으로 비교&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sql&quot;&gt;&lt;pre class=&quot;language-sql&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;//Case 컬럼명&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//    WHEN 값1 THEN 출력1 &lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//    WHEN 값2 THEN 출력2&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//    ELSE 출력3&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//END&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;SELECT&lt;/span&gt; 
    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; department
        &lt;span class=&quot;token keyword&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;back-end&apos;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;BE&apos;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;front-end&apos;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;FE&apos;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;user-interface&apos;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;UI&apos;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;ETC&apos;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; department_alias 
&lt;span class=&quot;token keyword&quot;&gt;FROM&lt;/span&gt; table_name&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
&lt;h3&gt;#. 작업내용&lt;/h3&gt;
&lt;p&gt;변경사항이 없는 테이블의 경우 &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sql&quot;&gt;&lt;pre class=&quot;language-sql&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;insert&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;into&lt;/span&gt; autocrypt_v2g_prod&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;table_name 
&lt;span class=&quot;token keyword&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; autocrypt_v2g_1208&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;table_name &lt;span class=&quot;token keyword&quot;&gt;order&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;by&lt;/span&gt; created
&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;p&gt;CA_CERT 테이블 Migration&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;컬럼에 변경사항이 있는 경우, 각 컬럼을 명시&lt;/li&gt;
&lt;li&gt;case 문으로 타입이 변경 된 컬럼 해결&lt;/li&gt;
&lt;li&gt;bulk insert 가 되므로 한 row가 insert 될때마다 commit이 되지 않으므로 자신 테이블의 id를 참조하는 issuer_id는 NULL로 insert/commit 후 update문 실행&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sql&quot;&gt;&lt;pre class=&quot;language-sql&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;insert&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;into&lt;/span&gt; autocrypt_v2g_prod&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ca_cert
	&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;created&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; created_by&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; updated&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; updated_by&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	actor&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cert&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; not_after&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; not_before&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;serial&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; subject_dn&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ak_id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; sk_id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; path_length&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; provider_id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
	
	wca_id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	
	valid&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	last_issued&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	
	issuer_id &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;select&lt;/span&gt;
	s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;created&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; created_by&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;updated&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; updated_by&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;actor&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cert&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;not_after&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;not_before&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;serial&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;subject_dn&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ak_id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sk_id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path_length&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;provider_id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	
    s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; wca_id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	
	&lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;status&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;VALID&apos;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; valid &lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;last_issued &lt;span class=&quot;token keyword&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;1&apos;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; last_issued&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;	
	
    &lt;span class=&quot;token boolean&quot;&gt;NULL&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; issuer_id
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; autocrypt_v2g_1208&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ca_cert s &lt;span class=&quot;token keyword&quot;&gt;order&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;by&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;created
&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;update&lt;/span&gt; 
autocrypt_v2g_prod&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ca_cert target&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;select&lt;/span&gt;
	s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;select&lt;/span&gt; t&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; autocrypt_v2g_prod&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ca_cert t &lt;span class=&quot;token keyword&quot;&gt;where&lt;/span&gt; t&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;wca_id &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;issuer_id&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; issuer_id
&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; autocrypt_v2g_1208&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ca_cert s &lt;span class=&quot;token keyword&quot;&gt;order&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;by&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;created&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; result
&lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt; target&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;issuer_id &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;issuer_id
&lt;span class=&quot;token keyword&quot;&gt;where&lt;/span&gt; target&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;wca_id &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id
&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br&gt;
&lt;p&gt;값이 잘못 들어 갔을 경우 id의 sequence 까지 (autoincrement) 초기화 하기 위해 truncate문 사용&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sql&quot;&gt;&lt;pre class=&quot;language-sql&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;truncate&lt;/span&gt; autocrypt_v2g_prod&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tableName&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[[PKI] issuer private key로 서명]]></title><link>https://ssongey.github.io/works/posts/2020-11-26--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2020-11-26--001</guid><pubDate>Thu, 26 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;서명로직 코드&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;WCA ServerKey로 암호화 + base64 인코딩된 mo sub2 private key 복호화 후 서명&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;    &lt;span class=&quot;token comment&quot;&gt;// private key 로 직접 서명&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; base64EncodedMoSub2PrivKey &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;n2iWb4B7ES9Hc7HmAHvW5RMAAGUhwAJ3hOIUuqH9r9y5l4IGzg9nQfXxocKwJDIBSC/x67JcxNA6aALuz0gd+IQby7TTTfB74sxWSNjZUV67Xup0kPOx3wOWrxmO1R2/qGUkwflm3shSbz3YoWaavzipuYKen/6pBQ5kmKzONPFh+1Nprq34hY2lccf38QRp/aGXNbXvxRZcPsYGU5HIIw==&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; caServerKey &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;_u5PJineTniFyvQmHkWP6g&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; moSub2PrivateKeyByte &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;aesDecode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Base64&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;base64EncodedMoSub2PrivKey&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; caServerKey&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;PrivateKey&lt;/span&gt; moSub2PrivateKey &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PkiFactory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;privateKeyByteToClass&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;moSub2PrivateKeyByte&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;SignatureType&lt;/span&gt; signature &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SignatureType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    signature&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setSignedInfo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;signedInfo&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;JAXBElement&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;SignedInfoType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; signedInfoJAXB &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ObjectFactory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createSignedInfo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;signedInfo&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;SignatureValueType&lt;/span&gt; signatureValue &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SignatureValueType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;java&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;security&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;interfaces&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;/span&gt;ECPrivateKey&lt;/span&gt; ecPrivateKey &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;java&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;security&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;interfaces&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;/span&gt;ECPrivateKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; moSub2PrivateKey&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    signatureValue&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setValue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;MsgFactory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;signSignedInfoElement&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;signedInfoJAXB&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ecPrivateKey&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    signature&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setSignatureValue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;signatureValue&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; signatureXmlByte &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MsgFactory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;marshalToByteArray&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;signature&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SignatureType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; signatureXmlStr &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;signatureXmlByte&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;aesDecode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; secretKey&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; IV &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Hex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;62EC67F9C3A4A407FCB2A8C49031A8B3&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// TODO 16byte 넘어가는경우 자르지 말고, 16byte 길이를 유지할수 있는방법을 찾아봐야함.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; password &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; secretKey&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;StringUtils&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;leftPad&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;secretKey&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;StringUtils&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;substring&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;secretKey&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token class-name&quot;&gt;Key&lt;/span&gt; key &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SecretKeySpec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;password&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getBytes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;AES&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token class-name&quot;&gt;Cipher&lt;/span&gt; c &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Cipher&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getInstance&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;AES/CBC/PKCS7Padding&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;BouncyCastleProvider&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;PROVIDER_NAME&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Cipher&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;DECRYPT_MODE&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; key&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;IvParameterSpec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;IV&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;doFinal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Exception&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;RuntimeException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PrivateKey&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;privateKeyByteToClass&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; privKey&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;NoSuchProviderException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;NoSuchAlgorithmException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;InvalidKeySpecException&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;KeyFactory&lt;/span&gt; kf &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;KeyFactory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getInstance&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;EC&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;BouncyCastleProvider&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;PROVIDER_NAME&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;PrivateKey&lt;/span&gt; privateKey &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; kf&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;generatePrivate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PKCS8EncodedKeySpec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;privKey&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; privateKey&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[[PKI] OCSP Request 생성]]></title><description><![CDATA[HashAlgorithm 에 따른 OCSP Request 생성 방법]]></description><link>https://ssongey.github.io/works/posts/2020-11-25--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2020-11-25--001</guid><pubDate>Wed, 25 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;HashAlgorithm 에 따른 OCSP Request 생성 방법&lt;/h2&gt;
&lt;h3&gt;SHA-1&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;id-sha1&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;    &lt;span class=&quot;token class-name&quot;&gt;X509Certificate&lt;/span&gt; cert &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PkiFactory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;x509StringToClass&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;MIICmzCCAkGgAwIBAgIGAOjUpRAeMAoGCCqGSM49BAMCMEAxCzAJBgNVBAYTAktSMQwwCgYDVQQKDANITUMxDDAKBgNVBAsMA0hNQzEVMBMGA1UEAwwMSE1DX01PU3ViQ0EyMB4XDTIwMTEyNDEyNTk1N1oXDTIyMTEyNDE0NTk1OVowQzELMAkGA1UEBhMCS1IxDDAKBgNVBAoMA0hNQzEMMAoGA1UECwwDSE1DMRgwFgYDVQQDDA9LUkVWUDAwMDAwMDA1QVgwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQaoaM2ufpGTDqLVDPOYKJYeKb65vJ36EXY/zsTh/9EYi8yzPSQTrm0blb3s74YsvZ9BUJfDdX6Hh0X5gFTrugLo4IBIjCCAR4waAYDVR0jBGEwX4AULT3vADHec7fHnQwHDR1BvaZI8dihRKRCMEAxCzAJBgNVBAYTAktSMQwwCgYDVQQKDANITUMxDDAKBgNVBAsMA0hNQzEVMBMGA1UEAwwMSE1DX01PU3ViQ0ExggEwMB0GA1UdDgQWBBSHpsbH4R8RnTS3EDJ/8lS46eBRAzAOBgNVHQ8BAf8EBAMCA+gwRQYDVR0fBD4wPDA6oDigNoY0Y249ZHBfVmZ0Y05Ec3RRd21jYXg0TkZfZ3FmUXAwLG91PUhNQyxvPUhNQyxjPUtSLmNybDA8BggrBgEFBQcBAQQwMC4wLAYIKwYBBQUHMAGGIGh0dHA6Ly8xMjcuMC4wLjE6ODA4OS9PQ1NQU2VydmVyMAoGCCqGSM49BAMCA0gAMEUCIQDa2APe7zqfBBXBUtWjhwAkxxqJNiMHdnnGWRKL3/tdMgIgDuwTB/iByJO4uf+Mx/Sfs+vs5Snhi6DQ0A4lJyQLL1E=&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;X509Certificate&lt;/span&gt; issuerCert &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PkiFactory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;x509StringToClass&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;MIIB0zCCAXmgAwIBAgIBMDAKBggqhkjOPQQDAjBAMQswCQYDVQQGEwJLUjEMMAoGA1UECgwDSE1DMQwwCgYDVQQLDANITUMxFTATBgNVBAMMDEhNQ19NT1N1YkNBMTAeFw0yMDExMDQxNTAwMDBaFw0yMjExMDQxNTAwMDBaMEAxCzAJBgNVBAYTAktSMQwwCgYDVQQKDANITUMxDDAKBgNVBAsMA0hNQzEVMBMGA1UEAwwMSE1DX01PU3ViQ0EyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEQevrFh4ZAsgrxz7mKT1igUUbiXnH5Yyj2bw7Fo07hluYWxtFQd8TYwwm5IYkudRNygj69OspvAQf0NdnonQ5BqNkMGIwDgYDVR0PAQH/BAQDAgHGMBIGA1UdEwEB/wQIMAYBAf8CAQAwPAYIKwYBBQUHAQEEMDAuMCwGCCsGAQUFBzABhiBodHRwOi8vMTI3LjAuMC4xOjgwODkvT0NTUFNlcnZlcjAKBggqhkjOPQQDAgNIADBFAiEA7EU/OnEAChywBv+1RLh3mScq6HX9pGdQJl4wAzKMFGsCIBVKjvuqiQoaabi2s+9nLsLLLXO1hEElmJc/2noaB0FH&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;X509CertificateHolder&lt;/span&gt; issuerCertHolder &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;X509CertificateHolder&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;issuerCert&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getEncoded&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;DigestCalculator&lt;/span&gt; digestCalculator &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;BcDigestCalculatorProvider&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;CertificateID&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;HASH_SHA1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;CertificateID&lt;/span&gt; id &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CertificateID&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;digestCalculator&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; issuerCertHolder&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cert&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getSerialNumber&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;VerifyContractByOcspReq&lt;/span&gt; req &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;VerifyContractByOcspReq&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
      emaid&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;OcspData&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;OcspData&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;hashAlgorithm&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;SHA1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;issuerNameHash&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Base64&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toBase64String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getIssuerNameHash&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;issuerKeyHash&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Base64&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toBase64String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getIssuerKeyHash&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;serialNumber&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getSerialNumber&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;SHA-256&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;id-sha256 에 대한 정의를 못찾아서 직접 OID를 넣는 방법을 택

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/dc9513729221b2b3a91c46716047f22b/764be/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 806px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 30.83333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABYlAAAWJQFJUiTwAAABQ0lEQVQY02WQy3KCQBBF+f9f0WxcBAIqCqS0osKIgYH4AESIltFU+Yq7m+5JlZssTvVMT3fPva3NZjMIESDLMqxWGdI0xXK5xGKxgIylitF7hPW6xOFwwPH4TXUrjEZvsDsdvHou7G4XnuvgI02g2bYN13Wx2+1QVzWKokD9WdO5QpEXqDhSbr//wu12w8/9jiRJ4FDPs27A7vdhtttwPA8ySaF1abrjOKRgjYIoyxKbaoPT6YTr9YrL5aLi+XxWOSaKInik7KnZRKvVgqHrdKeBMobG9qSU6lcuZMtxHCHPc6V6u93+Yz6fqzUZhoFer6dglzxL00l2o/H302AwQJ8sdGg3lmXhhRp0gs9Mm6yZpklY4FVxLefG4zH8yUSJ0oQQGA6HKhmGIfgeBMEDnxAB58Tjzfd9FSc0hOG+6XSqFP4CqWyfRK/VcSQAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/dc9513729221b2b3a91c46716047f22b/764be/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/dc9513729221b2b3a91c46716047f22b/8ff5a/001-01.png 240w,
/devHistoryBlog/static/dc9513729221b2b3a91c46716047f22b/e85cb/001-01.png 480w,
/devHistoryBlog/static/dc9513729221b2b3a91c46716047f22b/764be/001-01.png 806w&quot;
        sizes=&quot;(max-width: 806px) 100vw, 806px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;    &lt;span class=&quot;token class-name&quot;&gt;X509Certificate&lt;/span&gt; cert &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PkiFactory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;x509StringToClass&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;MIICmzCCAkGgAwIBAgIGAOjUpRAeMAoGCCqGSM49BAMCMEAxCzAJBgNVBAYTAktSMQwwCgYDVQQKDANITUMxDDAKBgNVBAsMA0hNQzEVMBMGA1UEAwwMSE1DX01PU3ViQ0EyMB4XDTIwMTEyNDEyNTk1N1oXDTIyMTEyNDE0NTk1OVowQzELMAkGA1UEBhMCS1IxDDAKBgNVBAoMA0hNQzEMMAoGA1UECwwDSE1DMRgwFgYDVQQDDA9LUkVWUDAwMDAwMDA1QVgwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQaoaM2ufpGTDqLVDPOYKJYeKb65vJ36EXY/zsTh/9EYi8yzPSQTrm0blb3s74YsvZ9BUJfDdX6Hh0X5gFTrugLo4IBIjCCAR4waAYDVR0jBGEwX4AULT3vADHec7fHnQwHDR1BvaZI8dihRKRCMEAxCzAJBgNVBAYTAktSMQwwCgYDVQQKDANITUMxDDAKBgNVBAsMA0hNQzEVMBMGA1UEAwwMSE1DX01PU3ViQ0ExggEwMB0GA1UdDgQWBBSHpsbH4R8RnTS3EDJ/8lS46eBRAzAOBgNVHQ8BAf8EBAMCA+gwRQYDVR0fBD4wPDA6oDigNoY0Y249ZHBfVmZ0Y05Ec3RRd21jYXg0TkZfZ3FmUXAwLG91PUhNQyxvPUhNQyxjPUtSLmNybDA8BggrBgEFBQcBAQQwMC4wLAYIKwYBBQUHMAGGIGh0dHA6Ly8xMjcuMC4wLjE6ODA4OS9PQ1NQU2VydmVyMAoGCCqGSM49BAMCA0gAMEUCIQDa2APe7zqfBBXBUtWjhwAkxxqJNiMHdnnGWRKL3/tdMgIgDuwTB/iByJO4uf+Mx/Sfs+vs5Snhi6DQ0A4lJyQLL1E=&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;X509Certificate&lt;/span&gt; issuerCert &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PkiFactory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;x509StringToClass&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;MIIB0zCCAXmgAwIBAgIBMDAKBggqhkjOPQQDAjBAMQswCQYDVQQGEwJLUjEMMAoGA1UECgwDSE1DMQwwCgYDVQQLDANITUMxFTATBgNVBAMMDEhNQ19NT1N1YkNBMTAeFw0yMDExMDQxNTAwMDBaFw0yMjExMDQxNTAwMDBaMEAxCzAJBgNVBAYTAktSMQwwCgYDVQQKDANITUMxDDAKBgNVBAsMA0hNQzEVMBMGA1UEAwwMSE1DX01PU3ViQ0EyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEQevrFh4ZAsgrxz7mKT1igUUbiXnH5Yyj2bw7Fo07hluYWxtFQd8TYwwm5IYkudRNygj69OspvAQf0NdnonQ5BqNkMGIwDgYDVR0PAQH/BAQDAgHGMBIGA1UdEwEB/wQIMAYBAf8CAQAwPAYIKwYBBQUHAQEEMDAuMCwGCCsGAQUFBzABhiBodHRwOi8vMTI3LjAuMC4xOjgwODkvT0NTUFNlcnZlcjAKBggqhkjOPQQDAgNIADBFAiEA7EU/OnEAChywBv+1RLh3mScq6HX9pGdQJl4wAzKMFGsCIBVKjvuqiQoaabi2s+9nLsLLLXO1hEElmJc/2noaB0FH&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;X509CertificateHolder&lt;/span&gt; issuerCertHolder &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;X509CertificateHolder&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;issuerCert&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getEncoded&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;AlgorithmIdentifier&lt;/span&gt; HASH_SHA256 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AlgorithmIdentifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ASN1ObjectIdentifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2.16.840.1.101.3.4.2.1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DERNull&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;INSTANCE&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;DigestCalculator&lt;/span&gt; digestCalculator &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;BcDigestCalculatorProvider&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;HASH_SHA256&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;CertificateID&lt;/span&gt; id &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CertificateID&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;digestCalculator&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; issuerCertHolder&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cert&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getSerialNumber&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;VerifyContractByOcspReq&lt;/span&gt; req &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;VerifyContractByOcspReq&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
      emaid&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;OcspData&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;OcspData&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;hashAlgorithm&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;SHA256&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;issuerNameHash&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Base64&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toBase64String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getIssuerNameHash&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;issuerKeyHash&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Base64&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toBase64String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getIssuerKeyHash&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;serialNumber&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getSerialNumber&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[[Gradle] 테스트 없이 빌드]]></title><link>https://ssongey.github.io/works/posts/2020-11-24--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2020-11-24--001</guid><pubDate>Tue, 24 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;$ gradle build --exclude-task test&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[[스프링 핵심 원리 리뷰] Container Bean 생성]]></title><link>https://ssongey.github.io/history/posts/2020-11-14--001.md</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-11-14--001.md</guid><pubDate>Sat, 14 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;# 스프링 컨테이너 생성&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;ApplicationContext&lt;/span&gt; applicationContext 
      &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AnnotationConfigApplicationContext&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;AppConfig&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/aca2881e7fd310641dee14f2b16c710f/bd82c/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 47.91666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABYlAAAWJQFJUiTwAAABI0lEQVQoz42S2Y6DMAxF+X0+qd/BS0VZHiirCpQWxF7PHEtB6aga1dKVYye+XmJHfmXfd/lPlmWRcRxlnmdpmkbO57PC8zy18XM/TZM4p9NJ1nWV6/UqSZJIlmXi+74EQSCXy0XSNJW6rqXrOgUEt9tNNX70/X6Xx+MhRVGI47quEhKY57kCYhLgi+NYg2yhI6retu3NTwJHvhAqe71e2hKVRFGkXQDuaJd7JSQbhtEGZq7MhyA0ZIyiqiolp3JIaZmKsd8qtAmB+RAIzceYdodh0CTY+A/C5/OpmdGfhPnahJDYv2rOvDsIQVmWetH3vZ7DMNQHBNESlRgC8Pd8zJABA34TBysBIMU2K/ONaIW0SwCBlP1phqySncwkstG2ra7ZD2IhAUimpjaEAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/aca2881e7fd310641dee14f2b16c710f/d9199/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/aca2881e7fd310641dee14f2b16c710f/8ff5a/001-01.png 240w,
/devHistoryBlog/static/aca2881e7fd310641dee14f2b16c710f/e85cb/001-01.png 480w,
/devHistoryBlog/static/aca2881e7fd310641dee14f2b16c710f/d9199/001-01.png 960w,
/devHistoryBlog/static/aca2881e7fd310641dee14f2b16c710f/07a9c/001-01.png 1440w,
/devHistoryBlog/static/aca2881e7fd310641dee14f2b16c710f/bd82c/001-01.png 1585w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h3&gt;# 스프링 빈 등록&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;빈 이름은 메서드 이름을 사용&lt;/li&gt;
&lt;li&gt;빈 이름을 직접 부여할 수도 있다 @Bean(name”memberService2”)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/489ee6d9d6f2bbc7cd102bf6203b6f4c/0bdcb/001-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 45.833333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAABYlAAAWJQFJUiTwAAAB/UlEQVQoz32SW2saQRiG91+00JsYozG7q7s7e3A9BJH8ggYkGtKf2CbYoBVy63Vzo4LnMx5Q1/Ws4NuZoZRcdeBldgfmmfd7v094eysgn8/hV6GA9/ffqFQqKJfLKJfKfC+VSnCWDo7HI1arFbbbLabTKer1OhqNBlqtFjabzT8JETMENRiATnQYpoG4TRChUmJBhFQFXu8V8rk8TqcT5vM5DocDBw+HQ3S7Xbiui/1+z2HsXIiGCbSQSIEaCCGwDA2mSaDSXQtr8Ek+vOZ+4nw+Y7fbcYcMMplMMBqNMJvNOIwt9qgQtzUYiohYNIpEMom7ZAL2rY4bEoBEzz3XF3jOfYd7WGIwHKBarfJS1+s1HMfh36x8FgN3SIgKv98PVSPQTQsaLV2WZYiiCFmRcem/xMvrM9yjg96wxy+z3NjlTqeDZrPJ1ev1eAXCbYTA1GRYlsWBUdtAImYiHtERsiUK9FCHP7A6umi1m9xRrVbDeDxGv99Hu93mYnAWhRCzdRBFgmnoNDuLNsREJGyC2CpCehBXN168UOD6tEJ/2OdOmJZLGsFgwKHsnzWJ5SvoSgCi7wKyJEKSg9AoXAtJuJa9ND8PPn/5hGw2y0Nno/O/xRonPD19QyqVQiaTRjqdxsNfpR8yeMw84v7rPYrFIh+XxWLBXXycu49iuf4BRRAE4LPOLWMAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/489ee6d9d6f2bbc7cd102bf6203b6f4c/d9199/001-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/489ee6d9d6f2bbc7cd102bf6203b6f4c/8ff5a/001-02.png 240w,
/devHistoryBlog/static/489ee6d9d6f2bbc7cd102bf6203b6f4c/e85cb/001-02.png 480w,
/devHistoryBlog/static/489ee6d9d6f2bbc7cd102bf6203b6f4c/d9199/001-02.png 960w,
/devHistoryBlog/static/489ee6d9d6f2bbc7cd102bf6203b6f4c/07a9c/001-02.png 1440w,
/devHistoryBlog/static/489ee6d9d6f2bbc7cd102bf6203b6f4c/0bdcb/001-02.png 1579w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h3&gt;# 스프링 빈 조회&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;  &lt;span class=&quot;token class-name&quot;&gt;AnnotationConfigApplicationContext&lt;/span&gt; ac 
          &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AnnotationConfigApplicationContext&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;AppConfig&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token annotation punctuation&quot;&gt;@Configuration&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AppConfig&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token annotation punctuation&quot;&gt;@Bean&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DataService&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;dataService&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DataServiceImpl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token annotation punctuation&quot;&gt;@Test&lt;/span&gt;
  &lt;span class=&quot;token annotation punctuation&quot;&gt;@DisplayName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;빈 이름으로 조회&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;findBeanByName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;DataService&lt;/span&gt; dataService &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ac&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getBean&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;dataService&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DataService&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;assertThat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dataService&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isInstanceOf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;DataServiceImpl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token annotation punctuation&quot;&gt;@Test&lt;/span&gt;
  &lt;span class=&quot;token annotation punctuation&quot;&gt;@DisplayName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;이름 없이 타입으로만 조회&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;findBeanByType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;DataService&lt;/span&gt; dataService &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ac&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getBean&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;DataService&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;assertThat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dataService&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isInstanceOf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;DataServiceImpl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token annotation punctuation&quot;&gt;@Test&lt;/span&gt;
  &lt;span class=&quot;token annotation punctuation&quot;&gt;@DisplayName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;구체 타입으로 조회&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;findBeanByImplName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// 좋은 코드는 아니다.&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// 항상 역활과 구현을 구분해야 한다.&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// 그리고 역할에 의존해야 한다.&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;DataService&lt;/span&gt; dataService &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ac&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getBean&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;dataService&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DataServiceImpl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;assertThat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dataService&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isInstanceOf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;DataServiceImpl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token annotation punctuation&quot;&gt;@Test&lt;/span&gt;
  &lt;span class=&quot;token annotation punctuation&quot;&gt;@DisplayName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;빈 이름으로 조회 실패&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;findBeanByNameX&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;assertThrows&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;NoSuchBeanDefinitionException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
        &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; ac&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getBean&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;xxx&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DataService&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;스프링 빈 조회 - 상속관계&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;부모 타입으로 조회하면 자식 타입도 함께 조회&lt;/li&gt;
&lt;li&gt;Object 타입으로 조회하면 모든 스프링 빈을 조회&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/054a303856f5ecf75599435a8d9791c8/ce0a7/001-03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 43.75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAABYlAAAWJQFJUiTwAAABFUlEQVQoz21SiaqEQAzz/39PvHW971sRvLukMDLue4VSnThp0qokSUJxHFOapuR5HrmuS7quE84R930/idj3nZqmoTzPXxjyOA5SgiAg3/cJ1TAMJjRNk8qyJDlkQmBoeF3XC2NC27YJ6TgOfT6fB5TVyQF1WZYxaV3XL4wJYU/TNE6oPM/zj00oGceRbaKKwHNRFDQMA99DskJYRWdB8EuIzlEUsQvRELFtG58jl2XhxgrmBXVt277m8fssE8p4GIa8TJw/hLBdVdW/6lDneaa+77nCnsDFu6hYGBOqqkpd171UiYo5QQFwXLQsi8mnaeIlYjHAsHW4UPARLq3r+gxWpNgqHOAiiDAeQQIxWArc4V9Ggy974q+7XRjmPgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/054a303856f5ecf75599435a8d9791c8/d9199/001-03.png&quot;
        srcset=&quot;/devHistoryBlog/static/054a303856f5ecf75599435a8d9791c8/8ff5a/001-03.png 240w,
/devHistoryBlog/static/054a303856f5ecf75599435a8d9791c8/e85cb/001-03.png 480w,
/devHistoryBlog/static/054a303856f5ecf75599435a8d9791c8/d9199/001-03.png 960w,
/devHistoryBlog/static/054a303856f5ecf75599435a8d9791c8/07a9c/001-03.png 1440w,
/devHistoryBlog/static/054a303856f5ecf75599435a8d9791c8/ce0a7/001-03.png 1590w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;AnnotationConfigApplicationContext&lt;/span&gt; acExtends &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; 
          &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AnnotationConfigApplicationContext&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;TestConfig&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token annotation punctuation&quot;&gt;@Configuration&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;TestConfig&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token annotation punctuation&quot;&gt;@Bean&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DataPolicy&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rateDataPolicy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;RateDataPolicy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token annotation punctuation&quot;&gt;@Bean&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DataPolicy&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fixDataPolicy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;FixDataPolicy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token annotation punctuation&quot;&gt;@Test&lt;/span&gt;
  &lt;span class=&quot;token annotation punctuation&quot;&gt;@DisplayName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;부모 타입으로 조회시, 자식이 둘 이상 있으면, 중복 오류가 발생한다.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;findBeanByParentTypeDuplicate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;assertThrows&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;NoUniqueBeanDefinitionException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; acExtends&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getBean&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;DataPolicy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token annotation punctuation&quot;&gt;@Test&lt;/span&gt;
  &lt;span class=&quot;token annotation punctuation&quot;&gt;@DisplayName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;부모 타입으로 조회시, 자식이 둘 이상 있으면, 빈 이름을 지정하면 된다.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;findBeanByParentTypeBeanName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;RateDataPolicy&lt;/span&gt; rateDataPolicy &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; acExtends&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getBean&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;rateDataPolicy&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;RateDataPolicy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;assertThat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rateDataPolicy&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isInstanceOf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;RateDataPolicy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token annotation punctuation&quot;&gt;@Test&lt;/span&gt;
  &lt;span class=&quot;token annotation punctuation&quot;&gt;@DisplayName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;특정 하위 타입으로 조회&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;findBeanBySubType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;RateDataPolicy&lt;/span&gt; rateDataPolicy &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; acExtends&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getBean&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;RateDataPolicy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;assertThat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rateDataPolicy&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isInstanceOf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;RateDataPolicy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token annotation punctuation&quot;&gt;@Test&lt;/span&gt;
  &lt;span class=&quot;token annotation punctuation&quot;&gt;@DisplayName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;부모 타입으로 모두 조회하기&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;findAllBeanByParentType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;Map&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DataPolicy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; beansOfType &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; acExtends&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getBeansOfType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;DataPolicy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;assertThat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;beansOfType&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isEqualTo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; key &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; beansOfType&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;keySet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token class-name&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;key = &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; key &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; value = &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; beansOfType&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;key&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[[스프링 핵심 원리 리뷰] Singleton Container]]></title><link>https://ssongey.github.io/history/posts/2020-11-14--002</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-11-14--002</guid><pubDate>Sat, 14 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;스프링 없는 순수한 DI 컨테이너&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;요청시마다 객체를 새로 생성한다

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/7ba29536b82a71776fec267ced6c97ec/efeb1/002-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 50%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABYlAAAWJQFJUiTwAAAB2klEQVQoz32SzW7TUBCF/TDwEkWCXbuHhwCp0L5EN7CiK8KKRaMUKVDlASJFitiFKpvGJHHs/FzHThzbuU7s+iexD8y0TVshGMmydeX55pwzV8Ft5XmOf5WUEkEQQAiBzlUHwhDQf+nQVA3tdhv9fh9hGML3fShJkmCz2eB/NZ/PGep6LryFB+lJmMKEO3NhTS1YloXVagXbtqHUajWUy2WGTqdT6LqO4XCIyWRyD3JdFEWBfFtAuALvLt7i4PM+3nx7DZnI3eDlcgml1Wqh2WxyI02YzWYMJnv0jMdjHkA/+54PYQt8vTxH6ccnVH5WEKURUNwA2XK328VoNMLDLD3PYxuO4+wUPixS66ydXe55kd8Dq9UqSqUSh042aUCv14NhGAwiZaQ8zVJkSYbOsIMXp8/x9OQJnn3cgx1Yu0EMHAwGnFuWZdxM26JnvV6zOjoj2/RNDVEYIc5iWH9A19n13wopv0ajwQe08cViwVZJFUHojKB3RZmdX1bwof4eZ60zhGn4OMN6vQ6yTfY0TeM8TdPkxdCCCEx5JmmCYBlANVQcXxzh1ZeXOPx+CD/2H91XhTZJiijg7XaLOI75TpHlu7eqqpwpDaB7GMoQ0peIgog3T/0kiFi/ASOC35jpfiC6AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/7ba29536b82a71776fec267ced6c97ec/d9199/002-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/7ba29536b82a71776fec267ced6c97ec/8ff5a/002-01.png 240w,
/devHistoryBlog/static/7ba29536b82a71776fec267ced6c97ec/e85cb/002-01.png 480w,
/devHistoryBlog/static/7ba29536b82a71776fec267ced6c97ec/d9199/002-01.png 960w,
/devHistoryBlog/static/7ba29536b82a71776fec267ced6c97ec/07a9c/002-01.png 1440w,
/devHistoryBlog/static/7ba29536b82a71776fec267ced6c97ec/efeb1/002-01.png 1593w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token annotation punctuation&quot;&gt;@Configuration&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AppConfig&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token annotation punctuation&quot;&gt;@Bean&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;DataService&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;dataService&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DataServiceImpl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token annotation punctuation&quot;&gt;@Test&lt;/span&gt;
  &lt;span class=&quot;token annotation punctuation&quot;&gt;@DisplayName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;스프링 없는 순수한 DI 컨테이너&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;pureContainer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;AppConfig&lt;/span&gt; appConfig &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AppConfig&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// 호출시마다 객체를 생성&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;DataService&lt;/span&gt; dataService1 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; appConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;dataService&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;DataService&lt;/span&gt; dataService2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; appConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;dataService&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// 참조값이 다른 것을 확인&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;assertThat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dataService1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isNotSameAs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dataService2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;싱글톤 컨테이너&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;스프링 컨테이너 덕분에 요청시마다 객체를 생성하는 것이 아니라, 이미 만들어진 객체를 재사용한다.&lt;/li&gt;
&lt;li&gt;스프링 컨테이너는 싱글톤 컨테이너 역할을 한다.&lt;/li&gt;
&lt;li&gt;이렇게 싱글톤 객체를 생성하고 관리하는 기능을 싱글톤 레지스트리라 한다.

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/e1969ad39cc239852f33e1ec5c1aa642/7bf53/002-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 50%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABYlAAAWJQFJUiTwAAABd0lEQVQoz41Sy26CUBTkf9o/aD+g/bNu2XTnxj9w507c6cqFj6iER6KCIggI+ODhtHNSkmJS05OcXC73njkzc66Cn7jdbvgrjscjoiiS1bZtTKdTLJdLTCYTGIYhZ3EcIwxDKHmeoyxLPIr9fo/D4SCFnufBdV3sdjtst1vZE4iA3CvdbhetVgtpmmKz2UjH+XwuKwt5mUX/CTZURqMRer0eyJQAdbIbWdRMyICZJAnSJMUlu3z7RKuAqqoEUCSbpils7oOeFkUh63q9FlDHcYStF3pYOAuEWdjwXxh2Oh2oqoosy7BarUTubDaDruvClAAEIosiL2C7Nt4/3/D88YRX9QVWYDUlW5YlUzufz2J+LY3JQfi+L5OlHMqN4ghja4yhPYTpm9KowXAwGEDTNPlxvV4RBIGwqn3jC+BFBgHZpOnNnYf9fh/tdls2lMxJM38PiD4T9HQ6PZwyCSgspunsQgZ8vFx5WH8TkNMme9pyn1REa0joC9DK7zQR3b2JAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/e1969ad39cc239852f33e1ec5c1aa642/d9199/002-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/e1969ad39cc239852f33e1ec5c1aa642/8ff5a/002-02.png 240w,
/devHistoryBlog/static/e1969ad39cc239852f33e1ec5c1aa642/e85cb/002-02.png 480w,
/devHistoryBlog/static/e1969ad39cc239852f33e1ec5c1aa642/d9199/002-02.png 960w,
/devHistoryBlog/static/e1969ad39cc239852f33e1ec5c1aa642/07a9c/002-02.png 1440w,
/devHistoryBlog/static/e1969ad39cc239852f33e1ec5c1aa642/7bf53/002-02.png 1595w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token annotation punctuation&quot;&gt;@Test&lt;/span&gt;
  &lt;span class=&quot;token annotation punctuation&quot;&gt;@DisplayName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;스프링 컨테이너와 싱글톤&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;springContainer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;ApplicationContext&lt;/span&gt; ac &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AnnotationConfigApplicationContext&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;AppConfig&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;DataService&lt;/span&gt; dataService1 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ac&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getBean&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;dataService&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DataService&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;DataService&lt;/span&gt; dataService2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ac&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getBean&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;dataService&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DataService&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// 참조값이 동일한 것을 확인&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;assertThat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dataService1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isSameAs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dataService2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;싱글톤 방식의 주의점&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;무상태(stateless)로 설계해야 한다.&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[[스프링 핵심 원리 리뷰] @Configuration]]></title><link>https://ssongey.github.io/history/posts/2020-11-14--003</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-11-14--003</guid><pubDate>Sat, 14 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;# @Configuration과 바이트코드 조작의 마법&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;@Configuration 사용 시 ‘CGLIB’ 라는 바이트코드 조작 라이브러리를 사용하여 클래스 구성한다.&lt;/li&gt;
&lt;li&gt;때문에 여러 곳에서 특정 Bean의 객체 생성을 유도하더라도 싱글톤이 보장되도록 해준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/cb0780cfe66b9bbd0ac218383ed6a687/0bdcb/003-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 53.333333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABYlAAAWJQFJUiTwAAABXElEQVQoz41TW07CUBDtHojug28fiS6GJWh0BX4a3YX/LoAP/oQWAgk1KaShUqDQAiGRtrc9csbcIiqESU46mTtzZubcWyPPcxzCYrFAGIaYz+eYTqdot9toNptotVrodDpyFkWRgDkGDliWZQiCQBJZwGLf9zEcDuU7Go12yBgzlFLFNPQJbUmSSPKxxgbGbDZDr9eD4ziYTCZCkKbpH0I25MSp2pzlENDXcdp4PP4mNE0TjUZDAvsIdZHEVQKVqR1pCkI6q9VK9NGT7Fs5+oxQeang/OkMl88XuH+92wy6zRdC3iJXpaAUltAdfxKmcYqu10X5oYzT2xOUbkq4frxCEAZYr9dbDS3LkqdQr9dB37btfwk9z0Pf6cP/8FF9q6Jm1uC8O7C7ttx6QcgJl8tlAa6v1yahluLoWz6UQEI2PNYonaHf3m9w7TiOMRgM5A/hA98HEjHHdV18AfEmQn6hcQjlAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;003 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/cb0780cfe66b9bbd0ac218383ed6a687/d9199/003-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/cb0780cfe66b9bbd0ac218383ed6a687/8ff5a/003-01.png 240w,
/devHistoryBlog/static/cb0780cfe66b9bbd0ac218383ed6a687/e85cb/003-01.png 480w,
/devHistoryBlog/static/cb0780cfe66b9bbd0ac218383ed6a687/d9199/003-01.png 960w,
/devHistoryBlog/static/cb0780cfe66b9bbd0ac218383ed6a687/07a9c/003-01.png 1440w,
/devHistoryBlog/static/cb0780cfe66b9bbd0ac218383ed6a687/0bdcb/003-01.png 1579w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token annotation punctuation&quot;&gt;@Configuration&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AppConfig&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

  &lt;span class=&quot;token annotation punctuation&quot;&gt;@Bean&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MemberService&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;memberService&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;call AppConfig.memberService&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MemberServiceImpl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;memberRepository&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token annotation punctuation&quot;&gt;@Bean&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;OrderService&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;orderService&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;call AppConfig.orderService&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;OrderServiceImpl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;memberRepository&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
 
  &lt;span class=&quot;token annotation punctuation&quot;&gt;@Bean&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MemberRepository&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;memberRepository&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;call AppConfig.memberRepository&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MemoryMemberRepository&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;출력결과&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;call AppConfig.memberService
call AppConfig.memberRepository
call AppConfig.orderService&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4&gt;# AppConfig@CGLIB 예상 코드&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token annotation punctuation&quot;&gt;@Bean&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DataService&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;dataService&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dataService 가 이미 스프링 컨테이너에 등록되어 있으면&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; 스프링 컨테이너에서 찾아서 변환&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    기존 로직을 호출하여 dataService를 생성하고 스프링 컨테이너에 등록
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; 반환
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;@Configuration 삭제 시 출력결과는&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;call AppConfig.memberService
call AppConfig.memberRepository
call AppConfig.orderService
call AppConfig.memberRepository
call AppConfig.memberRepository&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[@RequestBody, @ResponseBody]]></title><link>https://ssongey.github.io/history/posts/2020-11-10--001</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-11-10--001</guid><pubDate>Tue, 10 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;1. 자바 직렬화 (Serialize)&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;            Deserialize                   Serialize
Byte Data ---------------&amp;gt; Java Object ---------------&amp;gt; Byte Data&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;2. @RequestBody, @ResponseBody&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;@RequestBody 어노테이션과 @ResponseBody 어노테이션은 각각 HTTP 요청 몸체를 자바 객체로 변환하고 자바 객체를 HTTP 응답 몸체로 변환하는 데 사용된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;3. HttpMessageConverter를 이용한 변환 처리&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;AnnotationMethodHandlerAdapter 클래스는 @RequestBody 어노테이션이 적용된 파라미터나 @ResponseBody 어노테이션이 적용된 메서드에 대해 HttpMessageConverter를 사용해서 변환을 처리한다. 주요 HttpMessageConverter 구현 클래스는 다음과 같다.&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;구현 클래스&lt;/th&gt;
&lt;th&gt;설 명&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ByteArrayHttpMessageConverter&lt;/td&gt;
&lt;td&gt;HTTP 메시지와 byte 배열 사이의 변환을 처리한다. 컨텐츠 타입은  application/octet-stream이다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;StringHttpMessageConverter&lt;/td&gt;
&lt;td&gt;HTTP 메시지와 String 사이의 변환을 처리한다. 컨텐츠 타입은  text/plain;charset=ISO-8859-1이다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FormHttpMessageConverter&lt;/td&gt;
&lt;td&gt;HTML 폼 데이터를 MultiValueMap으로 전달받을 때 사용된다. 지원하는 컨텐  츠 타입은 application-x-www-form-urlencorded이다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SourceHttpMessageConverter&lt;/td&gt;
&lt;td&gt;HTTP 메시지와 javax.xml.transform.Source 사이 변환을 처리한다. 컨텐츠 타  입은 application/xml 또는 text/xml이다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MarshallingHttpMessageConverter&lt;/td&gt;
&lt;td&gt;스프링의 Marshaller와 unMarshaller를 이용해서 XML HTTP 메시지와 객체 사  이의 변환을 처리한다. 컨텐츠 타입은 application/xml 또는 text/xml이다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MappingJacksonHttpMessageConverter&lt;/td&gt;
&lt;td&gt;Jackson 라이브러리를 이용해서 JSON HTTP 메시지와 객체 사이의 변환을 처  리한다. 컨텐츠 타입은 applicaion/json이다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</content:encoded></item><item><title><![CDATA[DTO 클래스?]]></title><link>https://ssongey.github.io/history/posts/2020-11-10--002</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-11-10--002</guid><pubDate>Tue, 10 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;DTO&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Data Transfer Object&lt;/li&gt;
&lt;li&gt;각 레이어 사이에 데이터를 전달하기 위한 목적으로 사용하는 Object&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;View Layer와 DB Layer의 역할 분리를 하기위함으로 사용&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;API의 req와 res에 맞게 domain이 수정될 필요 없다.&lt;/li&gt;
&lt;li&gt;req, res에 불필요한 properties 가 들어가지 않는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;필수 값에 대한 조건 체크하는 것이나 DTO 에서 Domain 으로 변환하거나, Domain 에서 DTO 로 변환하는 로직은 Domain 이 아닌 DTO 에 담겨야 한다.&lt;/li&gt;
&lt;li&gt;@NotNull 과 같은 Data 의 Validation 도 DTO 의 역할 이기 때문에 DTO 에 넣어주게 되면 역할과 책임이 좀 더 명백해지게 된다.&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[[Code Convention] DTO Class]]></title><link>https://ssongey.github.io/history/posts/2020-11-10--003</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-11-10--003</guid><pubDate>Tue, 10 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;DTO Class Code Convention&lt;/h2&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/cc6f89aaf1252ee4350cc615b916ff3c/c7dcc/003-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 641px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 120.41666666666669%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAYCAYAAAD6S912AAAACXBIWXMAABJ0AAASdAHeZh94AAADBElEQVQ4y6VVW3akOgzMbqax8dsGGmiS3Ox/TTUlQb/SmZmP+6FjMLgolUriLdcRMTdczg7/LQbzYLEw5qVge9+wrJ9IKSOmhFwqSm2IkdehIIYEay2MMbpKvOU6IJaGqXjMxaJGizFbDONA0BVtmOC9R9/3cM5ryHXfO11/BEwEdDyUouFhi64zOJ0kOsYv3p/0kKzd6bSvR1zBrutbaTtgyh5fXx2W2aDWPUol4zailkE/WGrl/aBp19TQ8ojgw88MQ/B4HwxGpr00i5YMpmwwEGQ6rxjPMzUszCAouKTuXdC0nwHJQABt73FuBu8szHruKbhHcI6Hdu1Ex2tq9+heU74ytBS5JIttJMvqofu5kDlZWNGve2LyGE8My42hQysGH4sAOtokI8RIdqymHLoBCDP7I/A3QE+9DD5XatccwRLZRabqlKGAaJo30J/ZPqdMD67Ucci85n5myo5FEGAxdyC4gP2J3QFIhgw56Phy6C1cfzAkQPQ9AXcTm4OZ6KmaHmv3UCitcm4TnLBwBht1nGrGedmwzhO+thGXeaAcZ6SQ1Taib8pZW1CY57B/+LlTKL6knfhAgPVF7stz76OCaf8SRI1dm7pA+zs6PvsG6GkP8Vun4lv12C01SVPu1Xf3/e4h5e6Wct2rLMb13hD076L/K262icnjY+swDjtg1x1Mu3tHXAuixXhgbOW9o2AKKPNQAT86zMdwiLRQZOekFHmdVWMxuhZDihILtas6EwXMmgeGOhNjwOdZusTiMlrORw7besI0NiyXT1b9otNG/cjCCFD0SatunsfXCAnxYeEsnMhsSEHHVqMUhZWVAdGT4aMHdR6a1/4+jD2gJ6DvaReCemdp6n3KSJdoP/dGV72WVaaPsYcL7m54MfbKeThRu7kGDMPIdN85Dxcs40ijb5yLC6Z55b9mUw/Kv8bzrA4SdtOLsbMYmyxlT6a5TGjtZV8Y9+7Yf1o0eGsK3PhxT4yHiR3Ui2IVNWn3bGxzWETjavZvBj+MvQPKl1VY8/+M/RsOv+WNoLD9hwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;003 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/cc6f89aaf1252ee4350cc615b916ff3c/c7dcc/003-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/cc6f89aaf1252ee4350cc615b916ff3c/8ff5a/003-01.png 240w,
/devHistoryBlog/static/cc6f89aaf1252ee4350cc615b916ff3c/e85cb/003-01.png 480w,
/devHistoryBlog/static/cc6f89aaf1252ee4350cc615b916ff3c/c7dcc/003-01.png 641w&quot;
        sizes=&quot;(max-width: 641px) 100vw, 641px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h3&gt;#1.클래스 정의 방법&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;도메인 또는 리소스 별 DTO 클래스 생성 후(CouponDto), 각 API(Controller 에 정의된 메소드: CreateReq, CreateRes) 에 해당하는 DTO를 InnerClass 로 정의&lt;/li&gt;
&lt;li&gt;CouponDto의 객체 생성을 하지 않으므로 InnerClass는 static 키워드를 명시한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;h3&gt;#2.생성자의 접근자는 최소한으로&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;객체 생성이 불필요한 클래스의 기본 생성자 접근자는 Private로 지정&lt;br&gt;
—&gt; 개별 DTO는 InnerClass로 정의하기 때문에 객체 생성이 불필요하다.  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/074fcf83cf622a547fa49db7e0942133/85ff8/003-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 467px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 14.166666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAABJ0AAASdAHeZh94AAAAlklEQVQI10XMURLCIAwE0N7GgVBSKgVC0Dp6/zOtKR/68SY7SWaX83To3UPVo4lppt5QarCsdnuhFgFvCdIHSuv2p5YV5RBIHujHgJQBIsLyEbIF2YGg2aNkRusV+lA8z7cVC1LaEUIA84bIPLFZ14g48TQLKxO2QEgrIUcPtof9fiAfFXvOiDHOMu89vHM/7prXbvrnL36yXrDoT8t/AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;003 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/074fcf83cf622a547fa49db7e0942133/85ff8/003-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/074fcf83cf622a547fa49db7e0942133/8ff5a/003-02.png 240w,
/devHistoryBlog/static/074fcf83cf622a547fa49db7e0942133/85ff8/003-02.png 467w&quot;
        sizes=&quot;(max-width: 467px) 100vw, 467px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br&gt;
&lt;h3&gt;#3. Request Dto 클래스&lt;/h3&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/8da319325ee3518a439824e6331866c8/6114d/003-03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 623px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 64.16666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAABJ0AAASdAHeZh94AAABpUlEQVQ4y42T6XKEIBCE8zjKDYKo7FF5/4fq9OCu2SNJ5UcXJehH98z4EfMMHyJaG7E1Be8VtFEwljKGslCKe1pzz8JSfTUOzjrum+Nc9JFuwCth16axzgqtamyVF1RedPrEsjTMdUGZK3KZMU0FORaUqXboG9D5iBoVTgQtRaMmhaBHJMc1JmSCply6M/n4VQK6rx1oXYDnx6dVYZs1XUT4OHHfw/ClcRgwjuOTk0e9ORRgCgqfjHxeFGLk85QRQoBz9hnwA/RHYBCHdNcYOedMl5VAOnX2Kdor4FUHMNLh5czIjC2upLvWSpef3Sn1O1TOCCy9Vo6jMgdNKXYxoy4bmxV293SaUuI75gD+7pDRegO0QvaaEQ1CmjiPHiWy45Ole4eRjqQxXdKk3qhdw6j6ubg+gIbAlYCWDN2tWNsZ18uGy2nByhmcpwXRJ0ReJvXt88h0krBEi+Ttw2Az2r1mkX+I47zJ/AVeJDPqjO8wL+PFzgtUtL+TCGMqJjuAUiPnOPEyczfre7wBqs/fLep9HYfv+F0PkSN/Iyn+3jX1Z8H/oy+PL4/6+ib2eAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;003 03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/8da319325ee3518a439824e6331866c8/6114d/003-03.png&quot;
        srcset=&quot;/devHistoryBlog/static/8da319325ee3518a439824e6331866c8/8ff5a/003-03.png 240w,
/devHistoryBlog/static/8da319325ee3518a439824e6331866c8/e85cb/003-03.png 480w,
/devHistoryBlog/static/8da319325ee3518a439824e6331866c8/6114d/003-03.png 623w&quot;
        sizes=&quot;(max-width: 623px) 100vw, 623px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h4&gt;##3-1. @NoArgsConstructor 의 접근자는 Private로 한다.&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;@RequestBody 를 사용하면 Spring 내부에서 Jackson 라이브러리를 사용하여 Deserialize (JSON 데이터와 Request 객체 사이의 변환) 을 한다.&lt;/li&gt;
&lt;li&gt;이때 기본 전략으로 Default Constructor + Reflection 을 사용한다. 이때 최소 접근자는 Private 이다.

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/0edbaa6e53d8d82ac1948d8cbd2130d5/a0209/003-04.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 725px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 11.249999999999998%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAACCAYAAABYBvyLAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAcUlEQVQI1zWMWw6DMAwEuU7tChIS8jAh6k/vf6SpQerHaHal1S7pKOy5EPeMdeFzCXMIw8S7Yu3lrsz5pbaT7Ptmg9rN7T1VWvKcjXVdWe6zmxATNSjzUEp0ZyVvSvdc45tSO3ZeD1sIqCoi+viPiPADV15AE4ryECEAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;003 04&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/0edbaa6e53d8d82ac1948d8cbd2130d5/a0209/003-04.png&quot;
        srcset=&quot;/devHistoryBlog/static/0edbaa6e53d8d82ac1948d8cbd2130d5/8ff5a/003-04.png 240w,
/devHistoryBlog/static/0edbaa6e53d8d82ac1948d8cbd2130d5/e85cb/003-04.png 480w,
/devHistoryBlog/static/0edbaa6e53d8d82ac1948d8cbd2130d5/a0209/003-04.png 725w&quot;
        sizes=&quot;(max-width: 725px) 100vw, 725px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;##3-2. Data Validation&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Bean Validation에서 제공하는 @NotNull, @NotBlank, @Pattern 등을 사용하여 Request Data에 대한 오류를 최소화 한다.&lt;/li&gt;
&lt;li&gt;꼭 @RequestBody 옆에 @Valid 를 명시해줘야 한다.&lt;br&gt;
&lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/83f137a7f7568267a24cd8ac6094b064/33a7b/003-05.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 12.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAkUlEQVQI11WMWxaCMAwFWQ5Q09Y+kpZQqu5/T1fAx9GPOZmbjxl6D+g3BVdB1YplW1E4oInHulPEQWSG8IycX8RISFmQWRBiAkvdfwlp38NSElrrKEVRq0LbhlULHpvg3hh9v6p0BvngE+TyH0z53AMZA3vxcORBhmCtwzUkuGuE8+F0IotxnDFN5s3h0w/j158BaV+p0FDlkwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;003 05&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/83f137a7f7568267a24cd8ac6094b064/d9199/003-05.png&quot;
        srcset=&quot;/devHistoryBlog/static/83f137a7f7568267a24cd8ac6094b064/8ff5a/003-05.png 240w,
/devHistoryBlog/static/83f137a7f7568267a24cd8ac6094b064/e85cb/003-05.png 480w,
/devHistoryBlog/static/83f137a7f7568267a24cd8ac6094b064/d9199/003-05.png 960w,
/devHistoryBlog/static/83f137a7f7568267a24cd8ac6094b064/33a7b/003-05.png 1119w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
      &lt;/li&gt;
&lt;li&gt;Validation이 실패할 경우, MethodArgumentNotValidException 의 예외가 발생한다.

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/9d0c349132ff7b8265c54c3ec18f8b51/eba85/003-07.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 28.333333333333332%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABJ0AAASdAHeZh94AAAA8klEQVQY022Q3bKDIBCDfZ0q7g8gVp3W0/d/qJws9LIXmcDM7kfCVJvhagvOK+M4K/3C/TrweZ/43Bf+6PfV8N4NbSvIdUOlcqnwXLpEFcuSMM8zJs0KU8d+vLC1A23fse8NtWRsBITn7CiloNQK84y6NagZUlqxris9EbgMoBCoagSeaM8AHqjtyeWNw4JVpHssJC7HPRZ/KWZ6QhGD82Vzp6xXMKfyuKsGNPWZzIrpm+aXRsIkcHNoLJvQdSjOlDBVtIj/UlNWXLB81VN3Sa8+WSEoPQjUvmABptzLSM3/dRneYZLYgIAQz2M2979VNvsHOkq7d095jcEAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;003 07&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/9d0c349132ff7b8265c54c3ec18f8b51/d9199/003-07.png&quot;
        srcset=&quot;/devHistoryBlog/static/9d0c349132ff7b8265c54c3ec18f8b51/8ff5a/003-07.png 240w,
/devHistoryBlog/static/9d0c349132ff7b8265c54c3ec18f8b51/e85cb/003-07.png 480w,
/devHistoryBlog/static/9d0c349132ff7b8265c54c3ec18f8b51/d9199/003-07.png 960w,
/devHistoryBlog/static/9d0c349132ff7b8265c54c3ec18f8b51/eba85/003-07.png 1054w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;h3&gt;#4. Response Dto 클래스&lt;/h3&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/dd4f2ddab4b21bea77b93a35005efb67/27524/003-08.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 646px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 46.666666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAABJ0AAASdAHeZh94AAABOElEQVQoz5WSSXbDIBBEfRwz0w1CaLRf7n+nSoPkQdll8V8zFlTBjXNB5AHMHvumMRYNrQ2UeqE6Wut3u6M/48aYXhu3lyCxw74rrKsWcY0YD4hIKsM5J1XarU+MGAgcErzzb9HGLQ0jOAsUsFeNuRiso8E8GExZYaojlvWJOs1IWQ4WMeIECowUM7wPV8EuJrf03mPwIkYGIweUsWKU8UK5z/kQT9v3k6vlL8ECEpxsskbD2TYh1ai+wFp7IH0rts2rL+2/uR4ZNsulwskN2Gs8skEli62mbnN7/mCaFqx1wro06wuW7YF52ZBlL/ERAQvtoOOGaeihtwH2FtEZCV4WpdwJkhPJA0RP/WGaQKtNhE44JXH3JehD6LZV+zJvK/fTyvlNtLp+na8sP5ZPwXbiEfA15P/yC643FlBwuoIjAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;003 08&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/dd4f2ddab4b21bea77b93a35005efb67/27524/003-08.png&quot;
        srcset=&quot;/devHistoryBlog/static/dd4f2ddab4b21bea77b93a35005efb67/8ff5a/003-08.png 240w,
/devHistoryBlog/static/dd4f2ddab4b21bea77b93a35005efb67/e85cb/003-08.png 480w,
/devHistoryBlog/static/dd4f2ddab4b21bea77b93a35005efb67/27524/003-08.png 646w&quot;
        sizes=&quot;(max-width: 646px) 100vw, 646px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h4&gt;##4-1. 객체 생성을 위해 필드가 3개 이상일 경우는 @Builder를 사용한다.&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;@Builder 사용 시 All Arguments Constructor 가 자동으로 생성된다.  &lt;/li&gt;
&lt;li&gt;생성자를 이용한 객체 생성을 막기 위해 생성자를 따로 정의한 후(@AllArgsConstructor) 접근제어자를 Private로 정의한다.&lt;br&gt;
&lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/c7baa199350d983fb243c2b869cc1743/4d08a/003-09.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 709px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 15.416666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAmElEQVQI1z3Paw6EIAwEYI/jCihQoDwUNHv/M812Nbs/vgxNk0mZKDICV1gijDHjPBf0vsA6YX8MnCNJD621pJP9Y5O32/xtWy0mHxJCbvAxoe8zxqFwSWktCzIr8QKzRWsXau13WcrlxrkiJkb0DKYMcuEpJM5w3qORXBcU2ElpevKQudCKsg+M643aDnj5jTHmpr+U/vsAR01f8shqGNIAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;003 09&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/c7baa199350d983fb243c2b869cc1743/4d08a/003-09.png&quot;
        srcset=&quot;/devHistoryBlog/static/c7baa199350d983fb243c2b869cc1743/8ff5a/003-09.png 240w,
/devHistoryBlog/static/c7baa199350d983fb243c2b869cc1743/e85cb/003-09.png 480w,
/devHistoryBlog/static/c7baa199350d983fb243c2b869cc1743/4d08a/003-09.png 709w&quot;
        sizes=&quot;(max-width: 709px) 100vw, 709px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;##4-2. 객체 생성을 위해 필드가 3개 이상일 경우는 @Builder를 사용한다.&lt;/h4&gt;
&lt;h4&gt;##4-3. @Getter 필요 이유&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;@ResponseBody 를 사용하면 Spring 내부에서 Jackson 라이브러리를 사용하여 Response 객체를 Serialize(ByteCode로 변환) 하는데 이때 getter 메소드를 사용한다.  &lt;/li&gt;
&lt;li&gt;따라서 response 객체는 @Getter 를 사용해야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;hr&gt;
&lt;br&gt;
&lt;h2&gt;MapStruct&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;DTO -&gt; Entity, Entity -&gt; DTO의 객체 매핑을 위한 라이브러리&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;#1. gradle 추가&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;롬복과 함께 사용 시, lombok annotationProcessor 보다 mapstruct annotationProcessor가 먼저 선언이 되야 한다.&lt;/li&gt;
&lt;li&gt;SpringBoot 버전에 호환하는 MapStruct 버전이 존재, 해당부분 확인 필요

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/17bbbd0c849a5fb8341395ca3b978c3f/fbf08/003-10.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 20.833333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAkUlEQVQY02WPaxLDIAiEcx4FxFcck/ufa0uI7TTtj53dAYWPrbQBLQ0xRqgqSikuZrZaAFH0XjT/5LiyKYTw0Fb7PZCIMOfEeZ7uYwzUXlBHNuly067ILaF0W25ZEoOFIHq7D8yLUESQUnK6q8lMt9snWpkW1YP6y/8Ij+Nwun10J7xI3mRtZmgVey++4PfcSy8nq3wd02Z9uwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;003 10&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/17bbbd0c849a5fb8341395ca3b978c3f/d9199/003-10.png&quot;
        srcset=&quot;/devHistoryBlog/static/17bbbd0c849a5fb8341395ca3b978c3f/8ff5a/003-10.png 240w,
/devHistoryBlog/static/17bbbd0c849a5fb8341395ca3b978c3f/e85cb/003-10.png 480w,
/devHistoryBlog/static/17bbbd0c849a5fb8341395ca3b978c3f/d9199/003-10.png 960w,
/devHistoryBlog/static/17bbbd0c849a5fb8341395ca3b978c3f/fbf08/003-10.png 962w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;h3&gt;#2. Mapper Interface 생성&lt;/h3&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/aec804f2711a670a547440659818a3ef/7b1dc/003-11.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 956px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 23.75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAABYlAAAWJQFJUiTwAAAA8klEQVQY002QSXLFIAxEfR4zisFmsk1+XJX7n6gjtPqLLgHVPLW0hZgxu8ZVDJ5W8F4dz7gxP3945ovWb8SUEWJCPk6p5ANSyDDWQqmdpbDvSs4bsaFnx8CEn1Exa0Y/G67rxbgm7vkRSIhRgBSi3FM+4CkgWAVyGrv6AmrrQDHLpxgIwVmWgzWaAQuWpUaGSEKGLuBKTkbBm5VwF23L6D2htIFyJh474Pc+8PSI2QijnRi9oZWMWitqvxiUUNl/lgrHzZXWMMaIttV9RZc9sSzvJyQejd+OaFkGJRm0bJGil4SeCGl5eQLLe/Tes5+4OvwDBgugNqNYuUEAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;003 11&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/aec804f2711a670a547440659818a3ef/7b1dc/003-11.png&quot;
        srcset=&quot;/devHistoryBlog/static/aec804f2711a670a547440659818a3ef/8ff5a/003-11.png 240w,
/devHistoryBlog/static/aec804f2711a670a547440659818a3ef/e85cb/003-11.png 480w,
/devHistoryBlog/static/aec804f2711a670a547440659818a3ef/7b1dc/003-11.png 956w&quot;
        sizes=&quot;(max-width: 956px) 100vw, 956px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h4&gt;##2-1. @Mapper 사용&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;매핑 정책(Policy)과 전략(Strategy)를 설정할 수 있다.  &lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;정책&lt;/th&gt;
&lt;th&gt;값&lt;/th&gt;
&lt;th&gt;설명&lt;/th&gt;
&lt;th&gt;예시&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;unmappedSourcePolicy&lt;/td&gt;
&lt;td&gt;IGNORE(default), WARN, ERROR&lt;/td&gt;
&lt;td&gt;Source의 필드가 Target에 매핑되지 않을 때 정책이다.&lt;/td&gt;
&lt;td&gt;ERROR로 설정하면 매핑 시 Source.aField가 사용되지 않는다면 컴파일 오류가 발생시킨다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;unmappedTargetPolicy&lt;/td&gt;
&lt;td&gt;IGNORE, WARN(default), ERROR&lt;/td&gt;
&lt;td&gt;Target의 필드가 매핑되지 않을 때 정책이다.&lt;/td&gt;
&lt;td&gt;ERROR로 설정하면 매핑 시 Target.aField에 값이 매핑되지 않는다면 컴파일 오류가 발생시킨다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;typeConversionPolicy&lt;/td&gt;
&lt;td&gt;IGNORE(default), WARN, ERROR&lt;/td&gt;
&lt;td&gt;타입 변환 시 유실이 발생할 수 있을 때 정책이다.&lt;/td&gt;
&lt;td&gt;ERROR로 설정하면 long에서 int로 값을 넘길 때 값에 유실이 발생할 수 있다. 이런 경우에 컴파일 오류를 발생시킨다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;전략&lt;/th&gt;
&lt;th&gt;값&lt;/th&gt;
&lt;th&gt;설명&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;nullValueMappingStrategy&lt;/td&gt;
&lt;td&gt;RETURN&lt;em&gt;NULL(default), RETURN&lt;/em&gt;DEFAULT&lt;/td&gt;
&lt;td&gt;Source가 null일 때 정책이다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;nullValuePropertyMappingStrategy&lt;/td&gt;
&lt;td&gt;SET&lt;em&gt;TO&lt;/em&gt;NULL(default), SET&lt;em&gt;TO&lt;/em&gt;DEFAULT, IGNORE&lt;/td&gt;
&lt;td&gt;Source의 필드가 null일 때 정책이다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;##2-2. INSTANCE 생성&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;빌드 시점에 CouponMapper 를 상속받은 CouponMapperImpl(구현체) 클래스가 생성된다.&lt;/li&gt;
&lt;li&gt;따라서 이 구현체를 사용할 수 있는 객체를 생성한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;h3&gt;#3. Mapper 사용&lt;/h3&gt;
&lt;h4&gt;#3-1. Dto to Entity 또는 Entity to Dto 선언부 생성&lt;/h4&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/e12d18b9ab88729fb7fee6f030ace81a/5bf79/003-12.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 8.75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAACCAYAAABYBvyLAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAdElEQVQI1yXOURLDIAgE0NxHZyrRiLLYNNPe/0pbmn4wfABv2R6lUCfYe6dr4Xs1vlB5QQjdOc1oAIcqVQfNn2xHpw7jhLPWypQSc853bUX2e2BYcdS5HEQAPv7oicbLD34iCKYBnjc4Y18jROIhEWGJ/sO/mE9BjaqO7VwAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;003 12&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/e12d18b9ab88729fb7fee6f030ace81a/d9199/003-12.png&quot;
        srcset=&quot;/devHistoryBlog/static/e12d18b9ab88729fb7fee6f030ace81a/8ff5a/003-12.png 240w,
/devHistoryBlog/static/e12d18b9ab88729fb7fee6f030ace81a/e85cb/003-12.png 480w,
/devHistoryBlog/static/e12d18b9ab88729fb7fee6f030ace81a/d9199/003-12.png 960w,
/devHistoryBlog/static/e12d18b9ab88729fb7fee6f030ace81a/5bf79/003-12.png 966w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h4&gt;#3-2. @Getter, @Builder 설정&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;변환과정에서 꺼내오는 객체(source)에는 Getter가 있어야 하고, 변환해서 저장하고자 하는 객체(target)에는 Builder 혹은 Setter가 있어야 하는데 Setter는 지양한다.  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/bb9e9e4e6fcc0f2a3d120848bf434620/9d576/003-13.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 541px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 16.249999999999996%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAABJ0AAASdAHeZh94AAAAgUlEQVQI143OMRLDMAgEQH8n4BlLFhghRXHy/0ddsKqkc7FzBQzcUtSQi2JLO6oRxiCoEIg4/OY9ixwVWa6DBb0R3i+aeanG4QH3mPUPzBpSjsetw6pPqhUufUopY7ka7npES4EmwikM2RjPwjgSw4LnFRJ73ge8DfRTwSvP9sz/vlNfXncPyFC2AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;003 13&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/bb9e9e4e6fcc0f2a3d120848bf434620/9d576/003-13.png&quot;
        srcset=&quot;/devHistoryBlog/static/bb9e9e4e6fcc0f2a3d120848bf434620/8ff5a/003-13.png 240w,
/devHistoryBlog/static/bb9e9e4e6fcc0f2a3d120848bf434620/e85cb/003-13.png 480w,
/devHistoryBlog/static/bb9e9e4e6fcc0f2a3d120848bf434620/9d576/003-13.png 541w&quot;
        sizes=&quot;(max-width: 541px) 100vw, 541px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/77b064f1f1b366f0858f879197b871f0/ca12d/003-14.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 647px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 131.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAaCAYAAAC3g3x9AAAACXBIWXMAABYlAAAWJQFJUiTwAAACqklEQVRIx51V23biMAzkc+r73UmcANv+/z9pR04IgeVsSx90bGIzHmnG8inmgXys1JqlZRZkrSIhFEmJUUrMBeZyC8z77zWEXNeUUvt4WgFLB7xeJOUkO6hzkpw1GANpbcgYg+/uHsZj3ZPB2g3sAXBZLP25CmqTpLlJmkZB89IQXzROMw2Isc3UlgsNudJSChVkZo19AiwDBYC26ug6KBqSopYB2Eaaz/hzy+R8AFNP1rk+N1pRMEhXyZ72Q8oJgKkCNAQ6z40qTl5P033URj3WcZsL1FhJ9QC2AzJLPr04RckxA30Q4r75VTyv3wG9gyAfFIOACOJh43egLwEdAC+XDLUTip13lr8G5JSVtqgZLIFRSfnSZ28x/DwLOjcBgezmNYf0D0zfZRgNjA1ThxAp5ULJwzIHn/2E5Yktc2NYqwCQ7KKwVW4pH9X+DvQOCIbnKhGKalAUYZ8c+DbApz5is+z3+62UDVJmIyu1GXdjpN+wz5Mokq4NDCMMbiV5axFhY/fTlA8MvZa4o6oHA7IgDKh/a5uKGpaiaBwVmd4Xtx74lsrHu1wrukzrbauU1Tbcori7/OvB1+Doh5UCM0S38V6AmVxFEZt1xMcW4jHkmsFxD2dzGttC0+ULPTHTdUJTRU/0ToOx7wYPMcGbGYd5ipjHlPu3AEdElIl/90uAYOud6thomM9kAJDBbgq6+4//NKFDxxgBFvpmbq4emfSGC0DvIBofiuDRwBU9ZQ6Nu8vKtmRoygsFmHlBx3ZG97RudZPbwyUOj9gteG3v2AaAHqcWb5AKUuuCjP2RSqVSGcb+piQw/p/au8oMaNmHsAt7jx8frhN/E0/t/1vbMEMWwVu9Axo2NQzuzJP/Ds3iVZwK0mGlLp8LfFjQB/HeQlFWtRefhXgj/gK0HyB0aRafRwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;003 14&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/77b064f1f1b366f0858f879197b871f0/ca12d/003-14.png&quot;
        srcset=&quot;/devHistoryBlog/static/77b064f1f1b366f0858f879197b871f0/8ff5a/003-14.png 240w,
/devHistoryBlog/static/77b064f1f1b366f0858f879197b871f0/e85cb/003-14.png 480w,
/devHistoryBlog/static/77b064f1f1b366f0858f879197b871f0/ca12d/003-14.png 647w&quot;
        sizes=&quot;(max-width: 647px) 100vw, 647px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/ed749df7538d664edec5d824a180da2d/977f7/003-15.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 547px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 22.083333333333332%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAnUlEQVQY042PWQ7CMAxEexxiQ5qFNM6GuP+lBrepBEh88DGaKFZenpe4CcJ9g7UOtRj0RoiBYAyDmUDEGvo7y/0EXhX4GAZjEIrQhPHZtPcbvJ9/5QDGlLFb2pDU7qJQQqukthNcxEDEo7UnSulwPiBLRcqCXLT1fY4FNels9RN4rOwCxBN6ZCTHs1fWO8bmLZJ+Wvs4YDdrv4w/zV8UKXzJaofKyAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;003 15&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/ed749df7538d664edec5d824a180da2d/977f7/003-15.png&quot;
        srcset=&quot;/devHistoryBlog/static/ed749df7538d664edec5d824a180da2d/8ff5a/003-15.png 240w,
/devHistoryBlog/static/ed749df7538d664edec5d824a180da2d/e85cb/003-15.png 480w,
/devHistoryBlog/static/ed749df7538d664edec5d824a180da2d/977f7/003-15.png 547w&quot;
        sizes=&quot;(max-width: 547px) 100vw, 547px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;br&gt;
&lt;h5&gt;201203 수정사항&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Dto 클래스 내 Mapper 호출 메소드 명 변경&lt;br&gt;
—&gt; createReqToEntity() -&gt; toEntity()&lt;br&gt;
—&gt; entityToCreateRes() -&gt; of()  &lt;/li&gt;
&lt;li&gt;Response Dto 클래스 내 Validation 제거&lt;br&gt;
— res Dto 클래스 serialize 전 validation 로직 없음  &lt;/li&gt;
&lt;li&gt;MethodArgumentNotValidException 이미지 추가&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[[SpringBoot]RequestBody Validation]]></title><link>https://ssongey.github.io/history/posts/2020-11-10--004</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-11-10--004</guid><pubDate>Tue, 10 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Bean Validation (Hibernate Validation) 에서 제공하는 표준 Validation&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;사용법 : @AnnotationName(message=“Exception Message”)&lt;/li&gt;
&lt;li&gt;validation 이 실패 할 경우, MethodArgumentNotValidException 의 예외가 발생.&lt;/li&gt;
&lt;li&gt;이처럼 이러한 Validation 을 용도 및 상황에 맞게 사용한다면 사용자의 오류나 시스템의 오류를 최소화 할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Bean Validator&lt;/th&gt;
&lt;th&gt;설명&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;@NotNull&lt;/td&gt;
&lt;td&gt;Null만 허용안함, &quot;&quot; 이나 ” ” 일 경우 예외&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;@NotEmpty&lt;/td&gt;
&lt;td&gt;Null, &quot;&quot; 허용 안함, ” ” 일 경우 예외&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;@NotBlank&lt;/td&gt;
&lt;td&gt;Null, &quot;&quot;, ” ” 일 경우 예외 (String 객체에서 주로 사용)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;@Min(숫자)&lt;/td&gt;
&lt;td&gt;최소값&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;@Max(숫자)&lt;/td&gt;
&lt;td&gt;최대값&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;@Size(min=숫자, max=숫자)&lt;/td&gt;
&lt;td&gt;Max, Min 모두 포함&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;@Email&lt;/td&gt;
&lt;td&gt;이메일 형식이 아닌 경우 예외 발생&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;@Pattern(regexp = “정규식”)&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;참고)
&lt;a href=&quot;https://beanvalidation.org/2.0/spec/&quot;&gt;https://beanvalidation.org/2.0/spec/&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Lombok - Can not find symbol]]></title><link>https://ssongey.github.io/errors/posts/2020-11-10--001</link><guid isPermaLink="false">https://ssongey.github.io/errors/posts/2020-11-10--001</guid><pubDate>Tue, 10 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/4fd6968ae85b4663590439a611cde5d2/07eba/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 565px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 17.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAABJ0AAASdAHeZh94AAAAtUlEQVQY03WMWQ6CMBRFWZnDj1AcQoKVwbgBBQSp83ooifBpYXnXlsYoJn6cnJt7X55B8xKrQwk35VhmBWjG4cnujc/UzjGPOKa7/9jbAjNpw2ENnFxgcRCg5xbhvZVuOsJbg+Cq3MJhAlbyhBk/O3c5+WQrESB7AYPsHrCjCpa0k1bYXGqsWA3vWCM81whO2msJzWUvN8r0jX/UnbLqZ3EFY2C6GEw0Q5lHVp8x+cq/kL7Vrxe9A7b+xW1yLAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/4fd6968ae85b4663590439a611cde5d2/07eba/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/4fd6968ae85b4663590439a611cde5d2/8ff5a/001-01.png 240w,
/devHistoryBlog/static/4fd6968ae85b4663590439a611cde5d2/e85cb/001-01.png 480w,
/devHistoryBlog/static/4fd6968ae85b4663590439a611cde5d2/07eba/001-01.png 565w&quot;
        sizes=&quot;(max-width: 565px) 100vw, 565px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h3&gt;문제&lt;/h3&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/808e020dcee03895070ef6f8abdf0ab3/854dc/001-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 569px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 21.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAABJ0AAASdAHeZh94AAAAxElEQVQY04WPS07EMBBEcxwm/juxnZ+TmMkMrJHYzyXm/A8zIITEgkWpSq/Vrerm7dUwTYJtleSsidHheosPli44rNFIKVBKPSSl/PGTHnmyK9L0SCEerMnRcgyaZR7Zzxe2/Zl1K5TzlbyMvJTEUWa2crDW2ZI3ynEhrxmz39DXO/PxTgwd1jqaz6vJCYIVtVEkjRN9TKThy7s+Emvu+oDzHTGN1T3GKYyVeO8qGwh1V9VPGqU1ba3btu23Tr/yfxJ/2AfR3n/Tnc7raQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/808e020dcee03895070ef6f8abdf0ab3/854dc/001-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/808e020dcee03895070ef6f8abdf0ab3/8ff5a/001-02.png 240w,
/devHistoryBlog/static/808e020dcee03895070ef6f8abdf0ab3/e85cb/001-02.png 480w,
/devHistoryBlog/static/808e020dcee03895070ef6f8abdf0ab3/854dc/001-02.png 569w&quot;
        sizes=&quot;(max-width: 569px) 100vw, 569px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Dto 클래스에 @Builder 사용 시 builder() 메소드를 찾을 수 없다는 에러 발생&lt;/p&gt;
&lt;h3&gt;원인&lt;/h3&gt;
&lt;p&gt;Lombok의 어노테이션을 사용할 경우 컴파일 시 어노테이션을 먼저 스캔해서 코드(getter, setter 등)로 변환해주는 선처리가 필요
또는
IntelliJ에서 “Enable annotation processing” 을 활성화 &lt;/p&gt;
&lt;h4&gt;AnnotationProcessor?&lt;/h4&gt;
&lt;p&gt;어노테이션 프로세싱은 자바 컴파일러의 컴파일 단계에서, 유저가 정의한 어노테이션의 소스코드를 분석하고 처리하기 위해 사용되는 훅이다. 컴파일 에러나 컴파일 경고를 만들어내거나, 소스코드(.java)와 바이트코드(.class)를 내보내기도 한다.&lt;/p&gt;
&lt;h3&gt;해결&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;build.gradle 에 annotationProcessor 추가&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;annotationProcessor &lt;span class=&quot;token string&quot;&gt;&apos;org.projectlombok:lombok&apos;&lt;/span&gt;
testAnnotationProcessor &lt;span class=&quot;token string&quot;&gt;&apos;org.projectlombok:lombok&apos;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 테스트 코드에서 lombok 사용 시&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;- 2. IntelliJ File -&amp;gt; Settings 에서 아래 그림과 같이 설정
![](./001-03.PNG)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[/etc/logrotate.d 설정하기]]></title><link>https://ssongey.github.io/works/posts/2020-11-06--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2020-11-06--001</guid><pubDate>Fri, 06 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;/home/jenkins/workspace/V2G-Prod-Server/logs/*log 
/home/jenkins/workspace/V2G-Dev-Server/logs/*log &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    daily                                         
    compress                                      
    dateext                                       
    maxage &lt;span class=&quot;token number&quot;&gt;365&lt;/span&gt;                                    
    notifempty                                    
    missingok                                     
    copytruncate                                  
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;                                                 &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;옵션&lt;/th&gt;
&lt;th&gt;설명&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;rotate 숫자&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;log 보관 갯수 ex) rotate 5 : log파일이 5개 이상시 삭제&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;maxage 숫자&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;log 파일 생명 주기 ex) maxage 20 : 20일 경과시 삭제&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;size&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;지정된 용량보다 클 경우 로테이트 실행 ex) size +100k : 100k 이상 시 로테이트&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;daily&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;일 단위 파일순환&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;weekly&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;주 단위 파일순환&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;monthly&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;월 단위 파일순한&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;missingok&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;파일이 없어도 상관없음(에러가 아니도록 처리)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;notifempty&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;로그내용이 없으면 로테이트 안함&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;ifempty&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;로그 내용이 없어도 로테이트 진행&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;compress&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;로그파일을 gzip으로 압축하여 보관&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;nocompress&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;압축 안함&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;dateext&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;rotate된 로그파일명에 날짜 표시&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;dateyesterday&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;dateext 옵션과 함께 쓰면 파일명의 날짜에 어제 날짜로 저장&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;copytruncate&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;이 옵션을 넣지 않으면 현재 사용중인 로그를 다른이름으로 move하고 새로운 파일을 생성한다&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2&gt;# logrotate 수행&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;설정파일의 오류확인 - debug 모드로 실제 로테이션은 되지 않음&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;$ /usr/sbin/logrotate -d /etc/logrotate.d/v2g&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;설정파일을 강제수행&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;$ /usr/sbin/logrotate -f /etc/logrotate.d/v2g&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;# Cron 등록&lt;/h2&gt;
&lt;p&gt;syslog가 순환되고 있는 것은 cat /etc/cron.daily/logrotate 파일에 정의되어 crontab에서 실행되고 있다.
로테이션을 위해 생성한 /data/logs/test_logrotate 파일을 /etc/logrotate.d/ 하위에 두면 rsyslog가 로테이션되는 시간에 같이 로테이션 된다.
또는 해당 원하는 시간에  crontab에 추가하여 별도 관리하여도 된다.
1일치 로그로 관리하기 위하여 0시에 순환되도록 아래와 같이 설정한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;$ sudo crontab -e

0 0 * * * /usr/sbin/logrotate -f /etc/logrotate/v2g&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[[MariaDB] DB 백업 및 복구]]></title><link>https://ssongey.github.io/works/posts/2020-11-06--002</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2020-11-06--002</guid><pubDate>Fri, 06 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;백업(Export)&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;// 전체 DB 백업 
// mysqldump -u [DB계정명] -p -A &amp;gt; [저장할 파일명]
// mysqldump -u [DB계정명] -p --all-databases &amp;gt; [저장할 파일명]
$ mysqldump -u root -p -A &amp;gt; all.sql

// 특정 DB 백업 
// mysqldump -u [계정명] -p [DB명] &amp;gt; [저장할 파일명]
$ mysqldump -u root -p v2g &amp;gt; v2g.sql

// 생성 스크립트만 백업
// mysqldump -u [계정명] -p -d [DB명] &amp;gt; [저장할 파일명]
// mysqldump -u [계정명] -p --no-data [DB명] &amp;gt; [저장할 파일명]
$ mysqldump -u root -p -d v2g &amp;gt; v2g_ddl.sql

// 특정 Table 백업
// mysqldump -u [계정명] -p [DB명] [Table명] &amp;gt; [저장할 파일명]
$ mysqldump -u root -p v2g ca_cert leaf_cert &amp;gt; v2g_certs.sql

// 특정 table 제외하고 백업
// mysqldump -u [계정명] -p [DB명] --ignore-table=[DB명].[테이블명] &amp;gt; [저장할 파일명]
$ mysqldump -u root -p v2g --ignore-table=v2g.ca_cert --ignore-table=v2g.leaf_cert &amp;gt; v2g_ignore_certs.sql
 &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;복구(Import)&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;// mysqldump -u [DB계정명] -p [DB명] &amp;lt; [불러올 파일명]
$ mysqldump -u root -p v2g &amp;lt; v2g.sql&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[logrotate: because parent directory has insecure permissions]]></title><link>https://ssongey.github.io/errors/posts/2020-11-06--001</link><guid isPermaLink="false">https://ssongey.github.io/errors/posts/2020-11-06--001</guid><pubDate>Fri, 06 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/8a9e121d7ea7426672e413aefa7b924d/1e093/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 5.833333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAABCAYAAADeko4lAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAQ0lEQVQI1yXKXQ6AMAgDYI/kD1Bgc9P7H6qS+dA0/dKtdXDM5PN23iNWz9oeQsNJ0Z3wi2rHSqRSy7zM8Fs2Kxei/h8vDyEAYj/4fwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/8a9e121d7ea7426672e413aefa7b924d/d9199/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/8a9e121d7ea7426672e413aefa7b924d/8ff5a/001-01.png 240w,
/devHistoryBlog/static/8a9e121d7ea7426672e413aefa7b924d/e85cb/001-01.png 480w,
/devHistoryBlog/static/8a9e121d7ea7426672e413aefa7b924d/d9199/001-01.png 960w,
/devHistoryBlog/static/8a9e121d7ea7426672e413aefa7b924d/1e093/001-01.png 1376w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h3&gt;문제&lt;/h3&gt;
&lt;p&gt;logrotate 설정 후 강제 수행 시 오류 발생&lt;/p&gt;
&lt;h3&gt;원인&lt;/h3&gt;
&lt;p&gt;디렉토리의 권한이 너무 많아 insecure 하여 생긴 오류&lt;/p&gt;
&lt;h3&gt;해결&lt;/h3&gt;
&lt;p&gt;group, other write 권한을 제거&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;$ chmod 755 /home/jenkins/workspace/V2G-Dev-Server/logs&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[[CURL] curl 사용법]]></title><link>https://ssongey.github.io/works/posts/2020-11-05--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2020-11-05--001</guid><pubDate>Thu, 05 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt;CURL ?&lt;/span&gt;&lt;br/&gt;
다양한 프로토콜을 지원하는 데이터 전송용 Command Line Tool 이다.
(Http, Https, FTP, SFTP, SMTP 등을 지원)&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt;GET&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;$ curl -d &amp;quot;key1=value&amp;amp;key2=value2&amp;quot; -H &amp;quot;Content-Type: application/x-www-form-urlencoded&amp;quot; -X GET http://localhost:8080/data&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt;POST&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;# x-www-form-urlencoded
$ curl -H &amp;quot;Content-Type: application/x-www-form-urlencoded&amp;quot; -d &amp;quot;key1=value&amp;amp;key2=value2&amp;quot; -X POST http://localhost:8080/data&amp;quot;

# application/json
$ curl -H &amp;quot;Content-Type: application/json&amp;quot; -d &amp;#39;{&amp;quot;key1&amp;quot;:&amp;quot;value&amp;quot;, &amp;quot;key2&amp;quot;:&amp;quot;value2&amp;quot;} -X POST http://localhost:8080/data&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&quot;title__sub1&quot;&gt;옵션 정리&lt;/span&gt;
&lt;span class=&quot;title__sub2&quot;&gt;http의 메소드를 지정 [ -X ]&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;$ curl -X [PUT|GET|POST] http://www.example.net&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt;response header 확인 [ -I, i ]&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;# 헤더만 출력
$ curl -I http://www.example.net

# header와 body 둘다 출력
$ curl -i http://www.example.net&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt;SSL 인증서 에러 무시 [ -k ]&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;$ curl -k https://www.example.net&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt;output [ -o ]&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;$ curl -o /dev/null http://www.example.net&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt;특정 포맷에 맞게 write [ -w ]&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;# status code 출력
$ curl -w &amp;#39;%{http_code}\n&amp;#39; http://www.example.net&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt;진척상황 표시하지 않기 [ -s ]&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;# 에러도 표시되지 않음
$ curl -s https://www.example.net

# 에러는 표시
$ curl -sS https://www.example.net&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt;프록시 이용시 [ -x, —proxy ]&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;$ curl --proxy &amp;lt;proxyip&amp;gt;:&amp;lt;port&amp;gt; http://www.example.net
$ curl -x &amp;lt;proxyip&amp;gt;:&amp;lt;port&amp;gt; http://www.example.net

$ curl -x &amp;lt;proxyip&amp;gt;:&amp;lt;port&amp;gt; --proxy-user &amp;lt;username&amp;gt;:&amp;lt;password&amp;gt; http://www.example.net
$ curl -x &amp;lt;username&amp;gt;:&amp;lt;password&amp;gt;@&amp;lt;proxyip&amp;gt;:&amp;lt;port&amp;gt; http://www.example.net&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class=&quot;title__sub2&quot;&gt;최대접속시간제한을 설정 [ —connect-timeout ]&lt;/span&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;$ curl --connect-timeout 600 http://www.example.net&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Linux에서 tcp dump 확인]]></title><link>https://ssongey.github.io/works/posts/2020-11-04--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2020-11-04--001</guid><pubDate>Wed, 04 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; tcpdump -vvX &lt;span class=&quot;token string&quot;&gt;&quot;dst port 15000&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/c8cf52f78320eb5e0a640b4f26f8e46f/ee455/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 863px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 127.49999999999999%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAaCAYAAAC3g3x9AAAACXBIWXMAABYlAAAWJQFJUiTwAAAEPklEQVRIx11V2XLbRhDEr+SyJIuSeAskAeIGSAIQD1NiTB+SJb34zbYOqyqpSqqSf0me/Iud6VmASvKwhd3FbM9MT8+ulU0ihKGLKPYwncYIZN7pHGM46uHU7mAw7MIedDAcct2WdQ+Oe6prx7Uxcvo7m27vBJYfOMiLDEkSoCgnSNJQf/KgOx7oGDkCMOpjJMNxDFine6w2BOv1mjhpvsTxyQEsTl5vN4iiMWZ5htWrOcqziTpZrxdYLgtZT3E2zzGbJTKfwfdHaLUbGp096MLzhjg63kfjaA9Ws9XAfFHA84eS9hhx4isF/JKONAt1cE6n3DcpdhFGrlKUZgGarUMBFcB2p4FyTq8GMEkJ6CAQ4yTxdPAg9+OEgB7GY1u/U4k4y2KZBxLdAfb2f4T1094LiXAhXm3haShAIYLAhx8E4j2Qw4wiFGeR8OnCk3/D0UBtx56LoohQlgnS1Ba7DqxPnxf4+nSJu/sL3N9vcHdnxtPTG9l/i4fH13h83OKL7tPmZzw8bPD5ywV++/0Nvn27w19/f8Iff27xy6/nsC42AT5+3ODyKsf7yxzX13NcXRW4uZ3j9naJm5s5rmV8uD6Tf6XuvXs/lf8LXH0o8fZdge12KhV+ie9/+A7W/sGeEJ6JxnpC9Kmm4bhDSU94DH1dc677jkmz22tr2mEUqO3Yc7Tqxyf7sFpSlIvNKy0IyZ/lqVaNhE9E6PXg/ixPtNqeN1CbWgVsCOrysPFCANsEXCOOWVFftUgNUuQEKao5D/MgdTgWQDbCbJaqPjMBbXeODCB1mBcT7Qh2DSVAcOqNUVAenHNQh0kaqGzGImYCTcUpNUwdVsI+1KhcMfKkA3iAB9nbNWCaRbrvByNN0XUpEafakyBiXzk0EcpkuZqL9hyNgtylYkjemCIPZRPySP5CpYG2/E8atIOEfwVkhK32EdbnS203HiZf06oIeTUIxixML081RTrOZW++yHW+KwpTLsupNjibnqlqgZg6r7SZiVJHxSVvnFBoqZXA/f9wSE810awejU3Th7uCcJA3OjF3YE+ByDsD4K3VMCkbDkkujfMq5VgllGpRah7JIatKzkgNHZq7VIpSR7jjUERNgmlArnigLM29qHqkFgWAHLLa5jIO9P//dHgoP585ZLpMgdFOJCpW3Ggy1D2CMGWuSQuvOZ7hbf3MoQrbVs+hapAcjiswAY88I/gqfVaZ/wjK6CeSWbP1Lw557ROM7wnlkVTGtc6MBqu50MFC1M/BmVzOVAlxdoDr81V1Kxsd0iOBOc8r/phFUWYKwGoXsibgYllitSqfO4UTcsiGJyesJkWuT+agW72A3d0Lx2//tKUvn76EjnkJd7LhpWD05knargqVrUVO+f4ShI7M2tbicT+KDM9upV/ucViUQawXQYiFvH584Bk1vetDL1HWDzwjowPzfHbU1q6y6Pdb2n7/AFkjmqxwzDlVAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/c8cf52f78320eb5e0a640b4f26f8e46f/ee455/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/c8cf52f78320eb5e0a640b4f26f8e46f/8ff5a/001-01.png 240w,
/devHistoryBlog/static/c8cf52f78320eb5e0a640b4f26f8e46f/e85cb/001-01.png 480w,
/devHistoryBlog/static/c8cf52f78320eb5e0a640b4f26f8e46f/ee455/001-01.png 863w&quot;
        sizes=&quot;(max-width: 863px) 100vw, 863px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;# 자주사용하는 옵션&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;center&quot;&gt;옵션&lt;/th&gt;
&lt;th&gt;설명&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;-c [Number]&lt;/td&gt;
&lt;td&gt;제시된 수의 패킷을 받은 후 종료한다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;-i [Device]&lt;/td&gt;
&lt;td&gt;어느 인터페이스를 경유하는 패킷을 잡을지 지정한다. 지정되지 않으면 시스템의 인터페이스 리스트의 가장 낮은 번호를 가진 인터페이스를 선택(이 때 loopback은 제외)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;-v, -vv&lt;/td&gt;
&lt;td&gt;상세한 정보 출력&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;-w&lt;/td&gt;
&lt;td&gt;캡처한 패킷을 파일에 저장한다&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;-r file&lt;/td&gt;
&lt;td&gt;패킷들을 ‘-w’ 옵션으로 만들어진 파일로 부터 읽어 들인다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot;&gt;-x, -XXX&lt;/td&gt;
&lt;td&gt;각각의 패킷을 헥사 코드로 출력한다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;# Primitive&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;//packet의 IP destination 항목이  HOST 패킷일 때 출력.
$ tcpdump -i any dst host 10.10.10.1

//packet의 IP source항목이 HOST패킷일 때 출력.
$ tcpdump -i any src host 10.10.10.1

//IP source, IP destination 항목 중 어느 하나라도 HOST 패킷일 때 출력.
$ tcpdump -i any host 10.10.10.1

//패킷이 ip/tcp, ip/udp 프로토콜의 패킷이고 destination port의 값이 PORT일 때 출력.
$ tcpdump -i any src port 23

//패킷의 source port의 값으로 PORT를 가지면 출력.
$ tcpdump -i any dst port 23

//port PORT : 패킷의 source, destination port 중에 하나라도 PORT이면 출력.
$ tcpdump -i any port 23&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[예외 발생 시 트랜젝션 처리]]></title><link>https://ssongey.github.io/history/posts/2020-11-02--001</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-11-02--001</guid><pubDate>Mon, 02 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;-&lt;/th&gt;
&lt;th&gt;Exception&lt;/th&gt;
&lt;th&gt;RuntimeException&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;정의&lt;/td&gt;
&lt;td&gt;Runtime Exception을 제외한 모든 Exception&lt;/td&gt;
&lt;td&gt;Runtime Exception 하위 Exception&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;예외처리&lt;/td&gt;
&lt;td&gt;명시적인 예외처리 필요&lt;/td&gt;
&lt;td&gt;명시적인 예외처리를 강제하지 않음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;시점&lt;/td&gt;
&lt;td&gt;Compile Time&lt;/td&gt;
&lt;td&gt;Runtime&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;트랜젝션 처리&lt;/td&gt;
&lt;td&gt;non-rollback&lt;/td&gt;
&lt;td&gt;rollback&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;#. @Transactional&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;CheckedException 의 경우 롤백이 되지 않고, RuntimeException 의 경우 롤백이 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;#. rollbackFor 옵션&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;롤백이 되는 클래스 지정 방법&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Exception 예외로 롤백 &lt;/span&gt;
&lt;span class=&quot;token annotation punctuation&quot;&gt;@Transactional&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rollbackFor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 여러 예외 지정 &lt;/span&gt;
&lt;span class=&quot;token annotation punctuation&quot;&gt;@Transactional&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rollbackFro &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;RuntimeException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;#. noRollbackFor 옵션&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;특정 예외 발생 시 롤백이 되지 않도록 하는 방법&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token annotation punctuation&quot;&gt;@Transactional&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;noRollbackFor&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;IgnoreRollbackException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[[AWS] key 분실 시]]></title><link>https://ssongey.github.io/works/posts/2020-11-01--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2020-11-01--001</guid><pubDate>Sun, 01 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h4&gt;1. keypair 재 생성&lt;/h4&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/eca9dce3a5b770e7aad0f91e306c857e/26abe/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 251px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 102.91666666666669%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAVCAYAAABG1c6oAAAACXBIWXMAABJ0AAASdAHeZh94AAACTklEQVQ4y6VU2W7aQBTl/1/7HVWkPvQhCrTZRFWqNAsBYrzguAEDtjG28Tqe0zvD0tAQQ6mlke8sOnPOvXdODUd8nPN392ppmskD/myG8cRBEATwPBfuzMc8CDFxHMzDEBGN6dSR62vQXcC10/o50izFTauFk0+fcda4oFHHl6smbh8ecd38hrt2B43GV5xfXuO+06sGzLJcBmXJkOc5GCuRJAlYWcr1OI7lIAgsFgtEi7gacB0UjKEo8g0Qk/Pi33Mo93iJJ6UPpa/AtH4hSVN0Oh20bu5QMlJgXYLb9+AF5XuJWM2wJFZCzoKkJUkqpc+oSK43o7uIsaeAeyodZGuKVQz5GxnlSvZG4rbeypaSDAuqsj4YQDcGUrpmGBiNhpQCAzwLAJcYhrZMzV6Ga3Yje0x9F5BUX8p3nCnssQtkHrh1BT5+PAyQ75HAj5GcZxkUtQ/V0InVRBbFsiw8qTqRokKEQ/BkLpJ7mGTR1JqmYWiP4LkuEqq2TvNeX6PCUi8ap+DmhUj2/0s+qsqcmje32mDzCTK1ifyZYn+8zJ+QKZu4/AO2t8pFgvShjvyli6j+AfH3E4oVIDDBex/Bp/0lOIHyV69kibv9YqolC1YsFje+Z4yrdPC3RUmSGAF5XhhFCOkfk+Ok5EQxPUWxHtH6zPdpL5B7wkz4FugrQEYuo6oK2t0uDNNCp9eF+WzhZTiCbdswqJ00XceP25/0V2AMTFhDe/NEd0oWvSdulU+RbEsMYWHCG/NVXBSMLi/kOTHf5QO1vxcOaaMqb/wNAh9kTe7xcKUAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/eca9dce3a5b770e7aad0f91e306c857e/26abe/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/eca9dce3a5b770e7aad0f91e306c857e/8ff5a/001-01.png 240w,
/devHistoryBlog/static/eca9dce3a5b770e7aad0f91e306c857e/26abe/001-01.png 251w&quot;
        sizes=&quot;(max-width: 251px) 100vw, 251px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/058294bee0cfa7080bea0d76bb2f9d60/121b3/001-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 67.91666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAABJ0AAASdAHeZh94AAABaklEQVQ4y51Uy07DMBDMxyPxB3wJXLlz5IZESxX10DYlL9uxneewu3FKCWmpiDSZxI/xrD1JtIljvK/XWBHi7RZKa5RK/RtRcjxit98jTTNkeQ5rLaoz2BkvwVSVgM1E+90O648NtDEwBE2NilZiZhRlKe9FMbJSWqBDJdxW17VABL33aNsWTdMIps4J3F9Tu/C8LzDPZ7CpiF2xXU+T2rZDPwzo+36ZCUPg+cXtIuicJet6LLkK+1Lxnjl6duP+mGrcR+dEvCMMQXwI4ifBQ1bKYfCgfjZwCXNXvwQ/lUWeF+LI+xp/XUvOfgh670SQS2KHSxOXRC4K8o1LzrKcTqwRl13XXRW9tMh4KBQHzhO/TPE5OV04zbMSMAjRWMLQd6MghzRJjhJgzhoL3uIuqOL7CdCUjkiHHDJz0hnTp3QN2tBYY6HjV+jVi6BMD4jOP2ylb/sB8KJpmiKhyBXPDyie7pE/3qHcvuELPkFA+O8PH7cAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/058294bee0cfa7080bea0d76bb2f9d60/d9199/001-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/058294bee0cfa7080bea0d76bb2f9d60/8ff5a/001-02.png 240w,
/devHistoryBlog/static/058294bee0cfa7080bea0d76bb2f9d60/e85cb/001-02.png 480w,
/devHistoryBlog/static/058294bee0cfa7080bea0d76bb2f9d60/d9199/001-02.png 960w,
/devHistoryBlog/static/058294bee0cfa7080bea0d76bb2f9d60/121b3/001-02.png 1070w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h3&gt;2. 인스턴스 복제를 위해 이미지 생성 (인스턴스 정지 후 진행)&lt;/h3&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/9f364f5238db740f533197a3cef27446/5aae9/001-03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 610px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 68.75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAABJ0AAASdAHeZh94AAACfElEQVQ4y21TuY4TQRCdHyVACJGtCJAQCTkSAQkBEeIIWJBYiYzjL8DA2rterz1jz93TPff5eNW2A1haKvVV/erVq2qnbhpUVY0ojuG6HsIwwoZznCTIiwJ5nnPvIuZ90QH66zOYdycwnx7DfHgAc/YI+u09ZK9uo/zxBY4A1nUNpRR2fmCBBFRlGQoCivlhaAMKYP6NgG/uIv/4EPnpCfL395G9vgPz8hbq2Wc4XdehbVvI3Pf9X7Ocy1qCDsMITBMm3Bxytk0ZOFZw5NERcBgGa+0B7AiYJDGCgCyjPXMLMo2YRgkyYug71FVlM3U6Phr4KGPKLrUSK5nmOJAlmUkgo429l/TjOKEsqQ0sjGVIBh7fSUBH1y1M0yFUGlfeDqutj0jnyKoGcte0HRkmdI4tmOhc1w1GspsIKMAFi3rth/DiFE5Uj4jbCa4qMfdCWoRlmGFNTeSu5OMgCODt/D0o2e1T3rPLc3YCA2tuVQ84aWHIsEaQJmS4xdLdwYsSy1hYSjoCuFxdw7CFZAgrYWjTlQ4xORZrF9uIDEUKe1EBgU/x/R31yg46DrYwPgvSHx3/GRUBpVelT2NJ2eRn0PoFU3mOVP1kk/coy9ICjaxgymLMFxeW4fV6jRXtcnllm7+gX8Ae3fq+1TfNNJwiP6XoT2hPCTQnENg2Ut3e6pRpjfP5Ar/O51hcXOA3199nM64vkRljwQJW9/irHAaBos7SXknCYmw21kF+jDRzwwjy9TbUVyrsbXdwubZMr1aIWCQB0wQXc7RW1MhDksa2PRI6CH2VKdseUghhecMOAMe9OQKmLECSplarmHOSqsM+g6KjOAnoDfvPufj+AadlIZOzXJi4AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/9f364f5238db740f533197a3cef27446/5aae9/001-03.png&quot;
        srcset=&quot;/devHistoryBlog/static/9f364f5238db740f533197a3cef27446/8ff5a/001-03.png 240w,
/devHistoryBlog/static/9f364f5238db740f533197a3cef27446/e85cb/001-03.png 480w,
/devHistoryBlog/static/9f364f5238db740f533197a3cef27446/5aae9/001-03.png 610w&quot;
        sizes=&quot;(max-width: 610px) 100vw, 610px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h3&gt;3. 인스턴스 새로 생성&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Machine Image 선택시, 2번째 탭의 나의 AMI 선택 후 생성된 이미지 선택&lt;/li&gt;
&lt;li&gt;인스턴스 생성 후 새로 생성한 key 선택

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/249ab23cdbb7e2d9004f7dbcd5be292f/7631d/001-04.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 22.499999999999996%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAABJ0AAASdAHeZh94AAAApUlEQVQY021QWw6DMAzr/e+xm+we+9gHTICoRtV36+FCGGiLZLlxlMSpmqYJwzAc6PseWmt47+Gda+x2JkIILbfWHjVqfOvFQlHYGjaxlIKcM1JKB2KMP7lo5xpqhloW07bJELIMJZ+j1tpw1TaOqeDxMlDjOK4O6SwjeAfmxpgGOudQwb+QBW+bcLs/obquwzzPqGsDi/wPOYEumcuJZ5dft1fXH4FXhzml6a4EAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 04&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/249ab23cdbb7e2d9004f7dbcd5be292f/d9199/001-04.png&quot;
        srcset=&quot;/devHistoryBlog/static/249ab23cdbb7e2d9004f7dbcd5be292f/8ff5a/001-04.png 240w,
/devHistoryBlog/static/249ab23cdbb7e2d9004f7dbcd5be292f/e85cb/001-04.png 480w,
/devHistoryBlog/static/249ab23cdbb7e2d9004f7dbcd5be292f/d9199/001-04.png 960w,
/devHistoryBlog/static/249ab23cdbb7e2d9004f7dbcd5be292f/07a9c/001-04.png 1440w,
/devHistoryBlog/static/249ab23cdbb7e2d9004f7dbcd5be292f/7631d/001-04.png 1881w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[[PKI] PKCS 표준]]></title><link>https://ssongey.github.io/history/posts/2020-10-28--001</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-10-28--001</guid><pubDate>Wed, 28 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;공개 키 암호 표준&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;PKCS #7
— 암호화 데이터/ 전자서명&lt;/li&gt;
&lt;li&gt;PKCS #10 : CSR&lt;/li&gt;
&lt;li&gt;PKCS #12 : p12 or pfx&lt;br&gt;
— 개인키와 인증서를 합쳐 암호화하고 인증서 소유자에게 송부 방법&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/0cf21031fb549ff7531b04283fd8c415/70881/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 27.500000000000004%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABYlAAAWJQFJUiTwAAAA8UlEQVQY021R23KFIAz0//+yKorcFVBPX7abnNaZdvqwEzBmL2FIueA4KlIq6Ky1ndhrx86zoPfrOZ/XjcZ+bR0Xz+c/GFaX4ALhAyLJWz8RYsY4GcxmwTQbmGWFWS2s8/AhIlK87JU4FFlr1TrYzXPA6tA0L8hlRyoHyVYsJFnWDXZzJMkqdr8+cQnu1y88DmVonGYlEAcSWVx8jPxGAcNqhdhu6kCiV4qWo3NVTdclKxCyLoTiRiJvJHMkkqbnXYS8j0RA+F6Jkzv/CeFdJW4/L8XjMO8NgTsJMWksIZSHUgGSyKA+XG0aWfo/+Btb8AUUrsh/qKaWgAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/0cf21031fb549ff7531b04283fd8c415/d9199/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/0cf21031fb549ff7531b04283fd8c415/8ff5a/001-01.png 240w,
/devHistoryBlog/static/0cf21031fb549ff7531b04283fd8c415/e85cb/001-01.png 480w,
/devHistoryBlog/static/0cf21031fb549ff7531b04283fd8c415/d9199/001-01.png 960w,
/devHistoryBlog/static/0cf21031fb549ff7531b04283fd8c415/07a9c/001-01.png 1440w,
/devHistoryBlog/static/0cf21031fb549ff7531b04283fd8c415/29114/001-01.png 1920w,
/devHistoryBlog/static/0cf21031fb549ff7531b04283fd8c415/70881/001-01.png 3236w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;</content:encoded></item><item><title><![CDATA[[Vue] Keep Alive]]></title><link>https://ssongey.github.io/history/posts/2020-10-27--001</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-10-27--001</guid><pubDate>Tue, 27 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;keep-alive&lt;/h2&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/ff19d0593da7dff6bea546b79286257b/b94e3/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 75.41666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAABYlAAAWJQFJUiTwAAACB0lEQVQ4y6VU55LWMAzM+z8izHF86c0pdlzSvmXlXA6OAX5wntEobvJqV0pSdx2yokLT9Xg+n/jT+Nf6bfc8GacZddNhNgv+Z/z6WAx4nifWbcMWPM5jx7pucM7D+UDzcR7WFZoPLtbBLBaWfqEPYf2AVEYi7th32OIB3TZIizpS8PKa4pGVqOoWaV7h9ZHHufiiapCXNcqqjQ99SHk/DjhrofsW86whFEz0wzjF73GcL/++fnlBezC7g/d/5kyEPgQKovAtLfDE50fiydX9uuoVmrrBMIyYJg039AhjDz+N6GWv7dH2AzqafFcUsyUYsU4NkdNEyK2aNnLSlSW6IkddVpG3LCvQ5RlUnkI1DTKeEQ4lIxVTNxFMp0Z6Dck22SmIoBRyRc1AZd2yRBXN4jDwoKZfedjba/3cN1GSVXFg2/bIo6CLoljn3pXMM6J7fIcfFS87zPpCoOlXo7HqKT7m55FU8AzXZr3EfUEp4JI3vWP0k3acn5Mm0auDZTqSWtH0MPOM0DdYKcikFEoSL50kpEv93SacDxRqo2iWJSdlFAP2XsNMDJQ/MBYpSgry8uUruqrEsV1dIvx4mnSQpcll8cLrTl43Z7G/1WMsm4WC+MVE0kUcEcH5K0gIH1vwJv9vfZ1Ib4r8RkRgMMUOmUiy9KsxNgozUBjDPalVsY3k//63uR/5AaSxiPz21oMQAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/ff19d0593da7dff6bea546b79286257b/d9199/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/ff19d0593da7dff6bea546b79286257b/8ff5a/001-01.png 240w,
/devHistoryBlog/static/ff19d0593da7dff6bea546b79286257b/e85cb/001-01.png 480w,
/devHistoryBlog/static/ff19d0593da7dff6bea546b79286257b/d9199/001-01.png 960w,
/devHistoryBlog/static/ff19d0593da7dff6bea546b79286257b/b94e3/001-01.png 1126w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;keep-alive 는 비활성 컴포넌트 인스턴스를 파괴하지 않고 캐시한다.&lt;/li&gt;
&lt;li&gt;keep-alive 를 사용하면 컴포넌트 인스턴스가 전역 큐에 저장되고, 활성화 될 때는 기존 컴포넌트를 사용하여 activated 라이프 사이클 hook이 호출되며, 비활성화시에는 인스턴스를 소멸시키지 않고 deactivated 라이프사이클 hook이 호출된다.&lt;/li&gt;
&lt;li&gt;ref) &lt;a href=&quot;https://learnvue.co/2019/12/an-overview-of-vue-keep-alive/&quot;&gt;https://learnvue.co/2019/12/an-overview-of-vue-keep-alive/&lt;/a&gt;
&lt;a href=&quot;https://velog.io/@kyusung/VUE-keep-alive&quot;&gt;https://velog.io/@kyusung/VUE-keep-alive&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;destroy component cash&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token function-variable function&quot;&gt;clearComponentCache&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;param&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; component &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; param&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;matched&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;instances&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;default&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;component &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; component&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;$vnode &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; component&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;$vnode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;keepAlive&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;component&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;$vnode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;parent &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; component&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;$vnode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;parent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentInstance &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; component&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;$vnode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;parent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentInstance&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cache&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;component&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;$vnode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentOptions&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; key &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; component&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;$vnode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;key &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; 
            component&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;$vnode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;key &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
            component&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;$vnode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentOptions&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Ctor&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cid &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;component&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;$vnode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentOptions&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tag &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;component&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;$vnode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentOptions&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tag&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
          &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; cache &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; component&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;$vnode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;parent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentInstance&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cache&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
          &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; keys &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; component&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;$vnode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;parent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentInstance&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;keys&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
          &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cache&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;key&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;keys&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
              &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; index &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; keys&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;indexOf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;key&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
              &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;index &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                keys&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;splice&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;index&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
              &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;delete&lt;/span&gt; cache&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;key&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[[작업로그] 이중로그인 방지 (Spring Security)]]></title><link>https://ssongey.github.io/works/posts/2020-10-20--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2020-10-20--001</guid><pubDate>Tue, 20 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;의문사항&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;같은 Session 에서 중복 로그인이 가능하다.&lt;/li&gt;
&lt;li&gt;같은 Session 에서 중복 로그인 시 session id가 변경된다.&lt;/li&gt;
&lt;li&gt;로그아웃 후에 다시 로그인을 하면 ‘이미 접속된 아이디’ 오류가 난다.&lt;/li&gt;
&lt;li&gt;session 사용시 cookie 에 저장되는 JSESSIONID 에 대한 보안 이슈가 없는가&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;1. session 설정 내용&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;maximumSessions : 최대 세션 개수&lt;/li&gt;
&lt;li&gt;maxSessionsPreventsLogin : 기존에 접속한 사용자가 있을 경우 기존 사용자의 접속을 끊고, 나중에 접속한 사용자가 접속되도록 한다.(default: false)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token annotation punctuation&quot;&gt;@EnableWebSecurity&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SecurityConfig&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;WebSecurityConfigurerAdapter&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token annotation punctuation&quot;&gt;@Override&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;configure&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;HttpSecurity&lt;/span&gt; http&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sessionManagement&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;maximumSessions&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;maxSessionsPreventsLogin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sessionRegistry&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sessionRegistry&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;2. DEBUG&lt;/h4&gt;
&lt;p&gt;chrome 에서 admin 계정으로 로그인 후(SessionId를 부여 받음) 새탭에서 다시 admin 계정으로 로그인을 하면 &lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/e71d8d22b54e9a89669134ce90d302ed/d0fa6/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 69.58333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAABJ0AAASdAHeZh94AAABp0lEQVQ4y4VT21LrMAzs75BYviduSMvAy3k7UIb//5ZFFyeFUoaHHSkae7XWKofldEKbKpZWcV6PjIZ1XXFcHjG3RZHrhFwqUi4af8eEQ5kaQgioOaO1IxM0THNDZRQ+UBmZiWJK8D4wPIjh+Y4gKCJCjPp9SGUGkePLWUnqNCsSExTpyjEFJiGCcw7jOCokv4XUD7nO8Hy4sMJSTY0olOfFmLizQQiN1LA1ELVbncgboRRz9F1+6M/zdqETSfdhGH7gtm4K+XKMQRVRJ7o9vD31L5hClpoCqbpN2fDwcFfRnwoLG6Aul6JzS+k6S8kTKxcHdZ7aMOxu+83tLed6fzKbwoSliqtRHZZVkEOBN8D3OdIdZ3dzyPJuSmAlCW1Z0Y6PvDZNlzmmgpCKxsiKiZs4PusoYHSewWRkcRidwgiXfwjnV5TnC+LzxxUvH/BP73DnN9DTRXPPkc4X/bbaBe70hnH9r7Anc2fprg6TYaSrgr2mSr5Da86iYF8b3T8dvkHmarPbdlH+hO7sV4zDnT3c/8VoZnQ35Q/xJMZEjfuadGy79zX/BGGFs8k7goL5AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/e71d8d22b54e9a89669134ce90d302ed/d9199/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/e71d8d22b54e9a89669134ce90d302ed/8ff5a/001-01.png 240w,
/devHistoryBlog/static/e71d8d22b54e9a89669134ce90d302ed/e85cb/001-01.png 480w,
/devHistoryBlog/static/e71d8d22b54e9a89669134ce90d302ed/d9199/001-01.png 960w,
/devHistoryBlog/static/e71d8d22b54e9a89669134ce90d302ed/d0fa6/001-01.png 1263w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;동일한 SessionId 에서 로그인 시도를 했기 때문에&lt;br&gt;
ConcurrentSessionControlAuthenticationStrategy.onAuthentication() 에서
123라인의 allowableSessionsExceeded() 메소드(중복로그인 exception)를 호출하지 않고 종료가 된다.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/c697d99ae775c93e05f8c47ffa869909/d4c13/001-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 825px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 55.00000000000001%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABJ0AAASdAHeZh94AAABbUlEQVQoz41SWXaDMAzkOGHxJm9gSEhee/8rTWUR0hA+2o95kjEazUhu1u8vPB43PO4L1nXGfd3iepv5+xWlZKRxQp5mRvkTDYUE6zyUUtDawBiLYRjQdR36vhfU/L9oLAVoJtFawzknICJBzY0xclfje16btm37ItqbN46iEBprkTPbSxkxJolbHjdycoeG3nvJa4PqbnfSEBdYvrBaCZxR8E6DXFVsuHgrtNxwJ3wp1ZvqA6F/Ejo9IAXCmDzmKXEk5BQQ07ghV0wIrJpYXbXbtpeT7cb5yHYJaugRPKHkiLEsjCum+YpxWnC/rViXBVYN7MCyg8BuLKxxou44w52w7zA6hRIzpszPZWHCZRbE4FmZRypRxjL0igVoaGVOr6AhJrSWh8uzyCXJEiKTRl6Qj54RxGIdzcjk24JIZjqwq6rwHUzI8h3Jlh2rMGTl53qujQQfz0eW+FzGiXC3XKW3l/Y57DN+bX2ej/gBpUFY1GzVPb4AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/c697d99ae775c93e05f8c47ffa869909/d4c13/001-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/c697d99ae775c93e05f8c47ffa869909/8ff5a/001-02.png 240w,
/devHistoryBlog/static/c697d99ae775c93e05f8c47ffa869909/e85cb/001-02.png 480w,
/devHistoryBlog/static/c697d99ae775c93e05f8c47ffa869909/d4c13/001-02.png 825w&quot;
        sizes=&quot;(max-width: 825px) 100vw, 825px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;CompositeSessionAuthenticationStrategy.onAuthentication() 에서
fixation 기본값 인 migrateSession에 의해 AbstractSessionFixationProtectionStrategy 가 delegate 된다. (89라인)&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/fc4dfbbf00d74e99288cdb4ddde139d5/d8817/001-03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 64.58333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAABJ0AAASdAHeZh94AAABz0lEQVQ4y3WS6W7bMBCE/TaNed+UHCsp0tRH2qIoerz/m0yHlOzKcPrjw5KUPdjdmc3L+Q2H4wGfX19wPh3w5XzA8XTEfnrCuNtj9zhhGEaUUhcG1Mp7HW6odX7fhFQRtEVWEmMqGEjxEUPI2MXMc0C1pn+PSiEoTRS8EPDb7cz1LLCJucJYC88/xRgRQoRzDt55OOthjO3fldZQFJJSQlBgzfqtd2isg2EHSop3fkzW90Xgf1wFnfcI7NBzxNZlwxjDrtiZNgu239ddXYQu501YRm5jRu4vpgwfZuFWY/DI0SFYhei4O1bZR28dy3vBtkPNPYWYMIw7OjZ2Mdt22ESdoYjsQq06ww6luhG7GXkWNL2DsUTGonRzcs5IcTaoGWO16HhD9Aco8YAtnRUNsVSyiSnB1o+wzz+QXn8jffqF/PqH9Sfs9A16+g4/vSE9HVBIJuH5K8J0gtvP+IV2ZocFhpmzkaPmR7i8gy972DTyvUK6Au0SiVCdxLfa3wzz+q/OzDnkyJaxSdxjiHaBRiSOy71pI1kVf8doKQGttnRc9LOUl3EfOldTWhya2xfaXtdVtpxegr3inRyW7nAzIdOQTi7zfVWbOeIu1Pc5/As0J5fJd0jQlwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/fc4dfbbf00d74e99288cdb4ddde139d5/d9199/001-03.png&quot;
        srcset=&quot;/devHistoryBlog/static/fc4dfbbf00d74e99288cdb4ddde139d5/8ff5a/001-03.png 240w,
/devHistoryBlog/static/fc4dfbbf00d74e99288cdb4ddde139d5/e85cb/001-03.png 480w,
/devHistoryBlog/static/fc4dfbbf00d74e99288cdb4ddde139d5/d9199/001-03.png 960w,
/devHistoryBlog/static/fc4dfbbf00d74e99288cdb4ddde139d5/d8817/001-03.png 1238w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;AbstractSessionFixationProtectionStrategy.onAuthentication() 에서
Session Fixation Attack 방지로 인해 NewSessionId가 생성된다.&lt;br&gt;
즉, 동일 로그인ID ‘admin’ 으로 SessionId, NewSessionId 각 2개가 생성되었다.  &lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/7a9a20ac71cd934e3e0e3ffefb6b4d9c/8d7b0/001-04.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 27.083333333333332%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAABJ0AAASdAHeZh94AAAA4klEQVQY042Oa0+DMBiF+f+/SZ0YHfOLN5w3GIuZDFtuVToEBB5LE7N9Mr7J8zY9p+ekTryNEakgFQlfVcHYafqmotbKnkOrqT9zS1UKPvJ3VJbQ6JJup2hMptMFO5XavLPZbEi2b/hBjHufc/GiWawaZneS4+sE10/xnhReUOMuS05upfEyZn7G2YOynC4VRzfSZhwpBXkmeVwLG1qsWjzDfCoONFevreUy6pgb3zPa9M4LJxqjt+YTNefP2npOGIZEUYQqMv434x+wL5RSMhitN8vSD+Y+Mgx7fvVDvg+Y/B/e73haYs9DigAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 04&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/7a9a20ac71cd934e3e0e3ffefb6b4d9c/d9199/001-04.png&quot;
        srcset=&quot;/devHistoryBlog/static/7a9a20ac71cd934e3e0e3ffefb6b4d9c/8ff5a/001-04.png 240w,
/devHistoryBlog/static/7a9a20ac71cd934e3e0e3ffefb6b4d9c/e85cb/001-04.png 480w,
/devHistoryBlog/static/7a9a20ac71cd934e3e0e3ffefb6b4d9c/d9199/001-04.png 960w,
/devHistoryBlog/static/7a9a20ac71cd934e3e0e3ffefb6b4d9c/07a9c/001-04.png 1440w,
/devHistoryBlog/static/7a9a20ac71cd934e3e0e3ffefb6b4d9c/8d7b0/001-04.png 1723w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;탬 1, 탭2 의 브라우저 cookie 에는 마지막으로 생성된 NewSessionId가 부여되며, 기존 SessionId를 해제를 하지 못한 상태로 Client 에서 사라지게 된다.&lt;br&gt;
즉, NewSessionId로 로그아웃을 하더라도 ‘admin’ 계정에 대한 SessionId가 존재하므로 재 로그인 시 중복된 로그인 에러가 뜨게 된다.&lt;/p&gt;
&lt;h4&gt;3. 해결방안 : sessionFixation - none&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Session Fixation Attack 방지&lt;br&gt;
악의적인 사용자가 사이트에 접근하기 위한 세션을 만들고, 그 세션을 통해 다른 사용자로 로그인 하려고 하는 경우(예를 들어, 세션에 ID를 파라미터로 포함하여 전송하는 경우)
Session fixation attack의 잠재적인 위험이 존재하게 된다.&lt;br&gt;
스프링 시큐리티는 이러한 공격을 자동으로 막기 위하여 사용자 로그인 때마다 새로운 세션을 생성한다.&lt;br&gt;
이러한 방지 기능이 필요하지 않거나, 다른 기능들과 충돌이 발생할 경우에는, &lt;session-management&gt;의 session-fixation-protection 속성값으로 동작을 제어할 수 있다.&lt;br&gt;
속성은 다음과 같은 세가지 옵션값들을 가진다.  &lt;/li&gt;
&lt;li&gt;동일 세션에서 로그인이 재발생해도 동일한 session id를 갖도록 한다.&lt;/li&gt;
&lt;li&gt;동일 세션에서 중복 로그인 후 로그아웃하면 해당 로그인 id에 대한 세션이 해제가 되어 재 로그인이 가능하다.&lt;/li&gt;
&lt;li&gt;none 으로 설정 시 호출되는 Session Strategy Class&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/2615a5eb6d37fb817a32f1a0a35d9071/8efc2/001-05.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 828px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 55.41666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABJ0AAASdAHeZh94AAABRElEQVQoz5WSWXLDIBBEdR0JMeybHG9x+f5H6gwgO7ZlVyofrwCBehqmh+P1ivPljMv3EafTHvv9gsNhwfGwQ84BIWWmrOMjBTFvGYyL0C6geINgFLR1sLx2IcLw3Bjbad89dJtbEBHGccQ0TU90QesRtIDTBMkHhRCY5/k+PiJuI++9owkadkSKNtX+4oNgaA7JEJRnh0o2Zskupn7oWUh0qkBdvwpaz1c2/DZewe00i/HGXKvXn8ePTm6FNg61Da0R3khEq5EcN8dZpPLFXVsQuZu1GbemeC4Y1IhZdKcbwVgKfEwgvqLnLgcWLNEhRxYNXMiH1lmlNJTWbU5KfXzXIeaeK7uKpRiwlISSAjITY0QuCxJnLJXqOCOxa+drdOQmBYOx9Tq+HaiRkaQgJT0gf6G+rhkketlbWWPjm/p/Y/OOH+iGVTfcvb59AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 05&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/2615a5eb6d37fb817a32f1a0a35d9071/8efc2/001-05.png&quot;
        srcset=&quot;/devHistoryBlog/static/2615a5eb6d37fb817a32f1a0a35d9071/8ff5a/001-05.png 240w,
/devHistoryBlog/static/2615a5eb6d37fb817a32f1a0a35d9071/e85cb/001-05.png 480w,
/devHistoryBlog/static/2615a5eb6d37fb817a32f1a0a35d9071/8efc2/001-05.png 828w&quot;
        sizes=&quot;(max-width: 828px) 100vw, 828px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
     &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// migrateSession : 새로운 세션을 생성하고 기존의 세션 값들을 새 세션에 복사해준다. 기본값으로 설정되어 있다.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// none : 아무것도 수행하지 않는다. 원래의 세션이 유지된다.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// newSession : &quot;깨끗한&quot; 새로운 세션을 생성한다. 기존의 세션데이터는 복사하지 않는다.&lt;/span&gt;

http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sessionManagement&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sessionFixation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;none&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;maximumSessions&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;maxSessionsPreventsLogin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sessionRegistry&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sessionRegistry&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;4. JSESSIONID 는 안전한가?&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;기본적으로 HttpOnly 를 사용   &lt;/li&gt;
&lt;li&gt;HttpOnly는 Set-Cookie HTTP 응답 헤더에 포함 된 추가 플래그   &lt;/li&gt;
&lt;li&gt;쿠키를 생성 할 때 HttpOnly 플래그를 사용하면 보호 된 쿠키에 액세스하는 클라이언트 측 스크립트의 위험을 완화하는 데 도움이됩니다&lt;/li&gt;
&lt;li&gt;XSS ( 교차 사이트 스크립팅 ) 결함이 존재하고 사용자가이 결함을 악용하는 링크에 실수로 액세스하더라도 브라우저 (주로 Internet Explorer)는 쿠키를 제 3 자에게 공개하지 않는다.&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[[책리뷰/Effective Java] 예외]]></title><description><![CDATA[아이템70) 복구할 수 있는 상황에는 검사 예외를, 프로그래밍 오류에는 런타임 예외를 사용하라]]></description><link>https://ssongey.github.io/history/posts/2020-10-12--001--02</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-10-12--001--02</guid><pubDate>Mon, 12 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;아이템70) 복구할 수 있는 상황에는 검사 예외를, 프로그래밍 오류에는 런타임 예외를 사용하라&lt;/h2&gt;
&lt;p&gt;복구할 수 있는 상황이면 Checked Exception, 프로그래밍 오류거나 확실하지 않다면 Runtime Exception 을 예외로 던지자.  &lt;/p&gt;
&lt;h3&gt;Exception vs Error&lt;/h3&gt;
&lt;p&gt;오류(Error)는 시스템에 비정상적인 상황이 생겼을 때 발생한다(JVM 자원 부족 등).&lt;br&gt;
이는 시스템 레벨에서 발생하기 때문에 심각한 수준의 오류이다.&lt;br&gt;
따라서 개발자가 미리 예측하여 처리할 수 없기 때문에, 애플리케이션에서 오류에 대한 처리를 신경 쓰지 않아도 된다.&lt;/p&gt;
&lt;p&gt;오류가 시스템 레벨에서 발생한다면, 예외(Exception)는 개발자가 구현한 로직에서 발생한다.&lt;br&gt;
즉, 예외는 발생할 상황을 미리 예측하여 처리할 수 있다.&lt;br&gt;
즉, 예외는 개발자가 처리할 수 있기 때문에 예외를 구분하고 그에 따른 처리 방법을 명확히 알고 적용하는 것이 중요하다.&lt;/p&gt;
&lt;h3&gt;Exception&lt;/h3&gt;
&lt;p&gt;예외 클래스 구조&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;모든 예외클래스는 Throwable 클래스를 상속받고 있다&lt;/li&gt;
&lt;li&gt;Error는 시스템 레벨의 심각한 수준의 에러이기 때문에 시스템에 변화를 주어 문제를 처리해야 하는 경우가 일반적이다.&lt;/li&gt;
&lt;li&gt;Exception은 개발자가 로직을 추가하여 처리한다.&lt;/li&gt;
&lt;li&gt;RuntimeException은 CheckedException과 UncheckedException을 구분하는 기준

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/ad2fe7b123b9f182826ba5b510b5d459/c1328/001--02-1.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 866px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 74.58333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAABJ0AAASdAHeZh94AAACJElEQVQ4y41UaY/aQAzN//877YfS7bGwq0UsLWcIhCMBkpA7tOQ+4NUzLdpAoaolK5bGY7/n54mAmp1OJ/4tigK2tcFmLcPQVwg8E2VZXuTcM+FWwTzPsDNW6PfaGA07cB2NN/mvgiyh7swYGtvSoWsKoVzA9ywcj0dc557z602EW12KIoc87WPQf0H3tQlVkVBV1U1E14g5QoYojiM4jgPP8xAEAY9VVYWiKHBdF/v9np+5roMkiXmDOsJzLMRxCNNYQJp0CckY5k7h9K5RsPTtZg5x3MF41IGyHFHh6KIgc4EJEPg2FRySoir2gfvW8YqO6+wwlUYYDrok2hpZlv5dsKpKUjWHKIowDIPQvdGoCGlJYNWNhv5wDN3YQdd1mJaNKE4QhiECGsWFKNpWwXzWw4ooLOcDaFuZqCT8UDEztOUMvWWCVzmCuC2RsHUMD7Caj7Cfn2C1WrCenmA3m0jmcwiea9NsZPjuFo69oXmuENEFZlaQozVJ0Z4f8SKXaEkl/JioHX7A+vQA68tnqO/fQW80YDY+IJImv9emJMXSNKOZ5Jz+mUKappyS5Xhw/D1cz+c5dVvQFvwk6hdrc2+32PosFgtomob1es3j6M/ldDZF3ush7Pdx+P4N5WqJI4ERrlW6fgX3LJVlpA8fUbaaKB6/cq+omfCv7b/XiHlKwoW08KFpIrRtHMiLLLtd8J7V/0bsBc0IpUKjWFIsShJ/Ub8AjRh9FbzPXdYAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001  02 1&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/ad2fe7b123b9f182826ba5b510b5d459/c1328/001--02-1.png&quot;
        srcset=&quot;/devHistoryBlog/static/ad2fe7b123b9f182826ba5b510b5d459/8ff5a/001--02-1.png 240w,
/devHistoryBlog/static/ad2fe7b123b9f182826ba5b510b5d459/e85cb/001--02-1.png 480w,
/devHistoryBlog/static/ad2fe7b123b9f182826ba5b510b5d459/c1328/001--02-1.png 866w&quot;
        sizes=&quot;(max-width: 866px) 100vw, 866px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Checked Exception VS Unchecked(Runtime) Exception&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;가장 명확한 구분 기준은 ‘꼭 처리를 해야 하느냐’이다.&lt;/li&gt;
&lt;li&gt;Checked Exception이 발생할 가능성이 있는 메소드라면 반드시 로직을 try/catch로 감싸거나 throw로 던져서 처리해야 한다.&lt;/li&gt;
&lt;li&gt;Unchecked Exception은 명시적인 예외처리를 하지 않아도 된다.

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/1062f18c82456b7ce83ce1c5c14a8902/2e367/001--02-2.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 47.08333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAABJ0AAASdAHeZh94AAABoElEQVQoz1VRaW+jMBDl//+pVT9V2pW6TTYpKTcECNjG5j4bvfWYtkqRnmY88+bNgTXyEJsIsHDfYLg5xlbRCTw4QkT/IMIjZHzCzDwMhQOVnMGCw57TYP4BXWZjkiksL4nxHgUI8xQxKxBmVwyqhLgliD0beexpe8Et8fEx1mhFDp5FSEMH1+AdWeQicm2wNMTUSVgvQYpn94pDJnDmLU7aMi4gVQ1VNxinGcM4Gbt93MErafL9MH6Dcl0/YNC+9efi4dfrGb/dCOdC4i0twcoSnHMopdB1HaZpwrosWDQYYyiKAnVdm/e67vFtW7XgoCf0IjwdL3i++HhNCtg5N+S2bdE0jRHu+14XrqawqioTl1IaAYpRw3med0FfNAjaBb4a4MgeTinNZEIII0qCBHo/+sQhUHMCiZK49ZaV+BvfYJcKrtSibCdSIa1HK1NnEqcpKJbnOUp9lsf17/f7LkgrHjIOm9V6wl2QiFRA6xHx8aMY5WnK8vPW5FNjOosVcIVA9fCrFp5e32fqB5nut22bIZMlwa/pCF8/h6antf8DrnWkTeT0lP4AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001  02 2&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/1062f18c82456b7ce83ce1c5c14a8902/d9199/001--02-2.png&quot;
        srcset=&quot;/devHistoryBlog/static/1062f18c82456b7ce83ce1c5c14a8902/8ff5a/001--02-2.png 240w,
/devHistoryBlog/static/1062f18c82456b7ce83ce1c5c14a8902/e85cb/001--02-2.png 480w,
/devHistoryBlog/static/1062f18c82456b7ce83ce1c5c14a8902/d9199/001--02-2.png 960w,
/devHistoryBlog/static/1062f18c82456b7ce83ce1c5c14a8902/2e367/001--02-2.png 1066w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;//Before&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;RuntimeException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;//After&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;RuntimeException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;예외 처리 방법&lt;/h4&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/08a762dd4c8ce9cc733908168ecca131/99f37/001--02-3.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 77.08333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAABJ0AAASdAHeZh94AAACaklEQVQ4y41U207cMBDd/28/oH3pG0+t+sAPVKgg9YZUSiVYFgi7bMLuxrnYiW+J7dOJw9JtEYiJRnGSmeOZM8eZgMwHB2EZuMnR2JLWBUq9hnUaowWE8DKfUCxMp9HoCj6mAs4HmJ7emRaF9PH5paAT5zxYzrBaMbRVBldfo6f8UvWxtpvSg+sw1rmT+P/zA6Cn3YN3MaBJDnD56TU+Zxb7Z2msKm89gT8N8LjC+3Y6ayFEg6t0g2WW4WI6RW8NaqJxaHvkelvdM4DSetjeI9sUWK5yZHcrMJaDcx5BVBewbtxDm9tKnwKdrBqP6cZjxjwu8hDv88pjyQOu1gbfzmsc/Cpx+LvEzyuOVrtn25/g777/uDQO+0cZ3r7/incfv0d/8+EYX874TtxjmzDi56YC5jWQVONU0wZYCuDHTOBkxnGSSJwmLY6nHKcLjVUbsKg9rovBHZLSxbUwHpNaOczvCiRZjiRlyIUl+aTo9MihJn4LiuEUbLSkwQmwWlEHHdqOlDG4BQ1vkJcfddgZBWt0vAeeQpzuoauSCFhKF6dcKw9FAxRsCXZ5iGEugXJlfQ5Hp2uwzvmtbEbrraaANXijsLhN4V0HJkMUdiV7mCGmOEd+9ArDaBirsZjtoeUXY75zg7Cp1JqjqmrkeY7bZYrFYo4kSWCUJG4DWmqXSSArFaqygiDwqipRFAWqWqJtNCzpeCgtnmVlJBrF6WUHrS2M7elsS3AlSIM+CnrQIyPCGGdoZAtNHGploZQClyVsZ8cpxxNAF7c5RFdC9oKIrlGaNfTO32YrE9VL+rZB2/MYy+kvJbriXujAH1ZPhkWxsG6mAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001  02 3&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/08a762dd4c8ce9cc733908168ecca131/d9199/001--02-3.png&quot;
        srcset=&quot;/devHistoryBlog/static/08a762dd4c8ce9cc733908168ecca131/8ff5a/001--02-3.png 240w,
/devHistoryBlog/static/08a762dd4c8ce9cc733908168ecca131/e85cb/001--02-3.png 480w,
/devHistoryBlog/static/08a762dd4c8ce9cc733908168ecca131/d9199/001--02-3.png 960w,
/devHistoryBlog/static/08a762dd4c8ce9cc733908168ecca131/99f37/001--02-3.png 1100w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1.예외 복구&lt;br&gt;
예외복구의 핵심은 예외가 발생하여도 애플리케이션은 정상적인 흐름으로 진행된다는 것이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; maxretry &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; MAX_RETRY&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;maxretry &lt;span class=&quot;token operator&quot;&gt;--&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;  
    &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// 예외가 발생할 가능성이 있는 시도&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 작업성공시 리턴&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;SomeException&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// 로그 출력. 정해진 시간만큼 대기&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; 
    &lt;span class=&quot;token keyword&quot;&gt;finally&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// 리소스 반납 및 정리 작업&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;RetryFailedException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 최대 재시도 횟수를 넘기면 직접 예외 발생  &lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;2.예외처리 회피&lt;br&gt;
호출한 쪽에서 다시 예외를 받아 처리하도록 하거나, 해당 메소드에서 이 예외를 던지는 것이 최선의 방법이라는 확신이 있을 때만 사용해야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SQLException&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;  
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 구현 로직&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;3.예외 전환&lt;br&gt;
호출한 쪽에서 예외를 받아서 처리할 때 좀 더 명확하게 인지할 수 있도록 돕기 위한 방법이다.&lt;br&gt;
어떤 예외인지 분명해야 처리가 수월해지기 때문이다.&lt;br&gt;
예를 들어 Checked Exception 중 복구가 불가능한 예외가 잡혔다면 이를 Unchecked Exception으로 전환하여서 다른 계층에서 일일이 예외를 선언할 필요가 없도록 할 수도 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;SQLException&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;  
   &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;
   &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DuplicateUserIdException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[[책리뷰/Effective Java] 예외]]></title><description><![CDATA[아이템69) 예외는 진짜 예외 상황에만 사용하라]]></description><link>https://ssongey.github.io/history/posts/2020-10-12--001--01</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-10-12--001--01</guid><pubDate>Mon, 12 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;아이템69) 예외는 진짜 예외 상황에만 사용하라&lt;/h2&gt;
&lt;p&gt;예외는 예외 상황에서 쓸 의도로 설계되었다.&lt;br&gt;
정상적인 제어 프름에서 사용해서는 안되며, 이를 프로그래머에게 강요하는 API를 만들어서도 안된다.&lt;/p&gt;
&lt;h3&gt;예외는 일상적인 제어 흐름용으로 쓰여선 안된다.&lt;/h3&gt;
&lt;p&gt;Good 코드와 같은 표준적이고 쉽게 이해되는 관용구를 사용해라&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;//Bad&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    range&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;climb&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;ArrayIndexOutOfBoundsException&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;//Good&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Mountain&lt;/span&gt; m &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; range&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    m&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;climb&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;정상적인 제어 흐름에서 예외를 사용할 일이 없어야 한다.&lt;/h3&gt;
&lt;p&gt;특정 상태에서만 호출할 수 있는 ‘상태 의존적’ 메서드를 제공하는 클래스는 ‘상태 검사’ 메서드도 함께 제공해야 한다. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;‘상태 의존적’ 메서드 : Iterator의 next()&lt;/li&gt;
&lt;li&gt;‘상태 검사’ 메서드 : Iterator의 hasNext()&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/c6592f78037bf221f06266c7bcf759b4/c6d67/001--01-1.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 734px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 59.583333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAABJ0AAASdAHeZh94AAABW0lEQVQoz31SWXbDMAj0cWIBAi1p0r7X+x+LgpBcu037MUabh2Fga4xaxMCgkg3CKrVqZlYkUgBQwAk4Ye5TSkd0bESouThIKaNKz7bOY40TxFf4mb9HuhJ63ABwXPA9KxtZfZcRuQV8Xx48zrLvP2Iv9xwiLMEiG4Q4CdclSWQfqBTENcj8fpz1WC8rzipDoXv3Zo+sdM/spGBlATngV9n/luwKpbDWe9VSi5Zext6bxPZzM3WleINCkZNExAvRUTIg2o/mCZs3Umwt1u2sjZJWU/5w3yQrJPt5T0c3F36SbohRspeWwC4whS/Tnx3mmqY6+BsnD7/Hxv1bzXF4stUoErrM3Cu1m3+coH9Wa4iV3szDJuGlRS4y5tK76/Dky8vDz3k2FI6xMUJ5GlkXbf2utfeIrQ9kzlMxfY/XCStRlGweVnv0NEVOvt9uuu/7BUdZe3rZmHXm1X4Bp+Zt9bC2MMsAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001  01 1&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/c6592f78037bf221f06266c7bcf759b4/c6d67/001--01-1.png&quot;
        srcset=&quot;/devHistoryBlog/static/c6592f78037bf221f06266c7bcf759b4/8ff5a/001--01-1.png 240w,
/devHistoryBlog/static/c6592f78037bf221f06266c7bcf759b4/e85cb/001--01-1.png 480w,
/devHistoryBlog/static/c6592f78037bf221f06266c7bcf759b4/c6d67/001--01-1.png 734w&quot;
        sizes=&quot;(max-width: 734px) 100vw, 734px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h4&gt;상태 검사 메서드 대신 사용할 수 있는 선택지&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Optional, 특정 값(null)
---계속&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[[책리뷰/Effective Java] 예외]]></title><description><![CDATA[아이템71) 필요 없는 검사 예외 사용은 피하라]]></description><link>https://ssongey.github.io/history/posts/2020-10-12--001--03</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-10-12--001--03</guid><pubDate>Mon, 12 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;아이템71) 필요 없는 검사 예외 사용은 피하라&lt;/h2&gt;
&lt;p&gt;API 호출자가 예외 상황에서 복구할 방법이 없다면 비검사 예외를 던지자.&lt;br&gt;
복구가 가능하고 호출자가 그 처리를 해주길 바란다면, 우선 옵셔널을 반환해도 될지 고민하자.&lt;br&gt;
옵셔널만으로는 상황을 처리하기에 충분한 정보를 제공할 수 없을 때만 검사 에외를 던지자.  &lt;/p&gt;
&lt;h3&gt;검사 예외 회피 방법&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;적절한 결과 타입을 담은 Optional 반환&lt;br&gt;
— 검사 예외를 던지는 대신, 단순히 빈 옵셔널을 반환하자&lt;br&gt;
— 단점은 예외가 발생한 이유를 담을 수 없다.  &lt;/li&gt;
&lt;li&gt;검사 예외를 던지는 메서드를 2개로 쪼개 비검사 예외로 변경&lt;br&gt;
단점)&lt;br&gt;
— 1. none thread-safe : actionPermitted와 action 호출 사이에 객체의 상태가 변할 수 있음&lt;br&gt;
— 2. actionPermitted 가 action 메소드의 작업 일부를 중복 수행한다면 성능 손해  &lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;//검사 예외를 던지는 메서드&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  obj&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;args&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;TheCheckedException&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
 &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt; 예외 상황에 대처
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;//상태 검사 메서드와 비검사 예외를 던지는 메서드&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;obj&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;actionPermitted&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;args&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  obj&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;args&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt; 예외 상황에 대처
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[[책리뷰/Effective Java] 예외]]></title><description><![CDATA[아이템72) 표준 예외를 사용하라]]></description><link>https://ssongey.github.io/history/posts/2020-10-12--001--04</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-10-12--001--04</guid><pubDate>Mon, 12 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;아이템72) 표준 예외를 사용하라&lt;/h2&gt;
&lt;p&gt;상황에 부합한다면 항상 표준 예외를 사용하자&lt;br&gt;
더 많은 정보를 제공하길 원한다면 표준 예외를 확장해도 좋지만, 예외는 직렬화 할 수 있다는 사실을 기억하자&lt;/p&gt;
&lt;h3&gt;Exception, RuntimeException, Throwable, Error 는 직접 재사용하지 말자&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;이 예외들은 다른 예외들의 상위 클래스이므로 안정적으로 테스트가 불가능하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;흔하게 재사용되는 예외&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;예외&lt;/th&gt;
&lt;th&gt;주요쓰임&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;IllegalArgumentException&lt;/td&gt;
&lt;td&gt;허용하지 않는 값이 인수로 건네졌을 때(null은 따로 NullPointerException으로 처리)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IllegalStateException&lt;/td&gt;
&lt;td&gt;args가 무엇이든 객체가 메서드를 수행하기에 적절하지 않은 상태일 때&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NullPointerException&lt;/td&gt;
&lt;td&gt;null을 허용하지 않는 메서드에 null을 건넸을 때&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IndexOutOfBoundsException&lt;/td&gt;
&lt;td&gt;인덱스가 범위를 넘어섰을 때&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ConcurrentModificationException&lt;/td&gt;
&lt;td&gt;허용하지 않는 동시 수정이 발견됐을 때&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UnSupportedOperationException&lt;/td&gt;
&lt;td&gt;호출한 메서드를 지원하지 않을 때&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;java exceptions handling mechanism&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;All-in-one Catch
— 항상 try 문 안에서 던져질 수 있는 특정 예외들에 해당하는 것들을 캐치하도록 하는 것이 좋다.&lt;br&gt;
이런 방식은 우리가 각 예외타입별 다른 방식으로 예외를 핸들 할 수 있는 가능성을 제공 한다.
아무런 조치를 취할 수 없다면, RuntimeException 을 통해 변환하는게 좋을 것이다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;doSomething&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ref) &lt;a href=&quot;https://m.blog.naver.com/PostView.nhn?blogId=sthwin&amp;#x26;logNo=220846528466&amp;#x26;targetKeyword=&amp;#x26;targetRecommendationCode=1&quot;&gt;https://m.blog.naver.com/PostView.nhn?blogId=sthwin&amp;#x26;logNo=220846528466&amp;#x26;targetKeyword=&amp;#x26;targetRecommendationCode=1&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Best Practices for Custom Exceptions&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;Always Provide a Benefit&lt;br&gt;
— 자바의 표준 예외들에 포함되지 않는 정보나 기능을 제공하지 않는 한 표준 예외를 사용하라&lt;/li&gt;
&lt;li&gt;Follow the Naming Convention&lt;br&gt;
— 표준 예외 클래스는 모두 Exception 으로 끝난다&lt;/li&gt;
&lt;li&gt;Provide Javadoc Comments for Your Exception Class&lt;br&gt;
— Javadoc은 예외가 발생할 수도 있는 상황과 예외의 일반적인 의미를 기술한다.&lt;br&gt;
목적은 다른 개발자들이 여러분의 API를 이해하도록 하고 일반적인 에러상황들을 피하도록 돕는것이다  &lt;/li&gt;
&lt;li&gt;Provide a Constructor That Sets the Cause&lt;br&gt;
— 커스텀 예외를 던지기 전에 표준예외을 캐치하는 케이스가 꽤 많다.&lt;br&gt;
보통 캐치된 예외에는 제품에 발생한 오류를 분석하는데 필요한 중요한 정보가 포함되어 있다.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;wrapException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; input&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MyBusinessException&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// do something&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;NumberFormatException&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// set &apos;e (Throwable)&apos;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MyBusinessException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;A message that describes the error.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ErrorCode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;INVALID_PORT_CONFIGURATION&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ref) &lt;a href=&quot;https://m.blog.naver.com/PostView.nhn?blogId=sthwin&amp;#x26;logNo=221144722072&amp;#x26;proxyReferer=https:%2F%2Fwww.google.com%2F&quot;&gt;https://m.blog.naver.com/PostView.nhn?blogId=sthwin&amp;#x26;logNo=221144722072&amp;#x26;proxyReferer=https:%2F%2Fwww.google.com%2F&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[[책리뷰/Effective Java] 예외]]></title><description><![CDATA[아이템73) 추상화 수준에 맞는 예외를 던져라]]></description><link>https://ssongey.github.io/history/posts/2020-10-12--001--05</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-10-12--001--05</guid><pubDate>Mon, 12 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;아이템73) 추상화 수준에 맞는 예외를 던져라&lt;/h2&gt;
&lt;p&gt;아래 계층의 예외를 예방하거나 스스로 처리할 수 없고, 그 예외를 상위 계층에 그대로 노출하기 곤란하다면 예외 번역을 사용하라.&lt;br&gt;
이때 예외 연쇄를 이용하면 상위 계층에는 맥락에 어울리는 고수준 예외를 던지면서 근본 원인도 함께 알려주어 오류를 분석하기에 좋다.&lt;/p&gt;
&lt;h3&gt;예외 번역 (exception translation)&lt;/h3&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/144ec8f1faa90fa93ee35ab5f474aef8/f6f78/001--05-1.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 932px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 32.08333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABJ0AAASdAHeZh94AAAA1UlEQVQY032R61KEMAyFef+HFFraKq5CrxS6zByTsDujDvrjm5OTlpCk3aAUhkHBOoeXvocxFilnpJQEHwJCjMiUi+QjxemhIRDxPGff2h2do0KjMXibJkyEtQ5Ka4zjCE30/SD5fd9Rtw3ruqLWKlpK+eGP40BXtx1lrfLBFa014be/4rhThykXfM4zlmU51XvSM54px3nW2+2DYi9dXcEr4R92bLR7h7avNKaBUlqUR5+pKO/rOdpfxZ5IwUoXQ8zwKcsDeOowPJQXnb/t6T/4Do/9BfaMy+MAhtmWAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001  05 1&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/144ec8f1faa90fa93ee35ab5f474aef8/f6f78/001--05-1.png&quot;
        srcset=&quot;/devHistoryBlog/static/144ec8f1faa90fa93ee35ab5f474aef8/8ff5a/001--05-1.png 240w,
/devHistoryBlog/static/144ec8f1faa90fa93ee35ab5f474aef8/e85cb/001--05-1.png 480w,
/devHistoryBlog/static/144ec8f1faa90fa93ee35ab5f474aef8/f6f78/001--05-1.png 932w&quot;
        sizes=&quot;(max-width: 932px) 100vw, 932px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h3&gt;예외 연쇄 (exception chaining)&lt;/h3&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/5e6a515a7eabbcd7526f44090da7bfe5/dc616/001--05-2.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 933px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 70%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAABJ0AAASdAHeZh94AAAB50lEQVQ4y4VSiZKqQAzk/79QlGsGFOW+D1H7pQe86u3WUtWVzBBCOt1WHMfwgwBaayilcD6fUZQlsjxHXhRomgY587xAUZSCwpxLqcm3Gt7xPAwDrNPpBHu/h+t6cBwHe8kd18VBctfzEARqvXNcc88a22a9+66TbzlY1/XSkBP6PnQYyseBiZxU69BM7fkBoihaWci7NE1xvlwMkzTLkCSJAaec5yusruteFKqqMhTruv7Ck/YwjPh8Ho/HV05YbT+glabkz5H5g67foqDv33d13aBt11reMz7B8zzP0lCK9SmBPsZCTwl8Q08pbfZ3uSRGJE5KUZqmNR//BNNwHEfUUlQSQvlJ/Y0avUwwTZMB63/CV0OCxbxg/oyfxeM4mHzYzqTJc2feTa89WtHxiJ1twxOL+KLo4eBA6dDQDUVdqs1IBzCGYSS1vllJKKrTBbEoXslK7vc7LNK6iA1o3CTNzOL54n6/rXFTb1kWLLfbGgU3yYlli9frdZ1wkHGNenWJvm3Q1LLHIkcmApSyP+ZVWWw7HF+7nMaPfNstm1qNWIUG9g87KPcA5exwVD7cQGjrCHHoI42Pvyr7n8r8ayvGTYsaSSaTCXX6se83D4pPezH002t/NjTKSfE8ryozTr9Y4y+Q8j92iymaEYoa9AAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001  05 2&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/5e6a515a7eabbcd7526f44090da7bfe5/dc616/001--05-2.png&quot;
        srcset=&quot;/devHistoryBlog/static/5e6a515a7eabbcd7526f44090da7bfe5/8ff5a/001--05-2.png 240w,
/devHistoryBlog/static/5e6a515a7eabbcd7526f44090da7bfe5/e85cb/001--05-2.png 480w,
/devHistoryBlog/static/5e6a515a7eabbcd7526f44090da7bfe5/dc616/001--05-2.png 933w&quot;
        sizes=&quot;(max-width: 933px) 100vw, 933px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;</content:encoded></item><item><title><![CDATA[[책리뷰/Effective Java] 예외]]></title><description><![CDATA[아이템75) 예외의 상세 메시지에 실패 관련 정보를 담으라]]></description><link>https://ssongey.github.io/history/posts/2020-10-12--001--07</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-10-12--001--07</guid><pubDate>Mon, 12 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;아이템75) 예외의 상세 메시지에 실패 관련 정보를 담으라&lt;/h2&gt;
&lt;h3&gt;스택추적&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;실패 원인을 분석할 때 얻을 수 있는 정보는 스택 정보인 경우가 많다.&lt;/li&gt;
&lt;li&gt;예외의 toString 메서드에 실패 원인에 관한 정보를 가능한 많이 담아 반환하는 일은 아주 중요하다. &lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;실패 순간을 포착하려면 발생한 예외에 관여된 모든 매개변수와 필드의 값을 실패 메시지에 담아야 한다.&lt;/h3&gt;
&lt;ul&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;java9에서 제공하는 IndexOutOfBoundsException &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;IndexOutOfBoundsException&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;RuntimeException&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;long&lt;/span&gt; serialVersionUID &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;234122996006267687L&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;IndexOutOfBoundsException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;IndexOutOfBoundsException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;IndexOutOfBoundsException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; index&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Index out of range: &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; index&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;저자가 권하는 방법&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/**
 * IndexOutOfBoundsException을 생성한다
 * @param lowerBound 인덱스의 최솟값
 * @param upperBound 인덱스의 최댓값 + 1
 * @param index 인덱스의 실젯값
 */&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;IndexOutOfBoundsException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; lowerBound&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; upperBound&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; index&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// 실패를 포착하는 상세 메시지를 생성한다.&lt;/span&gt;
   &lt;span class=&quot;token keyword&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;최솟값: %d , 최댓값: %d, 인덱스: %d&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; lowerBound&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; upperBound&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; index&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
   
   &lt;span class=&quot;token comment&quot;&gt;// 프로그램에서 이용할 수 있도록 실패 정보를 저장해둔다.&lt;/span&gt;
   &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lowerBound &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; lowerBound&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
   &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;upperBound &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; upperBound&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
   &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;index &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; index&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[[책리뷰/Effective Java] 예외]]></title><description><![CDATA[아이템76) 가능한 한 실패 원자적으로 만들라]]></description><link>https://ssongey.github.io/history/posts/2020-10-12--001--08</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-10-12--001--08</guid><pubDate>Mon, 12 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;아이템76) 가능한 한 실패 원자적으로 만들라&lt;/h2&gt;
&lt;p&gt;일반화 해서 말하자면 호출된 메서드가 실패 하더라도 해당 객체는 메서드 호출 전 상태를 유지해야 한다.
이러한 특성을 실패 원자적(failure atomic)이라고 한다.&lt;/p&gt;
&lt;h4&gt;메서드를 원자적으로 만드는 방법&lt;/h4&gt;
&lt;ul&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;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;substring&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; beginIndex&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;beginIndex &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;StringIndexOutOfBoundsException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;beginIndex&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; subLen &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; beginIndex&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;subLen &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;StringIndexOutOfBoundsException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;subLen&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;beginIndex &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;isLatin1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;StringLatin1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;newString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; beginIndex&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; subLen&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                      &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;StringUTF16&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;newString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; beginIndex&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; subLen&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[[책리뷰/Effective Java] 예외]]></title><description><![CDATA[아이템77) 예외를 무시하지 말라]]></description><link>https://ssongey.github.io/history/posts/2020-10-12--001--09</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-10-12--001--09</guid><pubDate>Mon, 12 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;아이템77) 예외를 무시하지 말라&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;API 설계자가 메서드 선언에 예외를 명시하는 까닭은, 그 메서드를 사용할 때 적절한 조취를 취해달라고 말하는 것이다.&lt;/li&gt;
&lt;li&gt;예외는 문제 상황에 잘 대처하기 위해서 존재하는데 catch 블록을 비워두면 예외가 존재할 이유가 없어진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; 
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt; 
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;SomeException&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;예외를 무시해야 할 떄&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;FileInputStream을 닫을 때
(입력 전용 스트림이므로) 파일의 상태를 변경하지 않았으니 복구할 것이 없음
(스트림을 닫는다는 건) 필요한 정보는 이미 다 읽었다는 뜻이니 남은 작업을 중단할 이유도 없음&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;예외를 무시하기로 했다면 catch 블록 안에 그렇게 결정한 이유를 주석으로 남기고 예외 변수 이름도 ignore로 바꿔놓도록 하자 .&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Future&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; f &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; exec&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;submit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;planarMap&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;chromaticNumber&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; 
&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; numColors &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; 
&lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; 
numColors &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; f&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1L&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;TimeUnit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;SECONDS&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; 
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;TimeoutException&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ExecutionException&lt;/span&gt; ignored&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[[책리뷰/Effective Java] 예외]]></title><description><![CDATA[나의결론]]></description><link>https://ssongey.github.io/history/posts/2020-10-12--001--10</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-10-12--001--10</guid><pubDate>Mon, 12 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;예외 처리에 대한 내 결론이올시다&lt;/h2&gt;
&lt;h3&gt;Parameter Validation in Controller&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;parameter validation 은 controller 내에서 진행&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Service (Business)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;service 로직에서 발생한 예외에 대해서는 cause, stacktrace 가 필요함.&lt;/li&gt;
&lt;li&gt;표준 예외를 적극적으로 사용 (정의된 메시지 사용)&lt;/li&gt;
&lt;li&gt;특정 로직에 대한 예외처리가 필요한 경우 custom exception 사용&lt;/li&gt;
&lt;li&gt;custom exception handling 은 controller 에서 정의&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;NoSuchMethodException&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
   &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MyServiceException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Some information: &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getMessage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;//Incorrect way&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;NoSuchMethodException&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
   &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MyServiceException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Some information: &quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;//Correct way&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Method (API)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;checked exception 에 대해 throws 선언&lt;/li&gt;
&lt;li&gt;빈 catch 블록을 생성하거나 예외를 무시하지 말 것 &lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;NoSuchMethodException&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;//Incorrect way&lt;/span&gt;
   &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;//Incorrect way&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SpecificException1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SpecificException2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;//Correct way&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ref)&lt;br&gt;
&lt;a href=&quot;https://woowacourse.github.io/javable/2020-08-17/custom-exception&quot;&gt;standard exception vs custom exception&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://howtodoinjava.com/best-practices/java-exception-handling-best-practices/#exception-types&quot;&gt;exception handling best practice&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://howtodoinjava.com/java/exception-handling/best-practices-for-for-exception-handling/&quot;&gt;custom exception handling best practice&lt;/a&gt;  &lt;/p&gt;
&lt;h4&gt;Ref [standard exception vs custom exception] 에 대한 소견&lt;/h4&gt;
&lt;p&gt;표준 예외를 적극적으로 사용하자!&lt;/p&gt;
&lt;ul&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;사용자 정의 예외가 필요하다?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;이름으로도 정보 전달이 가능하다.
— 반론) message에서도 충분히 가능하다&lt;/li&gt;
&lt;li&gt;상세한 예외 정보를 제공할 수 있다.
— 반론) back 에서는 message로 충분히 커버가 가능하며, front에서 예외에 대한 상세 내용이 필요하다면
ErrorResponse에 대한 클래스가 정의를 한다&lt;/li&gt;
&lt;li&gt;예외에 대한 응집도가 향상된다.
— 전달하는 정보의 양이 많아질수록? 이건 오케이
— 책임소재? stacktrace 활용하면 되지 않나?
— 같은 예외가 여러 곳에서 사용? standard exception 으로 충분히 커버 가능하지 않나?&lt;/li&gt;
&lt;li&gt;예외 발생 후처리가 용이하다.
— 발생위치 파악이 힘듬? stacktrace&lt;/li&gt;
&lt;li&gt;예외 생성 비용을 절감
— stacktrace는 필요하다고 본다.&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[[책리뷰/Effective Java] 예외]]></title><link>https://ssongey.github.io/history/posts/2020-10-12--001</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-10-12--001</guid><pubDate>Mon, 12 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/devHistoryBlog/history/posts/2020-10-12--001--01&quot;&gt;아이템69) 예외는 진짜 예외 상황에만 사용하라&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/devHistoryBlog/history/posts/2020-10-12--001--02&quot;&gt;아이템70) 복구할 수 있는 상황에는 검사 예외를, 프로그래밍 오류에는 런타임 예외를 사용하라&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/devHistoryBlog/history/posts/2020-10-12--001--03&quot;&gt;아이템71) 필요 없는 검사 예외 사용은 피하라&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/devHistoryBlog/history/posts/2020-10-12--001--04&quot;&gt;아이템72) 표준 예외를 사용하라&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/devHistoryBlog/history/posts/2020-10-12--001--05&quot;&gt;아이템73) 추상화 수준에 맞는 예외를 던져라&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/devHistoryBlog/history/posts/2020-10-12--001--06&quot;&gt;아이템74) 메서드가 던지는 모든 예외를 문서화하라&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/devHistoryBlog/history/posts/2020-10-12--001--07&quot;&gt;아이템75) 예외의 상세 메시지에 실패 관련 정보를 담으라&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/devHistoryBlog/history/posts/2020-10-12--001--08&quot;&gt;아이템76) 가능한 한 실패 원자적으로 만들라&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/devHistoryBlog/history/posts/2020-10-12--001--09&quot;&gt;아이템77) 예외를 무시하지 말라&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/devHistoryBlog/history/posts/2020-10-12--001--10&quot;&gt;나의 결론&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;https://jeong-pro.tistory.com/195&quot;&gt;https://jeong-pro.tistory.com/195&lt;/a&gt;
&lt;a href=&quot;https://cheese10yun.github.io/spring-guide-exception/&quot;&gt;https://cheese10yun.github.io/spring-guide-exception/&lt;/a&gt;
&lt;a href=&quot;https://wbluke.tistory.com/15&quot;&gt;https://wbluke.tistory.com/15&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[[Java] Enum]]></title><link>https://ssongey.github.io/history/posts/2020-10-04--001.md</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-10-04--001.md</guid><pubDate>Sun, 04 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;열거 타입(Enumeration Type)&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;한정된 값만을 갖는 데이터 타입&lt;/li&gt;
&lt;li&gt;한정된 값은 열거 상수(Enumeration Constant)로 정의&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;열거 타입 변수&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;열거 타입 변수 선언&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Week today;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;열거 상수 값 저장 (열거 타입 변수값은 열거 상수 중 하나)&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Week today = Week.SUNDAY;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;열거변수는 참조타입&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Week today = null;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;열거 타입 변수는 참조 타입
열거 타입 변수는 참조 타입이므로 null 값 저장 가능&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;열거 상수는 열거 객체를 참조한다&lt;/h3&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/8072482908af9b99e86957ebe49be105/49217/001--1.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 701px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 67.91666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAABJ0AAASdAHeZh94AAAC6klEQVQ4y22Si27iVhCG/ZJ9qD7BtpWqbJpGTZtttqtI3RZQNiQkhEvCEjaAQwIBDDYYMMb4fvl6bLrVrtSRfp+xZ87MP/9Yit0zFFWjJY9oP42pNR/pPo8o1drcPvTpDjRs14ckIQkj4iAgiWPsrc3W2rI2LV4mS1wvIAxDJF/7htVyQEd+4bHXp3nfRu49U7+7F2ixWG2I4oTQ8wkti3i7JfYDHMclEgXmqy3t/pzVxhM9YyRT/VZ00xkNRzx2ZRr1W5qNj8idDsPBC3EUkdpyvmSmTLEME2OxxhBn4Hv0FYNWT2O5tgXDAClNTtg901EC3886R1HIZwuDiMV8hWmKQmuDyVjDNKwsFggJlsKPRb5t20hJEmXFHDfAsgNsL2LrpL6PaXnZuHEUM+ipdB+GPMkT5E8jIZORsV8YjtBZFyO7GSFRcMdPna0ZvMxQhMDDsc5gNM/E9oNdPBCiO1s3QxiEmYae59IbLmh0JujGVnwPdgXTK6HjE6wMQsPAW28+67CzbMNiJNPEtTbZtn3PwxfypIVNyxbFvQz/MVSGuljKiEFfpd3qs9CNTJ/0ku8KZrpO/1nh6WmaNU3H+z+TvhTe90KBQBSKxFKElukvkrELUMTmW0LHVnvMqv1pt8QkJZ98BclxHBxbID1TJo7NZmOgqVMmSiq+jrFaMamVaV1VeSxXmDeq2CI/3erXcJCm0ykpNE1lPpuhqmMeHqrcNyt8bFxTvy2KRY2ZzTR0VWE+VZiJ3PR9LpD6mra7rwoSUkf8wHK3S7l6x2X5jmKpyvt8gb8KBfLnRS6uSshyGm9QumlwXWtydXNHqXwrYjUq9Rb1RpuawEO7g1SpVEjx4bxE4cPlDmeXnJ1fcVa8pnhZplat8tPRKa/2Tvjx8JQf9v/g+9dv+W7vdw6OcxyfXnD07pyL0g1SLpcjRSGfp1D4Avlchnx+Fz88OmHv4Df2fz7m9b/nwS8n7B++4fDXd8J/y5/v/+YfmUgCl9aYB8gAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001  1&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/8072482908af9b99e86957ebe49be105/49217/001--1.png&quot;
        srcset=&quot;/devHistoryBlog/static/8072482908af9b99e86957ebe49be105/8ff5a/001--1.png 240w,
/devHistoryBlog/static/8072482908af9b99e86957ebe49be105/e85cb/001--1.png 480w,
/devHistoryBlog/static/8072482908af9b99e86957ebe49be105/49217/001--1.png 701w&quot;
        sizes=&quot;(max-width: 701px) 100vw, 701px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Week week1 = Week.SUNDAY;
Week week2 = Week.SUMDAY;

System.out.println(wee1 == week2); // true&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;week1, week2 모두 참조 타입으로&lt;br&gt;
힙에 생성된 Week.SUNDAY 객체의 주소값을 가지고 있으므로
주소 비교시 true 가 출력된다.&lt;/p&gt;
&lt;h2&gt;열거 객체의 메소드&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;열거 객체는 열거 상수의 문자열을 내부 데이터로 가지고 있음&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;열거 타입은 컴파일 시 java.lang.Enum 클래스를 자동 상속&lt;br&gt;
열거 객체는 java.lang.Enum  클래스의 메소드 사용 가능

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/283d508245c5b8baa6ffb188d3bda755/1ac29/001--2.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 27.083333333333332%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAABJ0AAASdAHeZh94AAABEElEQVQY0y2Q2XKDMAxF+f9/6/ShmUynbMaYxQZCgBhjltxeaB80sjXy0ZED/bD4vCe4JxWEnpA3L9zjEl9hjo9bhFC2rFkk1QhR/4U0E36kwS1UKDoH1drrbTs4BH47kBc1mseA17LD+Q2z3yHyAqrScOuBhaG7AVGaIRISqVT4DmMIWcB0PZ6jxbxsOFnBdrzxHCZMs4f9L87Oc0iF4gRywLrjGphmOWICBbMgtKwMEt6jRKAnYycr8OvGBgnT9peN8ytBNRszSFXCNB2Bb3T9eEFiPj4j4wbxacxzVWtYt2DbabjQIEkFVFlfq3nquGWFNi2a9sEaDWk9Wv4VrWttkKmCthI5c8ktTgZbLuAvOcV4Dt8MExEAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001  2&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/283d508245c5b8baa6ffb188d3bda755/d9199/001--2.png&quot;
        srcset=&quot;/devHistoryBlog/static/283d508245c5b8baa6ffb188d3bda755/8ff5a/001--2.png 240w,
/devHistoryBlog/static/283d508245c5b8baa6ffb188d3bda755/e85cb/001--2.png 480w,
/devHistoryBlog/static/283d508245c5b8baa6ffb188d3bda755/d9199/001--2.png 960w,
/devHistoryBlog/static/283d508245c5b8baa6ffb188d3bda755/1ac29/001--2.png 1022w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Week today = Week.SUNDAY;
today.name(); // SUNDAY
today.ordinal(); // 0 (enum 순서는 0부터 시작)
today.valueOf(&amp;quot;SUNDAY&amp;quot;) // Week.SUNDAY&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[[책리뷰/이것이 자바다] Class]]></title><description><![CDATA[Annotation]]></description><link>https://ssongey.github.io/history/posts/2020-10-04--002--01</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-10-04--002--01</guid><pubDate>Sun, 04 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;Annotation&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;프로그램에게 추가적인 정보를 제공해주는 메타데이터(metadata)&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;어노테이션 용도&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;컴파일러에게 코드 작성 문법 에러 체크하도록 정보 제공&lt;br&gt;
ex) 메소드가 재정의 되었는지 확인할 수 있다. (@Override)&lt;/li&gt;
&lt;li&gt;소프트웨어 개발 툴이 빌드나 배치 시 코드를 자동 생성하게 정보 제공&lt;br&gt;
ex)xml 설정 파일을 자동 생성하거나 배포를 위한 JAR 압축 파일을 자동 생성할 수 있다.&lt;/li&gt;
&lt;li&gt;실행 시(런타임시) 특정 기능 실행하도록 정보 제공&lt;br&gt;
ex) 객체가 애플리케이션 내부에서 해야할 역할을 정의할 수 있다. (컨트롤러, 서비스 등)&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Annotation 정의 및 적용&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// 정의&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token annotation punctuation&quot;&gt;@interface&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AnnotationName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;//default 엘리먼트&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;elementName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;//적용&lt;/span&gt;
&lt;span class=&quot;token annotation punctuation&quot;&gt;@AnnotationName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;value 값&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token annotation punctuation&quot;&gt;@AnnotationName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;value 값&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; elementName&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;Annotation 적용 대상&lt;/h4&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/86762c8a5a58a19c3cbd470dc100aa0f/a0209/002--01-1.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 725px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 46.666666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAABYlAAAWJQFJUiTwAAABeklEQVQoz4WQ626CQBCFff9HazVBBURhuQgsK5cFIgJqzOnMGtumaeKPk7OZnfnmsth4MT43PpabA5ZbHytbwNpFsP0MXqRg0b/lRnCCHMdyQFR0iFWPuOiNh7I1CjKNuh+x2DoePlZrpPKErCiRqxqq0qSWYiVW1hYHERu5+xBhkkPEGQQ5x1TVoekGVPqMYZyxkHmOUARIjwnpCFVI5FmG6zyj7ztEocCR/uIoQlWe0HctulaTd9BNjXG84HqdMc8T7vcbFt5uh7W1RlmWqOsaTdOY92UcqaBBEASoyflvmrlwNj5Nz/dIeazLhcA3AiZxgr3nIadJpZRG0zSZZIb7h4MB/i7+Twy8MTCiVVzXhW3bBJUGwgk8hdYaHjejJu+ALAPk2ziOAwanaWqkdUt3uZLTyr5vGjGc13wLDOnoPJ3r7iCEQJIkaNsfIE8YUJyBryn5JH/1DayrCkVRQNIUfIfH42EKWefzGUoptN2zwX+glzh/GAZ8AU8So7rA63N2AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002  01 1&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/86762c8a5a58a19c3cbd470dc100aa0f/a0209/002--01-1.png&quot;
        srcset=&quot;/devHistoryBlog/static/86762c8a5a58a19c3cbd470dc100aa0f/8ff5a/002--01-1.png 240w,
/devHistoryBlog/static/86762c8a5a58a19c3cbd470dc100aa0f/e85cb/002--01-1.png 480w,
/devHistoryBlog/static/86762c8a5a58a19c3cbd470dc100aa0f/a0209/002--01-1.png 725w&quot;
        sizes=&quot;(max-width: 725px) 100vw, 725px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h4&gt;&lt;/h4&gt;</content:encoded></item><item><title><![CDATA[[Java] Class]]></title><link>https://ssongey.github.io/history/posts/2020-10-04--002</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-10-04--002</guid><pubDate>Sun, 04 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;객체(Object) 란?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;자신의 속성과 동작을 가진 모든 것&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;객체 vs 인스턴스&lt;br&gt;
— 객체는 선언을 의미
— 인스턴스는 연산자를 통해 클래스로부터 실체화가 됨을 의미&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;class Car { ... }
Car tico, morning, matiz; // 객체
tico = new Car(); // 인스턴스&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h5&gt;참고&lt;/h5&gt;
&lt;p&gt;&lt;a href=&quot;https://dbnsecu.tistory.com/8&quot;&gt;https://dbnsecu.tistory.com/8&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://gmlwjd9405.github.io/2018/09/17/class-object-instance.html&quot;&gt;https://gmlwjd9405.github.io/2018/09/17/class-object-instance.html&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;객체간의 관계&lt;/h2&gt;
&lt;h4&gt;관계의 종류&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;집합 관계: 완성품과 부품의 관계&lt;/li&gt;
&lt;li&gt;사용 관계: 객체가 다른 객체를 사용하는 관계&lt;/li&gt;
&lt;li&gt;상속 관계: 종류 객체와  구체적인 사물 객체 관계

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/e1dea42cb4af4f90f96507f339214fe4/d0e73/002--1.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 671px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 79.58333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAACXBIWXMAABJ0AAASdAHeZh94AAACTUlEQVQ4y51UaXPaMBDl//+gHtM20w+QkFIIxAFf2GAbH2DMId8Xr5LAEChtZ7ozO7Kk1ZN231u38B92OBz4WBQFpnMbuunhuHJAqwlo/P38X4DbMEW7L+Hbs4woLfnab4D3QNlYM68va1lRQTQC2I4HQbXRV5ZHwNuXsOm9C25tH6V4+KnD9XzYywADyUZZVccXplkGVTdhOqurlBqr6xrazIKiLxAnKSp6MIkjKOYaH9pveBppIHF2SXnm7PA4kPHxUYa7SfhGkiQghPDvgGTojlR86owxoKmFZA/f9xHHMSeDXdg8pLXaxuiNLeQxwcIL0B0vkGUpP+C5Lvx1gJ7kYk3HKCTovJqcDMYoe+kVUQywooXuCDbaAwUvkgXbJzz4vYnmFl+7MoaSAcnwKVCNP6mDp0yiDGN1AcsNOJv3bKLZGE40ZHn5Vym17rGY5TlNO0N+GosiR10VtAQOLMvitWWiZnvMr2p41lmjMeppEqEsC36IeVmWSNMEcRTyuhV03qwnScxjz4C3dVj6AUTVxGYfXYnTopKSqGxIGF1lMzNsSJpJL7jpFK7HooYwdXg7tV9tMMK4iOMCL6KJ7z0ZA9U/gzE59ccz3nqMuHMNG0BB9zE1PNR5hD5Vvm4fg3qiQztijSwJuWzWu5iT90wlFgQbqkuC9sjk4r4CXG4TfH5S0BemGCkOwpP61cUOX7oShuIMb5qH/JSeoK/x8IPKSTQgzldcTq3bH4HhbjGZ2gh20bl+bEeeLyHql0v474sCjDUH8syl7Xsk5hdfjs4y5DsQvwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002  1&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/e1dea42cb4af4f90f96507f339214fe4/d0e73/002--1.png&quot;
        srcset=&quot;/devHistoryBlog/static/e1dea42cb4af4f90f96507f339214fe4/8ff5a/002--1.png 240w,
/devHistoryBlog/static/e1dea42cb4af4f90f96507f339214fe4/e85cb/002--1.png 480w,
/devHistoryBlog/static/e1dea42cb4af4f90f96507f339214fe4/d0e73/002--1.png 671w&quot;
        sizes=&quot;(max-width: 671px) 100vw, 671px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;클래스 변수&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;new 연산자에 의해 리턴 된 객체의 번지 저장 (참조 타입 변수)&lt;/li&gt;
&lt;li&gt;힙 영역의 객체를 사용하기 위해 사용

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/997e6001c610902d915bc718a2946957/7de01/002--2.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 794px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 24.583333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAABJ0AAASdAHeZh94AAABKklEQVQY0zWQ6U7CUBSE+/4PZaImGkFRiqylpRvl9ra3dN9AP68YJ/mS+XEyZ84xsrxCqoL0XFF1F+ruStkMFJq6HRmHC33X0/eD9iN/+iZVMSKOkIng+jVoRoaxxTDXDhPT4mPjYUc5XlxzECXOqeSYNJR6oTjFyDi9+f/AslYUlWLvB8RZxnhtaPsSY7H1mK193jc+D5MFs5WLKxtcHexGhQ5SpIlCygQp1K1t2zUkhYMThXpGMV0HeNLmXIUYthextAKNj+UJNs6Rj+UeyxeEomA+3fI52/H6NOf9ZU3X9lRNwcq949GcYgcZSzvgzbrnqEyMNCs4yYwkK8nrHpXXHE8JcZrrs3pEmBEeJIddSKzb/Orr+0qQztkGEyYrk+Vhrt/1TKR2/AD4cnPAGPuHegAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002  2&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/997e6001c610902d915bc718a2946957/7de01/002--2.png&quot;
        srcset=&quot;/devHistoryBlog/static/997e6001c610902d915bc718a2946957/8ff5a/002--2.png 240w,
/devHistoryBlog/static/997e6001c610902d915bc718a2946957/e85cb/002--2.png 480w,
/devHistoryBlog/static/997e6001c610902d915bc718a2946957/7de01/002--2.png 794w&quot;
        sizes=&quot;(max-width: 794px) 100vw, 794px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;인스턴스 멤버&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;인스턴스 생성 시 아래와 같은 메모리 구조를 갖는다.

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/fa559797bc9942acb2507cb85da0e734/0f79a/002--3.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 689px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 54.166666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABJ0AAASdAHeZh94AAACFUlEQVQoz3WS627aQBBGef8nitK0Uksa0tBwDTE2Nr6BbfAF3zBgY04XI1CjpiONdn/snJ3vm2mNFYvHV4mBbDM1A+ZuymyZ4IRbznE6nT7kOUwnoP1boj+1mrqhsmxqbD+nNVIWPDwNmeg+khkh2zGStcFe5/8Favaa+8cBjz2ZzlBjrK2aGsNLaWlOTF9eoLmZyBTVSVEWCcvgArxA+QBcrBNeJYueZNJ905GtqOnQXGW0ZnYoJE8Zq57oMEAyzp2GArgVgJqyOlCfjmcsx7oSZ43lRvwazxnNHEaqK8A270aIJVS1pqbP00DleaTRnVjioU5PdhrJlYAFoU+cxMRp2gBPVMxMl4efo8bHHyIHiiskx+hnyXlRku+P5LvykvuSrDhQHCoBKNmXBYbj0xGf2quI46kgL3YEUYofxXjrkE2SUwjGTtS0rj7tD1uWjkWSRhzKLbt9LgpjTNfg5c1ANTxGmk2cBeTbXNhw4rNoXY3epCs8z8P3Q1x3he1qouMNQTpnqE5o916xfBVNdCQtPOZ+jLXJMTcZUbG/bcQN6IQyM6PP3HpH0YdI+jNR6oqpd5HN83q809eGfFOm3I1n3E/UJr8qNk5a/As8CK+S3Cfd+uJcN5LjzKErf2kmqosd7UwGqF6HQ1UJyQg/xYjq+ia/AV4vn0W2C3gz72iPv9MevtBX71GWber6eN3Qv3b1cv8Dpxk4Wv0KbQEAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002  3&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/fa559797bc9942acb2507cb85da0e734/0f79a/002--3.png&quot;
        srcset=&quot;/devHistoryBlog/static/fa559797bc9942acb2507cb85da0e734/8ff5a/002--3.png 240w,
/devHistoryBlog/static/fa559797bc9942acb2507cb85da0e734/e85cb/002--3.png 480w,
/devHistoryBlog/static/fa559797bc9942acb2507cb85da0e734/0f79a/002--3.png 689w&quot;
        sizes=&quot;(max-width: 689px) 100vw, 689px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;this 키워드&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;인스턴스 자신의 주소를 가지고 있는 키워드

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/965ac43876ec650ff6c4ed7f06a9fdc7/cecac/002--4.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 728px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 54.166666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABJ0AAASdAHeZh94AAAB9UlEQVQoz41S63KaQBjNK/YB2z+dPkSnzWjMqG1iiBIJoBBU5A6iolyWy+m3xMaY6Y8yc/h2v13OnnOWq+3GxcKYQbO2WHoBnCgibLDyQyxdHyvqmV7Ywo1iWouxpjU3jPHxaZoGV1nBYFkDXP/6gu/CBN3JBENZQlcU8WM0xrVA9UFEbzzFvaKiL8m4FacYKRq2hwx7QlGWZ0I+2Puf0b/9hJ/3Om7GKn5LGu4kHcMnHd3HGTrCDIKygKitIKhLDEUdPer3JwamcxOy4SArXklbQsYYng0LQXxE3dC8asDKugXfWFKtqhpNDeS0NysK5NRnpKyuaxSsREX1RNiAjyXNw534gtHUwFixsXALmEFJWZZE8ro5TEKsIhOsZu1cdeetzYsM+aAiRepyh7EaQtJjPM0jyMsEulPQZeWkhh9awozWkGwZRrB4Q7CnC9p6OObHs2VOKOkhqbPwINl4lB3KzIU4D2E43B5ZZynZqpDkh5a4o/SwS/eIDtGburNCCk5+2ZDlNSaKD4FIp3oEzc6h2wWSlKGvDzDQhlCdGWaehmdbwTq2YG8dypxdWq6JMElLHLKGUON4qklateAObPrY23nw90GrrCPf4OvgG+ZEfqHwfaj8gi4r/vnz8ifJEjikLmf5ud+cMvzL/j94T/rxEP7+A5ggPzF4DYBLAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002  4&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/965ac43876ec650ff6c4ed7f06a9fdc7/cecac/002--4.png&quot;
        srcset=&quot;/devHistoryBlog/static/965ac43876ec650ff6c4ed7f06a9fdc7/8ff5a/002--4.png 240w,
/devHistoryBlog/static/965ac43876ec650ff6c4ed7f06a9fdc7/e85cb/002--4.png 480w,
/devHistoryBlog/static/965ac43876ec650ff6c4ed7f06a9fdc7/cecac/002--4.png 728w&quot;
        sizes=&quot;(max-width: 728px) 100vw, 728px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;정적 멤버와 static&lt;/h2&gt;
&lt;h4&gt;정적(static) 멤버란?&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;클래스에 고정된 필드와 메소드 - 정적 필드, 정적 메소드&lt;/li&gt;
&lt;li&gt;정적 멤버는 클래스에 소속된 멤버&lt;br&gt;
— 객체 내부에 존재하지 않고, 메소드 영역에 존재&lt;br&gt;
— 정적 멤버는 객체를 생성하지 않고 클래스로 바로 접근해 사용

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/fd66c6c2551992959f6abddb8bea5bb4/7fee5/002--5.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 781px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 27.500000000000004%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABJ0AAASdAHeZh94AAABRUlEQVQY012QSXOCQBBG+f/3/IuccsohqVT2UmNKwA2duBBARBgGVIgbL6MmF7vqzfRh6pvXbXSFhzMOsPpjvucZYVoykwVBsmam8eM1WV5QppIsiljLhEIpXNcljhccqi2HnxWHpWJXLjFuH5vcvbZ4N0e0RxGmCGmPY5xvpUnpuIpwrkicPqLRILBtVmFIIiVK6U+WktjzUL5PmecYdXtMy/Fo9lzsr5DP0z1HBDnCz+jr4Dj/oSgKpu4UlWX8V8Weid+hadZoOyYyDzEa7Ql1e4Q1DE4BQ83AO9sNfUXPlfrhjkgN+BDXWOKBqtJh+jgi84AonWimzGKBcf9m8fTR47He1WMLatr4udnn5XOgzX1MbbtIt/hJi3vrilrnhupw9jsGX5aRrjao9fbEsb8k0eOWmz37/QaZheR6+ae4P8NLfgFuO748ykBSPgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002  5&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/fd66c6c2551992959f6abddb8bea5bb4/7fee5/002--5.png&quot;
        srcset=&quot;/devHistoryBlog/static/fd66c6c2551992959f6abddb8bea5bb4/8ff5a/002--5.png 240w,
/devHistoryBlog/static/fd66c6c2551992959f6abddb8bea5bb4/e85cb/002--5.png 480w,
/devHistoryBlog/static/fd66c6c2551992959f6abddb8bea5bb4/7fee5/002--5.png 781w&quot;
        sizes=&quot;(max-width: 781px) 100vw, 781px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;정적 초기화 블록&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;클래스가 메소드 영역으로 로딩될 때 자동으로 실행하는 블록&lt;/li&gt;
&lt;li&gt;정적 필드 초기화 및 정적 메소드 호출 가능&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;인스턴스 멤버나 메소드 호출 불가능&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;static {
...
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Annotation&lt;/h4&gt;</content:encoded></item><item><title><![CDATA[[책리뷰/Effective Java] 객체 생성과 파괴]]></title><description><![CDATA[아이템1) 생성자 대신 정적 팩터리 메서드를 고려해라]]></description><link>https://ssongey.github.io/history/posts/2020-10-04--003--01</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-10-04--003--01</guid><pubDate>Sun, 04 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;아이템1) 생성자 대신 정적 팩터리 메서드를 고려해라&lt;/h2&gt;
&lt;p&gt;정적 팩터리 메서드와 public 생성자는 각자의 쓰임새가 있으니 상대적인 장단점을 이해하고 사용하는 것이 좋다.
그렇다고 하더라고 정적 팩터리를 사용하는 게 유리한 경우가 더 많으므로 무작정 public 생성자를 제공하던 습관이 있다면 고치자.&lt;/p&gt;
&lt;h3&gt;정적 팩터리 메서드가 생성자보다 좋은 장점&lt;/h3&gt;
&lt;h4&gt;1. 이름을 가질 수 있다.&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;어떤 역할의 객체 생성인지 명시 가능&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;값이 소스인 BigInteger를 반환  
생성자 :            BigInteger(int, int, Random)
정적 팩터리 매서드 : BigInteger.probablePrime(int, Random)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;2. 호출될 때마다 인스턴스를 새로 생성하지 않아도 된다.&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/devHistoryBlog/history/posts/2020-10-04--004&quot;&gt;플라이웨이트 패턴(Flyweight pattern)&lt;/a&gt;&lt;br&gt;
데이터를 공유하여 메모리를 절약하는 패턴,
공통으로 사용되는 객체는 한번만 사용되고 Pool에의해서 관리, 사용된다.
(JVM의 String Pool에서 같은 String이 잇는지 먼저 찾는다. [불변객체 String])  &lt;/li&gt;
&lt;li&gt;불변클래스&lt;br&gt;
인스턴스를 미리 만들어 놓거나 인스턴스 캐싱으로 재사용하여 불필요한 객체 생성을 피할 수 있다.
ex ) Boolean.valueOf(boolean b);&lt;/li&gt;
&lt;li&gt;인스턴스 통제(instance-controlled) 클래스&lt;br&gt;
정적 팩터리 방식의 클래스는 언제 어느 인스턴스를 살아 있게 할지를 철저히 통제할 수 있다.&lt;br&gt;
싱글턴 / noninstatntialbe로 만들 수 있다.&lt;br&gt;
불변 값 클래스에서 동치 인스턴스 하나임을 보장 ex ) Enum : 인스턴스가 하나만 만들어짐&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;3. 반환 타입의 하위 타입 객체를 반환할 수 있는 능력이 있다.&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;생성자의 경우에는 반환형 클래스가 정해져있지만, static factory method 는 하위타입을 반환할수도 있다. &lt;/li&gt;
&lt;li&gt;java.util.Collections 가 예시다&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;ps. Java8 인터페이스&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Default Method&lt;br&gt;
— default 키워드를 통해 메서드를 구현할 수 있다.&lt;br&gt;
또, 이를 구현하는 클래스는interface의 메서드를 @Override 할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Coffee&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;  
  &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getBrandName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;MEGA&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// getBrandName이 없는 DTO 클래스 생성&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Americano&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Coffee&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;long&lt;/span&gt; price&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Americano&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;long&lt;/span&gt; price&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;price &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; price&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// default 메소드에 적용되어있는 getBrandName() 메소드 사용&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Test&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;    
  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; args&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;Coffee&lt;/span&gt; coffee &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Americano&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;coffee&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getBrandName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;디폴트 메소드 vs 추상클래스 차이점&lt;br&gt;
— 인터페이스는 private 값을 가지지 못한다.(오직 public, abstract, default, static 상태만 가질 수 있다.)
— 인터페이스는 생성자를 가질 수 없지만 추상클래스는 생성자를 가질 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;참고 - 인터페이스에 대한 설명&lt;br&gt;
&lt;a href=&quot;https://wedul.site/320&quot;&gt;https://wedul.site/320&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://m.blog.naver.com/heartflow89/220969525191&quot;&gt;https://m.blog.naver.com/heartflow89/220969525191&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;4. 입력 매개변수에 따라 매번 다른 클래스의 객체를 반환할 수 있다.&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;하위타입이기만 하면 어떤 클래스의 객체를 반환하든 상관없다.&lt;br&gt;
— EX) EnumSet&lt;br&gt;
— 정적 팩터리 메소드인 noneOf() 에서,&lt;br&gt;
원소가 64개 이하면 long 변수 하나로 관리하는 RegularEnumSet 을 반환하고,&lt;br&gt;
65개 이상이면 long 배열로 관리하는 JumboEnumSet 을 반환
— 클라이언트에서는 이 두 객체의 존재를 모르고, 다음 릴리즈에서 이 내용을 변경할 수 있는 유연성을 가진다.

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/2b4904268c2b2accb90da2f63ccfdb66/68de2/003--01-1.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 677px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 72.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAABJ0AAASdAHeZh94AAABn0lEQVQ4y41TUXaDMAzjOCO2kzihtLC93f9WnpwE2m7d3j6EgRBhycqUhWxNZO8FNZPVWu12u1lBXS5rq5dlaffrdbOU1SgEEyZj5hNEZAHvJxI8gHQOwBwG5l8RsB5C3/wdTjr5hSObqJgk7sj466ipRotYOyBZ2kYaBI8ITuit5+QQyMkmEQQxWRoQ/IzwzRPoJ84OnVAlmGKjarWYkuWopqk0CPFLea/kDg+pyQvsLftCaPXAU1c+CLl3et4/dhgOD+ENR2q+iQ4PT9+67OZj6T4e916d+ElygYcKD7UslrV0/yRb5IgP539JvhPi4lnsHqqlFIGMIRUAQ2LpkPhUmUYORTq4e40OAwhDG0yRN1N+Q5dquaBTDEhjgQJHbah5acPyPVWz1Rb+BapiJ4wI9gVZ21cs4kQkTFoLNi4rTo1bkNsGf+ex8uq2eLxml+phH7acwXbSvbJtILwuO7BZhZ/rbbP949O2bbeCrl2WE8mQ+CqLE7UFtsyexYgMQqqktphxbpucFP/M3iPpdBxub7/jPtXz/PrzH6fjEV+wDar6BnR1hgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;003  01 1&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/2b4904268c2b2accb90da2f63ccfdb66/68de2/003--01-1.png&quot;
        srcset=&quot;/devHistoryBlog/static/2b4904268c2b2accb90da2f63ccfdb66/8ff5a/003--01-1.png 240w,
/devHistoryBlog/static/2b4904268c2b2accb90da2f63ccfdb66/e85cb/003--01-1.png 480w,
/devHistoryBlog/static/2b4904268c2b2accb90da2f63ccfdb66/68de2/003--01-1.png 677w&quot;
        sizes=&quot;(max-width: 677px) 100vw, 677px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/5af9e2a6eff94c8f4abfe68c2a9c3d0e/0ad97/003--01-2.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 717px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 37.083333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAABJ0AAASdAHeZh94AAABAElEQVQoz22RSXLFIAxEfR0DAsRkO5X7X6vTAr6TRRZdjPX0BId3DlECnvvGuL/QBsfrQi8ZrXWU2mZaH6hc19aQYoT3Ht7t2DyEOR7Or41E6KgZXSOqZlzdQBWqBaXUF5y5FhFIDDMxC2IUOIpZDr+BwgqJB2abYuIlJlnyAkjckWXkHa08Au+Haed+DQOTk+AZDaMpHrZ3399sn61fD3LOr2XiPLHInLOgO5fZ7NQMnVvAmjxUTqTAsBVlu1mVMJ2jljrbNYgVsD2hncH8hhn0MF2LcFGiQRnaltrfN5zvSCMtG7j3TOQD/PzFBNoP2cE549d4nv/G/Tl7YR9L5gd+1NdOv215QAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;003  01 2&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/5af9e2a6eff94c8f4abfe68c2a9c3d0e/0ad97/003--01-2.png&quot;
        srcset=&quot;/devHistoryBlog/static/5af9e2a6eff94c8f4abfe68c2a9c3d0e/8ff5a/003--01-2.png 240w,
/devHistoryBlog/static/5af9e2a6eff94c8f4abfe68c2a9c3d0e/e85cb/003--01-2.png 480w,
/devHistoryBlog/static/5af9e2a6eff94c8f4abfe68c2a9c3d0e/0ad97/003--01-2.png 717w&quot;
        sizes=&quot;(max-width: 717px) 100vw, 717px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h4&gt;5. 정적 팩터리 메스드를 작성하는 시점에서는 반환할 객체의 클래스가 존재하지 않아도 된다.&lt;/h4&gt;
&lt;p&gt;— 다시&lt;/p&gt;
&lt;h3&gt;단점&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;정적 팩터리 메서드만 제공하는 클래스는 상속할 수 없다.&lt;br&gt;
상속을 하려면 pubilc 이나 protected 생성자가 필요하기 때문이다.&lt;/li&gt;
&lt;li&gt;정적 팩터리 메서드는 프로그래머가 찾기 어렵다.
생성자처럼 API 설명에 명확히 드러나지 않기 때문에 프로그래머가 직접 정적 팩터리 메서드를 찾아야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;정적 팩터리 매서드 명명 방식&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;from&lt;br&gt;
— 매개변수를 하나 받아서 해당 타입의 인스턴스를 반환하는 형변환 매서드&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt; d &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;instance&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;of&lt;br&gt;
— 여러 매개변수를 받아 적합한 타입으 ㅣ인스턴스를 반환하는 집계 메서드&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Rank&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; faceCards &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;EnumSet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;JACK&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; QUEEN&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; KING&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;valueOf&lt;br&gt;
— from과 of의 더 자세한 버전&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;BigInteger&lt;/span&gt; prime &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;BigInteger&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;valueOf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;MAX_VALUE&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;instance 혹은 getInstance&lt;br&gt;
— 매개변수를 받는다면, 매개변수로 명시한 인스턴스를 반환하지만, 같은 인스턴스임을 보장하지 않음&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;StackWalker&lt;/span&gt; luke &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;StackWalker&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getInstance&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;options&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;create 혹은 newInstance&lt;br&gt;
— instance 혹은 getInstance 와 같지만, 매번 새로운 인스턴스를 생성해 반환함을 보장한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Object&lt;/span&gt; newArray &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;newInstance&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;classObject&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; arrayLen&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;getType&lt;br&gt;
— getInstance와 같으나, 생성할 클래스가 아닌 다른 클래스에 팩터리 매서드를 정의할 때 사용&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;FileStore&lt;/span&gt; fs &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Files&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getFileStore&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;newType&lt;br&gt;
— newInstance와 같으나, 생성할 클래스가 아닌 다른 클래스에 팩터리 매서트를 정의할 때 사용&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;BufferedReader&lt;/span&gt; br &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Files&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;newBufferedReader&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;type&lt;br&gt;
— getType과 newType의 간결한 버전&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Complaint&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; litany &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Collections&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;legacyLitany&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[[책리뷰/Effective Java] 객체 생성과 파괴]]></title><description><![CDATA[아이템2) 생성자에 매개변수가 많다면 빌더를 고려하라]]></description><link>https://ssongey.github.io/history/posts/2020-10-04--003--02</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-10-04--003--02</guid><pubDate>Sun, 04 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;아이템2) 생성자에 매개변수가 많다면 빌더를 고려하라&lt;/h2&gt;
&lt;p&gt;생성자와 static factory method 의 똑같은 단점은 매개변수가 많을 때 적절히 대응하기 어렵다.&lt;br&gt;
생성자나 정적 팩터리가 처리해야 할 매개변수가 많다면 빌더 패턴을 선택하는 게 더 낫다.&lt;br&gt;
매개변수 중 다수가 필수가 아니거나 같은 타입이면 특히 더 그렇다.&lt;br&gt;
빌더는 점층적 생성자보다 클라이언트 코드를 읽고 쓰기가 훨씬 간결하고, 자바빈즈보다 훨씬 안전하다.&lt;/p&gt;
&lt;h4&gt;점층적 생성자 패턴(telescoping constructor pattern)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;매개변수가 많아지면 클라이언트 코드를 장성하거나 읽기 어렵다. &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; 생성자&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;변수&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; 생성자&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;변수&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 변수&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; 생성자&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;변수&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 변수&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 변수&lt;span class=&quot;token number&quot;&gt;3.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;자바빈즈 패턴(JavaBeans pattern)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;setter를 이용&lt;/li&gt;
&lt;li&gt;객체 하나를 생성하기 위해선 여러개의 매서드 호출이 필요&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;객체가 완전히 생성되기 전까지 일관성이 무너진 상태에 놓임&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Coffee&lt;/span&gt; coffee &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Americano&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
coffee&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setPrice&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
coffee&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setCapacity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;빌더 패턴(Builder Pattern)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;필수 매개변수만으로 생성자 또는 정적 팩터리를 호출하여 빌더 객체를 얻음&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;NutritionFacts&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; servingSize&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; servings&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; calories&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; fat&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Builder&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Builder&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;//필수 매개변수&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; servingSize&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; servings&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// 선택적 배개변수 - 기본값으로 초기화&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; calories &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; fat &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Builder&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; servingSize&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; servings&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;servingSize &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; servingSize&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;servings &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; servings&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Builder&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;calories&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; val&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; calories &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; val&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Builder&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; val&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; fat &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; val&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;NutritionFacts&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Nutrition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  
  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;NutritionFacts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Builder&lt;/span&gt; builder&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;servingSize &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; builder&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;servingSize&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;servings &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; builder&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;servings&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;calories &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; builder&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;calories&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fat &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; builder&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fat&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;//사용&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;NutritionFacts&lt;/span&gt; cocaCola &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;NutritionFacts&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Builder&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;240&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;calories&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[[책리뷰/Effective Java] 객체 생성과 파괴]]></title><description><![CDATA[아이템3) private 생성자나 열거 타입으로 싱글턴임을 보증하라]]></description><link>https://ssongey.github.io/history/posts/2020-10-04--003--03</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-10-04--003--03</guid><pubDate>Sun, 04 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;아이템3) private 생성자나 열거 타입으로 싱글턴임을 보증하라&lt;/h2&gt;
&lt;p&gt;싱글턴(Singleton)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;인스턴스를 오직 하나만 생성할 수 있는 클래스&lt;/li&gt;
&lt;li&gt;함수와 같은 무상태(stateless) 객체나 설계상 유일해야 하는 시스템 컴포넌트에 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;싱글턴을 만드는 방법 3가지&lt;/h2&gt;
&lt;h3&gt;1. public static final 필드 방식&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;예외: reflection API 인 AccessibleObject.setAccessible을 사용하여 private 생성자 호출 가능
이를 방어하기 위해 생성자를 수정하여 두번째 객체가 생성되려 할 떄 예외를 던지게 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Elvis&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Elvis&lt;/span&gt; INSTANCE &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Elvis&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Elvis&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;leaveTheBuilding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;2. public static method 방식&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Elvis&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Elvis&lt;/span&gt; INSTANCE&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Elvis&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getInstance&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; INSTANCE&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;leaveTheBuilding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;1,2번의 예외&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;직렬화된 인스턴스를 역직렬화할 때마다 새로운 인스턴스가 생성&lt;br&gt;
— 두번째 객체가 생성될때 예외를 던져도?? 테스트 해보기&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;이를 방지하기 위해 인스턴스 필드에 transient 키워드를 선언하고 readResolve 메서드를 생성한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;transient&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Elvis&lt;/span&gt; INSTANCE&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// 싱글턴임을 보장해주는 메서드, 역직렬화시 호출&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;readResolve&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; INSTANCE &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;참고&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://nesoy.github.io/articles/2018-04/Java-Serialize&quot;&gt;직렬화/역직렬화&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nesoy.github.io/articles/2018-06/Java-transient&quot;&gt;Java transient&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. Enum 방식&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;public 필드 방식과 비슷하지만 더 간결하고 위의 예외에 대한 방어가 다 된다.&lt;/li&gt;
&lt;li&gt;대부분 상황에서 원소가 하나뿐인 열거 타입이 싱글턴을 만드는 가장 좋은 방법이다.&lt;/li&gt;
&lt;li&gt;상속(extends) 이 필요한 경우 이 방법은 사용 할 수 없다. (implements 는 가능)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Elvis&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
   INSTANCE&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
   &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;leaveTheBuilding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[[책리뷰/Effective Java] 객체 생성과 파괴]]></title><description><![CDATA[아이템4) 인스턴스화를 막으려거든 private 생성자를 사용하라]]></description><link>https://ssongey.github.io/history/posts/2020-10-04--003--04</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-10-04--003--04</guid><pubDate>Sun, 04 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;아이템4) 인스턴스화를 막으려거든 private 생성자를 사용하라&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;정적 멤버만을 담은 유틸리티 클래스는 인스턴스로 만들어 쓰려고 설계한 게 아니다.  &lt;/li&gt;
&lt;li&gt;생성자를 명시하지 않으면 컴파일러가 자동으로 기본 생성자를 만들어주며,
사용자는 이 생성자가 자동 생성된 것인지 구분할 수 없다.  &lt;/li&gt;
&lt;li&gt;상속이 불가능한 클래스가 된다.&lt;br&gt;
— 모든 자식 생성자는 상위 클래스의 생성자를 호출하게 되는데, 이를 private로 선언하였기 때문에 호출이 불가능하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Utility&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Utility&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AssertionError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[[책리뷰/Effective Java] 객체 생성과 파괴]]></title><description><![CDATA[아이템5) 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라]]></description><link>https://ssongey.github.io/history/posts/2020-10-04--003--05</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-10-04--003--05</guid><pubDate>Sun, 04 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;아이템5) 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;클래스가 내부적으로 하나 이상의 자원에 의존하고, 그 자원이 클래스 동작에 영향을 준다면 싱글턴과 정적 유틸리티 클래스는 사용하지 않는 것이 좋다.  &lt;/li&gt;
&lt;li&gt;이 자원들을 클래스가 직접 만들게 해서도 안된다. 대신 필요한 자원을 생성자에게 넘겨주자.&lt;/li&gt;
&lt;li&gt;의존 객체 주입 이 기법은 클래스의 유연성, 재사용정, 테스트 용이성을 개선해준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SpellChecker&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Lexicon&lt;/span&gt; dictionary&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SpellChecker&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Lexicon&lt;/span&gt; dictionary&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dictionary &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Objects&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;requiredNonNull&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dictionary&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;isValid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; word&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;suggestions&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; typo&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;생성자에 자원 팩터리를 넘겨주는 방식 (Factory Method Pattern)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;클라이언트가 제공한 팩터리가 생성한 타일들로 구성된 모자이크를 만드는 메서드&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Mosaic&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Supplier&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; extens &lt;span class=&quot;token class-name&quot;&gt;Tile&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; tileFactory&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h5&gt;참고&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://shlee0882.tistory.com/195&quot;&gt;Supplier 예제&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[[책리뷰/Effective Java] 객체 생성과 파괴]]></title><description><![CDATA[아이템7) 다 쓴 객체 참조를 해제하라]]></description><link>https://ssongey.github.io/history/posts/2020-10-04--003--07</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-10-04--003--07</guid><pubDate>Sun, 04 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;아이템7) 다 쓴 객체 참조를 해제하라&lt;/h2&gt;
&lt;p&gt;메모리 누수는 겉으로 잘 드러나지 않아 시스템에 수년간 잠복하는 사례도 있다.&lt;br&gt;
이런 누수는 철저한 코드 리뷰나 힙 프로파일러 같은 디버깅 도구를 동원해야만 발견되기도 한다.&lt;br&gt;
그래서 이런 종류의 문제는 예방법을 익혀두는 것이 매우 중요하다.&lt;/p&gt;
&lt;h4&gt;메모리 누수 발생 코드&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Stack&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Obejct&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; elements&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; size &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; DEFAULT_INITIAL_CAPACITY &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Stack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    elements &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;DEFAULT_INITIAL_CAPACITY&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; 
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  
  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Object&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;ensureCapacity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    elements&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;size&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;pop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;size &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;EmptyStackException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; elements&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;--&lt;/span&gt;size&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  
  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ensureCapacity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;elements&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; size&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      elements &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Arrays&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;copyOf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;elements&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;size&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;해결방법&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Object[]은 Arrays.copyOf()를 통해 길이조절이 되는 상황이다.&lt;br&gt;
pop() 메소드에서 size를 감소시키나, 해당 값은 그대로 두고 있으므로 메모리 누수가 발생하는 것을 볼 수 있다.&lt;br&gt;
이 경우 명시적으로 null 을 할당해줌으로써 참조해제를 통해 GC를 돌릴 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;pop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;size &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;EmptyStackException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;Object&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; elements&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;--&lt;/span&gt;size&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    elements&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;size&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 참조값인데.... result도 null이 아닌가?? 확인 필요&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; result&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;메모리 누수 주범&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;자기 메모리를 직접 관리하는 클래스&lt;/li&gt;
&lt;li&gt;캐시&lt;/li&gt;
&lt;li&gt;리스너 혹은 콜백&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;메모리 누수 예방법&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;원소를 다 사용한 즉시 그 원소가 참조한 객체들을 null 처리 한다.&lt;/li&gt;
&lt;li&gt;WeakHashMap 또는 LinkedHashMap의 removeEldestEntry() 를 사용&lt;/li&gt;
&lt;li&gt;백그라운드 스레드 활용 (ScheduledThreadPoolExecutor)&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;참고&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://blog.breakingthat.com/2018/08/26/java-collection-map-weakhashmap/&quot;&gt;WeakHashMap (약한 참조 해시맵)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://javafactory.tistory.com/735&quot;&gt;LinkedHashMap.removeEldestEntry()&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[[책리뷰/Effective Java] 객체 생성과 파괴]]></title><description><![CDATA[아이템8) finalizer 와 cleaner 사용을 피해라]]></description><link>https://ssongey.github.io/history/posts/2020-10-04--003--08</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-10-04--003--08</guid><pubDate>Sun, 04 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;아이템8) finalizer 와 cleaner 사용을 피해라&lt;/h2&gt;
&lt;p&gt;cleaner(자바 8까지는 finalizer) 는 안전망 역할이나 중요하지 않는 네이티브 자원 회수 용으로만 사용하자.&lt;br&gt;
물론 이런 경우라도 불확실성과 성능 저하에 주의해야 한다.&lt;/p&gt;
&lt;h4&gt;참고&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://jaehun2841.github.io/2019/01/08/effective-java-item8/#%EC%84%9C%EB%A1%A0&quot;&gt;https://jaehun2841.github.io/2019/01/08/effective-java-item8/#%EC%84%9C%EB%A1%A0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://lelecoder.com/21&quot;&gt;https://lelecoder.com/21&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;&lt;/h3&gt;
&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[[책리뷰/Effective Java] 객체 생성과 파괴]]></title><description><![CDATA[아이템9) try-finally 보다는 try-with-resources를 사용하라]]></description><link>https://ssongey.github.io/history/posts/2020-10-04--003--09</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-10-04--003--09</guid><pubDate>Sun, 04 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;아이템9) try-finally 보다는 try-with-resources를 사용하라&lt;/h2&gt;
&lt;p&gt;꼭 회수해야 하는 자원을 다룰 때는 try-finally 말고 try-with-resources 를 사용하면 정확하고 쉽게 회수할 수 있다.&lt;/p&gt;
&lt;h4&gt;try-finally&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;try 안에서 예외가 발생한 후에 finally 안에서 또 다시 예외가 발생 한 경우에는,&lt;br&gt;
두번째 예외가 첫번째 예외를 집어삼키므로 디버깅이 어렵다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;copy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; src&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; dst&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;IOException&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token class-name&quot;&gt;InputStream&lt;/span&gt; in &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token class-name&quot;&gt;OutputStream&lt;/span&gt; out &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    in &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;FileInputStream&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;src&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    out &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;FileOutputStream&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dst&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; buf &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;BUFFER_SIZE&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; n&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;n &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; in&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;buf&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;buf&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; n&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;finally&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;in &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; in&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;out &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;try-with-resources&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;코드가 간결해진다.&lt;/li&gt;
&lt;li&gt;try 안에서 발생된 예외가 기록된다.&lt;/li&gt;
&lt;li&gt;AutoCloseable 을 이용하여 닫아야하는 자원에 대해 정의할 수 있다.&lt;br&gt;
참고 - &lt;a href=&quot;https://multifrontgarden.tistory.com/192&quot;&gt;AutoCloseable 예제&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;copy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; src&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; dst&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;IOException&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;InputStream&lt;/span&gt; in &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;FileInputStream&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;src&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;OutputStream&lt;/span&gt; out &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;FileOutputStream&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dst&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; buf &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;BUFFER_SIZE&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; n&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;n &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; in&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;buf&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;buf&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; n&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;&lt;/h3&gt;</content:encoded></item><item><title><![CDATA[[책리뷰/Effective Java] 객체 생성과 파괴]]></title><description><![CDATA[아이템6) 불필요한 객체 생성을 피해라]]></description><link>https://ssongey.github.io/history/posts/2020-10-04--003--06</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-10-04--003--06</guid><pubDate>Sun, 04 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;아이템6) 불필요한 객체 생성을 피해라&lt;/h2&gt;
&lt;h3&gt;객체 재사용&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; s &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;data&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// bad&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; s &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;data&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// good&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;//bad&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; REGEX &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;isRomanNumeral&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;matches&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;REGEX&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;//caching - good&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; REGEX &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Pattern&lt;/span&gt; ROMAN &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Pattern&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;compile&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;REGEX&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;isRomanNumeral&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; ROMAN&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;matcher&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;matches&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;불필요한 객체를 만들어내는 예&lt;/h3&gt;
&lt;h4&gt;1. Adapter (view)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;실제 작업은 뒷단 객체에 위임하고, 자신은 제2의 인터페이스 역할을 해주는 객체&lt;/li&gt;
&lt;li&gt;Map 인터페이스의 keySet 메서드&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Map&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; serviceSinceMap &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;HashMap&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; 
serviceSinceMap&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Kakao&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2010&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; 
serviceSinceMap&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Naver&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1999&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; 

&lt;span class=&quot;token class-name&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; test1 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; serviceSinceMap&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;keySet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; 
&lt;span class=&quot;token class-name&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; test2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; serviceSinceMap&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;keySet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; 
test1&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;remove&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Kakao&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; 

&lt;span class=&quot;token class-name&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;test1 &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; test2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// true &lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;test1&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 1 &lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;test2&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 1 &lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;serviceSinceMap&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 1&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;2. Auto Boxing&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;프로그래머가 기본 타입과 박싱된 기본 타입을 섞어 쓸 때 자동으로 상호 변환해주는 기술&lt;/li&gt;
&lt;li&gt;박싱된 기본 타입(Long) 보다는 기본 타입(long) 을 사용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Long&lt;/span&gt; sum &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0l&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; 
&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;long&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;MAX_VALUE &lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; 
  sum &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; i&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 불필요한 Long 인스턴스가 2^31개가 만들어짐 &lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[[책리뷰/Effective Java] 객체 생성과 파괴]]></title><link>https://ssongey.github.io/history/posts/2020-10-04--003</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-10-04--003</guid><pubDate>Sun, 04 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/devHistoryBlog/history/posts/2020-10-04--003--01&quot;&gt;아이템1) 생성자 대신 정적 팩터리 메서드를 고려해라&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/devHistoryBlog/history/posts/2020-10-04--003--02&quot;&gt;아이템2) 생성자에 매개변수가 많다면 빌더를 고려하라&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/devHistoryBlog/history/posts/2020-10-04--003--03&quot;&gt;아이템3) private 생성자나 열거 타입으로 싱글턴임을 보증하라&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/devHistoryBlog/history/posts/2020-10-04--003--04&quot;&gt;아이템4) 인스턴스화를 막으려거든 private 생성자를 사용하라&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/devHistoryBlog/history/posts/2020-10-04--003--05&quot;&gt;아이템5) 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/devHistoryBlog/history/posts/2020-10-04--003--06&quot;&gt;아이템6) 불필요한 객체 생성을 피해라&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/devHistoryBlog/history/posts/2020-10-04--003--07&quot;&gt;아이템7) 다 쓴 객체 참조를 해제하라&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/devHistoryBlog/history/posts/2020-10-04--003--08&quot;&gt;아이템8) finalizer 와 cleaner 사용을 피해라&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/devHistoryBlog/history/posts/2020-10-04--003--09&quot;&gt;아이템9) try-finally 보다는 try-with-resources를 사용하라&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[[Design Pattern] Flyweight pattern]]></title><link>https://ssongey.github.io/history/posts/2020-10-04--004</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-10-04--004</guid><pubDate>Sun, 04 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h5&gt;참고&lt;/h5&gt;
&lt;p&gt;&lt;a href=&quot;https://beomseok95.tistory.com/259&quot;&gt;https://beomseok95.tistory.com/259&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://nowonbun.tistory.com/447&quot;&gt;https://nowonbun.tistory.com/447&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[[Java] Date, LocalDateTime 포맷팅]]></title><link>https://ssongey.github.io/works/posts/2020-09-28--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2020-09-28--001</guid><pubDate>Mon, 28 Sep 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;Date &amp;#x26; SimpleDateFormat&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; stringDate &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; 2011-01-18 00:00:00.0&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; 

&lt;span class=&quot;token class-name&quot;&gt;SimpleDateFormat&lt;/span&gt; dateFormatter &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SimpleDateFormat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;yyyyy-mm-dd hh:mm:ss&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; 
&lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt; stringToDate &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; dateFormatter&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;stringDate&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; 

&lt;span class=&quot;token class-name&quot;&gt;SimpleDateFormat&lt;/span&gt; dateFormatter2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SimpleDateFormat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;yyyyy-mm-dd&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; dateToString &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; dateFormatter2&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;stringToDate&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;LocalDateTime &amp;#x26; DateTimeFormatter&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; stringDate &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; 2011-01-18 00:00:00.0&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; 

&lt;span class=&quot;token class-name&quot;&gt;LocalDateTime&lt;/span&gt; stringToDate &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;LocalDateTime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;stringDate&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DateTimeFormatter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ofPattern&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;yyyy-MM-dd HH:mm:ss&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; dateToString &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; stringToDate&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;DateTimeFormatter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ofPattern&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;yyyy-MM-dd&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Unable to find a @SpringBootConfiguration, you need to use @ContextConfiguration or @SpringBootTest(classes=...) with your test]]></title><link>https://ssongey.github.io/errors/posts/2020-09-22--001</link><guid isPermaLink="false">https://ssongey.github.io/errors/posts/2020-09-22--001</guid><pubDate>Tue, 22 Sep 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;문제&lt;/h3&gt;
&lt;p&gt;테스트 코드 실행 시 아래와 같은 오류가 발생하였다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Unable to find a @SpringBootConfiguration, you need to use @ContextConfiguration or @SpringBootTest(classes=...) with your test
java.lang.IllegalStateException: Unable to find a @SpringBootConfiguration, you need to use @ContextConfiguration or @SpringBootTest(classes=...) with your test&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;원인&lt;/h3&gt;
&lt;p&gt;@SpringBootApplication 애노테이션이 붙은 클래스가 존재하는 패키지의 하위 패키지에 테스트를 둬야 한다는 원칙을 어김&lt;/p&gt;
&lt;h3&gt;해결&lt;/h3&gt;
&lt;p&gt;test.java 패키지 바로 아래 있던 테스트 클래스를
ProjectApplication.java 의 패키지 depth 와 동일하게 맞춰서 재실행&lt;/p&gt;
&lt;p&gt;main: com.company.project.ProjectApplication.java&lt;br&gt;
test: com.company.project.TestApplication.java &lt;/p&gt;</content:encoded></item><item><title><![CDATA[[책리뷰] 리펙토링]]></title><link>https://ssongey.github.io/history/posts/2020-09-19--001</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-09-19--001</guid><pubDate>Sat, 19 Sep 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Chapter3. 코드에서 나는 악취&lt;/h1&gt;
&lt;p&gt;리펙토링 기법: 패턴을 찾자.&lt;/p&gt;
&lt;h3&gt;1. 기이한 이름(Mysterious Name)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;코드를 명료하게 표현하는 데 가장 중요하나 요소 하나는 바로 ‘이름’이다.&lt;/li&gt;
&lt;li&gt;그래서 함수, 모듈, 변수, 클래스 등은 그 이름만 보고도 각각이 무슨 일을 하고 어떻게 사용해야 하는지 명확히 알 수 있도록 이름을 지어야 한다.&lt;/li&gt;
&lt;li&gt;마땅히 떠오르지 않는다면 설계에 근본적인 문제가 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. 중복 코드(Duplicated Code)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;중복된 코드는 하나로 통합하자.&lt;br&gt;
— 함수 추출하기, 상속 사용하기 &lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. 긴 함수 (Long Function)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;긴 함수는 이해하기 어렵다.&lt;br&gt;
— 주석을 달아야 할 부분은 무조건 함수로 만든다&lt;/li&gt;
&lt;li&gt;이해하기 쉬운 짧은 함수의 조건은 이름이다.&lt;br&gt;
— 함수 이름을 잘 지으면 본문 코드를 볼 이유가 사라진다.&lt;br&gt;
— 함수의 이름은 동작 방식이 아닌 의도 또는 목적이 드러나게 짓는다.  &lt;/li&gt;
&lt;li&gt;조건문/ 반복문&lt;br&gt;
— 뒷부분에 계속  &lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4. 긴 매개변수 목록(Long Parameter List)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;매개변수 객체 만들기  &lt;/li&gt;
&lt;li&gt;여러 개의 함수가 특정 매개변수들의 값을 공통으로 사용할 때 클래스를 정의하여 공통 값을들 클래스의 필드로 정의 후 사용한다??&lt;br&gt;
&amp;#x3C;&gt;이건 아닌듯 싶다.. 목적이 있는 클래스에 맞는 함수들을 멤버화 시키는게 맞다고 생각한다.&amp;#x3C;/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;5. 전역 데이터(Global Data)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;클래스 변수, 싱글톤&lt;/li&gt;
&lt;li&gt;코드베이스 어디에서든 수정이 가능하기에 버그 발생 요소가 높다.&lt;/li&gt;
&lt;li&gt;변수 캡슐화&lt;br&gt;
— 변수 캡슐화가 의미가 있을까??&lt;br&gt;
전역 데이터는 되도록 상수화를 사용하도록 하며, 가변 데이터일 경우 접근제어를 사용하는게 낫지 않을까 싶다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;6. 가변 데이터(Mutable Data)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;원본 데이터는 그대로 둔 채 변경하려는 값에 해당하는 복사본을 만들어 반환한다. (참조를 값으로 바꾼다)&lt;/li&gt;
&lt;li&gt;데이터에 대한 갱신 로직은 따로 정의를 하는게 좋다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;7/8. 뒤엉킨 변경(Divergent Change) vs 산탄총 수술(Shotgun Surgery)&lt;/h3&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/e8ca51b4a509e920e91b95b019cbb61b/55fc0/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 433px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 32.916666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAABJ0AAASdAHeZh94AAABYUlEQVQoz31Q207CQBTs//+CMUGgJUFfwGBUCMi14oOKCL5Q6AV6J4VCKbcynt2ExERjs5OzO2dm9myFi8sUMlkJVxkJaaqpdJb2DCLuH8p4LNdQJhQKJYhiHlLuGqKUR6F4h1a7i2q1gVqtgVzuBp+DIYTibQn1RhMd+RmNZpv2Laot1AnvvQ+8vvWIa5OxjkrlCeVKjS6qcE6WX9DvDzAcfEHudGFMZxBc18V6vcZ/n+/PoWkGgiCAaVrwfJ84wnz+SyswoaKMoRtTRNEG+/0eO4bdDtvtlp+XyyVUVYdBGlXVYFsOHMdFHMdcE0URNpsYx+MRgqFPeVPTKXg8IXOIYLHAlMafzUw+EauWZcPzfG5iPc/1YFoWH4ZdwjgWLqiajslE5SYWuKCw1WqF0UjhIpOCwjAETidaJz4x4xXqs99l2w6S5MifmyQJhMPhwEWsnsGmOPPnHuN+4i8PC/wGkQf90HaRiVoAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/e8ca51b4a509e920e91b95b019cbb61b/55fc0/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/e8ca51b4a509e920e91b95b019cbb61b/8ff5a/001-01.png 240w,
/devHistoryBlog/static/e8ca51b4a509e920e91b95b019cbb61b/55fc0/001-01.png 433w&quot;
        sizes=&quot;(max-width: 433px) 100vw, 433px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;뒤엉킨 변경 - 함께 변경 할 대상을 한데 모으는 것
— 전략패턴, 방문자 패턴, 켄트 벡의 자기 위임&lt;/li&gt;
&lt;li&gt;산탄총 수술 - JPA wrapper 도입 고민 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;9. 기능 편애(Feature Envy)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;정의된 목적에 해당하는 기능이 수행되도록 함수/클래스를 정의한다.&lt;/li&gt;
&lt;li&gt;기능편애를 거스르는? 이라기보단 좀 더 advanced 예제 : 전략 패턴, 방문자 패턴, 켄트 백의 자기 위임&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;10. 데이터 뭉치(Data Clumps)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;데이터 뭉치는 클래스화&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;11. 기본형 집착(Primitive Obsession)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;전화번호 같은 문자열화된 변수(stringly type)를 객체로 바꾸어 사용하자&lt;/li&gt;
&lt;li&gt;조건부 동작을 제어하는 타입 코드로 쓰였다면 다형성을 적용하자&lt;br&gt;
— 서브 클래스 적용 및 조건부 로직에 다형성 적용?? &lt;strong&gt;글쎄.. 뒤에서 다시 다루자&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;12. 반복되는 switch 문(Repeated Switches)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;반복되고 중복된 조건부 로직에 대해 다형성 도입&lt;br&gt;
— 조건절을 추가할 때마다 수정해야 할 부분이 여러 곳이면 안된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;13. 반복문(Loop)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;반복문을 파이프라인으로 바꾸기&lt;br&gt;
— filter, map 같은 파이프라인 연산을 사용하면 코드에서 각 원소들이 어떻게 처리되는지 쉽게 파알할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;14. 성의 없는 요소(Lazy Element)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;역할이 거의 없는 클래스 또는 함수는 제거하자&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;15. 추측성 일반화(Speculative Generality)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;미래를 대비해 작성한 후킹포인트와 특이 케이스 처리 로직은 불필요하다.&lt;br&gt;
— 후킹포인트: 함수 호출, 메시지, 이벤트 등을 중간에서 바꾸거나 가로채는 명령, 방법 기술이나 행위&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;16. 임시 필드(Temporary Field)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;특정 상황에서만 값이 설정되는 필드들은 따로 클래스화 한다.
— 클래스 목적에 의해 정의된 필드들을 다시 세분화 한다?&lt;br&gt;
필드가 많을 경우 그렇다고 하지만, nullable한 필드를 위한 세분화는 글쎄..
차라리 nullable로 필드를 정의하여 assertion 하는게 낫지 않을까?
해당 부분은 정말 특이 케이스라 생각한다&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;17. 메시지 체인(Message Chains)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;클라이언트가 객체 내비게이션 구조에 종속됐음을 의마한다.
(다른 객체를 요청하는 작업이 연쇄적으로 이어지는 코드)&lt;/li&gt;
&lt;li&gt;최종 결과 객체가 어떻게 쓰이는지 확인 후 체인을 숨기는 방법을 고민하자&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;18. 중개자(Middle Man)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;위임이 지나치면 문제가 된다.&lt;/li&gt;
&lt;li&gt;케이스에 따라 위임 메서드를 제거하여 실제로 일을 하는 객체와 직접 소통하게 하자(중개자 제거)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;19. 내부자 거래(Insider Trading)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;모듈간 결합도를 낮추기 위해 함수 또는 클래스를 세분화 한다. &lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;20. 거대한 클래스(Large Class)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;필드가 많으면 중복 코드가 생기기 쉽다&lt;/li&gt;
&lt;li&gt;상속 또는 서브클래스를 사용하여 분할하자. &lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;21. 서로 다은 인터페이스의 대안 클래스들(Alternative Classes with Different Interface)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;인터페이스 또는 상속을 이용한 설계를 고민하자&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;22. 데이터 클래스(Data Class)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;데이터 필드와 개터/세터 만으로 구성된 클래스&lt;/li&gt;
&lt;li&gt;immutable 한 필드는 세터를 제거하자.&lt;/li&gt;
&lt;li&gt;로직 단위를 쪼개 중간 결과 데이터의 구조(클래스)는 불변이다.&lt;br&gt;
불변 필드는 굳이 캡슐화 할 필요가 없다?? Object 구조 일 경우 값이 변경될 수 있으므로 getter 는 사용하는게 나을거 같다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;23. 상속 포기(Refused Bequest)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;일부 동작을 재활용하기 위한 목적으로 상속을 사용한다. (실무 관점에서 아주 유용하다에 동의)&lt;/li&gt;
&lt;li&gt;인터페이스를 따르지 않는 경우 서브 클래스 생성 또는 ????????&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;24. 주석(Comments)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;주석이 필요한 부분에 함수를 추출하여 이름을 잘짓자.&lt;/li&gt;
&lt;li&gt;선행조건을 명시하고 싶다면 어서션을 추가하자.&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[[HKMC] 작업로그]]></title><link>https://ssongey.github.io/works/posts/2020-09-15--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2020-09-15--001</guid><pubDate>Tue, 15 Sep 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;1. DB Instance 생성&lt;/h2&gt;
&lt;h3&gt;1.1. MYSQL CLI 로 접속&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# mysql -u root -p &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;mysql 명령어를 찾을 수 없다는 오류가 나와서 프로세스 확인 및 mysql client 설치 확인을 하였다&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# ps -ef | grep mysqld (프로세스 정상 동작 확인)
# rpm -qa | grep mysql (mysql 설치 안되어 있음)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;mysql을 rpm 으로 설치를 진행하지 않고 바이너리로 설치 한 듯 싶었다.
mysql 바이너리가 있는 디렉토리에서 직접 수행하였더니 아래와 같은 오류가 발생하였다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;ERROR 2002 (HY000): Can&amp;#39;t connect to local MySQL server through socket &amp;#39;/tmp/mysql.sock&amp;#39; (2)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;mysql.sock 파일 위치 문제로 보였으나,&lt;br&gt;
담당자가 root 계정(OS)으로 접속하여 시도하니 mysql 클라이언트가 정상 동작하였다.&lt;br&gt;
mysql.sock 파일 permission 문제였나? 내일 확인해 봐야겠다.&lt;/p&gt;
&lt;h4&gt;mysql.sock 파일 위치 문제시 해결 방안&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;경로 명시&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;mysql -u root -p mysql -S /var/lib/mysql/mysql.sock&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;soft link&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;ln -sf /tmp/mysql.sock /var/lib/mysql/mysql.sock&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;/usr/local/mysql/bin/mysqld_safe 파일에서 아래 부분을 mysql.sock 파일이 있는 위치에 맞게 수정&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;safe_mysql_unix_port=${mysql_unix_port:-${MYSQL_UNIX_PORT:-/tmp/mysql.sock}}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;1.2. DB 인스턴스 생성&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;mysql&amp;gt; create database DB_NAME default character set utf8 collate utf8_general_ci;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;default character set 부분이 외워지질 않네..&lt;/p&gt;
&lt;h3&gt;1.3. 계정 생성&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;mysql&amp;gt; create user [USER_NAME]@&amp;#39;localhost&amp;#39; identified by &amp;#39;[PASSWORD]&amp;#39;;
mysql&amp;gt; create user [USER_NAME]@&amp;#39;%&amp;#39; identified by &amp;#39;[PASSWORD]&amp;#39;;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;1.4. 권한 확인&lt;/h3&gt;
&lt;p&gt;1.4.1. 권한 확인&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;#접속된 계정 권한 확인
mysql&amp;gt; SHOW GRANTS FOR CURRENT_USER;
# 사용자별 권한 확인
mysql&amp;gt; SHOW GRANTS FOR &amp;#39;사용자계정&amp;#39;@&amp;#39;호스트&amp;#39;;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;1.4.2. 권한 추가&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;mysql&amp;gt; GRANT ALL PRIVILEGES ON [DB_NAME].[TABLE_NAME] TO [ID]@[HOST] IDENTIFIED BY &amp;#39;[PASSWORD]&amp;#39; with grant option;
# 권한 종류
- ALL PRIVILEGES : 모든 권한 추가 
- SELECT, INSERT, UPDATE, DELETE, ... : 권한을 일부분을 추가 
# with grant option 옵션
- with grant option : GRANT를 사용할 수 있는 권한 추가 &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;2. 서비스 기동&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;nohup java -jar -Duser.timezone=Asia/Seoul ${JAR_FILE} --server.port=${PORT} --spring.profiles.active=${SVC_ENV},swagger &amp;gt;&amp;gt; ./logs/server.log &amp;amp;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;옵션이 외워지지 않는다..&lt;br&gt;
이제부턴 실행 스크립트도 같이 전달해야겠다.&lt;/p&gt;
&lt;hr&gt;
&lt;h4&gt;ps. ssh timeout&lt;/h4&gt;
&lt;p&gt;타임 아웃이 걸린 ssh 접속을 오랜만에 했더니 명령어 기억이 나질 않았다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;export TMOUT=0&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[[코드리뷰] Null이 아닌 빈 컬렉션이나 배열을 반환하라]]></title><link>https://ssongey.github.io/history/posts/2020-09-14--001</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-09-14--001</guid><pubDate>Mon, 14 Sep 2020 00:00:00 GMT</pubDate><content:encoded>&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;return result.isEmpty() ? null : new ArrayList&amp;lt;&amp;gt;(result);&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;위와 같이 null을 반환하는 메서드를 작성함에 있어 문제점을 느끼지 못했다.&lt;br&gt;
값이 없으므로 당연히 null로 반환을 하는걸 당연하게 생각했다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# Null 정의
 - 변수에 아무것도 할당되지 않았을 때
 - 정의되지 않음
 - 특별한 값이 없음&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;근데 아니였구나… 잘못 알고 있었구나.. 그랬구나..&lt;/p&gt;
&lt;p&gt;아래와 같이 정리한다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;API에 null을 최대한 쓰지 말자&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# 반환 값이 있어야 한다면 null 대신 예외를 던지자
# 빈 반환값은 빈 컬렉션이나 Null 객체를 사용하자&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;매번 빈 컬렉션 할당하여 반환하지 말고 빈 불변 컬렉션을 반환하도록 하자.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# Collections 상수사용
Collections.emptyList, Collections.emptyMap, ..
# 불변 객체 선언 후 사용
private static final String[] EMPTY_ARRAY = new String[0];&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;선택적 매개변수는 null 대신 다형성(overload)를 사용하자&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;계약에 의한 설계(Design by Contract)를 하자 &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# API 규약을 소비자와 제공자 사이에 지켜야 할 엄격한 계약으로 여기는 설계방법
# 형식적 규약 외에 사전 조건과 사후 조건과 유지 조건을 포함
## 사전조건: 보호절(guard clause)
- 단정문
- Objects 메서드
- IllegalArgumentException
- NullPointException&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;</content:encoded></item><item><title><![CDATA[[Spring] SpringSecurity 에서 req/res에 대한 로깅은?]]></title><description><![CDATA[SpringSecurity 구조]]></description><link>https://ssongey.github.io/works/posts/2020-09-09--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2020-09-09--001</guid><pubDate>Wed, 09 Sep 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;모든 req/res DB 로깅은 interceptor 에서 진행하였고,&lt;br&gt;
로그인/ 로그아웃에 대한 req/res 로깅은 AuthenticationProvider 클래스를 구현한 곳에서 로깅을 하였는데,
로그인 로그아웃에 대한 로깅 위치에 대한 의문을 가지게 되었다.  &lt;/p&gt;
&lt;h3&gt;#. Spring Security 구조&lt;/h3&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/c70bd01ebcabd2d11fd60e720d57ed24/e3189/1.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 73.75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAABJ0AAASdAHeZh94AAACPklEQVQ4y52TDW+aUBSG+f9/ZlljljVr2rS2a5SpdauIE1AEP5AvAUG+9N25d2qwapbsJCdc9HLu+z7nXAH72O12PFkUZQl94UGdOdAqqU4dGEsf2+3u+M3HEA6FqgXzokRL1iH2J/vUeTYkHe/aHOV2eyKimsLZEfRjlm7YAv8TQkn2iqJAludYpznCOIUXxkizHOlmgyCKsXA8LN0VFraHcJ0gpQM3aQaf/gvoPVjHfB9DJbiui16vh6E2wuObgof2b9y3FegzG5s4gjRe4LYh4dPdK76+vkOaOEjWEVRjjs9PHdSeu6i9/MRNvYuJ5Z1a3hKbMAyRk1rGoywLbA9cswxBsEIURbSvpD0Fd+NHyfGZEXvelJisRknKnwvbJfkJkqxgOHkDhqaN7tCA2FPh+GFFABXOUkKW77kTQ+a7rVr4QnZuHtuo1d/w0B2hpZFl4shGRNYtKmjiF3WYqTmEPLEI0ZCjashT4l5AYM3ojl28yHN8+0H8OipEzUVLtZGQ4kvBlLNGOn4Ay4vgBDHcMOFuBMaiOVzgSZrhrq3yrNP6uzw7Flx6AXqKAdVkh2TcYhzH2JHlC2NDjKYeJMODPPUhm2ztYkBPZpnFmG7J7XMb9+I7vCA6UfrvwT6z97fLbO4sy6IpCM5uVvUKCoxFp9NBs9mEKIrQNA227WC5XHJOBymiPIFu+ZUrd+WmsNlT1RH6/QEGAwWKonEltm0fC7ICbMYKwoMryioFdzCMFSnzeJrm6qLla+8f4w+gzntp1UP0DQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;1&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/c70bd01ebcabd2d11fd60e720d57ed24/d9199/1.png&quot;
        srcset=&quot;/devHistoryBlog/static/c70bd01ebcabd2d11fd60e720d57ed24/8ff5a/1.png 240w,
/devHistoryBlog/static/c70bd01ebcabd2d11fd60e720d57ed24/e85cb/1.png 480w,
/devHistoryBlog/static/c70bd01ebcabd2d11fd60e720d57ed24/d9199/1.png 960w,
/devHistoryBlog/static/c70bd01ebcabd2d11fd60e720d57ed24/e3189/1.png 1035w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h3&gt;#. 구현내용&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;AuthenticationProvider 의 구현체에서 authenticate() 메소드를 Override 받아 로그인 확인 로직을 구현하였다.  &lt;/li&gt;
&lt;li&gt;req 데이터에 대한 로깅은 여기서 진행

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/265b4b7d063968a25eb05613d411e5cb/fd8a5/2.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 26.666666666666668%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAt0lEQVQY02WQaw7DIAyDe552QB5AYbv/ubI4rJO6/bCwIviwszVN1iobi5oKWddsImzELlpzKsU4P4xZfC5xppRt3/fQcRwh+E1rt3M8rZ/DWj9N1MG1hQ8YwIDIUrk+Adz9BfsC8fCcAE6r7qE+po35CjgAKaVbkl/IHxCPAWyeEieASL0SV1+BRqrQpzaSI3HO5fbBpuL1qtdTr6S4tERMXr2u5L6Cgj06EPBSaIGJonbMwpO9Aa47nRXYNhQTAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;2&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/265b4b7d063968a25eb05613d411e5cb/d9199/2.png&quot;
        srcset=&quot;/devHistoryBlog/static/265b4b7d063968a25eb05613d411e5cb/8ff5a/2.png 240w,
/devHistoryBlog/static/265b4b7d063968a25eb05613d411e5cb/e85cb/2.png 480w,
/devHistoryBlog/static/265b4b7d063968a25eb05613d411e5cb/d9199/2.png 960w,
/devHistoryBlog/static/265b4b7d063968a25eb05613d411e5cb/07a9c/2.png 1440w,
/devHistoryBlog/static/265b4b7d063968a25eb05613d411e5cb/fd8a5/2.png 1659w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;li&gt;로그인이 성공 할 경우 onAuthenticationSuccess() 를 재정의하여 res 데이터에 대한 로깅을 진행

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/396c68dc449dee647b552aa528a531f8/f69a0/3.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 19.583333333333332%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAl0lEQVQY02WPWQ7DIAxEc52wesGE9v73mjpuG1XNx9MwRjxgG9Kx5nAUz+V5GOZ6wOaBYRPMjE4Einyvv5B3YgG1Auo99jf2wTwWzAbmnC6y6CIaktYaSimotUb+E/Ocr76RCNRfosPALhG1eNnZu99aa8O+70FK6UZ22W/fmDQEouJCAp/piGpIz6TP93L2Qy7IN9K1fgECVnxKRG6QnAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;3&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/396c68dc449dee647b552aa528a531f8/d9199/3.png&quot;
        srcset=&quot;/devHistoryBlog/static/396c68dc449dee647b552aa528a531f8/8ff5a/3.png 240w,
/devHistoryBlog/static/396c68dc449dee647b552aa528a531f8/e85cb/3.png 480w,
/devHistoryBlog/static/396c68dc449dee647b552aa528a531f8/d9199/3.png 960w,
/devHistoryBlog/static/396c68dc449dee647b552aa528a531f8/07a9c/3.png 1440w,
/devHistoryBlog/static/396c68dc449dee647b552aa528a531f8/f69a0/3.png 1783w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;li&gt;로그인이 실패 할 경우 onAuthenticationFailure() 를 재정의하여 exception에 대한 로깅을 진행

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/e176badbed20da8902cfaa58cc296475/fe720/4.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 13.750000000000002%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAiElEQVQI103OWxLDIAgF0GynRhTkoUnb/S/r1thpph9nuPABbF0fUN4RjWBCcMlQqVDzmzRdmhpUdbKVr9meEtKfzSwQETBr8DBEd/QxcL7eGOeB8TxW79G/WoW7w/tYS3POIKLbZi3A81LliioXXplKRi47MqXZM0QamGVmAc9cSplVlt/3lw/JNl6wyRFygQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;4&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/e176badbed20da8902cfaa58cc296475/d9199/4.png&quot;
        srcset=&quot;/devHistoryBlog/static/e176badbed20da8902cfaa58cc296475/8ff5a/4.png 240w,
/devHistoryBlog/static/e176badbed20da8902cfaa58cc296475/e85cb/4.png 480w,
/devHistoryBlog/static/e176badbed20da8902cfaa58cc296475/d9199/4.png 960w,
/devHistoryBlog/static/e176badbed20da8902cfaa58cc296475/07a9c/4.png 1440w,
/devHistoryBlog/static/e176badbed20da8902cfaa58cc296475/fe720/4.png 1448w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;li&gt;AuthenticationException 에 대한 메시지 처리

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/38561763509c2ad2b5a8ace678c60e70/f2d92/5.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 44.99999999999999%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAABYlAAAWJQFJUiTwAAABS0lEQVQoz32RWW7DMAxEc5s4lmXtpCQvcdD7n2lKKUgRp0U/BqIWjB6HFz8rRDshREJMCTEEeO+Rk8XCFhwNKM4gigiJ4LzcB6lFTt699sZaKKVwMVqBggflghgjcjBgb5CZUEoBM4OJQLKGmGCMhdYz9Dxj0lrqp6Zpehq2gv2MHIWqVNSSUYSmNKOYwanKfkUQkmZyu90wXK99Hcfxly7tt+pHLEFjP76wipbCOLLHQqL9wHY8sN0fWEUsnXCucM79UL3r0nCrV1gkp2W7d4NGueaEIhGUvKLWXc42yZGROHfDJLW1rps0spMhWYUsbS/rjiLKnLAKXZFsmWo3Y8oSfuhUw3Bu+d20t7xHhdqmKT/nsvQBMCUkFxE9Icj6DH/+s80T4TRpBKPgje7jf8nKEJxpckIznIL/NDkZzsacHp5+Vu1s/JfoU992XRp2/Db5XAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;5&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/38561763509c2ad2b5a8ace678c60e70/d9199/5.png&quot;
        srcset=&quot;/devHistoryBlog/static/38561763509c2ad2b5a8ace678c60e70/8ff5a/5.png 240w,
/devHistoryBlog/static/38561763509c2ad2b5a8ace678c60e70/e85cb/5.png 480w,
/devHistoryBlog/static/38561763509c2ad2b5a8ace678c60e70/d9199/5.png 960w,
/devHistoryBlog/static/38561763509c2ad2b5a8ace678c60e70/f2d92/5.png 1027w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;#. AuthenticationException&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;UsernameNotFoundException : 계정 없음&lt;/li&gt;
&lt;li&gt;BadCredentialsException : 비밀번호 불일치&lt;/li&gt;
&lt;li&gt;SessionAuthenticationException : Invalid 한 세션&lt;/li&gt;
&lt;li&gt;AccountStatusException&lt;br&gt;
— AccountExpiredException : 계정만료&lt;br&gt;
— CredentialsExpiredException : 비밀번호 만료&lt;br&gt;
— DisabledException : 계정 비활성화&lt;br&gt;
— LockedException : 계정잠기  &lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;참고&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://sjh836.tistory.com/165&quot;&gt;https://sjh836.tistory.com/165&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.spring.io/spring-security/site/docs/3.1.x/apidocs/org/springframework/security/core/AuthenticationException.html&quot;&gt;https://docs.spring.io/spring-security/site/docs/3.1.x/apidocs/org/springframework/security/core/AuthenticationException.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[[Java] Final vs Static]]></title><link>https://ssongey.github.io/history/posts/2020-09-07--001</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-09-07--001</guid><pubDate>Mon, 07 Sep 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;서비스 클래스에서 constant 로 사용하기 위해 아래와 같이 변수를 선언했다&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt; private final List&amp;lt;String&amp;gt; ALPA_LIST = Arrays.asList(&amp;quot;a&amp;quot;, &amp;quot;b&amp;quot;, &amp;quot;c&amp;quot;)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;접근제어자가 private 이고, 하나의 controller 에만 주입되어 사용하고 있어
static 키워드 없이 사용하였는데,&lt;br&gt;
해당 변수에 대한 사용의도(private final이 constant로 적합한가?)에 대해 얘기를 하게 되었고
아래와 같은 의문을 갖게 되었다.&lt;/p&gt;
&lt;h3&gt;1. static vs final&lt;/h3&gt;
&lt;h4&gt;static&lt;/h4&gt;
&lt;p&gt;means there is only &lt;strong&gt;one copy of the variable in memory&lt;/strong&gt; shared by all instances of the class.&lt;/p&gt;
&lt;h4&gt;final&lt;/h4&gt;
&lt;p&gt;The final keyword just means the value &lt;strong&gt;can’t be changed.&lt;/strong&gt; Without final, any object can change the value of the variable.&lt;/p&gt;
&lt;h3&gt;2. private final vs private final static&lt;/h3&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/4bf136393090d1956b59790f132c060e/d52e5/1.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 848px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 67.08333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAABJ0AAASdAHeZh94AAABq0lEQVQ4y4VSi27CMAzs/3/k6PtB0+YJpaXg+ZwG2KRpkU5OHDs5n511XUd9PxBse+yruqGyqqhpWt7XfNdTzbZtuxjXAi3VTUMN24Yt8tZ1pawoCirLUhKKopTLU57T1ylnfxVR1XIG8EGeF1RwDuyJff0wkPeelmWhbLvfad3utAG8v91u8tPO+33fBXfxr3K3bdvL/3g8xD6fzwg+Z9oGUsYTrHGBplmTZgTnaLle5RH55PgISD4wunJMAnyZ40TnvDgulwuFEBjRXq5sX75AnhHjHRljmflOWGCXVjbPM6lpYmZs1URaaxpYE6UUaWPiHWMcFT9ihNWyRHY7l/h7ZTEgsgNAOzFCYmQYWeLux0rafSBzPrB+XAKXbSxgBXjc+SjFp3Y4J+0imTdkbLpRUzPM1E9cqtLUn0cpN7ESLQ/2/0GaorSlMx5i/dphlAehoz2YWmYPoAmvPSr46G5qqDyIxOF8jo1g8dEIJGBQgc8O+2P/F2sZ7KRHGmgMbrTrS7v/sK3voc8wg96HY7aM2JkHW02z/GoPtvDJvY1xqMSKJFZiH8cIfQP9uOZ8hgHE6QAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;1&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/4bf136393090d1956b59790f132c060e/d52e5/1.png&quot;
        srcset=&quot;/devHistoryBlog/static/4bf136393090d1956b59790f132c060e/8ff5a/1.png 240w,
/devHistoryBlog/static/4bf136393090d1956b59790f132c060e/e85cb/1.png 480w,
/devHistoryBlog/static/4bf136393090d1956b59790f132c060e/d52e5/1.png 848w&quot;
        sizes=&quot;(max-width: 848px) 100vw, 848px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;결론은…&lt;br&gt;
constant 로서 사용되는 변수는&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;모든 인스턴스에서 동일한 값을 사용하고,  &lt;/li&gt;
&lt;li&gt;새로 메모리를 잡을 필요가 없고&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;초기화 후에 immutable 한 값이므로
static 키워드를 추가하여 사용한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;private final static List&amp;lt;String&amp;gt; ALPA_LIST = Arrays.asList(&amp;quot;a&amp;quot;, &amp;quot;b&amp;quot;, &amp;quot;c&amp;quot;)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4&gt;[ 200914 추가내용 ]&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Arrays.asList()
# remove(), add()를 지원하지 않음. 사용시 java.lang.UnsupportedOperationException 발생
# ArrayList와 마찬가지로 set(), get(), contains() 제공&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;즉 value가 변할 수 있는 객체이므로, 상수로서 적합하지 않다.
따라서 immutable 하도록 아래와 같이 사용한다.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt; private final static List&amp;lt;String&amp;gt; ALPA_LIST = Collections.unmodifiableList(Arrays.asList(&amp;quot;a&amp;quot;, &amp;quot;b&amp;quot;, &amp;quot;c&amp;quot;))&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Java 9부터는 List &lt;E&gt; .of (E… elements) 정적 팩토리 메서드를 사용&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;@Test(expected = UnsupportedOperationException.class)
public final void givenUsingTheJava9_whenUnmodifiableListIsCreated_thenNotModifiable() {
    final List&amp;lt;String&amp;gt; list = new ArrayList&amp;lt;&amp;gt;(Arrays.asList(&amp;quot;one&amp;quot;, &amp;quot;two&amp;quot;, &amp;quot;three&amp;quot;));
    final List&amp;lt;String&amp;gt; unmodifiableList = List.of(list.toArray(new String[]{}));
    unmodifiableList.add(&amp;quot;four&amp;quot;);&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;참고&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://djkeh.github.io/articles/Why-should-final-member-variables-be-conventionally-static-in-Java-kor/&quot;&gt;https://djkeh.github.io/articles/Why-should-final-member-variables-be-conventionally-static-in-Java-kor/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/questions/1415955/private-final-static-attribute-vs-private-final-attribute&quot;&gt;https://stackoverflow.com/questions/1415955/private-final-static-attribute-vs-private-final-attribute&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/questions/13772827/difference-between-static-and-final&quot;&gt;https://stackoverflow.com/questions/13772827/difference-between-static-and-final&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Jenkins 빌드 후 실행 스크립트 작성]]></title><link>https://ssongey.github.io/works/posts/2020-09-02--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2020-09-02--001</guid><pubDate>Wed, 02 Sep 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;jenkins에서 github hook trigger 발생 후에
빌드 단계에서 실행 되는 스크립트를 작성하였다.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/f538019b6bb183f55b927b2e3f38fd88/36bb5/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 611px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 126.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAZCAYAAAAxFw7TAAAACXBIWXMAABYlAAAWJQFJUiTwAAACKklEQVQ4y51Vi5KiMBD0/39w11PLtRYDJCEQkIcv5qZH4uJdobhWtRNi7PQ8WdR1TUopStOUsiwTG8exWGst7XY7iqKInHO03+/lN+yPLaC1ljOLruuoqipBURT39eFwoKapGQ01bSu2ZfsKCxwsCk9Jkghwq9aGjDFyI5TiGRecTic6Ho9PMRAWlLJkkMFtA9LB5czlchCezIEQVj4f4oD4JVSyy+NDUDabsKpb+qNqVpORY3VBJVTD5TzPBa9cvbt8qBtSthQiECCesGVZUuG9EAPtzMQsWmSxrpgk5+zeAh+CH9ZvuYw/ggyqrLGTN88mxO2r1Yo2mw19fnw+qALO5/N7WcZXzTWGzKJrvC+o9CXD89pLQlDYgXRWHeZoKxVzYaONlBQ4yiiEAmfmqhRCKDEcP2tvHZIN5dN1R7per/8kBUq6SbU3hewWmhtkxmjuDidrXBRC8ZP9QPqs9ZgQBCBF74Y1XFfD5AlDY6xw0mXEUMZRZkWtG7ojAM8u467hAg/qJl1GjcGlQtwrRxPl9F8JzSlwKWw9TBpsvGqtWYSb9Yq2X18PbfdbCCHieCtqL0MBwxTPv4F0inMZbbdbWi6XtF6vZZQhoyD3Q8fMhRCG2YdMI6tp5OlbpZRaLYdwpu97ulwuUujPIIQggZpgURohASB653MnHL/tHj/9D/pHi8smFY5fpYoHRRSnlPDbLk41Rey+SjSvDXeOln3sWe55TKcw1YG/i+GI0uTlayQAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/f538019b6bb183f55b927b2e3f38fd88/36bb5/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/f538019b6bb183f55b927b2e3f38fd88/8ff5a/001-01.png 240w,
/devHistoryBlog/static/f538019b6bb183f55b927b2e3f38fd88/e85cb/001-01.png 480w,
/devHistoryBlog/static/f538019b6bb183f55b927b2e3f38fd88/36bb5/001-01.png 611w&quot;
        sizes=&quot;(max-width: 611px) 100vw, 611px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
     &lt;/p&gt;
&lt;p&gt;한 서버에 dev/ prod 두개의 서비스가 다 올라가야해서 스크립트 실행 시 parameter를 받는 방식으로 진행하였다.&lt;/p&gt;
&lt;p&gt;if문 작성이 왜이리 오래 걸렸는지…
관련 내용을 기록 좀 해두고 써먹어야겠다. &lt;/p&gt;
&lt;h3&gt;작성내용&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;#!/bin/bash

cd frontend
npm install
npm run build
cd ..

gradle build
gradle bootjar
if [ &amp;quot;$1&amp;quot; == &amp;quot;dev&amp;quot; ]; then
        PORT=15000
elif [ &amp;quot;$1&amp;quot; == &amp;quot;prod&amp;quot; ]; then
        PORT=15118
else
        echo bad parameter
        exit 1
fi

PID=`ps -ef | grep V2G | grep ${PORT} | grep -v grep | awk &amp;#39;{print $2}&amp;#39;`
PID_LENGTH=${#PID}
if [ ${PID_LENGTH} -gt 0 ]
then
        kill $PID
fi

BUILD_ID=dontKillMe nohup java -jar -Duser.timezone=Asia/Seoul ./build/libs/AutoCrypt-V2G-0.0.1-SNAPSHOT.jar --server.port=${PORT} --spring.profiles.active=$1,swagger &amp;gt;&amp;gt; ./logs/server.log &amp;amp;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;참고 내용&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;문자열 길이 구하기&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;${#PID}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;변수의 값을 참조할때는 ${변수이름} 처럼 중괄호로 감싸주는 습관을 들이면 좋다.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;if 문 사용법&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;FILENAME=&amp;quot;/home/test/temp&amp;quot;
VALUE=10
if [ ${VALUE} -eq 10 ] ; then
echo &amp;quot;VALUE is 10!&amp;quot;
fi
# 아래 -a (&amp;amp;&amp;amp;) 조건문은 아래와 같이 변경 가능합니다.
# if [ ${VALUE} -gt 5 ] &amp;amp;&amp;amp; [ ${VALUE} -lt 15 ] ; then
if [ ${VALUE} -gt 5 -a ${VALUE} -lt 15 ] ; then
echo &amp;quot;VALUE is greater than 5 and less than 15!&amp;quot;
fi
if [ -e ${FILENAME} ] ; then
echo &amp;quot;${FILENAME} exists&amp;quot;
fi&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;조건문 종류&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;비교식
[ -z ${A} ] : A 문자열의 길이가 0이면 TRUE
[ -n ${A} ] : A 문자열의 길이가 0이 아니면 TRUE
[ ${A} -eq ${B} ] : A와 B값이 같으면 TRUE
[ ${A} -ne ${B} ] : A와 B값이 다르면 TRUE
[ ${A} -gt ${B} ] : A가 B보다 크면 TRUE
[ ${A} -ge ${B} ] : A가 B보다 크거나 같으면 TRUE
[ ${A} -lt ${B} ] : A가 B보다 작으면 TRUE
[ ${A} -le ${B} ] : A가 B보다 작거나 같으면 TRUE
--
[ 조건식A -a 조건식B ] : 조건식 A와 B가 모두 TRUE이면 TRUE (&amp;amp;&amp;amp; 와 동일)
[ 조건식A -o 조건식B ] : 조건식 A가 TRUE거나 조건식B가 TRUE면 TRUE (|| 와 동일)
--
파일관련
[ -d ${A} ] : A 파일이 디렉토리면 TRUE
[ -e ${A} ] : A 파일이(노드, 디렉토리, 소켓 등등 모두) 존재하면 TRUE
[ -L ${A} ] : A 파일이 심볼릭 링크면 TRUE
[ -r ${A} ] : A 파일이 읽기 가능하면 TRUE
[ -s ${A} ] : A 파일의 크기가 0 보다 크면 TRUE
[ -w ${A} ] : A 파일이 쓰기 가능하면 TRUE
[ -x ${A} ] : A 파일이 실행 가능하면 TRUE
[ -c ${A} ] : A 파일이 Special character file 이면 TRUE
[ -f ${A} ] : A 파일이 디렉토리가 아닌 일반 regular 파일이면 TRUE
[ -S ${A} ] : A 파일이 소켓이면 TRUE
[ ${A} -nt ${B} ] : A 파일 B 파일보다 최신파일이면 참
[ ${A} -ot ${B} ]  : A 파일이 B 파일보다 이전파일이면 참
[ ${A} -ef ${B} ] : A 파일과 B 파일이 같은 파일이면 참&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;비교식 옵션 설명&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;-eq : EQual
-ne : NEgative
-gt : Greater Than
-ge : Greater than Equal
-lt : Less Than
-le : Less than Equal
-d : Directory
-e : Exist
-L : symbolic Link
-r : Readable
-w : Writeable
-x : eXecute
-nt : Newer Than
-ot : Older Than
-ef : Equal File&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;참고 사이트&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://louky0714.tistory.com/entry/BASH-Shell-%EB%AC%B8%EC%9E%90%EC%97%B4-%EA%B8%B8%EC%9D%B4-%EA%B5%AC%ED%95%98%EA%B8%B0&quot;&gt;문자열 길이 구하기&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[[StringBoot] Profile에 따른 application.yml 설정하기]]></title><link>https://ssongey.github.io/works/posts/2020-09-02--02</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2020-09-02--02</guid><pubDate>Wed, 02 Sep 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;1. yml 설정&lt;/h3&gt;
&lt;p&gt;수정 전&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;spring:
  active: cron_alert,swagger
  servlet:
    multipart:
      max-file-size: 10MB
      max-request-size: 10MB
  resources:
    static-locations: &amp;quot;classpath:/static/,classpath:/public/&amp;quot;
    add-mappings: true
  datasource:
    driver-class-name: org.mariadb.jdbc.Driver
    url: jdbc:mariadb://127.0.0.1:3306/autocrypt_v2g?autoReconnect=true
    username: root
    password: flatron123!
    hikari:
      idle-timeout: 10000
      max-lifetime: 420000
      connection-timeout: 10000
      validation-timeout: 10000
    dbcp2:
      test-while-idle: true
      validation-query: &amp;quot;SELECT 1&amp;quot;
  jpa:
    open-in-view: false
    generate-ddl: true
    properties:
      hibernate.dialect: org.hibernate.dialect.MySQL5InnoDBDialect
    show-sql: false
    hibernate:
      ddl-auto: update&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;2. 수정 후&lt;/h3&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/e5cb7b1169c920b536c92abd4872aea4/0f2bc/002-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 742px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 95.41666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAATCAIAAAAf7rriAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABnElEQVQ4y5VT0W7cIBD05+RYWGBZwNiHiZ2e2qpR7rH//yddnFNzihLpPBphG2vQMjs7vBJeA14c/uFctH5SSsOjGH5P5bqcf5Xy1taF4wkOYJjmqS61zCWVkqfJGKNOJ7Xj9gBQ34lHDzXAHEx0WkjkXWDPkTilEHLgYJAA0BjdYTr/i52BLmNKOygEEoEwpgunNcRKfCEu3E+UfU8BEaEXBANbfQ66MqSc8ziJUs7vxyqFCizc+KWLQ4yxtVZrfV/NR1Gg7vj1ned5XgXPz21ZiAgOuW2s1WIxohghBh8TZ1RRK3tS9kg8buK/C11Hv5G/xByNAd3reBDDtrSf28tLaz9av7bzHj/BfothYleTK4zOGu9Q+rR7q2F/6Z89a59x6zMhZAeZfYlhSpRilAGJwjJvuaypVApnH5oniYjfQ+I8icFd7A0kB4VMjClw2su2aHq1Ge1osK/WFbTeOttp5Zc4s4ckuDanOvI0yYQ0orCn62Mw7td7dHEpRfxa100wjuP77qOt4phi6rlmZjjaZ0Ylg/W0z/BR8T9UVtFlkK2tQgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/e5cb7b1169c920b536c92abd4872aea4/0f2bc/002-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/e5cb7b1169c920b536c92abd4872aea4/8ff5a/002-01.png 240w,
/devHistoryBlog/static/e5cb7b1169c920b536c92abd4872aea4/e85cb/002-01.png 480w,
/devHistoryBlog/static/e5cb7b1169c920b536c92abd4872aea4/0f2bc/002-01.png 742w&quot;
        sizes=&quot;(max-width: 742px) 100vw, 742px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;profiles 구분자 ---&lt;br&gt;
--- 를 이용하면 profiles 을 구분할 수 있다.
맨 위에 작성된 내용이 default 가 된다.&lt;/li&gt;
&lt;li&gt;profile 활성화

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/7748e61489faef5b94ea36fb8857aeb0/53ac9/002-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 2.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAABCAYAAADeko4lAAAACXBIWXMAABJ0AAASdAHeZh94AAAAR0lEQVQI1x3LUQrAMAgD0J1ng0Gps1pdHfT+Z8psv0IeyVHpBrcCfwXaH4hSJkG4IM4Lmn3ZnAPx2d6uj2jdbt4wooPSzBk/GY4g5c2iJ0IAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/7748e61489faef5b94ea36fb8857aeb0/d9199/002-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/7748e61489faef5b94ea36fb8857aeb0/8ff5a/002-02.png 240w,
/devHistoryBlog/static/7748e61489faef5b94ea36fb8857aeb0/e85cb/002-02.png 480w,
/devHistoryBlog/static/7748e61489faef5b94ea36fb8857aeb0/d9199/002-02.png 960w,
/devHistoryBlog/static/7748e61489faef5b94ea36fb8857aeb0/53ac9/002-02.png 1287w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/2820cb800de168c8d21f0b356bb0efad/9e3ea/002-03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 24.583333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAIAAADKYVtkAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAyElEQVQY011OW3LDIBDjKk0ajAFjAyY8zMskvf+VqtY/nc5oNFq0Ektm/sklXRSTkjJ2ByZ2+wc234WkcpmwdgEa78TYxe6re252V0I86PTxF7/hH+biceWvCjBc4oNFOKbdByPkJARV66xWpla+bpzNN5wGrY3UWuAnYyQACxWk1JCLf391MGbndc6+tXSeebzqkf3T61LCq6VRIwDRSwhxRxGBnUvAXqlx0yImV1sco7R+nKOeo6C0nwcWoGuNvad0OFzqgv0GT8c5wgz3Zz4AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002 03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/2820cb800de168c8d21f0b356bb0efad/d9199/002-03.png&quot;
        srcset=&quot;/devHistoryBlog/static/2820cb800de168c8d21f0b356bb0efad/8ff5a/002-03.png 240w,
/devHistoryBlog/static/2820cb800de168c8d21f0b356bb0efad/e85cb/002-03.png 480w,
/devHistoryBlog/static/2820cb800de168c8d21f0b356bb0efad/d9199/002-03.png 960w,
/devHistoryBlog/static/2820cb800de168c8d21f0b356bb0efad/07a9c/002-03.png 1440w,
/devHistoryBlog/static/2820cb800de168c8d21f0b356bb0efad/9e3ea/002-03.png 1503w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[[Node] gyp verb check python checking for Python executable "python" in the PATH]]></title><description><![CDATA[[Node] Node.js 종속성을 위해 Windows에서 Python 실행하기]]></description><link>https://ssongey.github.io/errors/2020-08-29-001</link><guid isPermaLink="false">https://ssongey.github.io/errors/2020-08-29-001</guid><pubDate>Sat, 29 Aug 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;문제&lt;/h2&gt;
&lt;p&gt;gatsby node_modules 설치 도중 문제 발생&lt;/p&gt;
&lt;h2&gt;원인&lt;/h2&gt;
&lt;p&gt;phthon 2.7 미설치 또는 PYTHON 환경변수 없음&lt;/p&gt;
&lt;h2&gt;해결&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;python 미 설치시&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;(관리자 권한으로 실행)
npm install --global --production windows-build-tools&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;설치 경로
C:\Users\ben.windows-build-tools\python27\python.exe
참고 - 지원되지 않으므로 3.x가 아닌 python 2.7을 사용  &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://stackoverflow.com/questions/39739626/what-is-node-gyp&quot;&gt;node-gyp&lt;/a&gt; 설치  &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;npm install --global node-gyp&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;일단 설치되면 모든 노드 - gyp 종속성이 다운로드되지만 여전히 환경 변수가 필요합니다.
유효성 검사 Python은 실제로 올바른 폴더에 있습니다.&lt;/p&gt;
&lt;p&gt;환경변수 세팅&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;setx PYTHON &amp;quot;%USERPROFILE%\.windows-build-tools\python27\python.exe&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;cmd를 재시작하고  후 PYTHON 변수 존재 여부 확인&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;set PYTHON&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;마지막으로 node module 재설치&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;npm install &amp;lt;module&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;참고&lt;br&gt;
&lt;a href=&quot;https://code.i-harness.com/ko-kr/q/e6ce22&quot;&gt;https://code.i-harness.com/ko-kr/q/e6ce22&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[[JPA] No EntityManager with actual transaction available for current thread]]></title><link>https://ssongey.github.io/errors/2020-08-31--001</link><guid isPermaLink="false">https://ssongey.github.io/errors/2020-08-31--001</guid><pubDate>Sat, 29 Aug 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;문제&lt;/h3&gt;
&lt;p&gt;deleteBy.. 메소드 호출시 오류 발생&lt;/p&gt;
&lt;h3&gt;원인&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://stackoverflow.com/questions/32269192/spring-no-entitymanager-with-actual-transaction-available-for-current-thread&quot;&gt;https://stackoverflow.com/questions/32269192/spring-no-entitymanager-with-actual-transaction-available-for-current-thread&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;해결&lt;/h3&gt;
&lt;p&gt;메소드에 @transaction 을 추가하는 방법으로 해결하였다.&lt;br&gt;
잘 모르겠는데… JPA delete transaction 을 찾아봐야겠다.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[[TLS] Cipher Suite]]></title><link>https://ssongey.github.io/history/posts/2020-05-21--001</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-05-21--001</guid><pubDate>Thu, 21 May 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;Cipher Suite&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;TLS에서는 암호화하는 방법을 표준으로 특정하지 않고, server와 client가 합의해서 결정한다. &lt;/li&gt;
&lt;li&gt;서로 합의해야 하는 알고리즘은 4가지이다.&lt;br&gt;
— 대칭키 전달 방식,&lt;br&gt;
— 인증서 서명 방식,&lt;br&gt;
— 대칭키 알고리즘,&lt;br&gt;
— HMAC 알고리즘&lt;/li&gt;
&lt;li&gt;TLS에서는 서버와 클라이언트가 이 4가지 알고리즘을 세트로 합의하고, 합의된 알고리즘으로 application layer의 내용을 암호화해서 전송한다.&lt;/li&gt;
&lt;li&gt;cipher suite는 TLS&lt;em&gt;ECDHE&lt;/em&gt;RSA&lt;em&gt;WITH&lt;/em&gt;AES&lt;em&gt;256&lt;/em&gt;GCM_SHA384와 같이 표기한다. 이 cipher suite를 읽어보면, 다음과 같이 해석할 수 있다.&lt;br&gt;
— 대칭키 전달 방식은 ECDHE(Elliptic Curve Diffie Hellman Ephermeral)을 사용하며,&lt;br&gt;
— 인증서 서명 방식은 RSA로 서명된 인증서로 상호간의 신원을 확인하고,&lt;br&gt;
— 대칭키 암호화 알고리즘은 AES 256bit와 GCM를 채택하고,&lt;br&gt;
— HMAC 알고리즘으로는 SHA 384를 사용해서 메시지의 무결성을 확인한다.&lt;/li&gt;
&lt;li&gt;cipher suite는 여러가지 있다. 그중에서 client가 지원하면서 취약하지 않은 cipher suite의 리스트를 서버에게 알려주면, 서버는 그중에 지원하는 cipher suite를 선택해서 보내 합의한다.&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[[작업로그] vue 빌드 사이즈 줄이기]]></title><link>https://ssongey.github.io/works/posts/2020-05-08--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2020-05-08--001</guid><pubDate>Fri, 08 May 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h4&gt;how to enable GZIP compression in stringboot&lt;/h4&gt;
&lt;p&gt;&lt;a href=&quot;https://frontbackend.com/spring/how-to-enable-gzip-compression-in-spring-boot&quot;&gt;https://frontbackend.com/spring/how-to-enable-gzip-compression-in-spring-boot&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;how to compress static files in vue&lt;/h4&gt;
&lt;p&gt;&lt;a href=&quot;https://medium.com/@aetherus.zhou/vue-cli-3-performance-optimization-55316dcd491c&quot;&gt;https://medium.com/@aetherus.zhou/vue-cli-3-performance-optimization-55316dcd491c&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;vue js bundle 줄이기&lt;/h4&gt;
&lt;p&gt;&lt;a href=&quot;https://ui.toast.com/weekly-pick/ko_20190603/&quot;&gt;https://ui.toast.com/weekly-pick/ko_20190603/&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[[PKI] 인증서 파일 형식 및 확장자]]></title><link>https://ssongey.github.io/history/posts/2020-05-03--001</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-05-03--001</guid><pubDate>Sun, 03 May 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;1. 인코딩 (확장자로 쓰이기도 한다.)&lt;/h3&gt;
&lt;h4&gt;# der&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Distinguished Encoding Representation (DER)&lt;/li&gt;
&lt;li&gt;바이너리 DER 형식으로 인코딩된 인증서. 텍스트 편집기에서 열었는데 읽어들일 수 없다면 이 인코딩일 확률이 높다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;# pem&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;X.509 v3 파일의 한 형태&lt;/li&gt;
&lt;li&gt;PEM (Privacy Enhanced Mail)은 Base64인코딩된 ASCII text file이다.&lt;/li&gt;
&lt;li&gt;원래는 secure email에 사용되는 인코딩 포멧이었는데 더이상 email쪽에서는 잘 쓰이지 않고 인증서 또는 키값을 저장하는데 많이 사용된다.&lt;/li&gt;
&lt;li&gt;-----BEGIN XXX-----, -----END XXX----- 로 묶여있는 text file을 보면 이 형식으로 인코딩 되어있다고 생각하면 된다. (담고있는 내용이 무엇인지에 따라 XXX 위치에 CERTIFICATE, RSA PRIVATE KEY 등의 키워드가 들어있다)&lt;/li&gt;
&lt;li&gt;인증서(Certificate = public key), 비밀키(private key), 인증서 발급 요청을 위해 생성하는 CSR (certificate signing request) 등을 저장하는데 사용된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. 확장자&lt;/h3&gt;
&lt;h4&gt;# crt, cer&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;인증서를 나타내는 확장자인 cer과 crt는 거의 동일하다고 생각하면 된다. &lt;/li&gt;
&lt;li&gt;cer은 Microsoft 제품군에서 많이 사용되고, crt는 unix, linux 계열에서 많이 사용된다.&lt;/li&gt;
&lt;li&gt;확장자인 cer이나 crt만 가지고는 파일을 열어보기 전에 인코딩이 어떻게되어있는지 판단하긴 힘들다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;# key&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;개인 또는 공개 PKCS#8 키를 의미&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;# p12&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;PKCS#12 형식으로 하나 또는 그이상의 certificate(public)과 그에 대응하는 private key를 포함하고 있는 key store 파일이며 패스워드로 암호화 되어있다. &lt;/li&gt;
&lt;li&gt;열어서 내용을 확인하려면 패스워드가 필요하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;# pfx&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;PKCS#12는 Microsoft의 PFX파일을 계승하여 만들어진 포멧이라 pfx와 p12를 구분없이 동일하게 사용하기도 한다.&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[[PKI] 인증서 유효성 검사]]></title><link>https://ssongey.github.io/history/posts/2020-04-26--001</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-04-26--001</guid><pubDate>Sun, 26 Apr 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/9ece20b4c4d24cb8560d1d0bb7abd312/aaf7f/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 31.666666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAsUlEQVQY042QUQuEIBCE+/9/L4p66KUyyyAq0aKiOWbBOLoOWhjc1fVz3Mh7jzRNkSQJyrJEnueSK6VgjAHjPE/Rm4jYuG0bmqZBVVXQWou4R92BIf/3SBSapmkS0DAMGMfxargDnoDfYAHSCUF0WNc11nXF27i7vBwS6pyDtRacK10uyyIrxzHPM/Z9R9u2oq7rpH50yIMww6Io5OtxHEvNy1mWoe97eSDMmPVxHD/AD4wh0ZFz8smAAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/9ece20b4c4d24cb8560d1d0bb7abd312/d9199/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/9ece20b4c4d24cb8560d1d0bb7abd312/8ff5a/001-01.png 240w,
/devHistoryBlog/static/9ece20b4c4d24cb8560d1d0bb7abd312/e85cb/001-01.png 480w,
/devHistoryBlog/static/9ece20b4c4d24cb8560d1d0bb7abd312/d9199/001-01.png 960w,
/devHistoryBlog/static/9ece20b4c4d24cb8560d1d0bb7abd312/07a9c/001-01.png 1440w,
/devHistoryBlog/static/9ece20b4c4d24cb8560d1d0bb7abd312/aaf7f/001-01.png 1668w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/cc8ecf73d154eb4a882941d8303f9fea/aaf7f/001-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 65.83333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAAAsTAAALEwEAmpwYAAABW0lEQVQ4y41S266CMBDk/z/QFzXcC9Jyk7uIc5hNemK0GiHLtqWd7sysZ4zB4XDA6XTCtm349Xk8Hs51b11XaK2RJAkul4uMeUlZllBKoaoqWc/zXNY5vt/vH0E9fpZlEUAeImAcxyiKAufzWebH41HAuI9hgZyAdrHrOolhGGC0we12gzZa5qzyVY6PlO3Pvu/lIEGC2Mf12krFaZpK9VEUiQRhGMo+e86Gnf9XSF1IZ5omRDqEmhKYUWOeZ1Bn/rfafTPJe0Z/pvF8O+kTjMD20nEcJfNCZ4U0IQgCaR9SJFWaQV05pzk0Kcsy2Us5OGZ2AlJ0gtDNuq7FaQtEAMa3Pn2jzM2kZWkwM4ZxEKfZl6T7KsebKXZAaiyfDpam3F2NBSRNUrRtKw43TePU29mHFN73fSTZTrPSyAoFlSss6/JT/731oeT9bbYK/dbtucYuApZtdlL7BPwHM7HygYDv9IoAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/cc8ecf73d154eb4a882941d8303f9fea/d9199/001-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/cc8ecf73d154eb4a882941d8303f9fea/8ff5a/001-02.png 240w,
/devHistoryBlog/static/cc8ecf73d154eb4a882941d8303f9fea/e85cb/001-02.png 480w,
/devHistoryBlog/static/cc8ecf73d154eb4a882941d8303f9fea/d9199/001-02.png 960w,
/devHistoryBlog/static/cc8ecf73d154eb4a882941d8303f9fea/07a9c/001-02.png 1440w,
/devHistoryBlog/static/cc8ecf73d154eb4a882941d8303f9fea/aaf7f/001-02.png 1668w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/a1f0a1e1eff0ec4aebc5327e602e2eb3/cc155/001-03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 886px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 44.166666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAIAAAC9o5sfAAAACXBIWXMAABYlAAAWJQFJUiTwAAABUElEQVQoz02Ry0+DQBCH+f+P3jwbkyYmetCDRw8mnkwkSrWER8Kb8ugupUChgF/ZQ7uHyc7OfPObmdXmeZZSCiHyPI+iyHVdy7KwhmHouu553nE5TdPI5RwOB9ztdstdA3Ych6Qsy4D95QRBQLgsyzRNkyThJQxDLlVVDcPQtm0cx9y10+lU1zUlpmkax7HrOgJYklBQTdm2DQxDFVogEyVKX+CiKEglAwaeLqhFBgBT0BpR0zSJksyM8Frf9wD45CFCIbBze31f7HZpnge+v16viYLBIKZg5tKUlIJhcNVsQRx7rivCqOm6psV0lN5sNoiRjCzdabwqnxibxIVsjsfKtLPVk3O3qj6/hnlmBWhiGVgpo3GBr885/vYh/eD916gfX8Y/a3md1F4VzEec21YwsuonpZBivxf6T/n8Gt0/iJvb3bfBMtg7TRHHsl3gf9Oe93PcqrskAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/a1f0a1e1eff0ec4aebc5327e602e2eb3/cc155/001-03.png&quot;
        srcset=&quot;/devHistoryBlog/static/a1f0a1e1eff0ec4aebc5327e602e2eb3/8ff5a/001-03.png 240w,
/devHistoryBlog/static/a1f0a1e1eff0ec4aebc5327e602e2eb3/e85cb/001-03.png 480w,
/devHistoryBlog/static/a1f0a1e1eff0ec4aebc5327e602e2eb3/cc155/001-03.png 886w&quot;
        sizes=&quot;(max-width: 886px) 100vw, 886px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/fe2b0842a97221382e164b9c1ad3731a/3c051/001-04.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 760px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 121.66666666666669%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAYCAIAAAB1KUohAAAACXBIWXMAABYlAAAWJQFJUiTwAAADQElEQVQ4y1WUe5eaMBDF+f6fqv1nt3ZbFVHAB/JSYEUgKvJQdu0viWfbzjliCJmZe+/MxGiaK1YUxWazjqKo7/u2bZumud1uj8fjU9lDGfvn8/l0OnFG7xhlWUZhmCSp53n7/Z7X4/G42+0C37cs63A45Hl+VlbXNYluff/x8fF0JjBJpOduD4SLsu12O7esMAxBFMfxer0i0Gw2W6/XhGbz6ayxbTYbDgEMf54+3p6XpmlVVVmW4biYL8zpdD6fk7/tWs3F0DE46jouH0ABJXISixOsSWUpWywWy+WSsL7vD8PwFzapJuNxGAYc5RXyq9UKnqAAJG7j8di27fyQV2Wpc0jn+/0eBgiWAA9tyrK49TcAv739giFfkRc305xaM2symYCfiFpwCZsVJ8gZRzHVgjYig9NxnDRJieg6znQ6JbqoRKkyd133dIbASQjUXigTQpRF6bouboTDRzvPTFOIU9d3RMcZvk+1cQA5BcfSJCE25dnFcacM/sgZBAEArzW+8ke1DS06nrbjoGMpRNN1xLKltu7lfOYQZEzThCqBGlXOa13fh0E6Q4Nsez8QeT7U9VCJtq6z96fVlwvP19cXKpIo05zR0gA0InmrVfT2u452bZK2m+21KEGxoqqeR8OhJYLPlYSObWvCErZEFceUfp+mddPUbXNqmkoIenvpulSRaqMZgk0nEzrsmOfEOrwfimMhBaMH4QO8/HBAJJ6Pf4zowx2Cg/r/z2STUHqUJD9P3ZhAPZ/kJLFgPHulOX1LY+kO6alY2xl80xXXBcfhKyfEeEVOUVWykFFE26K0nmqiGK0yjqIhW2mW6YRlUXAn0CcUlfZmIL9//8ZU0nzQZOCvzdX4alRmBSUYbBZJmvhb//Pjk6OohRAeQ7ve8BVStKOeVqNTziCELZkZhjAIaBKScG8clRGaVD9eXtlkZMGoC27As7k2SEq14K9vEuDMrTmxWINc3y1Mlb2wszTlK4jes0zWmUggBBVJGPelGglzaiIk/qzRiakYjUY/RyMGGxRgphGk81k1MMT2ux2EYcfprSeB6IGlQhzQXYXp20aqrZukEtwQCFyclMkdWSFGUFBwdlBB7ZW6cvo+/QPFBDBPYUHPigAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 04&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/fe2b0842a97221382e164b9c1ad3731a/3c051/001-04.png&quot;
        srcset=&quot;/devHistoryBlog/static/fe2b0842a97221382e164b9c1ad3731a/8ff5a/001-04.png 240w,
/devHistoryBlog/static/fe2b0842a97221382e164b9c1ad3731a/e85cb/001-04.png 480w,
/devHistoryBlog/static/fe2b0842a97221382e164b9c1ad3731a/3c051/001-04.png 760w&quot;
        sizes=&quot;(max-width: 760px) 100vw, 760px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/aa4925298449fecc0b7cd426f2a0db13/aaf7f/001-05.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 27.083333333333332%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAt0lEQVQY021QiwqEMAzz/39Rxano1DHf+J45Uphw5xU6bZamWYOmaRCGIaIoQp7nGIYBWZah6zpUVYUkSVDXtdQej+MYSin0fQ/Gfd/wEczzDGst2rYVwr7vUo/jKEmcnOM4cF0XzvOUdM5J/RLkQXJZljDGiNiyLI8bOuG3KIqvRh+/WECAE6dpkqQYB2zb9rikcz6b/1prGcp7L/hyuK4ruEu6TNNUHFGUjX4dXoh7JZc9/xx+AK4rgJr/BhCZAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 05&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/aa4925298449fecc0b7cd426f2a0db13/d9199/001-05.png&quot;
        srcset=&quot;/devHistoryBlog/static/aa4925298449fecc0b7cd426f2a0db13/8ff5a/001-05.png 240w,
/devHistoryBlog/static/aa4925298449fecc0b7cd426f2a0db13/e85cb/001-05.png 480w,
/devHistoryBlog/static/aa4925298449fecc0b7cd426f2a0db13/d9199/001-05.png 960w,
/devHistoryBlog/static/aa4925298449fecc0b7cd426f2a0db13/07a9c/001-05.png 1440w,
/devHistoryBlog/static/aa4925298449fecc0b7cd426f2a0db13/aaf7f/001-05.png 1668w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    
&lt;img src=&quot;./001-06.png&quot;&gt;

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/7e03bdedad72e9942d1854c2c2efab4e/aaf7f/001-07.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 55.00000000000001%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABYlAAAWJQFJUiTwAAACW0lEQVQozy2S6ZKaUBSEff+HSVKTZKKOiIACbsgqqyAXELfRMS/QaTE/TkHdgu92n+6eyEIkWwebhY6VqcHQJJgzGdbKQODbyPMdRh8jvP/8DmezRlOX2KwXSCIfosgQbz2cWoG/jyu8tYxevU94aGOhK4SNockDzFQJS3MK21ogiyKMpTEG728IPBuXU4vlXEcYOKj2O16yxKHe4/F1QeSb6LVih8hZY64SNvmATuiaah2exYGH0gshjSQsDI0QF3HoE1B2c2wrtI3o3j+vLRqRonescoSaBqs/wHI64SiwliZ8d4MkCVEK0SmcExiFHuIowPnUoD0I7LK4m1rsO/jjfkLvQOB2YcAaDWENh1jJY6yo0HOt18dVhclEwUyTkXJvZZ5C7DNCChRZgnyXQJQFTgcCPwnc7yKqWXFfBlx7zoUzDHeNiqs4nxtczido2hTyRx8bfYrItpC4DhLHRup7DNRHnkQ41gKPK4EpbZi06tvLLpz3t29c+pQzoz0f99snVFWDOvwDS1OQ+C4ElRVxhPw54RZFGOJQlrhdCHRZgakygqlPWJcJQn9DWzFURaLliOndMaVCZTyk+nm3x4znghDhBqho92n52DYv4JzqVKnPH/pQWZmA9guuYULAoSk7oD7TocgfHTDcusgY1n6XoiyyLpCawKYqcb+c0VsZKhyGIA1+YfD7R2c9DGxClK4SX7cbDN1kN+Wuc1ka8sJXGM/pgkljiDzD7USFM3ZvyZ9Xuoon3F6ZtO1gSkBBFdfzGaYxx3ymdh2sKyba1pzm//M1d9p9XK/4B4o5/ntUeRr1AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 07&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/7e03bdedad72e9942d1854c2c2efab4e/d9199/001-07.png&quot;
        srcset=&quot;/devHistoryBlog/static/7e03bdedad72e9942d1854c2c2efab4e/8ff5a/001-07.png 240w,
/devHistoryBlog/static/7e03bdedad72e9942d1854c2c2efab4e/e85cb/001-07.png 480w,
/devHistoryBlog/static/7e03bdedad72e9942d1854c2c2efab4e/d9199/001-07.png 960w,
/devHistoryBlog/static/7e03bdedad72e9942d1854c2c2efab4e/07a9c/001-07.png 1440w,
/devHistoryBlog/static/7e03bdedad72e9942d1854c2c2efab4e/aaf7f/001-07.png 1668w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;(계속)&lt;/p&gt;</content:encoded></item><item><title><![CDATA[[작업로그] 인증서 생성 요청 Flow]]></title><link>https://ssongey.github.io/works/posts/2020-04-13--002</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2020-04-13--002</guid><pubDate>Mon, 13 Apr 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/dfe18bba00117b6ca2026dca4580b24b/aaf7f/002-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 97.91666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAAsTAAALEwEAmpwYAAAC2ElEQVQ4y51ViY6bMBTk/3+uq2pVZdXdbE6OAOY+DLan8ww0e7WV6ujJxjyPh/E8J2iaBkopxHGMMAxhrYVzDv9qTvLWeNsCWSwxjqOPtwumaYKZZ7+J9DNDtpqTGCa8wlzOmA+vsFXpw3F9UJYlrtcrbrcb8jzH8XRCwbnz+YwT42W/x/fHR+yenrDb7fDt4QHJ5QIUBabDAS67wVwvMPxCN/QIhJWAVlWFfhjQ1DXGvvcyFNwgY2J8PCKlHHmW+U0lB2ZCfkzRRDmgR4INcMYg+CROXcGpHI79HEVwBJA5CMiHptsR4T7HOMyfNfQh2lE3SwBLUJskcF23vJMDED35RT5HdGtbxAeF8CflCvls7J3hdrJOa9gsXUQX8RlzFC4bFGrpy8Jrhr5Fdi0R7TMMZHsHXBn6oZyksFh1waTRZRV03fF4J7+hMAT1klwzWw+2rX+n4Z/8J7MqaZAcFfKoRq16z6rg3O2kkF1KpOfiCw232My9MV83KpLaL0wOOYp4Gauo8vPy6cI2+Gs1bDKs/aRnTOMMPUx+8dhPDO2fJbyGNe0gnhN/ZfTZVoaaWv1PCwo6XsDE3BtgQrtI2UmzIj4l8OUn468kehOBACiCRjRxyWqZeHJSeieWV5JmeGWVRCzLM59/sPTGlblbpXAf5AkERJFZRlYNwS0XDLyBOs7Ztoar6Dl6T+wjFeQNHUfeNh8td7cNk315STLNy1qiaTsMWYk+JSB1NiPFL9j3A+a2h9HL4Sws76D+cpBrqR94fa26bfvp0aDMOtarQpV2UHGDis913rNvUdKHzrrfZhVgr+H+sMfzyzMuci3JQTi7BJbL0/DHmljesV85cez8/MSfzyVoMKDH1ZygXAaNEdpqqDlHZUoUs8LkZtRjjqh65hd0aEyN1rQY5x5pe0bRhlBdiG5abqNAmBhHDtZ4VovO978Bt1AGKMm7617e08jQ09K7JfcXa0oTQQhZJKcAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/dfe18bba00117b6ca2026dca4580b24b/d9199/002-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/dfe18bba00117b6ca2026dca4580b24b/8ff5a/002-01.png 240w,
/devHistoryBlog/static/dfe18bba00117b6ca2026dca4580b24b/e85cb/002-01.png 480w,
/devHistoryBlog/static/dfe18bba00117b6ca2026dca4580b24b/d9199/002-01.png 960w,
/devHistoryBlog/static/dfe18bba00117b6ca2026dca4580b24b/07a9c/002-01.png 1440w,
/devHistoryBlog/static/dfe18bba00117b6ca2026dca4580b24b/aaf7f/002-01.png 1668w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/803a44831de81b81f789891538b2f680/aaf7f/002-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 96.66666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAATCAYAAACQjC21AAAACXBIWXMAAAsTAAALEwEAmpwYAAACQUlEQVQ4y5VUi47iMAzs///aCSFxYnl36RXoA0rftJTSOY9PKbAce1yQlbgk9njGiXW5XJDnOfb7PYIgAP0oiuC6rs5hGMJxHF2v12vdczqd1N/tdlgsFqjrGhxd18Fq21Y3FEWBNE1xvV51Ph6PupHJqqpC0zS65l7uoU87n8/q9wG54MfxeKxIDocDZrMZfN/HarVShJPJRBN8NxiMwzIOgzZinFm2+c4KyrJUFPRfWY+QGzWYwOfBVnyWRWRxHOt/X1G8QqcIGZCHWR4tE/58IX4+n2MrpDO4OWTMoOV8z1/PIUclAlQSaDMaoRRkhaB1RFUqSzGMylSffFLE5XKJzWaDLMtuJStcsboW/mRT+Wmjspc4OWtUaYJaSk6SRBJWGogdEISBUnGP9jGgDGbMBIkrGXmIpRINv9u2JCkqQcwuiBCFEbq2e+LxISB7LZFS2S5sWLYPkbEkoph4YxR1gTg9Yup+4FfoCN857JWt4v2JiltAKsw/GGy73eqNIHe+7+EsdMyCKXbZFtP9GAP3Bz4OP5FUMZz0E8k5RtomYvGtD98ZV7T9usVFf3JfBJhw2cnt6ZobQnPdPM9TRakgkfI7UQ8GA/iejzAIldt9eOjLxB2eR1FEftMGfCxIAcUhv0ySF3m/r7k0T/35IArbgI8BjYfMmlePgXviX9yQJ4SmZDYvy6avSORKck37iuhvQS38x3hHPIsvC5HQWCrbh/1nmvv+5XknqEXu2MRUkuqZHhzJnR4Oh5rgvtR/jd9u2L+6o7kPeAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;002 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/803a44831de81b81f789891538b2f680/d9199/002-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/803a44831de81b81f789891538b2f680/8ff5a/002-02.png 240w,
/devHistoryBlog/static/803a44831de81b81f789891538b2f680/e85cb/002-02.png 480w,
/devHistoryBlog/static/803a44831de81b81f789891538b2f680/d9199/002-02.png 960w,
/devHistoryBlog/static/803a44831de81b81f789891538b2f680/07a9c/002-02.png 1440w,
/devHistoryBlog/static/803a44831de81b81f789891538b2f680/aaf7f/002-02.png 1668w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;</content:encoded></item><item><title><![CDATA[[작업로그] 서명 생성/검증]]></title><link>https://ssongey.github.io/works/posts/2020-04-13--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2020-04-13--001</guid><pubDate>Mon, 13 Apr 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;#1. 서명 생성&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;[param]  &lt;/li&gt;
&lt;li&gt;algo: &lt;/li&gt;
&lt;li&gt;privKey:  the private key of the identity whose signature is going to be generated.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;[code]&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Signature&lt;/span&gt; signer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Signature&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getInstance&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;algo&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;BC&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
signer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;initSign&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;privKey&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
signer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;plainText&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; signer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sign&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;#2. 서명 검증&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;[param] &lt;/li&gt;
&lt;li&gt;algo : the name of the algorithm requested.&lt;/li&gt;
&lt;li&gt;pubKey: the public key of the identity whose signature is going to be verified.&lt;/li&gt;
&lt;li&gt;plainText&lt;/li&gt;
&lt;li&gt;signed: the signature bytes to be verified.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;[code]&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Signature&lt;/span&gt; signer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Signature&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getInstance&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;algo&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;BC&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
signer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;initVerify&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pubKey&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
signer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;plainText&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; signer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;verify&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;signed&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[[PKI] 공개키 인증서 형식]]></title><link>https://ssongey.github.io/history/posts/2020-04-13--003</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-04-13--003</guid><pubDate>Mon, 13 Apr 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/e53ac6b659328f36ac971d618bff4d0e/aaf7f/003-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 122.91666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAZCAYAAAAxFw7TAAAACXBIWXMAAAsTAAALEwEAmpwYAAADOElEQVQ4y5VVy3LaQBDk/8+5pnLMP+TqpFyVQ+IEKL+weQgQDyGEnghpt9O9IGIMcTlbNbXalba3Z3pm1Hp4eMRkMsV0OsXT0xO0ztIQ/c4HePefAFgYa2EPpvHyudd7ws8fN+h0utjtdmjN53OE0RabOCPohDZDWaaY9j7C733GHgH/HMtFAJ9nVkEIYwxaRZEimn1Bloy5AazXayRJgjgpUfNAXucozdZZZSvsbEnbufWWliNzxh13QStNYiTLLwjmXQRBhMFggDAM4XkjghG43iCqQqxpJcFkhSmQ1DGKukBeZZxz7MxuD9hQz/IS4WrlGCqeWZbif4fi2toH15LVigxXDszzPPi+j6raIY5jsu5jPB5TsAfMZjNst1sUReH2bm9vMRgO3NoxbNTabDYudnd3d1Suh263i8VyCZ+iXX39hna7g+/X1/BGI/fu/v7ezUEQuHNS+ASwoSyljiNNYBcL8AQQLEEpAbJeEuTx8RH9fh+vz7de59VxrZlu1HS9ns9QM6WqJcHzDNE6dMLJqqo6njkyfGli6EzPjFXNQw6QZqI1zAWxXpJpvUO6s7x+TeKEoYIpJSWKUsbzxgelxxiNPKyjaH+ArI8ATUjseQkdASeTCdNjyJrsOGu32/j167dTvInTJRfPAJuHiEzUHFQpAlc6uFpl6giwLEukaYq6rt8EdYASQe5qSDklrwAVBiX5iLmnRFcSK+feBbhQvnEo+6+urnDNJH5+fnb7Dat3u6wPxETuCVBuC0ziKIHFPs9zF+u3FD5hqL4ogQQosJubG6zYLJqYan84HL6ZgycMdUDxEVOBqAFoPSJIU68yxbWJ8UuBjnnYMJR7rnyppM/nmnslGUuQHtXXrGaxomhzxtUBHurenrcvuODrI6kckUVAVQMCFIwd9rfura4Ocw3LVDoaPTqp5bPBmrUzH5b5WbPTuJrmhUZrfwrDiyw9sOUWNstg1Jn0T7lYn7zdbAsY/h5q/goMVTYENWRs2IiNaxhzmHgDs4n4LoDVBTzXuqSYA2Wbcp6yZTkQdhoxU9fRQcdO86HGHcOmH14ELcQwIYuYLDZ0iyGgYHJP7/5a7i5vYvgH8TeLw613DB0AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;003 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/e53ac6b659328f36ac971d618bff4d0e/d9199/003-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/e53ac6b659328f36ac971d618bff4d0e/8ff5a/003-01.png 240w,
/devHistoryBlog/static/e53ac6b659328f36ac971d618bff4d0e/e85cb/003-01.png 480w,
/devHistoryBlog/static/e53ac6b659328f36ac971d618bff4d0e/d9199/003-01.png 960w,
/devHistoryBlog/static/e53ac6b659328f36ac971d618bff4d0e/07a9c/003-01.png 1440w,
/devHistoryBlog/static/e53ac6b659328f36ac971d618bff4d0e/aaf7f/003-01.png 1668w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/da2790f3d5b4466ac62ca3a5533397bb/aaf7f/003-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 95.41666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAATCAYAAACQjC21AAAACXBIWXMAAAsTAAALEwEAmpwYAAACUElEQVQ4y4VUi46bMBDk/z+uaqW0V+Wk6EIgvAnBvMGe7vhiRF4qyCws9uzOeMC7Xq84HA6IoghpmiIIAszzjHeHMeYuBkGI3e63xWDOW5YFdV3jcrmgqioopcAibduiLEs0TYMsy5EkCaZpWsEcIIszz2gBeen73oLFcWwjuy3KwnZM0K+vIz4+/qLrupddbg+PF621XZylGdJEQIpy7ZSVKcM7yq5bNzz3oms7XJVQ7hWKqkClLijrEnrR6LvexkfQV4cnuOuE3nQolxydadGYWobCqAcMpscgsdMdZjM/6fhE2b1Y5Owhi+QkCAsMkqmWC3oBU7qWN7Ix5p7qtsCqITdE1QqNapHLrg7dgLZpcQ7PVo5pnJBECeIofmulb8q3B1qH1gjDEPv93m4Sd/V0OoltMrsxtBbvGYuisLk8z++6vKM8DIO1EL3nPEc/fnsxwziOtgifmWcTnL/F8LboXMCJjLQNF1ptxfwswIIctBPB2B275f3aoQOkjpzATmhmZ2rmSXu321k5jsejzbMw55I6iz9Rfuct5glCvc7ns43cQBbffvMr5VdG3T7z3n1ypEY5GN1X9PjVrJQ5kfpwEmnynpHaUUMOpyF1u95+JI+gnqNLzaiV7/sWhPQSoRZJJGVaKr9ZxtmlEC1Z4CWgs0gplT/l3+bLBvj0nnTxZ/+JHz9/YbhZ6b/GtoMvhPYinYxZiiGOMEkHkwCPwQlTnmEpcixhILGwcT75MO8ou6QWwY0ssEPo6SSGThMYWkj+kVqKadkQrWo7zHhP+R8CTcO1O2VZ9AAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;003 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/da2790f3d5b4466ac62ca3a5533397bb/d9199/003-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/da2790f3d5b4466ac62ca3a5533397bb/8ff5a/003-02.png 240w,
/devHistoryBlog/static/da2790f3d5b4466ac62ca3a5533397bb/e85cb/003-02.png 480w,
/devHistoryBlog/static/da2790f3d5b4466ac62ca3a5533397bb/d9199/003-02.png 960w,
/devHistoryBlog/static/da2790f3d5b4466ac62ca3a5533397bb/07a9c/003-02.png 1440w,
/devHistoryBlog/static/da2790f3d5b4466ac62ca3a5533397bb/aaf7f/003-02.png 1668w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/5b083ac0584774c8090103885eaf459a/720e3/003-03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 122.49999999999999%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAZCAIAAAC+dZmEAAAACXBIWXMAAAsTAAALEwEAmpwYAAADc0lEQVQ4y1WUCY+iQBCF+f+/aTeZzWY2c6hcghxyyCkjAh7gNep+3SSbbEVJ21ZVv3rvNcphv++6brfbsbhcLtfr9fv7+3bjc+v7Y9NsN8SXiGq9rjcbkklYr8uXnz+U5/N5v99JqGs+dVkUZVlGURTHcRAs12QVRRxHaZpmaZokK/FdrWj1+9eLKD6fz8FyGS5l+H4cRfxfFEUUhXmekxqGQVHkBet4Jf5NViSo009RDOYoDLfbLZBACIqmafb7/W6/Pw3DRQ4yBrOwzb/gsQxdFDMJqV3bchqDUc/kJxnD0B+Px8MBQvY8WQ/DwL+7rtOmU1HMeLZlMVjbNFVVrcuy73v2bzLGsrZtR17pyCbr2eRDFEPp3DTzPKNfLYPzYSrLs1Uch2EIVUBlLjAgAYfTUZ1OlMfjwTlghkvLookBMQAxDcO2LU0VsVjY4KIp1IKcfCDoqiqKh74HGMW6rpEnu1jzuel57mw6ZeX7HoNfLueRCFrAhDEW0wwYCOg6DmKBE8EI27Yd1/E8L0mSLAN7imzgAj8zGJosPp1P19uVKalHJ1D4nohlsHRdR9M0ei2AZFmjnELRzWaOVI/7XdLQr5LEc10OAIVOhaYyMJjV2Qwm6OU6Lm5j2ouMuWkoeJOjGBucqjpDc9qTjdecxQIIpmlqumYYBj77qio+gvbj0TZNBdGQl37kQSyzIamh6xAGf67rvr+9AePP6yv1H+/vnx883tDVsS1ZLA2ApP7Sx8OsuRhhEMCQtEwprlRVSaVr1lSysK25stt1rJgTwmAVe+Qy4OL5XzzG+PfDd12laVu6Apvr4jgOOsm7W/HAtgzM/JPJJ/s4H8LYgXnuL/kK3hfWq+txWgIP4IQveb0QFhQgZ58deOIyYgeQ5mmqcMhsNsWVQRBgUhqRhwPLssDDSEIevLDgtnEr6YguSJtnmQJmaIRVRJ7LoAvikQQAGgGeVBpBCi14ksnPMs8V7IYT+M0keNORwTwkQQQvDVpzJZAA3gXaPHecBU3FySBhQow+jkpLvuPtp3i8Q+NrQDzF4jAGXkeqHc2Aik55UWBjXkmwCp9cacADQYjctuLV2bbkA4RnWeZiZgAQIMfAWAU+OQ4UV0Y8n8f3MYh4g4EMXIBF6q5rFXblIWuQoO+oFr2ZcDwWUljDAoKCCM5pRzFz/QXdnFGW+C3XNgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;003 03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/5b083ac0584774c8090103885eaf459a/d9199/003-03.png&quot;
        srcset=&quot;/devHistoryBlog/static/5b083ac0584774c8090103885eaf459a/8ff5a/003-03.png 240w,
/devHistoryBlog/static/5b083ac0584774c8090103885eaf459a/e85cb/003-03.png 480w,
/devHistoryBlog/static/5b083ac0584774c8090103885eaf459a/d9199/003-03.png 960w,
/devHistoryBlog/static/5b083ac0584774c8090103885eaf459a/07a9c/003-03.png 1440w,
/devHistoryBlog/static/5b083ac0584774c8090103885eaf459a/29114/003-03.png 1920w,
/devHistoryBlog/static/5b083ac0584774c8090103885eaf459a/720e3/003-03.png 1962w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;</content:encoded></item><item><title><![CDATA[[PKI] CSR(Certificate Singing Request)]]></title><link>https://ssongey.github.io/history/posts/2020-04-13--004</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-04-13--004</guid><pubDate>Mon, 13 Apr 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/3d192c833d63bf37f9b0dc817f604b3f/aaf7f/004-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAAAsTAAALEwEAmpwYAAABsUlEQVQ4y4VUXW+jMBDk99//6UtOre6lqtQ+9XTVKa3U3EkQwInt8hnANlPvpiBIaLLSapfgHc/OLgmUUoiiCFprxHEMKSXHJEk4l9EN/v/5gTR8wC66hU5uQeac5Ui1q9VPPD//5uegrmvI/R7b7Rbr9ZoPCCE4D8MI65c7D3aPphaoixhNFXJh3/ccm6ZBnucgHOccAnxZ23aepUJRFPySgOlwlh/gesxsABviYEQkMKaDCH9Bib8erPKsQr6RWiYZjpWOiwc/BZ16QFp0jUaabj3Llll1XTe2cYnREutgSITYMaMkTbhtok9xyuI70Om7EZBaLMsSSqoR6HjqunZTGwEJTGcam/gdsYz5N9t7OfoWrWv8YNyiZqfaBqc3WhjUqKCNQmY/kNsMhfV6uuois7OWx1v6Y147v59mj9IWKF2JD6twcMchEdupUyezoZyBeiNGlQcidhQJTHtQyncmxd4I7kAaP0wrGXQGODhte+83eXqz+9rDwU6fZy1fFuW8YAq0OBRaZPozIKc9fH19w+Pj02ypl2RZAmOGxhjeuyzL2Debf/wdW2uv7tySfQKuAJMmSnrB2QAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;004 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/3d192c833d63bf37f9b0dc817f604b3f/d9199/004-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/3d192c833d63bf37f9b0dc817f604b3f/8ff5a/004-01.png 240w,
/devHistoryBlog/static/3d192c833d63bf37f9b0dc817f604b3f/e85cb/004-01.png 480w,
/devHistoryBlog/static/3d192c833d63bf37f9b0dc817f604b3f/d9199/004-01.png 960w,
/devHistoryBlog/static/3d192c833d63bf37f9b0dc817f604b3f/07a9c/004-01.png 1440w,
/devHistoryBlog/static/3d192c833d63bf37f9b0dc817f604b3f/aaf7f/004-01.png 1668w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;</content:encoded></item><item><title><![CDATA[[작업로그] Crontab 설정]]></title><link>https://ssongey.github.io/works/posts/2020-02-03--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2020-02-03--001</guid><pubDate>Mon, 03 Feb 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;작업내역&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;수정 (편집기 열기)&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;$ crontab -e&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;수정내용&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;shell 이 설정되어 있지 않을 경우, bash로 생성한 스크립트는 오류가 발생할 수 있다.

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/34200430d7f519e4e73407a667c9d1f4/1b747/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 679px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 28.750000000000004%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAwUlEQVQY06WQxwqEQBBEB4wYDoYxoijm9P+fV1INetnDwu7h0U3PUF3VahxH9H2PIAhg2zYsy4JS6neu68I0TaiqCl3XIc/z/wQfhxRj37YtkiRBURTSR1GELMtQ1zXSNP0u6HkeXNd947JnfBKGIfjO6vu+9KZpCoZhCB+CjEtHJI5jzPOM4zhwnqewLAu2bcMwDJJg33fwTOu6yoyLueAV5GY6cxxH3DEm79k0DcqylKiMr7WWyjn/EJ6CUOMRvAG7f4tI0NayxQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/34200430d7f519e4e73407a667c9d1f4/1b747/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/34200430d7f519e4e73407a667c9d1f4/8ff5a/001-01.png 240w,
/devHistoryBlog/static/34200430d7f519e4e73407a667c9d1f4/e85cb/001-01.png 480w,
/devHistoryBlog/static/34200430d7f519e4e73407a667c9d1f4/1b747/001-01.png 679w&quot;
        sizes=&quot;(max-width: 679px) 100vw, 679px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;저장 및 종료&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cmd&quot;&gt;&lt;pre class=&quot;language-cmd&quot;&gt;&lt;code class=&quot;language-cmd&quot;&gt;^o // 저장 (control + o) 
^x // 종료 (control + x)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;참고&lt;/h4&gt;
&lt;p&gt;&lt;a href=&quot;https://zetawiki.com/wiki/%EB%A6%AC%EB%88%85%EC%8A%A4_%EB%B0%98%EB%B3%B5_%EC%98%88%EC%95%BD%EC%9E%91%EC%97%85_cron,_crond,_crontab&quot;&gt;https://zetawiki.com/wiki/%EB%A6%AC%EB%88%85%EC%8A%A4_%EB%B0%98%EB%B3%B5_%EC%98%88%EC%95%BD%EC%9E%91%EC%97%85_cron,_crond,_crontab&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[[작업로그] CertInstallationRes 구현]]></title><link>https://ssongey.github.io/works/posts/2020-01-27--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2020-01-27--001</guid><pubDate>Mon, 27 Jan 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/d46ebc8e71b6f7be29feff08dfc1e6e4/efeb1/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 68.75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAABYlAAAWJQFJUiTwAAACMUlEQVQ4y3VT6W7aYBDk/V+gP/oAVdUmoUcKDsE2ZzhbNVXTqK2UJq4Bn/jENhCm+y1gDtEfI2O0Ozs7sy4s0z4WSY8hfidxE2Egwfcv4U6LsJwzGNZHzGc9rOYDxnO2QSowpL5B3l/YJxQFcSgT0TmTudML2M4FHLeM+aZBEO0EDGhQnzDAlueQkIojr4Ff9+fQHyUqGnLxIukjClrQ/pTw49sZtMcyDavSIKH+FTyvuCNcK+uzumXWx9Sp4ff9e9gTGVHYxNi8wsiQEPpNOIaCp4dPGOtXSGcdsuUDtPELRhSqvD4rnEVtWrVNU1VMpzVkSRdYCHVd8vQGSXSTW+IHddiuTN7KLGSR1KlfptrO2kNRaFjX0CdlKlSYYE6EW5MxH2JFVojn6EnC7ZfX+HlX5KGeV8NCBJMNdyuHQQOuq/JaM1K5ynaJpXGHVQd+g+GYMnRNgmuq/L9lVeFaKrK4c+jhliQldduzEAUZrSEGCkuEn3HUQjLbbJD2mLhWfYnvX99Q33CTMiXIzTTFo0A8pw6fsFXJYdEzcBswxhVof0tsz8SqwLEVjOgaJnolP6d1ypTuLGhDeyhRwu8wGVUoHJU8qq9XdRT27+72LQz9mmuFQnGbWH7mAA8OW6RoU2qjsYTIb7F3pl2FRRBKDLPCCh1TQTBt5M3HX1muUKwdhy06VIXNDoMm3djaO5GkOJ/9z+4U0XZAYf/lmT+l7kHBfvM+jolywuOGUyT/az6Ff2bCAxu4o5xRAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/d46ebc8e71b6f7be29feff08dfc1e6e4/d9199/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/d46ebc8e71b6f7be29feff08dfc1e6e4/8ff5a/001-01.png 240w,
/devHistoryBlog/static/d46ebc8e71b6f7be29feff08dfc1e6e4/e85cb/001-01.png 480w,
/devHistoryBlog/static/d46ebc8e71b6f7be29feff08dfc1e6e4/d9199/001-01.png 960w,
/devHistoryBlog/static/d46ebc8e71b6f7be29feff08dfc1e6e4/07a9c/001-01.png 1440w,
/devHistoryBlog/static/d46ebc8e71b6f7be29feff08dfc1e6e4/efeb1/001-01.png 1593w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h3&gt;[ Error &amp;#x26; Solv ]&lt;/h3&gt;
&lt;h4&gt;#1. signature marshalling error&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;에러 메시지&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;[com.sun.istack.internal.SAXException2:
     @XmlRootElement 주석이 누락되어 &amp;quot;com.autocrypt.v2g.common.message.type.SignatureType&amp;quot; 유형을 요소로 마셜링할 수 없습니다.]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;원인&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;// 작업 시 , SignatureType에 @XmlRootElement 누락
val signatureByteArray = MsgDigest.generateXMLToByteArray(signature, SignatureType::class.java)?: return null&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;해결&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;// SignatureType에 anotation 추가
@XmlRootElement(name = &amp;quot;Signature&amp;quot;, namespace = &amp;quot;http://www.w3.org/2000/09/xmldsig#&amp;quot;)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;#2. grammarMsgDef로 EXI Encoding 후 Decoding 시 메시지가 짤려서 나오는 현상&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;원인&lt;br&gt;
certChain의 namespace 잘못됨&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;해결&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;msgBody에서 MsgDataTypes 로 변경&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[[PKI] 용어정리]]></title><link>https://ssongey.github.io/history/posts/2020-01-27--001</link><guid isPermaLink="false">https://ssongey.github.io/history/posts/2020-01-27--001</guid><pubDate>Mon, 27 Jan 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h4&gt;발행자 UID (akID)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;발급자의 공개키의 해쉬값&lt;/li&gt;
&lt;li&gt;issure DN이 동일할 수 있음&lt;/li&gt;
&lt;li&gt;동일한경우 발행자 UID 를 확인하여 발급자를 찾는다&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;대상자 UID (skID)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;내 공캐키의 해쉬값&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;self sign 인증서의 경우 (RootCA)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;subjectDN == issureDN&lt;/li&gt;
&lt;li&gt;발행자 UID == 대상자 UID&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[[Linux] DRBD 작업 내역]]></title><description><![CDATA[DRBD 사용하여 DB 이중화 작업]]></description><link>https://ssongey.github.io/works/posts/2019-12-17--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2019-12-17--001</guid><pubDate>Tue, 17 Dec 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;DRBD 사용하여 DB 이중화 작업 내역&lt;/h1&gt;
&lt;h3&gt;DRBD&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Distribute Replication Block Device&lt;/li&gt;
&lt;li&gt;블럭 디바이스를 HA(High Availabilty, 고가용성) 구성을 위한 Network Raid-1(mirroring) 유틸&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;환경&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Ubuntu 18.04&lt;/li&gt;
&lt;li&gt;MariaDB 10.1&lt;/li&gt;
&lt;li&gt;DRBD 8.9&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;장치준비&lt;/h3&gt;
&lt;h4&gt;구성&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;하드웨어 hotlink 연결

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/638759bbf82c8fcd8f177af19a229fd6/1628f/hotlink.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 49.16666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABJ0AAASdAHeZh94AAACl0lEQVQozxWS7U7TUACGdwMmfkTUqHxtlq0bWzu2rnRtWdut3diGMGQIm4IMnYgQmDJRVESjiUZNNMZEIz/0Aky8AK/t8fjjzTk/zvuZE3p2+IJyU6B9hOvNsbi8Qnu1w9buHr3+E/pPnrO5tcHWdpdH+7t0N9bIT6bJqAnkhIKWc7HsCm4xICgHhHZ2HmD4G7jzO4yNZYmPqwIpMpqBpudR1AkymQymNSkMC4JUwi0YJOMSkStJTGcV3WyJdyZqOkvo5cEDFubKdG8t4Dk2sWiEmDzGpcEhRkZHGTh/gTMD57hw8RInTp7i9NkBHu50MHUV15mhvf6ZWvOIMUknGpMJ/fj4iO8fHvPpaYsvBw3e92q82S5zdD/g4I5Hv+Oxu+Jwv11gvWkyW1L49naDP78Oubk4w9Vpj4pviVYykhQm9PRgk/29LmutCq2GIC0WBblE/1bAy7tV3m3P8Hlvnq/71zg+XOL4xTK9m0W+vrrN398f+Pmuy9uHNXqdIoeb9f+CYuz+HVqtGmlVwisouFYKLS0RvnwWVR7GTEeZysTwjXFK+STlKZV2w6XTrtOeK7Cy6HNvtc7rxx1Cvd4NmtdKAj6Ok8U0ZApmnAl1lKHBMxTsFL6rErgKjhnF0CKUHJW5uoWtx8gqYdRUmGRimPaySLi6UsH3czhTCrWqTXXaol6zsc0U1YrNdNkQiRMsNUsEjsJsNU810CkIY0uTRJNR0qkR8Y3CoqUQDPwMnjuBIdz0nKhmK0zqcRRFwi8azM64rK81aF0XxmKOfPYKmjKMpUviHmEy8z/dEJYRZ37eI5QXNUx7HF2LYuUTQlgWW8aIJ2RSyQhFT2eh4VMSZ9HNCWhilhRGLibSRQTCJORBimKGskj+Dx+OcGnoIK4QAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;hotlink&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/638759bbf82c8fcd8f177af19a229fd6/d9199/hotlink.png&quot;
        srcset=&quot;/devHistoryBlog/static/638759bbf82c8fcd8f177af19a229fd6/8ff5a/hotlink.png 240w,
/devHistoryBlog/static/638759bbf82c8fcd8f177af19a229fd6/e85cb/hotlink.png 480w,
/devHistoryBlog/static/638759bbf82c8fcd8f177af19a229fd6/d9199/hotlink.png 960w,
/devHistoryBlog/static/638759bbf82c8fcd8f177af19a229fd6/1628f/hotlink.png 1232w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/li&gt;
&lt;li&gt;
&lt;p&gt;두 서버간 파티션 및 drbd 연결 도식화&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;┌─────────────────────────┐    ┌────────────────────┐        
│  /opt/autocrypt/data2   │    │/opt/autocrypt/data1│        
┌───────────────────────────┐  ┌──────────────────────┐        
│                           │  │         ext4         │        
│            ext4           │──└──────────────────────┐      ┌───────────────────────────┐
│                           │            drbd         ├──────┤            drbd           │
┌───────────────────────────┐─────────────────────────┐      ┌───────────────────────────┐
│            sdb2           │            sdb1         │      │            sdb1           │ 
┌───────────────────────────────────────────────────────┐    ┌─────────────────────────────┐
│                           HDD                         │    │              HDD            │
└───────────────────────────────────────────────────────┘    └─────────────────────────────┘
                      Server1                                         Server2&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;작업내역&lt;/h3&gt;
&lt;h4&gt;1. 추가된 하드 자동 마운트 작업 (불필요시 skip)&lt;/h4&gt;
&lt;p&gt;1.1. sdb 파티션 구성&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# fdisk /dev/sdb  &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;1.2. 파티션 포맷&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;$xslt&quot;&gt;&lt;pre class=&quot;language-$xslt&quot;&gt;&lt;code class=&quot;language-$xslt&quot;&gt;# mkfs.ext4 /dev/sdb1
# mkfs.ext4 /dev/sdb2&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;1.3. 디바이스 UUID 확인 &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;$xslt&quot;&gt;&lt;pre class=&quot;language-$xslt&quot;&gt;&lt;code class=&quot;language-$xslt&quot;&gt;# blkid
/dev/sdb1: UUID=&amp;quot;bf5b50eb-5a00-4dc4-b628-243bea114909&amp;quot; TYPE=&amp;quot;ext4&amp;quot; PARTUUID=&amp;quot;18c5e0b8-01&amp;quot;
/dev/sdb2: UUID=&amp;quot;21d5fe61-691c-44fa-9066-d2365a52d45d&amp;quot; TYPE=&amp;quot;ext4&amp;quot; PARTUUID=&amp;quot;18c5e0b8-02&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;1.4. 서버 시작 시 자동 마운트를 위한 UUID 등록 (파티션 포맷 시 UUID가 변경된다)&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;$xslt&quot;&gt;&lt;pre class=&quot;language-$xslt&quot;&gt;&lt;code class=&quot;language-$xslt&quot;&gt;# vi /etc/fstab
UUID=21d5fe61-691c-44fa-9066-d2365a52d45d /opt/autocrypt/data2    ext4    defaults    0    0&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;1.5. 파티션 마운트 후 서버 재시작&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;$xslt&quot;&gt;&lt;pre class=&quot;language-$xslt&quot;&gt;&lt;code class=&quot;language-$xslt&quot;&gt;# mount /dev/sdb2 /opt/autocrypt/data2
# reboot&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;1.6. 디스크 정보 확인&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;$xslt&quot;&gt;&lt;pre class=&quot;language-$xslt&quot;&gt;&lt;code class=&quot;language-$xslt&quot;&gt;# df -h&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;h4&gt;2. hotlink 작업&lt;/h4&gt;
&lt;p&gt;2.1. hot link?&lt;br&gt;
데이터나 파일의 변경이 발생하면 관련된 다른 프로그램의 데이터나 파일도 변경되도록 지시하는 연결&lt;/p&gt;
&lt;p&gt;2.2 인터페이스 확인&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;ip a&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;2.2. hotlink용 네트워크 인터페이스 추가&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;$xslt&quot;&gt;&lt;pre class=&quot;language-$xslt&quot;&gt;&lt;code class=&quot;language-$xslt&quot;&gt;# vi /etc/netplan/파일명.yaml&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;$xslt&quot;&gt;&lt;pre class=&quot;language-$xslt&quot;&gt;&lt;code class=&quot;language-$xslt&quot;&gt;network:
    ethernets:
        enp0s3:
            dhcp4: true

        # enp0s9  : 테스트 장비 hotlink 네트워크 인터페이스 명
        # address : primary의 경우 addresses 10.1.1.1, secondary의 경우 10.1.1.2
        enp0s9:
            dhcp4: no
            addresses: [10.1.1.1/24]  
            gateway4: 10.1.1.1
    version: 2&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;2.2. 네트워크 적용&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;$xslt&quot;&gt;&lt;pre class=&quot;language-$xslt&quot;&gt;&lt;code class=&quot;language-$xslt&quot;&gt;# netplan apply&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr/&gt;
&lt;h4&gt;3. drbd 작업&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;3.1. drbd 설치&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;$xslt&quot;&gt;&lt;pre class=&quot;language-$xslt&quot;&gt;&lt;code class=&quot;language-$xslt&quot;&gt;# apt install drbd8-utils&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;***추가 내용 hostname 설정&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;3.2. 설정파일 수정&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;$xslt&quot;&gt;&lt;pre class=&quot;language-$xslt&quot;&gt;&lt;code class=&quot;language-$xslt&quot;&gt;# vi /etc/drbd.conf&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;$xslt&quot;&gt;&lt;pre class=&quot;language-$xslt&quot;&gt;&lt;code class=&quot;language-$xslt&quot;&gt;global {
    usage-count yes;
}
common {
    startup {
            wfc-timeout 10;
            degr-wfc-timeout 10;
            outdated-wfc-timeout 10;
    }
    syncer {
            rate 100M;
    }
    protocol C;
}
resource r0 {
net {
after-sb-0pri discard-least-changes;
after-sb-1pri discard-secondary;
after-sb-2pri disconnect;
}
    on vpki1 {
            device          /dev/drbd0;
            disk            /dev/sdb1; # drbd 대상 디바이스
            address         10.1.1.1:7789;
            meta-disk       internal;
    }
    on vpki2 {
            device          /dev/drbd0;
            disk            /dev/sdb1; # drbd 대상 디바이스
            address         10.1.1.2:7789;
            meta-disk       internal;
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;3.2. 메타 데이터 생성&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;$xslt&quot;&gt;&lt;pre class=&quot;language-$xslt&quot;&gt;&lt;code class=&quot;language-$xslt&quot;&gt;# drbdadm create-md r0&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;3.3. service 시작&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;$xslt&quot;&gt;&lt;pre class=&quot;language-$xslt&quot;&gt;&lt;code class=&quot;language-$xslt&quot;&gt;service drbd start&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;3.4. Primary 서버 설정 (Primary 서버만 작업)&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;$xslt&quot;&gt;&lt;pre class=&quot;language-$xslt&quot;&gt;&lt;code class=&quot;language-$xslt&quot;&gt;# drbdadm primary --force r0&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;3.5. drbd 파티션 포맷&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;$xslt&quot;&gt;&lt;pre class=&quot;language-$xslt&quot;&gt;&lt;code class=&quot;language-$xslt&quot;&gt;# mkfs.ext4 /dev/drbd0&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;3.6. DBMS 데이터 디렉토리 생성 및 마운트&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;$xslt&quot;&gt;&lt;pre class=&quot;language-$xslt&quot;&gt;&lt;code class=&quot;language-$xslt&quot;&gt;# mkdir -p /opt/autocrypt/data1
# mount /dev/drbd0 /opt/autocrypt/data1&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;3.7. 디스크 정보 확인&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;$xslt&quot;&gt;&lt;pre class=&quot;language-$xslt&quot;&gt;&lt;code class=&quot;language-$xslt&quot;&gt;df -h&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;3.8. drdb 상태 확인&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;$xslt&quot;&gt;&lt;pre class=&quot;language-$xslt&quot;&gt;&lt;code class=&quot;language-$xslt&quot;&gt;# cat /proc/drbd
또는
# drbd-overview
------------------------------------------------
#연결된 상태
Connected Primary/Secondary UpToDate/UpToDate
#싱크 작업 중 상태
SyncSource Primary/Secondary
#연결 시도중 상태
WFConnection Primary/Unknown
#미연결 상태
StandAlone Primary/Unknown&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;3.9. 미 연결 상태일 경우&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;$xslt&quot;&gt;&lt;pre class=&quot;language-$xslt&quot;&gt;&lt;code class=&quot;language-$xslt&quot;&gt;# drbdadm connect r0
OR
# service drbd restart&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;참고 (연결 상태일 경우)&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;$xslt&quot;&gt;&lt;pre class=&quot;language-$xslt&quot;&gt;&lt;code class=&quot;language-$xslt&quot;&gt;root@vpki1:~# drbd-overview
0:r0/0  Connected Primary/Secondary UpToDate/UpToDate
-----------------------------------------------------------------------------------
root@vpki1:~# netstat -anp | grep 7789
tcp        0      0 10.1.1.1:40083          10.1.1.2:7789           ESTABLISHED -
tcp        0      0 10.1.1.1:7789           10.1.1.2:49725          ESTABLISHED -&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr/&gt;
&lt;h4&gt;4. DB 작업&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;4.1. MariaDB 설치&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;$xslt&quot;&gt;&lt;pre class=&quot;language-$xslt&quot;&gt;&lt;code class=&quot;language-$xslt&quot;&gt;# apt install mariadb-server&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;4.2. 초기 MariaDB 데이터 백업&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;$xslt&quot;&gt;&lt;pre class=&quot;language-$xslt&quot;&gt;&lt;code class=&quot;language-$xslt&quot;&gt;# mv /var/lib/mysql ~/백업디렉토리/&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;4.3. 초기 MriaDB 데이터 /opt/autocrypt/data1 디렉토리로 복사&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;$xslt&quot;&gt;&lt;pre class=&quot;language-$xslt&quot;&gt;&lt;code class=&quot;language-$xslt&quot;&gt;# cp -rf ~/백업디렉토리/mysql/* /opt/autocrypt/data1/&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;4.4. mysql 실행을 위한 링크 생성&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;$xslt&quot;&gt;&lt;pre class=&quot;language-$xslt&quot;&gt;&lt;code class=&quot;language-$xslt&quot;&gt;# ln -s /opt/autocrypt/data1 /var/lib/mysql&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;4.5. mysql 디렉토리 owner 변경&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;$xslt&quot;&gt;&lt;pre class=&quot;language-$xslt&quot;&gt;&lt;code class=&quot;language-$xslt&quot;&gt;# chown -R mysql:mysql /var/lib/mysql/&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;4.6. MariaDB 시작&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;$xslt&quot;&gt;&lt;pre class=&quot;language-$xslt&quot;&gt;&lt;code class=&quot;language-$xslt&quot;&gt;# service mysql start&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;참고url&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://wlstnans.tistory.com/128&quot;&gt;https://wlstnans.tistory.com/128&lt;/a&gt;  &lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;&lt;hr&gt;
#### 테스트 내용
&lt;ol&gt;
&lt;li&gt;스플릿 브레인(Split Brain) 현상&lt;br&gt;
: 일반적으로 클러스터로 구성된 두 시스템 그룹간 네트워크의 일시적 동시 단절현상이 발생 시 나타나는 현상.
클러스터 상의 모든 노드들은 노드 각자가 자신을 primary라고 인식하게 되는 상황을 말한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;테스트:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt; primary : drbdadm down r0  
 secondary: drbdadm primary --force r0  
 primary : drbdadm up r0  
  =&amp;gt; Occur split brain  &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt; 해결: &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# drbdadm create-md r0  
# drbdadm up r0  
# drbdadm connect r0  
# service drbd start  &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;h4&gt;모니터링&lt;/h4&gt;
&lt;h5&gt;1. primary&lt;/h5&gt;
&lt;p&gt; monitoring target : was / db&lt;br&gt;
문제 발생 시 :&lt;br&gt;
- 1. stop was / db / drbd&lt;br&gt;
- 2. ?&lt;/p&gt;
&lt;h5&gt;2. secondary&lt;/h5&gt;
&lt;p&gt; monitoring target : drbd-overview or /proc/drbd&lt;br&gt;
check point :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# drbd-overview
0:r0/0  *Connected* Secondary/Primary UpToDate/UpToDate
---------------------------------------------------------
** 문제 발생 시 : status is not &amp;#39;Connected&amp;#39;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;h5&gt;스크립트 시나리오&lt;/h5&gt;
&lt;p&gt; -. secondary에서 primary로 변경&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt; # drbdadm primary --force r0&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt; -. check changed state&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt; # drbd-overview&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt; -. mount device&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt; # mount /dev/drbd0 /opt/autocrypt/data1&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt; -. check mounted state&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# df -h&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt; -. service start : DB, WAS, Primary Script?&lt;/p&gt;
&lt;p&gt; -. Secondary Script exit&lt;/p&gt;</content:encoded></item><item><title><![CDATA[[AWS] private key permission in Windows]]></title><link>https://ssongey.github.io/errors/posts/2019-08-28--001</link><guid isPermaLink="false">https://ssongey.github.io/errors/posts/2019-08-28--001</guid><pubDate>Wed, 28 Aug 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Problem&lt;/h2&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/b74608fd7390fd815c964c72e488a61f/90712/001-01.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 882px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 22.499999999999996%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAABJ0AAASdAHeZh94AAAA/UlEQVQY002PWXKDQAxEOUg+smEbA8MyLMO+GCfYAQyJc/+jdIRip/LR1Zop6amltW2JcTpj+ZzITzc/Y15G9mHoMYw9jm8N3vsOeRFD3zzCtDZwPROOu2cJx4AldtAOXY3p8oHr94KJAF/XmUEXAs4rfDxhoHd7qNAdaygl8fT8AH27QnXszZuotuwttLrJUVYpqjpDUSr2hv7yIkFWKHKFosoQRh5LSsHpfGlzshXyX1qSBFgV0+Y0DZGkAdIsomGXBn5PMowX7Fivf4nWE+9Am069S8vymLfJ0GVoFFOS0OE6Vj7VLmQg4PkW9QmG2MJAwD0+VCK5N7mF+QFNXqR9YD+dvQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 01&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/b74608fd7390fd815c964c72e488a61f/90712/001-01.png&quot;
        srcset=&quot;/devHistoryBlog/static/b74608fd7390fd815c964c72e488a61f/8ff5a/001-01.png 240w,
/devHistoryBlog/static/b74608fd7390fd815c964c72e488a61f/e85cb/001-01.png 480w,
/devHistoryBlog/static/b74608fd7390fd815c964c72e488a61f/90712/001-01.png 882w&quot;
        sizes=&quot;(max-width: 882px) 100vw, 882px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h2&gt;Solution&lt;/h2&gt;
&lt;h4&gt;1. 속성 -&gt; 보안 -&gt; 고급에서 상속 사용안함 클릭 후 명시적 사용 권한으로 변경&lt;/h4&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/09d13e75777bd72d0741265f3be97a55/7f15f/001-02.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 55.00000000000001%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABJ0AAASdAHeZh94AAABiklEQVQoz2VSiZaDIAz0/79yr7otohwioFhnM1i6F+/NA00ymRzd7D28QCkFYwyccyfshBhjtc3zjBAClmVBSgnrumLbtn/g/47B1lpM01SDGExYa6oD7SStfoIQhDSvuN/v2Pf9eROV8ONyQd/3NYDZc87IDyI6kJzJ5tnXb9rXUnAcRwUJeVMhbR3LpMKmlKTMxrfWuhLyvqlB3kFUehjrMBkrPu67RYJK+CxHCFrP1DBgGBTGUYs6KdN/wJpXDGOA0lbghVCU24BNVK85VSFEd5Yzo0gZ+17OkgW327X2UetRkhjEtKDXDtfRQU0edsnwUVqzrJjmhE3in0OJMeHvYZLWp7IVpAK82R1TOipUkHe8w+UDeRefsp8lc7Ktb1RZHplI2A7tbX2clw14gG8vfWV72C4OpiqkYyuVuzaO40lIhTJFTr3t4H/Eum4UUnvYDG3/qIR97a83vLz3eL98QsuQSMjT1qTh52GVHaUSbX2MrMMgBI3wqnQlW5bwuH+DK8WKeHOfvwC+ZlE67+maQgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 02&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/09d13e75777bd72d0741265f3be97a55/d9199/001-02.png&quot;
        srcset=&quot;/devHistoryBlog/static/09d13e75777bd72d0741265f3be97a55/8ff5a/001-02.png 240w,
/devHistoryBlog/static/09d13e75777bd72d0741265f3be97a55/e85cb/001-02.png 480w,
/devHistoryBlog/static/09d13e75777bd72d0741265f3be97a55/d9199/001-02.png 960w,
/devHistoryBlog/static/09d13e75777bd72d0741265f3be97a55/07a9c/001-02.png 1440w,
/devHistoryBlog/static/09d13e75777bd72d0741265f3be97a55/7f15f/001-02.png 1530w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h4&gt;2. administrators 제외 모두 제거&lt;/h4&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/903537fe542464a70be4517ec45bb3da/77672/001-03.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 77.08333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAABJ0AAASdAHeZh94AAABVklEQVQ4y62TW0/DMAyF+/9/IA8IJm2C3tN0bXrf5uWzmgkGfWDM0lES1z0+TuzItVaqykpd14q2bWWeZ8WyLLf9PE0yjuMmuq6Tvu8lsp7kdDqp0xgj1lq/llIUhZRlqed+GGSYZrlcLnI+n38APwZH5JxTJyrYkynArVlbzuMiWxZUqkJKPB6PWmpVVaoqjmMlR3koFwxe6X2p0+pnVcKmaZQEQj5AxAcUcg6+zvtCBarax7v2e6yWnGa57A8HSdPEI1W1gAeytfX7Wv0QoAIBVMB9f00K+C8yXPqaBQc/gECMKs7EUD4rdwv5PZSQgGcZyfWVefb/AuNalDDY0wi3Av5qSrh1h4+oVEJjaOZCclPL/jOVvDCSJon21G2Of8H9C4dJi5jZ3fubvLzuZPeRSeN8+/gefKRsSCMamElBZbdOSZiELaAkyzLJ81xXRCVJrANwBS1RkcBn15HUAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 03&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/903537fe542464a70be4517ec45bb3da/d9199/001-03.png&quot;
        srcset=&quot;/devHistoryBlog/static/903537fe542464a70be4517ec45bb3da/8ff5a/001-03.png 240w,
/devHistoryBlog/static/903537fe542464a70be4517ec45bb3da/e85cb/001-03.png 480w,
/devHistoryBlog/static/903537fe542464a70be4517ec45bb3da/d9199/001-03.png 960w,
/devHistoryBlog/static/903537fe542464a70be4517ec45bb3da/77672/001-03.png 1060w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h4&gt;3. 소유자 복사 -&gt; 추가 -&gt; 보안주체 선택 -&gt; 이름 입력 후 이름 확인&lt;/h4&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/465d5e85064614037fb38a3c7fa277a8/f5209/001-04.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 77.08333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAABJ0AAASdAHeZh94AAABdElEQVQ4y71TSW7DMBDT/3/Td/TcW5sAPiTeJEvyvrLDqRMUaXJJiwogtHiGJjUjUweL0jqEyqENDkPfYRzHK4Zh+ELfo+u6u2jbVnE+n2FcVWFdZmShx+uhRJJa2LJAnucoihJ1XaMj2TBhXdeH4OCPDROwLTjYES9vEYe8wTR0aJpW0KiCKHM7zHg0Lm4Yayi1loSxbzE1HtE7pGmKXlRt24ZlWXbMmKbpB+Z5VmWjrMllYghqz8tci6oQonxo0NDqfkd0QbUxRl0zMcage42lExGgljMhS5JEVaVZKoRB4b2/IpNzJjGBAnj51lol7vdiceYPpCh+r1QjKr0eEkoqexJxzWRaZCzPvnfCBYwzDPirweswrCYHC/AbXAlp5V8In7Z8Ibwdz6hUQuectgArWxQFKtmzldgirCqrd6+hbyvMMyUkycfHO47HoxKyJSp538/YJqlhclmW+loub5dNyvUj8EWdsgKnXPJEBB3yYZDjE+KYkOketeCgAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 04&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/465d5e85064614037fb38a3c7fa277a8/d9199/001-04.png&quot;
        srcset=&quot;/devHistoryBlog/static/465d5e85064614037fb38a3c7fa277a8/8ff5a/001-04.png 240w,
/devHistoryBlog/static/465d5e85064614037fb38a3c7fa277a8/e85cb/001-04.png 480w,
/devHistoryBlog/static/465d5e85064614037fb38a3c7fa277a8/d9199/001-04.png 960w,
/devHistoryBlog/static/465d5e85064614037fb38a3c7fa277a8/f5209/001-04.png 1061w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/548b2304dde2d346ca140a8048b5ad77/2c288/001-05.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 684px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 76.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAABJ0AAASdAHeZh94AAAB60lEQVQ4y5VUCY7aQBD0/x9HApEwYHxf+MIHvrADla7ZtbVJNisyUqkHu6e6unqMNvQtun5Ae7uhbW+4NQ2Gvsc03XG//z+0RgiapsZNCLtxRjvMaPo7+mHEfRwxvoiVMAxDuI6DOI4RZDXs+IowF7XdgGHo0fdfYxgGFSlonmdo5fWK8lqiqmuJBYoixyhJj8dPTJIwv4hazldVBS0IAjii8HQ6wTRNnM9nWKYFPi/LElcp+BWYQ6I8z3G5XKD5vg/LMhXh8XhU5IZhqD0LWJalkoui+A1ZlkHX9/i22WC73cIXAVSpCEliirJVofWmkAc/I1uQJAmSNFH+p2mqvNRc11UkVEWQlIl5XkjFCnVVrq1/jCzkeR70/R62bSOKInRdB43soaihUoJJjGEYwAtjuMFF2ktXtYvixTPmh2GkRChCKjSMk/LwcDioanzm+x48IbO9SA5nyvhlAMueV46EtGclpLncsH9e8lcXLzEt4kD20jZJFSEn83E9n0+5g49/gu+5pmkSfyt1oQl6qwgTmQ4nxEmzCr15+xz/Ri1w4hy66eLoRPCiFL607Inna8vKB/Fst9spD/l7Mf9PpJmQWQE2P3R8100YToDzu/8cZNu20NSfwruHjHy4tPEZOnm/5HKvomD5ln8BFuVuocV83ugAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 05&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/548b2304dde2d346ca140a8048b5ad77/2c288/001-05.png&quot;
        srcset=&quot;/devHistoryBlog/static/548b2304dde2d346ca140a8048b5ad77/8ff5a/001-05.png 240w,
/devHistoryBlog/static/548b2304dde2d346ca140a8048b5ad77/e85cb/001-05.png 480w,
/devHistoryBlog/static/548b2304dde2d346ca140a8048b5ad77/2c288/001-05.png 684w&quot;
        sizes=&quot;(max-width: 684px) 100vw, 684px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h4&gt;4. 아래와 같이 설정이 됐는지 확인 후 적용&lt;/h4&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/465c00888223455338b2a45176d21669/9cea8/001-06.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 73.33333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAABJ0AAASdAHeZh94AAABC0lEQVQ4y6WU226DMBBE/f9/19eqDylPhYINGF8wl4nHFSSkSdPASiPEAkezu6yFUhJN00AphbquVzHXagPVWjjvEUKPvv9b1jkIrTWMMaikRFVVG2nj0NqAcZzAmOcZ92LJj+MIkRxFN0VRQMoLrCxLdF0H7x2cey4fRWOCpVprk+VhGDYKIcR8SNdnao1HrS0Eb6w1yPM8QfYGqw7xe0EIHTZNm3qxR0tM0/TjkEmWvDx81PxHwyCDFco4WEHQvZdeAdIZOc75C/Da/h7o+ttcA18fxNYA53EIeAv+BTyiFcgJHY2luATk2nBKbOgeTVERmZSA3NnbQ+G/4u5/Fd94ez/h45Qhyz5xBjh3mxiAKjA9AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 06&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/465c00888223455338b2a45176d21669/d9199/001-06.png&quot;
        srcset=&quot;/devHistoryBlog/static/465c00888223455338b2a45176d21669/8ff5a/001-06.png 240w,
/devHistoryBlog/static/465c00888223455338b2a45176d21669/e85cb/001-06.png 480w,
/devHistoryBlog/static/465c00888223455338b2a45176d21669/d9199/001-06.png 960w,
/devHistoryBlog/static/465c00888223455338b2a45176d21669/9cea8/001-06.png 1278w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/fd0874d94c0d05eadc08a0835baffe73/bbb77/001-07.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 765px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 30%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABJ0AAASdAHeZh94AAAA1klEQVQY061QixKDIAzj/79ScRMcAqLOB+dd1nSPLxh3ubbQhDZmHEcMwwA/eJRSMAt4R7DOKSHnjGWekadJ65Si3iXJQwjaV5QXYEJ4wHsH5xxqrYIT2/YUbDiOA/u+a6zn+csZFdKzritOeSOXnLeg8zoZJ40xagOJX3wFmLOfxOu6VIQx6pYPndy01qLrbliXRWIHa1v0fS/R4na/a2yaRnPawB7WnOy9UYVtW12fE5siQos88lf6kNSjhEn8Ug8/XhGsKaSeCo+bELP4yw0obvDn8wLNp8zjciV5kAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;001 07&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/fd0874d94c0d05eadc08a0835baffe73/bbb77/001-07.png&quot;
        srcset=&quot;/devHistoryBlog/static/fd0874d94c0d05eadc08a0835baffe73/8ff5a/001-07.png 240w,
/devHistoryBlog/static/fd0874d94c0d05eadc08a0835baffe73/e85cb/001-07.png 480w,
/devHistoryBlog/static/fd0874d94c0d05eadc08a0835baffe73/bbb77/001-07.png 765w&quot;
        sizes=&quot;(max-width: 765px) 100vw, 765px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;</content:encoded></item><item><title><![CDATA[[백준] 3085번 사탕게임]]></title><description><![CDATA[[백준] 3085번 사탕게임]]></description><link>https://ssongey.github.io/algo/posts/1</link><guid isPermaLink="false">https://ssongey.github.io/algo/posts/1</guid><pubDate>Wed, 21 Aug 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;목차&lt;br&gt;
&lt;a href=&quot;#%EA%B0%9C%EB%B0%9C%EC%9D%84-%ED%95%98%EA%B3%A0-%EC%8B%B6%EC%96%B4%EC%9A%94&quot;&gt;1.개발을 하고 싶어요&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;#coding%EC%9D%84-%EC%9E%98%ED%95%98%EA%B3%A0-%EC%8B%B6%EC%96%B4%EC%9A%94&quot;&gt;2.코딩을 잘하고 싶어요&lt;/a&gt;  &lt;/p&gt;
&lt;h2&gt;개발을 하고 싶어요&lt;/h2&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/c0461ee94e67a1896b573608f6219184/67fe0/Q.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 83.33333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAYAAADdRIy+AAAACXBIWXMAABJ0AAASdAHeZh94AAABjElEQVQ4y61Ti26DMAzM///o1FLIg4SEEPB8LkEpo1onDelkhxjbZx9qmiYaR09lXWlllFIID/xt28SHbc+IwbnG4bwsC+WcSYUQKKUkl/DHcRQ/xigBNUGNqXHzPIsP65w7Ciu8qF0hSYzpCERV6YLvccYHAJLXO1iwPBJaP9F/PgoUtTZkjCFrLXnvxWqthTI6AIM6pysgrsYqxx93XUfDMIh9PHrq+17OAHzNFgXrGTN7jucJzDSESUahPHeIAOlst0BdEO5gAXTeLueSsmHJVDnIYD+cVV3QGQpVQeU5Sy3dwUcn2GwLzKn6a6PRl4SBEyARZtQChTAfJD5DEu7CbtkJ5cE6yvu22k2W/YO/0lbes+q5auaqtQN0BrFWwZ+7eDc/SXjvB/rqBnIhNZqaX2jhwfLug6Uwl1+EzfoZOVmcQbUcKGUVm/Mivuc441hvEcWWSyBWQcjWOKaaWXuJqf5ESkiSX0ZyDRb27cZ/ibZSIXL1K6DYx/+y0ZCIk18HC7oC7rY3ujvjG34rNUyrrccOAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Q&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/c0461ee94e67a1896b573608f6219184/d9199/Q.png&quot;
        srcset=&quot;/devHistoryBlog/static/c0461ee94e67a1896b573608f6219184/8ff5a/Q.png 240w,
/devHistoryBlog/static/c0461ee94e67a1896b573608f6219184/e85cb/Q.png 480w,
/devHistoryBlog/static/c0461ee94e67a1896b573608f6219184/d9199/Q.png 960w,
/devHistoryBlog/static/c0461ee94e67a1896b573608f6219184/67fe0/Q.png 1101w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
      &lt;/p&gt;
&lt;h2&gt;Coding을 잘하고 싶어요&lt;/h2&gt;
&lt;h3&gt;송은영&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;1. gatsby-cli 설치 및 프로젝트 생성 (lumen 테마 사용)&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;yarn&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; -g gatsby-cli
$ gatsby new devHistoryBlog https://github.com/GatsbyCentral/gatsby-v2-starter-lumen&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;2. gatsby 로컬 서버 구동 (기본포트 8000)&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; devHistoryBlog
$ gatsby develop&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;3. github repository 연동&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;//git remote &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; origin &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;repository_url&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
$ &lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; remote &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; origin https://github.com/SangBeo/devHistoryBlog.git&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;[브랜치 생성]&lt;br&gt;
github 페이지는 최종적으로 master의 파일들이 배포된다.&lt;br&gt;
master에서 gatsby 파일 관리와 gh-pages의 빌드를 같이 하니 난잡해서 보기 좋지 않다.&lt;br&gt;
그래서 개발은 develop 브랜치에서 진행하고 master 브랜치는 gh-pages로 배포할때만 사용한다&lt;br&gt;
-&gt; develop branch : gatsby 파일 구조를 관리&lt;br&gt;
-&gt; master : build 된 파일들을 github 페이지에 배포&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;3.1. develop 브랜치 생성&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;//-m 옵션을 이용하여 develop 브랜치로 이동
$ &lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; branch -m develop&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;3.2. 커밋과 푸쉬&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; *
$ commit -m &lt;span class=&quot;token string&quot;&gt;&quot;init commit&quot;&lt;/span&gt;
//push 시 -u 옵션을 붙여 이후 push 할때마다 develop 브랜치로 푸쉬한다
$ &lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push -u origin develop&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/f6762a3447b66ffb0bcdd9c10bcb04a8/38a65/1.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 79.16666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAACXBIWXMAABJ0AAASdAHeZh94AAACgklEQVQ4y5VTx2ocQRTc/wcf7aN/wKAP8MFXgy8Gg8EIJ4mVtKtJneP0lOv1alc4XDxD0a9Tdb20s8ZgGGaMKuJ+DDjOATHljhAzUi6Xudg+RBweRyhjoY0jLKwPcFzPpWKXEwmcRggBtRSklPqlEBMcDyYhoy1zscPTRZnXtWFtjeOKwjUZd/Lyoi1yzvj/b+t/2xpFBGzbhl1ZgVhAd/hCbdzkMaJwI4RMBae5ICbxoFzmtVBhJEF7ohfCWjy8PcDqA2KYuOrRVoe1WqzF0LZ9foLFxnFrntcjVBrw3fzE3t9hpC2v7FIYMQ+f4fQ3WPUVKdzy0oGvHvu4VcEDQLumPaK/JW7Q4h2ux494ef0aL768wpubK/I17CRTN/sDMzdhVrYj0/3MjDb6L64x7h0SAiWZtR6K8Cbhw8MnXP14i3f796iNSZl0wH6wuJ8cRlMw+xVHnTgPGO2KyTUYxsnmDZ6xPsOmhkF7TCpB6wrr1h7HnfWRNchaYmZ8Wjsc7eOkcRiJyWBcTD8zzAaWKnPdEDKTlirPFwyLxkzlnVDKxXsGnHJX1lGjb+taYVjwhkVrrOuQAlbaMNOp11ut62W0zvfa7YTSDY9LRGTchFDz0rKoDqU0FmU60UJ75poU97lEzujd4vyJUOpvZuxyPRWTdIzjpqMqKxCbsO6kNJdzHT4TenaUdNMTYcGoc49d35TL1nalpvfrs9uiNDFEfxJ2l0naCaX6j0tmPLbeSqJKyMRdpXUnOcdP3E75b5flMXcmlEZXrjB7J4Uxxu62KHXe94PSpzKKkpPL228IvHNx2bMM9kPE4mpXqKlqnmZMgnnBxET0kRi5Fv+RFFEunsn3C0wP2GTW8yfXAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;1&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/f6762a3447b66ffb0bcdd9c10bcb04a8/d9199/1.png&quot;
        srcset=&quot;/devHistoryBlog/static/f6762a3447b66ffb0bcdd9c10bcb04a8/8ff5a/1.png 240w,
/devHistoryBlog/static/f6762a3447b66ffb0bcdd9c10bcb04a8/e85cb/1.png 480w,
/devHistoryBlog/static/f6762a3447b66ffb0bcdd9c10bcb04a8/d9199/1.png 960w,
/devHistoryBlog/static/f6762a3447b66ffb0bcdd9c10bcb04a8/38a65/1.png 1075w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;br&gt;
그럼 위와 같이 develop 브랜치에 소스 push가 된다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4. gh-pages 설치 및 설정 파일 수정, 그리고 Deploy&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;yarn&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; --dev gh-pages&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;4.1. gatsby-config.js 수정

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/9b9f7bf8ba35b6c0af38da64066cf443/b0122/3.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 416px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 67.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAABJ0AAASdAHeZh94AAACBUlEQVQ4y31U2XLbMAzUx7RJZN0USfHS4St2JjN96f9/y3YFH3XSpA87AEl5ASwAZ/vhN6I+YUgH+OmESidU8xnN8Req8Qw97WC3CX0aUSmHvNbYNAab1qDoaGuDl1LjuejFZk69QncLerfAhj1cOiKv+KGZUNIvwxE1g5g5QMWAznsGiQK7jVAukcj8Jbw5tyhyrtZzf71T4svb5vJ28wXF7bvLfTbqdwxqD+1mNHpkKVZKNMygGZz48TxLRmaOGHZJ/C54Kf0xoUuGpb2kzMg/+fhjjV71olXOO9GKEN0IuadueXUlKfRHDQ86InYetnVYVMSsAtp6IFFgSQzyoj7g6VrmXZ4HMiFMfcTZjFhojyzZdQE5M7HbkSWyu2OUZpglSckFJXkuHjX+VLJmZm/s4omEe9oVnfJoXUTVW9TGoVytdbyj3w5fEt0Jh2FGsDM8s1S1hWOApuGPKivlPV27KX7+fal3wjBzDklo7ETtSFKsolND+vfR+DQi/0Pmx6M05cCSt31CYzzCcuDAjtLRUlnZiNWu58eGfIUscs0Sm7EjNBuifJQG6CmhXf1phN1NcPsZ3bBuBYmr75Gl3TuCnnFwW+z9DsEsKBT3mSNUEgWDFO2KtUkJZRc5j7e7f8EMX2Wwa25FO87YqIGbMWGQP4QAf5xoI/xhEr913BBq/J2efwBqtL1h4lKbbQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;3&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/9b9f7bf8ba35b6c0af38da64066cf443/b0122/3.png&quot;
        srcset=&quot;/devHistoryBlog/static/9b9f7bf8ba35b6c0af38da64066cf443/8ff5a/3.png 240w,
/devHistoryBlog/static/9b9f7bf8ba35b6c0af38da64066cf443/b0122/3.png 416w&quot;
        sizes=&quot;(max-width: 416px) 100vw, 416px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;url 수정&lt;/li&gt;
&lt;li&gt;pathPrefix 추가
4.2. package.json 필요시 수정&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;4.3. Deploy&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;//build 및 master branch로 push
$ &lt;span class=&quot;token function&quot;&gt;yarn&lt;/span&gt; deploy&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;5. 실행&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;http://sangbeo.github.io/devHistoryBlog&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Gatsby 구축]]></title><description><![CDATA[gatsby + gh-pages + github]]></description><link>https://ssongey.github.io/works/posts/2020-12-09--001</link><guid isPermaLink="false">https://ssongey.github.io/works/posts/2020-12-09--001</guid><pubDate>Sun, 18 Aug 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;1. gatsby-cli 설치 및 프로젝트 생성 (lumen 테마 사용)&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;yarn&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; -g gatsby-cli
$ gatsby new devHistoryBlog https://github.com/GatsbyCentral/gatsby-v2-starter-lumen&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;2. gatsby 로컬 서버 구동 (기본포트 8000)&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; devHistoryBlog
$ gatsby develop&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;3. github repository 연동&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;//git remote &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; origin &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;repository_url&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
$ &lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; remote &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; origin https://github.com/SangBeo/devHistoryBlog.git&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;[브랜치 생성]&lt;br&gt;
github 페이지는 최종적으로 master의 파일들이 배포된다.&lt;br&gt;
master에서 gatsby 파일 관리와 gh-pages의 빌드를 같이 하니 난잡해서 보기 좋지 않다.&lt;br&gt;
그래서 개발은 develop 브랜치에서 진행하고 master 브랜치는 gh-pages로 배포할때만 사용한다&lt;br&gt;
-&gt; develop branch : gatsby 파일 구조를 관리&lt;br&gt;
-&gt; master : build 된 파일들을 github 페이지에 배포&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;3.1. develop 브랜치 생성&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;//-m 옵션을 이용하여 develop 브랜치로 이동
$ &lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; branch -m develop&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;3.2. 커밋과 푸쉬&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; *
$ commit -m &lt;span class=&quot;token string&quot;&gt;&quot;init commit&quot;&lt;/span&gt;
//push 시 -u 옵션을 붙여 이후 push 할때마다 develop 브랜치로 푸쉬한다
$ &lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push -u origin develop&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/f6762a3447b66ffb0bcdd9c10bcb04a8/38a65/1.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 79.16666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAACXBIWXMAABJ0AAASdAHeZh94AAACgklEQVQ4y5VTx2ocQRTc/wcf7aN/wKAP8MFXgy8Gg8EIJ4mVtKtJneP0lOv1alc4XDxD0a9Tdb20s8ZgGGaMKuJ+DDjOATHljhAzUi6Xudg+RBweRyhjoY0jLKwPcFzPpWKXEwmcRggBtRSklPqlEBMcDyYhoy1zscPTRZnXtWFtjeOKwjUZd/Lyoi1yzvj/b+t/2xpFBGzbhl1ZgVhAd/hCbdzkMaJwI4RMBae5ICbxoFzmtVBhJEF7ohfCWjy8PcDqA2KYuOrRVoe1WqzF0LZ9foLFxnFrntcjVBrw3fzE3t9hpC2v7FIYMQ+f4fQ3WPUVKdzy0oGvHvu4VcEDQLumPaK/JW7Q4h2ux494ef0aL768wpubK/I17CRTN/sDMzdhVrYj0/3MjDb6L64x7h0SAiWZtR6K8Cbhw8MnXP14i3f796iNSZl0wH6wuJ8cRlMw+xVHnTgPGO2KyTUYxsnmDZ6xPsOmhkF7TCpB6wrr1h7HnfWRNchaYmZ8Wjsc7eOkcRiJyWBcTD8zzAaWKnPdEDKTlirPFwyLxkzlnVDKxXsGnHJX1lGjb+taYVjwhkVrrOuQAlbaMNOp11ut62W0zvfa7YTSDY9LRGTchFDz0rKoDqU0FmU60UJ75poU97lEzujd4vyJUOpvZuxyPRWTdIzjpqMqKxCbsO6kNJdzHT4TenaUdNMTYcGoc49d35TL1nalpvfrs9uiNDFEfxJ2l0naCaX6j0tmPLbeSqJKyMRdpXUnOcdP3E75b5flMXcmlEZXrjB7J4Uxxu62KHXe94PSpzKKkpPL228IvHNx2bMM9kPE4mpXqKlqnmZMgnnBxET0kRi5Fv+RFFEunsn3C0wP2GTW8yfXAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;1&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/f6762a3447b66ffb0bcdd9c10bcb04a8/d9199/1.png&quot;
        srcset=&quot;/devHistoryBlog/static/f6762a3447b66ffb0bcdd9c10bcb04a8/8ff5a/1.png 240w,
/devHistoryBlog/static/f6762a3447b66ffb0bcdd9c10bcb04a8/e85cb/1.png 480w,
/devHistoryBlog/static/f6762a3447b66ffb0bcdd9c10bcb04a8/d9199/1.png 960w,
/devHistoryBlog/static/f6762a3447b66ffb0bcdd9c10bcb04a8/38a65/1.png 1075w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;br&gt;
그럼 위와 같이 develop 브랜치에 소스 push가 된다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4. gh-pages 설치 및 설정 파일 수정, 그리고 Deploy&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;yarn&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; --dev gh-pages&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;4.1. gatsby-config.js 수정

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/devHistoryBlog/static/9b9f7bf8ba35b6c0af38da64066cf443/b0122/3.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 416px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 67.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAABJ0AAASdAHeZh94AAACBUlEQVQ4y31U2XLbMAzUx7RJZN0USfHS4St2JjN96f9/y3YFH3XSpA87AEl5ASwAZ/vhN6I+YUgH+OmESidU8xnN8Req8Qw97WC3CX0aUSmHvNbYNAab1qDoaGuDl1LjuejFZk69QncLerfAhj1cOiKv+KGZUNIvwxE1g5g5QMWAznsGiQK7jVAukcj8Jbw5tyhyrtZzf71T4svb5vJ28wXF7bvLfTbqdwxqD+1mNHpkKVZKNMygGZz48TxLRmaOGHZJ/C54Kf0xoUuGpb2kzMg/+fhjjV71olXOO9GKEN0IuadueXUlKfRHDQ86InYetnVYVMSsAtp6IFFgSQzyoj7g6VrmXZ4HMiFMfcTZjFhojyzZdQE5M7HbkSWyu2OUZpglSckFJXkuHjX+VLJmZm/s4omEe9oVnfJoXUTVW9TGoVytdbyj3w5fEt0Jh2FGsDM8s1S1hWOApuGPKivlPV27KX7+fal3wjBzDklo7ETtSFKsolND+vfR+DQi/0Pmx6M05cCSt31CYzzCcuDAjtLRUlnZiNWu58eGfIUscs0Sm7EjNBuifJQG6CmhXf1phN1NcPsZ3bBuBYmr75Gl3TuCnnFwW+z9DsEsKBT3mSNUEgWDFO2KtUkJZRc5j7e7f8EMX2Wwa25FO87YqIGbMWGQP4QAf5xoI/xhEr913BBq/J2efwBqtL1h4lKbbQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;3&quot;
        title=&quot;&quot;
        src=&quot;/devHistoryBlog/static/9b9f7bf8ba35b6c0af38da64066cf443/b0122/3.png&quot;
        srcset=&quot;/devHistoryBlog/static/9b9f7bf8ba35b6c0af38da64066cf443/8ff5a/3.png 240w,
/devHistoryBlog/static/9b9f7bf8ba35b6c0af38da64066cf443/b0122/3.png 416w&quot;
        sizes=&quot;(max-width: 416px) 100vw, 416px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;url 수정&lt;/li&gt;
&lt;li&gt;pathPrefix 추가
4.2. package.json 필요시 수정&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;4.3. Deploy&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;//build 및 master branch로 push
$ &lt;span class=&quot;token function&quot;&gt;yarn&lt;/span&gt; deploy&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;5. 실행&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;http://sangbeo.github.io/devHistoryBlog&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item></channel></rss>