<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>개발블로그</title>
    <link>https://jinmanp.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Tue, 12 May 2026 17:06:49 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>박진만</managingEditor>
    <image>
      <title>개발블로그</title>
      <url>https://tistory1.daumcdn.net/tistory/1126758/attach/94dcc79c720f4016a625617338dc8880</url>
      <link>https://jinmanp.tistory.com</link>
    </image>
    <item>
      <title>PostgreSQL DB 성능 개선을 위한 설정 파일 수정</title>
      <link>https://jinmanp.tistory.com/entry/%E3%84%B4</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;개발&amp;nbsp;서버에&amp;nbsp;PostgreSQL&amp;nbsp;DB&amp;nbsp;설치&amp;nbsp;후&amp;nbsp;사용하면서&amp;nbsp;속도가&amp;nbsp;느리다는&amp;nbsp;느낌을&amp;nbsp;받았습니다.&amp;nbsp;서버&amp;nbsp;사양은&amp;nbsp;낮지&amp;nbsp;않은데&amp;nbsp;DB&amp;nbsp;성능은&amp;nbsp;좋지&amp;nbsp;않아&amp;nbsp;설정의&amp;nbsp;문제가&amp;nbsp;있지&amp;nbsp;않을까&amp;nbsp;싶어&amp;nbsp;개선&amp;nbsp;방법을&amp;nbsp;찾아보았습니다. &lt;br /&gt;&lt;br /&gt;PostgreSQL&amp;nbsp;의&amp;nbsp;기본&amp;nbsp;설정은&amp;nbsp;최고의&amp;nbsp;성능을&amp;nbsp;내기&amp;nbsp;보다는&amp;nbsp;가능한&amp;nbsp;다양한&amp;nbsp;기기에서&amp;nbsp;잘&amp;nbsp;동작할&amp;nbsp;수&amp;nbsp;있도록&amp;nbsp;보수적으로&amp;nbsp;잡혀&amp;nbsp;있다고&amp;nbsp;합니다.&amp;nbsp;설치&amp;nbsp;후&amp;nbsp;아무런&amp;nbsp;설정을&amp;nbsp;건드리지&amp;nbsp;않았다면&amp;nbsp;속도가&amp;nbsp;느린게&amp;nbsp;당연한&amp;nbsp;것이었습니다. &lt;br /&gt;&lt;br /&gt;PostgreSQL&amp;nbsp;은&amp;nbsp;postgresql.conf&amp;nbsp;파일을&amp;nbsp;수정한&amp;nbsp;후&amp;nbsp;DB&amp;nbsp;를&amp;nbsp;재기동하면&amp;nbsp;설정이&amp;nbsp;변경됩니다.&amp;nbsp; &lt;br /&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;br /&gt;※ DB 재기동 없이 Query 또는 Command 를 실행해서 설정을 적용하는 방법도 있습니다. 그러나 일반적인 설정 적용은 가능하지만 일부 재시작이 필요한 설정은 적용되지 않습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;쿼리(Query)를&amp;nbsp;활용한&amp;nbsp;Reload&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1685595699153&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT pg_reload_conf();&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;-&amp;nbsp;명령어(Command)를&amp;nbsp;활용한&amp;nbsp;Reload&lt;/p&gt;
&lt;pre id=&quot;code_1685595731189&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pg_ctl reload -D [Datbasae 경로]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;※ postgresql.conf 파일이 있는 위치를 확인하는 방법입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1685596043704&quot; class=&quot;sql&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;show data_directory;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;1.PNG&quot; data-origin-width=&quot;211&quot; data-origin-height=&quot;176&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dp8D0n/btsijMiuYoV/wGIqNKzbWCYKkK1R4qM7PK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dp8D0n/btsijMiuYoV/wGIqNKzbWCYKkK1R4qM7PK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dp8D0n/btsijMiuYoV/wGIqNKzbWCYKkK1R4qM7PK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdp8D0n%2FbtsijMiuYoV%2FwGIqNKzbWCYKkK1R4qM7PK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;211&quot; height=&quot;176&quot; data-filename=&quot;1.PNG&quot; data-origin-width=&quot;211&quot; data-origin-height=&quot;176&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;※ 성능 개선을 위해 postgresql.conf 파일 내용을 수정한 항목입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1)&amp;nbsp;shared_buffers &lt;br /&gt;Postgresql&amp;nbsp;은&amp;nbsp;디스크에&amp;nbsp;메모리&amp;nbsp;값을&amp;nbsp;직접&amp;nbsp;변경하는&amp;nbsp;대신&amp;nbsp;공유&amp;nbsp;버퍼&amp;nbsp;캐시에&amp;nbsp;데이터를&amp;nbsp;읽도록&amp;nbsp;요청한다. &lt;br /&gt;서버의&amp;nbsp;메모리&amp;nbsp;성능은&amp;nbsp;이&amp;nbsp;공유버퍼의&amp;nbsp;용량을&amp;nbsp;조정함으로써&amp;nbsp;조절할&amp;nbsp;수&amp;nbsp;있다. &lt;br /&gt;기본값은&amp;nbsp;128MB,&amp;nbsp;최소&amp;nbsp;128KB&amp;nbsp;이상으로&amp;nbsp;설정해야&amp;nbsp;한다. &lt;br /&gt;서버&amp;nbsp;메모리의&amp;nbsp;1/4&amp;nbsp;정도&amp;nbsp;용량을&amp;nbsp;설정한다.&amp;nbsp;(공식&amp;nbsp;페이지에서는&amp;nbsp;40%를&amp;nbsp;넘지&amp;nbsp;않도록&amp;nbsp;권장) &lt;br /&gt;설정값은&amp;nbsp;MB,&amp;nbsp;GB&amp;nbsp;등&amp;nbsp;단위별로&amp;nbsp;설정&amp;nbsp;가능하다. &lt;br /&gt;&lt;br /&gt;2)&amp;nbsp;work_mem &lt;br /&gt;sort,&amp;nbsp;merge,&amp;nbsp;join&amp;nbsp;등에&amp;nbsp;사용하는&amp;nbsp;메모리&amp;nbsp;설정&amp;nbsp;값.&amp;nbsp;서버&amp;nbsp;사양에&amp;nbsp;따라&amp;nbsp;설정&amp;nbsp;값을&amp;nbsp;변경해주면&amp;nbsp;됩니다. &lt;br /&gt;기본값은&amp;nbsp;4MB&amp;nbsp;로&amp;nbsp;설정되어&amp;nbsp;있습니다. &lt;br /&gt;&lt;br /&gt;계산식 &lt;br /&gt;ex)&amp;nbsp;32GB&amp;nbsp;메모리에&amp;nbsp;max_connections&amp;nbsp;100 &lt;br /&gt;&lt;br /&gt;(시스템&amp;nbsp;전체&amp;nbsp;메모리)&amp;nbsp;/&amp;nbsp;(최대&amp;nbsp;커넥션&amp;nbsp;수&amp;nbsp;*&amp;nbsp;16) &lt;br /&gt;(32G&amp;nbsp;*&amp;nbsp;1024)&amp;nbsp;/&amp;nbsp;(100&amp;nbsp;*&amp;nbsp;16)&amp;nbsp;=&amp;nbsp;32,768&amp;nbsp;/&amp;nbsp;1600&amp;nbsp;=&amp;nbsp;20.48&amp;nbsp;=&amp;gt;&amp;nbsp;약&amp;nbsp;20MB&amp;nbsp;로&amp;nbsp;설정 &lt;br /&gt;&lt;br /&gt;1&amp;nbsp;/&amp;nbsp;(max_connections&amp;nbsp;*&amp;nbsp;2) &lt;br /&gt;(32G&amp;nbsp;*&amp;nbsp;1024)&amp;nbsp;/&amp;nbsp;(100&amp;nbsp;*&amp;nbsp;2)&amp;nbsp;=&amp;nbsp;163.84&amp;nbsp;=&amp;gt;&amp;nbsp;약&amp;nbsp;160MB&amp;nbsp;로&amp;nbsp;설정 &lt;br /&gt;&lt;br /&gt;이&amp;nbsp;계산식이&amp;nbsp;정답이라고&amp;nbsp;할&amp;nbsp;수는&amp;nbsp;없습니다. &lt;br /&gt;work_mem&amp;nbsp;을&amp;nbsp;크게&amp;nbsp;설정하면&amp;nbsp;대용량&amp;nbsp;작업을&amp;nbsp;할&amp;nbsp;때&amp;nbsp;좀더&amp;nbsp;성능이&amp;nbsp;좋아지지만&amp;nbsp;커넥션이&amp;nbsp;늘어나면&amp;nbsp;프로세스를&amp;nbsp;다&amp;nbsp;띄우지&amp;nbsp;못하고&amp;nbsp;초과되어&amp;nbsp;Out&amp;nbsp;of&amp;nbsp;Memory&amp;nbsp;가&amp;nbsp;발생할&amp;nbsp;수&amp;nbsp;있습니다. &lt;br /&gt;각자&amp;nbsp;상황에&amp;nbsp;맞게&amp;nbsp;운영하면서&amp;nbsp;최적&amp;nbsp;값을&amp;nbsp;찾아가면&amp;nbsp;될&amp;nbsp;것&amp;nbsp;같습니다. &lt;br /&gt;&lt;br /&gt;3)&amp;nbsp;maintenance_work_mem &lt;br /&gt;VACUUM,&amp;nbsp;CREATE&amp;nbsp;INDEX&amp;nbsp;및&amp;nbsp;ALTER&amp;nbsp;TABLE&amp;nbsp;ADD&amp;nbsp;FOREIGN&amp;nbsp;KEY&amp;nbsp;와&amp;nbsp;같이&amp;nbsp;유지&amp;nbsp;보수&amp;nbsp;작업에서&amp;nbsp;사용할&amp;nbsp;최대&amp;nbsp;메모리&amp;nbsp;크기 &lt;br /&gt;백업&amp;nbsp;및&amp;nbsp;복원&amp;nbsp;성능도&amp;nbsp;해당&amp;nbsp;설정의&amp;nbsp;영향을&amp;nbsp;받는다. &lt;br /&gt;기본값은&amp;nbsp;64MB이며,&amp;nbsp;work_mem&amp;nbsp;설정보다&amp;nbsp;크게&amp;nbsp;설정하는&amp;nbsp;것을&amp;nbsp;권장한다. &lt;br /&gt;maintenance_work_mem&amp;nbsp;설정은&amp;nbsp;서버&amp;nbsp;메모리의&amp;nbsp;1/16으로&amp;nbsp;설정하는&amp;nbsp;것을&amp;nbsp;권장한다. &lt;br /&gt;&lt;br /&gt;4)&amp;nbsp;wal_buffers &lt;br /&gt;데이터베이스의&amp;nbsp;변경&amp;nbsp;사항을&amp;nbsp;잠시&amp;nbsp;저장(로그)는&amp;nbsp;버퍼입니다.&amp;nbsp;WAL(Write&amp;nbsp;Ahead&amp;nbsp;Log)이라고&amp;nbsp;명칭합니다. &lt;br /&gt;백업&amp;nbsp;및&amp;nbsp;복구&amp;nbsp;관점에서&amp;nbsp;보면,&amp;nbsp;WAL&amp;nbsp;버퍼와&amp;nbsp;WAL&amp;nbsp;파일은&amp;nbsp;매우&amp;nbsp;중요합니다. &lt;br /&gt;데이터를&amp;nbsp;업데이트&amp;nbsp;할&amp;nbsp;때&amp;nbsp;어떤&amp;nbsp;변경을&amp;nbsp;할&amp;nbsp;것&amp;nbsp;인지를&amp;nbsp;남기는&amp;nbsp;로그이며,&amp;nbsp;PostgreSQL에서는&amp;nbsp;WAL(Write&amp;nbsp;Ahead&amp;nbsp;Log)이라&amp;nbsp;명칭합니다. &lt;br /&gt;Default&amp;nbsp;:&amp;nbsp;64KB &lt;br /&gt;트랜잭션&amp;nbsp;로그(WAL&amp;nbsp;log)&amp;nbsp;버퍼,&amp;nbsp;shared_buffers&amp;nbsp;의&amp;nbsp;1/32&amp;nbsp;권장 &lt;br /&gt;&lt;br /&gt;5)&amp;nbsp;max_wal_size &lt;br /&gt;WAL&amp;nbsp;조각&amp;nbsp;파일들은&amp;nbsp;더&amp;nbsp;이상&amp;nbsp;보관할&amp;nbsp;필요가&amp;nbsp;없어지면,&amp;nbsp;지워지는&amp;nbsp;것이&amp;nbsp;아니라,&amp;nbsp;앞으로&amp;nbsp;사용될&amp;nbsp;파일로&amp;nbsp;그&amp;nbsp;이름을&amp;nbsp;바뀝니다.&amp;nbsp;이&amp;nbsp;설정은&amp;nbsp;이렇게&amp;nbsp;남겨두는&amp;nbsp;WAL&amp;nbsp;최소값을&amp;nbsp;지정합니다. &lt;br /&gt;Default&amp;nbsp;:&amp;nbsp;80&amp;nbsp;MB &lt;br /&gt;산정&amp;nbsp;방법 &lt;br /&gt;OS&amp;nbsp;메모리의&amp;nbsp;1/2&amp;nbsp;또는&amp;nbsp;3/4&amp;nbsp;설정 &lt;br /&gt;&lt;br /&gt;6)&amp;nbsp;min_wal_size &lt;br /&gt;체크포인트&amp;nbsp;작업을&amp;nbsp;자동으로&amp;nbsp;진행할&amp;nbsp;WAL&amp;nbsp;최대&amp;nbsp;크기입니다. &lt;br /&gt;Default&amp;nbsp;:&amp;nbsp;1GB &lt;br /&gt;산정&amp;nbsp;방법 &lt;br /&gt;최소&amp;nbsp;1GB로&amp;nbsp;만들고&amp;nbsp;최대&amp;nbsp;수&amp;nbsp;GB를&amp;nbsp;50&amp;nbsp;-&amp;nbsp;100GB &lt;br /&gt;&lt;br /&gt;7)&amp;nbsp;random_page_cost &lt;br /&gt;비순차적으로&amp;nbsp;접근하는&amp;nbsp;디스크&amp;nbsp;페이지에&amp;nbsp;대한&amp;nbsp;계획&amp;nbsp;관리자의&amp;nbsp;예상&amp;nbsp;비용을&amp;nbsp;설정합니다. &lt;br /&gt;random&amp;nbsp;I/O&amp;nbsp;cost&amp;nbsp;추정값으로&amp;nbsp;높으면&amp;nbsp;풀스캔&amp;nbsp;선호,&amp;nbsp;상대적으로&amp;nbsp;줄이면&amp;nbsp;인덱스&amp;nbsp;스캔을&amp;nbsp;선호함 &lt;br /&gt;Default&amp;nbsp;:&amp;nbsp;4.0 &lt;br /&gt;&lt;br /&gt;8)&amp;nbsp;effective_cache_size &lt;br /&gt;단일&amp;nbsp;쿼리에&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;디스크&amp;nbsp;캐시의&amp;nbsp;효율적인&amp;nbsp;크기(캐시할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;메모리&amp;nbsp;양)에&amp;nbsp;대한&amp;nbsp;플래너의&amp;nbsp;가정을&amp;nbsp;설정합니다. &lt;br /&gt;이것은&amp;nbsp;인덱스를&amp;nbsp;사용하는&amp;nbsp;비용&amp;nbsp;추정에&amp;nbsp;반영됩니다.&amp;nbsp;값이&amp;nbsp;클수록&amp;nbsp;인덱스&amp;nbsp;스캔이&amp;nbsp;사용될&amp;nbsp;가능성이&amp;nbsp;높습니다. &lt;br /&gt;Default&amp;nbsp;:&amp;nbsp;4GB &lt;br /&gt;산정&amp;nbsp;방법 &lt;br /&gt;OS&amp;nbsp;메모리의&amp;nbsp;1/2&amp;nbsp;또는&amp;nbsp;3/4&amp;nbsp;설정 &lt;br /&gt;&lt;br /&gt;9)&amp;nbsp;autovacuum&amp;nbsp;설정 &lt;br /&gt;-&amp;nbsp;autovacuum_max_workers &lt;br /&gt;한&amp;nbsp;번에&amp;nbsp;실행할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;autovacuum&amp;nbsp;프로세스(autovacuum&amp;nbsp;제외)의&amp;nbsp;최대&amp;nbsp;수를&amp;nbsp;지정한다.&amp;nbsp; &lt;br /&gt;기본값은&amp;nbsp;3&amp;nbsp; &lt;br /&gt;&lt;br /&gt;-&amp;nbsp;autovacuum_vacuum_scale_factor,&amp;nbsp;autovacuum_analyze_scale_factor &lt;br /&gt;autovacuum_vacuum_scale_factor,&amp;nbsp;autovacuum_analyze_scale_factor&amp;nbsp;값&amp;nbsp;0&amp;nbsp;으로&amp;nbsp;설정 &lt;br /&gt;0&amp;nbsp;으로&amp;nbsp;설정해야&amp;nbsp;autovacuum_vacuum_threshold,&amp;nbsp;autovacuum_analyze_threshold&amp;nbsp;에&amp;nbsp;설정한&amp;nbsp;dead&amp;nbsp;tuple&amp;nbsp;수마다&amp;nbsp;autovacuum&amp;nbsp;이&amp;nbsp;동작함 &lt;br /&gt;&lt;br /&gt;-&amp;nbsp;autovacuum_vacuum_threshold,&amp;nbsp;autovacuum_analyze_threshold &lt;br /&gt;autovacuum_vacuum_threshold&amp;nbsp;=&amp;nbsp;100000 &lt;br /&gt;dead&amp;nbsp;tuple&amp;nbsp;이&amp;nbsp;10만개&amp;nbsp;생성될&amp;nbsp;때마다&amp;nbsp;autovacuum&amp;nbsp;이&amp;nbsp;동작함 &lt;br /&gt;&lt;br /&gt;-&amp;nbsp;vacuum_cost_limit &lt;br /&gt;vacuuming&amp;nbsp;프로세스를&amp;nbsp;슬립&amp;nbsp;시키는&amp;nbsp;누적&amp;nbsp;비용.&amp;nbsp;기본값은&amp;nbsp;200이다. &lt;br /&gt;autovacuum_vacuum_cost_limit&amp;nbsp;=&amp;nbsp;-1&amp;nbsp;일&amp;nbsp;경우&amp;nbsp;vacuum_cost_limit&amp;nbsp;값&amp;nbsp;참조&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;※ 실제 개발 서버에 적용한 설정파일입니다. 정답이 아니니 참고용으로만 활용하시길 바랍니다.&lt;br /&gt;-&amp;nbsp;개발서버&amp;nbsp;사양&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2.PNG&quot; data-origin-width=&quot;397&quot; data-origin-height=&quot;72&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ce3O53/btsihdOEeN3/OxmOa62a8Ui1KbQtNYFWXK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ce3O53/btsihdOEeN3/OxmOa62a8Ui1KbQtNYFWXK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ce3O53/btsihdOEeN3/OxmOa62a8Ui1KbQtNYFWXK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fce3O53%2FbtsihdOEeN3%2FOxmOa62a8Ui1KbQtNYFWXK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;397&quot; height=&quot;72&quot; data-filename=&quot;2.PNG&quot; data-origin-width=&quot;397&quot; data-origin-height=&quot;72&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/duyqh1/btsigEFq9ca/sg2PlkKEZ9FYM5ZGgUfNV1/postgresql.conf?attach=1&amp;amp;knm=tfile.conf&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;postgresql.conf&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.03MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>PostgresSQL</category>
      <category>PostgreSQL</category>
      <category>postgresql.conf</category>
      <category>성능개선</category>
      <author>박진만</author>
      <guid isPermaLink="true">https://jinmanp.tistory.com/58</guid>
      <comments>https://jinmanp.tistory.com/entry/%E3%84%B4#entry58comment</comments>
      <pubDate>Thu, 1 Jun 2023 14:04:18 +0900</pubDate>
    </item>
    <item>
      <title>linux (Ubuntu) 서버에서 postgresql 이 자동으로 재시작되는 이슈</title>
      <link>https://jinmanp.tistory.com/entry/linux-Ubuntu-%EC%84%9C%EB%B2%84%EC%97%90%EC%84%9C-postgresql-%EC%9D%B4-%EC%9E%90%EB%8F%99%EC%9C%BC%EB%A1%9C-%EC%9E%AC%EC%8B%9C%EC%9E%91%EB%90%98%EB%8A%94-%EC%9D%B4%EC%8A%88</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;※ 서버 및 DB 정보&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Ubuntu&amp;nbsp;20.04.5&amp;nbsp;LTS &lt;br /&gt;PostgreSQL&amp;nbsp;12&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;※ DB 모니터링 중 특정 시간에 DB가 종료되었다가 다시 시작되는 이슈를 발견하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;에러&amp;nbsp;로그&amp;nbsp;확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로그 파일 경로 확인 &lt;br /&gt;show&amp;nbsp;log_directory;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;264&quot; data-origin-height=&quot;247&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZPnsp/btshrdOJlVX/71f0i5MFiDDoulp9ulc9ZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZPnsp/btshrdOJlVX/71f0i5MFiDDoulp9ulc9ZK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZPnsp/btshrdOJlVX/71f0i5MFiDDoulp9ulc9ZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZPnsp%2FbtshrdOJlVX%2F71f0i5MFiDDoulp9ulc9ZK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;264&quot; height=&quot;247&quot; data-origin-width=&quot;264&quot; data-origin-height=&quot;247&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로그 파일 내용 확인 &lt;br /&gt;cd&amp;nbsp;/data/postgresql/log &lt;br /&gt;cat&amp;nbsp;postgresql-2023-05-25_000000.log&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1649&quot; data-origin-height=&quot;578&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/D1uuX/btshrv2QlUK/e2blKh04l32bgs6XHI5Y2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/D1uuX/btshrv2QlUK/e2blKh04l32bgs6XHI5Y2k/img.png&quot; data-alt=&quot;2023-05-25 06시 58분 24초에 DB shutdown&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/D1uuX/btshrv2QlUK/e2blKh04l32bgs6XHI5Y2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FD1uuX%2Fbtshrv2QlUK%2Fe2blKh04l32bgs6XHI5Y2k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1649&quot; height=&quot;578&quot; data-origin-width=&quot;1649&quot; data-origin-height=&quot;578&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;2023-05-25 06시 58분 24초에 DB shutdown&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;DB&amp;nbsp;로그&amp;nbsp;확인 &lt;br /&gt;cd&amp;nbsp;/var/log/postgresql &lt;br /&gt;cat&amp;nbsp;postgresql-12-main.log&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1831&quot; data-origin-height=&quot;200&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dbExFj/btshqLdRX65/acxXT6W7HFGmMsxcKmacp0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dbExFj/btshqLdRX65/acxXT6W7HFGmMsxcKmacp0/img.png&quot; data-alt=&quot;2023-05-25 06시 58분 29초에 DB start&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dbExFj/btshqLdRX65/acxXT6W7HFGmMsxcKmacp0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdbExFj%2FbtshqLdRX65%2FacxXT6W7HFGmMsxcKmacp0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1831&quot; height=&quot;200&quot; data-origin-width=&quot;1831&quot; data-origin-height=&quot;200&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;2023-05-25 06시 58분 29초에 DB start&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;※ 의심이 가는 부분을 하나씩 확인해보았다.&amp;nbsp; &lt;br /&gt;1.&amp;nbsp;서버&amp;nbsp;재기동 &lt;br /&gt;last&amp;nbsp;reboot&amp;nbsp;명령어로&amp;nbsp;서버&amp;nbsp;재기동&amp;nbsp;이력&amp;nbsp;확인&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;955&quot; data-origin-height=&quot;455&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cl3hyx/btshp63Veos/MCFXXLNbVU91cCWp2A4oYK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cl3hyx/btshp63Veos/MCFXXLNbVU91cCWp2A4oYK/img.png&quot; data-alt=&quot;5월 10일 15시55분에 기동 후 재기동 이력 없음&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cl3hyx/btshp63Veos/MCFXXLNbVU91cCWp2A4oYK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcl3hyx%2Fbtshp63Veos%2FMCFXXLNbVU91cCWp2A4oYK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;955&quot; height=&quot;455&quot; data-origin-width=&quot;955&quot; data-origin-height=&quot;455&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;5월 10일 15시55분에 기동 후 재기동 이력 없음&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2.&amp;nbsp;사용자가&amp;nbsp;직접&amp;nbsp;DB&amp;nbsp;중지&amp;nbsp;후&amp;nbsp;재기동 &lt;br /&gt;history&amp;nbsp;명령어로&amp;nbsp;사용자가&amp;nbsp;실행한&amp;nbsp;명령어&amp;nbsp;이력&amp;nbsp;확인 &lt;br /&gt;&amp;rarr; DB 재기동 관련된 명령어가 실행된 흔적은 없었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3.&amp;nbsp;자동&amp;nbsp;업데이트 &lt;br /&gt;서버&amp;nbsp;또는&amp;nbsp;PostgreSQL&amp;nbsp;패키지&amp;nbsp;자동&amp;nbsp;업데이트&amp;nbsp;과정에서&amp;nbsp;종종&amp;nbsp;서비스가&amp;nbsp;자동&amp;nbsp;재시작&amp;nbsp;된다고&amp;nbsp;함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;업데이트&amp;nbsp;기록&amp;nbsp;확인 &lt;br /&gt;cd&amp;nbsp;/var/log/unattended-upgrades &lt;br /&gt;cat&amp;nbsp;unattended-upgrades.log&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1824&quot; data-origin-height=&quot;154&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MaF5W/btshlYrTJyO/kMeaMzGuTp7dDGQoJGCadK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MaF5W/btshlYrTJyO/kMeaMzGuTp7dDGQoJGCadK/img.png&quot; data-alt=&quot;2023-05-25 06시 58분 01초 업데이트 기록 있음&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MaF5W/btshlYrTJyO/kMeaMzGuTp7dDGQoJGCadK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMaF5W%2FbtshlYrTJyO%2FkMeaMzGuTp7dDGQoJGCadK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1824&quot; height=&quot;154&quot; data-origin-width=&quot;1824&quot; data-origin-height=&quot;154&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;2023-05-25 06시 58분 01초 업데이트 기록 있음&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;cat&amp;nbsp;unattended-upgrades-dpkg.log&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1041&quot; data-origin-height=&quot;323&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bRsnpk/btshj4F9txq/NXygkc3uDnaElQwnGZrLC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bRsnpk/btshj4F9txq/NXygkc3uDnaElQwnGZrLC1/img.png&quot; data-alt=&quot;2023-05-25 06시 58분 18초 postgresql 업데이트 기록 있음&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bRsnpk/btshj4F9txq/NXygkc3uDnaElQwnGZrLC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRsnpk%2Fbtshj4F9txq%2FNXygkc3uDnaElQwnGZrLC1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1041&quot; height=&quot;323&quot; data-origin-width=&quot;1041&quot; data-origin-height=&quot;323&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;2023-05-25 06시 58분 18초 postgresql 업데이트 기록 있음&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;※ 원인은 3번 자동 업데이트 때문이었다.&amp;nbsp; &lt;br /&gt;의도치&amp;nbsp;않은&amp;nbsp;시간에&amp;nbsp;DB&amp;nbsp;재기동이&amp;nbsp;되는&amp;nbsp;것을&amp;nbsp;방지하기&amp;nbsp;위해&amp;nbsp;자동&amp;nbsp;업데이트&amp;nbsp;설정을&amp;nbsp;비활성화&amp;nbsp;해주기로&amp;nbsp;하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;Ubuntu&amp;nbsp;자동&amp;nbsp;업데이트&amp;nbsp;비활성화&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1.&amp;nbsp;설정&amp;nbsp;파일&amp;nbsp;있는&amp;nbsp;디렉토리로&amp;nbsp;이동 &lt;br /&gt;cd&amp;nbsp;/etc/apt/apt.conf.d&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;538&quot; data-origin-height=&quot;304&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cvbSoe/btshp6QqKof/jSPwMqHvlGAKt6EOt2Auq0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cvbSoe/btshp6QqKof/jSPwMqHvlGAKt6EOt2Auq0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cvbSoe/btshp6QqKof/jSPwMqHvlGAKt6EOt2Auq0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcvbSoe%2Fbtshp6QqKof%2FjSPwMqHvlGAKt6EOt2Auq0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;538&quot; height=&quot;304&quot; data-origin-width=&quot;538&quot; data-origin-height=&quot;304&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2.&amp;nbsp;10periodic&amp;nbsp;파일&amp;nbsp;수정&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;578&quot; data-origin-height=&quot;271&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2Pq7J/btshqkufKYp/9n1COEUXQJoiI3AM3aejJK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2Pq7J/btshqkufKYp/9n1COEUXQJoiI3AM3aejJK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2Pq7J/btshqkufKYp/9n1COEUXQJoiI3AM3aejJK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2Pq7J%2FbtshqkufKYp%2F9n1COEUXQJoiI3AM3aejJK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;578&quot; height=&quot;271&quot; data-origin-width=&quot;578&quot; data-origin-height=&quot;271&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3.&amp;nbsp;20auto-upgrades파일&amp;nbsp;수정&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;486&quot; data-origin-height=&quot;195&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vq4Th/btshqknt86H/OntepJ4yOQ6wkqK5EvTL50/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vq4Th/btshqknt86H/OntepJ4yOQ6wkqK5EvTL50/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vq4Th/btshqknt86H/OntepJ4yOQ6wkqK5EvTL50/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fvq4Th%2Fbtshqknt86H%2FOntepJ4yOQ6wkqK5EvTL50%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;486&quot; height=&quot;195&quot; data-origin-width=&quot;486&quot; data-origin-height=&quot;195&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>PostgresSQL</category>
      <category>linux</category>
      <category>PostgreSQL</category>
      <category>reboot</category>
      <category>ubuntu</category>
      <category>자동 업데이트</category>
      <category>재기동</category>
      <author>박진만</author>
      <guid isPermaLink="true">https://jinmanp.tistory.com/57</guid>
      <comments>https://jinmanp.tistory.com/entry/linux-Ubuntu-%EC%84%9C%EB%B2%84%EC%97%90%EC%84%9C-postgresql-%EC%9D%B4-%EC%9E%90%EB%8F%99%EC%9C%BC%EB%A1%9C-%EC%9E%AC%EC%8B%9C%EC%9E%91%EB%90%98%EB%8A%94-%EC%9D%B4%EC%8A%88#entry57comment</comments>
      <pubDate>Thu, 25 May 2023 16:40:57 +0900</pubDate>
    </item>
    <item>
      <title>git repository file history 전부 삭제</title>
      <link>https://jinmanp.tistory.com/entry/git-repository-file-history-%EC%A0%84%EB%B6%80-%EC%82%AD%EC%A0%9C</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;개인 프로젝트 소스를 private repository 에 중요한 데이터까지 전부 push 해서 관리 중입니다.&amp;nbsp;요즘은 개발자 입사 지원 시 git 에 포트폴리오 소스코드를 공개하는 것 같아서 방법을 고민해 보았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. private repository &amp;rarr; public repository &lt;br /&gt;가장&amp;nbsp;간편한&amp;nbsp;방법.&amp;nbsp; &lt;br /&gt;&amp;rarr; 중요 소스코드들이 포함되어 있기 때문에 이 방법은 배제하였습니다. &lt;br /&gt;&lt;br /&gt;2. git Submodule &lt;br /&gt;git 레포지토리 하위에 다른 저장소를 관리하기 위한 도구&amp;nbsp; &lt;br /&gt;상위&amp;nbsp;repository&amp;nbsp;는&amp;nbsp;슈퍼&amp;nbsp;프로젝트(superproject),&amp;nbsp;하위&amp;nbsp;repository&amp;nbsp;는&amp;nbsp;서브&amp;nbsp;모듈(submodule) &lt;br /&gt;서브모듈을 사용하면 특정한 git 레포지토리를 다른 레포지토리의 하위 디렉토리로 사용할 수 있다. &lt;br /&gt;&amp;rarr; 상위 repository public, 하위 repository private 으로 관리 &lt;br /&gt;여러명이&amp;nbsp;같이&amp;nbsp;사용하는&amp;nbsp;repository&amp;nbsp;라면&amp;nbsp;적용하기&amp;nbsp;괜찮아&amp;nbsp;보임 &lt;br /&gt;각각의&amp;nbsp;repository&amp;nbsp;가&amp;nbsp;따로&amp;nbsp;관리되기&amp;nbsp;때문에&amp;nbsp;서브&amp;nbsp;모듈(submodule)&amp;nbsp;쪽&amp;nbsp;소스가&amp;nbsp;수정되었을&amp;nbsp;경우&amp;nbsp;관리하기&amp;nbsp;까다로움 &lt;br /&gt;그러나&amp;nbsp;저는&amp;nbsp;개인&amp;nbsp;프로젝트를&amp;nbsp;혼자&amp;nbsp;개발하기&amp;nbsp;때문에&amp;nbsp;편하게&amp;nbsp;내가&amp;nbsp;수정한&amp;nbsp;소스&amp;nbsp;push&amp;nbsp;하고&amp;nbsp;싶어서&amp;nbsp;이&amp;nbsp;방법은&amp;nbsp;배제하였습니다. &lt;br /&gt;&lt;br /&gt;3. 공개용 git 계정 생성 &amp;rarr; repository import &amp;rarr; 중요 소스코드 file 및 history 를 전부 삭제 &lt;br /&gt;기존&amp;nbsp;git&amp;nbsp;계정은&amp;nbsp;개발용도로&amp;nbsp;편하게&amp;nbsp;사용하고&amp;nbsp;공개용으로&amp;nbsp;계정을&amp;nbsp;새로&amp;nbsp;생성해서&amp;nbsp;기존&amp;nbsp;계정의&amp;nbsp;repository&amp;nbsp;를&amp;nbsp;import&amp;nbsp;하고&amp;nbsp;중요&amp;nbsp;소스코드&amp;nbsp;file&amp;nbsp;및&amp;nbsp;history&amp;nbsp;를&amp;nbsp;전부&amp;nbsp;삭제하는&amp;nbsp;방법 &lt;br /&gt;&amp;rarr; 저한테 가장 알맞은 방법이라고 생각해서 이 방법을 선택했습니다.&amp;nbsp; &lt;br /&gt;공개용&amp;nbsp;계정에&amp;nbsp;import&amp;nbsp;한&amp;nbsp;시점&amp;nbsp;이후&amp;nbsp;변경된&amp;nbsp;소스는&amp;nbsp;반영이&amp;nbsp;되지&amp;nbsp;않는&amp;nbsp;단점이&amp;nbsp;있지만&amp;nbsp;저는&amp;nbsp;공개보다는&amp;nbsp;편하게&amp;nbsp;개발&amp;nbsp;관리하는게&amp;nbsp;우선이기&amp;nbsp;때문에&amp;nbsp;필요할&amp;nbsp;때&amp;nbsp;공개용&amp;nbsp;계정에&amp;nbsp;새로&amp;nbsp;import&amp;nbsp;한다는&amp;nbsp;생각으로&amp;nbsp;관리하기로&amp;nbsp;했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;※ 3번 방법을 windows 환경, gitlab.com 기준으로 진행하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;Python&amp;nbsp;설치&amp;nbsp;(이미&amp;nbsp;설치되어&amp;nbsp;있으면&amp;nbsp;Skip) &lt;br /&gt;1.&amp;nbsp;Python&amp;nbsp;최신&amp;nbsp;버전&amp;nbsp;다운로드&amp;nbsp;후&amp;nbsp;설치 &lt;br /&gt;&lt;a href=&quot;https://www.python.org/downloads/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.python.org/downloads/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;2.&amp;nbsp;환경변수&amp;nbsp;설정&amp;nbsp;후&amp;nbsp;콘솔에서&amp;nbsp;버전&amp;nbsp;확인 &lt;br /&gt;python&amp;nbsp;--version&amp;nbsp;또는&amp;nbsp;python3&amp;nbsp;--version&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;307&quot; data-origin-height=&quot;74&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d88YXW/btsgE6RLWyS/Bszc4SiDGGpItzmcAbJEz0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d88YXW/btsgE6RLWyS/Bszc4SiDGGpItzmcAbJEz0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d88YXW/btsgE6RLWyS/Bszc4SiDGGpItzmcAbJEz0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd88YXW%2FbtsgE6RLWyS%2FBszc4SiDGGpItzmcAbJEz0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;307&quot; height=&quot;74&quot; data-origin-width=&quot;307&quot; data-origin-height=&quot;74&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;-&amp;nbsp;git-filter-repo&amp;nbsp;설치 &lt;br /&gt;1.&amp;nbsp;GitHub에서&amp;nbsp;git-filter-repo&amp;nbsp;복제&lt;/p&gt;
&lt;pre id=&quot;code_1684681440446&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git clone https://github.com/newren/git-filter-repo.git&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;940&quot; data-origin-height=&quot;216&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/chBsZq/btsgUr7OLrG/smd3EBPldsDgxt5YK7r3g1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/chBsZq/btsgUr7OLrG/smd3EBPldsDgxt5YK7r3g1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/chBsZq/btsgUr7OLrG/smd3EBPldsDgxt5YK7r3g1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FchBsZq%2FbtsgUr7OLrG%2Fsmd3EBPldsDgxt5YK7r3g1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;940&quot; height=&quot;216&quot; data-origin-width=&quot;940&quot; data-origin-height=&quot;216&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;2.&amp;nbsp;git&amp;nbsp;--exec-path&amp;nbsp;실행하여&amp;nbsp;Git&amp;nbsp;디렉터리&amp;nbsp;확인&lt;/p&gt;
&lt;pre id=&quot;code_1684681428022&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git --exec-path&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;577&quot; data-origin-height=&quot;67&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/thN4a/btsgG6jplCS/yY8MHfVIBhVCQwixA6h1bK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/thN4a/btsgG6jplCS/yY8MHfVIBhVCQwixA6h1bK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/thN4a/btsgG6jplCS/yY8MHfVIBhVCQwixA6h1bK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FthN4a%2FbtsgG6jplCS%2FyY8MHfVIBhVCQwixA6h1bK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;577&quot; height=&quot;67&quot; data-origin-width=&quot;577&quot; data-origin-height=&quot;67&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;3.&amp;nbsp;git-filter-repo&amp;nbsp;파일을&amp;nbsp;Git&amp;nbsp;디렉터리로&amp;nbsp;복사&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1791&quot; data-origin-height=&quot;638&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lcBQF/btsgDMzidB3/BigZ6Rhdt82ERzotKOgHb0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lcBQF/btsgDMzidB3/BigZ6Rhdt82ERzotKOgHb0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lcBQF/btsgDMzidB3/BigZ6Rhdt82ERzotKOgHb0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlcBQF%2FbtsgDMzidB3%2FBigZ6Rhdt82ERzotKOgHb0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1791&quot; height=&quot;638&quot; data-origin-width=&quot;1791&quot; data-origin-height=&quot;638&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;4.&amp;nbsp;git&amp;nbsp;filter-repo&amp;nbsp;실행&amp;nbsp;-&amp;gt;&amp;nbsp;No&amp;nbsp;arguments&amp;nbsp;specified.&amp;nbsp;문구&amp;nbsp;나오면&amp;nbsp;정상&lt;/p&gt;
&lt;pre id=&quot;code_1684681415118&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git filter-repo&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;291&quot; data-origin-height=&quot;59&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sCHsp/btsgMbEvr06/zEupYn4ZLywy9AD7KZVrsK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sCHsp/btsgMbEvr06/zEupYn4ZLywy9AD7KZVrsK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sCHsp/btsgMbEvr06/zEupYn4ZLywy9AD7KZVrsK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsCHsp%2FbtsgMbEvr06%2FzEupYn4ZLywy9AD7KZVrsK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;291&quot; height=&quot;59&quot; data-origin-width=&quot;291&quot; data-origin-height=&quot;59&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;*&amp;nbsp;정상&amp;nbsp;문구&amp;nbsp;안나올&amp;nbsp;경우&amp;nbsp;-&amp;gt;&amp;nbsp;git-filter-repo&amp;nbsp;열기&amp;nbsp;-&amp;gt;&amp;nbsp;python3&amp;nbsp;를&amp;nbsp;python&amp;nbsp;으로&amp;nbsp;수정&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;286&quot; data-origin-height=&quot;59&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bym1uA/btsgEgN6Trc/wFCQdr8G4wHk4TEVlcmRpK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bym1uA/btsgEgN6Trc/wFCQdr8G4wHk4TEVlcmRpK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bym1uA/btsgEgN6Trc/wFCQdr8G4wHk4TEVlcmRpK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbym1uA%2FbtsgEgN6Trc%2FwFCQdr8G4wHk4TEVlcmRpK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;286&quot; height=&quot;59&quot; data-origin-width=&quot;286&quot; data-origin-height=&quot;59&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;883&quot; data-origin-height=&quot;226&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WyCx9/btsgUr03cY5/vXvy3O6bTwK9yxsKkHFOp1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WyCx9/btsgUr03cY5/vXvy3O6bTwK9yxsKkHFOp1/img.png&quot; data-alt=&quot;수정 전&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WyCx9/btsgUr03cY5/vXvy3O6bTwK9yxsKkHFOp1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWyCx9%2FbtsgUr03cY5%2FvXvy3O6bTwK9yxsKkHFOp1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;883&quot; height=&quot;226&quot; data-origin-width=&quot;883&quot; data-origin-height=&quot;226&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;수정 전&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;875&quot; data-origin-height=&quot;223&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IdvgB/btsgDJbxNab/kUgzxkgt67OJICqqR1fiBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IdvgB/btsgDJbxNab/kUgzxkgt67OJICqqR1fiBk/img.png&quot; data-alt=&quot;수정 후&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IdvgB/btsgDJbxNab/kUgzxkgt67OJICqqR1fiBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIdvgB%2FbtsgDJbxNab%2FkUgzxkgt67OJICqqR1fiBk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;875&quot; height=&quot;223&quot; data-origin-width=&quot;875&quot; data-origin-height=&quot;223&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;수정 후&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;291&quot; data-origin-height=&quot;59&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sCHsp/btsgMbEvr06/zEupYn4ZLywy9AD7KZVrsK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sCHsp/btsgMbEvr06/zEupYn4ZLywy9AD7KZVrsK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sCHsp/btsgMbEvr06/zEupYn4ZLywy9AD7KZVrsK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsCHsp%2FbtsgMbEvr06%2FzEupYn4ZLywy9AD7KZVrsK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;291&quot; height=&quot;59&quot; data-origin-width=&quot;291&quot; data-origin-height=&quot;59&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;-&amp;nbsp;공개용&amp;nbsp;계정으로&amp;nbsp;gitlab.com&amp;nbsp;로그인&amp;nbsp;-&amp;gt;&amp;nbsp;Projects&amp;nbsp;메뉴&amp;nbsp;-&amp;gt;&amp;nbsp;new&amp;nbsp;project&amp;nbsp;버튼&amp;nbsp;클릭&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1942&quot; data-origin-height=&quot;393&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5q9fi/btsgTiJQ5Mv/1BprYxgBf5GMnGuUcG9Pa0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5q9fi/btsgTiJQ5Mv/1BprYxgBf5GMnGuUcG9Pa0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5q9fi/btsgTiJQ5Mv/1BprYxgBf5GMnGuUcG9Pa0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5q9fi%2FbtsgTiJQ5Mv%2F1BprYxgBf5GMnGuUcG9Pa0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1942&quot; height=&quot;393&quot; data-origin-width=&quot;1942&quot; data-origin-height=&quot;393&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- import project 클릭&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1858&quot; data-origin-height=&quot;1125&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bRY22H/btsgQqnPgpd/pStJeM89PQR6oKXQoZXO5K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bRY22H/btsgQqnPgpd/pStJeM89PQR6oKXQoZXO5K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bRY22H/btsgQqnPgpd/pStJeM89PQR6oKXQoZXO5K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRY22H%2FbtsgQqnPgpd%2FpStJeM89PQR6oKXQoZXO5K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1858&quot; height=&quot;1125&quot; data-origin-width=&quot;1858&quot; data-origin-height=&quot;1125&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;repository&amp;nbsp;by&amp;nbsp;URL&amp;nbsp;클릭&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1940&quot; data-origin-height=&quot;665&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cxm4Ro/btsgJ0iWA4G/G0X7N9dyJtOjSJ7HCNnkm1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cxm4Ro/btsgJ0iWA4G/G0X7N9dyJtOjSJ7HCNnkm1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cxm4Ro/btsgJ0iWA4G/G0X7N9dyJtOjSJ7HCNnkm1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcxm4Ro%2FbtsgJ0iWA4G%2FG0X7N9dyJtOjSJ7HCNnkm1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1940&quot; height=&quot;665&quot; data-origin-width=&quot;1940&quot; data-origin-height=&quot;665&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;import&amp;nbsp;할&amp;nbsp;git&amp;nbsp;url,&amp;nbsp;계정,&amp;nbsp;비번&amp;nbsp;등&amp;nbsp;필요한&amp;nbsp;항목&amp;nbsp;입력&amp;nbsp;후&amp;nbsp;Create&amp;nbsp;project&amp;nbsp;버튼&amp;nbsp;클릭&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1502&quot; data-origin-height=&quot;1125&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oq5GI/btsgGi43fsc/KwRxQJzs9VKFCwHCdThwx0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oq5GI/btsgGi43fsc/KwRxQJzs9VKFCwHCdThwx0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oq5GI/btsgGi43fsc/KwRxQJzs9VKFCwHCdThwx0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Foq5GI%2FbtsgGi43fsc%2FKwRxQJzs9VKFCwHCdThwx0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1502&quot; height=&quot;1125&quot; data-origin-width=&quot;1502&quot; data-origin-height=&quot;1125&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;cmd&amp;nbsp;실행&amp;nbsp;후&amp;nbsp;clone&amp;nbsp;할&amp;nbsp;경로&amp;nbsp;이동&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;595&quot; data-origin-height=&quot;210&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/br7g6t/btsgQqOTtwn/7cpm2ivkAOkXoeAy9HO0RK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/br7g6t/btsgQqOTtwn/7cpm2ivkAOkXoeAy9HO0RK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/br7g6t/btsgQqOTtwn/7cpm2ivkAOkXoeAy9HO0RK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbr7g6t%2FbtsgQqOTtwn%2F7cpm2ivkAOkXoeAy9HO0RK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;595&quot; height=&quot;210&quot; data-origin-width=&quot;595&quot; data-origin-height=&quot;210&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;clone&lt;/p&gt;
&lt;pre id=&quot;code_1684681369881&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git clone https://gitlab.com/jinmanp/manman_frontend.git&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;878&quot; data-origin-height=&quot;223&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dpBZ5X/btsgMccleij/P2Xgby1UFlyMGfxjKWShgk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dpBZ5X/btsgMccleij/P2Xgby1UFlyMGfxjKWShgk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dpBZ5X/btsgMccleij/P2Xgby1UFlyMGfxjKWShgk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdpBZ5X%2FbtsgMccleij%2FP2Xgby1UFlyMGfxjKWShgk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;878&quot; height=&quot;223&quot; data-origin-width=&quot;878&quot; data-origin-height=&quot;223&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;filter-repo&amp;nbsp;로&amp;nbsp;repository&amp;nbsp;file&amp;nbsp;history&amp;nbsp;전부&amp;nbsp;삭제 &lt;br /&gt;1.&amp;nbsp;해당&amp;nbsp;repository&amp;nbsp;최상위&amp;nbsp;폴더로&amp;nbsp;이동&lt;/p&gt;
&lt;pre id=&quot;code_1684681357325&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cd manman_frontend&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;325&quot; data-origin-height=&quot;49&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xVetP/btsgFdXcfBA/J4YT3jPSEc18Ok7geBKjf1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xVetP/btsgFdXcfBA/J4YT3jPSEc18Ok7geBKjf1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xVetP/btsgFdXcfBA/J4YT3jPSEc18Ok7geBKjf1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxVetP%2FbtsgFdXcfBA%2FJ4YT3jPSEc18Ok7geBKjf1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;325&quot; height=&quot;49&quot; data-origin-width=&quot;325&quot; data-origin-height=&quot;49&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2.&amp;nbsp;삭제&amp;nbsp;명령&amp;nbsp;실행&lt;/p&gt;
&lt;pre id=&quot;code_1684681349824&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git filter-repo --force --invert-paths --path 삭제하고 싶은 폴더 및 파일&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1684681339209&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git filter-repo --force --invert-paths --path src/main/resources&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1100&quot; data-origin-height=&quot;317&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/neSRg/btsgEazXsYY/XotWrrv6m8fcOdRb6xAmkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/neSRg/btsgEazXsYY/XotWrrv6m8fcOdRb6xAmkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/neSRg/btsgEazXsYY/XotWrrv6m8fcOdRb6xAmkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FneSRg%2FbtsgEazXsYY%2FXotWrrv6m8fcOdRb6xAmkK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1100&quot; height=&quot;317&quot; data-origin-width=&quot;1100&quot; data-origin-height=&quot;317&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3.&amp;nbsp;repository&amp;nbsp;재연결 &lt;br /&gt;삭제 명령을 실행하면 repository 연결이 끊어진다. repository&amp;nbsp;다시&amp;nbsp;연결&lt;/p&gt;
&lt;pre id=&quot;code_1684681305763&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git remote add [remote name] [git URL]&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1684681318635&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git remote add origin https://gitlab.com/jinmanp/manman_frontend.git&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1150&quot; data-origin-height=&quot;49&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bTZEzA/btsgUslmZWM/H6JK1m6iLBlasQBcBan2Xk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bTZEzA/btsgUslmZWM/H6JK1m6iLBlasQBcBan2Xk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bTZEzA/btsgUslmZWM/H6JK1m6iLBlasQBcBan2Xk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbTZEzA%2FbtsgUslmZWM%2FH6JK1m6iLBlasQBcBan2Xk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1150&quot; height=&quot;49&quot; data-origin-width=&quot;1150&quot; data-origin-height=&quot;49&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4.&amp;nbsp;repository&amp;nbsp;push&lt;/p&gt;
&lt;pre id=&quot;code_1684681241400&quot; class=&quot;applescript&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git push [remote name] --force --all&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1684681264195&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git push origin --force --all&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;662&quot; data-origin-height=&quot;66&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RWjnZ/btsgTjosAPp/mkVWckr1ROoATJPlbgY621/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RWjnZ/btsgTjosAPp/mkVWckr1ROoATJPlbgY621/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RWjnZ/btsgTjosAPp/mkVWckr1ROoATJPlbgY621/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRWjnZ%2FbtsgTjosAPp%2FmkVWckr1ROoATJPlbgY621%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;662&quot; height=&quot;66&quot; data-origin-width=&quot;662&quot; data-origin-height=&quot;66&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5.&amp;nbsp;삭제&amp;nbsp;전&amp;nbsp;삭제&amp;nbsp;후&amp;nbsp;repository&amp;nbsp;비교&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1526&quot; data-origin-height=&quot;671&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uyHFm/btsgDNrTfIK/2lKJxAJB6zkHLW86syzeK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uyHFm/btsgDNrTfIK/2lKJxAJB6zkHLW86syzeK1/img.png&quot; data-alt=&quot;삭제 전&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uyHFm/btsgDNrTfIK/2lKJxAJB6zkHLW86syzeK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuyHFm%2FbtsgDNrTfIK%2F2lKJxAJB6zkHLW86syzeK1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1526&quot; height=&quot;671&quot; data-origin-width=&quot;1526&quot; data-origin-height=&quot;671&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;삭제 전&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1540&quot; data-origin-height=&quot;613&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dQxMKj/btsgEDI6hAx/Fw0LwHNsk3OEQOsUqm0P0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dQxMKj/btsgEDI6hAx/Fw0LwHNsk3OEQOsUqm0P0k/img.png&quot; data-alt=&quot;삭제 후&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dQxMKj/btsgEDI6hAx/Fw0LwHNsk3OEQOsUqm0P0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdQxMKj%2FbtsgEDI6hAx%2FFw0LwHNsk3OEQOsUqm0P0k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1540&quot; height=&quot;613&quot; data-origin-width=&quot;1540&quot; data-origin-height=&quot;613&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;삭제 후&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;※&amp;nbsp;pre-receive&amp;nbsp;hook&amp;nbsp;declined&amp;nbsp;오류&amp;nbsp;발생&amp;nbsp;시 &lt;br /&gt;※&amp;nbsp;remote:&amp;nbsp;You&amp;nbsp;are&amp;nbsp;not&amp;nbsp;allowed&amp;nbsp;to&amp;nbsp;push&amp;nbsp;code&amp;nbsp;to&amp;nbsp;this&amp;nbsp;project.&amp;nbsp;오류&amp;nbsp;발생&amp;nbsp;시 &lt;br /&gt;Protected&amp;nbsp;branches&amp;nbsp;설정&amp;nbsp;해제&amp;nbsp;또는&amp;nbsp;Allowed&amp;nbsp;to&amp;nbsp;force&amp;nbsp;push&amp;nbsp;허용&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1552&quot; data-origin-height=&quot;1125&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xKZny/btsgJZ5otKM/NBO1K6fECBpUTRAIKj0By0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xKZny/btsgJZ5otKM/NBO1K6fECBpUTRAIKj0By0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xKZny/btsgJZ5otKM/NBO1K6fECBpUTRAIKj0By0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxKZny%2FbtsgJZ5otKM%2FNBO1K6fECBpUTRAIKj0By0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1552&quot; height=&quot;1125&quot; data-origin-width=&quot;1552&quot; data-origin-height=&quot;1125&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>tech</category>
      <category>GIT</category>
      <category>history delete</category>
      <category>pre-receive hook declined</category>
      <category>remote: You are not allowed to push code to this project</category>
      <author>박진만</author>
      <guid isPermaLink="true">https://jinmanp.tistory.com/56</guid>
      <comments>https://jinmanp.tistory.com/entry/git-repository-file-history-%EC%A0%84%EB%B6%80-%EC%82%AD%EC%A0%9C#entry56comment</comments>
      <pubDate>Mon, 22 May 2023 00:04:21 +0900</pubDate>
    </item>
    <item>
      <title>[Android] https 요청 시 ssl 인증서 오류</title>
      <link>https://jinmanp.tistory.com/entry/Android-https-%EC%9A%94%EC%B2%AD-%EC%8B%9C-ssl-%EC%9D%B8%EC%A6%9D%EC%84%9C-%EC%98%A4%EB%A5%98</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;http&amp;nbsp;요청은&amp;nbsp;잘&amp;nbsp;되는데&amp;nbsp;https&amp;nbsp;요청&amp;nbsp;시&amp;nbsp;아래&amp;nbsp;오류&amp;nbsp;발생&lt;/p&gt;
&lt;pre id=&quot;code_1679993450205&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException:Trust anchor for certification path not found&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;원인 : Connection 하는 웹사이트의 Certificate 인증서가 안드로이드 단말에 존재하지 않을 경우 발생 &lt;br /&gt;&lt;br /&gt;해결방법 &lt;br /&gt;&lt;br /&gt;1.&amp;nbsp;요청하고자&amp;nbsp;하는&amp;nbsp;웹사이트의&amp;nbsp;인증서&amp;nbsp;확인&amp;nbsp;후&amp;nbsp;다운로드 &lt;br /&gt;&amp;nbsp;-&amp;nbsp;브라우저&amp;nbsp;주소창에&amp;nbsp;자물쇠&amp;nbsp;클릭&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;719&quot; data-origin-height=&quot;328&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbMvUV/btr6Agb5b6m/M5yINkQxOw7CwuBL0v2Cpk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbMvUV/btr6Agb5b6m/M5yINkQxOw7CwuBL0v2Cpk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbMvUV/btr6Agb5b6m/M5yINkQxOw7CwuBL0v2Cpk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbMvUV%2Fbtr6Agb5b6m%2FM5yINkQxOw7CwuBL0v2Cpk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;719&quot; height=&quot;328&quot; data-origin-width=&quot;719&quot; data-origin-height=&quot;328&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&amp;nbsp;-&amp;nbsp;인증서&amp;nbsp;정보&amp;nbsp;클릭&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;727&quot; data-origin-height=&quot;401&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c6pwYG/btr6pGW2vfa/yIroH7wn9G850BWoSedkz1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c6pwYG/btr6pGW2vfa/yIroH7wn9G850BWoSedkz1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c6pwYG/btr6pGW2vfa/yIroH7wn9G850BWoSedkz1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc6pwYG%2Fbtr6pGW2vfa%2FyIroH7wn9G850BWoSedkz1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;727&quot; height=&quot;401&quot; data-origin-width=&quot;727&quot; data-origin-height=&quot;401&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&amp;nbsp;-&amp;nbsp;세부정보&amp;nbsp;탭&amp;nbsp;선택&amp;nbsp;후&amp;nbsp;내보내기&amp;nbsp;버튼&amp;nbsp;클릭&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1471&quot; data-origin-height=&quot;1098&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pU7Hr/btr6BCeoulH/Zft2oKqtOk3H9vxXZFqJT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pU7Hr/btr6BCeoulH/Zft2oKqtOk3H9vxXZFqJT1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pU7Hr/btr6BCeoulH/Zft2oKqtOk3H9vxXZFqJT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpU7Hr%2Fbtr6BCeoulH%2FZft2oKqtOk3H9vxXZFqJT1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1471&quot; height=&quot;1098&quot; data-origin-width=&quot;1471&quot; data-origin-height=&quot;1098&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;2.&amp;nbsp;프로젝트에&amp;nbsp;인증서&amp;nbsp;복사 &lt;br /&gt;&amp;nbsp;-&amp;nbsp;res&amp;nbsp;&amp;gt;&amp;nbsp;raw&amp;nbsp;위치에&amp;nbsp;인증서&amp;nbsp;붙여넣기&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;257&quot; data-origin-height=&quot;234&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bybCuG/btr6CfcbV4s/VmrBPAvpj3PN2cbe3CKVQ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bybCuG/btr6CfcbV4s/VmrBPAvpj3PN2cbe3CKVQ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bybCuG/btr6CfcbV4s/VmrBPAvpj3PN2cbe3CKVQ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbybCuG%2Fbtr6CfcbV4s%2FVmrBPAvpj3PN2cbe3CKVQ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;257&quot; height=&quot;234&quot; data-origin-width=&quot;257&quot; data-origin-height=&quot;234&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;3.&amp;nbsp;Connection&amp;nbsp;시&amp;nbsp;인증서&amp;nbsp;정보&amp;nbsp;setting&lt;/p&gt;
&lt;pre id=&quot;code_1679993420070&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;CertificateFactory cf = CertificateFactory.getInstance(&quot;X.509&quot;);

InputStream caInput = getResources().openRawResource(R.raw.maandoo);
Certificate ca = cf.generateCertificate(caInput);

// Create a KeyStore containing our trusted CAs
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null,null);
keyStore.setCertificateEntry(&quot;ca&quot;, ca);

// Create a TrustManager that trusts the CAs in our KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);

// Create an SSLContext that uses our TrustManager
SSLContext sslContext = SSLContext.getInstance(&quot;TLS&quot;);
sslContext.init(null, tmf.getTrustManagers(), new java.security.SecureRandom());
caInput.close();

URL requestUrl = new URL(url + param);
HttpsURLConnection urlConnection = (HttpsURLConnection)requestUrl.openConnection();
urlConnection.setSSLSocketFactory(sslContext.getSocketFactory());
InputStream is = urlConnection.getInputStream();&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Android</category>
      <category>Android</category>
      <category>certificate</category>
      <category>https</category>
      <category>SSL</category>
      <category>sslhandshakeexception</category>
      <author>박진만</author>
      <guid isPermaLink="true">https://jinmanp.tistory.com/55</guid>
      <comments>https://jinmanp.tistory.com/entry/Android-https-%EC%9A%94%EC%B2%AD-%EC%8B%9C-ssl-%EC%9D%B8%EC%A6%9D%EC%84%9C-%EC%98%A4%EB%A5%98#entry55comment</comments>
      <pubDate>Tue, 28 Mar 2023 17:51:29 +0900</pubDate>
    </item>
    <item>
      <title>[Spring Boot] Swagger, Bearer + JWT(JSON Web Token) 적용</title>
      <link>https://jinmanp.tistory.com/entry/Spring-Boot-Swagger-Bearer-JWTJSON-Web-Token-%EC%A0%81%EC%9A%A9</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;Spring&amp;nbsp;Boot&amp;nbsp;3.0.4,&amp;nbsp;springdoc&amp;nbsp;2.0.4&amp;nbsp;기준 &lt;br /&gt;&lt;br /&gt;-&amp;nbsp;JWT(JSON&amp;nbsp;Web&amp;nbsp;Token) &lt;br /&gt;JSON 웹 토큰(JSON Web Token, JWT)은 선택적 서명 및 선택적 암호화를 사용하여 데이터를 만들기 위한 인터넷 표준으로 페이로드는 클레임(claim), 표명(assert)을 처리하는 JSON을 보관하고 있다. &lt;br /&gt;전달하고자하는&amp;nbsp;정보를&amp;nbsp;안전하게&amp;nbsp;전송하기&amp;nbsp;위핸&amp;nbsp;웹표준(RFC&amp;nbsp;7519)&amp;nbsp;방식으로,&amp;nbsp;인증에&amp;nbsp;필요한&amp;nbsp;중요정보(api&amp;nbsp;key,&amp;nbsp;api&amp;nbsp;secret)부터,&amp;nbsp;만료일,&amp;nbsp;발행자,&amp;nbsp;암호화&amp;nbsp;알고리즘과&amp;nbsp;같은&amp;nbsp;기본&amp;nbsp;정보까지&amp;nbsp;포함. &lt;br /&gt;JWT 토큰 내에 만료일이나 인증정보를 가지고 있기 때문에, 서버에서 인증을 위한 별도의 세션 처리를 할 필요가 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3가지(header, payload, signatue) 정보가 . 으로 구분되어 합쳐진 형태. &lt;br /&gt;&lt;br /&gt;1.&amp;nbsp;build.gradle &lt;br /&gt;-&amp;nbsp;implementation&amp;nbsp;추가&lt;/p&gt;
&lt;pre id=&quot;code_1679451868045&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5', 'io.jsonwebtoken:jjwt-jackson:0.11.5'&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1035&quot; data-origin-height=&quot;178&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cRyQuW/btr5dR5z3Eq/mMOOtF1qfW6KOV1pa7kmC0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cRyQuW/btr5dR5z3Eq/mMOOtF1qfW6KOV1pa7kmC0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cRyQuW/btr5dR5z3Eq/mMOOtF1qfW6KOV1pa7kmC0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcRyQuW%2Fbtr5dR5z3Eq%2FmMOOtF1qfW6KOV1pa7kmC0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1035&quot; height=&quot;178&quot; data-origin-width=&quot;1035&quot; data-origin-height=&quot;178&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2.&amp;nbsp;application.properties &lt;br /&gt;-&amp;nbsp;jwt&amp;nbsp;설정&amp;nbsp;내용&amp;nbsp;추가&amp;nbsp;:&amp;nbsp;apiKey,&amp;nbsp;secretKey&amp;nbsp;에&amp;nbsp;설정한&amp;nbsp;키&amp;nbsp;값을&amp;nbsp;입력한다.&lt;/p&gt;
&lt;pre id=&quot;code_1679451974940&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#jwt
jwt.token.typ=JWT
jwt.token.alg=HS256
jwt.token.apiKey=xxxxxxxxx
jwt.token.secretKey=xxxxxxxx&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;489&quot; data-origin-height=&quot;151&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UjGHv/btr5d177F6l/ltoyKKpE24fu3jFYikkjq1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UjGHv/btr5d177F6l/ltoyKKpE24fu3jFYikkjq1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UjGHv/btr5d177F6l/ltoyKKpE24fu3jFYikkjq1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUjGHv%2Fbtr5d177F6l%2FltoyKKpE24fu3jFYikkjq1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;489&quot; height=&quot;151&quot; data-origin-width=&quot;489&quot; data-origin-height=&quot;151&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3.&amp;nbsp;SwaggerConfig.java &lt;br /&gt;-&amp;nbsp;swagger&amp;nbsp;API&amp;nbsp;설정&amp;nbsp;:&amp;nbsp;기본&amp;nbsp;정보&amp;nbsp;설정&amp;nbsp;및&amp;nbsp;JWT&amp;nbsp;설정&lt;/p&gt;
&lt;pre id=&quot;code_1679452232753&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.SecretKey;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.test.common.request.TokenRequest;
import com.test.common.response.ErrorResponse;
import com.test.common.response.TokenResponse;

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.ServletInputStream;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.Setter;

@RequestMapping(value = &quot;/token&quot;)
@Tag(name = &quot;token&quot;, description = &quot;Bearer JWT Token API&quot;)
@ConfigurationProperties(prefix = &quot;jwt.token&quot;)
@RequiredArgsConstructor
@RestController
public class TokenController {
	
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Setter 
    private String typ;
    @Setter 
    private String alg;
    @Setter 
    private String apiKey;
    @Setter 
    private String secretKey;
	
    // input 스트링으로 들어오는 String 데이터들의 white space를 trim 해주는 역할을 한다.
    // 모든 요청이 들어올 때마다 해당 method를 거침 (node의 middleware 같은 것)
    @InitBinder
    public void initBinder(WebDataBinder dataBinder) {
        StringTrimmerEditor stringTrimmerEditor = new StringTrimmerEditor(true);
        dataBinder.registerCustomEditor(String.class, stringTrimmerEditor);
    }

    @Operation(description = &quot;JWT token 생성&quot;)
    @Parameters({
        @Parameter(name = &quot;apikey&quot;, description = &quot;apikey&quot;, required = true),
        @Parameter(name = &quot;nonce&quot;, description = &quot;현재시각(단위: millisecond)&quot;, required = true)
    })
    @PostMapping(value = &quot;&quot;)
    public ResponseEntity&amp;lt;? extends Object&amp;gt; createToken(
            @Parameter(hidden = true) @RequestBody TokenRequest tokenRequest
            , HttpServletRequest request
            ) throws Exception {
		
        ServletInputStream inputStream = request.getInputStream();
        String requestBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
        logger.debug(&quot;TokenController callApiJsonRequest requestBody : &quot; + requestBody);

        logger.debug(&quot;TokenController createToken tokenRequest.toString() : &quot; + tokenRequest.toString());
        logger.debug(&quot;TokenController createToken tokenRequest.getApiKey() : &quot; + tokenRequest.getApiKey());
        logger.debug(&quot;TokenController createToken tokenRequest.getNonce() : &quot; + tokenRequest.getNonce());

        if(StringUtils.isBlank(tokenRequest.getApiKey()) || tokenRequest.getNonce() == null) {
            return ResponseEntity.badRequest().body(new ErrorResponse(&quot;400&quot;, &quot;apiKey 또는 nonce가 없습니다.&quot;, null));
        } else if(!apiKey.equals(tokenRequest.getApiKey())) {
            return ResponseEntity.badRequest().body(new ErrorResponse(&quot;400&quot;, &quot;apiKey가 일치하지 않습니다.&quot;, null));
        }

        Date now = new Date();
        long nonce = tokenRequest.getNonce();
        long expTime = 1800000L; // 유효시간 : 30분

        try {

            if(nonce &amp;lt; now.getTime() - expTime) {
                return ResponseEntity.badRequest().body(new ErrorResponse(&quot;400&quot;, &quot;nonce값이 유효하지 않습니다.&quot;, null));
            }

        } catch(Exception e) {
            return ResponseEntity.badRequest().body(new ErrorResponse(&quot;400&quot;, &quot;nonce값은 millisecond값으로 설정해야 합니다.&quot;, null));
        }

        SecretKey key = Keys.hmacShaKeyFor(secretKey.getBytes(&quot;UTF-8&quot;));

        Map&amp;lt;String, Object&amp;gt; header = new HashMap&amp;lt;&amp;gt;();
        header.put(&quot;typ&quot;, typ);
        header.put(&quot;alg&quot;, alg);

        String jwt = Jwts.builder()
            .setHeader(header)
            .setIssuer(&quot;testApp&quot;)
            .setIssuedAt(now)
            .setExpiration(new Date(nonce + expTime))
            .claim(&quot;apiKey&quot;, apiKey)
            .signWith(key)
            .compact();

        return ResponseEntity.ok().body(new TokenResponse(jwt));
		
    }

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5.&amp;nbsp;TokenRequest.java &lt;br /&gt;-&amp;nbsp;요청&amp;nbsp;값&amp;nbsp;관리&amp;nbsp;:&amp;nbsp;요청&amp;nbsp;항목&amp;nbsp;정의&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1679452579230&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter @Setter @ToString
@Schema(name = &quot;TokenRequest&quot;)
public class TokenRequest {
	
    private String apiKey;

    @Schema(description = &quot;현재시각(단위: millisecond)&quot;)
    private Long nonce;
	
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6.&amp;nbsp;TokenResponse.java &lt;br /&gt;-&amp;nbsp;응답&amp;nbsp;값&amp;nbsp;관리&amp;nbsp;:&amp;nbsp;응답&amp;nbsp;항목&amp;nbsp;정의&lt;/p&gt;
&lt;pre id=&quot;code_1679452608670&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;

@Getter
public class TokenResponse {
	
    @Schema(description = &quot;JWT 토큰&quot;)
    private String token;

    public TokenResponse(String token) {
        this.token = token;
    }
	
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;7.&amp;nbsp;AuthorizationAspect.java &lt;br /&gt;-&amp;nbsp;@Aspect&amp;nbsp;를&amp;nbsp;이용한&amp;nbsp;token&amp;nbsp;유효성&amp;nbsp;검사 &lt;br /&gt;-&amp;nbsp;@Before&amp;nbsp;를&amp;nbsp;통해서&amp;nbsp;TokenController&amp;nbsp;를&amp;nbsp;제외한&amp;nbsp;모든&amp;nbsp;Controller&amp;nbsp;요청에&amp;nbsp;JWT&amp;nbsp;인증&amp;nbsp;적용&lt;/p&gt;
&lt;pre id=&quot;code_1679452781006&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.regex.Pattern;

import javax.crypto.SecretKey;

import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.test.common.exception.AuthorizationHeaderNotExistsException;
import com.test.common.exception.InvalidTokenException;
import com.test.common.exception.TokenExpiredException;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import io.jsonwebtoken.security.WeakKeyException;
import jakarta.servlet.http.HttpServletRequest;
import lombok.Setter;

@ConfigurationProperties(prefix = &quot;jwt.token&quot;)
@Aspect
@Component
public class AuthorizationAspect {
	
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Setter 
    private String apiKey;

    @Setter 
    private String secretKey;
    
    @Before(&quot;execution(* com.test..*Controller.*(..)) &amp;amp;&amp;amp; !target(com.test.common.web.TokenController)&quot;)
    public void checkToken(JoinPoint joinPoint) throws WeakKeyException, UnsupportedEncodingException, TokenExpiredException {

        logger.debug(&quot;AuthorizationAspect checkToken&quot;);

        SecretKey key = Keys.hmacShaKeyFor(secretKey.getBytes(&quot;UTF-8&quot;));
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
        String authorization = request.getHeader(&quot;Authorization&quot;);

        if(StringUtils.isBlank(authorization)){
            throw new AuthorizationHeaderNotExistsException();
        }

        if(Pattern.matches(&quot;^Bearer .*&quot;, authorization)) {

            authorization = authorization.replaceAll(&quot;^Bearer( )*&quot;, &quot;&quot;);
            Jws&amp;lt;Claims&amp;gt; jwsClaims = Jwts.parserBuilder()
                    .setSigningKey(key)
                    .build()
                    .parseClaimsJws(authorization);

            if(jwsClaims.getBody() != null) {

                Claims claims = jwsClaims.getBody();

                logger.debug(&quot;AuthorizationAspect checkToken claims : &quot; + claims);

                if(!claims.containsKey(&quot;apiKey&quot;) || !apiKey.equals(claims.get(&quot;apiKey&quot;).toString())
                        || claims.getExpiration() == null) {
                    throw new InvalidTokenException();
                }

                long exp = claims.getExpiration().getTime();

                logger.debug(&quot;AuthorizationAspect checkToken exp : &quot; + exp);
                logger.debug(&quot;AuthorizationAspect checkToken new Date().getTime() : &quot; + new Date().getTime());

                if(exp &amp;lt; new Date().getTime()) {
                    throw new TokenExpiredException();
                }

            }

        } else {
            throw new InvalidTokenException();
        }

    }
	
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;8. AuthorizationHeaderNotExistsException.java &lt;br /&gt;-&amp;nbsp;authorization&amp;nbsp;정보가&amp;nbsp;없을&amp;nbsp;때&amp;nbsp;발생&amp;nbsp;할&amp;nbsp;Exception&lt;/p&gt;
&lt;pre id=&quot;code_1679453352390&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class AuthorizationHeaderNotExistsException extends RuntimeException {

    private static final long serialVersionUID = -1013888520992595369L;

    public AuthorizationHeaderNotExistsException() {
        super(&quot;Authorization 헤더가 없습니다.&quot;);
    }
	
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;9.&amp;nbsp;InvalidTokenException.java &lt;br /&gt;-&amp;nbsp;token&amp;nbsp;값이&amp;nbsp;유효하지&amp;nbsp;않을&amp;nbsp;때&amp;nbsp;발생&amp;nbsp;할&amp;nbsp;Exception&lt;/p&gt;
&lt;pre id=&quot;code_1679453375948&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class InvalidTokenException extends RuntimeException {

    private static final long serialVersionUID = 346116252681253824L;

    public InvalidTokenException() {
        super(&quot;token 값이 유효하지 않습니다.&quot;);
    }
	
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;10.&amp;nbsp;TokenExpiredException.java &lt;br /&gt;-&amp;nbsp;token&amp;nbsp;유효기간이&amp;nbsp;만료&amp;nbsp;되었을&amp;nbsp;때&amp;nbsp;발생&amp;nbsp;할&amp;nbsp;Exception&lt;/p&gt;
&lt;pre id=&quot;code_1679453393672&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class TokenExpiredException extends RuntimeException {

    private static final long serialVersionUID = -3644870070470966659L;

    public TokenExpiredException() {
        super(&quot;토큰이 만료되었습니다.&quot;);
    }
	
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;11. Swagger ui 화면 접속&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Authorize 버튼과 API 목록 우측에 자물쇠 모양이 열려있는 모양으로 생성됨&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1894&quot; data-origin-height=&quot;921&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vnCWu/btr5guwaDae/2KZw57rs2xkVXjVLBNYfKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vnCWu/btr5guwaDae/2KZw57rs2xkVXjVLBNYfKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vnCWu/btr5guwaDae/2KZw57rs2xkVXjVLBNYfKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvnCWu%2Fbtr5guwaDae%2F2KZw57rs2xkVXjVLBNYfKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1894&quot; height=&quot;921&quot; data-origin-width=&quot;1894&quot; data-origin-height=&quot;921&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- API 요청 시 인증 오류 발생&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1876&quot; data-origin-height=&quot;1039&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mW7dO/btr5fNwcU6c/HAwJPWjpmbFtQ6xMQkx6x0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mW7dO/btr5fNwcU6c/HAwJPWjpmbFtQ6xMQkx6x0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mW7dO/btr5fNwcU6c/HAwJPWjpmbFtQ6xMQkx6x0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmW7dO%2Fbtr5fNwcU6c%2FHAwJPWjpmbFtQ6xMQkx6x0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1876&quot; height=&quot;1039&quot; data-origin-width=&quot;1876&quot; data-origin-height=&quot;1039&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- token API 정보 열기 &amp;rarr; Try it out 버튼 클릭 &amp;rarr; apiKey, nonce 입력 후 Execute 버튼 클릭 &amp;rarr; token 생성&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1876&quot; data-origin-height=&quot;981&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/K5mz0/btr5pFbWHyg/yWkOtiPLv66BDrKMNMtgM1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/K5mz0/btr5pFbWHyg/yWkOtiPLv66BDrKMNMtgM1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/K5mz0/btr5pFbWHyg/yWkOtiPLv66BDrKMNMtgM1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FK5mz0%2Fbtr5pFbWHyg%2FyWkOtiPLv66BDrKMNMtgM1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1876&quot; height=&quot;981&quot; data-origin-width=&quot;1876&quot; data-origin-height=&quot;981&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 생성된 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;token&lt;span&gt; 값 복사&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1840&quot; data-origin-height=&quot;957&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/znNQN/btr5qtWEQI3/vW9wNT2l77DNtjibJty8UK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/znNQN/btr5qtWEQI3/vW9wNT2l77DNtjibJty8UK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/znNQN/btr5qtWEQI3/vW9wNT2l77DNtjibJty8UK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FznNQN%2Fbtr5qtWEQI3%2FvW9wNT2l77DNtjibJty8UK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1840&quot; height=&quot;957&quot; data-origin-width=&quot;1840&quot; data-origin-height=&quot;957&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Authorize 버튼 클릭&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1894&quot; data-origin-height=&quot;921&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TEaDt/btr5ibwn6Rx/o1hclYtw2hdk6xcxXrgiH0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TEaDt/btr5ibwn6Rx/o1hclYtw2hdk6xcxXrgiH0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TEaDt/btr5ibwn6Rx/o1hclYtw2hdk6xcxXrgiH0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTEaDt%2Fbtr5ibwn6Rx%2Fo1hclYtw2hdk6xcxXrgiH0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1894&quot; height=&quot;921&quot; data-origin-width=&quot;1894&quot; data-origin-height=&quot;921&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 복사한 token 값 입력 후 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;Authorize&lt;span&gt;&amp;nbsp;클릭&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1082&quot; data-origin-height=&quot;557&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ba3Xbw/btr5nIgkgNg/zERCxHiCvwx63int2OfLC0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ba3Xbw/btr5nIgkgNg/zERCxHiCvwx63int2OfLC0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ba3Xbw/btr5nIgkgNg/zERCxHiCvwx63int2OfLC0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fba3Xbw%2Fbtr5nIgkgNg%2FzERCxHiCvwx63int2OfLC0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1082&quot; height=&quot;557&quot; data-origin-width=&quot;1082&quot; data-origin-height=&quot;557&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Close 버튼 클릭&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1052&quot; data-origin-height=&quot;473&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ox985/btr5fPnikej/xX4Lkr3yVPtCCGoRIpQsek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ox985/btr5fPnikej/xX4Lkr3yVPtCCGoRIpQsek/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ox985/btr5fPnikej/xX4Lkr3yVPtCCGoRIpQsek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fox985%2Fbtr5fPnikej%2FxX4Lkr3yVPtCCGoRIpQsek%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1052&quot; height=&quot;473&quot; data-origin-width=&quot;1052&quot; data-origin-height=&quot;473&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- API 목록 우측에 자물쇠 모양이 닫힌 모양으로 변경됨&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1898&quot; data-origin-height=&quot;900&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/C9XK4/btr5oryQZm5/pb7Akt8IpsmzGgtooywwKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/C9XK4/btr5oryQZm5/pb7Akt8IpsmzGgtooywwKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/C9XK4/btr5oryQZm5/pb7Akt8IpsmzGgtooywwKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FC9XK4%2Fbtr5oryQZm5%2Fpb7Akt8IpsmzGgtooywwKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1898&quot; height=&quot;900&quot; data-origin-width=&quot;1898&quot; data-origin-height=&quot;900&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- header 에 authorization: Bearer [생성한 token] 포함하여 API 요청 &amp;rarr; 정상 응답&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1850&quot; data-origin-height=&quot;770&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBk1Wz/btr5nK6vW6H/7ApQYTl8RN2NoP0WqJOdC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBk1Wz/btr5nK6vW6H/7ApQYTl8RN2NoP0WqJOdC1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBk1Wz/btr5nK6vW6H/7ApQYTl8RN2NoP0WqJOdC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBk1Wz%2Fbtr5nK6vW6H%2F7ApQYTl8RN2NoP0WqJOdC1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1850&quot; height=&quot;770&quot; data-origin-width=&quot;1850&quot; data-origin-height=&quot;770&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>spring</category>
      <category>bearer</category>
      <category>Json Web Token</category>
      <category>JWT</category>
      <category>spring boot</category>
      <category>swagger</category>
      <author>박진만</author>
      <guid isPermaLink="true">https://jinmanp.tistory.com/54</guid>
      <comments>https://jinmanp.tistory.com/entry/Spring-Boot-Swagger-Bearer-JWTJSON-Web-Token-%EC%A0%81%EC%9A%A9#entry54comment</comments>
      <pubDate>Wed, 22 Mar 2023 11:45:09 +0900</pubDate>
    </item>
    <item>
      <title>[Spring Boot] 스피링 부트 3.x Swagger Ui 설정</title>
      <link>https://jinmanp.tistory.com/entry/Spring-Boot-%EC%8A%A4%ED%94%BC%EB%A7%81-%EB%B6%80%ED%8A%B8-3x-Swagger-Ui-%EC%84%A4%EC%A0%95</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;- Spring Boot 3.0.4, springdoc 2.0.4 기준 &lt;br /&gt;- swagger : springfox, springdoc 2가지 라이브러리가 있음. &lt;br /&gt;&amp;nbsp; springfox 는 최근 업데이트가 없고 Spring Boot 3점 대 적용 시 일부 오류 발생 -&amp;gt; java 17 적용 때문인 것 같음 (Spring Boot 3 버전은 java 17 이상 필수) &lt;br /&gt;&amp;nbsp; 그래서 springdoc 적용 &lt;br /&gt;&lt;br /&gt;1.&amp;nbsp;build.gradle &lt;br /&gt;-&amp;nbsp;implementation&amp;nbsp;추가 &lt;br /&gt;implementation&amp;nbsp;'org.springframework.boot:spring-boot-starter-web' &lt;br /&gt;implementation&amp;nbsp;'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.4' &lt;br /&gt;implementation&amp;nbsp;'org.springframework.boot:spring-boot-starter-validation'&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;837&quot; data-origin-height=&quot;962&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cqkK7h/btr5d3dbLwz/Y56fg5fjvQekRzr3i0wIFk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cqkK7h/btr5d3dbLwz/Y56fg5fjvQekRzr3i0wIFk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cqkK7h/btr5d3dbLwz/Y56fg5fjvQekRzr3i0wIFk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcqkK7h%2Fbtr5d3dbLwz%2FY56fg5fjvQekRzr3i0wIFk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;837&quot; height=&quot;962&quot; data-origin-width=&quot;837&quot; data-origin-height=&quot;962&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2.&amp;nbsp;application.properties &lt;br /&gt;-&amp;nbsp;springdoc&amp;nbsp;설정&amp;nbsp;내용&amp;nbsp;추가 &lt;br /&gt;#springdoc &lt;br /&gt;springdoc.version=v1.0.0 &lt;br /&gt;springdoc.swagger-ui.path=/swagger-ui.html &lt;br /&gt;springdoc.swagger-ui.groups-order=DESC &lt;br /&gt;springdoc.swagger-ui.operationsSorter=method &lt;br /&gt;springdoc.swagger-ui.disable-swagger-default-url=true &lt;br /&gt;springdoc.swagger-ui.display-request-duration=true &lt;br /&gt;&lt;br /&gt;springdoc.api-docs.path=/api-docs &lt;br /&gt;springdoc.show-actuator=true &lt;br /&gt;springdoc.default-consumes-media-type=application/json &lt;br /&gt;springdoc.default-produces-media-type=application/json &lt;br /&gt;springdoc.paths-to-match=/**&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;619&quot; data-origin-height=&quot;545&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzuIcq/btr5cSpR19G/ojzKWFruNMtmaQWJG4kmJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzuIcq/btr5cSpR19G/ojzKWFruNMtmaQWJG4kmJ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzuIcq/btr5cSpR19G/ojzKWFruNMtmaQWJG4kmJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbzuIcq%2Fbtr5cSpR19G%2FojzKWFruNMtmaQWJG4kmJ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;619&quot; height=&quot;545&quot; data-origin-width=&quot;619&quot; data-origin-height=&quot;545&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3.&amp;nbsp;SwaggerConfig.java &lt;br /&gt;-&amp;nbsp;swagger&amp;nbsp;API&amp;nbsp;설정&amp;nbsp;:&amp;nbsp;기본&amp;nbsp;정보&amp;nbsp;설정&amp;nbsp;및&amp;nbsp;JWT&amp;nbsp;설정&lt;/p&gt;
&lt;pre id=&quot;code_1679388820402&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.Arrays;

import org.springdoc.core.models.GroupedOpenApi;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;

@Configuration
public class SwaggerConfig {

    @Bean
    public GroupedOpenApi manmanApi() {
        return GroupedOpenApi.builder()
            .group(&quot;manman Service API v1&quot;)
            .pathsToMatch(&quot;/**&quot;)
            .build();
    }
    
    @Bean
    public OpenAPI manmanOpenAPI(@Value(&quot;${springdoc.version}&quot;) String springdocVersion) {
    	
    	Info info = new Info().title(&quot;manman Service API 명세서&quot;)
            .description(&quot;manman 프로젝트 서비스 API 명세서입니다.&quot;)
            .version(springdocVersion);
                
    	SecurityScheme securityScheme = new SecurityScheme()
            .type(SecurityScheme.Type.HTTP).scheme(&quot;bearer&quot;).bearerFormat(&quot;JWT&quot;)
            .in(SecurityScheme.In.HEADER).name(&quot;Authorization&quot;);

	SecurityRequirement schemaRequirement = new SecurityRequirement().addList(&quot;bearerAuth&quot;);
    	
        return new OpenAPI()
            .components(new Components().addSecuritySchemes(&quot;bearerAuth&quot;, securityScheme))
            .security(Arrays.asList(schemaRequirement))
            .info(info);
        
    }
    
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4.&amp;nbsp;MusicController.java &lt;br /&gt;-&amp;nbsp;Controller&amp;nbsp;설정&amp;nbsp;:&amp;nbsp;설정한&amp;nbsp;정보가&amp;nbsp;swagger-ui.html&amp;nbsp;화면에&amp;nbsp;표현된다.&lt;/p&gt;
&lt;pre id=&quot;code_1679389013514&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.manman.common.response.ErrorResponse;
import com.manman.music.service.MusicService;
import com.manman.music.vo.MusicRequest;
import com.manman.music.vo.MusicResponse;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;

@Tag(name = &quot;Music&quot;, description = &quot;Music api 입니다.&quot;)
@RestController
@RequestMapping(&quot;/music&quot;)
public class MusicController {
	
	final private Logger logger = LoggerFactory.getLogger(this.getClass());

	@Autowired
	private MusicService musicService;
	
	@Operation(summary = &quot;Music 리스트 조회&quot;, description = &quot;Music 리스트 정보가 조회됩니다.&quot;)
	@ApiResponses({
		@ApiResponse(responseCode = &quot;200&quot;, description = &quot;OK&quot;,
			content = @Content(schema = @Schema(implementation = MusicResponse.class))),
		@ApiResponse(responseCode = &quot;400&quot;, description = &quot;BAD REQUEST&quot;, 
			content = @Content(schema = @Schema(implementation = ErrorResponse.class))),
		@ApiResponse(responseCode = &quot;404&quot;, description = &quot;NOT FOUND&quot;,
			content = @Content(schema = @Schema(implementation = ErrorResponse.class))),
		@ApiResponse(responseCode = &quot;500&quot;, description = &quot;INTERNAL SERVER ERROR&quot;,
			content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
	})
	@Parameters({
		@Parameter(name = &quot;category&quot;, description = &quot;카테고리&quot;, example = &quot;R01&quot;, required = true),
		@Parameter(name = &quot;regYmd&quot;, description = &quot;등록일시&quot;, example = &quot;20230305&quot;, required = false)
	})
	@RequestMapping(value = &quot;/selectMusicList&quot;, method = {RequestMethod.POST, RequestMethod.GET})
	ResponseEntity&amp;lt;List&amp;lt;MusicResponse&amp;gt;&amp;gt; selectMusicList(
		@Parameter(hidden = true) @Validated(MusicRequest.validSelectMusicList.class) @RequestBody MusicRequest musicRequest
	) throws Exception {

		logger.debug(&quot;MusicController selectMusicList musicRequest.getCategory() : &quot; + musicRequest.getCategory());
		logger.debug(&quot;MusicController selectMusicList musicRequest.getRegYmd() : &quot; + musicRequest.getRegYmd());

		return ResponseEntity.ok().body(musicService.selectMusicList(musicRequest));

	}
    
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5.&amp;nbsp;MusicRequest.java &lt;br /&gt;-&amp;nbsp;요청&amp;nbsp;값&amp;nbsp;관리&amp;nbsp;Class&amp;nbsp;:&amp;nbsp;요청&amp;nbsp;항목&amp;nbsp;정의&amp;nbsp;및&amp;nbsp;각&amp;nbsp;항목&amp;nbsp;별&amp;nbsp;validation&amp;nbsp;을&amp;nbsp;정의한다.&lt;/p&gt;
&lt;pre id=&quot;code_1679389229264&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class MusicRequest {
	
    public interface validSelectMusicList {}

    @NotBlank(groups = validSelectMusicList.class)
    @Schema(description = &quot;카테고리&quot;)
    private String category;

    @Schema(description = &quot;등록일시&quot;)
    private String regYmd;

    @Schema(description = &quot;가수&quot;)
    private String artist;    

    @Schema(description = &quot;제목&quot;)
    private String title;    

    @Schema(description = &quot;등록번호&quot;)
    private String regNo;    

    @Schema(description = &quot;비디오 ID&quot;)
    private String videoId;    

    @Schema(description = &quot;썸네일&quot;)
    private String thumbnail;

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6.&amp;nbsp;MusicResponse.java &lt;br /&gt;-&amp;nbsp;&amp;nbsp;응답&amp;nbsp;값&amp;nbsp;관리&amp;nbsp;Class&amp;nbsp;:&amp;nbsp;응답&amp;nbsp;항목을&amp;nbsp;정의한다.&lt;/p&gt;
&lt;pre id=&quot;code_1679389280283&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@NoArgsConstructor
public class MusicResponse {
	
    @Schema(description = &quot;등록번호&quot;)
    private String regNo;

    @Schema(description = &quot;순위&quot;)
    private int rank;

    @Schema(description = &quot;제목&quot;)
    private String title;

    @Schema(description = &quot;가수&quot;)
    private String artist;

    @Schema(description = &quot;등록일시&quot;)
    private String regYmd;

    @Schema(description = &quot;카테고리&quot;)
    private String category;

    @Schema(description = &quot;썸네일&quot;)
    private String thumbnail;

    @Schema(description = &quot;비디오 ID&quot;)
    private String videoId;
	
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;7. swagger-ui 화면&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1548&quot; data-origin-height=&quot;920&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nllFQ/btr42SSbZ88/Yr2jzmWsCdmFYfoWs1BjP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nllFQ/btr42SSbZ88/Yr2jzmWsCdmFYfoWs1BjP1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nllFQ/btr42SSbZ88/Yr2jzmWsCdmFYfoWs1BjP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnllFQ%2Fbtr42SSbZ88%2FYr2jzmWsCdmFYfoWs1BjP1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1548&quot; height=&quot;920&quot; data-origin-width=&quot;1548&quot; data-origin-height=&quot;920&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>spring</category>
      <category>Spring Boot 3.0</category>
      <category>springdoc</category>
      <category>swagger</category>
      <author>박진만</author>
      <guid isPermaLink="true">https://jinmanp.tistory.com/53</guid>
      <comments>https://jinmanp.tistory.com/entry/Spring-Boot-%EC%8A%A4%ED%94%BC%EB%A7%81-%EB%B6%80%ED%8A%B8-3x-Swagger-Ui-%EC%84%A4%EC%A0%95#entry53comment</comments>
      <pubDate>Tue, 21 Mar 2023 18:06:59 +0900</pubDate>
    </item>
    <item>
      <title>[Spring Boot] 설정 파일(application.properties, logback.xml) 개발, 운영 분리 설정</title>
      <link>https://jinmanp.tistory.com/entry/Spring-Boot-%EC%84%A4%EC%A0%95-%ED%8C%8C%EC%9D%BCapplicationproperties-logbackxml-%EA%B0%9C%EB%B0%9C-%EC%9A%B4%EC%98%81-%EB%B6%84%EB%A6%AC-%EC%84%A4%EC%A0%95</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Spring&amp;nbsp;Boot&amp;nbsp;개발&amp;nbsp;환경에&amp;nbsp;따라&amp;nbsp;설정&amp;nbsp;파일을&amp;nbsp;분리해서&amp;nbsp;관리하는&amp;nbsp;방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1.&amp;nbsp;application.properties &lt;br /&gt;-&amp;nbsp;spring.profiles.active&amp;nbsp;에&amp;nbsp;profiles&amp;nbsp;값&amp;nbsp;설정&amp;nbsp;:&amp;nbsp;dev(개발),&amp;nbsp;release(운영)&amp;nbsp;으로&amp;nbsp;분리함 &lt;br /&gt;-&amp;nbsp;개발,&amp;nbsp;운영&amp;nbsp;환경에서&amp;nbsp;공통적으로&amp;nbsp;사용하는&amp;nbsp;설정은&amp;nbsp;application.properties&amp;nbsp;파일에&amp;nbsp;작성.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1104&quot; data-origin-height=&quot;319&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/v2OSa/btr42Swzcgv/OSmBLspn6CNbYOohPgYGW1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/v2OSa/btr42Swzcgv/OSmBLspn6CNbYOohPgYGW1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/v2OSa/btr42Swzcgv/OSmBLspn6CNbYOohPgYGW1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fv2OSa%2Fbtr42Swzcgv%2FOSmBLspn6CNbYOohPgYGW1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1104&quot; height=&quot;319&quot; data-origin-width=&quot;1104&quot; data-origin-height=&quot;319&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2.&amp;nbsp;application-dev.properties &lt;br /&gt;-&amp;nbsp;spring.profiles.active&amp;nbsp;값이&amp;nbsp;dev&amp;nbsp;로&amp;nbsp;되어&amp;nbsp;있을&amp;nbsp;경우&amp;nbsp;해당&amp;nbsp;파일을&amp;nbsp;설정&amp;nbsp;파일로&amp;nbsp;인식 &lt;br /&gt;-&amp;nbsp;개발&amp;nbsp;환경에서&amp;nbsp;사용하는&amp;nbsp;설정&amp;nbsp;application-dev.properties&amp;nbsp;파일에&amp;nbsp;작성&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1230&quot; data-origin-height=&quot;319&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uqtwr/btr40SjJHue/9fTSrD4KqoY7buYwreT7Tk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uqtwr/btr40SjJHue/9fTSrD4KqoY7buYwreT7Tk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uqtwr/btr40SjJHue/9fTSrD4KqoY7buYwreT7Tk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fuqtwr%2Fbtr40SjJHue%2F9fTSrD4KqoY7buYwreT7Tk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1230&quot; height=&quot;319&quot; data-origin-width=&quot;1230&quot; data-origin-height=&quot;319&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. application-release.properties &lt;br /&gt;-&amp;nbsp;spring.profiles.active&amp;nbsp;값이&amp;nbsp;release&amp;nbsp;로&amp;nbsp;되어&amp;nbsp;있을&amp;nbsp;경우&amp;nbsp;해당&amp;nbsp;파일을&amp;nbsp;설정&amp;nbsp;파일로&amp;nbsp;인식 &lt;br /&gt;-&amp;nbsp;운영&amp;nbsp;환경에서&amp;nbsp;사용하는&amp;nbsp;설정&amp;nbsp;application-release.properties&amp;nbsp;파일에&amp;nbsp;작성&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1263&quot; data-origin-height=&quot;318&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/74TqD/btr41IVchxX/VcwuGXCbwuz5cukbX3dBHK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/74TqD/btr41IVchxX/VcwuGXCbwuz5cukbX3dBHK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/74TqD/btr41IVchxX/VcwuGXCbwuz5cukbX3dBHK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F74TqD%2Fbtr41IVchxX%2FVcwuGXCbwuz5cukbX3dBHK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1263&quot; height=&quot;318&quot; data-origin-width=&quot;1263&quot; data-origin-height=&quot;318&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. logback 설정도 spring.profiles.active 값에 따라 분기할 수 있다. &lt;br /&gt;-&amp;nbsp;application-dev.properties&amp;nbsp;파일에&amp;nbsp;logging.config=classpath:logback-spring-dev.xml&amp;nbsp;설정 &lt;br /&gt;-&amp;nbsp;application-release.properties&amp;nbsp;파일에&amp;nbsp;logging.config=classpath:logback-spring-release.xml&amp;nbsp;설정 &lt;br /&gt;-&amp;nbsp;logback.xml&amp;nbsp;또는&amp;nbsp;logback-spring.xml&amp;nbsp;파일이&amp;nbsp;있을&amp;nbsp;경우&amp;nbsp;삭제 &lt;br /&gt;-&amp;nbsp;logback-spring-dev.xml&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;319&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXXMHT/btr4TJnrsax/cUAHnWNy3R38khTo9YQohK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXXMHT/btr4TJnrsax/cUAHnWNy3R38khTo9YQohK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXXMHT/btr4TJnrsax/cUAHnWNy3R38khTo9YQohK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXXMHT%2Fbtr4TJnrsax%2FcUAHnWNy3R38khTo9YQohK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;319&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;319&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1679369932370&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;
&amp;lt;!DOCTYPE xml&amp;gt;
&amp;lt;configuration&amp;gt;

    &amp;lt;!-- pattern --&amp;gt;
    &amp;lt;property name=&quot;LOG_PATTERN_DEFAULT&quot; value=&quot;[%d{yyyy:MM:dd HH:mm:ss}] %-5level --- [%thread] %logger{35} : %msg %n&quot;/&amp;gt;
    
    &amp;lt;property name=&quot;LOG_PATH&quot; value=&quot;C:\\Users\\abc\\git\\abcd\\logs&quot;/&amp;gt;
    &amp;lt;property name=&quot;LOG_FILE_NAME&quot; value=&quot;abcd&quot;/&amp;gt;

    &amp;lt;!-- CONSOLE appender --&amp;gt;
    &amp;lt;appender name=&quot;CONSOLE&quot; class=&quot;ch.qos.logback.core.ConsoleAppender&quot;&amp;gt;
        &amp;lt;encoder class=&quot;ch.qos.logback.classic.encoder.PatternLayoutEncoder&quot;&amp;gt;
            &amp;lt;pattern&amp;gt;${LOG_PATTERN_DEFAULT}&amp;lt;/pattern&amp;gt;
        &amp;lt;/encoder&amp;gt;
    &amp;lt;/appender&amp;gt;
    
    &amp;lt;!-- file appender --&amp;gt;
    &amp;lt;appender name=&quot;INFO_DEFAULT_FILE_APPENDER&quot; class=&quot;ch.qos.logback.core.rolling.RollingFileAppender&quot;&amp;gt;
        &amp;lt;file&amp;gt;${LOG_PATH}/${LOG_FILE_NAME}.log&amp;lt;/file&amp;gt;
        &amp;lt;rollingPolicy class=&quot;ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy&quot;&amp;gt;
            &amp;lt;fileNamePattern&amp;gt;${LOG_PATH}/${LOG_FILE_NAME}.%d{yyyy-MM-dd}_%i.zip&amp;lt;/fileNamePattern&amp;gt;
            &amp;lt;!-- &amp;lt;fileNamePattern&amp;gt;${LOG_PATH}/${LOG_FILE_NAME}.%d{yyyy-MM-dd}_%i.zip&amp;lt;/fileNamePattern&amp;gt; --&amp;gt;
            &amp;lt;!-- 파일당 최고 용량 kb, mb, gb --&amp;gt;
        	&amp;lt;maxFileSize&amp;gt;100MB&amp;lt;/maxFileSize&amp;gt;
            &amp;lt;!-- 일자별 로그파일 최대 보관주기(~일), 해당 설정일 이상된 파일은 자동으로 제거--&amp;gt;
            &amp;lt;maxHistory&amp;gt;30&amp;lt;/maxHistory&amp;gt;
            &amp;lt;!-- 로그 파일 아카이브 저장소의 최대크기를 지정. totalSizeCap을 초과하면 가장 오래된 파일 삭제. maxHistory 1순위, totalSizeCap 2순위--&amp;gt;
            &amp;lt;totalSizeCap&amp;gt;3GB&amp;lt;/totalSizeCap&amp;gt;
        &amp;lt;/rollingPolicy&amp;gt;
        &amp;lt;encoder class=&quot;ch.qos.logback.classic.encoder.PatternLayoutEncoder&quot;&amp;gt;
            &amp;lt;pattern&amp;gt;${LOG_PATTERN_DEFAULT}&amp;lt;/pattern&amp;gt;
        &amp;lt;/encoder&amp;gt;
    &amp;lt;/appender&amp;gt;

    &amp;lt;appender name=&quot;ERROR_DEFAULT_FILE_APPENDER&quot; class=&quot;ch.qos.logback.core.rolling.RollingFileAppender&quot;&amp;gt;
        &amp;lt;filter class=&quot;ch.qos.logback.classic.filter.LevelFilter&quot;&amp;gt;
            &amp;lt;level&amp;gt;ERROR&amp;lt;/level&amp;gt;
            &amp;lt;onMatch&amp;gt;ACCEPT&amp;lt;/onMatch&amp;gt;
            &amp;lt;onMismatch&amp;gt;DENY&amp;lt;/onMismatch&amp;gt;
        &amp;lt;/filter&amp;gt;
        &amp;lt;file&amp;gt;${LOG_PATH}/${LOG_FILE_NAME}-error.log&amp;lt;/file&amp;gt;
        &amp;lt;rollingPolicy class=&quot;ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy&quot;&amp;gt;
            &amp;lt;fileNamePattern&amp;gt;${LOG_PATH}/${LOG_FILE_NAME}-error.%d{yyyy-MM-dd}_%i.zip&amp;lt;/fileNamePattern&amp;gt;
            &amp;lt;!-- &amp;lt;fileNamePattern&amp;gt;${LOG_PATH}/${LOG_FILE_NAME}-error.%d{yyyy-MM-dd}_%i.zip&amp;lt;/fileNamePattern&amp;gt; --&amp;gt;
            &amp;lt;!-- 파일당 최고 용량 kb, mb, gb --&amp;gt;
        	&amp;lt;maxFileSize&amp;gt;100MB&amp;lt;/maxFileSize&amp;gt;
            &amp;lt;totalSizeCap&amp;gt;3GB&amp;lt;/totalSizeCap&amp;gt;
        &amp;lt;/rollingPolicy&amp;gt;
        &amp;lt;encoder class=&quot;ch.qos.logback.classic.encoder.PatternLayoutEncoder&quot;&amp;gt;
            &amp;lt;pattern&amp;gt;${LOG_PATTERN_DEFAULT}&amp;lt;/pattern&amp;gt;
        &amp;lt;/encoder&amp;gt;
    &amp;lt;/appender&amp;gt;
    
    &amp;lt;logger name=&quot;com.abcd&quot; additivity=&quot;false&quot;&amp;gt;
    	&amp;lt;level value=&quot;DEBUG&quot;/&amp;gt;
    	&amp;lt;appender-ref ref=&quot;CONSOLE&quot;/&amp;gt;
    	&amp;lt;appender-ref ref=&quot;INFO_DEFAULT_FILE_APPENDER&quot;/&amp;gt;
    	&amp;lt;appender-ref ref=&quot;ERROR_DEFAULT_FILE_APPENDER&quot;/&amp;gt;
    &amp;lt;/logger&amp;gt;
    &amp;lt;logger name=&quot;org.springframework&quot; additivity=&quot;false&quot;&amp;gt;
    	&amp;lt;level value=&quot;INFO&quot;/&amp;gt;
    	&amp;lt;appender-ref ref=&quot;CONSOLE&quot;/&amp;gt;
    	&amp;lt;appender-ref ref=&quot;INFO_DEFAULT_FILE_APPENDER&quot;/&amp;gt;
    	&amp;lt;appender-ref ref=&quot;ERROR_DEFAULT_FILE_APPENDER&quot;/&amp;gt;
    &amp;lt;/logger&amp;gt;
    &amp;lt;root level=&quot;ERROR&quot;&amp;gt;
    	&amp;lt;appender-ref ref=&quot;CONSOLE&quot;/&amp;gt;
    	&amp;lt;appender-ref ref=&quot;INFO_DEFAULT_FILE_APPENDER&quot;/&amp;gt;
    	&amp;lt;appender-ref ref=&quot;ERROR_DEFAULT_FILE_APPENDER&quot;/&amp;gt;
    &amp;lt;/root&amp;gt;
     
&amp;lt;/configuration&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- logback-spring-release.xml&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;319&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/v6IAj/btr41It3K9p/LWIwwRs9AAZBI1gzKDcVPK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/v6IAj/btr41It3K9p/LWIwwRs9AAZBI1gzKDcVPK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/v6IAj/btr41It3K9p/LWIwwRs9AAZBI1gzKDcVPK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fv6IAj%2Fbtr41It3K9p%2FLWIwwRs9AAZBI1gzKDcVPK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;319&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;319&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1679370052553&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;
&amp;lt;!DOCTYPE xml&amp;gt;
&amp;lt;configuration&amp;gt;

    &amp;lt;!-- pattern --&amp;gt;
    &amp;lt;property name=&quot;LOG_PATTERN_DEFAULT&quot; value=&quot;[%d{yyyy:MM:dd HH:mm:ss}] %-5level --- [%thread] %logger{35} : %msg %n&quot;/&amp;gt;
    
    &amp;lt;property name=&quot;LOG_PATH&quot; value=&quot;/home/abcd/log&quot;/&amp;gt;
    &amp;lt;property name=&quot;LOG_FILE_NAME&quot; value=&quot;abcd&quot;/&amp;gt;

    &amp;lt;!-- CONSOLE appender --&amp;gt;
    &amp;lt;appender name=&quot;CONSOLE&quot; class=&quot;ch.qos.logback.core.ConsoleAppender&quot;&amp;gt;
        &amp;lt;encoder class=&quot;ch.qos.logback.classic.encoder.PatternLayoutEncoder&quot;&amp;gt;
            &amp;lt;pattern&amp;gt;${LOG_PATTERN_DEFAULT}&amp;lt;/pattern&amp;gt;
        &amp;lt;/encoder&amp;gt;
    &amp;lt;/appender&amp;gt;
    
    &amp;lt;!-- file appender --&amp;gt;
    &amp;lt;appender name=&quot;INFO_DEFAULT_FILE_APPENDER&quot; class=&quot;ch.qos.logback.core.rolling.RollingFileAppender&quot;&amp;gt;
        &amp;lt;file&amp;gt;${LOG_PATH}/${LOG_FILE_NAME}.log&amp;lt;/file&amp;gt;
        &amp;lt;rollingPolicy class=&quot;ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy&quot;&amp;gt;
            &amp;lt;fileNamePattern&amp;gt;${LOG_PATH}/${LOG_FILE_NAME}.%d{yyyy-MM-dd}_%i.zip&amp;lt;/fileNamePattern&amp;gt;
            &amp;lt;!-- &amp;lt;fileNamePattern&amp;gt;${LOG_PATH}/${LOG_FILE_NAME}.%d{yyyy-MM-dd}_%i.zip&amp;lt;/fileNamePattern&amp;gt; --&amp;gt;
            &amp;lt;!-- 파일당 최고 용량 kb, mb, gb --&amp;gt;
        	&amp;lt;maxFileSize&amp;gt;100MB&amp;lt;/maxFileSize&amp;gt;
            &amp;lt;!-- 일자별 로그파일 최대 보관주기(~일), 해당 설정일 이상된 파일은 자동으로 제거--&amp;gt;
            &amp;lt;maxHistory&amp;gt;30&amp;lt;/maxHistory&amp;gt;
            &amp;lt;!-- 로그 파일 아카이브 저장소의 최대크기를 지정. totalSizeCap을 초과하면 가장 오래된 파일 삭제. maxHistory 1순위, totalSizeCap 2순위--&amp;gt;
            &amp;lt;totalSizeCap&amp;gt;3GB&amp;lt;/totalSizeCap&amp;gt;
        &amp;lt;/rollingPolicy&amp;gt;
        &amp;lt;encoder class=&quot;ch.qos.logback.classic.encoder.PatternLayoutEncoder&quot;&amp;gt;
            &amp;lt;pattern&amp;gt;${LOG_PATTERN_DEFAULT}&amp;lt;/pattern&amp;gt;
        &amp;lt;/encoder&amp;gt;
    &amp;lt;/appender&amp;gt;

    &amp;lt;appender name=&quot;ERROR_DEFAULT_FILE_APPENDER&quot; class=&quot;ch.qos.logback.core.rolling.RollingFileAppender&quot;&amp;gt;
        &amp;lt;filter class=&quot;ch.qos.logback.classic.filter.LevelFilter&quot;&amp;gt;
            &amp;lt;level&amp;gt;ERROR&amp;lt;/level&amp;gt;
            &amp;lt;onMatch&amp;gt;ACCEPT&amp;lt;/onMatch&amp;gt;
            &amp;lt;onMismatch&amp;gt;DENY&amp;lt;/onMismatch&amp;gt;
        &amp;lt;/filter&amp;gt;
        &amp;lt;file&amp;gt;${LOG_PATH}/${LOG_FILE_NAME}-error.log&amp;lt;/file&amp;gt;
        &amp;lt;rollingPolicy class=&quot;ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy&quot;&amp;gt;
            &amp;lt;fileNamePattern&amp;gt;${LOG_PATH}/${LOG_FILE_NAME}-error.%d{yyyy-MM-dd}_%i.zip&amp;lt;/fileNamePattern&amp;gt;
            &amp;lt;!-- &amp;lt;fileNamePattern&amp;gt;${LOG_PATH}/${LOG_FILE_NAME}-error.%d{yyyy-MM-dd}_%i.zip&amp;lt;/fileNamePattern&amp;gt; --&amp;gt;
            &amp;lt;!-- 파일당 최고 용량 kb, mb, gb --&amp;gt;
        	&amp;lt;maxFileSize&amp;gt;100MB&amp;lt;/maxFileSize&amp;gt;
            &amp;lt;totalSizeCap&amp;gt;3GB&amp;lt;/totalSizeCap&amp;gt;
        &amp;lt;/rollingPolicy&amp;gt;
        &amp;lt;encoder class=&quot;ch.qos.logback.classic.encoder.PatternLayoutEncoder&quot;&amp;gt;
            &amp;lt;pattern&amp;gt;${LOG_PATTERN_DEFAULT}&amp;lt;/pattern&amp;gt;
        &amp;lt;/encoder&amp;gt;
    &amp;lt;/appender&amp;gt;
    
    &amp;lt;logger name=&quot;com.abcd&quot; additivity=&quot;false&quot;&amp;gt;
    	&amp;lt;level value=&quot;ERROR&quot;/&amp;gt;
    	&amp;lt;appender-ref ref=&quot;CONSOLE&quot;/&amp;gt;
    	&amp;lt;appender-ref ref=&quot;INFO_DEFAULT_FILE_APPENDER&quot;/&amp;gt;
    	&amp;lt;appender-ref ref=&quot;ERROR_DEFAULT_FILE_APPENDER&quot;/&amp;gt;
    &amp;lt;/logger&amp;gt;
    &amp;lt;logger name=&quot;org.springframework&quot; additivity=&quot;false&quot;&amp;gt;
    	&amp;lt;level value=&quot;ERROR&quot;/&amp;gt;
    	&amp;lt;appender-ref ref=&quot;CONSOLE&quot;/&amp;gt;
    	&amp;lt;appender-ref ref=&quot;INFO_DEFAULT_FILE_APPENDER&quot;/&amp;gt;
    	&amp;lt;appender-ref ref=&quot;ERROR_DEFAULT_FILE_APPENDER&quot;/&amp;gt;
    &amp;lt;/logger&amp;gt;
    &amp;lt;root level=&quot;ERROR&quot;&amp;gt;
    	&amp;lt;appender-ref ref=&quot;CONSOLE&quot;/&amp;gt;
    	&amp;lt;appender-ref ref=&quot;INFO_DEFAULT_FILE_APPENDER&quot;/&amp;gt;
    	&amp;lt;appender-ref ref=&quot;ERROR_DEFAULT_FILE_APPENDER&quot;/&amp;gt;
    &amp;lt;/root&amp;gt;
     
&amp;lt;/configuration&amp;gt;&lt;/code&gt;&lt;/pre&gt;</description>
      <category>spring</category>
      <category>logback</category>
      <category>properties</category>
      <category>spring boot</category>
      <category>spring.profiles.active</category>
      <category>설정파일</category>
      <author>박진만</author>
      <guid isPermaLink="true">https://jinmanp.tistory.com/52</guid>
      <comments>https://jinmanp.tistory.com/entry/Spring-Boot-%EC%84%A4%EC%A0%95-%ED%8C%8C%EC%9D%BCapplicationproperties-logbackxml-%EA%B0%9C%EB%B0%9C-%EC%9A%B4%EC%98%81-%EB%B6%84%EB%A6%AC-%EC%84%A4%EC%A0%95#entry52comment</comments>
      <pubDate>Tue, 21 Mar 2023 12:41:18 +0900</pubDate>
    </item>
    <item>
      <title>[AWS] Amazon Linux 1 jdk 17 설치</title>
      <link>https://jinmanp.tistory.com/entry/Amazon-Linux-1-jdk-17-%EC%84%A4%EC%B9%98</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;운영하고 있는 Amazon Linux 서버에 jdk 버전업을 하려고 aws 설치 가이드대로 시도&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/corretto/latest/corretto-17-ug/amazon-linux-install.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.aws.amazon.com/ko_kr/corretto/latest/corretto-17-ug/amazon-linux-install.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1678856990097&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Amazon Corretto 17 Installation Instructions for Amazon Linux 2 and Amazon Linux 2022 - Amazon Corretto 17&quot; data-og-description=&quot;Amazon Corretto 17 Installation Instructions for Amazon Linux 2 and Amazon Linux 2022 This topic describes how to install and uninstall Amazon Corretto 17 on a host or container running the Amazon Linux 2 or Amazon Linux 2022 operating systems. Install usi&quot; data-og-host=&quot;docs.aws.amazon.com&quot; data-og-source-url=&quot;https://docs.aws.amazon.com/ko_kr/corretto/latest/corretto-17-ug/amazon-linux-install.html&quot; data-og-url=&quot;https://docs.aws.amazon.com/ko_kr/corretto/latest/corretto-17-ug/amazon-linux-install.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/corretto/latest/corretto-17-ug/amazon-linux-install.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.aws.amazon.com/ko_kr/corretto/latest/corretto-17-ug/amazon-linux-install.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Amazon Corretto 17 Installation Instructions for Amazon Linux 2 and Amazon Linux 2022 - Amazon Corretto 17&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Amazon Corretto 17 Installation Instructions for Amazon Linux 2 and Amazon Linux 2022 This topic describes how to install and uninstall Amazon Corretto 17 on a host or container running the Amazon Linux 2 or Amazon Linux 2022 operating systems. Install usi&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.aws.amazon.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가이드 내용대로 해보았으나 설치되지 않음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가이드는 Amazon Linux 2 and Amazon Linux 2022 서버 대상 내 서버는 옛날 버전 Amazon Linux 라서 안되는 것 같음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;Linux&lt;span&gt; 용 설치파일로 설치 완료.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;설치방법&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1678857226937&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;wget https://corretto.aws/downloads/latest/amazon-corretto-17-x64-linux-jdk.rpm

sudo rpm -ivh amazon-corretto-17-x64-linux-jdk.rpm

-- java 설치 목록에서 jdk17 선택
sudo alternatives --config java

-- 버전확인
java -version&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 설치된 java 삭제 방법&lt;/p&gt;
&lt;pre id=&quot;code_1678857416124&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;- 설치된 jdk 목록 확인
rpm -qa | grep jdk

- 기존 설치된 jdk 삭제
sudo yum remove jdk-17-17.0.6-9.x86_64 -y&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Servers</category>
      <category>amazon linux</category>
      <category>Amazon Linux1</category>
      <category>JDK 17</category>
      <author>박진만</author>
      <guid isPermaLink="true">https://jinmanp.tistory.com/51</guid>
      <comments>https://jinmanp.tistory.com/entry/Amazon-Linux-1-jdk-17-%EC%84%A4%EC%B9%98#entry51comment</comments>
      <pubDate>Wed, 15 Mar 2023 14:17:54 +0900</pubDate>
    </item>
    <item>
      <title>[PostGIS] st_equals 함수 속도 느림 공간 index 안타는 문제</title>
      <link>https://jinmanp.tistory.com/entry/PostGIS-stequals-%ED%95%A8%EC%88%98-%EC%86%8D%EB%8F%84-%EB%8A%90%EB%A6%BC-%EA%B3%B5%EA%B0%84-index-%EC%95%88%ED%83%80%EB%8A%94-%EB%AC%B8%EC%A0%9C</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;공간 테이블 geometry 컬럼 gist 인덱스 설정되어 있는 상태&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;st_equals 함수 사용하면 속도가 너무 느림. 공간 인덱스 안타는 것 같음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;느린 쿼리문&lt;/p&gt;
&lt;pre id=&quot;code_1657528681125&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT t1.geom, t2.geom
FROM table_a t1 join table_a t2   
ON st_equals(t1.geom, t2.geom)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인덱스 타도록 쿼리문 수정&lt;/p&gt;
&lt;div class=&quot;revenue_unit_wrap&quot;&gt;
  &lt;div class=&quot;revenue_unit_item adsense responsive&quot;&gt;
    &lt;div class=&quot;revenue_unit_info&quot;&gt;반응형&lt;/div&gt;
    &lt;script src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot; async=&quot;async&quot;&gt;&lt;/script&gt;
    &lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block;&quot; data-ad-host=&quot;ca-host-pub-9691043933427338&quot; data-ad-client=&quot;ca-pub-4796638766531299&quot; data-ad-format=&quot;auto&quot;&gt;&lt;/ins&gt;
    &lt;script&gt;(adsbygoogle = window.adsbygoogle || []).push({});&lt;/script&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;pre id=&quot;code_1657528723194&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT t1.geom, t2.geom
FROM table_a t1 join table_a t2   
ON (st_equals(t1.geom, t2.geom) and t1.geom &amp;amp;&amp;amp; t2.geom)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 쿼리문 테스트 결과 인덱스 잘 탐&lt;/p&gt;</description>
      <category>PostGIS</category>
      <category>index</category>
      <category>PostGIS</category>
      <category>PostgreSQL</category>
      <category>st_equals</category>
      <category>느림</category>
      <category>속도</category>
      <category>인덱스</category>
      <author>박진만</author>
      <guid isPermaLink="true">https://jinmanp.tistory.com/50</guid>
      <comments>https://jinmanp.tistory.com/entry/PostGIS-stequals-%ED%95%A8%EC%88%98-%EC%86%8D%EB%8F%84-%EB%8A%90%EB%A6%BC-%EA%B3%B5%EA%B0%84-index-%EC%95%88%ED%83%80%EB%8A%94-%EB%AC%B8%EC%A0%9C#entry50comment</comments>
      <pubDate>Mon, 11 Jul 2022 17:40:18 +0900</pubDate>
    </item>
    <item>
      <title>[PostgresSQL] plsql(plpgsql) procedure/function 결과 파일로 output</title>
      <link>https://jinmanp.tistory.com/entry/PostgresSQL-plsqlplpgsql-procedurefunction-%EA%B2%B0%EA%B3%BC-%ED%8C%8C%EC%9D%BC%EB%A1%9C-output</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;procedure 수행 시 오류 발생 내용을 파일로 생성해서 확인하고 싶었다.&lt;/p&gt;
&lt;pre id=&quot;code_1656983808014&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;CREATE OR REPLACE PROCEDURE cloud.check_insert_error()
 LANGUAGE plpgsql
AS $procedure$
declare 

/***************************************************************************/
/* 임시변수 선언                                                              */
/***************************************************************************/
n_insert_cnt numeric := 0; -- 작업 건수
n_error_cnt numeric := 0; -- 오류 건수
n_re_insert_cnt numeric := 0; -- 오류 발생 후 재작업 건수
n_re_error_cnt numeric := 0; -- 재작업 오류 건수
n_error_cn text; -- 오류 내용
n_result_cn text; -- 작업 결과 내용

n_sqlstate text;
n_message_text text;

/********************************************************************************/
/* CURSOR 선언                                                                                                                                                       */ 
/********************************************************************************/
l_cursor RECORD;

/********************************************************************************/
/* CURSOR 문 선언                                                                                                                                                    */
/********************************************************************************/
c_cursor CURSOR FOR
SELECT a
	, b
	, c
	, d
	, e
	, f
	, g
	, h 
FROM table_a;

/***************************************************************************/
/* BEGIN PROCEDURE                                                         */
/***************************************************************************/
BEGIN

	FOR l_cursor IN c_cursor loop
		
		BEGIN
			
			INSERT INTO table_b
			(a, b, c, d, e, f, g, h)
			VALUES(
			l_cursor.a
			, l_cursor.b
			, l_cursor.c
			, l_cursor.d
			, l_cursor.e
			, l_cursor.f
			, l_cursor.g
            , l_cursor.h
			);
            
            n_insert_cnt := n_insert_cnt + 1;
			
			EXCEPTION WHEN OTHERS THEN  
				GET STACKED diagnostics 
			   	n_sqlstate := RETURNED_SQLSTATE,
				n_message_text := MESSAGE_TEXT;
				n_error_cn := concat(n_error_cn, (chr(13)||'오류 데이터 a : '||l_cursor.a||' ['||n_sqlstate||'] '||n_message_text));
			
				n_error_cnt := n_error_cnt + 1;
                
                BEGIN
                	INSERT INTO table_b
                    (a, b, c, d, e, f, g, h)
                    VALUES(
                    l_cursor.a
                    , l_cursor.b
                    , l_cursor.c
                    , l_cursor.d
                    , l_cursor.e
                    , l_cursor.f
                    , l_cursor.g
                    , l_cursor.h
                    );
                    
                    n_re_insert_cnt := n_re_insert_cnt + 1;

                    EXCEPTION WHEN OTHERS THEN  
                        GET STACKED diagnostics 
                        n_sqlstate := RETURNED_SQLSTATE,
                        n_message_text := MESSAGE_TEXT;
                        n_error_cn := concat(n_error_cn, (chr(13)||'재작업 오류 데이터 a : '||l_cursor.a||' ['||n_sqlstate||'] '||n_message_text));

                        n_re_error_cnt := n_re_error_cnt + 1;
                
                END;
		
		END;
		
	END LOOP;	
	
	n_result_cn := '작업 건수 : ' || n_insert_cnt || ', 오류 건수 : ' || n_error_cnt || ', 오류 발생 후 재작업 건수 : ' || n_re_insert_cnt || ', 재작업 오류 건수 : ' || n_re_error_cnt || n_error_cn;

	execute format($fmt$
		copy (select '%s') to 'D:\check_insert_error_result.txt' (format csv)
		$fmt$, n_result_cn);

	COMMIT;

END $procedure$
;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>PostgresSQL</category>
      <category>file</category>
      <category>function</category>
      <category>output file</category>
      <category>output txt file</category>
      <category>plpgsql</category>
      <category>plsql</category>
      <category>PostgresSQL</category>
      <category>Procedure</category>
      <author>박진만</author>
      <guid isPermaLink="true">https://jinmanp.tistory.com/49</guid>
      <comments>https://jinmanp.tistory.com/entry/PostgresSQL-plsqlplpgsql-procedurefunction-%EA%B2%B0%EA%B3%BC-%ED%8C%8C%EC%9D%BC%EB%A1%9C-output#entry49comment</comments>
      <pubDate>Tue, 5 Jul 2022 10:33:31 +0900</pubDate>
    </item>
  </channel>
</rss>