<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>히태하태 공부 일기장📝</title>
        <link>https://velog.io/</link>
        <description>시작이 반이다. 일단 시작해보자.</description>
        <lastBuildDate>Tue, 02 Sep 2025 06:08:36 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>히태하태 공부 일기장📝</title>
            <url>https://velog.velcdn.com/images/hithae_hothae/profile/5311f213-62c0-4009-9969-2166d82d6258/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. 히태하태 공부 일기장📝. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/hithae_hothae" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[C언어] 포인터]]></title>
            <link>https://velog.io/@hithae_hothae/C%EC%96%B8%EC%96%B4-%ED%8F%AC%EC%9D%B8%ED%84%B0</link>
            <guid>https://velog.io/@hithae_hothae/C%EC%96%B8%EC%96%B4-%ED%8F%AC%EC%9D%B8%ED%84%B0</guid>
            <pubDate>Tue, 02 Sep 2025 06:08:36 GMT</pubDate>
            <description><![CDATA[<p>0) 왜 포인터인가?</p>
<p>C는 “메모리에 가까운 언어”예요. 포인터는 메모리의 주소를 값으로 갖는 변수입니다. 이 주소값을 통해 우리는 메모리 블록의 시작점을 가리키고, 타입 정보를 바탕으로 그 블록을 해석합니다. 성능·표현력·시스템 프로그래밍의 자유를 주지만, 잘못 쓰면 치명적 버그(크래시, UAF, OOB)가 됩니다.</p>
<p>1) 메모리 모델 한 장 요약</p>
<p>일반적인 64-bit Linux 프로세스의 가상 메모리 개략(ASLR 생략):</p>
<p>높은 주소
┌───────────────────────┐
│           스택(Stack) │  ↓ 성장 (함수 프레임, 지역변수)
├───────────────────────┤
│             힙(Heap)  │  ↑ 성장 (malloc/free)
├───────────────────────┤
│   데이터/ BSS 영역    │  전역/정적 변수 (초깃값/무초깃값)
├───────────────────────┤
│          텍스트(Text) │  코드/상수
└───────────────────────┘
낮은 주소</p>
<p>포인터는 이 주소 공간 어딘가를 가리키는 정수 같은 값(단, 산술이 타입 크기 단위로 진행).</p>
<p>64-bit에선 포인터 크기가 8바이트(일반적). sizeof(void*) == 8.</p>
<p>2) 포인터의 기초: 선언, 주소 연산, 역참조
int a = 10;
int *p = &a;   // p에는 &#39;a의 주소&#39;가 들어감
*p = 20;       // p가 가리키는 메모리에 20을 씀 → a가 20이 됨</p>
<p>&amp; : 주소 연산자 (변수 → 그 변수의 시작 주소)</p>
<ul>
<li>: 역참조 (주소 → 그 주소가 가리키는 “값”)</li>
</ul>
<p>p의 타입(int*)은 “이 주소를 int로 해석하라”는 약속입니다.</p>
<p>포인터 크기와 정렬
printf(&quot;%zu %zu\n&quot;, sizeof(int<em>), sizeof(double</em>)); // 보통 둘 다 8</p>
<p>타입과 무관하게 “포인터 자체의 크기”는 플랫폼 고정(대개 8). 하지만 <strong>포인터 연산(p+1)</strong>은 sizeof(*p)만큼 이동한다는 점이 핵심.</p>
<p>3) 데이터 레벨: 바이트로 보는 메모리</p>
<p>리틀엔디언에서 “낮은 주소에 하위 바이트”가 옵니다.</p>
<p>#include &lt;stdio.h&gt;
#include &lt;stdint.h&gt;</p>
<p>int main() {
    uint32_t x = 0x11223344;     // 16진 상수
    uint8_t <em>px = (uint8_t</em>)&x;  // 바이트 단위 접근</p>
<pre><code>printf(&quot;%02X %02X %02X %02X\n&quot;, px[0], px[1], px[2], px[3]);
return 0;</code></pre><p>}</p>
<p>메모리 바이트 배치(리틀엔디언):</p>
<p>주소:   0x1000  0x1001  0x1002  0x1003
값:       44      33      22      11</p>
<p>px[0] == 0x44, px[1] == 0x33 …</p>
<p>같은 주소를 uint32_t<em>로 보면 한 덩어리 0x11223344, uint8_t</em>로 보면 바이트 배열.</p>
<p>char*로 보면 뭐든 바이트 스트림</p>
<p>표준이 보장하는 유일한 “바이트 단위 포인터”는 unsigned char<em>/char*예요. 임의의 객체를 안전하게 바이트복사하려면 memcpy를 쓰고, 바이트 단위 검사도 char</em> 캐스팅으로 합니다.</p>
<p>4) 배열과 포인터: 같지만 다르다
int arr[4] = {10, 20, 30, 40};
int *p = arr;           // == &amp;arr[0]</p>
<p>주소/크기 차이
printf(&quot;%zu\n&quot;, sizeof(arr));  // 4 * sizeof(int) == 16 (배열 전체 크기)
printf(&quot;%zu\n&quot;, sizeof(p));    // 포인터 크기 == 8</p>
<p>식에서 배열 이름은 대부분 첫 요소의 주소로 decay합니다. 그러나 sizeof(arr)처럼 “배열 자체”가 필요한 문맥에선 decay 안 되고 전체 크기.</p>
<p>포인터 연산의 단위</p>
<p>가령 p가 0x1000을 가리키면(64-bit, int=4B 가정):</p>
<p>p        = 0x1000 → *p     == arr[0]
p + 1    = 0x1004 → *(p+1) == arr[1]
p + 2    = 0x1008 → *(p+2) == arr[2]</p>
<p>arr vs &amp;arr</p>
<p>arr의 타입: int*로 decay</p>
<p>&amp;arr의 타입: int (*)[4] (배열 전체의 포인터)</p>
<p>산술도 다름: &amp;arr + 1은 16바이트를 건너뜀(배열 전체 크기만큼)</p>
<p>5) 동적 메모리와 포인터: Heap의 삶과 죽음
#include &lt;stdlib.h&gt;
int *p = malloc(sizeof(int) * 3); // 힙에 12바이트
p[0] = 7; p[1] = 8; p[2] = 9;
free(p);                          // 메모리 반납
p = NULL;                         // 댕글링 방지</p>
<p>데이터 레벨 관찰 포인트</p>
<p>malloc은 커널로부터 큰 페이지를 받아 <strong>사용자 공간 할당자(glibc ptmalloc 등)</strong>가 쪼개서 줍니다.</p>
<p>우리가 받는 포인터 바로 앞에는 할당자용 메타데이터가 있을 수 있어요(크기·상태). 이 영역은 사용 금지.</p>
<p>UAF(use-after-free): free(p) 후 *p를 접근하면 정의되지 않은 동작.</p>
<p>Double free: 같은 포인터 두 번 free → 힙 손상/크래시.</p>
<p>calloc/realloc</p>
<p>calloc(n, sz): n*sz 바이트 할당 후 0으로 초기화.</p>
<p>realloc(p, newsz): 크기 변경. 새 블록이 필요하면 복사 후 옛 블록 free. 실패 시 원래 포인터 유지.</p>
<p>6) 이중 포인터, 포인터 배열, 그리고 문자열
포인터의 포인터
int val = 42;
int <em>p = &val;    // int에 대한 포인터
int *</em>pp = &p;    // &quot;int<em>에 대한 포인터&quot;
*</em>pp = 100;       // val = 100</p>
<p>포인터 배열 vs 이차원 배열
// 포인터 배열: 각 행이 제각각 위치
char *rows[3] = { &quot;hi&quot;, &quot;pointer&quot;, &quot;world&quot; };</p>
<p>// 진짜 2D 배열(연속 메모리)
int grid[2][3] = { {1,2,3}, {4,5,6} };</p>
<p>메모리 그림(포인터 배열):</p>
<p>rows ──┬─&gt; &quot;hi\0&quot;
       ├─&gt; &quot;pointer\0&quot;
       └─&gt; &quot;world\0&quot;</p>
<p>rows 자체는 3개의 <strong>포인터 값(각 8B)</strong>로 이루어진 연속 메모리. 각 포인터는 어디든 가리킬 수 있음(힙/텍스트/스택 상수 등).</p>
<p>7) 구조체와 포인터: 정렬(Alignment)과 패딩(Padding)
#include &lt;stdio.h&gt;
#include &lt;stddef.h&gt;</p>
<p>struct S {
    char  a;   // 1B
    int   b;   // 4B
    short c;   // 2B
};</p>
<p>int main() {
    printf(&quot;sizeof(S) = %zu\n&quot;, sizeof(struct S));
    printf(&quot;offsets: a=%zu b=%zu c=%zu\n&quot;,
           offsetof(struct S, a),
           offsetof(struct S, b),
           offsetof(struct S, c));
}</p>
<p>가능한 배치(일반 x86_64, int 4B 정렬, short 2B 정렬):</p>
<p>offset 0: a (1B)
offset 1-3: padding (3B)    // b를 4바이트 경계에 맞추기 위함
offset 4-7: b (4B)
offset 8-9: c (2B)
offset 10-11: padding (2B)  // 전체 크기를 가장 큰 정렬(4B)의 배수로
sizeof(S) == 12</p>
<p>포인터로 구조체 접근
struct S s = { &#39;Z&#39;, 0x11223344, 0x5566 };
struct S *ps = &s;
printf(&quot;%X\n&quot;, ps-&gt;b);   // 0x11223344</p>
<p>주의: 패킹(packed)</p>
<p>네트워크/파일 포맷에 맞추려 패딩을 없애고 싶을 때:</p>
<p>struct <strong>attribute</strong>((packed)) P {
    char a;
    int  b;
    short c;
}; // 패딩 제거 (미세 성능/정렬 페널티, 미이식성 주의)</p>
<p>별도: 엄격 별칭(aliasing) 규칙</p>
<p>서로 다른 타입의 포인터로 동일 메모리를 접근하면 UB가 될 수 있어요. 바이트 접근(unsigned char*)만이 예외적으로 허용.</p>
<p>8) const와 포인터: 어디가 상수일까?
const int *p;      // p는 가변, p가 가리키는 &quot;값&quot;은 상수(읽기전용)
int * const p2;    // p2 자체가 상수(재할당 불가), 값은 수정 가능
const int * const p3; // 포인터도 상수, 값도 상수</p>
<p>문법 팁: const는 별표 왼쪽을 수식한다고 기억하면 이해가 빨라요.</p>
<p>9) 함수 포인터: 콜백의 핵심
#include &lt;stdio.h&gt;
int add(int a, int b) { return a+b; }
int mul(int a, int b) { return a*b; }</p>
<p>int calc(int (*op)(int,int), int x, int y) {
    return op(x,y);
}</p>
<p>int main() {
    printf(&quot;%d\n&quot;, calc(add, 2, 3)); // 5
    printf(&quot;%d\n&quot;, calc(mul, 2, 3)); // 6
}</p>
<p>시그니처 주의</p>
<p>함수 포인터 타입이 정확히 일치해야 안전합니다. 표준 라이브러리의 qsort, pthread_create 등은 콜백 함수 포인터를 인자로 받습니다.</p>
<p>10) 흔한 실수 &amp; 베스트 프랙티스
(1) sizeof(<em>p) vs sizeof(p)
int *p = malloc(10 * sizeof(</em>p)); // int 10개 (OK)
int *q = malloc(10 * sizeof(q));  // sizeof(q)==8 (버그!)</p>
<p>(2) 배열 길이 vs 포인터 길이
int a[5];
int *p = a;
sizeof(a) == 20   // 배열 전체 바이트
sizeof(p) == 8    // 포인터 크기</p>
<p>(3) 경계 밖 접근(Out-Of-Bounds)</p>
<p>정의되지 않은 동작(UB). 테스트에선 “우연히” 통과해도 배포 후 크래시.</p>
<p>(4) 댕글링/Double-Free
free(p);
*p = 10;  // UAF (금지)
free(p);  // Double-free (금지)
p = NULL; // 관례적으로 바로 NULL 대입</p>
<p>(5) 정렬/패딩 무시</p>
<p>네트워크/디스크 포맷 직렬화는 memcpy/명시적 바이트 변환으로 처리하세요. 구조체를 그대로 송수신하는 건 이식성 지뢰.</p>
<p>(6) void*의 함정</p>
<p>void*는 타입 정보가 없어 산술 불가. 반드시 적절한 타입으로 캐스팅 후 연산.</p>
<p>11) 메모리 레벨 예제 모음
예제 A: 배열 메모리 지도
int arr[4] = {10,20,30,40};
int <em>p = arr;
printf(&quot;%p %p %p %p\n&quot;, (void</em>)&amp;arr[0], (void<em>)&amp;arr[1], (void</em>)&amp;arr[2], (void*)&amp;arr[3]);</p>
<p>가상 배치(가정, int=4B):</p>
<p>&amp;arr[0] = 0x1000: 0A 00 00 00
&amp;arr[1] = 0x1004: 14 00 00 00
&amp;arr[2] = 0x1008: 1E 00 00 00
&amp;arr[3] = 0x100C: 28 00 00 00</p>
<p>p+1 == &amp;arr[1], *(p+2) == 30.</p>
<p>예제 B: short 엔디언 차이
short s = 0x1234;  // 16-bit
unsigned char <em>c = (unsigned char</em>)&s;
printf(&quot;%02X %02X\n&quot;, c[0], c[1]); // 리틀엔디언: 34 12</p>
<p>예제 C: 구조체 바이트 보기
struct S { char a; int b; short c; } s = { &#39;A&#39;, 0x01020304, 0x0506 };
unsigned char <em>m = (unsigned char</em>)&s;
/* 바이트 덤프 */
for (size_t i=0; i&lt;sizeof s; ++i) printf(&quot;%02X &quot;, m[i]); puts(&quot;&quot;);</p>
<p>가능 출력(12B, 리틀엔디언 가정):</p>
<p>41 00 00 00  04 03 02 01  06 05 00 00
 a  pad pad  b(LSB...MSB)  c(LSB MSB) pad</p>
<p>예제 D: argv 메모리 레벨
int main(int argc, char *<em>argv) {
    // argv는 char</em>의 배열(포인터 배열)로 볼 수 있음
    // argv[i]는 각 문자열의 시작 주소
}</p>
<p>메모리적으로:</p>
<p>argv ──┬─&gt; &quot;prog\0&quot;
       ├─&gt; &quot;arg1\0&quot;
       └─&gt; &quot;arg2\0&quot;</p>
<p>argv 자체는 [포인터, 포인터, 포인터, NULL]의 연속 배열.</p>
<p>12) 함수 인자 전달: 배열은 왜 포인터로 느껴질까
void foo(int a[10]) {        // 사실상 int *a 와 동일
    printf(&quot;%zu\n&quot;, sizeof(a)); // 8 (포인터 크기)
}</p>
<p>함수 인자로 배열을 넘기면 포인터로 decay합니다. 길이가 필요한 함수라면 길이를 별도 인자로 받거나, struct로 묶는 패턴이 안전합니다.</p>
<p>13) 고급 주제 한 숟갈</p>
<p>restrict: 같은 객체를 서로 다른 포인터가 가리키지 않는다는 약속으로 최적화 유도 (void foo(int *restrict a, int *restrict b, size_t n)).</p>
<p>원자적 접근: 멀티스레드에서 포인터/데이터 접근은 &lt;stdatomic.h&gt;의 원자 타입을 고려.</p>
<p>안전한 캐스팅: 네트워크/파일 바이너리 파싱 시는 무조건 바이트 단위 파서(엔디언 변환 함수)로 접근. 구조체 재해석은 금물.</p>
<p>14) 체크리스트 (실전용)</p>
<p> malloc(N * sizeof(*p)) — 타입 변경에도 안전</p>
<p> free 후 p=NULL</p>
<p> 경계 검사(OOB 금지)</p>
<p> sizeof(arr) vs sizeof(ptr) 혼동 금지</p>
<p> 구조체 직렬화 금지(명시적 변환 사용)</p>
<p> 함수 포인터 시그니처 일치 확인</p>
<p> const의 위치로 무엇이 불변인지 분명히</p>
<p> 포인터 연산은 요소 크기 단위임을 기억</p>
<p>15) 마무리</p>
<p>포인터는 “주소”라는 단순한 출발점에서 타입, 정렬, 엔디언, 배열 디케이, 구조체 패딩, 동적 메모리, 함수 포인터까지 연결됩니다. 핵심은 두 가지예요.</p>
<p>타입이 해석을 결정한다 — 같은 바이트라도 int<em>/char</em>로 전혀 다르게 보인다.</p>
<p>경계/수명 관리 — OOB, UAF, Double-free를 철저히 차단하라.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Java] Integer.valueOf vs new Integer]]></title>
            <link>https://velog.io/@hithae_hothae/Java-Integer.valueOf-vs-new-Integer</link>
            <guid>https://velog.io/@hithae_hothae/Java-Integer.valueOf-vs-new-Integer</guid>
            <pubDate>Tue, 20 May 2025 07:30:41 GMT</pubDate>
            <description><![CDATA[<p>Java에서 Integer.valueOf() vs new Integer() — 객체 생성 방식의 차이와 성능 영향
Java에서 정수 값을 객체로 사용할 일이 많습니다. 이때 가장 많이 사용하는 클래스는 Integer인데, 이를 객체로 생성하는 방식에는 두 가지가 있습니다:</p>
<pre><code>Integer a = new Integer(100);
Integer b = Integer.valueOf(100);</code></pre><p>겉보기엔 동일한 결과를 만들 것 같지만, 실제로는 동작 방식, 메모리 처리, 성능 등에서 큰 차이를 보입니다. 본 글에서는 Integer.valueOf()와 new Integer()의 차이를 JVM의 내부 구조까지 포함해 자세히 알아보겠습니다.</p>
<h3 id="📌-1-사용법의-차이-생성자-vs-정적-팩토리-메서드">📌 1. 사용법의 차이: 생성자 vs 정적 팩토리 메서드</h3>
<p>Java에서 객체를 생성하는 일반적인 방식은 new 키워드를 사용하는 것입니다.</p>
<pre><code>Integer i1 = new Integer(100);</code></pre><p>이 방식은 항상 새로운 Integer 인스턴스를 생성합니다. 반면, valueOf()는 정적(static) 메서드로, 내부적으로 객체 재사용을 시도합니다.</p>
<pre><code>Integer i2 = Integer.valueOf(100);</code></pre><p>이 메서드는 단순히 new와 같은 기능을 감싸는 것 같지만, 내부적으로는 매우 다른 처리를 합니다. 이 차이는 특히 많은 수의 정수 객체를 다루는 코드에서 메모리 사용과 성능에 지대한 영향을 줍니다.</p>
<h3 id="🔍-2-내부-처리-방식-캐시cache-사용-여부">🔍 2. 내부 처리 방식: 캐시(Cache) 사용 여부</h3>
<p>2.1 new Integer(): 항상 새로운 객체 생성
new Integer()를 사용하면 JVM은 힙 메모리(Heap) 에 새로운 Integer 객체를 생성합니다. 이 객체는 GC(Garbage Collector)에 의해 관리되며, 동일한 값을 갖더라도 참조가 다르므로 == 비교에서는 항상 false가 됩니다.</p>
<pre><code>Integer a = new Integer(100);
Integer b = new Integer(100);
System.out.println(a == b); // false</code></pre><p>2.2 Integer.valueOf(): -128 ~ 127 캐시 재사용
valueOf()는 객체 재사용을 위한 캐시 메커니즘을 제공합니다. 이 메서드는 -128부터 127까지의 정수에 대해 미리 만들어진 Integer 객체를 재사용합니다.</p>
<pre><code>Integer x = Integer.valueOf(100);
Integer y = Integer.valueOf(100);
System.out.println(x == y); // true</code></pre><p>내부 코드를 보면 다음과 같은 구조입니다:</p>
<pre><code>public static Integer valueOf(int i) {
    if (i &gt;= -128 &amp;&amp; i &lt;= 127)
        return IntegerCache.cache[i + 128];
    else
        return new Integer(i);
}</code></pre><p>즉, -128~127 범위의 정수는 IntegerCache라는 배열에 미리 만들어 놓고, 동일한 값을 요청하면 해당 객체를 그대로 반환합니다.</p>
<h3 id="🧠-3-jvm-메모리-구조와-객체-위치">🧠 3. JVM 메모리 구조와 객체 위치</h3>
<p>이 차이는 JVM의 메모리 영역 구조와도 연결됩니다.</p>
<p>메모리 영역    설명
Heap    new 키워드로 생성된 객체가 위치하는 공간. GC 대상.
Method Area    클래스, 정적 변수, 정적 메서드가 저장되는 공간. 정적 캐시도 여기에 위치.
IntegerCache    Integer.valueOf()의 캐시 배열. 클래스 로딩 시 Method Area에 위치함.</p>
<p>Integer.valueOf()는 클래스 로딩 시 캐시를 Method Area에 로드하고, 반복적으로 재사용합니다. 반면 new Integer()는 매번 Heap에 새 객체를 생성하므로 GC에 부담을 줍니다.</p>
<h3 id="⚙️-4-성능-및-메모리-측면-비교">⚙️ 4. 성능 및 메모리 측면 비교</h3>
<table>
<thead>
<tr>
<th>항목</th>
<th><code>new Integer()</code></th>
<th><code>Integer.valueOf()</code></th>
</tr>
</thead>
<tbody><tr>
<td>객체 생성 비용</td>
<td>높음 (항상 새 인스턴스)</td>
<td>낮음 (캐시 활용 시 객체 재사용)</td>
</tr>
<tr>
<td>메모리 사용량</td>
<td>많음 (중복 객체 다수 존재)</td>
<td>적음 (공통 객체 공유)</td>
</tr>
<tr>
<td>GC 부담</td>
<td>큼</td>
<td>작음</td>
</tr>
<tr>
<td><code>==</code> 비교 가능 여부</td>
<td>불가 (<code>false</code>)</td>
<td>가능 (<code>true</code>, 캐시 범위 내일 경우)</td>
</tr>
<tr>
<td>속도</td>
<td>느림 (Heap 할당 + GC 대상)</td>
<td>빠름 (캐시 참조만으로 반환)</td>
</tr>
<tr>
<td>코드 권장 여부</td>
<td>❌ Java 9부터 deprecated</td>
<td>✅ 추천되는 표준 방식</td>
</tr>
</tbody></table>
<p>결론적으로, Integer.valueOf()는 성능, 메모리 효율성 모두에서 우월하며, new Integer()는 더 이상 사용을 권장하지 않습니다.</p>
<h3 id="🧪-5-실무-예제-비교">🧪 5. 실무 예제 비교</h3>
<p>예제 1: 캐시 범위 내 비교</p>
<pre><code>Integer a = Integer.valueOf(100);
Integer b = Integer.valueOf(100);
System.out.println(a == b); // true
System.out.println(a.equals(b)); // true</code></pre><p>예제 2: 캐시 범위 외 비교</p>
<pre><code>Integer x = Integer.valueOf(200);
Integer y = Integer.valueOf(200);
System.out.println(x == y); // false
System.out.println(x.equals(y)); // true</code></pre><p>예제 3: 오토박싱이 어떻게 동작할까?</p>
<pre><code>Integer a = 100; // 컴파일러가 자동으로 Integer.valueOf(100) 호출
Integer b = 100;
System.out.println(a == b); // true</code></pre><p>자동 박싱(Autoboxing)도 내부적으로 valueOf()를 사용하므로 동일한 최적화 혜택을 받습니다.</p>
<h3 id="💡-6-캐시-범위-확장-고급">💡 6. 캐시 범위 확장 (고급)</h3>
<p>기본적으로 캐시 범위는 -128 ~ 127로 설정되어 있지만, JVM 옵션으로 확장할 수 있습니다.</p>
<pre><code>-Djava.lang.Integer.IntegerCache.high=1000</code></pre><p>이렇게 설정하면 1000까지의 값도 캐싱되어 valueOf() 사용 시 객체를 재사용하게 됩니다. 대량의 정수 객체가 필요한 경우 성능 개선에 도움이 됩니다.</p>
<h3 id="✅-7-최종-정리-및-실무-가이드">✅ 7. 최종 정리 및 실무 가이드</h3>
<p>new Integer()는 매번 새 객체를 만들고 GC 부담이 크므로 사용하지 말 것</p>
<p>Integer.valueOf()는 캐시를 통해 객체를 재사용하므로 성능과 메모리 측면에서 매우 효율적</p>
<p>== 비교를 사용하려면 캐시 범위 내 값만 안전하게 비교 가능 (그 외엔 .equals() 사용)</p>
<p>Java 9부터 new Integer(int) 생성자는 deprecated 되었음</p>
<h3 id="✍️-마무리">✍️ 마무리</h3>
<p>Integer.valueOf()와 new Integer()의 차이는 단순히 객체 생성 방식의 차원을 넘어, JVM의 메모리 구조, 객체 관리 방식, 성능 최적화 등 Java 내부 작동 원리와 깊은 관련이 있습니다. 실무에서 수많은 정수 객체를 다뤄야 한다면, 이 차이를 이해하고 valueOf() 방식으로 코드를 작성하는 것이 메모리 효율성과 성능 개선에 큰 도움이 됩니다.</p>
<p>작은 습관 하나가 전체 시스템의 퍼포먼스를 바꿀 수 있습니다. 언제나 valueOf()를 우선 사용하고, == 대신 .equals()를 기본으로 생각합시다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[DB] Index ]]></title>
            <link>https://velog.io/@hithae_hothae/DB-Index</link>
            <guid>https://velog.io/@hithae_hothae/DB-Index</guid>
            <pubDate>Wed, 26 Mar 2025 06:18:51 GMT</pubDate>
            <description><![CDATA[<p>📌 실무에서 자주 마주치는 DB 인덱스 성능 이슈와 최적화 전략</p>
<p>서비스 성능 개선을 위해 쿼리 튜닝을 할 때 가장 먼저 고려하는 것이 <strong>인덱스(Index)</strong>입니다. 
하지만 &quot;인덱스를 추가했다고 무조건 빠르다&quot;는 오해도 많은데요, 
이번 글에서는 인덱스를 추가할 때 유의할 점, 복합 인덱스 설계, GROUP BY 쿼리 최적화까지 실제 적용 가능한 팁으로 정리해봅니다.
<br/> </p>
<p>✅ 인덱스를 추가할 때 고려할 점
MariaDB(MySQL)에서 인덱스를 추가하는 방법은 간단합니다:</p>
<pre><code class="language-sql">CREATE INDEX idx_column1 ON your_table (column1);</code></pre>
<p>또는</p>
<pre><code class="language-sql">ALTER TABLE your_table ADD INDEX idx_column1 (column1);</code></pre>
<p>하지만 대용량 테이블의 경우, 인덱스 추가 시 테이블 잠금이 발생하거나 수 초~수 분 이상 시간이 걸릴 수 있습니다. 
이 작업이 CRUD 성능에 어떤 영향을 미치는지도 함께 고려해야 합니다.</p>
<p><br/> <br/> </p>
<p>✅ 인덱스가 CRUD에 미치는 영향</p>
<table>
<thead>
<tr>
<th>항목</th>
<th>영향 설명</th>
</tr>
</thead>
<tbody><tr>
<td>SELECT</td>
<td>성능 대폭 향상 (인덱스 사용 시 탐색 범위 축소)</td>
</tr>
<tr>
<td>INSERT</td>
<td>인덱스 추가로 쓰기 속도 약간 저하 (인덱스도 같이 갱신됨)</td>
</tr>
<tr>
<td>UPDATE/DELETE</td>
<td>조건에 따라 인덱스를 쓰면 빠를 수 있지만, 인덱스가 많을수록 전체 처리 비용은 증가할 수 있음</td>
</tr>
</tbody></table>
<p>성능 측정 기준:</p>
<ul>
<li>EXPLAIN SELECT ...로 실행 계획 확인</li>
</ul>
<ul>
<li><p>SHOW PROFILE, SHOW STATUS 또는 응답 시간 측정</p>
</li>
<li><p>Using index, Using where, Using filesort, Using temporary 등 힌트 확인</p>
</li>
</ul>
<br/> 
✅ 복합 인덱스: 성능 최적화의 핵심</br></br>
📌 복합 인덱스란?
여러 컬럼을 조합한 인덱스입니다.

<pre><code class="language-sql">CREATE INDEX idx_name_age ON user (name, age);</code></pre>
<p>이 인덱스는 (name) 단독 조건 또는 (name, age) 조건에서 효율적입니다.</p>
<p>🎯 Leftmost Prefix Rule
복합 인덱스는 왼쪽에서부터 사용하는 쿼리에서만 잘 작동합니다.</p>
<table>
<thead>
<tr>
<th>WHERE 조건</th>
<th>인덱스 사용 여부</th>
</tr>
</thead>
<tbody><tr>
<td>WHERE name = &#39;Tom&#39;</td>
<td>✅ 사용 가능</td>
</tr>
<tr>
<td>WHERE age = 30</td>
<td>❌ 사용 안 됨</td>
</tr>
<tr>
<td>WHERE name = &#39;Tom&#39; AND age = 30</td>
<td>✅ 전체 인덱스 사용</td>
</tr>
</tbody></table>
<p>이 원칙을 지키지 않으면 복합 인덱스를 만들고도 성능 향상을 얻지 못합니다.</p>
<br/> 
✅ 단일 인덱스 vs 복합 인덱스</br></br>

<table>
<thead>
<tr>
<th>항목</th>
<th>단일 인덱스</th>
<th>복합 인덱스</th>
</tr>
</thead>
<tbody><tr>
<td>구조</td>
<td>컬럼 하나당 하나</td>
<td>여러 컬럼 결합</td>
</tr>
<tr>
<td>쿼리 사용성</td>
<td>단순 조건 쿼리 적합</td>
<td>복합 조건 쿼리에 유리</td>
</tr>
<tr>
<td>성능  조건</td>
<td>적을수록 빠름</td>
<td>다양한 조건 최적화 가능</td>
</tr>
<tr>
<td>병합 가능성</td>
<td>Index Merge 활용</td>
<td>Merge 대신 하나로 최적화</td>
</tr>
</tbody></table>
</br>
실무에서는 JOIN, ORDER BY, GROUP BY까지 고려해 컬럼 순서를 정하는 것이 중요합니다.

<p></br></br></p>
<p>✅ GROUP BY 쿼리와 인덱스의 관계
GROUP BY는 내부적으로 <strong>정렬(SORT)</strong>이나 임시 테이블을 사용합니다.
인덱스를 잘 활용하면 이러한 연산을 생략할 수 있어 성능을 크게 끌어올릴 수 있습니다.</p>
<br/> 
✅ 잘 설계된 인덱스 예</br>

<pre><code class="language-sql">CREATE INDEX idx_dept_job ON employee (department_id, job_title);

SELECT department_id, job_title, COUNT(*)
FROM employee
GROUP BY department_id, job_title;</code></pre>
<p>위 쿼리는 Using index for group-by 로 실행되며, 별도의 정렬 없이 인덱스 순서대로 집계됩니다.</p>
<br/> 
✅ 실무 인덱스 설계 전략 요약<br/> 

<ol>
<li><p>WHERE, JOIN, GROUP BY, ORDER BY 쿼리 구조를 먼저 파악</p>
</li>
<li><p>자주 쓰는 컬럼 + 선택도 높은 컬럼을 기준으로 복합 인덱스 설계</p>
</li>
<li><p>EXPLAIN, SHOW PROFILE, slow_query_log 등을 통해 인덱스 활용 여부 확인</p>
</li>
<li><p>Using index, Using filesort, Using temporary 등 힌트 분석</p>
</li>
<li><p>필요 없는 인덱스는 정리해서 쓰기 성능도 고려할 것</p>
</li>
</ol>
<br/> 
✅ 마무리<br/> 
인덱스는 칼날처럼 날카로운 도구입니다. <br/> 
잘 쓰면 대단한 성능 향상을 만들지만, 무분별하게 남발하면 오히려 쓰기 성능 저하, 공간 낭비, 유지보수 난이도 증가로 이어질 수 있습니다.

<p>쿼리 패턴을 중심으로 설계된 인덱스는 최고의 성능 최적화 수단이라는 걸 기억하세요!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[리눅스] Mount 개념과 디스크 용량 관련]]></title>
            <link>https://velog.io/@hithae_hothae/%EB%A6%AC%EB%88%85%EC%8A%A4-Mount-%EA%B0%9C%EB%85%90%EA%B3%BC-%EB%94%94%EC%8A%A4%ED%81%AC-%EC%9A%A9%EB%9F%89-%EA%B4%80%EB%A0%A8</link>
            <guid>https://velog.io/@hithae_hothae/%EB%A6%AC%EB%88%85%EC%8A%A4-Mount-%EA%B0%9C%EB%85%90%EA%B3%BC-%EB%94%94%EC%8A%A4%ED%81%AC-%EC%9A%A9%EB%9F%89-%EA%B4%80%EB%A0%A8</guid>
            <pubDate>Mon, 06 Jan 2025 08:18:11 GMT</pubDate>
            <description><![CDATA[<h2 id="리눅스-mount와-디스크-관리-정리">리눅스 Mount와 디스크 관리 정리</h2>
<h2 id="1-리눅스-mount-개념">1. 리눅스 Mount 개념</h2>
<p>1) Mount란?
리눅스에서 <strong>마운트(Mount)</strong>는 디스크, 파티션, 혹은 파일 시스템을 특정 디렉터리에 연결하는 과정입니다.
마운트된 디스크는 해당 디렉터리 아래에서 파일 시스템 계층 구조의 일부로 동작합니다.
2) 루트(/)의 역할
/는 리눅스 파일 시스템의 최상위 디렉터리로, 모든 디렉터리의 출발점입니다.
특정 디스크(예: /dev/sda3)를 /에 마운트하면, 해당 디스크가 시스템의 기본 저장소 역할을 하며, /var, /home 등의 하위 디렉터리도 이 디스크 공간을 공유합니다.</p>
<h2 id="2-디스크와-파일-시스템의-내부-처리">2. 디스크와 파일 시스템의 내부 처리</h2>
<p>1) 디스크 공간 관리
리눅스 파일 시스템은 블록(Block) 단위로 디스크 공간을 관리합니다.
예: 블록 크기가 4KB인 경우, 1KB의 파일도 1개의 블록(4KB)을 차지.
inode는 파일 메타데이터(소유자, 권한, 블록 위치 등)를 관리하는 구조체입니다.
2) 디렉터리와 파일 저장
디렉터리는 특수한 파일로 관리되며, 하위 파일과 디렉터리 정보를 inode와 블록에 저장.
파일 생성 시:
사용 가능한 inode를 할당.
파일 크기에 따라 필요한 블록을 디스크에서 할당.</p>
<h2 id="3-df--h와-디스크-공간-확인">3. df -h와 디스크 공간 확인</h2>
<p>1) df -h 명령어
df -h는 현재 마운트된 파일 시스템의 용량과 사용량을 확인하는 명령어입니다.</p>
<p>출력 예시:</p>
<pre><code>df -h

Filesystem      Size  Used Avail Use% Mounted on
/dev/sda3       200G   20G  180G  10% /
Size: 파일 시스템의 총 크기.
Used: 사용 중인 공간.
Avail: 사용 가능한 남은 공간.
Mounted on: 파일 시스템이 마운트된 디렉터리.</code></pre><p>2) du 명령어
특정 디렉터리의 용량 확인:</p>
<pre><code>du -sh /path/to/directory</code></pre><h2 id="4-새로운-디렉터리-마운트">4. 새로운 디렉터리 마운트</h2>
<h3 id="1-a-디렉터리-생성">1) /A 디렉터리 생성</h3>
<pre><code>mkdir /A
</code></pre><p>/A는 /의 하위 디렉터리로, 기본적으로 / 디스크(/dev/sda3) 공간을 사용.</p>
<h3 id="2-새로운-디스크를-마운트">2) 새로운 디스크를 마운트</h3>
<p>디스크 확인:</p>
<pre><code>lsblk</code></pre><p>예: /dev/sdb 디스크 발견.</p>
<p>파일 시스템 생성:</p>
<pre><code>mkfs.xfs /dev/sdb1</code></pre><p>/A 디렉터리에 마운트:</p>
<pre><code>mount /dev/sdb1 /A</code></pre><p>마운트 확인:</p>
<pre><code>df -h

Filesystem      Size  Used Avail Use% Mounted on
/dev/sda3       180G   20G  160G  10% /
/dev/sdb1       100G    1G   99G   1% /A</code></pre><h2 id="5-디스크-분할-및-마운트-분리">5. 디스크 분할 및 마운트 분리</h2>
<h3 id="1-기존-디스크-분할">1) 기존 디스크 분할</h3>
<p>만약 새로운 디스크가 없다면, 기존 디스크에서 일부 공간을 분리:</p>
<pre><code>sudo fdisk /dev/sda</code></pre><p>기존 파티션 크기 축소.
새로운 파티션 생성 (예: /dev/sda4).</p>
<h3 id="2-새-파일-시스템-생성-및-마운트">2) 새 파일 시스템 생성 및 마운트</h3>
<pre><code>mkfs.ext4 /dev/sda4
mount /dev/sda4 /A</code></pre><h2 id="6-마운트-영구-설정">6. 마운트 영구 설정</h2>
<p>재부팅 후에도 마운트를 유지하려면 /etc/fstab에 추가합니다.</p>
<p>디스크 UUID 확인:</p>
<pre><code>blkid /dev/sdb1</code></pre><p>/etc/fstab 편집:</p>
<pre><code>sudo vi /etc/fstab</code></pre><p>추가 내용:</p>
<pre><code>UUID=abc123 /A xfs defaults 0 0</code></pre><p>설정 적용:</p>
<pre><code>sudo mount -a</code></pre><h2 id="7-요약">7. 요약</h2>
<h3 id="마운트의-기본-개념">마운트의 기본 개념:</h3>
<p>디스크를 특정 디렉터리에 연결하여 사용.
루트(/)에 마운트된 디스크는 하위 디렉터리가 동일한 디스크 공간을 공유.
df -h로 용량 확인:</p>
<p>특정 디렉터리는 기본 디스크의 용량을 사용.
별도의 디스크를 마운트하면 독립적인 저장 공간으로 사용 가능.
디렉터리 마운트 분리:</p>
<p>새로운 디스크를 추가하거나 기존 디스크를 분할.
/A를 새로운 디스크로 마운트하여 독립적인 용량 관리.
영구 마운트 설정:</p>
<p>/etc/fstab에 디스크 UUID를 등록하여 재부팅 후에도 유지.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[AWS Builders Korea Program] - AWS 코어 서비스로 간단한 웹 애플리케이션 직접 만들기 (feat. VPC, EC2, ELB)]]></title>
            <link>https://velog.io/@hithae_hothae/AWS-Builders-Korea-Program-AWS-%EC%BD%94%EC%96%B4-%EC%84%9C%EB%B9%84%EC%8A%A4%EB%A1%9C-%EA%B0%84%EB%8B%A8%ED%95%9C-%EC%9B%B9-%EC%95%A0%ED%94%8C%EB%A6%AC%EC%BC%80%EC%9D%B4%EC%85%98-%EC%A7%81%EC%A0%91-%EB%A7%8C%EB%93%A4%EA%B8%B0-feat.-VPC-EC2-ELB</link>
            <guid>https://velog.io/@hithae_hothae/AWS-Builders-Korea-Program-AWS-%EC%BD%94%EC%96%B4-%EC%84%9C%EB%B9%84%EC%8A%A4%EB%A1%9C-%EA%B0%84%EB%8B%A8%ED%95%9C-%EC%9B%B9-%EC%95%A0%ED%94%8C%EB%A6%AC%EC%BC%80%EC%9D%B4%EC%85%98-%EC%A7%81%EC%A0%91-%EB%A7%8C%EB%93%A4%EA%B8%B0-feat.-VPC-EC2-ELB</guid>
            <pubDate>Mon, 20 Mar 2023 11:53:21 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/hithae_hothae/post/ee8b544e-aab0-4300-a2e0-f8c970a67492/image.png" alt=""></p>
<blockquote>
<h4 id="🎤-본-글은-aws-공식-builders-korea-program-온라인-워크샵-세미나를-수강하고-정리한-내용이며-모든-사진-및-내용은-해당-세미나를-출처로-합니다">🎤 본 글은 AWS 공식 Builders Korea Program 온라인 워크샵 세미나를 수강하고 정리한 내용이며, 모든 사진 및 내용은 해당 세미나를 출처로 합니다.</h4>
</blockquote>
<h1 id="들어가며">들어가며,</h1>
<p>약 3시간의 이론 및 실습 과정이며 초심자를 타겟으로 한 세미나라서 부담없이 실습해보며 AWS를 맛볼 수 있다.</p>
<h1 id="a-이론">A. 이론</h1>
<p><img src="https://velog.velcdn.com/images/hithae_hothae/post/1e97d956-c8d7-4b4c-9c38-a2d9648b94ac/image.png" alt=""></p>
<ul>
<li><p>Regions
AWS 서비스 운영지역
각 지역별 <a href="https://aws.amazon.com/ko/compliance/">Compliance</a> 및 비용 고려</p>
</li>
<li><p>Availability Zones (AZ)
하나 혹은 복수의 Data Center 로 구성
재해상황으로 부터 안전하게 물리적 거리</p>
</li>
<li><p>PoP
네트워크나 통신장비가 연결되는 장비
낮은 대기 시간 및 빠른 결과 제공</p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/hithae_hothae/post/933d2348-e798-4699-ac09-2f3754358054/image.png" alt=""></p>
<ul>
<li>Virtual Private Cloud (가상의 네트워크 환경)
리전 레벨의 자원. 타 리전에서 사용 불가.</li>
</ul>
<ul>
<li>AZ(가용 영역 레벨의 자원)
하나의 EC2를 다른 AZ에 불가.</li>
</ul>
<h1 id="b-실습-web-application-with-ec2">B. 실습 Web application with EC2</h1>
<p><img src="https://velog.velcdn.com/images/hithae_hothae/post/a7d9f975-8f3a-4a19-8469-7a88e3bb004b/image.png" alt=""></p>
<ol>
<li>네트워크 구성</li>
<li>웹 서버 생성</li>
<li>로드 밸런서 구성</li>
</ol>
<h1 id="1-네트워크-구성하기-vpc">1. 네트워크 구성하기 (VPC)</h1>
<h2 id="11-vpc-생성">1.1. VPC 생성</h2>
<p>Virtual Private Cloud(VPC)
VPC는 자체 데이터 센터에서 운영하는 기존 네트워크와 아주 유사한 가상 네트워크입니다. 
VPC를 생성한 후 서브넷을 추가할 수 있습니다.</p>
<ul>
<li><p>VPC 콘솔 에 로그인 합니다.</p>
</li>
<li><p>아래의 화면에서 VPC 마법사 시작을 클릭하여 VPC 생성 마법사를 시작합니다. VPC 마법사를 사용하면 기본이 아닌 VPC 구성을 손쉽게 생성할 수 있습니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/4720c146-dd8f-4b42-97be-b9a2be7f8252/image.png" alt=""></p>
</li>
<li><p>VPC 설정에서 VPC,서브넷 등을 선택합니다. 이름의 경우 VPC-Lab 으로 작성합니다.CIDR 블록은 기본값인 10.0.0.0/16 으로 설정합니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/e9acbbf4-ee7d-4057-b7bf-8667ca5b2460/image.png" alt=""></p>
</li>
<li><p>가용 영역(AZ) 는 1개를 선택하고, 가용 영역은 ap-northeast-2a 로 선택합니다. 이 가용영역은 아까 설정했던 VPC 의 부분집합 입니다. 밑에 있는 퍼블릭 서브넷 수도 1개로 선택하고, CIDR 블록을 10.0.10.0/24 로 설정합니다. 프라이빗 서브넷은 만들지 않으므로, 0개를 선택합니다.이후 다른 것은 선택하지 않고, 우측 하단의 VPC 생성 버튼을 누릅니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/90060f9b-a918-4673-bc32-a7ebe4d09ae5/image.png" alt=""></p>
</li>
</ul>
<blockquote>
<p>VPC IPv4 CIDR 블록 값을 지정할 때에는 향후 직접 연결할 가능성이 있는 네트워크와 주소가 중복되지 않도록 할당하는 것이 중요합니다. 또한, 향후 확장을 고려하여 충분히 큰 주소를 할당합니다.</p>
</blockquote>
<ul>
<li><p>생성이 완료되면 VPC-Lab-vpc 이름의 VPC 를 볼 수 있습니다. 이를 VPC-Lab 으로 이름을 변경해 줍니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/a170af06-702a-4df5-b542-95ee6081f0ff/image.png" alt=""></p>
</li>
<li><p>서브넷 화면에 들어가서 방금 서브넷 이름도 public subnet A 로 변경해 줍니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/743a66e4-7591-4033-a435-66e105e4589e/image.png" alt=""></p>
</li>
<li><p>현재까지의 아키텍처 구성은 아래와 같습니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/a555cd81-1c98-44a8-bb0e-57ef3b72ba83/image.png" alt=""></p>
</li>
</ul>
<hr>
<h4 id="cidr-주소-범위-이해하기">CIDR 주소 범위 이해하기</h4>
<p>CIDR(Classless Inter-Domain Routing)은 네트워크의 주소와 크기를 표현하는 방식 중 하나입니다. 위의 실습에서 생성한 VPC는 16을 서브넷 값으로 하는 IP 주소 범위입니다. 각 자원에 줄 수 있는 IP 갯수는 2의 16승인 65,536개입니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/6d85dfee-64dd-4291-936e-08de93b1ad6c/image.png" alt="">
VPC CIDR 블록을 지정할 때, 허용된 블록 크기는 /16 넷 마스크 (사용 가능한 IP 주소 65,536개)~ /28 넷 마스크(사용 가능한 IP 주소 16개)입니다. 각 서브넷 CIDR 블록에서 첫 4개의 IP 주소와 마지막 IP 주소는 사용자가 사용할 수 없으므로 인스턴스에 할당할 수 없습니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/b95372f7-601b-4bc1-9f6a-08867eb4039e/image.png" alt=""></p>
<hr>
<h2 id="12-추가-서브넷-생성">1.2. 추가 서브넷 생성</h2>
<p>고가용성을 확보하기 위해, 다중 가용 영역에 서비스를 배포하는 것이 중요합니다. 따라서 본 실습에서는 앞에서 생성한 서브넷이 위치한 가용 영역 A 외에 다른 가용 영역인 C에 서브넷을 생성합니다.</p>
<ul>
<li><p>왼쪽 사이드 바에서 서브넷 메뉴를 클릭한 후, 서브넷 생성 버튼을 클릭합니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/faf0a7bb-d07d-4ae0-ab19-3b0ae479a399/image.png" alt=""></p>
</li>
<li><p>VPC ID에는 방금 생성한 VPC를 선택합니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/ac52b758-8c50-4308-b23c-7f9e10f20731/image.png" alt=""></p>
</li>
<li><p>아래의 서브넷 설정에서는 화면과 같이 값을 입력한 후, 서브넷 생성 버튼을 클릭합니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/7f42dda1-4a67-4862-aade-1b7e2f0cbcb9/image.png" alt=""></p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/hithae_hothae/post/a128f32f-5663-4854-87aa-9508535cf81f/image.png" alt=""></p>
<ul>
<li><p>public subnet A와 public subnet C가 모두 생성된 것을 확인할 수 있습니다. 
<img src="https://velog.velcdn.com/images/hithae_hothae/post/77da006b-7c7a-4f00-9c96-a766f0527dce/image.png" alt=""></p>
</li>
<li><p>현재까지의 아키텍처 구성은 아래와 같습니다. 
<img src="https://velog.velcdn.com/images/hithae_hothae/post/85413268-c8b5-41c1-aea7-a880e505465e/image.png" alt=""></p>
</li>
</ul>
<h2 id="13-라우팅-테이블-편집">1.3. 라우팅 테이블 편집</h2>
<p>라우팅 테이블에는 서브넷 또는 게이트 웨이의 네트워크 트래픽이 전송되는 위치를 결정하는데 사용되는 라우팅이라는 규칙 집합이 포함되어 있습니다.</p>
<p>기본 라우팅 테이블은 VPC와 함께 자동으로 생성되는 라우팅 테이블입니다. 다른 라우팅 테이블과 명시적으로 연결되지 않은 모든 서브넷의 라우팅을 제어하는 역할을 합니다.
사용자 지정 라우팅 테이블은 기본 라우팅 테이블 외에 사용자가 생성한 라우팅 테이블입니다.</p>
<ul>
<li><p>서브넷 메뉴에서 작업 버튼을 클릭한 후, 라우팅 테이블 연결 편집을 선택합니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/e7d024ff-1271-48c0-b80e-77099da5c07b/image.png" alt=""></p>
</li>
<li><p>라우팅 테이블 ID에서 기본 라우팅 테이블이 아닌 다른 라우팅 테이블을 선택한 후, 저장합니다. 이때, 선택한 라우팅 테이블에 인터넷으로 향하는 경로가 있는지 확인합니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/328c40ee-9b3e-452e-8612-0df1bf521482/image.png" alt=""></p>
</li>
<li><p>public subnet C를 선택한 후, 세부 정보 탭에서 변경된 라우팅 테이블 하이퍼 링크를 클릭하면 라우팅 정보를 확인할 수 있습니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/1840280f-5c09-46c4-a32e-f2fb72b3c2ab/image.png" alt="">
라우팅 테이블을 클릭 후, 라우트 탭에서 확인할 수 있는 결과는 아래와 같습니다. 이를 통해, public subnet C도 인터넷으로 향하는 경로가 생성되었음을 확인할 수 있습니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/06ff0a01-46c8-47c7-ad1f-33447f032fde/image.png" alt=""></p>
</li>
<li><p>현재까지의 아키텍처 구성은 아래와 같습니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/f606be5a-d8f4-44c4-84fb-4c3d44c33ad8/image.png" alt=""></p>
</li>
</ul>
<h2 id="14-보안-그룹-생성">1.4. 보안 그룹 생성</h2>
<p>보안 그룹은 인스턴스에 대한 인바운드 및 아웃바운드 트래픽을 제어하는 가상 방화벽 역할을 합니다.</p>
<ul>
<li><p>왼쪽 사이드 바에서 보안 그룹 메뉴를 클릭한 뒤, 보안 그룹 생성 버튼을 클릭합니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/8ed3efad-cbf3-4842-a153-ecb45bab2be6/image.png" alt=""></p>
</li>
<li><p>화면과 같이 보안 그룹 및 설명을 입력한 후, 본 실습에서 생성한 VPC를 선택합니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/8f37af41-395a-4392-a3f4-04620b2120c5/image.png" alt=""></p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/hithae_hothae/post/34051d18-7d66-42a4-9f9f-da6fe80a96bd/image.png" alt=""></p>
<ul>
<li>인바운드 규칙에서 아래와 같이 규칙을 부여한 후, 오른쪽 하단의 보안 그룹 생성 버튼을 클릭합니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/afc47c66-2eff-4ea5-ae62-408df07fab48/image.png" alt=""></li>
</ul>
<p><img src="https://velog.velcdn.com/images/hithae_hothae/post/f3d7a80f-ed65-4221-8adb-5230d1066a6d/image.png" alt=""></p>
<ul>
<li>아래와 같이 인바운드 규칙이 생성된 것을 확인합니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/f9ae0625-baf7-460d-a670-1fd8df222912/image.png" alt=""></li>
</ul>
<h1 id="2-웹-서버-생성하기">2. 웹 서버 생성하기</h1>
<p>EC2(Elastic Compute Cloud) 이해하기</p>
<p>Amazon EC2 는 AWS 클라우드에서 확장 가능한 컴퓨팅 용량을 제공합니다. Amazon EC2를 사용하면 하드웨어 선투자할 필요가 없어 더 빠르게 애플리케이션을 개발하고 배포할 수 있습니다. Amazon EC2를 통해, 원하는 만큼 가상 서버를 구축하고 보안 및 네트워크 구성과 스토리지 관리가 가능합니다. 또한, Amazon EC2는 갑작스러운 트래픽 증가와 같은 변동 사항에도 신속하게 규모를 확장하거나 축소할 수 있어 서버 트래픽 예측 필요성이 줄어듭니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/9b97187f-5bb8-475e-ba77-d6ce75120ebb/image.png" alt=""></p>
<h2 id="21-웹-서버-인스턴스-생성하기">2.1. 웹 서버 인스턴스 생성하기</h2>
<blockquote>
<ul>
<li>AMI 선택</li>
</ul>
</blockquote>
<ul>
<li>인스턴스 유형 선택</li>
<li>인스턴스 구성</li>
<li>스토리지 추가</li>
<li>태그 추가</li>
<li>보안 그룹 구성</li>
<li>검토</li>
</ul>
<hr>
<ul>
<li><p>EC2 콘솔 에 로그인 합니다.</p>
</li>
<li><p>아래의 화면에서 인스턴스 시작을 클릭하여 인스턴스를 생성합니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/28dc90af-2237-4a72-9bb3-fe3b9371397e/image.png" alt=""></p>
</li>
<li><p>이름에 webserver 1을 입력합니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/8a2be740-addc-4bdb-abe7-98bf3837b50a/image.png" alt=""></p>
</li>
</ul>
<blockquote>
<p>🎈 여기에서 추가 태그 추가라는 것이 보이시나요? AWS 리소스에는 태그 형태로 메타 데이터를 지정할 수 있습니다. 태그를 사용하면 리소스를 손쉽게 관리, 식별, 정리, 검색 및 필터링을 할 수 있습니다. 태그를 생성하여 용도, 소유자, 환경 또는 기타 기준으로 리소스를 분류할 수 있습니다.</p>
</blockquote>
<ul>
<li><p>어플리케이션 및 OS 이미지 에서는 Quick Start 에서 다음과 같이 선택합니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/5f0b02ad-986b-415d-9d63-6bb514228fea/image.png" alt="">
<img src="https://velog.velcdn.com/images/hithae_hothae/post/3d8aac8d-2e35-4e2e-8da9-063258f126de/image.png" alt=""></p>
</li>
<li><p>인스턴스 유형으로는 t2.micro를 선택합니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/17baf021-1cb3-4ab2-9254-00fe4825204b/image.png" alt=""></p>
</li>
<li><p>키 페어(로그인) 에서는 새 키 페어 생성 을 선택합니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/6497680a-f147-470b-8489-1fb3e682502c/image.png" alt=""></p>
</li>
<li><p>키 페어 생성창에서는 다음과 같이 입력 및 선택합니다. 그 다음 키 페어 생성을 누릅니다. 키를 다운받는다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/3fe5198c-fde4-46b9-b3cf-dd972c228565/image.png" alt=""></p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/hithae_hothae/post/891b4efd-ca74-44da-a0bb-dad88e5450c4/image.png" alt=""></p>
<ul>
<li><p>네트워크 설정에서 편집 버튼을 누릅니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/83a4c55b-9e60-4cea-b6d9-1f355a09eb51/image.png" alt=""></p>
</li>
<li><p>VPC 와 서브넷, 퍼블릭 IP 자동 할당 세션에 다음의 값을 입력합니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/d7ede628-1d2b-4bd5-99e4-d9ed5658a0b9/image.png" alt=""></p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/hithae_hothae/post/6dc16350-bb2d-4e5c-bec5-3e73fd7cb1a6/image.png" alt=""></p>
<ul>
<li><p>방화벽(보안 그룹) 으로는 기존 보안 그룹 선택 을 선택한 후, 아까 보안 그룹 생성하기 에서 생성했던 보안그룹인 webserver-sg를 찾아서 선택합니다
<img src="https://velog.velcdn.com/images/hithae_hothae/post/899b8920-21c2-4c7d-b60d-ca5c5e298520/image.png" alt=""></p>
</li>
<li><p>스토리지 구성에서는 기본 값인 8 GiB gp2 로 설정합니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/c1b431e2-224a-4d47-9738-80b3ffdf0a23/image.png" alt=""></p>
</li>
<li><p>바로 아래에 있는 고급 세부 정보 를 펼쳐서 가장 아래로 스크롤 하면 사용자 데이터 가 보이며, 넓은 칸이 보입니다. 그 칸에 아래의 내용을 복사 및 붙여넣기 합니다.</p>
<blockquote>
<p>🎈 고급 세부 정보 - 사용자 데이터
인스턴스가 시작되며 실행 될 수 있도록 스크립트를 작성 가능</p>
</blockquote>
</li>
</ul>
<pre><code class="language-shell">#!/bin/sh

    # Install a LAMP stack
    amazon-linux-extras install -y lamp-mariadb10.2-php7.2 php7.2
    yum -y install httpd php-mbstring

    # Start the web server
    chkconfig httpd on
    systemctl start httpd

    # Install the web pages for our lab
    if [ ! -f /var/www/html/immersion-day-app-php7.tar.gz ]; then
    cd /var/www/html
    wget https://aws-joozero.s3.ap-northeast-2.amazonaws.com/immersion-day-app-php7.tar.gz  
    tar xvfz immersion-day-app-php7.tar.gz
    fi

    # Install the AWS SDK for PHP
    if [ ! -f /var/www/html/aws.zip ]; then
    cd /var/www/html
    mkdir vendor
    cd vendor
    wget https://docs.aws.amazon.com/aws-sdk-php/v3/download/aws.zip
    unzip aws.zip
    fi

    # Update existing packages
    yum -y update
</code></pre>
<p><img src="https://velog.velcdn.com/images/hithae_hothae/post/56231bdd-407d-4e88-a863-2a5316882704/image.png" alt=""></p>
<ul>
<li><p>이제 오른쪽에 있는 요약에서 인스턴스 시작 버튼을 누릅니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/101cfb82-2cb8-40b9-ae76-1e02dd3c46b9/image.png" alt=""></p>
</li>
<li><p>인스턴스가 성공적으로 만들어지게 되면, 인스턴스 창에서 다음과 같이 인스턴스 상태와 상태 검사를 확인하실 수 있습니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/857e62da-4cbe-4267-a998-ee1749b48cb0/image.png" alt=""></p>
</li>
<li><p>인스턴스 화면에서 생성한 인스턴스를 클릭한 후, 세부 정보에서 IPv4 퍼블릭 IP 값을 복사한 후, 웹 브라우저에 붙여 넣습니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/823209f1-efba-4b80-8b27-b4e97f350241/image.png" alt=""></p>
</li>
<li><p>아래와 같은 웹 화면을 확인할 수 있습니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/0a6698c2-30bc-45ff-889e-31aac6b87350/image.png" alt=""></p>
</li>
<li><p>현재까지의 아키텍처 구성은 아래와 같습니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/60377409-8708-437d-a826-516069c84109/image.png" alt=""></p>
</li>
</ul>
<h2 id="22-ami-생성하기">2.2. AMI 생성하기</h2>
<ul>
<li>AMI 개념
Amazon Machine Image(AMI)는 인스턴스를 시작하는데 필요한 정보를 제공합니다. 인스턴스를 시작할 때, AMI를 지정해야하는데, 동일한 구성의 인스턴스가 여러 개 필요할 때는 한 AMI를 사용하여 여러 인스턴스를 시작할 수 있습니다. 본 실습에서는 4-1 웹 서버 인스턴스 생성하기에서 생성한 인스턴스의 이미지를 뜨는 작업을 수행합니다.</li>
</ul>
<hr>
<ul>
<li><p>앞서 생성한 인스턴스를 클릭한 후, 작업 메뉴에서 이미지 및 템플릿 클릭, 이미지 생성을 클릭합니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/c9bf3e05-95b9-43dd-bbdd-cdcf6d127aa0/image.png" alt=""></p>
</li>
<li><p>이미지 생성 페이지에서 아래와 같이 값(webserver-ami)을 입력한 후, 우측 하단의 이미지 생성 버튼을 클릭합니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/c3df0056-03c1-410a-bbca-9f9f5163ff13/image.png" alt=""></p>
</li>
<li><p>왼쪽 사이드 바에서 AMI 메뉴를 클릭한 후, 방금 생성한 이미지를 확인합니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/317a42e7-e65a-4df7-8b70-1f4a7dfdd0bd/image.png" alt=""></p>
</li>
<li><p>현재까지의 아키텍처 구성은 아래와 같습니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/a96e0648-91d8-4c16-a7e2-7e91c87f8213/image.png" alt=""></p>
</li>
</ul>
<h2 id="23-ami-기반-인스턴스-생성하기">2.3. AMI 기반 인스턴스 생성하기</h2>
<ul>
<li><p>AMI 메뉴에서 상태 변경이 완료되면 AMI로 인스턴스 시작 버튼을 클릭합니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/1aa65ec0-229d-4f51-a352-851ee927c023/image.png" alt=""></p>
</li>
<li><p>이름 및 태그 에 이름을 webserver 2 로 지정합니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/2b331cd0-2cfc-4722-9b4f-a033e7aa92fa/image.png" alt=""></p>
</li>
<li><p>쭉 내려오셔서 키 페어(로그인) 에서 키 페어 이름을 keypair-seoul 로 지정합니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/13c1c322-9b76-4be2-8657-4344126c9bfa/image.png" alt=""></p>
</li>
<li><p>네트워크 설정 으로 넘어와서 편집을 누릅니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/8d9ea199-9e36-4b48-91ef-6304cb3e0a1c/image.png" alt=""></p>
</li>
<li><p>아래와 같이 값을 입력합니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/31dbda51-4076-4e18-bc34-4abb9fd24b96/image.png" alt="">
<img src="https://velog.velcdn.com/images/hithae_hothae/post/a91e4ec0-4885-46c3-b30b-e2cd8e35883a/image.png" alt=""></p>
</li>
<li><p>여기까지 하셨다면, 오른쪽 밑에 있는 인스턴스 시작 을 눌러 인스턴스를 시작합니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/f87972bf-0fe8-4f0a-a920-01a0eb6777fb/image.png" alt=""></p>
</li>
</ul>
<ul>
<li><p>왼쪽 사이드 바에서 인스턴스 메뉴를 클릭한 후, 방금 생성된 webserver 2의 퍼블릭 IPv4 주소를 복사한 후, 웹 브라우저에 붙여 넣습니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/a42a86fe-5756-4cc4-87a8-a98dc081c50c/image.png" alt=""></p>
</li>
<li><p>아래와 같은 웹 화면을 확인할 수 있습니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/d669e4bf-6236-4594-a304-ed5f40bd425f/image.png" alt=""></p>
</li>
<li><p>현재까지의 아키텍처 구성은 아래와 같습니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/fcf1e09d-4050-4de4-83dc-4e946d7a1409/image.png" alt=""></p>
</li>
</ul>
<h1 id="3-로드밸런서-구성하기">3. 로드밸런서 구성하기</h1>
<blockquote>
<ul>
<li>ELB(Elastic Load Balancing) 이해하기
Elastic Load Balancing 은 들어오는 애플리케이션 트래픽을 Amazon EC2 인스턴스, 컨테이너, IP 주소, Lambda 함수, 가상 어플라이언스와 같은 여러 대상에 자동으로 분산시킵니다. Elastic Load Balancing은 단일 가용 영역 또는 여러 가용 영역에서 다양한 애플리케이션 부하를 처리할 수 있습니다. Elastic Load Balancing이 제공하는 네 가지 로드 밸런서는 모두 애플리케이션의 내결함성에 필요한 고가용성, 자동 조정, 강력한 보안을 갖추고 있습니다.</li>
</ul>
<p>Application Load Balancer
Network Load Balancer
Gateway Load Balancer
Classic Load Balancer</p>
</blockquote>
<hr>
<p><img src="https://velog.velcdn.com/images/hithae_hothae/post/53b4743b-ba78-485a-b1dc-0165eb8bc5bc/image.png" alt=""></p>
<ul>
<li>왼쪽 사이드 바에서 로드 밸런서 메뉴를 클릭한 후, 로드 밸런서 생성 버튼을 클릭합니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/7bf4b82b-0bdb-4f9b-b965-15fdb7f12d1e/image.png" alt=""></li>
</ul>
<ul>
<li>Load Balancer 유형 선택에서 Application Load Balancer를 선택합니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/b5ef97a3-57ca-43d9-a9b2-7a080d08a32f/image.png" alt=""></li>
</ul>
<ul>
<li>Load Balancer 구성에서 아래와 같이 값을 입력한 후, 스크롤을 내립니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/44be0b96-131a-4384-a98a-59ea84231b79/image.png" alt="">
<img src="https://velog.velcdn.com/images/hithae_hothae/post/4b375620-69d0-4f5b-b2bf-708cc0686c90/image.png" alt=""></li>
</ul>
<blockquote>
<p>🎈 리스너는 연결 요청을 확인하는 프로세스입니다. 리스너는 프로토콜 및 포트로 구성되며 로드밸런서의 앞단과 뒷단을 연결하는 역할을 합니다</p>
</blockquote>
<ul>
<li><p>VPC에서는 VPC-Lab을 선택한 후, 매핑 항목에서는 public subnet A와 public subnet C를 선택합니다. 해당 작업은 로드밸런서에서 트래픽을 라우팅할 VPC와 가용 영역을 지정하는 작업입니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/60374e8b-6bfe-4bd0-9880-77794716d9b5/image.png" alt="">
<img src="https://velog.velcdn.com/images/hithae_hothae/post/2b082f22-4dbf-49b0-9129-b3c84edc4423/image.png" alt=""></p>
</li>
<li><p>보안 그룹에서 새 보안 그룹 생성 버튼을 클릭합니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/4b7ca061-83ba-45ae-aba9-7ee171793893/image.png" alt=""></p>
</li>
<li><p>보안 그룹 생성에서 보안 그룹 이름에는 webalb-sg 을 입력하고 설명에는 security group for load balancer 를 입력합니다. VPC 에서 돋보기를 눌러서 VPC-Lab 으로 변경합니다. 인바운드 규칙으로는 유형으로는 HTTP, 소스로는 내 IP 를 선택합니다. 보안 그룹 생성 버튼을 눌러 보안 그룹을 생성합니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/9a677e78-050e-4dad-b186-03ecc97900b0/image.png" alt=""></p>
</li>
<li><p>다시 로드 밸런서 화면으로 돌아와서 방금 만든 보안 그룹으로 보안 그룹을 지정합니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/5daea6f5-aa8c-4674-baed-1007a77ccb66/image.png" alt=""></p>
</li>
<li><p>리스너 및 라우팅에서 대상 그룹 생성 버튼을 클릭합니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/82d68097-1352-4def-8ad9-050fec4d5228/image.png" alt=""></p>
</li>
<li><p>대상 유형 선택에는 인스턴스 를 선택하고 대상 그룹 이름은 webserver-tg 로 지정합니다. 프로토콜은 HTTP 로 선택합니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/1f6165e6-a481-4982-9094-608da73c5780/image.png" alt=""></p>
</li>
<li><p>VPC 에는 VPC-Lab 을 지정합니다. 그 다음 오른쪽 아래의 다음 버튼을 누릅니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/48eb7f5e-ceb1-4479-9033-958d5b75f687/image.png" alt=""></p>
</li>
<li><p>대상 등록에 보이는 두 개의 인스턴스 webserver 1 과 webserver 2 를 아래에 보류 중인 것으로 포함 버튼을 통해 대상으로 등록합니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/09abb4c2-8785-4552-8dfe-bf07df806631/image.png" alt=""></p>
</li>
<li><p>대상 그룹이 생성되면 로드 밸런서 화면으로 다시 돌아와서 리스너 및 라우팅 에서 대상 그룹으로 지정합니다.이후 오른쪽 아래의 로드밸런서 생성 으로 로드밸런서를 생성합니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/f236b56d-53ec-4bff-8d3f-95aa30a57db5/image.png" alt=""></p>
</li>
<li><p>로드밸런서를 통하여 웹 애플리케이션에 접근하기 이전, 챕터 4에서 생성하였던 웹 서버가 로드 밸런서의 트래픽만 받게 하기 위하여 보안 그룹 인바운드 규칙 편집 작업을 수행합니다. 보안 그룹 메뉴에서 webserver-sg 보안 그룹을 선택 후, 인바운드 규칙 편집을 클릭합니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/a352f464-374a-48f5-b230-fee7f4224172/image.png" alt="">
기존 HTTP 인바운드 규칙을 삭제후, 새로운 규칙을 생성합니다. 로드밸런서의 트래픽만 받을 수 있도록 소스 부분에서 사용자 지정 클릭 후, webalb-sg를 지정합니다. 이후 오른쪽 하단에 있는 규칙 저장 버튼을 누릅니다.</p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/hithae_hothae/post/4ffd0d93-fb7c-4480-90ca-96c14e5a5f30/image.png" alt="">
<img src="https://velog.velcdn.com/images/hithae_hothae/post/008f600c-1890-456a-8d5e-abdbff3f2f8a/image.png" alt=""></p>
<ul>
<li><p>다시 로드 밸런서 메뉴로 들어와 방금 생성한 로드밸런서의 상태를 확인한 후, active가 되면 아래의 설명에서 DNS 이름을 복사하여 웹 브라우저에 붙여 넣습니다. (참고: DNS 이름을 웹 브라우저로 복사 붙여넣기 후 연결이 안될 시 http://&quot;DNS 이름&quot;로 연결 되었는지 확인하시기 바랍니다. 본 실습에서는 HTTP 인바운드 규칙을 허용해놨습니다.)
<img src="https://velog.velcdn.com/images/hithae_hothae/post/38d6b60f-c6be-4d79-94a9-b2085ebbf3d4/image.png" alt=""></p>
</li>
<li><p>아래와 같은 웹 화면을 확인할 수 있습니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/e4db9d23-0943-480e-9a68-957f316c0d3a/image.png" alt=""></p>
</li>
<li><p>웹 화면 새로 고침을 클릭하면 Application Load Balancer에서 기본으로 제공하는 라운드 로빈 알고리즘에 따라 화면에 보이는 InstanceID, Availabilty Zone 값이 변경되는 것을 확인할 수 있습니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/60ee5009-2913-439f-b00b-51217f75402b/image.png" alt=""></p>
</li>
<li><p>현재까지의 아키텍처 구성은 아래와 같습니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/9ef4640c-163f-4a96-9173-e7951bc6649f/image.png" alt=""></p>
</li>
</ul>
<hr>
<h4 id="로드밸런서-대상-상태-확인">로드밸런서 대상 상태 확인</h4>
<ul>
<li><p>왼쪽 사이드 바에서 대상 그룹 메뉴를 클릭한 후, 로드밸런서 생성 단계에서 만든 대상 그룹을 선택합니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/b42f1210-f412-4267-8add-a456a39d7dab/image.png" alt=""></p>
</li>
<li><p>세부 페이지에서 대상 탭을 클릭하면 로드밸런서에 등록된 인스턴스들의 상태를 확인할 수 있습니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/8e8a2e79-3c25-498a-9add-dc970410050b/image.png" alt=""></p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[AWS] Security Group & NACL]]></title>
            <link>https://velog.io/@hithae_hothae/AWS-Security-Group</link>
            <guid>https://velog.io/@hithae_hothae/AWS-Security-Group</guid>
            <pubDate>Sat, 18 Mar 2023 09:22:53 GMT</pubDate>
            <description><![CDATA[<p>보안 그룹은 인스턴스에 대한 인바운드 및 아웃바운드 트래픽을 제어하는 가상 방화벽 역할</p>
<ul>
<li><p>보안 장치
Network Access List(NACL)와 함께 방화벽의 역할을 하는 서비스</p>
</li>
<li><p>Port 허용
트래픽이 지나갈 수 있는 Port, Source 설정 가능
Deny 불가능. NACL 로 가능.</p>
</li>
<li><p>인스턴스 단위
하나의 인스턴스에 하나 이상의 Security Group 설정 가능
NACL 의 경우 서브넷 단위
설정된 Instance 는 설정한 모든 SG의 룰을 적용 받음</p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/hithae_hothae/post/cf39c23d-f0e3-4492-9b5b-b2da2f3ea8db/image.png" alt=""></p>
<ul>
<li><p>설정된 모든 룰을 사용해서 필터링 (AND 조건)
NACL의 경우 적용된 룰의 순서대로 필터링</p>
</li>
<li><p>Stateful (Security Group)
Inbound로 들어온 트래픽이 별 다른 Outbound 설정 없이 나갈 수 있음.
들어온 상태를 기억하고 있다고 Stateful</p>
</li>
<li><p>Stateless (NACL)
정해둔 Inbound/Outbound 정책 그대로만 허용/차단 한다.</p>
</li>
</ul>
<hr>
<ul>
<li>EC2 인스턴스 보안 그룹 설정
<img src="https://velog.velcdn.com/images/hithae_hothae/post/54971d8e-c9e4-4e6a-a011-a16dd8889e6a/image.png" alt=""></li>
</ul>
<p>설정된 보안 그룹을 확인 및 편집
<img src="https://velog.velcdn.com/images/hithae_hothae/post/57c55cf9-9617-4676-aa38-6d9253f9478d/image.png" alt=""></p>
<ul>
<li>인바운드 규칙 편집
<img src="https://velog.velcdn.com/images/hithae_hothae/post/78abfaaa-7fd6-499a-8155-47514c0bdbb5/image.png" alt=""></li>
</ul>
<hr>
<h4 id="참조">참조</h4>
<p><a href="https://www.youtube.com/watch?v=IwaJoXpO4l4&amp;list=PLfth0bK2MgIa6w63IglYQD_qljDntSh-H&amp;index=4&amp;t=160s">https://www.youtube.com/watch?v=IwaJoXpO4l4&amp;list=PLfth0bK2MgIa6w63IglYQD_qljDntSh-H&amp;index=4&amp;t=160s</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[AWS] CloudFront.  ]]></title>
            <link>https://velog.io/@hithae_hothae/AWS-CDN-CloudFront</link>
            <guid>https://velog.io/@hithae_hothae/AWS-CDN-CloudFront</guid>
            <pubDate>Fri, 03 Mar 2023 00:18:47 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/hithae_hothae/post/42ac5943-71c4-4ce5-bc63-a46f001b5c0e/image.png" alt=""></p>
<h1 id="cloud-front">Cloud Front</h1>
<p>WebBrowser 가 WebServer 로 요청하는 내용을 중간에서 캐싱하는 서비스. 
캐싱 기능 및 전세계에 컨텐츠를 빠르게 제공 할 수 있도록 하는 CDN 기능을 가진 서비스.</p>
<h3 id="cache">Cache</h3>
<p>동적으로 생성하여 제공하는 웹페이지를, 일정 시간동안 저장하여 재 요청을 하지 않도록 하는 기술.</p>
<p>웹서버는 Cache-Control 을 이용하여, 본인에게 일정시간 요청하지 않도록 설정하도록 html 상단에 아래를 추가해본다.</p>
<blockquote>
</blockquote>
<pre><code>&lt;?php
header(&quot;Cache-Control : max-age=10&quot;);
sleep(1);
?&gt;</code></pre><p>웹브라우저에서 새로고침(F5)을 하는 경우는, CacheControl max age를 0으로 세팅해서 요청하기에, 캐싱이 안됨. 링크를 통해 들어가는 경우는 Cache 기능 사용.</p>
<p>WebServer 가 Cloud Front 에게 Contents 를 제공하면서 &#39;일정 시간동안 요청하지 마라&#39; 라고 부여하는 값(?) . Cloud Front 가 WebBrowser 로 이를 전달하여 WebBrowser에서 요청을 하지 않게 한다.</p>
<p><img src="https://velog.velcdn.com/images/hithae_hothae/post/0da00c29-623c-4305-837d-a6d6d848813c/image.png" alt=""></p>
<h4 id="invalidation-무효화">Invalidation (무효화)</h4>
<p>특정 경로,파일에 대해 Cache된 내용을 무효화 하는 CloudFront 기능.</p>
<blockquote>
<p>CloudFront에는 캐시된 콘텐츠를 무효화하고 업데이트된 콘텐츠를 제공하는 무효화 기능이 있습니다. 무효화란 캐시된 콘텐츠를 강제로 삭제하여 새로운 콘텐츠를 가져오는 것을 의미합니다. 이 기능을 사용하면 업데이트된 콘텐츠가 즉시 반영되며, 사용자가 이전 버전의 캐시된 콘텐츠를 볼 수 없도록 할 수 있습니다.</p>
</blockquote>
<ul>
<li>전체 무효화 (Invalidation): 캐시된 모든 콘텐츠를 무효화하는 것으로, 업데이트된 콘텐츠가 즉시 반영됩니다. 이 기능을 사용하면 모든 사용자가 새로운 콘텐츠를 볼 수 있습니다. 다만, 비용과 시간이 소요되는 작업이므로 자주 사용하지 않는 것이 좋습니다.<blockquote>
</blockquote>
</li>
<li>개별 무효화 (Individual Invalidation): 특정 파일이나 디렉토리를 선택하여 무효화하는 것으로, 업데이트된 콘텐츠만 새로 로드됩니다. 이 기능은 비교적 빠르고 비용도 적게 들기 때문에 자주 사용됩니다.<blockquote>
</blockquote>
무효화 기능은 API, AWS Management Console, AWS CLI 및 SDK를 통해 수행할 수 있으며, 캐시 무효화 작업의 상태와 진행 상황은 CloudFront 콘솔에서 모니터링할 수 있습니다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/75480328-7dc1-4edc-9b1a-738288abbbf6/image.png" alt=""></li>
</ul>
<h2 id="cdn">CDN</h2>
<p>CDN : Contents Delivery Network</p>
<p>전세계에 캐시 서버에 컨텐츠를 제공하여, 어느 나라에 있던 빠르게 정보를 제공 할 수 있음.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[AWS EC2] EBS와 AMI를 통한 Backup/ScaleUp]]></title>
            <link>https://velog.io/@hithae_hothae/AWS-EC2-EBS%EC%99%80-AMI%EB%A5%BC-%ED%86%B5%ED%95%9C-BackupScaleUp</link>
            <guid>https://velog.io/@hithae_hothae/AWS-EC2-EBS%EC%99%80-AMI%EB%A5%BC-%ED%86%B5%ED%95%9C-BackupScaleUp</guid>
            <pubDate>Thu, 02 Mar 2023 13:40:45 GMT</pubDate>
            <description><![CDATA[<h2 id="1-ebs-elastic-block-store">1. EBS (Elastic Block Store)</h2>
<p>AWS 클라우드 EC2 인스턴스에 사용할 영구 블록 스토리지 볼륨을 제공.
EBS 볼륨은 가용 영역 내에 자동으로 복제, 구성요소 장애로부터 보호해주고, 고가용성 및 내구성을 제공.</p>
<p>스토리지 볼륨 사용에는 두 가지  타입이 존재한다.</p>
<ul>
<li><p>EBS Based 
EC2와 네트워크로 연결되어 있음. 독자적으로 존재. EC2 연결 끊어도 존재.
Snapshot 기능. 인스턴스 업그레이드 가능. Stop 가능.</p>
</li>
<li><p>Instance Storage 
EC2 내부에 존재하여, EC2 제거 시, 같이 사라짐.
빠르지만 저장이 필요 없는 경우. Stop 불가능.</p>
</li>
</ul>
<h2 id="2-ami-amazon-machine-image">2. AMI Amazon Machine Image</h2>
<p>AMI 는 인스턴스를 시작하는 이미지. 
하나의 AMI 로 여러개의 동일한 구성의 인스턴스 시작 가능.</p>
<blockquote>
<ul>
<li>구성 
1개 이상의 EBS 스냅샷 또는 인스턴스 저장 지원 AMI 의 경우, 인스턴스 루트 볼륨에 대한 템플릿 (예: 운영체제, APP 서버)
AMI 를 사용하여 인스턴스를 시작할 수 있는 AWS 계정을 제어하는 시작 권한.
시작될 때 인스턴스에 연결할 볼륨을 지정하는 블록 디바이스 매핑.</li>
</ul>
</blockquote>
<h2 id="3-ami-생성">3. AMI 생성</h2>
<p>AWS 인스턴스 탭에서 생성했던 인스턴스 우클릭 후, 이미지 생성.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/b22e4962-7391-411d-a49d-b1e6deff0fde/image.png" alt=""></p>
<p>** 이미지 생성동안은 인스턴스가 멈춤</p>
<p><img src="https://velog.velcdn.com/images/hithae_hothae/post/97f3023b-b156-4cd7-a030-5a62b3da2df9/image.png" alt="">
<img src="https://velog.velcdn.com/images/hithae_hothae/post/820abded-76dc-4749-96e9-a9c08e89b79c/image.png" alt=""></p>
<p>AMI 탭에 들어가서 이미지 생성 확인.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/e1ab567b-36ed-4181-8269-369dd7791f25/image.png" alt=""></p>
<hr>
<h3 id="reference">Reference</h3>
<p><a href="https://youtu.be/ieG7hup-R8U">https://youtu.be/ieG7hup-R8U</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Tip] AWS 무료 교육 사이트]]></title>
            <link>https://velog.io/@hithae_hothae/Tip-AWS-%EB%AC%B4%EB%A3%8C-%EA%B5%90%EC%9C%A1-%EC%82%AC%EC%9D%B4%ED%8A%B8</link>
            <guid>https://velog.io/@hithae_hothae/Tip-AWS-%EB%AC%B4%EB%A3%8C-%EA%B5%90%EC%9C%A1-%EC%82%AC%EC%9D%B4%ED%8A%B8</guid>
            <pubDate>Tue, 28 Feb 2023 00:12:34 GMT</pubDate>
            <description><![CDATA[<h2 id="aws-공식">AWS 공식</h2>
<h4 id="aws-educate-실시간-클라우드-학습-및-실습">AWS Educate (실시간 클라우드 학습 및 실습)</h4>
<p><a href="https://aws.amazon.com/ko/education/awseducate/">https://aws.amazon.com/ko/education/awseducate/</a></p>
<hr>
<h4 id="aws-builders-online-series">AWS Builders Online Series</h4>
<p><a href="https://aws.amazon.com/ko/events/builders-online-series/">https://aws.amazon.com/ko/events/builders-online-series/</a></p>
<hr>
<h4 id="aws-builders-korea-program-세미나-동영상-및-자료">AWS Builders Korea Program 세미나 동영상 및 자료</h4>
<p><a href="https://kr-resources.awscloud.com/aws-builders-korea-level100">https://kr-resources.awscloud.com/aws-builders-korea-level100</a></p>
<hr>
<h4 id="aws-builders-korea-program-2023-강연">AWS Builders Korea Program 2023 강연</h4>
<p><a href="https://aws.amazon.com/ko/events/seminars/aws-builders/">https://aws.amazon.com/ko/events/seminars/aws-builders/</a>
<img src="https://velog.velcdn.com/images/hithae_hothae/post/6f5d533f-baae-4ab7-ab40-97913e36f7af/image.png" alt=""></p>
<hr>
<h4 id="awsome-day-online-conference-현재-마감">AWSOME DAY online conference (현재 마감)</h4>
<p><a href="https://aws.amazon.com/ko/events/awsome-day/awsome-day-online/">https://aws.amazon.com/ko/events/awsome-day/awsome-day-online/</a></p>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Tip] Velog 글자 색 변경 ]]></title>
            <link>https://velog.io/@hithae_hothae/Tip-Velog-%EA%B8%80%EC%9E%90-%EC%83%89-%EB%B3%80%EA%B2%BD</link>
            <guid>https://velog.io/@hithae_hothae/Tip-Velog-%EA%B8%80%EC%9E%90-%EC%83%89-%EB%B3%80%EA%B2%BD</guid>
            <pubDate>Mon, 27 Feb 2023 08:20:59 GMT</pubDate>
            <description><![CDATA[<h2 id="🎨-velog-에서-글자-색-및-배경-색-바꾸기">🎨 Velog 에서 글자 색 및 배경 색 바꾸기</h2>
<p>Velog 에 글을 쓸 때 Bold 처리, 기울여쓰기, 취소선 밖에 없는 줄 알았다...
아래와 같이, html 형식으로 작성하면 글자 색을 바꿀 수 있다.</p>
<blockquote>
<pre><code>&lt;span style=&quot;color:pink&quot;&gt; text &lt;/span&gt;
&lt;span style=&quot;color:#25d925&quot;&gt; text2 &lt;/span&gt;</code></pre></blockquote>
<pre><code>&lt;span style=&quot;color:pink&quot;&gt; text &lt;/span&gt;
&lt;span style=&quot;color:#25d925&quot;&gt; text2 &lt;/span&gt;


&gt;```
&lt;span style=&quot;background-color:lightblue&quot;&gt; text &lt;/span&gt;
&lt;span style=&quot;background-color:#5692A2&quot;&gt; text2 &lt;/span&gt;</code></pre><p><span style="background-color:lightblue"> text </span>
<span style="background-color:#5692A2"> text2 </span></p>
<p>색상 이름에는 영문 또는 색상코드를 입력 하면 된다.</p>
<p>많이 귀찮아서 잘 안 쓸 것같다....</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[AI 에게 물었다] 함수와 메소드의 차이에 대해 알려줘.]]></title>
            <link>https://velog.io/@hithae_hothae/AI-%EC%97%90%EA%B2%8C-%EB%AC%BC%EC%97%88%EB%8B%A4-%ED%95%A8%EC%88%98%EC%99%80-%EB%A9%94%EC%86%8C%EB%93%9C%EC%9D%98-%EC%B0%A8%EC%9D%B4%EC%97%90-%EB%8C%80%ED%95%B4-%EC%95%8C%EB%A0%A4%EC%A4%98</link>
            <guid>https://velog.io/@hithae_hothae/AI-%EC%97%90%EA%B2%8C-%EB%AC%BC%EC%97%88%EB%8B%A4-%ED%95%A8%EC%88%98%EC%99%80-%EB%A9%94%EC%86%8C%EB%93%9C%EC%9D%98-%EC%B0%A8%EC%9D%B4%EC%97%90-%EB%8C%80%ED%95%B4-%EC%95%8C%EB%A0%A4%EC%A4%98</guid>
            <pubDate>Mon, 27 Feb 2023 06:47:03 GMT</pubDate>
            <description><![CDATA[<p><strong>[AI 에게 물었다]</strong> 이 시리즈는, 본 글을 시작으로 요즘 아주 핫한 이슈인 인공지능 채팅 서비스 ChatGPT를 얼마나 더 효율적으로 사용 할 수 있을지를 목표로 가진다. 
앞으로는  단순한 Code를 짜는 일 보다는, 인공지능을 잘(제대로) 이용 할 줄 알고, 정확한 정보를 가려낼 줄 아는 능력이 중요한 시대가 올 것이다. 
그러므로, ChatGPT를 이용하여 조금 더 디테일하고 정확한 답을 찾기위해 노력하는 사람이 <strong>쓸모</strong> 있는 사람이 될 것이다.</p>
<hr>
<p>ChatGPT AI 를 이용하여 간략한 질문이나 심오한 문제 해결 등을 시켜보며 기록해보려한다. 
처음으로, 프로그래밍에서의 함수와 메소드의 차이에 대해 물었다.</p>
<hr>
<h4 id="q-프로그래밍에서-함수와-메소드의-차이에-대해-알려줘-상세하면서-이해하기-쉽도록-java-코드를-예를-들어-알려줘">Q. 프로그래밍에서 함수와 메소드의 차이에 대해 알려줘. 상세하면서 이해하기 쉽도록 java 코드를 예를 들어 알려줘.</h4>
<p>A.
함수와 메소드 모두 프로그래밍에서 재사용 가능한 코드 블록입니다. 하지만 함수와 메소드는 조금 다른 의미를 가지고 있습니다.</p>
<p>함수는 일반적으로 언어의 전역 범위에서 정의되며, 입력 매개변수를 사용하여 작업을 수행하고 값을 반환합니다. 함수는 특정 클래스나 객체와 관련이 없습니다.</p>
<p>반면, 메소드는 특정 클래스나 객체의 멤버로 정의됩니다. 메소드는 객체의 상태를 변경하거나 객체의 동작을 수행하며 클래스의 인스턴스 메소드라고도 합니다.</p>
<p>이제 Java 코드를 통해 함수와 메소드를 비교해 보겠습니다.</p>
<pre><code class="language-java">public class Example {

    // 함수
    public static int add(int a, int b) {
        return a + b;
    }

    // 메소드
    public void printMessage(String message) {
        System.out.println(message);
    }

    public static void main(String[] args) {

        // 함수 호출
        int result = add(5, 10);
        System.out.println(result);

        // 메소드 호출
        Example ex = new Example();
        ex.printMessage(&quot;Hello, world!&quot;);
    }
}</code></pre>
<p>위의 예제에서, add()는 함수입니다. add()는 Example 클래스 내부에서 정의되어 있지 않으며, 다른 클래스에서도 호출할 수 있습니다. printMessage()는 메소드입니다. printMessage()는 Example 클래스의 인스턴스 메소드로, 클래스의 인스턴스를 생성해야 호출할 수 있습니다.</p>
<p>main() 메소드에서 add() 함수를 호출하고 printMessage() 메소드를 호출하기 위해 Example 클래스의 인스턴스를 생성했습니다.</p>
<p>이러한 차이점을 이해하면 함수와 메소드를 사용할 때 어떤 것을 선택해야 하는지에 대한 기준을 좀 더 명확하게 설정할 수 있습니다.</p>
<h4 id="q-그렇다면-클래스에-포함되어-있는지-아닌지가-함수와-메소드를-나누는-기준이라고-생각하면-되는거야">Q. 그렇다면, 클래스에 포함되어 있는지 아닌지가 함수와 메소드를 나누는 기준이라고 생각하면 되는거야?</h4>
<p>A. 
네, 함수와 메소드를 나누는 가장 큰 차이점은 함수는 일반적으로 언어의 전역 범위에서 정의되며 클래스나 객체와 관련이 없는 반면, 메소드는 특정 클래스나 객체의 멤버로 정의된다는 것입니다.</p>
<p>따라서 함수는 언어 전체에서 사용할 수 있는 범용적인 기능을 제공하며, 메소드는 클래스나 객체의 특정 동작을 구현하는 데 사용됩니다.</p>
<p>따라서 클래스나 객체에 관련된 작업을 수행해야 할 때는 메소드를 사용하고, 객체와 관련이 없는 범용적인 작업을 수행해야 할 때는 함수를 사용하는 것이 좋습니다.</p>
<h4 id="q-java-말고-다른-언어에서도-동일해">Q. java 말고 다른 언어에서도 동일해?</h4>
<p>A.
대부분의 객체 지향 언어에서 함수와 메소드의 개념은 비슷합니다. 하지만 언어마다 약간의 차이점이 있을 수 있습니다.</p>
<p>예를 들어, Python에서는 함수와 메소드를 구별하지 않습니다. 클래스 내에 정의된 함수도 메소드로 취급합니다. 그러나 일반적으로 메소드는 클래스와 객체와 연관된 동작을 수행하는 것으로 이해하고 있습니다.</p>
<p>C++에서는 함수와 메소드를 구분합니다. C++에서는 클래스 내에 정의된 함수를 멤버 함수라고하며, Java의 메소드와 비슷한 개념입니다.</p>
<p>따라서 각 언어의 문법과 철학에 따라 함수와 메소드가 구분되는 방법이 약간 다르지만, 대부분의 언어에서 클래스나 객체와 관련된 작업을 수행할 때는 메소드를 사용하고, 그 외의 범용적인 작업을 수행할 때는 함수를 사용하는 것이 일반적입니다.</p>
<h4 id="q-java-의-람다는-함수야-메소드야">Q. java 의 람다는 함수야 메소드야?</h4>
<p>A.
Java의 람다 표현식은 함수형 인터페이스를 구현하기 위한 익명 함수입니다. 따라서 람다 표현식은 함수에 가깝습니다.</p>
<p>하지만 Java의 람다 표현식은 내부적으로는 메소드로 구현됩니다. 람다 표현식은 실제로는 메소드의 구현을 간단하게 작성한 것입니다. 이 구현은 함수형 인터페이스의 단일 추상 메소드를 구현하고 이를 호출할 수 있는 객체를 생성하는 데 사용됩니다.</p>
<p>Java 8 이전에는 함수형 프로그래밍 패턴을 구현하려면 인터페이스와 익명 클래스를 사용해야 했습니다. 하지만 Java 8부터는 람다 표현식을 사용하여 함수형 인터페이스를 구현할 수 있게 되었습니다.</p>
<p>따라서 Java의 람다 표현식은 실제로는 메소드의 구현을 담고 있지만, 함수형 프로그래밍에서는 일반적으로 함수로 취급되며 함수형 인터페이스를 구현하는 데 사용됩니다.</p>
<hr>
<p>위 처럼, ChatGPT는 단순히 물어본 것에 대해서만 검색해서 알려주는 것이 아니라 , 앞의 내용들을 기억하여 문맥을 이해한다. 또한 이야기에서의 문장을 이해하고 추가적으로 알면 좋은 내용들도 같이 알려주기도 한다. </p>
<p>정말 이제 Googling 보다는 ChatGPTing 의 시대가 오는듯하다. 💻</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[AWS EC2] EC2(Elastic Compute Cloud) 를 이용한 웹서버 만들기 ]]></title>
            <link>https://velog.io/@hithae_hothae/AWS-EC2-1.-EC2Elastic-Compute-Cloud-%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EC%9B%B9%EC%84%9C%EB%B2%84-%EB%A7%8C%EB%93%A4%EA%B8%B0</link>
            <guid>https://velog.io/@hithae_hothae/AWS-EC2-1.-EC2Elastic-Compute-Cloud-%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EC%9B%B9%EC%84%9C%EB%B2%84-%EB%A7%8C%EB%93%A4%EA%B8%B0</guid>
            <pubDate>Sun, 26 Feb 2023 12:47:45 GMT</pubDate>
            <description><![CDATA[<h3 id="1-ec2-란-무엇인가">1. EC2 란 무엇인가.</h3>
<p>클라우드 상에서 컴퓨팅 작업을 할 수 있도록 서버를 지원하며, 신속하게 크기 조정이 가능하며 사용한 만큼만 요금을 지불하여 장애에 대한 복원력이 뛰어나다.</p>
<blockquote>
</blockquote>
<ul>
<li>On-Demand 
약정이 필요없으며, 시간 또는 초당 컴퓨팅 파워로 측정된 가격을 지불.<blockquote>
</blockquote>
</li>
<li>Spot Instance
경매 형식으로 정한 금액 넘어가는 경우 반납. 저렴한 방식으로 사용가능.<blockquote>
</blockquote>
</li>
<li>예약 인스턴스 Reserved Instance (RI)
약정해서 사용. 저렴. 수요 예측이 확실할 때.<blockquote>
</blockquote>
</li>
<li>전용 호스트 (Dedicated)
실제 물리서버를 임대하는 방식</li>
</ul>
<hr>
<h3 id="2-ec2-타입-종류">2. EC2 타입 종류</h3>
<p><img src="https://velog.velcdn.com/images/hithae_hothae/post/2afd3d70-78eb-4f32-83bd-deba106d4115/image.png" alt=""></p>
<hr>
<h3 id="3-ec2-만들기">3. EC2 만들기</h3>
<p>EC2 프리티어 버전 생성하기
EC2의 인스턴스  탭에서 인스턴스 시작 선택.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/bb916a3f-b7b6-4e08-9c04-2f0de912d7e9/image.png" alt=""></p>
<p>프리티어(무료) 인스턴스 선택 후, <strong>새 키 페어 생성</strong>
<img src="https://velog.velcdn.com/images/hithae_hothae/post/bfc6f7b2-d9cc-4231-96f8-2fdbacb33837/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/hithae_hothae/post/d1900f80-b2e9-4f9a-95af-a9c79c430d03/image.png" alt="">
키 페어 이름 정하구 RSA 방식에 pem 파일로 생성.
<strong>해당 인스턴스에 매핑되는 키 페어이므로, 유실시 다른 키페어로 접속 불가하니 잘 보관 할 수 있도록한다.</strong></p>
<p><img src="https://velog.velcdn.com/images/hithae_hothae/post/754f2961-41a9-49d2-bffe-92a2a9fcc3ba/image.png" alt=""></p>
<p>인스턴스 생성 확인</p>
<hr>
<h3 id="4-ec2-에-접속">4. EC2 에 접속</h3>
<h4 id="41-securecrt-을-통해-ppk-private-key-파일-만들고-접속">4.1 SecureCRT 을 통해 PPK (Private Key) 파일 만들고 접속</h4>
<p>SecureCRT 다운로드 설치.</p>
<p><img src="https://velog.velcdn.com/images/hithae_hothae/post/c4257ab8-958f-4d55-9428-ec7d3c14bca3/image.png" alt="">
Convert Private Key to OpenSSH Format 클릭 후, 아까 다운로드 받은 PEM 파일 선택.
ppk 파일로 저장. (같은 이름으로 하면 관리가 용이하다.)</p>
<p>새 세션 생성.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/0a643a05-d502-408d-a6de-82499bb21c5c/image.png" alt=""></p>
<p>public IP 복사 입력
<img src="https://velog.velcdn.com/images/hithae_hothae/post/4d3b32b3-b68f-4c14-bc7d-99db364c9087/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/hithae_hothae/post/778ff594-3191-4c09-9da8-ff52038d7a04/image.png" alt=""></p>
<p>프리티어로 선택한 Amazon Linux의 경우, 기본 사용자 이름은 ec2-user 로 정의 되어있다.
(<a href="https://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/managing-users.html#ami-default-user-names">https://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/managing-users.html#ami-default-user-names</a>)</p>
<p><img src="https://velog.velcdn.com/images/hithae_hothae/post/c6636f78-4783-4e30-8d41-2b8288e245d4/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/hithae_hothae/post/cad7750b-f769-486b-b6c5-de4e4b1afdf8/image.png" alt=""></p>
<p>기본로그인은 정의된 사용자 name 으로만 가능하며, 암호 인증 및 루트 로그인은 비활성화되어 있고 sudo는 활성화되어 있습니다.</p>
<h4 id="42-filezilla를-통해-ftp-접속">4.2 FileZilla를 통해 FTP 접속</h4>
<hr>
<h3 id="5-웹서버-설치-및-구동">5. 웹서버 설치 및 구동</h3>
<h4 id="51-yum-을-통해-아파치-웹서버-설치">5.1 Yum 을 통해 아파치 웹서버 설치</h4>
<p><img src="https://velog.velcdn.com/images/hithae_hothae/post/0b97b3b1-8441-42fe-bf9a-9d7afe239cbd/image.png" alt="">
<img src="https://velog.velcdn.com/images/hithae_hothae/post/18572749-e59b-46df-8083-160162ff34eb/image.png" alt=""></p>
<h4 id="52-httpd-서비스-등록">5.2 Httpd 서비스 등록</h4>
<p><img src="https://velog.velcdn.com/images/hithae_hothae/post/6256e809-8623-459e-bdaf-61e80fbccc2e/image.png" alt=""></p>
<blockquote>
<p><strong>service httpd start *<em>: httpd 서비스 데몬 start 
*</em>chkconfig httpd on</strong> : 인스턴스가 죽었다 살아나도 자동으로 httpd 올려주도록 등록.</p>
</blockquote>
<p>Index.html 생성
<img src="https://velog.velcdn.com/images/hithae_hothae/post/eb8e9546-50ec-4aaa-9731-3dc7a4b02756/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/hithae_hothae/post/ff84a4b5-76a0-4dd1-b601-dcac136252b7/image.png" alt=""></p>
<h3 id="6-인스턴스-보안-설정">6. 인스턴스 보안 설정</h3>
<p>기본적으로 port 22(ssh) 만 오픈 되어있으므로, Web 서버 기동후  페이지 접속을 위해 HTTP(80)번 포트를 열어 주어야한다. 
방화벽 세팅과 유사한 인스턴스 보안 그룹 설정을 변경해준다.</p>
<p><img src="https://velog.velcdn.com/images/hithae_hothae/post/269329bf-f4cd-4707-a4a8-2b11d4a5e5a7/image.png" alt="">
인스턴스 선택후, 보안탭에서 인바운드 보안 그룹을 클릭하여 해당 보안그룹으로 들어간다.</p>
<p><img src="https://velog.velcdn.com/images/hithae_hothae/post/25f8e573-9c87-4ecd-a5b1-ecb024d5ee9d/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/hithae_hothae/post/fc9667ca-6ce2-4233-baaf-d34874b77cc8/image.png" alt="">
http 접속을 위해 인바운드 규칙 편집을 눌러, 규칙을 추가한다.
[ HTTP , Anywhere ]</p>
<p><img src="https://velog.velcdn.com/images/hithae_hothae/post/139c20e1-ef86-4989-b041-e05ffd2764f4/image.png" alt=""></p>
<p>Public IP로 접속시, 아까 작성한 index.html 내용이 정상 노출되므로 웹서버가 잘 동작하는것을 확인 할 수 있었다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[AWS - S3] AWS S3 (Simple Storage Service) 이해하기]]></title>
            <link>https://velog.io/@hithae_hothae/AWS-S3-1.-AWS-S3-Simple-Storage-Service-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@hithae_hothae/AWS-S3-1.-AWS-S3-Simple-Storage-Service-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0</guid>
            <pubDate>Thu, 23 Feb 2023 03:44:19 GMT</pubDate>
            <description><![CDATA[<p>AWS S3 (Simple Storage Service) 에 대해 이해해보자.</p>
<p>S3는 간단히 말해, 분산 HardDisk 대여라고 할 수 있다.</p>
<p>중요한 프로젝트, 디렉토리, 파일, 내용을 안전하게 보관 하기 위한 목적으로 사용된다.</p>
<h3 id="1-구성">1. 구성</h3>
<blockquote>
<p>Bucket : 저장소
Object : 파일</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/hithae_hothae/post/71767eb1-2e12-492f-8d89-540bfa6055dd/image.png" alt=""></p>
<h2 id="버킷-이름은-고유해야-하며-리전은-물리적인-저장-장소를-정하므로-사용자와-가까운-곳일수록-좋다"><strong>버킷 이름</strong>은 <strong>고유</strong>해야 하며, 리전은 물리적인 저장 장소를 정하므로 사용자와 가까운 곳일수록 좋다.</h2>
<p><img src="https://velog.velcdn.com/images/hithae_hothae/post/3948901d-e3df-4088-b652-4349fceb21c2/image.png" alt=""></p>
<p>버킷의 버전 관리를 원한다면 &#39;버전관리&#39; 체크.
AWS 에 올릴 떄 기본적으로 object를 암호화.</p>
<hr>
<h3 id="2-버킷-읽기-수정-삭제">2. 버킷 읽기 수정 삭제</h3>
<p><img src="https://velog.velcdn.com/images/hithae_hothae/post/ece884f2-dc5c-437d-845b-aab078bb22ac/image.png" alt=""></p>
<h3 id="3-폴더-만들기">3. 폴더 만들기</h3>
<p>말그대로 폴더. 생성 및 관리 정말 쉽다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/91452b10-a2b3-480e-9d19-642f608eea49/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/hithae_hothae/post/5f34e865-af4a-4e68-bfa7-2b048e042475/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/hithae_hothae/post/9a08a75c-9b2e-4ada-9b21-774e88586cd7/image.png" alt=""></p>
<p>속성, 권한, 지표 등 탭을 눌러보면 여러 기능이 있다. 읽어보면 알 수 있는 정도이다.</p>
<h3 id="4-객체-생성">4. 객체 생성</h3>
<p>파일 또는 폴더를 추가하여 업로드 하는 것.</p>
<p><img src="https://velog.velcdn.com/images/hithae_hothae/post/a8befda5-214a-4093-937b-54231652ea46/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/hithae_hothae/post/76bb0072-0da2-4b1f-a63c-48de71d85060/image.png" alt=""></p>
<h3 id="5-권한-부여">5. 권한 부여</h3>
<p>기본적으로 Non Public 이므로, 업로드한 파일의 링크를 공유하여도 타인이 임의로 열어 볼 수 없다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/hithae_hothae/post/ff69311d-579a-426a-b2fc-ef8cad6510a2/image.png" alt=""></p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/hithae_hothae/post/f3aa45f2-f207-4b3a-8228-4ff4d34fd385/image.png" alt=""></p>
<p>public 으로 권한 변경하여 파일 확인이 가능하다. <strong>(주의 !)</strong>
우선, 버킷의 퍼블릭 액세스 차단 편집의 &#39;모든 퍼블릭 액세스 차단&#39; 체크 해제를 해준다.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/51550447-f632-421e-9d17-57510261e65f/image.png" alt=""></p>
<p>객체의 소유권 세팅 (ACL 활성화됨 으로 선택하여 객체에 대한 액세스는 ACL  을 사용하여 지정 가능)</p>
<p><img src="https://velog.velcdn.com/images/hithae_hothae/post/2c06d0a4-ecb6-4fc2-a924-8293bab4e5f0/image.png" alt=""></p>
<p>객체를 선택 후, 권한 탭에서 편집을 하여 권한 부여 가능.
<img src="https://velog.velcdn.com/images/hithae_hothae/post/34ff7688-4e4e-49a4-85b9-d5b06f580f86/image.png" alt="">
<img src="https://velog.velcdn.com/images/hithae_hothae/post/82aae848-c3a7-417c-9784-93197f8de2c4/image.png" alt=""></p>
<p>이후 객체 url 을 통해 외부에서 접근 가능.</p>
<hr>
<p>AWS S3 에 대해 간단하게 알아보았다. S3 는 기본적으로 정적 웹서버를 탑재하고 있으므로, 파일서버로 사용하기에도 유용한 것 같다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[K8s] 3. 쿠버네티스 namespace, yaml 템플릿과 API]]></title>
            <link>https://velog.io/@hithae_hothae/K8s-3.-%EC%BF%A0%EB%B2%84%EB%84%A4%ED%8B%B0%EC%8A%A4-namespace-yaml-%ED%85%9C%ED%94%8C%EB%A6%BF%EA%B3%BC-API</link>
            <guid>https://velog.io/@hithae_hothae/K8s-3.-%EC%BF%A0%EB%B2%84%EB%84%A4%ED%8B%B0%EC%8A%A4-namespace-yaml-%ED%85%9C%ED%94%8C%EB%A6%BF%EA%B3%BC-API</guid>
            <pubDate>Thu, 03 Mar 2022 06:11:57 GMT</pubDate>
            <description><![CDATA[<h2 id="31-namespace">3.1 Namespace</h2>
<h3 id="311-namespace-란-">3.1.1 <strong>Namespace</strong> 란 ?</h3>
<blockquote>
<p>물리적인 클러스터내에서 논리적으로 클러스터를 나누어서 사용 할 수 있도록 구분.
기본적으로 default Namespace 존재. 
kube-로 시작하는 Namespace는 쿠버네티스 운영환경에 필요한 기본적인 Namespace.</p>
</blockquote>
<h3 id="312-namespace-생성">3.1.2 Namespace 생성</h3>
<ul>
<li><p>CLI 을 이용한 Namespace 생성 
<code>kubectl create namespace [namespace명] --dry-run -o yaml &gt; [yaml파일명 ]</code>
<code>--dry-run</code> : 실제로 생성하지 않고 생성가능한지 확인용
<code>-o yaml</code> : 실행 결과를 yaml 파일로 출력 </p>
<blockquote>
<ul>
<li>yaml 내용물
apiVersion: v1
kind: Namespace
metadata:
name: [namespcae명]</li>
</ul>
</blockquote>
</li>
<li><p>yaml 파일을 통한 namespcae 생성 명령어
<code>kubectl create -f [yaml파일]</code>
<code>kubectl create -f [yaml파일명] -n [실행될 네임스페이스]</code>      &lt;- 생략시 default namespace</p>
</li>
</ul>
<h3 id="313-namespace-switching">3.1.3 Namespace Switching</h3>
<p>쿠버네티스의 config 에 Switching 할 context를 생성해야한다. 
<code>kubectl config view</code> : 쿠버네티스 설정 정보 확인 (context 확인 가능)</p>
<p>context 를 이용한 default namespace 지정하여 파드 생성 등을 네임스페이스 지정없이 작업 가능.</p>
<ul>
<li>현재 context 조회 : <code>kubectl config current-context</code></li>
<li>컨텍스트 정보 확인 : <code>kubectl config get-contexts [컨택스트명]</code></li>
<li>새로운 context 생성 : <code>kubectl config set-context [컨텍스트명] --cluster=[클러스터명] --user=[유저명] --namespace=[네임스페이스]</code></li>
<li>사용 context 변경 : <code>kubectl config use-context [컨텍스트명]</code>     --&gt; [컨텍스트명]의 namespace를 default namespace로 가지게 되며, 이후 -n [네임스페이스] 옵션 없이 사용가능.</li>
</ul>
<br>

<ul>
<li><p>네임스페이스 내 pod 삭제
kubectl delete pods [pod] -n [namespace]   --&gt; 네임스페이스 생략시 , 현재 컨텍스트의 네임스페이스로...</p>
</li>
<li><p>네임스페이스 삭제 (안에 모든 pods 삭제)
kubectl delete namespaces [namespace]</p>
</li>
<li><p>네임스페이스 확인
kubectl get namespaces</p>
</li>
</ul>
<h2 id="32-yaml">3.2 yaml</h2>
<h2 id="33-api">3.3 API</h2>
<p>API version 
alpha -&gt; beta -&gt; stable 단계를 거쳐서 업데이트 되고있다.
<code>kubectl explain pod</code> :  resouce documentaion. API version 및 description 확인 가능.</p>
<ul>
<li>API Object 의 종류 및 버전</li>
</ul>
<table>
<thead>
<tr>
<th align="left">Object명</th>
<th align="left">버전</th>
</tr>
</thead>
<tbody><tr>
<td align="left">Deployment</td>
<td align="left">apps/v1</td>
</tr>
<tr>
<td align="left">Pod</td>
<td align="left">v1</td>
</tr>
<tr>
<td align="left">ReplicaSet</td>
<td align="left">apps/v1</td>
</tr>
<tr>
<td align="left">ReplicationController</td>
<td align="left">v1</td>
</tr>
<tr>
<td align="left">Service</td>
<td align="left">v1</td>
</tr>
<tr>
<td align="left">PersistentVolume</td>
<td align="left">v1</td>
</tr>
</tbody></table>
]]></description>
        </item>
        <item>
            <title><![CDATA[[K8s] 2. 쿠버네티스 설치 및 구성]]></title>
            <link>https://velog.io/@hithae_hothae/K8s-2.-%EC%BF%A0%EB%B2%84%EB%84%A4%ED%8B%B0%EC%8A%A4-%EC%84%A4%EC%B9%98-%EB%B0%8F-%EA%B5%AC%EC%84%B1</link>
            <guid>https://velog.io/@hithae_hothae/K8s-2.-%EC%BF%A0%EB%B2%84%EB%84%A4%ED%8B%B0%EC%8A%A4-%EC%84%A4%EC%B9%98-%EB%B0%8F-%EA%B5%AC%EC%84%B1</guid>
            <pubDate>Thu, 03 Mar 2022 06:11:46 GMT</pubDate>
            <description><![CDATA[<h2 id="21-설치없이-쿠버네티스-사용">2.1 설치없이 쿠버네티스 사용</h2>
<p><del>- 카타코다에서 지원하는 playground (Master/node1 로 구성되어있어 바로 사용가능) 
<a href="https://www.katacoda.com/courses/kubernetes/playground">https://www.katacoda.com/courses/kubernetes/playground</a></del><br><strong>2023년 현재는 서비스 종료됨</strong></p>
<ul>
<li>docker 에서 지원하는 playground (4시간 이용, Master, worker Node 직접 구성 후 사용가능)
<a href="https://labs.play-with-k8s.com/">https://labs.play-with-k8s.com/</a></li>
</ul>
<h2 id="22-설치">2.2 설치</h2>
<ul>
<li><p>CNI (Container Network Interface)
Container 간 통신을 지원하는 VxLAN. POD Network이라고도 부름
필수적으로 하나는 설치 되어있어야 Container 간 통신 가능
다양한 종류의 플러그인 존재 [ 플라넬(flannel), 칼리코(calico), 위브넷(weavenet) ]</p>
</li>
<li><p>Control plane(Master node)
woker node 상태 관리 및 제어
single master
multi master</p>
</li>
<li><p>Worker node
도커 플랫폼을 통해 컨테이너 동작하며 실제 서비스 제공</p>
</li>
</ul>
<h4 id="221-환경-구성">2.2.1 환경 구성</h4>
<ul>
<li>windows에 VMware 가상 머신을 설치 후, master 1개와 node 2개를 설치 Ubuntu 20.04 LTS 버전으로 설치.</li>
</ul>
<p><img src="https://images.velog.io/images/hithae_hothae/post/6829d234-e7d9-4005-9029-793dfc632073/image.png" alt=""></p>
<hr>
<h4 id="222-docker-설치">2.2.2 docker 설치</h4>
<blockquote>
</blockquote>
<ul>
<li>Docker Install to all system
<a href="https://docs.docker.com/engine/install/ubuntu/">https://docs.docker.com/engine/install/ubuntu/</a></li>
</ul>
<blockquote>
</blockquote>
<ul>
<li>Set up the repository <pre><code class="language-linux">$ sudo apt-get update
$ sudo apt-get install -y \
  ca-certificates \
  curl \
  gnupg \
  lsb-release</code></pre>
</li>
</ul>
<blockquote>
</blockquote>
<ul>
<li><p>Add Docker’s official GPG ke
curl -fsSL <a href="https://download.docker.com/linux/ubuntu/gpg">https://download.docker.com/linux/ubuntu/gpg</a> | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg</p>
<blockquote>
</blockquote>
</li>
<li><p>Repository 등록
echo <br>&quot;deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] <a href="https://download.docker.com/linux/ubuntu">https://download.docker.com/linux/ubuntu</a> <br>$(lsb_release -cs) stable&quot; | sudo tee /etc/apt/sources.list.d/docker.list &gt; /dev/null</p>
</li>
</ul>
<blockquote>
</blockquote>
<ul>
<li>Install Docker Engine<pre><code class="language-java">-- Repository Cache update
$ sudo apt-get update 
-- docker ce, docker cli, continerd io 설치
$ sudo apt-get install -y docker-ce docker-ce-cli containerd.io</code></pre>
</li>
</ul>
<blockquote>
</blockquote>
<ul>
<li>Docker 설치 확인
sudo systemctl enable docker
sudo systemctl start docker
sudo docker version
<img src="https://images.velog.io/images/hithae_hothae/post/e5a61ee9-32ab-45fa-b271-775d262c8186/image.png" alt=""></li>
</ul>
<hr>
<h3 id="223-kubernetes-설치">2.2.3 kubernetes 설치</h3>
<blockquote>
</blockquote>
<p><a href="https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/">https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/</a>
<img src="https://images.velog.io/images/hithae_hothae/post/498fa80a-d001-4fb2-86a5-8cac1e5acbfb/image.png" alt=""></p>
<blockquote>
</blockquote>
<ul>
<li>설치전 환경설정 
kubeadmin 으로 설치 시 , 모든 노드들은 swap off 되어 있어야 한다.
swapoff -a &amp;&amp; sed -i &#39;swap/s/^/#/&#39; /etc/fstab</li>
</ul>
<blockquote>
</blockquote>
<ul>
<li>Letting iptables see bridged traffic (bridge 네트워크를 바라 볼 수 있도록 세팅)
cat &lt;&lt;EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sudo sysctl --system</li>
</ul>
<blockquote>
</blockquote>
<ul>
<li>port 설정 (방화벽은 disabled 하고 실습. 실제로 앞단에서 방화벽을 다루므로)</li>
<li><ul>
<li>방화벽 사용 시, 활성 포트 목록
<a href="https://kubernetes.io/docs/reference/ports-and-protocols/">https://kubernetes.io/docs/reference/ports-and-protocols/</a></li>
<li><ul>
<li>방화벽 disabled 명령어
systemctl stop firewalld
systemctl disable firewalld</li>
</ul>
</li>
</ul>
</li>
</ul>
<blockquote>
</blockquote>
<p><strong>kubeadm, kubelet, kubectl 설치</strong>
<code>kubeadm</code> : the command to bootstrap the cluster.
<code>kubelet</code> : the component that runs on all of the machines in your cluster and does things like starting pods and containers.
<code>kubectl</code> : the command line util to talk to your cluster.</p>
<blockquote>
</blockquote>
<p>sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl</p>
<blockquote>
</blockquote>
<p>sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg <a href="https://packages.cloud.google.com/apt/doc/apt-key.gpg">https://packages.cloud.google.com/apt/doc/apt-key.gpg</a></p>
<blockquote>
</blockquote>
<p>echo &quot;deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] <a href="https://apt.kubernetes.io/">https://apt.kubernetes.io/</a> kubernetes-xenial main&quot; | sudo tee /etc/apt/sources.list.d/kubernetes.list</p>
<blockquote>
</blockquote>
<p>sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl</p>
<blockquote>
</blockquote>
<ul>
<li>kubectl 명령어 자동완성
BASH
source &lt;(kubectl completion bash)
source &lt;(kubeadm completion bash)
echo &quot;source &lt;(kubectl completion bash)&quot; &gt;&gt; ~/.bashrc
echo &quot;source &lt;(kubeadm completion bash)&quot; &gt;&gt; ~/.bashrc</li>
</ul>
<p>systemctl start kubelet
systemctl enable kubelet</p>
<h2 id="23-구성">2.3 구성</h2>
<p><code>kubeadm init</code>   : master 에서만 실행. API, controller, schduler, etcd, CoreDNS 구성</p>
<h3 id="231-control-plane">2.3.1 Control plane</h3>
<h3 id="namespace">namespace</h3>
]]></description>
        </item>
        <item>
            <title><![CDATA[[K8s] 1. 쿠버네티스 Kubernetes 소개]]></title>
            <link>https://velog.io/@hithae_hothae/K8s-1.-%EC%BF%A0%EB%B2%84%EB%84%A4%ED%8B%B0%EC%8A%A4-Kubernetes-%EC%86%8C%EA%B0%9C</link>
            <guid>https://velog.io/@hithae_hothae/K8s-1.-%EC%BF%A0%EB%B2%84%EB%84%A4%ED%8B%B0%EC%8A%A4-Kubernetes-%EC%86%8C%EA%B0%9C</guid>
            <pubDate>Thu, 03 Mar 2022 06:11:28 GMT</pubDate>
            <description><![CDATA[<p>😃 이성미 강사님의, 따배쿠 쿠버네티스 강의를 수강하며 정리를 하려합니다. 
(<a href="https://www.youtube.com/watch?v=Sj9Z6-w1VUE&amp;list=PLApuRlvrZKohaBHvXAOhUD-RxD0uQ3z0c&amp;index=2">https://www.youtube.com/watch?v=Sj9Z6-w1VUE&amp;list=PLApuRlvrZKohaBHvXAOhUD-RxD0uQ3z0c&amp;index=2</a>)</p>
<p>k8s 공식 페이지를 참고하며 공부해보자. 
(<a href="https://kubernetes.io/ko/">https://kubernetes.io/ko/</a>)</p>
<h3 id="컨테이너">컨테이너</h3>
<p>서비스 마다, OS 를 각각 갖는 가상머신과는 다르게
OS 위에 Docker 플랫폼을 설치후 그 위에 각각의 Containerized App 들만 빠르고 간편하게 확장 축소 할 수 있도록하여 빠른 배포를 지원한다.</p>
<h3 id="멀티호스트-도커플랫폼">멀티호스트 도커플랫폼</h3>
<p>하나의 도커 플랫폼으로 운영중, 문제가 생기면 전체 서비스에 영향을 미치기에 다중 플랫폼을 구성하여 서비스한다. 이것을 멀티포스트 도커 플랫폼이라 하며, 무수히 많은 플랫폼을 관리자가 일일이 관리하기 불가능하기에, 이를 통합 관리 하기 위한 것이 필요했다.</p>
<h3 id="컨테이너-오케스트레이션">컨테이너 오케스트레이션</h3>
<p>컨테이너를 목적에 맞게 알맞게 배치하여 최적의 환경을 구축 및 복구 등 총괄을 하는 구조.
Docker <strong>control  plane</strong> 에 요구 하기만 하면, 적절한 도커 플랫폼(<strong>worker node</strong>)에 서비스를 구동 시켜 준다. </p>
<p><img src="https://velog.velcdn.com/images/hithae_hothae/post/7cb96546-c500-44e4-be3d-7faae367e21d/image.png" alt=""></p>
<hr>
<h3 id="쿠버네티스">쿠버네티스</h3>
<p>컨테이너 오케스트레이션 중 가장 많이 사용되며, 구글이 15년간 프로덕션 워크로드 운영 경험을 토대로 구축하였다. 일주일에 수십억개의 컨테이너들을 운영하게 하기 위한 만큼 탁월한 확장성을 지녔다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Spring] @GetMapping 과 @PostMapping]]></title>
            <link>https://velog.io/@hithae_hothae/Spring-GetMapping-%EA%B3%BC-PostMapping</link>
            <guid>https://velog.io/@hithae_hothae/Spring-GetMapping-%EA%B3%BC-PostMapping</guid>
            <pubDate>Tue, 02 Nov 2021 16:52:54 GMT</pubDate>
            <description><![CDATA[<h1 id="getmapping-postmapping">@GetMapping @PostMapping</h1>
<p>Spring 4.3 이후에 추가된 Get/Post 요청 전용 매핑 어노테이션.</p>
<p>원래 Spring은 @RequestMapping 어노테이션으로만 HTTP Request 모든 Url 을 매핑할 수 있었다. 아래와 같이 처리 할 수 있었다.</p>
<blockquote>
<pre><code class="language-java">@RequestMapping(value = &quot;/test&quot;, method = RequestMethod.GET)
public Test getTest() {
}
</code></pre>
</blockquote>
<p>@RequestMapping(value = &quot;/test&quot;, method = RequestMethod.POST)
public Test getTest(Test test) {
}
@RequestMapping(value = &quot;/test/{id}&quot;, method = RequestMethod.GET)
public Test getTest(@PathVariable(&quot;id&quot;) String id) {
}</p>
<pre><code>
4.3버전 이후로 추가된 HTTP Request 어노테이션을 사용함으로써 attribute 를 더이상 사용 할 필요 없어졌다.

&gt;```java 
@GetMapping(value = &quot;/test&quot;)
public Test getTest() {
}
@PostMapping(value = &quot;/test&quot;)
public Test setTest(Test test) {
}
@GetMapping(value = &quot;/test/{id}&quot;)
public Test getTest(@PathVariable(&quot;id&quot;) String id) {
}</code></pre><p>내부적으로 보면 @PostMapping 어노테이션은 @RequestMapping(method = RequestMethod.POST)  어노테이션의 shortcut 이다. 정확히 일치하게 동작하며, 사용 편의성을 위해 만들어졌다고 보면된다.</p>
<blockquote>
<pre><code class="language-java">@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@RequestMapping(method = RequestMethod.POST)
public @interface PostMapping {
    //code
}</code></pre>
</blockquote>
<h1 id="참고">참고</h1>
<p><a href="https://howtodoinjava.com/spring5/webmvc/controller-getmapping-postmapping/">https://howtodoinjava.com/spring5/webmvc/controller-getmapping-postmapping/</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Python] Programmers 코딩테스트 연습 - '최소 직사각형']]></title>
            <link>https://velog.io/@hithae_hothae/Python-Programmers-%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%97%B0%EC%8A%B5-%EC%B5%9C%EC%86%8C-%EC%A7%81%EC%82%AC%EA%B0%81%ED%98%95</link>
            <guid>https://velog.io/@hithae_hothae/Python-Programmers-%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%97%B0%EC%8A%B5-%EC%B5%9C%EC%86%8C-%EC%A7%81%EC%82%AC%EA%B0%81%ED%98%95</guid>
            <pubDate>Fri, 01 Oct 2021 07:37:09 GMT</pubDate>
            <description><![CDATA[<h1 id="🎈-문제-설명">🎈 문제 설명</h1>
<p>명함 지갑을 만드는 회사에서 지갑의 크기를 정하려고 합니다. 다양한 모양과 크기의 명함들을 모두 수납할 수 있으면서, 작아서 들고 다니기 편한 지갑을 만들어야 합니다. 이러한 요건을 만족하는 지갑을 만들기 위해 디자인팀은 모든 명함의 가로 길이와 세로 길이를 조사했습니다.</p>
<p>아래 표는 4가지 명함의 가로 길이와 세로 길이를 나타냅니다.</p>
<table>
<thead>
<tr>
<th>명함 번호</th>
<th>가로 길이</th>
<th>세로 길이</th>
</tr>
</thead>
<tbody><tr>
<td>1</td>
<td>60</td>
<td>50</td>
</tr>
<tr>
<td>2</td>
<td>30</td>
<td>70</td>
</tr>
<tr>
<td>3</td>
<td>60</td>
<td>30</td>
</tr>
<tr>
<td>4</td>
<td>80</td>
<td>40</td>
</tr>
<tr>
<td>가장 긴 가로 길이와 세로 길이가 각각 80, 70이기 때문에 80(가로) x 70(세로) 크기의 지갑을 만들면 모든 명함들을 수납할 수 있습니다. 하지만 2번 명함을 가로로 눕혀 수납한다면 80(가로) x 50(세로) 크기의 지갑으로 모든 명함들을 수납할 수 있습니다. 이때의 지갑 크기는 4000(=80 x 50)입니다.</td>
<td></td>
<td></td>
</tr>
</tbody></table>
<p>모든 명함의 가로 길이와 세로 길이를 나타내는 2차원 배열 sizes가 매개변수로 주어집니다. 모든 명함을 수납할 수 있는 가장 작은 지갑을 만들 때, 지갑의 크기를 return 하도록 solution 함수를 완성해주세요.</p>
<h3 id="-제한사항">* 제한사항</h3>
<p>sizes의 길이는 1 이상 10,000 이하입니다.
sizes의 원소는 [w, h] 형식입니다.
w는 명함의 가로 길이를 나타냅니다.
h는 명함의 세로 길이를 나타냅니다.
w와 h는 1 이상 1,000 이하인 자연수입니다.</p>
<h5 id="입출력-예">입출력 예</h5>
<table>
<thead>
<tr>
<th>sizes</th>
<th>result</th>
</tr>
</thead>
<tbody><tr>
<td>[[60, 50], [30, 70], [60, 30], [80, 40]]</td>
<td>4000</td>
</tr>
<tr>
<td>[[10, 7], [12, 3], [8, 15], [14, 7], [5, 15]]</td>
<td>120</td>
</tr>
<tr>
<td>[[14, 4], [19, 6], [6, 16], [18, 7], [7, 11]]</td>
<td>133</td>
</tr>
</tbody></table>
<h1 id="🎈-내-풀이">🎈 내 풀이</h1>
<blockquote>
</blockquote>
<pre><code class="language-python">def solution(sizes):
    mx, my = 0, 0
    for xy in sizes:
        x,y = min(xy), max(xy)
        if mx * my == 0 :
            mx, my = x, y
        else :
            mx, my = max(mx, x), max(my, y)
    return mx * my</code></pre>
<p>가로/세로의 값을 가지는 list는 가로가 될 수도 있고, 세로가 될 수도있다. 그러므로 더 큰 값은 세로, 더 작은 값은 가로로 고정해버리고 가로 중의 최대값과 세로중의 최대값을 구하면 된다. </p>
<h1 id="🎈-다른-사람-풀이">🎈 다른 사람 풀이</h1>
<blockquote>
<pre><code class="language-python">solution = lambda sizes: max(sum(sizes, [])) * max(min(size) for size in sizes)</code></pre>
</blockquote>
<p>```
lambda를 이용하여 심플하게 표현하였다. 그리고 sum함수로써 list 두개의 합으로 새 list 를 만들었다. 
전체 값중 가장 큰 값 * 각 카드의 작은값중 최대값</p>
<p>간단한 문제여서 풀이는 이정도로 마치겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Django] 장고 Model]]></title>
            <link>https://velog.io/@hithae_hothae/Django-%EC%9E%A5%EA%B3%A0-Model</link>
            <guid>https://velog.io/@hithae_hothae/Django-%EC%9E%A5%EA%B3%A0-Model</guid>
            <pubDate>Thu, 23 Sep 2021 08:48:36 GMT</pubDate>
            <description><![CDATA[<h1 id="🎈-model">🎈 Model</h1>
<blockquote>
<p><strong>모델 생성 &amp; 적용 과정</strong>
사용할 데이터 확인 → 데이터 모델링 → 데이터에 맞는 field 작성 → 모델 생성 / 변경 → django 반영</p>
</blockquote>
<p>django에서 model 생성.</p>
<blockquote>
<pre><code class="language-python">#models.py
from django.db import models
class Menu(models.Model):
    name = models.CharField(max_length=50)
    price = models.IntegerField()
    img_path = models.TextField()</code></pre>
</blockquote>
<pre><code></code></pre><h1 id="🎈-migration">🎈 Migration</h1>
<blockquote>
<p>마이그레이션(Migration)은 모델(Model)의 변경 사항 즉 Django 프로젝트의 데이터 구조 변경 사항을 관리하기 위한 Django만의 관리 방법이다. 변경될 때마다 히스토리를 하나씩 만들어 두고 마치 블럭을 갈아 끼우듯 생성한 히스토리를 실제 데이터베이스에 반영하는 거죠. 그리고 이 모든 과정은 Django의 ORM(Object-Relational Mapping)을 통해 진행한다.</p>
</blockquote>
<blockquote>
<p>변화하여 병합할 Migrations 을 생성. 
<strong>python manage.py makemigrations</strong></p>
</blockquote>
<blockquote>
<p>전체 migrations 확인
 <strong>python manage.py showmigrations</strong></p>
</blockquote>
<blockquote>
<p>ORM 을 통해 sql 로 변경을 확인
<strong>python manage.py sqlmigrate {app명} {migrations num}</strong></p>
</blockquote>
<blockquote>
<p>변경 히스토리를 기준으로 데이터베이스에 반영
<strong>python manage.py migrate</strong></p>
</blockquote>
<h1 id="🎈-데이터-넣고-조회">🎈 데이터 넣고 조회</h1>
<blockquote>
</blockquote>
<p>해당 프로젝트로 이동 후 shell 실행
<strong>python manage.py shell</strong></p>
<ul>
<li>model 가져오기
from {app}.models import {model명}</li>
<li>데이터 삽입
{model명}.objects.create({필드명}={값})</li>
<li>모든 데이터 조회
{model명}.objects.all()</li>
<li>모든 세부 데이터 조회
{model명}.objects.all().values()</li>
</ul>
<h1 id="🎈-데이터-상세-조회">🎈 데이터 상세 조회</h1>
<blockquote>
</blockquote>
<p>{model}.objects.all() : 모든 데이터 조회
{model}.objects.all.values(컬럼명) : 특정 컬럼의 데이터 조회
{model}.objects.order_by(필드명) : 정렬된 데이터를 조회, 내림차순으로 할땐 필터에 &#39;-&#39; 붙여서 사용
{model}.objects.get(field=value) : 하나의 데이터를 조회. 여러개 나올 시 에러 발생
{model}.objects.filter(field=value) : 여러 데이터를 조회
rows = {model}.objects.count() : 데이터 개수 세기
data = {model}.objects.exclude(field=value) : 특정 조건 제외한 데이터 조회
data = {model}.objects.filter(price=10000).order_by(&#39;name&#39;) : 체인으로 연결해서 조회</p>
<blockquote>
<p><strong>조건 키워드 검색</strong>
<code>__exact</code>, <code>__iexact</code> : 대소문자 구분/미구분 일치하는지를 체크</p>
</blockquote>
<pre><code class="language-python">data = {model}.objects.filter({필드명}__iexact=&#39;chicken&#39;)
# {필드명}이 &#39;chicken&#39;인 데이터를 모두 조회합니다.
# 단, 대소문자를 구분하지 않습니다.</code></pre>
<hr>
<p><code>__contains</code>,<code>__icontains</code> : 지정한 문자열을 포함하는지 체크 (대소문자 구분/미구분)</p>
<pre><code class="language-python">data = {model}.objects.filter({필드명}__contains=&#39;chicken&#39;)
# {필드명}에 &#39;chicken&#39;이 포함된 모든 데이터를 조회합니다.
# 단, 대소문자를 구분합니다. (__contains)</code></pre>
<hr>
<p><code>__range</code> : 지정한 범위 내에 포함되는지 체크</p>
<pre><code class="language-python">data = {model}.objects.filter({필드명}__range=(1000,5000))
# {필드명}이 1000~5000인 모든 데이터를 조회합니다.</code></pre>
<hr>
<p><code>__in</code> : 주어진 리스트 안에 존하는 자료를 조회</p>
<pre><code class="language-python">data = {model}.objects.filter({필드명}__in=[21,25,27])</code></pre>
<h1 id="🎈-데이터-수정">🎈 데이터 수정</h1>
<blockquote>
</blockquote>
<p>from {app}.models import {model명}
data = {model명}.objects.get(id=1)
<strong>data.{필드명} = {변경할내용}
data.save()</strong>
{model명}.objects.all()</p>
<h1 id="🎈-데이터-삭제">🎈 데이터 삭제</h1>
<blockquote>
</blockquote>
<p>from {app}.models import {model명}
data = {model명}.objects.get(id=1)
<strong>data.delete()</strong></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Django] 장고 시작하기]]></title>
            <link>https://velog.io/@hithae_hothae/Django-%EC%9E%A5%EA%B3%A0-%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@hithae_hothae/Django-%EC%9E%A5%EA%B3%A0-%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0</guid>
            <pubDate>Fri, 17 Sep 2021 04:57:14 GMT</pubDate>
            <description><![CDATA[<p>본 게시물은 학습기록용입니다.😊
codeit 의 <strong>Django 웹 개발</strong> 코스를 노트하기 위함입니다.
<a href="https://www.codeit.kr/courses/django-web-development">https://www.codeit.kr/courses/django-web-development</a></p>
<h1 id="1-django-개발-환경-세팅">1. Django 개발 환경 세팅</h1>
<p>Windows 환경에서 가상 Linux 시스템을 설치 후, 그곳에 파이썬 가상환경을 구축하여 버전별 환경 구축을 용이하도록 한다.</p>
<blockquote>
<p>pyenv : 파이썬 설치, 관리
pyenv-virtualenv : 파이썬 가상 환경 관리
WSL (Windows Subsystem for Linux ) : Windows 에서 리눅스 터미널을 사용할 수 있게 해주는 확장 프로그램
VSCode : 텍스트 에디터 </p>
</blockquote>
<h3 id="11-wsl-설치설정">1.1 WSL 설치/설정</h3>
<ul>
<li><p>Windows 기능 켜기/끄기 에서 Linux용 Windows 하위 시스템 [v] 체크
<img src="https://images.velog.io/images/hithae_hothae/post/ce046771-23c5-431b-8675-3b49c5e9896e/image.png" alt=""></p>
</li>
<li><p>Mircrosoft Store 에서 Ubuntu 18.04 LTS 버전 설치
<img src="https://images.velog.io/images/hithae_hothae/post/e38da053-cfef-4261-8b48-0e897753f373/image.png" alt=""></p>
</li>
<li><p>Ubuntu 초기 계정 세팅 
<img src="https://images.velog.io/images/hithae_hothae/post/c8dcc62b-bf76-4a93-b952-01843209295f/image.png" alt=""></p>
</li>
</ul>
<h3 id="12-ubuntu-기본-패키지-설치">1.2 Ubuntu 기본 패키지 설치</h3>
<blockquote>
<ul>
<li>sudo apt-get update</li>
</ul>
</blockquote>
<ul>
<li>sudo apt-get install -y make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev xz-utils tk-dev git python-pip    </li>
</ul>
<h3 id="13-pyenv-설치">1.3 pyenv 설치</h3>
<blockquote>
<p>curl <a href="https://pyenv.run">https://pyenv.run</a> | bash</p>
</blockquote>
<h3 id="14-pyenv를-이용하여-python-설치">1.4 pyenv를 이용하여 python 설치</h3>
<blockquote>
<p>pyenv install --list
pyenv install { 파이썬 버전 }
pyenv versions
pyenv virtualenv { 파이썬 버전 } { 가상환경 이름 }
pyenv uninstall { 가상환경 이름 }</p>
</blockquote>
<h3 id="15-global--local-가상-환경-적용">1.5 global / local 가상 환경 적용</h3>
<blockquote>
<p>pyenv global { 파이썬 버전 }
pyenv local { 가상환경 이름 }</p>
</blockquote>
<h3 id="16-django-설치-및-확인">1.6 Django 설치 및 확인</h3>
<blockquote>
<p>pip install django=={장고 버전}
django-admin --version</p>
</blockquote>
<h1 id="2-django-프로젝트-생성">2. Django 프로젝트 생성</h1>
<pre><code>django-admin startproject [프로젝트 이름]</code></pre><h1 id="3-django--프로젝트-구조">3. Django  프로젝트 구조</h1>
<blockquote>
<p><strong>[프로젝트이름] (project root)</strong>
    <code>manage.py</code> : Django 프로젝트 관리를 위한 명령어를 지원 (App 생성, DB관련명령, 서버실행)
    <code>db.sqlite3</code> : 프로젝트내 Database 파일
    <code>project app</code> : APP 디렉토리</p>
<blockquote>
<p><strong>[프로젝트이름] (project app)</strong>
    <code>__init__.py</code>  :  파이썬 패키지임을 알리는 파일
    <code>settings.py</code> : 프로젝트 시간대 설정, 데이터베이스 설정 등 전반적인 설정파일
    <code>utls.py</code> : URL 을 보고 알맞은 페이지로 연결
    <code>wsgi.py</code> : WebServer Gateway Interface. 웹서버와  Python 어플리케이션인 Django 소통 프로토콜</p>
</blockquote>
</blockquote>
<h1 id="4-django-app">4. Django App</h1>
<p> django 에서는 웹서비스에서 각 기능 단위를 App 이라 한다. 그리고 그 전체를 하나의 project 라 한다.
 app 을 생성하기 위해서 아래 명령어 실행.</p>
<blockquote>
<p>python manage.py startapp {app name}
 <img src="https://images.velog.io/images/hithae_hothae/post/ed65e9d1-bdca-47ec-a5b2-24ec1beadb9b/image.png" alt="">
 settings.py 에서 INSTALLED_APPS 에 추가한 App 을 적어준다.</p>
</blockquote>
<h1 id="5-app-변경사항-적용-및-서버-실행">5. App 변경사항 적용 및 서버 실행</h1>
<blockquote>
<p>python manage.py migrate
python manage.py runserver</p>
</blockquote>
]]></description>
        </item>
    </channel>
</rss>