<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>a_a.log</title>
        <link>https://velog.io/</link>
        <description>개발세포 이야기</description>
        <lastBuildDate>Sun, 01 Feb 2026 01:17:32 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. a_a.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/a_a" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[JPA] JPA 영속성 컨텍스트란? with EntityManager #1]]></title>
            <link>https://velog.io/@a_a/JPA-JPA-%EC%98%81%EC%86%8D%EC%84%B1-%EC%BB%A8%ED%85%8D%EC%8A%A4%ED%8A%B8%EB%9E%80-with-EntityManager-1</link>
            <guid>https://velog.io/@a_a/JPA-JPA-%EC%98%81%EC%86%8D%EC%84%B1-%EC%BB%A8%ED%85%8D%EC%8A%A4%ED%8A%B8%EB%9E%80-with-EntityManager-1</guid>
            <pubDate>Sun, 01 Feb 2026 01:17:32 GMT</pubDate>
            <description><![CDATA[<p>본 글에 앞서 JPA의 구동 방식과 EntityManager, EntityManagerFactory에 대해 잘 모른다면 아래 글을 먼저 참고하시는 것이 좋습니다.  </p>
<p>[웹 개발/Jpa] - 
<a href="https://velog.io/@a_a/JPA-JPA%EA%B5%AC%EB%8F%99-%EB%B0%A9%EC%8B%9D-EntityManager-EntityManagerFactory-%EB%9E%80">[jpa] JPA구동 방식 + EntityManager, EntityManagerFactory 란?</a></p>
<p> <br><br></p>
<h1 id="📌-jpa-영속성-컨텍스트">📌 JPA 영속성 컨텍스트</h1>
<h2 id="◾-entitymanager">◾ EntityManager</h2>
<p>영속성 컨텍스트를 이해하기에 앞서, JPA구동 방식 포스팅에서 <code>EntityManager</code>에 대해 알아보았지만 다시 짧게 요약하면, <code>EntityManager</code>는 <strong>엔티티를 관리</strong>하는 역할을 하여 <strong>데이터베이스에 CRUD</strong>를 할 수 있게 하는 JPA의 핵심적인 역할을 하는 녀석이다.</p>
<p>&#39;엔티티매니저는 생성될 때 영속성 컨텍스트라는 것을 함께 생성해 이것을 통해 관리한다.&#39; 라고 하였다. 이 말은 텍스트 그대로 <strong>엔티티매니저가 생성될 때 영속성 컨텍스트라는 것도 함께 생성이 된다는 것이다.</strong> </p>
<p>그렇다면 영속성 컨텍스트란 무엇일까?</p>
<p><br><br></p>
<h2 id="◾-영속성-컨텍스트">◾ 영속성 컨텍스트</h2>
<p>JPA 학습에 있어 가장 중요한 것 2가지를 말한다면 아래와 같다고 한다.
<br></p>
<blockquote>
<ol>
<li>객체와 관계형 데이터베이스 매핑하기<ol start="2">
<li>영속성 컨텍스트</li>
</ol>
</li>
</ol>
</blockquote>
<br>


<p>1번은 DB를 어떻게 설계하고, 객체를 어떻게 설계하여 이 두 가지를 어떻게 JPA로 매핑해서 쓸 것인지에 대한 설계와 관련된 부분이라면 2번은 JPA가 어떻게 동작하는가?와 관련이 있다. </p>
<p>이것을 명확히 이해하면 JPA가 내부적으로 어떻게 동작하는지를 이해할 수 있다. 영속성 컨텍스트는 아래와 같은 특징이 있다.
<br></p>
<p>💧객체를 관리하는데 사용되는 중요한 개념</p>
<p>💧JPA를 이해하기 위한 핵심요소</p>
<p>💧&quot;엔티티를 영구 저장하는 환경&quot;이라는 뜻</p>
<p>💧 EntityManager.persist(entity);</p>
 <br>

<p>영속성 컨텍스트는 &#39;엔티티를 영구 저장하는 환경&#39;이라는 뜻이다. 엔티티매니저를 이용하여 인스턴스 변수를 em이라하였을때 데이터베이스의 데이터를 변경하는 코드를 작성하고 <code>em.persist(entity)</code>를 호출하여 엔티티를 넣었다. </p>
<pre><code class="language-java">            //등록
            Member member = new Member();
            member.setId(2L);
            member.setName(&quot;hello!JPAAAA&quot;);
            em.persist(member);</code></pre>
<p>그렇다면 <code>em.persist()</code>를 통해 db에 저장이 되는것일까? 정확히 말하면 그렇지 않다. <code>persist()</code>는 db에 저장하는 것이 아니라 엔티티를 영속성 컨텍스트에 저장한다는 의미이다. db에 반영되는 시점이 궁금하다면 바로 아래를 참조하자</p>
<br>


<h3 id="💡db에-반영되는-시점">💡DB에 반영되는 시점</h3>
<p>그렇다면 db에 언제 반영되는것일까? <strong>실제로 데이터베이스에 저장되는 시점은 트랜잭션이 커밋될 때</strong>이다. JPA는 트랜잭션 단위로 데이터베이스와의 작업을 처리하므로, persist()를 호출하더라도 그 변화는 트랜잭션이 커밋되는 시점에 데이터베이스에 반영된다. </p>
<p>-&gt; 이 말은, 만일 트랜잭션이 롤백된다면 영속성 컨텍스트에 있는 변경 사항도 롤백되어 테이터베이스에는 아무런 영향을 미치지 않는다.</p>
<p>엔티티를 생성하면 그 안에 1:1로 영속성 컨텍스트라는 공간이 생성이 된다. 이를 아래와 같이 그림으로 그려보았다. 
<img src="https://velog.velcdn.com/images/a_a/post/415edc16-b673-47d7-bb64-da7865e538d9/image.png" alt=""></p>
<p>em.persist(entity)를 호출하게 되면 영속성 컨텍스트(persistence context)안에 객체를 저장하게 되는 것이다. 객체, 엔티티는 아래와 같은 생명주기를 가진다.</p>
<p> <br><br></p>
<h2 id="◾-엔티티의-생명주기">◾ 엔티티의 생명주기</h2>
<h3 id="-비영속-newtransient">• 비영속 (new/transient)</h3>
<p>엔티티 객체가 생성되고, 영속성 컨텍스트와 전혀 관계가 없는 새로운 상태이다.</p>
<p>→ 처음에 멤버 객체를 생성한 직후의 상태로, new상태라 하고 비영속이라한다. 영속성 컨텍스트와 전혀 관계없는 상태이다.</p>
<h3 id="-영속-managed-상태영속성-컨텍스트에-관리되는-상태">• 영속 (managed) 상태(영속성 컨텍스트에 관리되는 상태)</h3>
<p>→ entityManager.persist()를 사용하여 엔티티를 저장하면  영속 상태가 된다. 영어로는 managed. 영속성 컨텍스트에 의해 관리되는 상태이다. 이 상태에서 엔티티의 상태 변경이 자동으로 감지되고 데이터베이스와 동기화된다.</p>
<h3 id="-준영속-detached">• 준영속 (detached)</h3>
<p>영속 상태의 엔티티가 영속성 컨텍스트에서 분리되어 더 이상 관리되지 않는 상태이다. 엔티티매니저의 detach()메서드를사용하거나 트랜잭션이 종료될 때 해당 엔티티는 준영속 상태로 전환된다. </p>
<h3 id="-삭제-removed">• 삭제 (removed)</h3>
<p>엔티티가 삭제되는 상태이다. 엔티티매니저의 remove()메서드를 사용하여 엔티티를 삭제하면 해당 엔티티는 삭제 상태가 된다. </p>
<p>-&gt;삭제 상태의 엔티티는 영속성 컨텍스트에서 분리되고, 향후 엔티티의 상태 변경이나 삭제를 데이터베이스에 반영한다.</p>
<h2 id="brbrbr"> <br><br><br></h2>
<p><strong>Reference</strong></p>
<p>자바 ORM 표준 JPA 프로그래밍 - 기본편 / 김영한 / 인프런 강의</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Network] 네트워크 용어 : 서브넷 마스크]]></title>
            <link>https://velog.io/@a_a/Network-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EC%9A%A9%EC%96%B4-%EC%84%9C%EB%B8%8C%EB%84%B7-%EB%A7%88%EC%8A%A4%ED%81%AC</link>
            <guid>https://velog.io/@a_a/Network-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EC%9A%A9%EC%96%B4-%EC%84%9C%EB%B8%8C%EB%84%B7-%EB%A7%88%EC%8A%A4%ED%81%AC</guid>
            <pubDate>Fri, 30 Jan 2026 14:28:31 GMT</pubDate>
            <description><![CDATA[<h1 id="📌네트워크-용어">📌네트워크 용어</h1>
<h2 id="◾서브넷-마스크subnet-mask">◾서브넷 마스크(Subnet Mask)</h2>
<p>서브넷 마스크는 IP주소를 네트워크 부분과 호스트 부분으로 나누는 기준이다. 쉽게 말해서 서브넷 마스크는 이 둘 사이의 &#39;구분선&#39;과 같은 역할을 한다. 분리하는 역할을 하는 것이다!!</p>
<ul>
<li><p>1(255)의 비트: 네트워크 부분</p>
</li>
<li><p>0의 비트: 호스트 부분</p>
<p>1은 &#39;여기는 네트워크 부분이므로 건드리지 마&#39; , 0은 &#39;여기는 마음대로 할당해도 돼!&#39; 와 같은 것이다.<br><br><br></p>
</li>
</ul>
<h2 id="◾이해하기">◾이해하기</h2>
<p>예를 들어서, 
만약 마스크가 255.255.255.0 (/24)이라면, 이를 이진수로 풀면 아래와 같다. </p>
<pre><code>11111111.11111111.11111111.00000000 (1이 24개)</code></pre><p>위에서 1의 부분은 네트워크 부분이라고 했으므로 이는 앞에서부터 1이 있는 24번째 칸까지는 <strong>절대 변하지 않는 고유 이름</strong>이다 그리고 나머지 0이 있는 맨 뒷칸들은 변할 수 있는 부분이다. 
<br>
만일, 우리집의 IP가 192.168.0.3 이라면, <code>192.168.0</code> 까지는 마스크의 <code>1</code>이 덮고 있는 구역이라서 네트워크 이름이 된다. 
마지막 <code>3</code>은 마스크의 <code>0</code>이 덮고 있는 구역이라서 <strong>내 컴퓨터 번호(호스트)</strong>가 된다. </p>
<br>

<ol>
<li>192.168.0 =&gt; 변하지 않는 공통 주소</li>
<li>3 =&gt;  변수가 되는 나의 주소</li>
</ol>
<br>
즉, `192.168.0.1` 부터 `192.168.0.254`까지는 모두 같은 동네 사람인 것이다. (1번부터 254번까지 할당이 가능하다. )

<p>쉽게 생각하면 아파트에 401동이라는 건 공통 주소고, 그 안에서 101호부터,102호,..1404호.. 등 그 뒤는 하나 하나의 쓸 수 있는 주소가 된다. 401동이라는 것은 공통된 주소이고 그 안에서는 다른 주소를 가질 수 있다. </p>
<p>서브넷 마스크도 255로 된 즉 이진수로 말하면 1로 된 부분은 공통 주소이고 0 으로 된 부분은 호스트 주소가 된다. 0이 많으면 많을수록 자유자재로 주소를 많이 가질 수 있으므로, 아파트로 말하면 0이 많을수록 살 수 있는 가구 수가 늘어가는 것이다. </p>
<p>역할을 정리하면 아래와 같다. 
<br></p>
<h2 id="◾서브넷-마스크의-역할">◾서브넷 마스크의 역할</h2>
<p>역할: IP 주소의 범위를 쪼개서 네트워크를 효율적으로 관리하고 보안을 강화한다. </p>
<p>네트워크를 잘게 쪼개는 것을 서브네팅이라고 한다. 이는 보안적으로 네트워크를 분리 서로 접근하지 못하게 막는다. </p>
<p>또 한 동네에 사람이 너무 많이 살면 소음이 심해지는 것처럼, 네트워크를 쪼개서 부하를 줄인다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JPA] JPA구동 방식 + EntityManager, EntityManagerFactory 란?]]></title>
            <link>https://velog.io/@a_a/JPA-JPA%EA%B5%AC%EB%8F%99-%EB%B0%A9%EC%8B%9D-EntityManager-EntityManagerFactory-%EB%9E%80</link>
            <guid>https://velog.io/@a_a/JPA-JPA%EA%B5%AC%EB%8F%99-%EB%B0%A9%EC%8B%9D-EntityManager-EntityManagerFactory-%EB%9E%80</guid>
            <pubDate>Mon, 26 Jan 2026 11:43:11 GMT</pubDate>
            <description><![CDATA[<h2 id="📌jpa-동작">📌JPA 동작</h2>
<h3 id="◾jpa-구동-방식">◾JPA 구동 방식</h3>
<p>JPA구동 방식은 아래와 같다. JPA는 <code>Persistence</code>라는 클래스가 존재한다.
<br></p>
<ol>
<li><p>Persistence클래스에서 <code>META-INF/persistence.xml</code>라 하는 설정 정보를 읽는다.</p>
</li>
<li><p><code>EntityManagerFactory</code>라는 클래스를 만든다.</p>
</li>
<li><p><code>EntityManagerFactory</code>에서 필요할 때마다 <code>EntityManger</code>라는 것을 만들어 동작한다.</p>
<br>

</li>
</ol>
<p><code>persistence.xml</code>은 설정 파일이다. JPA구현체에서 어떻게 동작해야 하는지에 대한 정보를 제공한다. 그렇다면 EntityManager와 EntityManagerFactory란 무엇일까? 다음 단락을 참조하자</p>
<p> <br><br></p>
<h2 id="📌entitymanager와-entitymanagerfactory">📌EntityManager와 EntityManagerFactory</h2>
<h3 id="◾entitymanager란">◾EntityManager란?</h3>
<p>이름 그대로 <code>Entity</code>를 관리하는 역할을 하는 클래스라고 보면 된다. <code>EntityManager</code>가 엔티티들을 어떻게 관리할까? 
<br>
<code>EntityManager</code>가 생성될 때 안에 영속성 컨텍스트라는 것을 함께 생성해 이것을 통해 관리한다. 영속성 컨텍스트에 대한 설명은 다음 포스팅을 참조하자. <code>EntityManager</code>에 대해 정리하면 아래와 같다.
<br></p>
<h4 id="🔻entitymanager-특징">🔻EntityManager 특징</h4>
<p>💧 엔티티를 관리하는 역할을 한다</p>
<p>💧 JPA의 대부분의 기능을 제공한다</p>
<p>💧 엔티티를 DB에 CRUD할 수 있게 한다</p>
<p>💧 엔티티 매니저는 쓰레드간에 공유하면 안된다. (아래 설명 참조)</p>
<p>💧 JPA의 모든 데이터 변경은 트랜잭션 안에서 실행 (아래 설명 참조)</p>
 <br>



<p>엔티티 매니저는 DB커넥션을 유지하면서 DB와 통신을 할 정도로 밀접한 관계가 있으므로 <strong>스레드 간에 절대 공유하거나 재사용하면 안된다.</strong> 사용하고 버려야한다. 자세한 설명은 아래 더보기를 참조하자
<br></p>
<pre><code>💡 EntityManager를 스레드 간에 공유하면 안 되는 이유 

### 1. 영속성 컨텍스트의 동시성 문제
각각의 엔티티 매니저는 자체 영속성 컨텍스트를 가지고 있습니다. 영속성 컨텍스트는 엔티티의 상태를 추적하고 캐싱하는 데 사용됩니다. 스레드 간에 영속성 컨텍스트를 공유하면 여러 스레드에서 동시에 수정하려 할 수 있어 데이터 정합성이 깨질 수 있습니다.

### 2. 트랜잭션 관리의 어려움
하나의 스레드에서 시작된 트랜잭션은 해당 스레드에서만 커밋 또는 롤백되어야 합니다. 엔티티 매니저를 공유하면 트랜잭션의 범위가 모호해져 예상치 못한 커밋이나 롤백이 발생할 수 있습니다.

### 3. 캐시와 일관성 문제
각 영속성 컨텍스트의 1차 캐시는 스레드별로 독립적이어야 합니다. 공유 시 캐시 관리가 불가능해져 데이터 일관성을 보장할 수 없습니다.

**결론:** 따라서 각각의 스레드에서 독립적인 엔티티 매니저 인스턴스를 사용해야 합니다.
</code></pre><br>




<p>엔티티 매니저의 메서드들을 이용해 데이터를 변경하는 작업은 트랜잭션 안에서 실행해야한다. 그리고 변경이 완료된 후에 트랜잭션을 커밋하여 데이터베이스에 실제로 반영된다. 커밋 전에는 쿼리가 생성되지 않는다 즉 트랜잭션을 커밋할 때까지 데이터베이스에 실제로 변경 사항이 반영되지 않는다. </p>
<br>
(엔티티 매니저의 메서드들을 활용한 CRUD에 대해서는 본 글의 가장 아래의 예제 코드를 참조할 수 있다)

 <br>

<br>

<h3 id="◾entitymanagerfactory">◾EntityManagerFactory</h3>
<p>엔티티 매니저는 사용 후 버려야 한다고 했다. 즉 요청이 올때마다 엔티티매니저는 계속 생성이 되어야한다. 이것을 누가 해줄까? EntityManagerFactory이다. 이름 그대로 엔티티매니저를 만들어내는 공장이라고 보면된다. 엔티티 매니저를 생성하고 관리하는 역할을 한다.   엔티티 매니저는 여러 스레드가 동시에 접근해도 안전하다. 단순히 엔티티 매니저만 만들기 때문이다.  엔티티 매니저는 보통 애플리케이션의 라이프사이클 동안 단일 인스턴스(1개)만 생성된다.</p>
<p>엔티티 매니저와 엔티티 매니저 팩토리에 대해 알아보았다 웹 애플리케이션을 개발한다면 고객 요청이 올 때 이 두 개가 어떻게 동작하는 가는 아래와 같다.</p>
<ol>
<li><p>고객의 요청이 온다</p>
</li>
<li><p>EntityManagerFactory가 EntityManager를 생성한다</p>
</li>
<li><p>EntityManager는 데이터베이스 커넥션을 사용해 DB를 사용하게 된다</p>
</li>
</ol>
<p>다음은 엔티티 팩토리를 생성해 이를 통해 엔티티 매니저를 생성하는 코드이다.</p>
<pre><code>    //persistence-unit의 name=&quot;hello&quot; 인자로 전달
    EntityManagerFactory emf = Persistence.createEntityManagerFactory(&quot;hello&quot;);
    EntityManager em = emf.createEntityManager();</code></pre><p>엔티티 매니저와 엔티티 매니저 팩토리를 이해했다면 이들과 더불어 동작하는 영속성 컨텍스트는 무엇일까? JPA를 이해하는 데 중요한 역할을 하는 녀석이다. 이는 다음 글에서 알아볼 예정이다. 아래는 앞서 설명한 내용에 대한  jpa예제 코드이다 </p>
<p><br><br></p>
<h3 id="◾entitymanagerfactory-entitymanager를-이용한-jpa-예제-코드">◾EntityManagerFactory, EntityManager를 이용한 JPA 예제 코드</h3>
<pre><code class="language-public">        //persistence-unit의 name=&quot;hello&quot;
        EntityManagerFactory emf = Persistence.createEntityManagerFactory(&quot;hello&quot;);

        EntityManager em = emf.createEntityManager();

        EntityTransaction tx = em.getTransaction();
        tx.begin(); // 트랜잭션 안에서 작업을 해야한다.

        try {
            //등록
//            Member member = new Member();
//            member.setId(2L);
//            member.setName(&quot;hello!JPAAAA&quot;);
//            em.persist(member);

            //조회 find()메서드
//            Member findMember = em.find(Member.class, 1L);
            //수정
//            findMember.setName(&quot;헨노우 제이피에이&quot;);

            //삭제 remove()메서드
//            em.remove(member);

            tx.commit();
        } catch (Exception e) {
            tx.rollback();
        }finally {
            em.close();
        }
        emf.close(); // 엔티티 매니저 팩토리 종료. 애플리케이션을 종료 시 emf도 종료해야한다.
    }</code></pre>
<p>코드를 보면 트랜잭션을 시작하고(<code>tx.begin()</code>) 엔티티매니저를 이용해 DB작업에 대한 코드를 작성한다. 그리고 트랜잭션을 이용해 커밋한다(실제 이 시점에 데이터베이스에 변경이 일어난다)
<br>
<code>em.persist()</code>시점이 아닌 트랜잭션을 커밋하는 시점에 데이터베이스 변경이 일어남을 기억하자. 이 부분은 영속성 컨텍스트와 관련이 있는데 이는 다음 포스팅에서 할 예정이다</p>
<br>
엔티티 매니저는 사용 후 반드시 종료한다. 전체 애플리케이션을 종료 시에는 엔티티매니저팩토리도 종료한다.







<hr>
<p><strong>Reference</strong></p>
<p>자바 ORM 표준 JPA 김영한</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Java/systemd] 자바 애플리케이션 매니저 systemd 사용법]]></title>
            <link>https://velog.io/@a_a/Javasystemd-%EC%9E%90%EB%B0%94-%EC%95%A0%ED%94%8C%EB%A6%AC%EC%BC%80%EC%9D%B4%EC%85%98-%EB%A7%A4%EB%8B%88%EC%A0%80-systemd-%EC%82%AC%EC%9A%A9%EB%B2%95</link>
            <guid>https://velog.io/@a_a/Javasystemd-%EC%9E%90%EB%B0%94-%EC%95%A0%ED%94%8C%EB%A6%AC%EC%BC%80%EC%9D%B4%EC%85%98-%EB%A7%A4%EB%8B%88%EC%A0%80-systemd-%EC%82%AC%EC%9A%A9%EB%B2%95</guid>
            <pubDate>Sun, 25 Jan 2026 09:41:25 GMT</pubDate>
            <description><![CDATA[<h2 id="🔸systemd란">🔸systemd란</h2>
<p><a href="https://velog.io/@a_a/pm2NodeJS-pm2-%EC%9E%90%EC%A3%BC-%EC%93%B0%EB%8A%94-%EB%AA%85%EB%A0%B9%EC%96%B4-%EC%A0%95%EB%A6%AC">[pm2/NodeJS] pm2 자주 쓰는 명령어 정리</a></p>
<p>지난 시간에는 <code>NodeJS</code> 서버를 사용할 때 이를 리눅스 서버에 배포 시 프로세스를 관리하는 도구인<code>pm2</code>에 대해 정리해보았다. 이번 시간에는 비슷한 성격이지만 <code>Java</code> 언어를 사용할 때 서버를 다루는 <code>systemd</code>에 대해 알아볼 것이다. </p>
<p><code>systemd</code>란, 리눅스에서 서버 프로그램을 자동으로 실행, 중지, 재시작해주는 기본 서비스 관리자라고 할 수 있다. 노드에서 pm2의 역할과 동일한데, 사실 노드의 pm2를 OS레벨로 마든게 systemd라고 보면 된다고 한다. </p>
<br>

<h2 id="🔸systemd-역할">🔸systemd 역할</h2>
<ul>
<li>부팅 및 서비스 관리 </li>
<li>프로세스 감시 및 자동 복구 </li>
<li>리소스 및 로그 통합 관리</li>
</ul>
<p>systemd를 한 줄로 요약하면, <code>.jar</code> 파일을 리눅스 시스템의 정식 구성원으로 등록시켜주는 도구이다. 그리고 그 외에도 위와 같은 역할들을 수행한다. 
<br></p>
<h2 id="🔸systemd-사용하기">🔸systemd 사용하기</h2>
<h3 id="◾1-서비스-파일-생성하기">◾1. 서비스 파일 생성하기</h3>
<p>리눅스 시스템 서비스 설정 디렉토리에 <code>.service</code>파일을 생성한다. 이 때 루트 권한이 필요하다. </p>
<ul>
<li><p>서비스 파일 생성</p>
<pre><code class="language-bash">sudo vi /etc/systemd/system/myapp.service</code></pre>
</li>
<li><p>서비스 내용 작성하기 </p>
<pre><code class="language-bash">[Unit]
Description=Java Spring Boot Application
After=network.target
</code></pre>
</li>
</ul>
<p>[Service]</p>
<h1 id="애플리케이션을-실행할-사용자-보안상-root-권한보다-별도-계정-권한-권장">애플리케이션을 실행할 사용자 (보안상 root 권한보다 별도 계정 권한 권장)</h1>
<p>User=ubuntu</p>
<h1 id="애플리케이션-경로">애플리케이션 경로</h1>
<p>WorkingDirectory=/home/ubuntu/app</p>
<h1 id="실행-명령어-절대-경로-사용-권장">실행 명령어 (절대 경로 사용 권장)</h1>
<p>ExecStart=/usr/bin/java -jar /home/ubuntu/app/application.jar</p>
<h1 id="프로세스가-죽었을-때-재시작-설정">프로세스가 죽었을 때 재시작 설정</h1>
<p>Restart=always
RestartSec=10</p>
<h1 id="로그-설정">로그 설정</h1>
<p>StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=myapp</p>
<p>[Install]
WantedBy=multi-user.target</p>
<pre><code>

### ◾2. 서비스 활성화 및 실행


- systemd 설정 반영하기</code></pre><p>sudo systemctl daemon-reload</p>
<pre><code>&lt;br&gt;

- 서비스 시작</code></pre><p>sudo systemctl start myapp</p>
<pre><code>&lt;br&gt;

- 부팅 시 자동 시작 등록</code></pre><p>sudo systemctl enable myapp</p>
<pre><code>&lt;br&gt;

- 상태 확인

sudo systemctl status myapp</code></pre><p><code>pm2</code>의 <code>pm2 status(pm2 list)</code> 와 같은 역할이다. </p>
<pre><code>&lt;br&gt;



### ◾3. 로그 확인

- 전체 로그 보기</code></pre><p>journalctl -u myapp</p>
<pre><code>

- 실시간 로그 보기 (Tail)</code></pre><p>journalctl -u myapp -f</p>
<pre><code>
`journalctl`을 통해 로그를 관리한다. pm2의 `pm2 logs`와 같은 역할이다. 

&lt;br&gt;


### ◾JAR 파일 교체(배포) 시 
새 버전의 `.jar` 파일을 업로드한 후에는 아래 명령어로 간단히 재시작하면 된다. </code></pre><p>sudo systemctl restart myapp</p>
<pre><code></code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[pm2/NodeJS] pm2 자주 쓰는 명령어 정리]]></title>
            <link>https://velog.io/@a_a/pm2NodeJS-pm2-%EC%9E%90%EC%A3%BC-%EC%93%B0%EB%8A%94-%EB%AA%85%EB%A0%B9%EC%96%B4-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@a_a/pm2NodeJS-pm2-%EC%9E%90%EC%A3%BC-%EC%93%B0%EB%8A%94-%EB%AA%85%EB%A0%B9%EC%96%B4-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Sat, 24 Jan 2026 13:37:18 GMT</pubDate>
            <description><![CDATA[<h2 id="🔸pm2란">🔸pm2란</h2>
<p><code>pm2</code>란 <code>NodeJS</code> 서버를 백그라운드에서 실행하고 관리할 수 있게 해주는 도구이다. 노드 서버를 다룬다면 한 번쯤은 다루게 되는 프로세스 관리자이다. 리눅스 서버에서 노드 서버를 다룰 때 사용하게 된다.
<br>
서버를 켜고 끄는 것 말고도 모니터링, 최적화 등 여러 기능이 많은 도구이다. 이번 시간에는 자주 사용하는 <code>pm2</code> 명령어를 알아볼 것이다. 명령어가 어렵지 않고 직관적인 편이라 사용하기 용이했다. </p>
<h2 id="🔸pm2-명령어">🔸pm2 명령어</h2>
<h3 id="◾pm2-전역-설치">◾pm2 전역 설치</h3>
<p>pm2를 <code>-g</code>  옵션을 붙여 전역으로 설치한다. 어디서든 pm2 명령어를 사용할 수 있게 해준다. 서버 전체에서 프로세스를 관리하는 도구이기 때문에 전역으로 설치한다. </p>
<pre><code>npm install -g pm2</code></pre><br>

<h3 id="◾pm2-설치-확인">◾pm2 설치 확인</h3>
<p>pm2가 정상 설치되었는지 확인한다. </p>
<pre><code>pm2 -v</code></pre><br>

<h3 id="◾서버-실행하기">◾서버 실행하기</h3>
<h4 id="🔻js-파일-실행">🔻JS 파일 실행</h4>
<pre><code>pm2 start app.js</code></pre><br>

<h4 id="🔻이름-지정하여-실행하기">🔻이름 지정하여 실행하기</h4>
<pre><code>pm2 start app.js --name my-app</code></pre><br>


<h3 id="◾상태-확인하기-多">◾상태 확인하기 (多)</h3>
<h4 id="🔻전체-프로세스서버-목록-조회">🔻전체 프로세스(서버) 목록 조회</h4>
<pre><code>pm2 list</code></pre><p>위에서 <code>start</code>명령어로 실행시킨 서버들이 돌아가고 있을 것이다. 아래 명령어로 전체 프로세스 목록을 확인할 수 있다.</p>
<p><code>start</code>로 실행시킨 것, <code>stop</code>되어있는 것 등 삭제되지 않고 pm2로 올린 서버들 전체를 보여준다. </p>
<p>pm2 사용 시 가장 많이 사용하는 명령어이다. <code>pm2 status</code>도 같은 명령어이다. 
<br></p>
<h4 id="🔻상태-정보-조회">🔻상태 정보 조회</h4>
<pre><code>pm2 show my-app</code></pre><h3 id="◾서버-중지">◾서버 중지</h3>
<pre><code>pm2 stop my-app</code></pre><h3 id="◾서버-재시작">◾서버 재시작</h3>
<pre><code>pm2 reload my-app</code></pre><p><code>restart</code>는 그냥 껐다 키는 것이지만, reload는 무중단 재시작이라고한다. (단, 클러스터 모드일 때)</p>
<h3 id="◾서버-제거">◾서버 제거</h3>
<pre><code>pm2 delete my-app</code></pre><p>pm2에서 제거된다. stop은 서버를 중단하지만, delete는 완전 제거이다. </p>
<h3 id="◾로그-보기多">◾로그 보기(多)</h3>
<p>실무에서 정말 많이 사용하는 명령어 중 하나이다. </p>
<h4 id="🔻현재-전체-로그-보기">🔻현재 전체 로그 보기</h4>
<pre><code>pm2 logs</code></pre><h4 id="🔻특정-앱-로그-보기">🔻특정 앱 로그 보기</h4>
<pre><code>pm2 logs my-app
pm2 logs --lines 100 </code></pre><p>로그 파일 위치는 <code>~/ .pm2/logs/</code>에서 확인할 수 있다. 
<br></p>
<h3 id="◾서버-재부팅-시-자동-실행">◾서버 재부팅 시 자동 실행</h3>
<h4 id="1-startup-명령-실행">1. startup 명령 실행</h4>
<pre><code>pm2 startup</code></pre><h4 id="2-출력-명령어-실행">2. 출력 명령어 실행</h4>
<pre><code>sudo env PATH=$PATH:/usr/bin pm2 startup systemd -u ubuntu --hp /home/ubuntu
</code></pre><p>1번에서 startup명령어를 통해 실행시키면 해당 경로에 맞는 명령어를 알려준다. 그대로 실행시킨다. </p>
<h4 id="3-저장-명령어">3. 저장 명령어</h4>
<pre><code>pm2 save</code></pre><p>이제 서버 재부팅해도 자동으로 실행된다. </p>
<p>실무에서 정말 유용한 명령어이다. </p>
<p>이 작업을 해두지 않으면 현재 pm2를 이용해 띄운 서버들이 존재하는 엄마 서버(?)가 죽으면 다시 켰을 때 서버들이 당연히 종료되어 있기 때문에 수동으로 다시 켜줘야하는데, 이 명령어를 통해 방지할 수 있다. 
<br></p>
<h3 id="◾클러스터-모드">◾클러스터 모드</h3>
<pre><code>pm2 start app.js -i max</code></pre><ul>
<li>CPU 코어 수만큼 인스터스 실행</li>
<li>로드밸런싱 자동</li>
</ul>
<br>

<p>다음 시간에는 ecosystem.config.js 파일을 이용하여 사용하는 것도 알아볼 것이다. </p>
<h3 id="⭐자주-사용하는-명령어-요약">⭐자주 사용하는 명령어 요약</h3>
<p><code>pm2 list</code> 를 통해 아이디를 확인할 수 있는데 아이디를 이용해서도 명령어를 이용할 수 있다. <code>pm2 start app.js</code> 대신 <code>pm2 start 0</code> 과 같이 사용한다. </p>
<pre><code>pm2 start 1 #서버 시작
pm2 list #모든 서버 리스트 출력
pm2 logs #전체 로그 출력 
pm2 logs 1 #하나의 서버 로그 출력
pm2 reload 1 #서버 재시작
pm2 stop 1 #서버 중단
pm2 detete 1 #서버 삭제</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[error/NestJS] npm install 패키지 설치 시 Cannot read properties of null (reading 'matches') 에러]]></title>
            <link>https://velog.io/@a_a/errorNestJS-npm-install-%ED%8C%A8%ED%82%A4%EC%A7%80-%EC%84%A4%EC%B9%98-%EC%8B%9C-Cannot-read-properties-of-null-reading-matches-%EC%97%90%EB%9F%AC</link>
            <guid>https://velog.io/@a_a/errorNestJS-npm-install-%ED%8C%A8%ED%82%A4%EC%A7%80-%EC%84%A4%EC%B9%98-%EC%8B%9C-Cannot-read-properties-of-null-reading-matches-%EC%97%90%EB%9F%AC</guid>
            <pubDate>Tue, 20 Jan 2026 13:15:14 GMT</pubDate>
            <description><![CDATA[<h2 id="◾에러-파악하기">◾에러 파악하기</h2>
<h3 id="✔️background">✔️Background</h3>
<p>cron 기능을 NestJS(NodeJS) 에서 사용하기 위해 <code>npm install @nestjs/schedule</code> 명령어를 통해 설치를 시도하였다. </p>
<br>

<h3 id="✔️에러-발생-상황">✔️에러 발생 상황</h3>
<p>그런데 패키지가 설치가 되지 않고, 다음과 같은 에러가 발생했다. 
이 패키지에 국한된 문제는 아니고, 그 외에도 <code>npm install</code> 시 가끔 발생하는 에러라고 한다. 
<br></p>
<pre><code>PS D:\workspace\apple_server&gt; npm install @nestjs/schedule
npm ERR! Cannot read properties of null (reading &#39;matches&#39;)

npm ERR! A complete log of this run can be found in: C:\Users\user\AppData\Local\npm-cache\_logs\2025-12-05T06_30_33_139Z-debug-0.log</code></pre><p><br><br><br></p>
<h2 id="◾에러-해결하기">◾에러 해결하기</h2>
<h3 id="🔨시도1--캐시-초기화">🔨시도1 : 캐시 초기화</h3>
<pre><code>PS D:\workspace\apple_server&gt; npm cache clean --force
npm WARN using --force Recommended protections disabled.</code></pre><br>
깨진 캐시 때문에 이런 일이 발생하기도 한다고 해서 npm캐시를 완전 초기화 하는 명령어를 실행해보았다. 
<br>


<p>이렇게 캐시를 지우고, 다시 설치 명령어를 실행해보았으나 같은 에러가 발생했다. </p>
<p><br><br></p>
<h3 id="🔨시도2--node_modules와-package-lockjson-제거-성공">🔨시도2 : node_modules와 package-lock.json 제거 (성공)</h3>
<p>두 번째는 package-lock.json파일과 node_modules 폴더를 삭제 후 재설치 하는 것이다. 시간은 조금 걸릴 수 있지만 확실한 방법이다. 
<br></p>
<ul>
<li>package-lock.json 파일, node_module폴더 삭제<pre><code>rm -rf node_modules package-lock.json 
npm install</code></pre></li>
</ul>
<p>이렇게 삭제하고 재설치를 진행한 후, 필요한 패키지를 설치해보니 정상적으로 설치되었다!</p>
<p><br><br>
 참고로 버전 불일치 때문에 위와 같은 에러가 일어나기도 한다고 한다. 나의 경우 캐시 삭제는 해결되지 않았고, 노드 모듈 폴더와 락 파일 삭제가 효과가 있었다.  </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[postgreSQL] 기존 유저를 슈퍼 유저로 변경하기 ]]></title>
            <link>https://velog.io/@a_a/postgreSQL-%EA%B8%B0%EC%A1%B4-%EC%9C%A0%EC%A0%80%EB%A5%BC-%EC%8A%88%ED%8D%BC-%EC%9C%A0%EC%A0%80%EB%A1%9C-%EB%B3%80%EA%B2%BD%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@a_a/postgreSQL-%EA%B8%B0%EC%A1%B4-%EC%9C%A0%EC%A0%80%EB%A5%BC-%EC%8A%88%ED%8D%BC-%EC%9C%A0%EC%A0%80%EB%A1%9C-%EB%B3%80%EA%B2%BD%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 21 Oct 2025 06:23:45 GMT</pubDate>
            <description><![CDATA[<h3 id="🔸슈퍼-유저-권한-부여하기">🔸슈퍼 유저 권한 부여하기</h3>
<p>DB에 권한이 없어서 데이터베이스에 접근을 못하는 상황이 있다. 이 경우 내가 연결한 사용자에게 슈퍼유저 권한을 주면 된다. </p>
<br>
이미 유저는 생성된 상태이므로 존재하는 유저를 슈퍼유저로 변경해보자 

<br>

<p>아래 명령어로 슈퍼유저로 변경할 수 있다. </p>
<br>


<pre><code>ALTER USER &lt;username&gt; WITH SUPERUSER;</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[NestJS] 서버 시작 시 자동 실행 로직 넣기 (자동으로 DB 데이터 넣기) ]]></title>
            <link>https://velog.io/@a_a/NestJS-%EC%84%9C%EB%B2%84-%EC%8B%9C%EC%9E%91-%EC%8B%9C-%EC%9E%90%EB%8F%99-%EC%8B%A4%ED%96%89-%EB%A1%9C%EC%A7%81-%EB%84%A3%EA%B8%B0-%EC%9E%90%EB%8F%99%EC%9C%BC%EB%A1%9C-DB-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%84%A3%EA%B8%B0</link>
            <guid>https://velog.io/@a_a/NestJS-%EC%84%9C%EB%B2%84-%EC%8B%9C%EC%9E%91-%EC%8B%9C-%EC%9E%90%EB%8F%99-%EC%8B%A4%ED%96%89-%EB%A1%9C%EC%A7%81-%EB%84%A3%EA%B8%B0-%EC%9E%90%EB%8F%99%EC%9C%BC%EB%A1%9C-DB-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%84%A3%EA%B8%B0</guid>
            <pubDate>Fri, 03 Oct 2025 09:26:39 GMT</pubDate>
            <description><![CDATA[<h2 id="🔸onmoduleinit">🔸OnModuleInit</h2>
<p>서버 시작 시 자동으로 서버에서 초기화를 해야하거나, 무언가 초기에 해야할 작업을 부팅 시 실행시켜야 할 경우가 있다. </p>
<p>이 때 NestJS에서는 <code>OnModuleInit</code> 인터페이스를 사용할 수 있다. </p>
<ul>
<li><p>인터페이스: OnModuleInit</p>
</li>
<li><p>역할: 모듈이 초기화될 때 자동으로 호출되는 onModuleInit() 메서드를 구현하게 해줌.</p>
</li>
<li><p>사용 시점: NestJS가 모듈과 의존성 주입을 다 끝내고 난 후 호출.
<br><br><br></p>
</li>
</ul>
<h2 id="🔸사용법">🔸사용법</h2>
<pre><code>import { Injectable, OnModuleInit } from &#39;@nestjs/common&#39;;

@Injectable()
export class MyService implements OnModuleInit {

  onModuleInit() {
    console.log(&#39;모듈이 초기화됨!&#39;);
    // 서버 시작 시 실행하고 싶은 코드 작성
    this.initializeData();
  }

  private initializeData() {
    console.log(&#39;기본 데이터 초기화 중...&#39;);
    // 예: DB에 기본값 넣기, 캐시 초기화 등
  }
}
</code></pre><p>implements OnModuleInit를 붙이고</p>
<p>onModuleInit() 메서드를 구현하면 됨.</p>
<p>NestJS가 자동으로 호출해 줌.</p>
<p><br><br></p>
<h2 id="🔸서버에-자동으로-db-데이터-적재">🔸서버에 자동으로 DB 데이터 적재</h2>
<p>기존 service에서 <code>OnModuleInit</code> 인터페이스를 implement하여 초기화 코드로 DB에 자동으로 권한 데이터를 저장하는 코드를 작성하였다. </p>
<p>확인 결과, </p>
<p>DB에 데이터가 성공적으로 들어간 것을 확인할 수 있다. 
<img src="https://velog.velcdn.com/images/a_a/post/21e1a9bd-292b-43b4-9c3c-9dce5c856515/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[zsh] zsh에서 프롬프트에 IP 주소와 현재 디렉터리 표시하기]]></title>
            <link>https://velog.io/@a_a/zsh-zsh%EC%97%90%EC%84%9C-%ED%94%84%EB%A1%AC%ED%94%84%ED%8A%B8%EC%97%90-IP-%EC%A3%BC%EC%86%8C%EC%99%80-%ED%98%84%EC%9E%AC-%EB%94%94%EB%A0%89%ED%84%B0%EB%A6%AC-%ED%91%9C%EC%8B%9C%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@a_a/zsh-zsh%EC%97%90%EC%84%9C-%ED%94%84%EB%A1%AC%ED%94%84%ED%8A%B8%EC%97%90-IP-%EC%A3%BC%EC%86%8C%EC%99%80-%ED%98%84%EC%9E%AC-%EB%94%94%EB%A0%89%ED%84%B0%EB%A6%AC-%ED%91%9C%EC%8B%9C%ED%95%98%EA%B8%B0</guid>
            <pubDate>Wed, 24 Sep 2025 07:08:00 GMT</pubDate>
            <description><![CDATA[<h2 id="backgroud">Backgroud</h2>
<p>계정명을 바꾸고, 프롬프트에 옛날 호스트명으로 뜨는 현상 때문에 호스트명을 현재 계정 이름과 동일하게 변경하였는데 이 때문인지 뒤에 경로가 뜨질 않았다. 
<br></p>
<p>보통은 내가 이동한 디렉터리가 뒤에 표시되는데, 나는 경로를 이동해도 여전히 <code>apple%</code> 로만 표시되었다. <code>cd</code>로 이동을 하고<code>pwd</code>나 <code>ls</code>로 확인을 해보니 디렉터리 이동은 계속해서 하는게 맞는데, 경로 표시가 프롬프트에서 되지 않았다. </p>
<p><br><br></p>
<h2 id="확인방법">확인방법</h2>
<p>아래 명령어로 확인을 했을 때, 빈 값이면 프롬프트가 간단하게 %만 보이는 거고, 아니라면 기본값으로 복구하려면 .zshrc를 새로 만들어야 한다. </p>
<pre><code class="language-bash">echo $PROMPT</code></pre>
<p>나는 따로 호스트명을 임의로 변경을 해서인지 여기 빈 값이 아니라 외계어같은 값이 나왔다. </p>
<p><br><br></p>
<h2 id="적용방법">적용방법</h2>
<h3 id="1-zshrc만들기">1. zshrc만들기</h3>
<p>아래 명령어를 이용해 zshrc를 만든다. 보통 관리자 권한으로 하지 않으면 파일을 다 작성하고 저장할 때 permission 에러가 뜨는 경우가 많아 아래처럼 sudo를 붙여주었다.</p>
<br>
zshrc파일을 만들어 설정해주자. 

<pre><code>sudo nano ~/.zshrc</code></pre><br>

<blockquote>
<p><strong>경로는 상관없을까?🤔</strong>
<code>~</code>는 현재 계정의 홈 디렉터리를 의미한다. 예를 들어, 사용자가 apple이라면 <code>/home/apple</code> 이다. 따라서 nano ~/.zshrc는 현재 디렉터리에 상관없이 항상 /home/apple/.zshrc 파일을 연다. </p>
</blockquote>
<p><br><br></p>
<h3 id="2-pmopt줄-추가">2. pmopt줄 추가</h3>
<p>내가 최종 원하는 결과가 나온 명령어였다. 
EX) <code>apple@123.123.1.1 /home %</code> 와 같은 형태 </p>
<pre><code>PROMPT=&quot;%n@$(hostname -I | cut -d&#39; &#39; -f1) %1~ %# &quot;</code></pre><p><br><br></p>
<h3 id="3-저장-후-적용">3. 저장 후 적용</h3>
<p>파일을 저장하고 빠져나온 후 아래 명령어를 통해 적용한다. </p>
<pre><code>source ~/.zshrc</code></pre><p><br><br></p>
<h4 id="변천사">변천사..</h4>
<p>적용이 정상적으로 될 때까지 zshrc파일을 수정하고 저장하고 source로 다시 적용하면서 반복했더니 원하는 대로 <code>&lt;계정명&gt;@&lt;IP주소&gt; &lt;디렉터리경로&gt;</code>이렇게 나왔다. </p>
<p><img src="https://velog.velcdn.com/images/a_a/post/62e6c5a7-8874-4dde-9adf-17b34052bdc8/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] DB 파티셔닝이란? ]]></title>
            <link>https://velog.io/@a_a/TIL-DB-%ED%8C%8C%ED%8B%B0%EC%85%94%EB%8B%9D%EC%9D%B4%EB%9E%80</link>
            <guid>https://velog.io/@a_a/TIL-DB-%ED%8C%8C%ED%8B%B0%EC%85%94%EB%8B%9D%EC%9D%B4%EB%9E%80</guid>
            <pubDate>Sun, 14 Sep 2025 14:15:08 GMT</pubDate>
            <description><![CDATA[<h2 id="📌데이터베이스-파티셔닝partitioning이란">📌데이터베이스 파티셔닝(partitioning)이란?</h2>
<h3 id="◾파티셔닝이란">◾파티셔닝이란</h3>
<p>데이터베이스 파티셔닝(partitioning)은 하나의 큰 테이블이나 인덱스를 물리적으로 여러 조각(파티션)으로 나누어 저장, 관리하는 방법을 말한다. </p>
<p>즉, 논리적으로는 한 테이블이지만, 실제 저장소에서는 여러 개의 작은 단위로 쪼개 두는 것이다. </p>
<p>데이터베이스에서 대용량 데이터를 효율적으로 저장, 관리하기 위해 사용하는 기법 중 하나이다. </p>
<blockquote>
<ul>
<li>DB기법 중 <code>저장 구조/데이터 관리 기법</code>에 속한다. </li>
</ul>
</blockquote>
<blockquote>
<ul>
<li>트랜잭션, 쿼리 최적화 같은 논리적 처리 기법이 아닌, <code>물리적 데이터 배치 전략</code>에 가깝다.</li>
</ul>
</blockquote>
<p><br><br></p>
<h3 id="◾파티셔닝을-왜-사용하는가">◾파티셔닝을 왜 사용하는가?</h3>
<h4 id="1-성능-향상">1. 성능 향상</h4>
<p>날짜와 같은 특정 범위만 조회할 때는 전체 테이블이 아닌 해당 파티션만 스캔하므로 쿼리 속도가 향상된다. </p>
<p>아무래도 한 테이블에서 찾는 것보다 어떤 단위로 쪼개 두면 그만큼 한 테이블의 데이터 개수가 적어지므로 속도가 향상될 것이다. </p>
<h4 id="2-관리-편의성">2. 관리 편의성</h4>
<p>오래된 데이터 파티션만 쉽게 삭제, 백업, 이동이 가능하다. </p>
<h4 id="3-확장성">3. 확장성</h4>
<p>테이블이 수십억 건 이상 커지더라도 각 파티션을 분산 저장, 관리가 가능하다. </p>
<br>

<h2 id="📌파티셔닝-동작과-주의할-점">📌파티셔닝 동작과 주의할 점</h2>
<h3 id="◾파티셔닝-동작-방식">◾파티셔닝 동작 방식</h3>
<h4 id="내부-동작">내부 동작</h4>
<ol>
<li>개발자는 평소처럼 <code>ELECT * FROM orders WHERE order_date BETWEEN …</code> 와 같이 쿼리를 작성한다. </li>
<li>DB 엔진이 자동으로 해당 파티션만 스캔한다. (파티션 프루닝)</li>
<li>결과 값을 얻는다. </li>
</ol>
<p>즉 파티션을 설정해두면, 개발자는 평소와 같이 DB를 조회하면 된다. </p>
<p><br><br></p>
<h3 id="◾파티셔닝-설계-시-주의할-점">◾파티셔닝 설계 시 주의할 점</h3>
<ul>
<li>파티셔닝 키(기준 컬럼) 설계가 중요하다. </li>
<li>파티션 개수가 너무 많으면 오히려 오버헤드가 발생할 수 있다. </li>
<li>인덱스,  FK 제약조건 제약이 있을 수 있다. (DBMS마다 다름)
<br><br></li>
</ul>
<h3 id="◾파티셔닝과-비슷한-개념">◾파티셔닝과 비슷한 개념</h3>
<p>인덱싱은 많이 들어보았던 것 같은데 이것과는 무슨 차이점이 있을까? 파티셔닝과 비슷한 개념과 비교를 해보면 아래와 같다. </p>
<ul>
<li>파티셔닝
: 하나의 DB인스턴스 안에서 테이블을 물리적으로 쪼갬
: 차이점) 논리적 테이블은 1개</li>
<li>샤딩
: 여러 DB서버에 데이터를 분산
: 차이점) DB 인스턴스도 여러 개 </li>
<li>인덱싱 
: 데이터 검색 속도 향상을 위해 별도 구조 유지
: 차이점) 테이블 분할 아님</li>
</ul>
<hr>
<p>실제 파티셔닝을 적용해보았는데, 그리 어렵지도 않고 한 번 설정해두면 DB안에서 자동으로 파티셔닝 자식 테이블에서 해당하는 데이터를 주므로 사용도 동일하게 하면 된다. </p>
<p>다만 자식 테이블 생성하는 로직은 필요하다. 파티셔닝에서 부모, 자식 개념이 있는데 자식 테이블에 저장이 되는 구조인 듯 하다. 이 부분은 cron으로 만들어주었고, 안전하게 default테이블도 생성해두었다. </p>
<p>다음 파티셔닝 글에서는 실제 사용해본 것을 자세히 정리해보아야겠다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Java/JPA] JPA란? ORM, Hibernate란?]]></title>
            <link>https://velog.io/@a_a/JPA-JPA%EB%9E%80-ORM-Hibernate%EB%9E%80</link>
            <guid>https://velog.io/@a_a/JPA-JPA%EB%9E%80-ORM-Hibernate%EB%9E%80</guid>
            <pubDate>Sat, 13 Sep 2025 12:44:18 GMT</pubDate>
            <description><![CDATA[<br>

<h2 id="📌-jpa란">📌 JPA란</h2>
<h3 id="◾-jpa란">◾ JPA란?</h3>
<ul>
<li><p>JPA 는 Java Persistence API의 약자</p>
</li>
<li><p>자바 진영의 ORM 기술 표준</p>
</li>
<li><p>애플리케이션과 JDBC사이에서 동작한다.</p>
<p><br><br></p>
</li>
</ul>
<p>JPA는 자바에서 표준으로 사용되는 ORM기술이다. 이 JPA를 이용하면 기존의 SQL개발의 무한 반복적인 쿼리문을 작성해야하는 문제점, 패러다임의 불일치 등을 해결해준다. ORM기술이 무엇인지는 아래 단락을 참고하자</p>
<p><img src="https://velog.velcdn.com/images/a_a/post/68c5a15d-b891-40e3-83b8-894142b62162/image.png" alt=""></p>
<p>출처: 김영한 자바 ORM 표준 JPA
<br><br></p>
<p>위 그림처럼 JPA는 자바 애플리케이션과 JDBC사이에서 동작한다. 동작방식은 아래와 같이 이루어진다.</p>
<p>개발자가 JPA에게 명령을 한다. 👉 JPA가 JDBC API 사용하여 SQL호출 👉 DB로부터 결과를 받아 동작</p>
<p> <br><br></p>
<h3 id="◾-orm이란">◾ ORM이란?</h3>
<ul>
<li><p>Object Realtional Mapping(객체 관계 매핑)</p>
</li>
<li><p>객체는 객체대로, 관계형 데이터베이스는 관계형 데이터베이스대로 설계하고 ORM 프레임워크가 중간에서 매핑한다.</p>
</li>
<li><p>대중적인 언어는 대부분 ORM 기술이 존재한다. </p>
</li>
</ul>
<p><br><br></p>
<p> 자바도 대중적 언어이므로 ORM기술들이 존재한다.</p>
<p>쉽게 말해서 ORM은 양쪽 기술을 연결해주는, 중간에 끼인 기술이다. 그리하여 JPA는 자바 객체와 데이터베이스 테이블 간의 매핑을 제공하여 객체 지향 프로그래밍에서의 개념과 데이터베이스 간의 상호작용을 쉽게 하도록 해준다.</p>
<p>ORM프레임워크는 단순히 <code>SQL을 개발자 대신 생성해 데이터베이스에 전달</code>해주는 것뿐 아니라 다양한 <code>패러다임의 불일치도 해결</code>해준다.</p>
<blockquote>
<p>객체 측면에서는 정교한 객체 모델링을 할 수 있고 관계형 데이터베이스는 데이터베이스에 맞도록 모델링만 하면 된다.</p>
</blockquote>
<blockquote>
<p>둘을 어떻게 매핑해야하는지 매핑 방법만 ORM 프레임워크에게 알려주면 된다. </p>
</blockquote>
<p> <br><br></p>
<h2 id="📌jpa의-역사">📌JPA의 역사</h2>
<h3 id="◾-jpa-탄생과-hibernate">◾ JPA 탄생과 Hibernate</h3>
<p>과거 자바 진영에서는 Enterprise Java Beans(EJB)라는 기술 표준이 존재했고 그 안에는 엔티티 빈이라는 ORM기술도 포함되어 있었으나 너무 복잡하고 기술의 성능도 좋지 않았다.</p>
<p>그러던 중 개빈 킹에 의해 가볍고, 실용적이며 기술 성숙도도 높은 하이버네이트라는 오픈소스 ORM프레임워크가 등장하게 된다. 오픈 소스지만 개발자들의 열광으로 발전을 하여 널리 쓰이게 되었고 결국 자바 진영에서 하이버네이트 창시자인 개빈 킹을 데리고 자바 ORM의 새로운 표준을 만들게 된다. 하이버네이트가 오픈소스로 시작했지만 표준으로 만들어지며 JPA표준에 맞춰 용어나 기술들도 정제, 컨버팅되어 개발을 하게 된다. 그리하여 JPA가 만들어지게 되었고 JPA는 시간이 지날수록 더욱 더 널리 쓰이고 있다. </p>
<p>JPA를 사용하기 위해서는 JPA를 구현한 ORM 프레임워크를 선택해야 하며, 하이버네이트가 가장 대중적이므로 하이버네이트를 사용하는 것을 권한다.</p>
<p><br><br></p>
<h3 id="◾jpa-버전별-특징">◾JPA 버전별 특징</h3>
<p>JPA의 버전별 특징은 다음과 같다. 2.0 버전 이전에는 부족했던 기능들이 다소 있었으나 2.0버전에서 대부분의 ORM기능을 포함하게 되었다.</p>
<ul>
<li><p>JPA 1.0(JSR 220) 2006년 : 초기 버전. 복합 키와 연관관계 기능이 부족</p>
</li>
<li><p>JPA 2.0(JSR 317) 2009년 : 대부분의 ORM 기능을 포함, JPA Criteria 추가</p>
</li>
<li><p>JPA 2.1(JSR 338) 2013년 : 스토어드 프로시저 접근, 컨버터(Converter), 엔티 티 그래프 기능이 추가</p>
</li>
</ul>
<p>** 출처/참고 **</p>
<p>자바 ORM 표준 JPA 프로그래밍 - 기본편 / 김영한 / 인프런 강의</p>
<p> <a href="https://ssdragon.tistory.com/51">https://ssdragon.tistory.com/51</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[vultr] 인스턴스 / 서버 접속하기 with Putty]]></title>
            <link>https://velog.io/@a_a/vultr-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4-%EC%84%9C%EB%B2%84-%EC%A0%91%EC%86%8D%ED%95%98%EA%B8%B0-with-Putty</link>
            <guid>https://velog.io/@a_a/vultr-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4-%EC%84%9C%EB%B2%84-%EC%A0%91%EC%86%8D%ED%95%98%EA%B8%B0-with-Putty</guid>
            <pubDate>Fri, 12 Sep 2025 02:00:46 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>작성일 2023. 12. 30.</p>
</blockquote>
<p>이번 시간에는 지난 시간 생성한 인스턴스로 Putty를 이용해 서버에 접속해보는 것을 해보겠습니다.
<br><br></p>
<p>인스턴스 생성, Vultr에서는 Compute영역에서 서버 생성하는 것을 하지 않았거나 모르는 분들은 아래 글을 참조하여 서버를 생성하실 수 있습니다.</p>
<p>2023.12.29 - [웹 개발/vultr] - [vultr] <a href="https://velog.io/@a_a/vultr-Compute-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4-%EC%83%9D%EC%84%B1%ED%95%98%EA%B8%B0-%ED%81%B4%EB%9D%BC%EC%9A%B0%EB%93%9C-%EC%84%9C%EB%B2%84-%EC%83%9D%EC%84%B1%ED%95%98%EA%B8%B0">Compute 인스턴스 생성하기 / 클라우드 서버 생성하기</a></p>
<p>준비물: 가입완료 본 글에서는 가입이 되어있는 상태에서 진행한다. 참고로 처음 가입을 해야하는 경우이거나 가입을 한 경우 프로모션 코드를 찾아 입력하면 250달러를 받을 수 있으니 꼭 아래</p>
<p> <br><br><br><br></p>
<h2 id="📌putty로-서버에-접속하기">📌Putty로 서버에 접속하기</h2>
<p>Putty를 이용해 생성한 서버에 접속을 해볼 것이다. 우선 Putty를 다운로드해야한다.</p>
<p><br><br></p>
<h3 id="🤔putty란">🤔Putty란?</h3>
<p>네트워크 통신을 위한 클라이언트 프로그램으로, 주로 원격 서버에 안전하게 접속하기 위해 사용된다. 주로 SSH(보안 쉘)과 Telent프로토콜을 지원하며, 콘솔 기반의 텍스트 인터에피스를 통해 사용자가 서버와 통신할 수 있도록 한다.</p>
<p><br><br></p>
<h3 id="putty-다운로드">Putty 다운로드</h3>
<p>아래 사이트에서 Download Putty를 클릭한다. </p>
<p><a href="https://www.putty.org/">https://www.putty.org/</a></p>
<p>Download PuTTY - a free SSH and telnet client for Windows</p>
<p>Is Bitvise affiliated with PuTTY? Bitvise is not affiliated with PuTTY. We develop our SSH Server for Windows, which is compatible with PuTTY. Many PuTTY users are therefore our users as well. From time to time, they need to find the PuTTY download link. W</p>
<p><a href="http://www.putty.org">www.putty.org</a></p>
<p>자기 pc에 맞는 버전을 선택한다. 64-bit x86의 putty.exe를 클릭해 다운한다. </p>
<p>(요즘은 대부분 64비트를 이용하고 있다고 한다.)</p>
<p><img src="https://velog.velcdn.com/images/a_a/post/b384cf50-0dd6-4b5e-92cb-4243fef20432/image.png" alt=""></p>
<p> <br><br></p>
<h2 id="서버-접속하기">서버 접속하기</h2>
<h3 id="인스턴스-준비">인스턴스 준비</h3>
<p>지난번 생성했던 &#39;test-instance&#39; 이 서버로 접속을 해볼 것이다. </p>
<p><img src="https://velog.velcdn.com/images/a_a/post/249a2352-3785-4b23-be5a-b3740ff70196/image.png" alt=""></p>
<p>인스턴스 생성이 안되었으면 글 맨 처음에 언급했듯이 이전 글을 참고하여 인스턴스를 생성하고 오면 된다.</p>
<p>접속할 인스턴스를 클릭한다. 그러면 아래 화면과 같이 IP주소, Username, Password 등을 확인할 수 있다. 서버에 접속하기 위해 필요한 정보들이다. </p>
<p><img src="https://velog.velcdn.com/images/a_a/post/d46fa37b-5403-4db4-aeb1-901ea2aa4a26/image.png" alt=""></p>
<p> <br><br></p>
<h3 id="putty-실행">Putty 실행</h3>
<p>Putty실행하면 아래와 같은 화면이 나올 것이다. </p>
<p> <img src="https://velog.velcdn.com/images/a_a/post/6af60c8a-4b6a-4c20-b2a3-a65b65d573fb/image.png" alt=""></p>
<p><br><br></p>
<h3 id="hostname입력하기">Hostname입력하기</h3>
<p>Host name칸에 넣을 IP주소를 복사한다. 오른쪽 복사 버튼을 이용하면 편리하다.</p>
<p><img src="https://velog.velcdn.com/images/a_a/post/55b505d5-bda7-4966-a32c-d6c3f868c074/image.png" alt=""></p>
<p>인스턴스 창에서 복사한 IP주소를 붙여넣고 Open을 클릭한다 .</p>
<p><img src="https://velog.velcdn.com/images/a_a/post/40fe6d5c-b593-43d6-9f3e-91e99915e9fb/image.png" alt=""></p>
<p>보안에 대한 경고창이 뜬다. 이 호스트를 신뢰할 것인지 묻는 것인데 Accept를 클릭한다.
<img src="https://velog.velcdn.com/images/a_a/post/69327ec6-de58-4e1f-8ad1-4914c20bdb15/image.png" alt=""></p>
<p> <br><br></p>
<h3 id="username과-password-입력">Username과 Password 입력</h3>
<p>인스턴스의 Username인 root를 입력한다.
<img src="https://velog.velcdn.com/images/a_a/post/5158127d-107f-47fb-87b5-ce69e8d9e3ad/image.png" alt=""></p>
<p>비밀번호를 입력해야 한다. 인스턴스 창으로 되돌아가 Password를 복사해준다. 
<img src="https://velog.velcdn.com/images/a_a/post/33a781b4-e7f2-4ab9-a785-eb705f3eb1ce/image.png" alt=""></p>
<p>Putty창으로 돌아와 마우스 오른쪽 버튼을 클릭한다. 그리고 Enter를 누른다.</p>
<p> <br><br></p>
<blockquote>
<p>⚠️비밀번호를 입력하여도 화면에 아무것도 표시되지 않는다. 이는 정상이다. 입력되지 않은 것이 아니므로 비밀번호를 붙여넣고 Enter키를 눌러주면 된다.</p>
</blockquote>
<p> <br><br></p>
<p>참고로 많은 cmd창에서는 마우스 오른쪽 버튼이 붙여넣기라고 한다. shift+enter를 이용해 붙여넣어도 된다.</p>
<p><img src="https://velog.velcdn.com/images/a_a/post/15218d9c-aa8b-4821-b15c-72030e958ea6/image.png" alt=""></p>
<p> 아래와 같은 화면이 나오고 [root@test-instance ~]# 가 뜬다면 정상적으로 접속이 된 것이다. 
<img src="https://velog.velcdn.com/images/a_a/post/97b51540-43a3-4d69-a5dd-5a0d8d1692ee/image.png" alt=""></p>
<p>이제 원하는 서비스를 할 수 있다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[vultr] Compute 인스턴스 생성하기 / 클라우드 서버 생성하기]]></title>
            <link>https://velog.io/@a_a/vultr-Compute-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4-%EC%83%9D%EC%84%B1%ED%95%98%EA%B8%B0-%ED%81%B4%EB%9D%BC%EC%9A%B0%EB%93%9C-%EC%84%9C%EB%B2%84-%EC%83%9D%EC%84%B1%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@a_a/vultr-Compute-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4-%EC%83%9D%EC%84%B1%ED%95%98%EA%B8%B0-%ED%81%B4%EB%9D%BC%EC%9A%B0%EB%93%9C-%EC%84%9C%EB%B2%84-%EC%83%9D%EC%84%B1%ED%95%98%EA%B8%B0</guid>
            <pubDate>Sun, 07 Sep 2025 10:37:42 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>작성일 2023. 12. 29</p>
</blockquote>
<blockquote>
<p>사전준비: 가입하기
본 글에서는 가입이 되어있는 상태에서 진행한다. </p>
</blockquote>
<p>참고로 처음 가입을 해야하는 경우이거나 가입을 한 경우 프로모션 코드를 찾아 입력하면 250달러를 받을 수 있으니 꼭 아래 페이지에서 쿠폰 코드를 확인하여 가입 후 입력하길 바란다. 시간에 따라 쿠폰 코드가 바뀌는 것 같아 아래 주소로 현 시점에 사용 가능한 코드를 확인하는 것이 좋다.</p>
<p><a href="https://www.vultr.com/coupons/">https://www.vultr.com/coupons/</a></p>
<p> <br><br><br></p>
<h2 id="📌vultr인스턴스-생성하기">📌Vultr인스턴스 생성하기</h2>
<h3 id="1-compute-선택하기">1. Compute 선택하기</h3>
<p><a href="https://www.vultr.com">https://www.vultr.com</a></p>
<p>위 주소에서 로그인을 하고 Products - Compute를 선택한다. 오른쪽 위의 [ Deploy + ] 버튼을 클릭한다. </p>
<p><img src="https://velog.velcdn.com/images/a_a/post/4595ba6d-8d34-44f0-8079-76a2e6963000/image.png" alt=""></p>
<p>Deploy New Server를 클릭한다. </p>
<p> <img src="https://velog.velcdn.com/images/a_a/post/a059f199-a46a-456f-adda-a08d5f568f0e/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/a_a/post/2d0fb37b-6815-454c-acbf-b91e2f8c292e/image.png" alt=""></p>
<p>이제부터 아주 간단하다. 원하는 스펙을 선택해주기만 하면된다. 본 글에서는 서버 접속을 위한 테스트용으로 가벼운 스펙의 인스턴스를 만들 것이다.</p>
<p> <br><br></p>
<h3 id="2-서버-선택하기">2. 서버 선택하기</h3>
<p>두번째 항목인 Cloud Compute를 선택한다. </p>
<p><img src="https://velog.velcdn.com/images/a_a/post/fc8b9df2-a96f-4f2e-98a0-431fbfd4ad8e/image.png" alt=""></p>
<p><br><br></p>
<h3 id="3-cpu--storage-technology-선택하기">3. CPU &amp; Storage Technology 선택하기</h3>
<p>가장 오른쪽의 Regular Perfomance를 선택한다. 가장 저렴한 모델이다. </p>
<p><img src="https://velog.velcdn.com/images/a_a/post/348004a9-057f-4115-9be0-a3197a72d978/image.png" alt=""></p>
<p> <br><br></p>
<h3 id="4-server-location-선택하기">4. Server Location 선택하기</h3>
<p>Seoul을 선택한다. 
<img src="https://velog.velcdn.com/images/a_a/post/50692079-8679-40a0-8765-1dd3643b37ec/image.png" alt=""></p>
<p> <br><br></p>
<h3 id="5-server-image-선택하기">5. Server Image 선택하기</h3>
<p>원하는 서버 이미지를 선택한다. 본 글에서는 로키 8버전을 선택했다. 
<img src="https://velog.velcdn.com/images/a_a/post/5d4751ef-0e92-4ce9-8cf4-fc2f18c59cd2/image.png" alt=""></p>
<p><br><br></p>
<h3 id="6-server-size-선택하기">6. Server Size 선택하기</h3>
<p>원하는 서버 사이즈를 선택해준다. CPU, Memory(RAM),저장 용량 등이 포함된다.</p>
<p>가장 첫번째를 선택했다. 클릭하면 더 높은 성능으로 업그레이드 할 것인지 물어보는데 수락하여서, 최종 6달러가 책정되었다. (업그레이드하지 않아도 상관없지만 제공된 250달러를 보유하고 있어 자금이 넉넉하기 때문에 선택했다.)</p>
<p> <img src="https://velog.velcdn.com/images/a_a/post/18fbb95a-cacf-4040-82fe-26c771b84795/image.png" alt=""></p>
<p><br><br></p>
<h3 id="7-자동-백업-여부--기타-선택사항들-선택하기">7. 자동 백업 여부 &amp; 기타 선택사항들 선택하기</h3>
<p>자동 백업을 하지 않아도 상관은 없으나, 자금이 넉넉하기 때문에 ON으로 두었다. 나머지 기타 기능들은 원하는 것을 체크하면 된다.</p>
<p>⚠️단, No Public IPv4 Address를 체크하면 해당 서버에 공개 IPv4주소가 할당되지 않는다. 이 경우 주소가 없으므로 외부에서 해당 서버 접속을 할 수 없다. </p>
<p>본 글에서는 모두 기본값으로 두었다. </p>
<p><img src="https://velog.velcdn.com/images/a_a/post/bee38145-6606-4e51-9002-a2197fb05723/image.png" alt=""></p>
<p><br><br></p>
<h3 id="8--server-hostname--label-정하기">8.  Server Hostname &amp; Label 정하기</h3>
<p>SSH Keys 의 경우 특별히 추가하지 않았다.</p>
<p>원하는 호스트이름과 라벨을 호스트이름을 &#39;test-instance&#39;로 입력해주었다. 호스트 이름을 입력하니 자동으로 label이 입력되었다. 물론 별도로 각각 지정을 해줄 수 있는 듯 하다.</p>
<p> <img src="https://velog.velcdn.com/images/a_a/post/4c752f14-a450-41ad-b306-4f9af436b8e7/image.png" alt=""></p>
<p><br><br></p>
<h3 id="9-비용-확인--deploy하기">9. 비용 확인 &amp; Deploy하기</h3>
<p>최종 비용이 아래 뜨는 것을 확인하고 오른쪽에 Deply Now버튼을 클릭한다.</p>
<p><img src="https://velog.velcdn.com/images/a_a/post/23478cba-2056-4352-9bc2-17a5bfde313f/image.png" alt=""></p>
<p>실제로 진행해보면 그리 복잡하지 않다. 방금 만든 인스턴스가 installing되는 것을 확인할 수 있다.
<img src="https://velog.velcdn.com/images/a_a/post/2b86c1f8-5e3d-40ba-b672-965de51964c3/image.png" alt=""></p>
<p>잠시 기다리면 Running상태가 된다. 인스턴스 생성이 완료되었다. 이제 인스턴스를 사용할 수 있다.</p>
<p><img src="blob:https://velog.io/edd1cd98-f634-4216-8016-9ec4f4694c7f" alt="업로드중.."></p>
<p>인스턴스를 여러 번 생성해보며 느낀 것은 AWS보다 VULTR가 더 직관적이라고 들었는데, 실제로도 사용해보니 초보자가 접근하기에는 AWS보다 더 접근하기 쉽게 느껴진다. 인스턴스 생성과정도 더 간편한 듯 하다. </p>
<p> <br><br><br><br></p>
<p>다음 시간에는 이번에 만든 서버를 Putty를 이용해 접속하는 방법에 대해 알아볼 것입니다</p>
<p>[웹 개발/vultr] - [vultr] 인스턴스 / 서버 접속하기 with Putty</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[AWS] EC2 인스턴스 cmd로 ssh 접속하기(Ubuntu)]]></title>
            <link>https://velog.io/@a_a/AWS-EC2-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4-cmd%EB%A1%9C-ssh-%EC%A0%91%EC%86%8D%ED%95%98%EA%B8%B0Ubuntu</link>
            <guid>https://velog.io/@a_a/AWS-EC2-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4-cmd%EB%A1%9C-ssh-%EC%A0%91%EC%86%8D%ED%95%98%EA%B8%B0Ubuntu</guid>
            <pubDate>Thu, 04 Sep 2025 14:06:50 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>2023.12.10 작성</p>
</blockquote>
<p>본 글에서는 윈도우 cmd창에서 EC2를 ssh로 연결하는 것을 해보겠습니다.</p>
<p>EC2인스턴스 생성에 대한 이해가 필요하다면 아래 글을 먼저 참조해주세요</p>
<p>2023.12.09 - [웹 개발/AWS] - [aws] EC2인스턴스 생성하기</p>
<p> <br><br> <br><br></p>
<h2 id="📌ec2인스턴스-생성하기">📌EC2인스턴스 생성하기</h2>
<h3 id="1-연결할-인스턴스-준비">1. 연결할 인스턴스 준비</h3>
<p>연결할 인스턴스가 있어야합니다. 
<img src="https://velog.velcdn.com/images/a_a/post/595c7a35-6507-4c1b-9e93-26837db220f1/image.png" alt=""></p>
<p> <br><br></p>
<h3 id="2-키-페어-보안설정-변경하기">2. 키 페어 보안설정 변경하기</h3>
<p>키 페어가 있는 폴더로 이동합니다. 키 페어의 속성을 열고 보안탭 - 고급을 엽니다.</p>
<p><img src="https://velog.velcdn.com/images/a_a/post/0ae0c33e-3a1a-4b1c-851b-bd00d69ceeb3/image.png" alt=""></p>
<p>아래와 같은 화면이 나올 것입니다.  상속 사용 안함을 클릭하고 Administrators와 SYSTEM을 제외하고 나머지들을 모두 제거합니다.</p>
<p> <img src="https://velog.velcdn.com/images/a_a/post/79667ded-add0-4d3e-abfd-4d7fca9021ab/image.png" alt=""></p>
<p>제거하면 아래와 같은 화면이 될 것입니다.
<img src="https://velog.velcdn.com/images/a_a/post/0fe1695d-a0d7-4ac6-8152-c15f3bda78a4/image.png" alt=""></p>
<p> <br><br></p>
<h3 id="3-cmd-관리자-실행">3. cmd 관리자 실행</h3>
<p>cmd를 관리자 권한으로 실행하고 키 페어가 있는 디렉토리로 이동합니다.</p>
<pre><code>cd &lt;키 페어 경로&gt;</code></pre><p>  <br><br></p>
<h3 id="4-인스턴스-ip-주소-복사">4. 인스턴스 IP 주소 복사</h3>
<p>인스턴스 위에서 오른쪽 버튼을 클릭하고 연결을 선택합니다.
<img src="https://velog.velcdn.com/images/a_a/post/c331534c-1ac0-4342-873d-ac8ddbe3e2a3/image.png" alt=""></p>
<p>  <br><br></p>
<p>SSH 클라이언트 탭에서 4번에 적힌 것을 복사합니다.</p>
<p><img src="https://velog.velcdn.com/images/a_a/post/005eff92-99db-40b5-aeaf-40a3cf6f7988/image.png" alt=""></p>
<p>  <br><br></p>
<h3 id="5-ssh-접속">5. ssh 접속</h3>
<p>현재 키 페어가 있는 경로로 이동을 하여서  키 페어 이름만 적어도 접속이 된다. </p>
<pre><code class="language-ssh"></code></pre>
<p><img src="https://velog.velcdn.com/images/a_a/post/d2ed528a-9ea3-49e3-9ecc-7b038db4a9e3/image.png" alt=""></p>
<br>


<h3 id="키-페어-경로에-있지-않은-경우"><strong>키 페어 경로에 있지 않은 경우</strong></h3>
<p>키 페어 경로에 있지 않은 경우는 아래와 같이 전체 경로를  키페어 이름과 함께 &quot;\키페어이름.pem&quot;으로 끝나게 적어준다. 
<code>ssh -i &lt;키 페어 경로&gt; &lt;사용자이름&gt;@&lt;DNS주소&gt;</code></p>
<p>아래는 키 페어 경로가 아닌 D드라이브에서(어느 곳이든 무방) 키 페어 전체 경로를 적고 접속한 모습이다. 
<img src="https://velog.velcdn.com/images/a_a/post/f39f739b-38b6-4745-9a2e-b03540719f5e/image.png" alt=""></p>
<p> <br><br></p>
<h3 id="⚠️연결이-안될-경우">⚠️연결이 안될 경우</h3>
<p>사용자 이름이나 키 페어 경로를 잘못 입력 시 아래와 같은 경고가 뜨고 접속이 안되었다.</p>
<p><img src="https://velog.velcdn.com/images/a_a/post/7d592f6d-4032-4a53-b45d-bf526832af0d/image.png" alt=""></p>
<p>우분투 연결이 안된다면 사용자 이름이나 키 페어 경로를 잘 살펴봐야합니다.</p>
<p>사용자 이름은 아래에 있는 것과 일치해야합니다!</p>
<p><img src="https://velog.velcdn.com/images/a_a/post/d2d77270-7be0-47cb-ad23-582c045d3717/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[AWS] EC2인스턴스 생성하기]]></title>
            <link>https://velog.io/@a_a/AWS-EC2%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4-%EC%83%9D%EC%84%B1%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@a_a/AWS-EC2%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4-%EC%83%9D%EC%84%B1%ED%95%98%EA%B8%B0</guid>
            <pubDate>Wed, 03 Sep 2025 13:29:47 GMT</pubDate>
            <description><![CDATA[<p>EC2에 대한 이해가 필요하다면 아래를 먼저 참고하는 것이 좋습니다.</p>
<p><a href="https://dani0312.tistory.com/30">2023.12.01 - [웹 개발/AWS] - [aws] EC2란?</a></p>
 <br>

<h2 id="📌ec2인스턴스-생성하기">📌EC2인스턴스 생성하기</h2>
<h3 id="1-ec2인스턴스-시작">1. EC2인스턴스 시작</h3>
<p>aws에서 EC2서비스를 선택한다.</p>
<p><img src="https://velog.velcdn.com/images/a_a/post/18b4c6a2-ae8c-4b7a-96d0-6d8c30aa0c26/image.png" alt=""></p>
<p>그러면 이러한 화면이 보일 것이다. 현재 생성해둔 인스턴스가 한 개도 없는 모습니다. 인스턴스 생성을 위해 오른쪽 위에 [인스턴스 시작] 버튼을 누른다.</p>
<p><img src="https://velog.velcdn.com/images/a_a/post/051cbf7d-9ca2-44c0-a532-2a345aef0603/image.png" alt=""></p>
<p> <br> <br></p>
<h3 id="2-이름-지정">2. 이름 지정</h3>
<p>인스턴스 이름을 지정한다.</p>
<p>(참고로 생략해도 생성가능하다. 그러나 구별을 위해 이름을 지정하는 것이 좋을 듯 하다.)</p>
<p><img src="https://velog.velcdn.com/images/a_a/post/3069488a-bfb8-4b76-8c05-b1287d7e9d19/image.png" alt="">
 <br> <br></p>
<h3 id="3--ami-선택">3.  AMI 선택</h3>
<p>Amazon Linux2 AMI를 선택한다. </p>
<p>Amazon Linux2는 차세대 Amazon Linux 운영 체제로, 현대 애플리케이션 환경에 Linux커뮤니티의 최신 기능과 장기적인 기능을 제공한다고 한다.</p>
<p>원하는 AMI가 없다면 오른쪽 &#39;더 많은 AMI찾아보기&#39;를 클릭하여 화면에 보이는 것 이외에도 많은 AMI를 확인하여 선택할 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/a_a/post/d3dd43c4-3aa4-4967-8d58-a46f516f21a9/image.png" alt=""></p>
<br>


<blockquote>
<p>🤔AMI란?
Amazon Machine Image의 약자로 aws에서 사용되는 약자이다. EC2 인스턴스를 시작하는 데 필요한 정보를 이미지로 만들어 둔 것을 의미한다. 인스턴스라는 가상머신에 운영체제 등을 설치할 수 있게 구워 넣은 이미지로 생각하면 된다.</p>
</blockquote>
 <br>
 <br>



<h3 id="4--인스턴스-유형-선택">4.  인스턴스 유형 선택</h3>
<p>인스턴스 유형을 선택한다. 프리티어 사용이 가능한 t2.micro를 선택한다.</p>
<p>현재는 연습용이라 낮은 사양을 사용하지만, 더 높은 트래픽이 오면 더 높은 사양을 선택해 트래픽을 처리합니다.</p>
<p><img src="https://velog.velcdn.com/images/a_a/post/17dc5dbd-79cc-454a-87f7-51e2fa6f0154/image.png" alt="">
 <br> <br></p>
<h3 id="5-키-페어-설정">5. 키 페어 설정</h3>
<p>키 페어 설정을 해야한다. 기존 생성해둔 키페어가 존재할 경우 선택을 클릭하여 원하는 키페어를 지정할 수 있다. </p>
<p>생성해둔 키페어가 없다면 새 키 페어 생성을 클릭한다.
<img src="https://velog.velcdn.com/images/a_a/post/243d24c1-f3ca-4bcd-8786-f4970e84e94b/image.png" alt=""></p>
<p>키페어 이름을 입력하고 키 페어 생성을 누른다. 자동으로 키페어가 PC에 다운로드 된다. </p>
<p>다운은 한 번만 가능하니 보관에 유의하자!</p>
<p><img src="https://velog.velcdn.com/images/a_a/post/9f02d37e-cc79-4f2d-812b-9940faf07e47/image.png" alt=""></p>
 <br>

<blockquote>
<p>🤔키페어란?
SSH 터미널로 인스턴스에 접근할 때 반드시 필요한 비밀 키이다. 비밀 키를 분실 시 복잡한 작업이 요구되므로 잘 관리해야 한다. 보안상 외부에 절대 노출되면 안되고 다운은 한 번만 가능하니 보관에 유의하자!</p>
</blockquote>
<p>  <br> <br></p>
<h3 id="6-네트워크-설정">6. 네트워크 설정</h3>
<p>VPC와 서브넷 등은 AWS서비스들의 네트워크 환경을 구성해준다. VPC와 서브넷을 따로 사용한다면 해당 옵션을 선택하고 없다면 기본 값으로 남겨둔 뒤 넘어간다.</p>
<p>( 필요에 따라 탄력적 IP를 할당하는 경우 퍼블릭IP 자동할당을 비활성화 한다. 본 글에서는 기본값인 활성화로 그대로 진행한다. )</p>
<p>보안 그룹 설정을 위해 네트워크 설정에서 오른쪽 위 편집을 누른다. 
<img src="https://velog.velcdn.com/images/a_a/post/a19dc90e-4906-47db-9702-cf56f3663e5e/image.png" alt=""></p>
<p>보안 그룹 규칙을 추가해보자 인바운드란, 외부---&gt; 인스턴스 이렇게 외부에서 인스턴스로 들어오는 트래픽, 요청에 대한 보안 설정이다. SSH통신을 위해 기본적으로 22포트는 오픈이 되어있다. SSH통신을 원한다면 기본값으로 그냥 두면 되고 HTTP통신을 하고 싶다면 80포트에 대한 규칙을 추가한다.</p>
  <br>

<p>위치 무관은 외부의 모든 IP에서 접근할 수 있도록 하는 것이다. 웹 서버 통신을 위해 웹 서버 규칙을 설정해보자. 아래 보안 그룹 규칙 추가를 클릭한다. 
<img src="https://velog.velcdn.com/images/a_a/post/20dbf565-11fd-40d7-b011-1454e2c6867d/image.png" alt=""></p>
<p>유형으로 HTTP를 선택한다. 자동으로 포트가 80으로 지정된 것을 확인할 수 있다.</p>
<p>소스 유형은 위치 무관을 선택한다.
<img src="https://velog.velcdn.com/images/a_a/post/9ed839e7-d266-4269-a049-fe4f3b24f4d6/image.png" alt=""></p>
<p>아웃바운드 규칙은 따로 설정하지 않았다. 아웃바운드란 인스턴스---&gt;외부로 나가는 트래픽이다. 디폴트값으로 모두 허용되어있는 상태이다.
 <br> <br></p>
<h3 id="7-스토리지-설정">7. 스토리지 설정</h3>
<p>최소 8GB부터 설정이 가능하다. 프리티어의 경우 30GB까지 무료로 사용이 가능하다. 기본값으로 설정하였다.</p>
<p><img src="https://velog.velcdn.com/images/a_a/post/418f227a-b22b-4210-8c52-2e6b0d1204af/image.png" alt="">
 <br> <br></p>
<h3 id="8-고급-세부-정보">8. 고급 세부 정보</h3>
<p>고급 세부 정보를 펼치면 필요에 따라 항목별로 세부적인 설정을 할 수 있다. 본 글에서는 생략하였다.</p>
<p><img src="https://velog.velcdn.com/images/a_a/post/6dde41e0-99f7-46c2-b4fb-6251a6b2dbfc/image.png" alt=""></p>
<p> <br> <br></p>
<h3 id="9-확인-및-생성">9. 확인 및 생성</h3>
<p>마지막 요약에서 내가 선택한 설정들의 주요 정보를 확인할 수 있다. 확인 후 인스턴스 시작을 클릭한다. </p>
<p><img src="https://velog.velcdn.com/images/a_a/post/1fb205e2-9dc4-4857-8eb1-58183526edf7/image.png" alt=""></p>
<p>인스턴스 시작을 클릭하면 인스턴스를 생성하기 시작하고 곧 인스턴스 생성이 완료된다. 
<img src="https://velog.velcdn.com/images/a_a/post/171ade97-8394-4bc0-b5cd-0175e93a17f0/image.png" alt="">
<img src="https://velog.velcdn.com/images/a_a/post/45e41d05-55a2-48e2-b588-faf3ff8c0203/image.png" alt=""></p>
<p>인스턴스 탭에서 새로 생성된 인스턴스가 추가된 것을 확인할 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/a_a/post/ad4354cd-2b7a-47d5-b931-636743efc42a/image.png" alt=""></p>
<p> <br> <br> <br> <br></p>
<hr>
<p><strong>참조 사이트</strong></p>
<p><a href="https://goddaehee.tistory.com/316">https://goddaehee.tistory.com/316</a></p>
<p><a href="https://sinclairstudio.tistory.com/474">https://sinclairstudio.tistory.com/474</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[AWS] EC2란?]]></title>
            <link>https://velog.io/@a_a/AWS-EC2%EB%9E%80</link>
            <guid>https://velog.io/@a_a/AWS-EC2%EB%9E%80</guid>
            <pubDate>Mon, 25 Aug 2025 09:16:10 GMT</pubDate>
            <description><![CDATA[<p>AWS 또는 클라우드 컴퓨팅에 대한 이해가 필요하다면 아래를 먼저 참고하는 것이 좋습니다.</p>
<p><a href="https://velog.io/@a_a/AWS-AWS%EB%9E%80-%ED%81%B4%EB%9D%BC%EC%9A%B0%EB%93%9C-%EC%BB%B4%ED%93%A8%ED%8C%85%EC%9D%B4%EB%9E%80">AWS란? 클라우드 컴퓨팅이란?</a></p>
 <br>
 <br>




<h2 id="📌-ec2">📌 EC2</h2>
<h3 id="◾ec2란">◾EC2란?</h3>
<p>Elastic Compute Cloud의 줄임말이다. EC2란 AWS에서 제공해주는 <code>클라우드 컴퓨팅 서비스</code>로, 아마존이 <code>사용자들에게 독립된 컴퓨터를 임대</code>해주는 서비스라고 볼 수 있다.  AWS에서 가장 핵심적인 서비스라고 할 수 있다.</p>
<p>이 서비스를 통해 아마존이 각 세계에 구축한 데이터 센터의 서버용 컴퓨터들의 자원을 원격으로 사용할 수 있다. 쉽게 이야기하여, 아마존으로부터 컴퓨터를 빌려 사용하는 것이다. AWS가 제공하는 URL(Public DNS)을 통해 컴퓨터에 접근할 수 있다. </p>
 <br>
 <br>











<h3 id="◾ec2-특징">◾EC2 특징</h3>
<h4 id="--용량을-늘리거나-줄일-수-있음탄력성">- 용량을 늘리거나 줄일 수 있음(탄력성)</h4>
<p>용량을 추가하여 월간 또는 연간 프로세스 또는 웹 사이트 트래픽 급증 등 컴퓨팅 사용량이 많은 작업을 처리할 수 있고, 사용량이 감소하면 용량을 다시 축소(스케일 다운)할 수 있다. 또한 Auto Scailinig으로 사용량에 따라 인스턴스 조절이 가능하다.</p>
<h4 id="--원하는-수의-가상-서버를-구축">- 원하는 수의 가상 서버를 구축</h4>
<p>사용한 만큼만 비용 지불</p>
<h4 id="--보안-및-네트워킹을-구성">- 보안 및 네트워킹을 구성</h4>
<p>Amazon VPC와 함께 사용자 컴퓨팅 리소스에 보안성 및 강력한 네트워킹 기능 제공</p>
<h4 id="--효과적인-스토리지-관리">- 효과적인 스토리지 관리</h4>
<h4 id="--안정성-보장">- 안정성 보장</h4>
<p>EC2리전에 대해 99.999..%의 가용성 보장</p>
  <br>
 <br>




<h3 id="◾ec2를-사용하는-이유">◾EC2를 사용하는 이유</h3>
<p>위 단락 EC2의 특징이 곧 EC2의 장점이자 EC2를 사용해야 하는 이유이다. 즉 높은 편리성, 효율성, 비용 절감을 할 수 있으므로 이것이 EC2를 사용하는 이유라 할 수 있다.
 <br></p>
<p>별도의 물리적인 서버를 도입하지 않고도 아마존에서 이를 빌려 활용할 수 있으니 이것만으로도 EC2의 장점이 되기에 충분하다.</p>
  <br>

<p>아래 이미지는 물리 서버를 도입하는 것과 aws의 서비스를 이용하는 것의 차이를 잘 보여준다.</p>
<p><img src="https://velog.velcdn.com/images/a_a/post/69485fde-0882-42ce-8bed-f795443b688c/image.png" alt=""></p>
<pre><code>코드를 입력하세요</code></pre><p>출처: server30sopt.log</p>
<p> <br> <br>
 <br></p>
<hr>
<h4 id="참고-사이트">참고 사이트</h4>
<p><a href="https://velog.io/@kyj311/AWS-EC2-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0">https://velog.io/@kyj311/AWS-EC2-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0</a></p>
<p><a href="https://seoyeonhwng.medium.com/aws-ec2%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80-acf6b7041908">https://seoyeonhwng.medium.com/aws-ec2%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80-acf6b7041908</a></p>
<p>EC2개념 정리에 좋은 글</p>
<p><a href="https://velog.io/@server30sopt/AWS-EC2-%EA%B0%9C%EB%85%90-%EC%A0%95%EB%A6%AC">https://velog.io/@server30sopt/AWS-EC2-%EA%B0%9C%EB%85%90-%EC%A0%95%EB%A6%AC</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[PostgreSQL/error] error: no pg_hba.conf entry for host .. 에러 해결하기]]></title>
            <link>https://velog.io/@a_a/PostgreSQLDB-error-no-pghba.conf-entry-for-host-..-%EC%97%90%EB%9F%AC-%ED%95%B4%EA%B2%B0%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@a_a/PostgreSQLDB-error-no-pghba.conf-entry-for-host-..-%EC%97%90%EB%9F%AC-%ED%95%B4%EA%B2%B0%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 19 Aug 2025 02:08:54 GMT</pubDate>
            <description><![CDATA[<h2 id="💡당시-상황">💡당시 상황</h2>
<ul>
<li>NestJS</li>
<li>PostgreSQL</li>
<li>local server<br>
내 로컬 서버에서 다른 서버의 DB를 사용하려는 상황이었다. DB의 종류는 postgreSQL 이었다. 
<br>
해당 프로젝트의 DB 설정은 config.production.yaml 파일로 되어있었고 서버에 있는 설정 파일과 동일하게 DB설정을 했다. host, username, password, port 등 모든 설정을 동일하게 했는데도 로컬에서 서버를 실행해서 접속하려하면  DB 접속이 실패했다. 
<br>
<br>
## 🚨에러

</li>
</ul>
<h3 id="에러코드">에러코드</h3>
<pre><code>error: no pg_hba.conf entry for host &quot;172.30.11.111&quot;, user &quot;abcd1234&quot;, database &quot;database1&quot;, no encryption</code></pre><br>

<h3 id="문제원인">문제원인</h3>
<p>PostgreSQL서버의 접속 허용 정책 (pg_hba.conf) 때문에 막힌 상황이다. 설정을 알맞게 하더라도 <code>pg_hba.conf</code> 에 클라이언트(접속하려는 서버) 서버의 IP가 허용되지 않으면 연결할 수 없다고 한다. </p>
<p>postgreSQL을 사용하다보니 이 문제는 정말 자주 발생하는 문제였다. 
<br>
<br></p>
<h2 id="🔍해결하기">🔍해결하기</h2>
<h3 id="1-서버에-접속하여-설정파일-열기">1. 서버에 접속하여 설정파일 열기</h3>
<p>DB를 띄우고 있는 Postgres가 설치된 서버로 접속하여 <code>pg_hab.conf</code>파일을 열어야한다. </p>
<p>보통 경로는 아래 두 곳에 있다고 한다.</p>
<ul>
<li>/etc/postgresql/{버전}/main/pg_hba.conf (Debian/Ubuntu 계열)</li>
<li>/var/lib/pgsql/{버전}/data/pg_hba.conf (CentOS/RHEL 계열)</li>
</ul>
<p>우분투 서버를 사용하고 있어서 첫 번쨰 경로에 있었다. </p>
<br>

<p>** 접속하기 ** </p>
<pre><code>cd etc/postgresql/{버전}/main</code></pre><br>

<p>** 파일 열기 **</p>
<pre><code>sudo nano pg_hba.conf</code></pre><p>sudo로 열지 않으면 파일이 보이지 않을 수 있다. 
<br>
<br></p>
<h3 id="2-파일에-허용-규칙-추가하기">2. 파일에 허용 규칙 추가하기</h3>
<p>파일에 아래와 같은 명령어를 추가한다. </p>
<pre><code>host    database1    abcd1234    172.30.11.111/32    md5</code></pre><p>=&gt; 172.30.1.122 이 IP에서 abcd1234 유저가 topcore DB 접속 가능하도록 허용</p>
<br>

<p>또는 데이터베이스, 유저를 지정하지 않고 아래와 같이 설정하면 모두 허용하도록 할 수 있다. </p>
<pre><code>host    all    all    172.30.1.122/32    md5</code></pre><ul>
<li><code>all</code> 로 설정하면 모든 DB, 모든 유저를 허용하겠다는 것이다. </li>
<li><code>md5</code>는 패스워드 기반 암호화 인증 (보통 이걸 많이 쓴다고 한다.)<br>

</li>
</ul>
<blockquote>
<p><strong>💡참고</strong></p>
</blockquote>
<ul>
<li><code>trust</code> : 비밀번호 없이 허용 → 위험 ⚠️</li>
<li><code>md5</code> : 패스워드 필요 (일반적으로 사용)</li>
<li><code>scram-sha-256</code> : PostgreSQL 10+에서 권장되는 더 안전한 방법</li>
<li><code>all all 0.0.0.0/0</code> → 모든 IP 허용, 보안상 권장되지 않음</li>
</ul>
<br>

<h3 id="3-postgresql-서버-재시작">3. PostgreSQL 서버 재시작</h3>
<ul>
<li>Ubuntu/Debian<pre><code>sudo systemctl reload postgresql</code></pre><br></li>
<li>CentOS/RHEL<pre><code>sudo systemctl reload postgresql-13</code></pre></li>
</ul>
<p><br><br></p>
<h2 id="⭐확인">⭐확인</h2>
<p>다시 서버를 접속해보니 정상적으로 접속된다!
postgres를 사용하며 자주 만나는 문제여서 기억해두면 좋을 듯 하다. 
<img src="https://velog.velcdn.com/images/a_a/post/e52dbbe1-8877-4826-9fe8-4bf8c951b15a/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[error/Jenkins] error=0, Failed to exec spawn helper 젠킨스 빌드 실패 에러
]]></title>
            <link>https://velog.io/@a_a/errorJenkins-error0-Failed-to-exec-spawn-helper-%EC%A0%A0%ED%82%A8%EC%8A%A4-%EB%B9%8C%EB%93%9C-%EC%8B%A4%ED%8C%A8-%EC%97%90%EB%9F%AC</link>
            <guid>https://velog.io/@a_a/errorJenkins-error0-Failed-to-exec-spawn-helper-%EC%A0%A0%ED%82%A8%EC%8A%A4-%EB%B9%8C%EB%93%9C-%EC%8B%A4%ED%8C%A8-%EC%97%90%EB%9F%AC</guid>
            <pubDate>Wed, 13 Aug 2025 09:24:46 GMT</pubDate>
            <description><![CDATA[<h2 id="💡당시-상황">💡당시 상황</h2>
<p>젠킨스에서 백엔드 프로젝트도, 프론트 프로젝트도 같은 에러가 나면서 빌드가 실패했다. 빌드로 개발중인 서버에 배포가 되어야 진행이 되는데, 여기서 문제가 발생하면서 모든 것이 막히게 된 상황이었다. </p>
<p>Jenkins에 대해 수정한 것은 전혀 없는 상황이었다. 단지 평소 하던대로 개발한 내용을 푸쉬하고 Jenkins에서 빌드 버튼을 눌러 빌드 명령어를 실행하였는데, 갑자기 이런 문제가 터진 것이었다. </p>
<br>

<h2 id="🔍문제-원인">🔍문제 원인</h2>
<h3 id="문제의-핵심">문제의 핵심</h3>
<pre><code>error=0, Failed to exec spawn helper
</code></pre><p>문제의 핵심은 위의 메세지였다. Jenkins가 <code>git</code> 프로세스를 실행하려다 OS 차원에서 fork/exec 단게에서 실패한 것이다. </p>
<h3 id="왜-갑자기-이럴까">왜 갑자기 이럴까?</h3>
<p>아무것도 안 건드렸어도 아래 상황 중 하나면 이런 에러가 뜰 수 있다고 한다. </p>
<h4 id="1-시스템-리소스-부족">1. 시스템 리소스 부족</h4>
<p>프로세스 실행에 필요한 메모리/스레드 부족
리눅스에서 fork() 실패 시 이런 메시지가 나옵니다.</p>
<p>원인:</p>
<ul>
<li>메모리 부족</li>
<li>너무 많은 프로세스가 실행 중</li>
<li>ulimit로 프로세스 개수 제한됨</li>
</ul>
<h4 id="2-git-실행-파일-손상-or-권한-문제">2. git 실행 파일 손상 or 권한 문제</h4>
<ul>
<li>/usr/bin/git이 깨졌거나, 실행권한이 사라짐</li>
<li>패키지 업데이트 도중 오류 발생 가능</li>
</ul>
<h4 id="3-path-문제">3. PATH 문제</h4>
<ul>
<li>Jenkins가 실행되는 환경의 PATH에서 git 경로가 사라짐</li>
<li>시스템에선 잘 되지만 Jenkins 서비스 환경에서는 실행 불가</li>
</ul>
<h4 id="4-파일-핸들-제한">4. 파일 핸들 제한</h4>
<ul>
<li>/var/lib/jenkins/caches/ 또는 임시 디렉토리(/tmp)에서 파일 생성이 안 되는 상태</li>
<li>디스크 풀(full) / inode 부족도 fork 실패의 원인</li>
</ul>
<br>

<h3 id="제일-흔한-원인">제일 흔한 원인</h3>
<h4 id="1-리눅스-서버에서-메모리-부족--프로세스-제한-때문에-fork-실패">1. 리눅스 서버에서 메모리 부족 + 프로세스 제한 때문에 fork 실패</h4>
<h4 id="2-jenkins를-오래-켜놔서-쌓인-빌드-프로세스나-플러그인-프로세스가-자원-다-사용함">2. Jenkins를 오래 켜놔서 쌓인 빌드 프로세스나 플러그인 프로세스가 자원 다 사용함</h4>
<br>
### 에러 코드

<pre><code>java.io.IOException: error=0, Failed to exec spawn helper: pid: 887899, exit value: 1
    at java.base/java.lang.ProcessImpl.forkAndExec(Native Method)
    at java.base/java.lang.ProcessImpl.&lt;init&gt;(ProcessImpl.java:314)
    at java.base/java.lang.ProcessImpl.start(ProcessImpl.java:244)
    at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1110)
Caused: java.io.IOException: Cannot run program &quot;git&quot; (in directory &quot;/var/lib/jenkins/caches/git-d09a7cd79cb123ea724a4331f9f6f532&quot;): error=0, Failed to exec spawn helper: pid: 887899, exit value: 1
    at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1143)
    at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1073)
    at hudson.Proc$LocalProc.&lt;init&gt;(Proc.java:252)
    at hudson.Proc$LocalProc.&lt;init&gt;(Proc.java:221)
    at hudson.Launcher$LocalLauncher.launch(Launcher.java:995)
    at hudson.Launcher$ProcStarter.start(Launcher.java:507)
    at PluginClassLoader for git-client//org.jenkinsci.plugins.gitclient.CliGitAPIImpl.launchCommandIn(CliGitAPIImpl.java:2839)
Caused: hudson.plugins.git.GitException: Error performing git command: git init /var/lib/jenkins/caches/git-d09a7cd79cb123ea724a4331f9f6f532
    at PluginClassLoader for git-client//org.jenkinsci.plugins.gitclient.CliGitAPIImpl.launchCommandIn(CliGitAPIImpl.java:2862)
    at PluginClassLoader for git-client//org.jenkinsci.plugins.gitclient.CliGitAPIImpl.launchCommandIn(CliGitAPIImpl.java:2771)
    at PluginClassLoader for git-client//org.jenkinsci.plugins.gitclient.CliGitAPIImpl.launchCommandIn(CliGitAPIImpl.java:2766)
    at PluginClassLoader for git-client//org.jenkinsci.plugins.gitclient.CliGitAPIImpl.launchCommand(CliGitAPIImpl.java:2059)
    at PluginClassLoader for git-client//org.jenkinsci.plugins.gitclient.CliGitAPIImpl$5.execute(CliGitAPIImpl.java:1083)
Caused: hudson.plugins.git.GitException: Could not init /var/lib/jenkins/caches/git-d09a7cd79cb123ea724a4331f9f6f532
    at PluginClassLoader for git-client//org.jenkinsci.plugins.gitclient.CliGitAPIImpl$5.execute(CliGitAPIImpl.java:1085)
    at PluginClassLoader for git-client//org.jenkinsci.plugins.gitclient.CliGitAPIImpl.init(CliGitAPIImpl.java:365)
    at PluginClassLoader for git-client//hudson.plugins.git.GitAPI.init(GitAPI.java:246)
    at PluginClassLoader for git//jenkins.plugins.git.GitSCMFileSystem$BuilderImpl.build(GitSCMFileSystem.java:390)
Caused: java.io.IOException
    at PluginClassLoader for git//jenkins.plugins.git.GitSCMFileSystem$BuilderImpl.build(GitSCMFileSystem.java:413)
    at PluginClassLoader for scm-api//jenkins.scm.api.SCMFileSystem.of(SCMFileSystem.java:219)
    at PluginClassLoader for workflow-cps//org.jenkinsci.plugins.workflow.cps.CpsScmFlowDefinition.create(CpsScmFlowDefinition.java:120)
    at PluginClassLoader for workflow-cps//org.jenkinsci.plugins.workflow.cps.CpsScmFlowDefinition.create(CpsScmFlowDefinition.java:72)
    at PluginClassLoader for workflow-job//org.jenkinsci.plugins.workflow.job.WorkflowRun.run(WorkflowRun.java:316)
    at hudson.model.ResourceController.execute(ResourceController.java:101)
    at hudson.model.Executor.run(Executor.java:446)
Finished: FAILURE</code></pre><br>

<h2 id="✔️해결하기">✔️해결하기</h2>
<h3 id="응급-조치">응급 조치</h3>
<pre><code>sudo systemctl restart jenkins</code></pre><p>리소스가 비워져서 일시적으로 복구될 가능성 높음
근본 해결 위해선 ulimit 조정, 메모리 확보, git 경로/권한 점검 필요</p>
<br>
현재는 급한 불을 꺼야해서 응급 조치를 해두었고, 

<br>
추후 이 오류가 다시 나지 않도록 Jenkins 서버 자원 관리에 대해서도 다뤄볼 예정이다!
]]></description>
        </item>
        <item>
            <title><![CDATA[[AWS] AWS란? 클라우드 컴퓨팅이란?]]></title>
            <link>https://velog.io/@a_a/AWS-AWS%EB%9E%80-%ED%81%B4%EB%9D%BC%EC%9A%B0%EB%93%9C-%EC%BB%B4%ED%93%A8%ED%8C%85%EC%9D%B4%EB%9E%80</link>
            <guid>https://velog.io/@a_a/AWS-AWS%EB%9E%80-%ED%81%B4%EB%9D%BC%EC%9A%B0%EB%93%9C-%EC%BB%B4%ED%93%A8%ED%8C%85%EC%9D%B4%EB%9E%80</guid>
            <pubDate>Sat, 21 Jun 2025 14:01:04 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>작성일 2023.11.29</p>
</blockquote>
<h2 id="📌aws">📌AWS</h2>
<h3 id="◾aws란">◾AWS란?</h3>
<p>aws에서는 aws를 다음과 같이 소개하고 있다.
<br></p>
<blockquote>
<p>Amazon Web Services(AWS)는 전 세계적으로 분포한 데이터 센터에서 
200개가 넘는 완벽한 기능의 서비스를 제공하는, 세계적으로 가장 포괄적이며, 널리 채택되고 있는 클라우드입니다. <br>
빠르게 성장하는 스타트업, 가장 큰 규모의 엔터프라이즈, 주요 정부 기관을 포함하여 수백만 명의 고객이 AWS를 사용하여 비용을 절감하고, 민첩성을 향상시키고 더 빠르게 혁신하고 있습니다.</p>
</blockquote>
<br>

<p>아마존 웹 서비스(Amaon web services)인 AWS는 클라우드 컴퓨터 분야에서 압도적 세계 1위의 점유율을 차지하고 있는 아마존 닷컴의 클라우드 컴퓨팅 서비스이다. 현재 개인 및 소규모 회사를 포함한 다양한 사용자들이 있으며, 클라우드 컴퓨팅의 장점을 이용하기 위해 많은 거대 기업에서도 활용된다고 한다.</p>
 <br>


<ul>
<li>네트워킹을 기반으로 가상 컴퓨터와 스토리지, 네트워크 인프라 등 다양한 서비스를 제공</li>
<li>비즈니스와 개발자가 웹 서비스를 이용하여 확장 가능하고 정교한 애플리케이션을 구축하도록 지원</li>
<li>대표적 서비스: EC2, S3<br>

</li>
</ul>
<p>쉽게 이야기하면, 아마존에서 컴퓨터를 빌려 사용할 수 있게 해주는 것이다.  또한 이것이 클라우드 컴퓨팅의 본질이라고 한다. 클라우드 컴퓨팅에 대한 개념이 익숙치 않다면 아래 단락을 참고하자</p>
 <br>


<p>AWS에서 제공하는 서비스와 관련 기능들은 정말 다양하고 많다. 그러나 이것들을 한번에 학습하기보다는 필요한 것들을 하나씩 학습해나가는 것이 좋다고 한다. </p>
<p> <br> <br> <br></p>
<h2 id="📌클라우드-컴퓨팅">📌클라우드 컴퓨팅</h2>
<h3 id="◾클라우드-컴퓨팅이란">◾클라우드 컴퓨팅이란?</h3>
<p>클라우드 컴퓨팅이란 인터넷, 즉 클라우드를 통해 서버, 스토리지, 데이터베이스 등 필요한 IT자원을 제공하는 것을 뜻한다. 앞서 언급한 것처럼 쉽게 이야기하여, <strong>컴퓨터를 빌려주는 것</strong>이 클라우드 컴퓨팅의 본질이다.</p>
<p>  <br> <br></p>
<p>◾클라우드 컴퓨팅의 주요 서비스
클라우드 컴퓨팅의 주요 서비스로 3가지가 있다.</p>
<p>  <br>  <br></p>
<h4 id="infrastructure-as-a-serviceiaas"><strong>Infrastructure as a Service(IaaS)</strong></h4>
<p>사용주체: 시스템 관리자
이용항목: 컴퓨팅 리소스
인프라로서의 서비스를 뜻하며 기존 물리적인 형태로 사용해왔던 스토리지, 서버 등의 인프라를 가상화된 환경에서 쉽고 신속하게 할당받아 사용할 수 있는 서비스이다.
PaaS와 SaaS의 기반이 되는 가장 기본적인 클라우드 서비스의 형태이다.
ex) EC2, S3</p>
  <br>

<p><strong>Platform as a Service(PaaS)</strong></p>
<p>사용주체: 개발자
이용항목: 개발 플랫폼
개발자가 어플리케이션을 개발, 서비스 하기위해 사용가능한 서비스(윈도우,리눅스와 같은 운영체제)와 기능들이 (개발 환경도 플랫폼) 제공되는 클라우드 서비스이다. 여기서 환경이란 운영체제, 미들웨어, 애플리케이션 실행환경 등이 포함된다.
이미 구축 후 제공되는 인프라가 존재하기에 개발자는 상위의 플랫폼에서 빠르게 어플리케이션을 개발 및 서비스 할 수 있다.</p>
 <br>


<p><strong>Software as a Service(SaaS)</strong></p>
<p>사용주체: 현업 사용자
이용항목: 소프트웨어 애플리케이션
클라우드 기반의 응용 프로그램을 서비스 형태로 제공하는 것을 말하며, 일반 사용자들이 가장 많이 접하게 되는 형태이다. 
네이버클라우드, 웹 메일, ERP 등과 같은 형태의 서비스를 사용자에게 제공한다.</p>
<p>주요 서비스로 위의 3가지이나, aws와 같은 서비스는 아래에 해당한다고 할 수 있다.</p>
  <br>





<p><strong>Everything as a Service(EaaS)</strong></p>
<p>XaaS라고도 한다
IaaS, PaaS, SaaS 세 가지를 통칭하는 말이다.
AWS는 EaaS라고 할 수 있다.</p>
<p> <br> <br></p>
<p>서비스 별 단계와 관계를 이해하는데 도움이 되었던 이미지이다.</p>
<p><img src="https://velog.velcdn.com/images/a_a/post/b92291ac-df73-44cc-a2ba-197b913bdfcd/image.png" alt=""></p>
<p>출처: 뉴딜코리아</p>
<p><img src="https://velog.velcdn.com/images/a_a/post/20e99f96-9542-46a2-b1b8-373066b08bf5/image.png" alt=""></p>
<p>출처:&nbsp; velog-hanif.log</p>
<p><img src="https://velog.velcdn.com/images/a_a/post/7bcd0fae-8549-4773-b556-d98a682ca2ba/image.png" alt=""></p>
<p>출처: TCPSCHOOL.com</p>
<br>


<p>2023.12.01 - [웹 개발/aws] - [aws] EC2란?
<a href="https://dani0312.tistory.com/30">https://dani0312.tistory.com/30</a></p>
<p> <br> <br> <br> <br></p>
<hr>
<p><strong>Reference</strong></p>
<p><a href="https://aws.amazon.com/ko/what-is-aws/">https://aws.amazon.com/ko/what-is-aws/</a></p>
<p><a href="https://goddaehee.tistory.com/174">https://goddaehee.tistory.com/174</a></p>
<p><a href="https://velog.io/@hanif/AWS%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80">https://velog.io/@hanif/AWS%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80</a></p>
<p><a href="https://seaforest76.tistory.com/13">https://seaforest76.tistory.com/13</a></p>
<p>클라우드 컴퓨팅 iaas, paas, saas 이해에 좋은 글</p>
<p><a href="https://velog.io/@hanif/AWS%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80">https://velog.io/@hanif/AWS%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[error/spring] BeanCreation, BeanDefinition 에러]]></title>
            <link>https://velog.io/@a_a/errorspring-BeanCreation-BeanDefinition-%EC%97%90%EB%9F%AC</link>
            <guid>https://velog.io/@a_a/errorspring-BeanCreation-BeanDefinition-%EC%97%90%EB%9F%AC</guid>
            <pubDate>Thu, 19 Jun 2025 04:05:16 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>작성일 2024. 3. 24.</p>
</blockquote>
<br>

<p>spring 공부를 진행하다가 빈 관련된 에러 두 가지를 마주치고 해결했던 것을 정리해보고자 한다.
<br></p>
<h2 id="📌beandefinition-에러">📌BeanDefinition 에러</h2>
<h3 id="✔️background">✔️Background</h3>
<p>A디렉터리에서 작업하던 것을 그대로 B디렉터리에 복붙해오면서 작업하며 발생하게 된 에러이다. 컨트롤러, 서비스, 레포지토리 등을 복붙해와서 리팩토링을 하였기 때문이다. <strong>&quot;스프링 빈은 유일해야 하는데 이름이 중복된다면 빈 정의 오류가 발생한다. &quot;</strong></p>
 <br>

<h3 id="✔️해결과정">✔️해결과정</h3>
<pre><code>● A컨트롤러, A컨트롤러 → A컨트롤러, B컨트롤러</code></pre><p>컨트롤러를 예로 든다면 A컨트롤러와 같이 동일한 이름의 컨트롤러가 2개 이상 존재하면 안된다. 스프링은 스프링 컨테이너에 스프링 빈을 등록할 때 기본으로 싱글톤(Singleton)으로 등록한다.</p>
<p>싱글톤 방식은 유일하게 하나만 등록해서 공유한다. 특별한 경우를 제외하면 대부분 싱글톤을 사용한다. <strong>따라서 스프링 빈은 유일해야하는데, 같은 이름의 컨트롤러를 2개 선언하여 에러가 발생한 것이다.</strong> 하나의 컨트롤러의 이름을 변경하여 빈 정의 에러를 해결하였다. 이 에러의 대표적인 에러 원인은 다음과 같다고 한다.</p>
 <br>

<h3 id="✔️-beandefinition-주요-에러-원인">✔️ BeanDefinition 주요 에러 원인</h3>
 <br>


<h4 id="1-빈-이름-충돌">1. 빈 이름 충돌</h4>
<p>: Spring 컨테이너에 같은 이름의 빈이 여러 개 등록되어 있을 때 발생할 수 있다. </p>
<h4 id="2-의존성-주입-문제">2. 의존성 주입 문제</h4>
<p>: 빈이 필요로 하는 의존성을 주입할 때, 주입할 빈이 존재하지 않거나, 여러 개의 빈이 존재할 때 발생할 수 있다. <code>@Autowired</code>, <code>@Inject</code> 등을 사용하여 의존성을 주입할 때 발생할 수 있다.</p>
<h4 id="3-빈-설정-오류">3. 빈 설정 오류</h4>
<p>: 빈의 설정이 올바르지 않아서 발생할 수 있다. 예를 들어, 필수 속성이 빠져 있거나, 잘못된 속성 값이 설정되어 있는 경우 발생할 수 있다. </p>
<p><br><br></p>
<h2 id="📌beancreation-에러">📌BeanCreation 에러</h2>
<h3 id="✔️background-1">✔️Background</h3>
<p>BeanDefinition 에러를 한 번 맞닥뜨리고 이를 해결하여 같은 이름의 컨트롤러, 서비스 등은 없는데 왜 BeanCreation에러가 날까? 생각을 해보면서 코드를 곰곰히 보았다. 
<br></p>
<pre><code>● A컨트롤러, A컨트롤러 → A컨트롤러, B컨트롤러</code></pre> <br>

<p>앞서 Bean Definition 오류를 위와 같이 해결하였는데, 컨트롤러의 api가 같은 path를 가지고 있었다. 그러니까, A컨트롤러의 path와 http메서드 이 2가지와 동일한 API가 B컨트롤러에도 존재하는 것이다. 마치 아래와 같은 상황이다.</p>
 <br>


<p>두 API는 같은 HTTP method, 같은 PATH를 가지고 있다. PATH가 다른 것이 직접적인 원인은 아니지만, 이것으로 컨트롤러 충돌이 발생해 <code>BeanCreation</code>에러가 발생할 수 있다고 한다.
<br></p>
<pre><code>test() : GET /add

test2(): GET /add</code></pre> <br>

<h3 id="✔️해결과정-1">✔️해결과정</h3>
<p>두 개 이상의 컨트롤러 클래스가 동일한 API 경로를 매핑하는 경우 충돌이 발생하고, 이로 인해 빈이 생성되는 과정에서 충돌이 발생할 수 있다고 한다.</p>
  <br>

<p>중복된 path를 다르게 설정해주어야한다. 두 메서드의 위치가 각각 다른 컨트롤러에 있었기 때문에 <code>@RequestMapping</code>부분에 /v1,/v2과 같이 구분을 해주어 다르게 path를 다르게 해주었다.</p>
 <br>

<p><code>@RequestMapping</code> 부분을 반드시 변경해주어야 하는 것은 아니고  각 메서드의 path를 변경해도 된다. 궁극적으로 path를 유니크하게 설정하여 각각의 API를 생성하는 것이 목적이다. 
 <br>
참고로, <code>@RequestMapping</code>를 자체를 사용하지 않고 개발하는 경우도 역시나 메서드의 path를 변경해주면 구별될 것이다. (이 어노테이션의 사용유무는 개발자의 취향이라고 한다.)</p>
<p> <br><br><br></p>
<hr>
<h3 id="✔️-beancreation-에러">✔️ BeanCreation 에러</h3>
<p>이 오류는 다양한 원인으로 발생할 수 있지만, 일반적인 원인 몇 가지는 아래와 같다고 한다. 
<br></p>
<h4 id="1-의존성-주입-문제">1. 의존성 주입 문제</h4>
<p>: Spring이 빈을 생성하거나 초기화하는 동안 해당 빈이 필요로 하는 의존성을 주입하는데 실패할 경우 발생할 수 있다.</p>
<h4 id="2-빈-생성-시-예외-발생">2. 빈 생성 시 예외 발생:</h4>
<p>빈의 생성자나 초기화 메서드 중 하나에서 예외가 발생할 경우 BeanCreation에러가 발생할 수 있다. 빈이 필요한 자원을 초기화하는 중에 예외가 발생하여 빈의 생성이 중단되는 경우 발생할 수 있다.</p>
<h4 id="3-빈-구성-오류">3. 빈 구성 오류:</h4>
<p>빈의 설정이 올바르지 않거나, 빈을 생성할 때 필요한 속성이 빠져있는 경우 발생할 수 있다. </p>
 <br>



<p>BeanCreation에러의 경우, 사실 내가 해결한 방법도 위의 에러원인에 해당하지 않는다. 그러나 이 글을 찾아오는 분들과 다음에 이 에러를 마주했을 경우 위의 경우에 해당할 수 있기 때문에 정리하였다.</p>
<p>이번 케이스의 경우 에러의 원인을 찾기 위해 검색부터 했으면 해결하는데 더 오래 걸렸을 것이다. (대표적인 에러 원인에 해당하지 않기 때문에🥲) 검색하기 전에 우선 내가 작성한 코드를 먼저 살펴보는 것이 좋은 듯 하다. </p>
<p><br><br></p>
<hr>
<p><strong>Reference</strong>
스프링 빈과 컨테이너, 그리고 의존관계
<a href="https://bnzn2426.tistory.com/124">https://bnzn2426.tistory.com/124</a>
Bean 등록 및 의존 관계 설정하기
<a href="https://katfun.tistory.com/178">https://katfun.tistory.com/178</a></p>
]]></description>
        </item>
    </channel>
</rss>