<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>코딩하는 주노 이야기</title>
    <link>https://co-no.tistory.com/</link>
    <description>일상의 불편함을 기술로서 해결하기 위해 노력하는 IT 엔지니어입니다.

Contact point) 
jjh3706@gmail.com</description>
    <language>ko</language>
    <pubDate>Sun, 9 Aug 2026 16:05:41 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>코_노</managingEditor>
    <item>
      <title>[MSSQL] Blocking 유발하는 세션(root blocker)을 찾아내고, 운영자 계정에 root blocker만 kill할 수 있는 프로시저 제공하기</title>
      <link>https://co-no.tistory.com/entry/MSSQL-Blocking-%EC%9C%A0%EB%B0%9C%ED%95%98%EB%8A%94-%EC%84%B8%EC%85%98root-blocker%EC%9D%84-%EC%B0%BE%EC%95%84%EB%82%B4%EA%B3%A0-%EC%9A%B4%EC%98%81%EC%9E%90-%EA%B3%84%EC%A0%95%EC%97%90-root-blocker%EB%A7%8C-kill%ED%95%A0-%EC%88%98-%EC%9E%88%EB%8A%94-%ED%94%84%EB%A1%9C%EC%8B%9C%EC%A0%80-%EC%A0%9C%EA%B3%B5%ED%95%98%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;원래 MSSQL 에서 Session Kill 할 수 있는 권한은 DBA만 가지고 있는 게 바람직하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;MSSQL에서의 Session Kill 권한&lt;/b&gt;은 기본적으로, '&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;ALTER ANY CONNECTION'&lt;/b&gt;&lt;/span&gt; 권한이 부여되어 있어야 하며, 이는 서버 인스턴스 범위의 권한이기에, 해당 권한을 가진 SQL Login은 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;모든 세션에 대해 Kill 할 수 있는 아주 강력하고 위험한 권한&lt;/b&gt;&lt;/span&gt;을 가지게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나, 모든 운영 환경에 있어 DBA가 365일 24시간 내내 5분대기조처럼 있을 수는 없고,&lt;br /&gt;상황에 따라서 Kill 을 수행할 수 있는 조건만 잘 제어한다면, &lt;br /&gt;운영자에게 특정 상황의 경우에만 Kill 할 수 있는 프로시저를 제공하는 게, &lt;br /&gt;긴급한 장애도 해결하고 DBA도 한결 편해질 수 있는 방법임을 요즘 체감한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 그에 대한 방법에 대해 알아보고자 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 현재 Blocking을 유발하는 세션, 즉, root blocker session을 찾는 쿼리는 다음 쿼리를 수행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 쿼리를 프로시저화 시켜서, 운영자용 계정에 실행 권한을 부여하는 것도 blocking을 빠르게 확인하는 데에 도움이 될 것이다.&lt;/p&gt;
&lt;pre id=&quot;code_1767078429348&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT req.session_id
	, ses.host_name
	, ses.login_name
	, req.status
	, req.blocking_session_id	-- 이 값이 0이면, 다음 중 하나. 1. root blocker / 2. blocking 상태는 아님.
	, req.wait_type
	, SUBSTRING(sql_text.text,req.statement_start_offset/2, 
		(CASE 
			WHEN req.statement_end_offset = -1
			THEN LEN(CONVERT(NVARCHAR(max), sql_text.text)) * 2
			ELSE req.statement_end_offset 
			END - req.statement_start_offset)/2
	) AS [Query_Text] --- statement of batch or proc executing right now
	, DB_NAME(ses.database_id) AS [Current Used DB] 
	, CAST(DATEDIFF(ss, req.start_time, GETDATE()) AS NVARCHAR)+ N'초' AS [Request 경과시간]
	, object_name(sql_text.objectid) AS [SP명]	-- ad-hoc 또는 prepared SQL statement 라면, Null 로 나옴
	, req.cpu_time AS [CPU_Time (ms단위)]
	, req.total_elapsed_time
	, req.reads
	, req.writes 
	, req.logical_reads 
	, req.scheduler_id
FROM sys.dm_exec_requests AS req WITH (NOLOCK)
INNER JOIN sys.dm_exec_sessions AS ses WITH (NOLOCK) ON req.session_id = ses.session_id
CROSS APPLY sys.dm_exec_sql_text(req.sql_handle) AS sql_text
WHERE req.session_id &amp;gt; 50 
	AND sql_text.text NOT LIKE '%sp_server_diagnostics%'
ORDER BY req.blocking_session_id, req.session_id, req.status, req.cpu_time, req.logical_reads&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;0. 테스트 DB 및 Table 생성&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로시저를 생성하기에 앞서, 설명할 프로시저가 잘 동작하는 지 테스트 해 볼 필요가 있으므로, 테스트 환경을 구성하는 쿼리부터 수행하자. &lt;b&gt;(이 프로시저를 운영 환경에서 바로 테스트하는 건 당연히 안 되니까.) &lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1767078176869&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- 테스트용 데이터베이스 생성 (최초 1회)
IF NOT EXISTS (SELECT name FROM sys.databases WHERE name = 'TestBlockingDB')
BEGIN
    CREATE DATABASE TestBlockingDB;
END
GO

USE TestBlockingDB;
GO

-- 테스트용 테이블 생성 (최초 1회)
IF OBJECT_ID('dbo.TestTable') IS NULL
BEGIN
    CREATE TABLE dbo.TestTable (
        ID INT PRIMARY KEY,
        Name NVARCHAR(50),
        Value INT
    );
    INSERT INTO dbo.TestTable (ID, Name, Value) VALUES (1, 'Item A', 10);
    INSERT INTO dbo.TestTable (ID, Name, Value) VALUES (2, 'Item B', 20);
    PRINT '[TestTable] Table creation and test data insertion complete.';
END
ELSE
BEGIN
    PRINT '[TestTable] already exists!!!';
END
GO&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;1. Session Kill 을 [운영자 계정] 대신 수행(IMPERSONATE)할 계정 생성&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서는 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;'KillUser' 라고 유저를 생성해서 설명한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1767078789528&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* EXECUTE AS 용도로 사용할 KILL 전용 계정 생성 */

USE [master];
GO

IF NOT EXISTS (SELECT * FROM sys.sql_logins WHERE name = 'KillerUser')
BEGIN
    CREATE LOGIN KillerUser 
		WITH PASSWORD = 'MyStrongPassword!', 
		CHECK_POLICY = ON,
		DEFAULT_DATABASE = [master]
    PRINT '[KillerUser] Login creation complete.';
END
ELSE
BEGIN
    PRINT '[KillerUser] Login already exists!!!';
END

-- KillerUser SQL 로그인을 master DB의 유저로 매핑
USE [master]; -- master DB 컨텍스트에서 실행
IF NOT EXISTS (SELECT * FROM sys.database_principals WHERE name = 'KillerUser')
BEGIN
    CREATE USER KillerUser FOR LOGIN KillerUser;
    PRINT '[KillerUser] Login successfully mapped to the [master] database as a user.';
END
ELSE
BEGIN
    PRINT 'The user [KillUser] already exists in the [master] DB!!!';
END

-- KillerUser 로그인에게 ALTER ANY CONNECTION, VIEW SERVER STATE 서버 권한만 부여
GRANT ALTER ANY CONNECTION TO KillerUser;
PRINT 'ALTER ANY CONNECTION permission to [KillerUser].';
GRANT VIEW SERVER STATE TO KillerUser;
PRINT 'Granted VIEW SERVER STATE permission to [KillerUser].';

-- 생성된 KillerUser 로그인을 직접 로그인 불가하도록 DISABLE (보안상 권장)
ALTER LOGIN KillerUser DISABLE;
PRINT '[KillerUser] Login disable complete.';

-- 생성된 KillerUser 로그인을 impersonate 할 수 있도록 운영자 계정에 권한 부여
GRANT IMPERSONATE ON USER::KillerUser TO [특정_APP_운영자용_계정]&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;2. 프로시저 생성 및 실행 권한 부여&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Blocking 유발 세션 조회 쿼리 프로시저인 &lt;span style=&quot;color: #8a3db6;&quot;&gt;[sp_GetBlockingInfo]&lt;/span&gt; 생성&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1767141488548&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;USE master; -- 실제 운영 환경에서는 별도 공용 DB (ex. [DBA_Tools]) 생성 권장
GO

-- 기존 프로시저가 있다면 삭제
IF OBJECT_ID('dbo.sp_GetBlockingInfo') IS NOT NULL
    DROP PROCEDURE dbo.sp_GetBlockingInfo;
GO

CREATE PROCEDURE dbo.sp_GetBlockingInfo
    @specific_spid INT = NULL -- 특정 SPID를 입력받아 그 SPID 및 그와 관련된 blocking/blocked 정보를 조회
AS
BEGIN
    SET NOCOUNT ON;

    SELECT
        req.session_id,
        ses.host_name,
        ses.login_name,
        req.status,
        req.blocking_session_id,
        req.wait_type,
        SUBSTRING(sql_text.text, req.statement_start_offset / 2,
            (CASE
                WHEN req.statement_end_offset = -1
                THEN LEN(CONVERT(NVARCHAR(max), sql_text.text)) * 2
                ELSE req.statement_end_offset
            END - req.statement_start_offset) / 2
        ) AS [Query_Text],
        DB_NAME(ses.database_id) AS [Current Used DB],
        CAST(DATEDIFF(ss, req.start_time, GETDATE()) AS NVARCHAR) + N'초' AS [Request 경과시간],
        object_name(sql_text.objectid) AS [SP명],
        req.cpu_time AS [CPU_Time (ms단위)],
        req.total_elapsed_time,
        req.reads,
        req.writes,
        req.logical_reads,
        req.scheduler_id
    FROM sys.dm_exec_requests AS req WITH (NOLOCK)
    INNER JOIN sys.dm_exec_sessions AS ses WITH (NOLOCK) ON req.session_id = ses.session_id
    CROSS APPLY sys.dm_exec_sql_text(req.sql_handle) AS sql_text
    WHERE
        req.session_id &amp;gt; 50
        AND sql_text.text NOT LIKE '%sp_server_diagnostics%'
        AND (@specific_spid IS NULL OR req.session_id = @specific_spid OR req.blocking_session_id = @specific_spid) -- 특정 SPID 관련 정보만 필터링
    ORDER BY
        req.blocking_session_id, req.scheduler_id, req.status, req.cpu_time, req.logical_reads;

END;
GO

-- sp_GetBlockingInfo 프로시저 실행 권한을 운영자 계정에 부여
GRANT EXECUTE ON dbo.sp_GetBlockingInfo TO [특정_APP_운영자용_계정];
-- KillerUser도 이 프로시저를 KillerUser 컨텍스트에서 호출할 수 있도록 PUBLIC에 EXECUTE 권한 부여
GRANT EXECUTE ON dbo.sp_GetBlockingInfo TO [KillerUser];&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;특정 세션 KILL 프로시저인 &lt;span style=&quot;color: #8a3db6;&quot;&gt;[sp_KillBlockingSession]&lt;/span&gt; 생성&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 이 프로시저를 Session Kill 권한이 없는 운영자 계정에 실행 권한을 부여할 예정이므로, &lt;br /&gt;이 프로시저가 특정 상황에서만 동작하도록 잘 제한해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단하게 설명하면, 이 프로시저는 다음의 경우에만 동작한다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;프로시저의 파라미터로 입력한 SPID에 해당하는 세션이 &lt;b&gt;현재도 유효한 활성 세션인지&lt;/b&gt; 확인&lt;/li&gt;
&lt;li&gt;프로시저의 파라미터로 입력한 SPID에 해당하는 세션이 &lt;b&gt;실제 root blocker 세션이 맞는 지&lt;/b&gt; 검증&lt;/li&gt;
&lt;li&gt;프로시저의 실행 계정이&lt;b&gt; 파라미터로 입력한 대상 DB에 대해 'public' 이상의 권한이 있는 지&lt;/b&gt; 확인&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, 운영자 계정에 아래 프로시저에 대한 실행 권한뿐만 아니라, 자체적으로도 이미 DB 서버의 lock 등을 확인할 수 있는 권한인, &lt;b&gt;VIEW SERVER STATE&lt;/b&gt; 권한도 필요하다. 혹시 해당 권한이 없다면, 아래 쿼리를 수행하여 부여할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1767139721957&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- 아래 쿼리는 sa 권한으로 수행
USE [master];
GRANT VIEW SERVER STATE TO [특정_APP_운영자용_계정];&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;pre id=&quot;code_1767141696197&quot; class=&quot;sql&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;sql&quot;&gt;&lt;code&gt;USE [master]; -- [master] DB보다는 공통으로 관리되는 DB를 별도 생성하고, 해당 DB에 프로시저를 생성하는 것을 보안상 권장.
GO

-- 아래 프로시저를 생성하는 DB는 TRUSTWORTHY ON 설정이 되어 있어야 하므로, 보안 관리에 매우 주의가 필요.
ALTER DATABASE [master] SET TRUSTWORTHY ON;

-- 기존 프로시저가 있다면 삭제
IF OBJECT_ID('dbo.sp_KillBlockingSession') IS NOT NULL
    DROP PROCEDURE dbo.sp_KillBlockingSession;
GO

CREATE PROCEDURE dbo.sp_KillBlockingSession
    @spid_to_kill INT,
    @target_db_name SYSNAME
WITH EXECUTE AS 'KillerUser'
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @session_exists BIT = 0;
    DECLARE @is_root_blocker BIT = 0;
    DECLARE @session_db_name SYSNAME;
    DECLARE @caller_login_name SYSNAME = ORIGINAL_LOGIN();
    DECLARE @command NVARCHAR(100);

    -- sp_GetBlockingInfo의 결과를 저장할 임시 테이블 변수
    DECLARE @BlockingInfo TABLE (
        session_id INT,
        host_name SYSNAME,
        login_name SYSNAME,
        status NVARCHAR(30),
        blocking_session_id INT,
        wait_type NVARCHAR(60),
        Query_Text NVARCHAR(MAX),
        CurrentUsedDB NVARCHAR(100) NULL,
        Request_ElapsedTime NVARCHAR(50),
        SPName NVARCHAR(200) NULL,
        CPU_Time INT,
        Total_ElapsedTime INT,
        reads BIGINT,
        writes BIGINT,
        logical_reads BIGINT,
        scheduler_id INT
    );

    PRINT '--- SPID ' + CAST(@spid_to_kill AS NVARCHAR) + ' KILL trying... ---';
    PRINT 'Target DB: ' + @target_db_name;
    PRINT 'Caller User: ' + @caller_login_name;

    -- dbo.sp_GetBlockingInfo 호출 및 결과 저장
    INSERT INTO @BlockingInfo
    EXEC dbo.sp_GetBlockingInfo @specific_spid = @spid_to_kill;

    -- 1. 입력 SPID가 유효한 활성 사용자 세션인지 확인
    IF EXISTS (SELECT 1 FROM @BlockingInfo WHERE session_id = @spid_to_kill AND status &amp;lt;&amp;gt; 'sleeping' AND status &amp;lt;&amp;gt; 'dormant')
    BEGIN
        SET @session_exists = 1;
    END

    IF @session_exists = 0
    BEGIN
        PRINT 'ERROR: The specified SPID ' + CAST(@spid_to_kill AS NVARCHAR) + ' is not a valid user session or does not exist.';
        RETURN 1;
    END

    -- 2. Root Blocker 여부 확인 및 세션 DB 정보 가져오기
    SELECT TOP 1 @is_root_blocker = 1,
                 @session_db_name = CurrentUsedDB
    FROM @BlockingInfo
    WHERE session_id = @spid_to_kill
      AND blocking_session_id = 0 -- 본인이 block 당하고 있지 않음
      AND EXISTS (SELECT 1 FROM @BlockingInfo WHERE blocking_session_id = @spid_to_kill); -- 다른 세션을 block하고 있음

    IF @is_root_blocker = 0
    BEGIN
        PRINT 'ERROR: SPID ' + CAST(@spid_to_kill AS NVARCHAR) + ' is not a Root Blocker or a session executing a suitable query, so KILL is not performed.';
        -- 실제 Root Blocker를 찾는 힌트를 줄 수 있음
        DECLARE @actual_blocker_spid INT;
        SELECT TOP 1 @actual_blocker_spid = blocking_session_id
        FROM @BlockingInfo
        WHERE session_id = @spid_to_kill AND blocking_session_id &amp;lt;&amp;gt; 0;

        IF @actual_blocker_spid IS NOT NULL
        BEGIN
             PRINT 'INFO: SPID ' + CAST(@spid_to_kill AS NVARCHAR) + ' is being blocked by SPID ' + CAST(@actual_blocker_spid AS NVARCHAR) + '.';
             PRINT 'INFO: Root Blocker is SPID ' + CAST(@actual_blocker_spid AS NVARCHAR) + ' or in its preceding chain.';
        END
        RETURN 1;
    END

    PRINT 'INFO: SPID ' + CAST(@spid_to_kill AS NVARCHAR) + ' is a Root Blocker.';
    PRINT 'INFO: Current DB for the Root Blocker session: [' + @session_db_name + ']';

    -- 3. 입력받은 Target DB와 Root Blocker 세션의 Current Used DB 일치 여부 확인
    IF @session_db_name IS NULL OR @session_db_name &amp;lt;&amp;gt; @target_db_name
    BEGIN
        PRINT 'ERROR: The DB of the Root Blocker session ''' + ISNULL(@session_db_name, 'NULL') + ''' does not match the requested target DB [' + @target_db_name + ']. KILL will not be performed.';
        RETURN 1;
    END

    PRINT 'INFO: The Root Blocker session''s DB [' + @session_db_name + '] matches the requested target DB [' + @target_db_name + '].';

    -- 4. 프로시저 실행자가 대상 DB에 대해 'public' 이상의 권한이 있는지 확인
    DECLARE @caller_has_db_access BIT = 0;
    
    EXECUTE AS CALLER;
    BEGIN TRY
        IF HAS_DBACCESS(@target_db_name) = 1
        BEGIN
            SET @caller_has_db_access = 1;
        END
    END TRY
    BEGIN CATCH
        -- 대상 DB에 아예 접근 권한이 없어서 HAS_DBACCESS 호출 자체가 에러가 나는 경우
        SET @caller_has_db_access = 0;
    END CATCH
    REVERT;

    IF @caller_has_db_access = 0
    BEGIN
        PRINT 'ERROR: The caller [' + @caller_login_name + '] does not have permission (public or higher) to the target DB [' + @target_db_name + '], so the KILL operation will not be performed!';
        RETURN 1;
    END

    PRINT 'INFO: The calling user [' + @caller_login_name + '] has been verified to have permission for the target DB [' + @target_db_name + '].';
    
    -- KILL 실행 전, Root Blocker의 호스트명과 로그인명 출력
    DECLARE @root_blocker_hostname SYSNAME;
    DECLARE @root_blocker_loginname SYSNAME;

    SELECT TOP 1 @root_blocker_hostname = host_name,
                 @root_blocker_loginname = login_name
    FROM @BlockingInfo
    WHERE session_id = @spid_to_kill;

    PRINT 'WARNING: Attempting to KILL Root Blocker SPID ''' + CAST(@spid_to_kill AS NVARCHAR(10)) + '''.';
    PRINT 'WARNING: Session details - Host: [' + ISNULL(@root_blocker_hostname, 'N/A') + '], Login: [' + ISNULL(@root_blocker_loginname, 'N/A') + '].';

    -- 5. 모든 검증을 통과했으므로 KILL 명령 실행
    SET @command = 'KILL ' + CAST(@spid_to_kill AS NVARCHAR(10));
    PRINT 'INFO: Execute KILL command: ' + @command;
    EXEC sp_executesql @command;
    PRINT 'INFO: SPID ' + CAST(@spid_to_kill AS NVARCHAR(10)) + ' has been successfully KILLed.';

END;
GO

-- 프로시저 실행 권한 부여
-- '특정_애플리케이션_사용자명'에게 이 프로시저를 실행할 권한을 부여합니다.
GRANT EXECUTE ON dbo.sp_KillBlockingSession TO [특정_APP_운영자용_계정];&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;위 생성된 프로시저 사용 방법&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1767079265870&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;USE [master];
EXEC dbo.sp_KillBlockingSession
    @spid_to_kill = 58,           -- Kill하려는 SPID (예시)
    @target_db_name = 'MyTargetAppDB'; -- Kill을 허용할 특정 DB명 (예시)&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;3. 실제 Blocking 상황을 테스트 DB에서 유발하고, 프로시저 잘 동작하는 지 확인&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 Blocking 상황을 유발하는 시나리오는 다음과 같다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;SSMS에서 첫번째 쿼리 창에서 아래 'SSMS 쿼리 창 #1' 쿼리를 수행하여 Exclusive Lock(X Lock)을 걸고 트랜잭션을 1시간동안 열어둔다. 그리고 이 쿼리 창은 테스트가 끝나기 전까지 닫거나 COMMIT 또는 ROLLBACK이 되지 않도록 한다.&lt;/li&gt;
&lt;li&gt;SSMS에서 두번째 쿼리 창을 열어, 아래 'SSMS 쿼리 창 #2' 쿼리를 수행한다. 위 쿼리에서 잠근 ID = 1 인 행을 업데이트하려고 시도하도록 쿼리를 구성한 것이고, 위에서 실행한 세션이 당연히 닫히지 않았을 테니, 이 쿼리는 Block된다.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre id=&quot;code_1767079511844&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- === SSMS 쿼리 창 #1: Blocking 유발 쿼리 (1시간 딜레이 후 자동 COMMIT) ===
USE TestBlockingDB;
GO

PRINT '=== Start executing query to block the other query ===';
SELECT @@SPID AS 'Blocking_SPID'; -- 이 세션의 SPID를 확인

BEGIN TRAN; -- 트랜잭션 시작

-- ID=1인 행을 업데이트하여 배타적 잠금을 걸고 트랜잭션을 열어둠
UPDATE dbo.TestTable
SET Value = 100
WHERE ID = 1;

PRINT 'Updating row ID=1 and maintaining lock...';
PRINT 'INFO: It will be automatically committed after a 1H delay.';

-- 1시간 대기 (01:00:00)
WAITFOR DELAY '01:00:00';

COMMIT TRAN; -- 1시간 후 자동으로 트랜잭션 커밋 (잠금 해제)

PRINT 'The transaction has been automatically committed. The lock has been released.';&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1767079558316&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- === SSMS 쿼리 창 #2: Block될 쿼리 ===
USE TestBlockingDB;
GO

PRINT '=== Start executing query to be blocked ===';
SELECT @@SPID AS 'Blocked_SPID'; -- 이 세션의 SPID를 확인 (예: 59)

-- ID=1인 행을 업데이트 시도 -&amp;gt; Blocking 세션이 잠금을 해제할 때까지 Block될 것임
UPDATE dbo.TestTable
SET Value = 150
WHERE ID = 1;

PRINT 'INFO: Update complete (This message appears after the block is released)';&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;[sp_GetBlockingInfo]&lt;/span&gt; SP를 운영자용 계정에서 실행&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1767079626317&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- === SSMS 쿼리 창 #4 (또는 창 #3): Kill 프로시저 실행 ===
USE master; -- 프로시저가 master DB에 있다고 가정
EXEC dbo.sp_GetBlockingInfo;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 쿼리 수행 결과를 보면, 아래와 같이 block되고 있는 세션은 blocking_session_id의 값이 root blocker 세션의 session_id 값으로 나타날 것이다. 또한 root blocker의 경우, blocking_session_id 값이 0 으로 되어 있는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1491&quot; data-origin-height=&quot;544&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Cm6za/dJMcabbL7p4/zmpbCFb7bnXRr9ktQlimrk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Cm6za/dJMcabbL7p4/zmpbCFb7bnXRr9ktQlimrk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Cm6za/dJMcabbL7p4/zmpbCFb7bnXRr9ktQlimrk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCm6za%2FdJMcabbL7p4%2FzmpbCFb7bnXRr9ktQlimrk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1491&quot; height=&quot;544&quot; data-origin-width=&quot;1491&quot; data-origin-height=&quot;544&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;[sp_KillBlockingSession]&lt;/span&gt; SP를 운영자용 계정에서 실행&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1767079764598&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- === SSMS 쿼리 창 #4 (또는 창 #3): Kill 프로시저 실행 ===
USE master; -- 프로시저가 master DB에 있다고 가정

EXEC dbo.sp_KillBlockingSession
    @spid_to_kill = 260,           -- &amp;lt;&amp;lt;--- 실제 Blocking SPID를 입력하세요! (예: 260)
    @target_db_name = 'TestBlockingDB'; -- &amp;lt;&amp;lt;--- Kill하려는 SPID가 사용하는 DB 이름&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1389&quot; data-origin-height=&quot;806&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mswmD/dJMcaaRty5O/5xGoukNWGNB3AKSAF2iwEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mswmD/dJMcaaRty5O/5xGoukNWGNB3AKSAF2iwEK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mswmD/dJMcaaRty5O/5xGoukNWGNB3AKSAF2iwEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmswmD%2FdJMcaaRty5O%2F5xGoukNWGNB3AKSAF2iwEK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1389&quot; height=&quot;806&quot; data-origin-width=&quot;1389&quot; data-origin-height=&quot;806&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 '&lt;b&gt;SPID # has been successfully KILLed.&lt;/b&gt;' 문구가 출력되었다면, 생성한 프로시저가 잘 동작하는 것이고, 테스트 시나리오에서 수행한 'SSMS 쿼리 창 #1'에 세션이 끊긴 문구가 출력된 것을 볼 수 있을 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1366&quot; data-origin-height=&quot;813&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/datNG0/dJMcabv45TC/XzGiEgNpDmCzwvuOwh9aKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/datNG0/dJMcabv45TC/XzGiEgNpDmCzwvuOwh9aKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/datNG0/dJMcabv45TC/XzGiEgNpDmCzwvuOwh9aKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdatNG0%2FdJMcabv45TC%2FXzGiEgNpDmCzwvuOwh9aKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1366&quot; height=&quot;813&quot; data-origin-width=&quot;1366&quot; data-origin-height=&quot;813&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;4. 테스트 DB 삭제&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;위와 같이 생성한 프로시저들이 모두 잘 동작하는 것을 확인했다면, 다음과 같이 테스트 DB를 삭제하면서 마무리 하도록 하자!&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1767079803284&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- 테스트 정리 (필요 시)
USE master;
GO
DROP DATABASE TestBlockingDB;
GO&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DB/SQL Server (MSSQL)</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/194</guid>
      <comments>https://co-no.tistory.com/entry/MSSQL-Blocking-%EC%9C%A0%EB%B0%9C%ED%95%98%EB%8A%94-%EC%84%B8%EC%85%98root-blocker%EC%9D%84-%EC%B0%BE%EC%95%84%EB%82%B4%EA%B3%A0-%EC%9A%B4%EC%98%81%EC%9E%90-%EA%B3%84%EC%A0%95%EC%97%90-root-blocker%EB%A7%8C-kill%ED%95%A0-%EC%88%98-%EC%9E%88%EB%8A%94-%ED%94%84%EB%A1%9C%EC%8B%9C%EC%A0%80-%EC%A0%9C%EA%B3%B5%ED%95%98%EA%B8%B0#entry194comment</comments>
      <pubDate>Wed, 31 Dec 2025 11:37:57 +0900</pubDate>
    </item>
    <item>
      <title>[MSSQL] SQL Server Failover Cluster 구성</title>
      <link>https://co-no.tistory.com/entry/MSSQL-SQL-Server-Failover-Cluster-%EA%B5%AC%EC%84%B1</link>
      <description>&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;0. 사전 준비&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;0.1. Windows Server Failover Cluster(WSFC) Feature(기능) 설치&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span&gt;아래와 같이 [Server Manager] 를 통해, 'Failover Clustering' Feature를 설치해 주어야 한다.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;해당 feature 설치 후에는 안정적인 운영을 위해 시스템 reboot 가 필요할 수 있는 점 인지하자.&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1426&quot; data-origin-height=&quot;747&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bulUaf/btsPGk1lib9/hOxnrLavgBK40zwM9WH3v1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bulUaf/btsPGk1lib9/hOxnrLavgBK40zwM9WH3v1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bulUaf/btsPGk1lib9/hOxnrLavgBK40zwM9WH3v1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbulUaf%2FbtsPGk1lib9%2FhOxnrLavgBK40zwM9WH3v1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1426&quot; height=&quot;747&quot; data-origin-width=&quot;1426&quot; data-origin-height=&quot;747&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;0.2. Windows Server Failover Cluster 구성&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1048&quot; data-origin-height=&quot;807&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cK0iVe/btsPFjvd8PW/fB0FCj955nBJb6BywKYKo0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cK0iVe/btsPFjvd8PW/fB0FCj955nBJb6BywKYKo0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cK0iVe/btsPFjvd8PW/fB0FCj955nBJb6BywKYKo0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcK0iVe%2FbtsPFjvd8PW%2FfB0FCj955nBJb6BywKYKo0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1048&quot; height=&quot;807&quot; data-origin-width=&quot;1048&quot; data-origin-height=&quot;807&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span&gt;&lt;b&gt;[Create Cluster]&lt;/b&gt; 를 클릭 후, &lt;b&gt;[Create Clustser Wizard]&lt;/b&gt; 에서 아래와 같이, Failover Cluster에 추가할 node(서버)들의 hostname을 입력하여 추가한다.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;671&quot; data-origin-height=&quot;459&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FWjql/btsPFZJUoFn/DUKqxcEIhmCq2BlzvdEap0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FWjql/btsPFZJUoFn/DUKqxcEIhmCq2BlzvdEap0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FWjql/btsPFZJUoFn/DUKqxcEIhmCq2BlzvdEap0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFWjql%2FbtsPFZJUoFn%2FDUKqxcEIhmCq2BlzvdEap0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;671&quot; height=&quot;459&quot; data-origin-width=&quot;671&quot; data-origin-height=&quot;459&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span&gt;그럼 다음과 같이 Failover Cluster 구성이 가능한 지 Validation을 할 것인지 묻는데, 안전하게 Failover Cluster를 구성하기 위해, &lt;b&gt;Yes&lt;/b&gt;를 클릭 후 Next로 넘어가자!&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;670&quot; data-origin-height=&quot;455&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cOVQ52/btsPFuwAPVw/shR3Kkz9mBub1EbYwIIJ1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cOVQ52/btsPFuwAPVw/shR3Kkz9mBub1EbYwIIJ1k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cOVQ52/btsPFuwAPVw/shR3Kkz9mBub1EbYwIIJ1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcOVQ52%2FbtsPFuwAPVw%2FshR3Kkz9mBub1EbYwIIJ1k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;670&quot; height=&quot;455&quot; data-origin-width=&quot;670&quot; data-origin-height=&quot;455&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span&gt;위 과정에서 Next, Next 진행하다 보면, [Validate a Configuration Wizard] 가 나타나고, 여기에서 Failover Cluster 구성에 필요한 &lt;b&gt;Validation&lt;/b&gt;을 실질적으로 진행하게 된다. 그럼 다음과 같이 'Summary' 로 결과까지 볼 수 있게 되는데, &lt;u&gt;&lt;i&gt;&lt;b&gt;여기에서 Success로 나타나지 않은 것들은 추후에 Failover Cluster 구성에 문제가 생길 수 있으므로, 문제가 생긴다면 이 부분 먼저 살펴보도록 하자.&lt;/b&gt;&lt;/i&gt;&lt;/u&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;671&quot; data-origin-height=&quot;464&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/crp1ZG/btsPF80007M/QnkiyggPf7lEyExCjxCEDk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/crp1ZG/btsPF80007M/QnkiyggPf7lEyExCjxCEDk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/crp1ZG/btsPF80007M/QnkiyggPf7lEyExCjxCEDk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcrp1ZG%2FbtsPF80007M%2FQnkiyggPf7lEyExCjxCEDk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;671&quot; height=&quot;464&quot; data-origin-width=&quot;671&quot; data-origin-height=&quot;464&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span&gt;Validation이 끝나면 다음과 같이 &lt;b&gt;[Access Point for Administering the Cluster]&lt;/b&gt; 단계로, 여기에서 실제 Failover Cluster의 이름과 이에 매핑되는 IP를 지정하게 된다. 여기에서 설정하는 IP는 실제 다른 node에서 사용하고 있는 IP를 쓰면 안되므로, 잘 설정하자!&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;670&quot; data-origin-height=&quot;459&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oQ5Za/btsPE4rtUsP/j19ubsIe1GLqKKP1jEnLTK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oQ5Za/btsPE4rtUsP/j19ubsIe1GLqKKP1jEnLTK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oQ5Za/btsPE4rtUsP/j19ubsIe1GLqKKP1jEnLTK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoQ5Za%2FbtsPE4rtUsP%2Fj19ubsIe1GLqKKP1jEnLTK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;670&quot; height=&quot;459&quot; data-origin-width=&quot;670&quot; data-origin-height=&quot;459&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span&gt;아래와 같은 화면을 본다면, &lt;b&gt;WSFC 생성&lt;/b&gt;은 성공적으로 마친 것이다!&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;670&quot; data-origin-height=&quot;454&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZOHtu/btsPEtyxHOL/rkKB509BM8vQl6iUwJzY1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZOHtu/btsPEtyxHOL/rkKB509BM8vQl6iUwJzY1K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZOHtu/btsPEtyxHOL/rkKB509BM8vQl6iUwJzY1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZOHtu%2FbtsPEtyxHOL%2FrkKB509BM8vQl6iUwJzY1K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;670&quot; height=&quot;454&quot; data-origin-width=&quot;670&quot; data-origin-height=&quot;454&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span&gt;☞ Failover Cluster - 트러블슈팅&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;text-align: left;&quot;&gt;&lt;i&gt;&lt;b&gt;&lt;span&gt;'Access is denied' &lt;/span&gt;&lt;/b&gt;&lt;/i&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span&gt;아래와 같은 에러가 나타났다면, 현재 Failover Clustesr 생성을 진행하고 있는 AD 계정이 domain controller 권한이 아니기 때문에, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;Computer Object&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt; 의 생성 권한&lt;/b&gt;&lt;/span&gt;이 없어서 생기는 문제일 것이다. 이는 사내의 AD 담당자에게 요청하여, 현재 구성을 진행하고 있는 AD 계정에 적절한 권한을 부여 받아야 한다.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;667&quot; data-origin-height=&quot;455&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2CqUX/btsPEvpAst3/71iVVhgKEZTbkFXafApEJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2CqUX/btsPEvpAst3/71iVVhgKEZTbkFXafApEJk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2CqUX/btsPEvpAst3/71iVVhgKEZTbkFXafApEJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2CqUX%2FbtsPEvpAst3%2F71iVVhgKEZTbkFXafApEJk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;667&quot; height=&quot;455&quot; data-origin-width=&quot;667&quot; data-origin-height=&quot;455&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 기본적인 WSFC 기능의 활성화와 함께 SQL Server Failover Cluster 를 구성할 node들을 해당 WSFC에 구성하였다면, 본격적으로 SQL Server Failover Cluster 구성에 대해 알아보도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;1. SQL Server Failover Cluster 에서 사용할 디스크들을 WSFC에 등록&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1391&quot; data-origin-height=&quot;753&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cZOgH0/btsPFE0bvdO/khEcNYNOporI52j1khoX01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cZOgH0/btsPFE0bvdO/khEcNYNOporI52j1khoX01/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cZOgH0/btsPFE0bvdO/khEcNYNOporI52j1khoX01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcZOgH0%2FbtsPFE0bvdO%2FkhEcNYNOporI52j1khoX01%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1391&quot; height=&quot;753&quot; data-origin-width=&quot;1391&quot; data-origin-height=&quot;753&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span&gt;&lt;b&gt;[Failover Cluster Manager]&lt;/b&gt; 를 열어, 왼쪽 탭에서 &lt;b&gt;[Disks]&lt;/b&gt; 로 가면, &lt;b&gt;[Add Disk]&lt;/b&gt;가 있는데, 이걸 클릭하면 아래와 같은 화면이 나온다. 이때, WSFC에 들어가 있는 node들 간에 공유할 수 있는 disk가 있다면, &lt;b&gt;[Add Disk]를 수행할 디스크들을 선택&lt;/b&gt;할 수 있도록 하는 화면이 나오는 것이다.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span&gt;MSSQL의 FCI(Failover Cluster Instance)를 구성하기 위해서는, 스토리지상 동일한 볼륨에 대해서 WSFC에 참여한 member node 간 disk를 Active-Standby 형태로 공유하는 것이므로, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;WSFC에 참여한 member node 들에서 하나의 node에만 해당 볼륨을 mount 하는 것이 맞다.&lt;/b&gt; &lt;/span&gt;(OS 상에서 동일한 볼륨에 대해 LUN을 같게 하는 것 자체가 불가할 것이다.)&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1391&quot; data-origin-height=&quot;755&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bCEdvJ/btsPF3ZSvjM/HvmdjTW3Ux5GNjOOFKcQkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bCEdvJ/btsPF3ZSvjM/HvmdjTW3Ux5GNjOOFKcQkk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bCEdvJ/btsPF3ZSvjM/HvmdjTW3Ux5GNjOOFKcQkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbCEdvJ%2FbtsPF3ZSvjM%2FHvmdjTW3Ux5GNjOOFKcQkk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1391&quot; height=&quot;755&quot; data-origin-width=&quot;1391&quot; data-origin-height=&quot;755&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1.1. Disk Witness in Quorum 설정 - SQL Server Failover cluster 노드 수가 짝수일 때에만 (특히 2대)&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span&gt;2노드 클러스터는 다음과 같은 문제를 가지고 있다.&lt;/span&gt;&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;text-align: left;&quot;&gt;&lt;span&gt;노드 1 (1 투표 행사) + 노드 2 (1 투표 행사) = &lt;b&gt;총 2 투표&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;text-align: left;&quot;&gt;&lt;span&gt;이 상태에서 만약 두 노드 중 하나라도 다운되거나 네트워크 통신이 끊기면, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;남은 노드 혼자서는 과반수 (총 투표수 2의 과반수는 2)를 확보할 수가 없게 되므로, 클러스터 전체가 오프라인이 되어 버린다.&lt;/b&gt;&lt;/span&gt; 즉 기껏 Failover Cluster를 구성해 놓고도 HA가 보장되지 않는 것이다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span&gt;위와 같은 문제를 해결하기 위해, &lt;b&gt;1 투표를 행사할 수 있도록 하는 역할을 하는 볼륨을 하나 더 mount&lt;/b&gt; 하여, 해당 LUN에 대해 [Disk Witness] 역할을 수행하도록 하는 것이다. 따라서, 2노드로만 이루어져 있거나, 클러스터의 총 노드 수가 짝수가 되어 과반수가 애매해질 경우, 그만큼을 [Disk Witness] 로 설정하여 HA를 보장할 수 있도록 구성해야 한다.&lt;/span&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span&gt;참고로, &lt;b&gt;Disk Witness 역할을 수행하는 Disk&lt;/b&gt;는 해당 LUN이 정상적으로 동작하기만 한다면 쿼럼상 1투표를 행사할 수 있는 것이기 때문에, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;WSFC 상에서 어느 node에 있던 상관이 없다.&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;b&gt;&lt;span&gt;[Disk witness] 방식의 쿼럼 설정 &lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;b&gt;방법&lt;/b&gt;은 다음과 같다.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1554&quot; data-origin-height=&quot;540&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/w4nLv/btsPFYKZAAz/YMMAizufn1izmEGmtdNB3K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/w4nLv/btsPFYKZAAz/YMMAizufn1izmEGmtdNB3K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/w4nLv/btsPFYKZAAz/YMMAizufn1izmEGmtdNB3K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fw4nLv%2FbtsPFYKZAAz%2FYMMAizufn1izmEGmtdNB3K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1554&quot; height=&quot;540&quot; data-origin-width=&quot;1554&quot; data-origin-height=&quot;540&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span&gt;위와 같이 해당 &lt;b&gt;[Failover Cluster Manager] - [해당 클러스터 이름] - Actions 탭의 [More Actions] - [Configure Cluster Quorum Settings]&lt;/b&gt; 를 클릭하고 [Next] 를 누르면 다음과 같이 나온다.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;669&quot; data-origin-height=&quot;461&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sfyNO/btsPDafxsDn/kdMQRk3JdprB3KvSiLzdV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sfyNO/btsPDafxsDn/kdMQRk3JdprB3KvSiLzdV1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sfyNO/btsPDafxsDn/kdMQRk3JdprB3KvSiLzdV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsfyNO%2FbtsPDafxsDn%2FkdMQRk3JdprB3KvSiLzdV1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;669&quot; height=&quot;461&quot; data-origin-width=&quot;669&quot; data-origin-height=&quot;461&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span&gt;그럼 위와 같이 &lt;b&gt;[Select the quorum witness]&lt;/b&gt; 를 선택하고 Next 를 클릭한다.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;669&quot; data-origin-height=&quot;464&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Blns3/btsPF9yUHiZ/Qha1O91IC5fU7Z2sGZztLK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Blns3/btsPF9yUHiZ/Qha1O91IC5fU7Z2sGZztLK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Blns3/btsPF9yUHiZ/Qha1O91IC5fU7Z2sGZztLK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBlns3%2FbtsPF9yUHiZ%2FQha1O91IC5fU7Z2sGZztLK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;669&quot; height=&quot;464&quot; data-origin-width=&quot;669&quot; data-origin-height=&quot;464&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span&gt;Quorum witness 를 구성하는 방식은 다양하지만, 여기서 우리가 설정할 것은 [Disk Witness in Quorum] 방식이므로,&lt;b&gt; [Configure a disk witness]&lt;/b&gt; 를 선택한다.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;669&quot; data-origin-height=&quot;465&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oVYlt/btsPF2s6eyr/AnrpvhiaKW4T2HAgQIOiD1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oVYlt/btsPF2s6eyr/AnrpvhiaKW4T2HAgQIOiD1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oVYlt/btsPF2s6eyr/AnrpvhiaKW4T2HAgQIOiD1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoVYlt%2FbtsPF2s6eyr%2FAnrpvhiaKW4T2HAgQIOiD1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;669&quot; height=&quot;465&quot; data-origin-width=&quot;669&quot; data-origin-height=&quot;465&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span&gt;필자의 경우, 이미 SQL Server FCI 와 쿼럼을 구성해놓은 상태이기 때문에 저렇게 나타나는데, 아직 쿼럼 구성을 해 두지 않았다면, &lt;b&gt;쿼럼용으로 mount 한 디스크 (SQL Server FCI 그룹에 들어가 있으면 안됨)를 선택&lt;/b&gt;하고 Next 를 클릭한다.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;670&quot; data-origin-height=&quot;462&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/begtsn/btsPEtFogYb/Wazp5EDICTZVcgyMSLpaV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/begtsn/btsPEtFogYb/Wazp5EDICTZVcgyMSLpaV0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/begtsn/btsPEtFogYb/Wazp5EDICTZVcgyMSLpaV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbegtsn%2FbtsPEtFogYb%2FWazp5EDICTZVcgyMSLpaV0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;670&quot; height=&quot;462&quot; data-origin-width=&quot;670&quot; data-origin-height=&quot;462&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span&gt;그럼 위와 같이 &lt;b&gt;[Confirmation]&lt;/b&gt; 을 거쳐, 최종적으로 [Disk witness] 방식의 쿼럼을 설정하게 된다.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span&gt;그럼 결과물로 아래와 같이 해당 disk가 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;[Disk Witness In Quorum]&lt;/b&gt;&lt;/span&gt; 으로 설정되어 있는 지 반드시 확인하자!&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1267&quot; data-origin-height=&quot;749&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bOPIJh/btsPETcxiiA/i2ELjBQq95pgBWyBgNffP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bOPIJh/btsPETcxiiA/i2ELjBQq95pgBWyBgNffP1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bOPIJh/btsPETcxiiA/i2ELjBQq95pgBWyBgNffP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbOPIJh%2FbtsPETcxiiA%2Fi2ELjBQq95pgBWyBgNffP1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1267&quot; height=&quot;749&quot; data-origin-width=&quot;1267&quot; data-origin-height=&quot;749&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;2. Active node에서 SQL Server FCI(Failover Cluster Instance) 최초 구성&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;785&quot; data-origin-height=&quot;573&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cAzabl/btsPF5QLXLq/rBhowmV2okbO6FKB8j1Rf1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cAzabl/btsPF5QLXLq/rBhowmV2okbO6FKB8j1Rf1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cAzabl/btsPF5QLXLq/rBhowmV2okbO6FKB8j1Rf1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcAzabl%2FbtsPF5QLXLq%2FrBhowmV2okbO6FKB8j1Rf1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;785&quot; height=&quot;573&quot; data-origin-width=&quot;785&quot; data-origin-height=&quot;573&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span&gt;위 MSSQL 설치 화면에서&lt;b&gt; [Installation] - [New SQL Server failover cluster installation]&lt;/b&gt; 을 클릭하고 다음을 넘어가다보면, 아래와 같이 &lt;b&gt;Feature Selection&lt;/b&gt; 부분부터 세세히 봐야할 필요가 있다.&lt;/span&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;805&quot; data-origin-height=&quot;608&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/smnmM/btsPFElzuR0/VPiNPYm3mMPmn3CCFC3pJ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/smnmM/btsPFElzuR0/VPiNPYm3mMPmn3CCFC3pJ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/smnmM/btsPFElzuR0/VPiNPYm3mMPmn3CCFC3pJ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsmnmM%2FbtsPFElzuR0%2FVPiNPYm3mMPmn3CCFC3pJ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;805&quot; height=&quot;608&quot; data-origin-width=&quot;805&quot; data-origin-height=&quot;608&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;Instance root directory&lt;/b&gt;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;SQL Server 인스턴스에 종속적인 핵심 파일이 설치되는 최상위 디렉토리&lt;/b&gt;&lt;/span&gt;로, &lt;b&gt;바이너리 파일(실행 파일, DLL 등), DB 엔진, &lt;/b&gt;&lt;/span&gt;&lt;span&gt;&lt;b&gt;인스턴스별 설정 파일, 오류 로그, 트레이스 파일&lt;/b&gt; 등과 함께, &lt;/span&gt;&lt;b&gt;&lt;span&gt;SQL Server Agent, SSAS, SSIS&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;b&gt;, SSRS 인스턴스별로 선택된 기능의 실행에 필요한 파일&lt;/b&gt;들이 포함된다.&lt;/span&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li style=&quot;text-align: left;&quot;&gt;&lt;span&gt;FCI 구성 시에는, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;SQL Server 서비스가 실행될 각 Cluster node 에서의 local drive 하위로 지정이 되어야&lt;/b&gt;&lt;/span&gt; 한다. &lt;br /&gt;공유 스토리지가 아닌 각 node에 독립적으로 SQL Server 실행 파일을 가지고 있어야, failover 시 문제 없이 SQL Server 서비스가 시작될 수 있기 때문이다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;Shared feature directory&lt;/b&gt;&lt;/span&gt;&lt;span&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;서버에 설치된 모든 SQL Server 인스턴스가 공유하는 공통 구성 요소들이 설치되는 디렉토리&lt;/b&gt;&lt;/span&gt;로, &lt;b&gt;Client Tools Connectivity (ODBC 드라이버, OLE DB provider, SQL Native Client 등), SQL Server Browser 서비스, SQL Server Writer 서비스&lt;/b&gt;와 같이 여러 MSSQL 인스턴스에 공통적으로 필요한 서비스 파일들이 설치되는 디렉토리이다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;Shared feature directory (x86&lt;/b&gt;&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;)&lt;/b&gt;&lt;/span&gt;: Shared feature directory와 동일하게 모든 SQL Server 인스턴스가 공유하는 공통 구성 요소들이 저장되는 디렉토리이지만, &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;32비트 버전의 파일&lt;/b&gt;&lt;/span&gt;들을 위한 경로&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span&gt;그럼 아래 화면에서 보면, &lt;b&gt;[SQL Server Network Name]&lt;/b&gt; 을 입력해야 되는 부분이 나오는데, 이거는 실제 Client들이 SQL Server FCI에 연결할 때 사용할 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;SQL Server vIP와 매핑되는 domain name&lt;/b&gt;&lt;/span&gt;으로 신중하게 결정해야 한다.&lt;/span&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span&gt;특히, 기존에 이미 client들에게 공유된 domain name이 있고, 그 시스템을 마이그레이션하는 것이라면, 해당 domain name과 동일하게 설정하는 것이 나중에 client들이 변경사항을 최소화하므로 유리할 것이다.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span&gt;여기에 입력된 domain name은 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;SQL Server FCI가 설치되면서 자동으로&lt;/b&gt;&lt;/span&gt; DNS 서버에 &lt;b&gt;[Cluster Network Configuration]&lt;/b&gt; 에서 지정한 IP와 함께 매핑되도록 등록한다.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;804&quot; data-origin-height=&quot;608&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sCNnt/btsPDoxZ5Dn/dD0vqXETogDfN3Kju17h2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sCNnt/btsPDoxZ5Dn/dD0vqXETogDfN3Kju17h2k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sCNnt/btsPDoxZ5Dn/dD0vqXETogDfN3Kju17h2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsCNnt%2FbtsPDoxZ5Dn%2FdD0vqXETogDfN3Kju17h2k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;804&quot; height=&quot;608&quot; data-origin-width=&quot;804&quot; data-origin-height=&quot;608&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span&gt;위 단계 다음으로 &lt;b&gt;[Cluster Resource Group]&lt;/b&gt; 단계이다. &lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span&gt;아래 &lt;/span&gt;&lt;span&gt;[SQL Server&lt;/span&gt;&lt;span&gt; cluster resource group name&lt;/span&gt;&lt;span&gt;] 에 설정하는 부분이 결국에 WSFC 상에서 아래와 같이 [Roles]의 name으로 설정되게 되므로,&lt;/span&gt;&lt;span&gt; 각 인프라의 convention 에 따라 설정하면 되겠다.&lt;/span&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span&gt;그리고 &lt;b&gt;[Qualified]&lt;/b&gt; 란이 빨간색 네모로 보이며, Message를 보면 자칫 Failover Cluster 를 구성할 수 없는 것처럼 보이는데, 이 상태에서 Next 로 다음 Phase로 넘어가도 SQL S&lt;/span&gt;&lt;span&gt;erver FCI를 구성하는 데에는 큰 문제가 없을 것이다.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span&gt;그 이유는 SQL Server FCI가 구성하는 메커니즘을 이해해야 한다. &lt;b&gt;SQL Server FCI&lt;/b&gt;는 WSFC에 이미 존재하는 리소스 그룹을 사용하는 게 아니라, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;새로운 독립적인 리소스 그룹을 만들고, 그 안에 SQL Server FCI 자신이 필요로 하는 모든 리소스들을 포함하는 방식으로 생성&lt;/b&gt;&lt;/span&gt;이 된다. 따라서 아래의 &lt;b&gt;[Qualified] 란에 빨간색으로 부적격으로 표시되는 이유&lt;/b&gt;는, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;이미 WSFC에 생성되어 있는 Available Storage 그룹과 Cluster Group&lt;/b&gt;&lt;/span&gt;은 신규로 생성하는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;SQL Server FCI에 사용하기에는 부적합하다는 의미로&lt;/b&gt; &lt;/span&gt;받아들이면 된다. 따라서, 강제로 해당 그룹에 SQL Server FCI 리소스들을 넣으면 안된다는 것이다!&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;943&quot; data-origin-height=&quot;723&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cHmPRP/btsPDC3NYYH/8MN99br1alS8bMkNFOPwj0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cHmPRP/btsPDC3NYYH/8MN99br1alS8bMkNFOPwj0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cHmPRP/btsPDC3NYYH/8MN99br1alS8bMkNFOPwj0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcHmPRP%2FbtsPDC3NYYH%2F8MN99br1alS8bMkNFOPwj0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;688&quot; height=&quot;527&quot; data-origin-width=&quot;943&quot; data-origin-height=&quot;723&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1564&quot; data-origin-height=&quot;662&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dnKb5X/btsPFC2mJAt/W498kkKQSf40W9XKrXB4M1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dnKb5X/btsPFC2mJAt/W498kkKQSf40W9XKrXB4M1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dnKb5X/btsPFC2mJAt/W498kkKQSf40W9XKrXB4M1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdnKb5X%2FbtsPFC2mJAt%2FW498kkKQSf40W9XKrXB4M1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;659&quot; height=&quot;280&quot; data-origin-width=&quot;1564&quot; data-origin-height=&quot;662&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span&gt;다음으로는 &lt;b&gt;[Cluster Disk Selection]&lt;/b&gt; 단계이다. 여기서 매우 주의해야할 점이 있다.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span&gt;필자의 경우, SQL Server FCI에서 사용할 데이터,로그,tempdb,백업 파일 등이 저장될 용도의 볼륨 1곳('Cluster Disk 1'), 쿼럼용 볼륨 1곳('Cluster Disk 2')으로 OS상에서 disk를 mount 시켰는데, 이 단계에서 쿼럼용 볼륨을 체크해서는 안된다. &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;여기에서 선택하는 disk는 오로지 SQL Server FCI 에서 사용되는 모든 DB와 관련된 파일(.mdf, .ldf, tempdb, backup files)등이 default 로 저장되는 위치로 설정해야만 올바른 SQL Server FCI를 구성할 수 있다. 쿼럼은 이러한 Disk의 failover 시 vote 역할만 수행하는 witness임을 잊지 말자!&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;807&quot; data-origin-height=&quot;612&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c5m59w/btsPF6Wsoma/0OxZf6ZSqnQIke20i5izZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c5m59w/btsPF6Wsoma/0OxZf6ZSqnQIke20i5izZ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c5m59w/btsPF6Wsoma/0OxZf6ZSqnQIke20i5izZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc5m59w%2FbtsPF6Wsoma%2F0OxZf6ZSqnQIke20i5izZ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;612&quot; height=&quot;465&quot; data-origin-width=&quot;807&quot; data-origin-height=&quot;612&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span&gt;다음으로는 &lt;b&gt;[Cluster Network Configuration]&lt;/b&gt; 단계이며, 여기에서 중요한 포인트는 &lt;b&gt;[Address] 를 설정&lt;/b&gt;하는 부분이다. 이 부분이 이전 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;[Instance Configuration] 에서 설정한 [SQL Server Network Name] 과 매핑될 IP&lt;/b&gt;&lt;/span&gt;이며, &lt;b&gt;SQL Server FCI의 실제 vIP(Client가 접속을 시도하는 서비스 IP)에 해당하는 IP&lt;/b&gt;를 넣어야 하는 것이다.&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;807&quot; data-origin-height=&quot;609&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xMUwW/btsPEvC6HJe/jFa6SIh68EeorzcxYEeZTk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xMUwW/btsPEvC6HJe/jFa6SIh68EeorzcxYEeZTk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xMUwW/btsPEvC6HJe/jFa6SIh68EeorzcxYEeZTk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxMUwW%2FbtsPEvC6HJe%2FjFa6SIh68EeorzcxYEeZTk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;641&quot; height=&quot;484&quot; data-origin-width=&quot;807&quot; data-origin-height=&quot;609&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span&gt;[Server Configuration] 에서는 올바른 SQL Server 인스턴스 및 Agent의 서비스 계정 설정 및 Collation 을 선택하도록 하고, 다음으로 중요하게 볼 단계가 &lt;b&gt;[Database Engine Configuration]&lt;/b&gt; 이다. 아래처럼 보이는 &lt;b&gt;[Data Directories]&lt;/b&gt; 에서 각 항목별로 의미하는 바는 다음과 같다.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;☞ &amp;nbsp;참고로 하기 디렉토리들에 이미 기존 MSSQL 인스턴스가 사용하거나 기존 MSSQL 인스턴스가 사용하던 .mdf, .ndf, .ldf, .bak 파일 등이 남아 있으면, 해당 경로를 지정하여 SQL Server 인스턴스 설치가 불가하므로, 미리 다른 데로 옮겨두든 삭제하든 해야 한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;text-align: left;&quot;&gt;&lt;b&gt;&lt;span&gt;D&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;b&gt;ata root directory&lt;/b&gt;: SQL Server 인스턴스가 설치될 때, &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;시스템 데이터베이스 파일(.mdf, .ldf)의 기본 저장 위치로 사용되는 경로&lt;/b&gt;&lt;/span&gt;로, 일반적으로 이 디렉토리 하위에 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;'MSSQL\Data'와 같은 디렉토리를 추가로 생성&lt;/b&gt;&lt;/span&gt;하여 그 하위에 SQL Server 인스턴스의 시스템 DB(master, model, msdb) 파일이 저장된다.&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;text-align: left;&quot;&gt;&lt;span&gt;여기서 중요한 점은, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;SQL Server FCI의 경우, 시스템 DB가 Failover Cluster의 node간 공유가 되어야 하므로, node의 local drive가 아닌 WSFC에 디스크로 참여하는 공유되는 볼륨의 drive로 지정해야 한다는 것&lt;/b&gt;&lt;/span&gt;이다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li style=&quot;text-align: left;&quot;&gt;&lt;span&gt;&lt;b&gt;User database directory&lt;/b&gt;: 별도로 설정하지 않으면 [Data root directory] 하위에 'MSSQL\Data' 디렉토리 하위로 지정되며, 이 디렉토리는 User DB의 데이터 파일(.mdf)이 저장되는 위치이다. &lt;b&gt;DB 생성 시, 각 DB마다 이 디렉토리와 다른 별도의 디렉토리로 해당 DB 파일의 저장 경로를 설정할 수 있지만, 별도로 설정하지 않게 되면 default로 사용하게 될 디렉토리&lt;/b&gt;이다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;text-align: left;&quot;&gt;&lt;span&gt;&lt;b&gt;User database log directory&lt;/b&gt;: User DB의 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;로그 파일(.ldf) 파일이 기본적으로 저장될 위치&lt;/b&gt;&lt;/span&gt;를 설정하는 것이다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;text-align: left;&quot;&gt;&lt;span&gt;&lt;b&gt;Backup directory&lt;/b&gt;: DB의 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;백업 파일 (.bak, .trn)이 기본적으로 저장될 위치&lt;/b&gt;&lt;/span&gt;를 설정하는 것이다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;808&quot; data-origin-height=&quot;609&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cJImRX/btsPEMEAcRj/4CiEESJ3Tf5RgcV58KSfS0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cJImRX/btsPEMEAcRj/4CiEESJ3Tf5RgcV58KSfS0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cJImRX/btsPEMEAcRj/4CiEESJ3Tf5RgcV58KSfS0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcJImRX%2FbtsPEMEAcRj%2F4CiEESJ3Tf5RgcV58KSfS0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;639&quot; height=&quot;482&quot; data-origin-width=&quot;808&quot; data-origin-height=&quot;609&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span&gt;위와 같은 과정을 거쳐 SQL Server Failover Cluster의 Active Node로 사용할 서버에서 SQL Server FCI 구성을 모두 마치게 된 것이다.&lt;/span&gt;&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;3. SQL server Failover Cluster에 Node 추가&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span&gt;아래와 같이 Standby Node로 이동하여 &lt;b&gt;[SQL Server Installation Center] - [Installation] - [Add node to a SQL Server failover cluster]&lt;/b&gt; 를 선택하여 해당 node를 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;구성된 SQL Server Failover Cluster에 넣어주도록&lt;/b&gt; &lt;/span&gt;하자!&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;786&quot; data-origin-height=&quot;598&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/by3ppg/btsPDqiaFm6/Xrv1Mpa61eovL0vG3sxoak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/by3ppg/btsPDqiaFm6/Xrv1Mpa61eovL0vG3sxoak/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/by3ppg/btsPDqiaFm6/Xrv1Mpa61eovL0vG3sxoak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fby3ppg%2FbtsPDqiaFm6%2FXrv1Mpa61eovL0vG3sxoak%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;671&quot; height=&quot;511&quot; data-origin-width=&quot;786&quot; data-origin-height=&quot;598&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span&gt;몇 번 Next 로 넘어가다 보면, 아래와 같이 &lt;b&gt;[Cluster Node Configuration]&lt;/b&gt; 단계가 나오는데, 여기에서 SQL Server Failover Cluster를 여러개 구성한 경우, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;현재 node가 조인될 클러스터 그룹을 잘 선택하도록&lt;/b&gt;&lt;/span&gt; 하자.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;803&quot; data-origin-height=&quot;610&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bQCYI3/btsPF8fEvVT/d0mvvqwPdYJJcpWJN2tLYk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bQCYI3/btsPF8fEvVT/d0mvvqwPdYJJcpWJN2tLYk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bQCYI3/btsPF8fEvVT/d0mvvqwPdYJJcpWJN2tLYk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbQCYI3%2FbtsPF8fEvVT%2Fd0mvvqwPdYJJcpWJN2tLYk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;803&quot; height=&quot;610&quot; data-origin-width=&quot;803&quot; data-origin-height=&quot;610&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span&gt;그럼 아래와 같이 &lt;b&gt;[Cluster Network Configuration]&lt;/b&gt; 단계가 되는데, 여기에 표기된 IP는 이미 SQL Server FCI 구성 시에 설정한 해당 failover cluster의 SQL Server vIP 를 그대로 가져오므로, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;해당 IP가 맞는지 그리고 체크박스에 체크된 것 확인&lt;/b&gt;&lt;/span&gt;하고 넘어가면 된다.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;806&quot; data-origin-height=&quot;606&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKqL82/btsPDo5MFn8/m09HtVolvpgZVUACX6dEzk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKqL82/btsPDo5MFn8/m09HtVolvpgZVUACX6dEzk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKqL82/btsPDo5MFn8/m09HtVolvpgZVUACX6dEzk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKqL82%2FbtsPDo5MFn8%2Fm09HtVolvpgZVUACX6dEzk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;806&quot; height=&quot;606&quot; data-origin-width=&quot;806&quot; data-origin-height=&quot;606&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;다음 단계로는 &lt;b&gt;[Service Accounts]&lt;/b&gt; 인데, 여기에서 SQL Server FCI 구성 시에 입력한 SQL Server 및 Agent의 서비스 계정 정보를 그대로 가져오므로, 해당 계정의 패스워드를 한번 더 입력한 후 Next로 넘어가야 한다. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;806&quot; data-origin-height=&quot;609&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DmhRQ/btsPDnTlbCC/hM8BYLJ1ndZviVi70tEc6k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DmhRQ/btsPDnTlbCC/hM8BYLJ1ndZviVi70tEc6k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DmhRQ/btsPDnTlbCC/hM8BYLJ1ndZviVi70tEc6k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDmhRQ%2FbtsPDnTlbCC%2FhM8BYLJ1ndZviVi70tEc6k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;806&quot; height=&quot;609&quot; data-origin-width=&quot;806&quot; data-origin-height=&quot;609&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나머지는 Next 를 하다 보면, [Complete] 가 되어 Add Node 까지 끝나게 된다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 한 후, 아래 과정을 통해 ,실제 MSSQL 인스턴스의 failover 가 잘 수행되는 지 확인해 보면 SQL Server Failover Cluster 구성이 끝이 난다!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1267&quot; data-origin-height=&quot;750&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKPjHn/btsPFhc493G/cYOxBYWCgyMURXQdLROsfK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKPjHn/btsPFhc493G/cYOxBYWCgyMURXQdLROsfK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKPjHn/btsPFhc493G/cYOxBYWCgyMURXQdLROsfK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKPjHn%2FbtsPFhc493G%2FcYOxBYWCgyMURXQdLROsfK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1267&quot; height=&quot;750&quot; data-origin-width=&quot;1267&quot; data-origin-height=&quot;750&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>DB/SQL Server (MSSQL)</category>
      <category>MSSQL 2019 Standard</category>
      <category>MSSQL Failover Cluster</category>
      <category>SQL Server 2019</category>
      <category>SQL Server Failover Cluster</category>
      <category>SQL Server Failover Cluster 구성</category>
      <category>SQL Server FCI</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/193</guid>
      <comments>https://co-no.tistory.com/entry/MSSQL-SQL-Server-Failover-Cluster-%EA%B5%AC%EC%84%B1#entry193comment</comments>
      <pubDate>Fri, 1 Aug 2025 19:14:52 +0900</pubDate>
    </item>
    <item>
      <title>[Actions] Github Actions 를 시작하기 전, 기본 개념 익히기</title>
      <link>https://co-no.tistory.com/entry/Actions-Github-Actions-%EB%A5%BC-%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0-%EC%A0%84-%EA%B8%B0%EB%B3%B8-%EA%B0%9C%EB%85%90-%EC%9D%B5%ED%9E%88%EA%B8%B0</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;GitHub Actions 이란?&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;빌드, 테스트, 배포 파이프라인을 자동화&lt;/b&gt;&lt;/span&gt;할 수 있게 해주는 &lt;b&gt;Github&lt;/b&gt;의 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;CI/CD 플랫폼&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;u&gt;Github Repository&lt;/u&gt;로의 모든 Pull Request를 빌드하고 테스트하는 워크플로우를 생성하거나, Merge된 Pull Request를 &lt;u&gt;프로덕션(서버)에 배포하는 등의 작업&lt;/u&gt;을 수행할 수 있게 함&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;단순히 DevOps를 넘어서, &lt;u&gt;Github Repository에서 여러 이벤트가 발생할 때&lt;/u&gt; 워크플로우를 실행하게 한다. 예를 들어, 새로운 Issue를 만든 사람에게 자동으로 적절한 Label을 추가하는 워크플로우를 실행할 수도 있음&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;GitHub은 워크플로우를 실행할 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;Linux, Windows, macOS&lt;/b&gt;&lt;/span&gt; 기반의 VM을 제공하거나, 유저가 관리하는 데이터 센터 또는 클라우드 인프라에서 &lt;i&gt;&lt;b&gt;Self-Hosted Runner&lt;/b&gt;&lt;/i&gt;를 호스팅 할 수 있음&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;Github Actions의 Component&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;448&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bR0juz/btsMsabha02/9WcYKS9wFD9B18rMKzuLv0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bR0juz/btsMsabha02/9WcYKS9wFD9B18rMKzuLv0/img.png&quot; data-alt=&quot;Github Actions의 Component인 'Event', 'Runner', 'Job', 'Step' 의 구조&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bR0juz/btsMsabha02/9WcYKS9wFD9B18rMKzuLv0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbR0juz%2FbtsMsabha02%2F9WcYKS9wFD9B18rMKzuLv0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;448&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;448&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Github Actions의 Component인 'Event', 'Runner', 'Job', 'Step' 의 구조&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;a style=&quot;color: #8a3db6;&quot; href=&quot;https://docs.github.com/ko/actions/about-github-actions/understanding-github-actions#workflows&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Workflow&lt;/a&gt; &lt;/span&gt;(워크플로)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;: Github의 Repository 안에서 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;하나 이상의 Job(작업)&lt;/b&gt;&lt;/span&gt;을 가지는 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;YAML 단위의 자동화 프로세스&lt;/b&gt;&lt;/span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #333333; text-align: left;&quot;&gt;Repo 기준 최상단에서 &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #dddddd; color: #f89009;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;i&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt;.github/workflows&lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt; 디렉토리 하위에 위치하며, &lt;b&gt;.yml&lt;/b&gt; 파일로 존재&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;한 Repo 안&lt;/b&gt;에 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;여러 개의 워크플로(.yml 파일)&lt;/b&gt;&lt;/span&gt;를 가질 수 있고, &lt;u&gt;각각 다른 일련의 작업 수행 가능&lt;/u&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;Github의 Repository의 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;특정한 Event(Push, PR, Issue 등)에 의해 트리거됨&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;수동으로 트리거&lt;/b&gt; 또는 &lt;b&gt;정의된 일정&lt;/b&gt;에 따라 진행 가능&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;한 워크플로 내에서 다른 워크플로 참조&lt;/b&gt;도 가능 (&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;i&gt;&lt;b&gt;Reusing Workflow&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;) &lt;br /&gt;&amp;rarr; &lt;a href=&quot;https://docs.github.com/en/actions/sharing-automations/reusing-workflows&quot;&gt;https://docs.github.com/en/actions/sharing-automations/reusing-workflows&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;워크플로에 대한 더 자세한 정보&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&amp;rarr; &lt;a href=&quot;https://docs.github.com/en/actions/writing-workflows&quot;&gt;https://docs.github.com/en/actions/writing-workflows&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;a style=&quot;color: #8a3db6;&quot; href=&quot;https://docs.github.com/ko/actions/learn-github-actions/understanding-github-actions#events&quot;&gt;Events&lt;/a&gt;&lt;/span&gt; (이벤트)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;: Workflow 실행을 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;트리거하는 Repository의 특정 활동&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;이 &amp;lsquo;활동&amp;rsquo;은 예를 들면, Github 상에서 누군가가 &lt;u&gt;PR(Pull Request) 또는 Issue를 생성&lt;/u&gt;하거나, &lt;u&gt;커밋을 Repo에 Push&lt;/u&gt; 하는 등의 행위를 수행하는 것으로부터 기원한다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;워크플로 안에서 &lt;span style=&quot;background-color: #dddddd; color: #ef5369;&quot;&gt;&lt;i&gt;&lt;b&gt;on&lt;/b&gt;&lt;/i&gt; &lt;/span&gt;구문으로서, 첫 시작에 대한 조건에 해당하는 부분&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;span style=&quot;background-color: #dddddd; color: #ef5369;&quot;&gt; &lt;i&gt;&lt;b&gt;on&lt;/b&gt;&lt;/i&gt; &lt;/span&gt;&amp;nbsp;구문 안에서 &lt;i&gt;&lt;span style=&quot;background-color: #dddddd; color: #ef5369;&quot;&gt;&lt;b&gt;schedule &lt;/b&gt;&lt;/span&gt;&lt;/i&gt;을 설정하여 일정 시간 자체를 트리거로 하는 워크플로 설정 가능 &lt;br /&gt;&amp;rarr; &lt;a href=&quot;https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#schedule&quot;&gt;https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#schedule&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;REST API의 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;POST 요청&lt;/b&gt;&lt;/span&gt;으로 Repo에 이벤트를 가할 수도 있음&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&amp;rarr; &lt;a href=&quot;https://docs.github.com/en/rest/repos/repos?apiVersion=2022-11-28#create-a-repository-dispatch-event&quot;&gt;https://docs.github.com/en/rest/repos/repos?apiVersion=2022-11-28#create-a-repository-dispatch-event&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;워크플로를 트리거하는 데에 사용할 수 있는 &lt;b&gt;전체 이벤트 목록&lt;/b&gt; &lt;br /&gt;&amp;rarr; &lt;a href=&quot;https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows&quot;&gt;https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;a style=&quot;color: #8a3db6;&quot; href=&quot;https://docs.github.com/ko/actions/learn-github-actions/understanding-github-actions#jobs&quot;&gt;Jobs&lt;/a&gt;&lt;/span&gt; (작업)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;: 한 runner 안에서 실행되는 하나의 워크플로 안의 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&amp;lsquo;&lt;i&gt;&lt;b&gt;step&lt;/b&gt;&lt;/i&gt;&amp;rsquo;들의 집합&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;default로 job은 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;서로 간의 종속성이 없어 병렬로 실행&lt;/b&gt;&lt;/span&gt;되나, 서로 간의 종속성을 만들어 &lt;b&gt;직렬로 수행도 가능&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;각 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;i&gt;&lt;b&gt;step&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;은 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;실행될 쉘 스크립트&lt;/b&gt;&lt;/span&gt; 또는 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;실행될 하나의 &lt;i&gt;action&lt;/i&gt;&lt;/b&gt; &lt;b&gt;단위&lt;/b&gt;&lt;/span&gt;를 의미&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;각 &lt;u&gt;step은 순차적으로 실행&lt;/u&gt;되며, 이에 따라 이전 step에 의존하게 됨&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;각 &lt;u&gt;step&lt;/u&gt;은 하나의 runner 안에서 실행되므로, &lt;u&gt;서로 데이터를 공유할 수 있음&lt;/u&gt;. &lt;br /&gt;예를 들면, 애플리케이션을 빌드하는 step 다음에 빌드된 애플리케이션을 테스트하는 step을 가질 수 있음&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;작업에 대한 더 자세한 정보 &lt;br /&gt;&amp;rarr; &lt;a href=&quot;https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does&quot;&gt;https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://docs.github.com/ko/actions/learn-github-actions/understanding-github-actions#actions&quot;&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;Actions&lt;/span&gt;&lt;/a&gt; (액션)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;복잡하지만 자주 반복되는 task를 수행&lt;/b&gt;&lt;/span&gt;하는 Github Actions 에서만 사용 가능한 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;커스텀 애플리케이션&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;워크플로 파일 안에서 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;반복되는 코드의 양을 획기적으로 줄여줌&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;워크플로가 실행되는 Github Repo와 연동되는 &lt;b&gt;Git Repo 를 가져오거나&lt;/b&gt;, 빌드 환경에 맞는 올바른 &lt;b&gt;Tool-Chain을 설정&lt;/b&gt;하거나, 클라우드 제공업체에 대한 &lt;b&gt;authentication&lt;/b&gt; 을 설정 가능&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;Github 마켓플레이스&lt;/b&gt;에서 워크플로에 사용할 액션을 찾을 수 있고, &lt;u&gt;직접 작성도 가능&lt;/u&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;action 생성에 대한 더 자세한 정보 &lt;br /&gt;&amp;rarr; &lt;a href=&quot;https://docs.github.com/en/actions/sharing-automations&quot;&gt;https://docs.github.com/en/actions/sharing-automations&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://docs.github.com/ko/actions/learn-github-actions/understanding-github-actions#runners&quot;&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;Runners&lt;/span&gt;&lt;/a&gt; (러너)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;: 워크플로가 트리거될 때, 해당 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;워크플로를 실행하는 주체가 되는 서버&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;각 러너는 한 번에 하나의 job을 실행할 수 있음&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;Github은 &lt;b&gt;자체적으로&lt;/b&gt; 워크플로를 실행할 수 있는 &lt;b&gt;Ubuntu, Windows, macOS&lt;/b&gt; 러너를 제공&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;각 워크플로 실행마다 깔끔하게 프로비저닝된 새삥(?) VM&lt;/b&gt;&lt;b&gt;에서 실행됨&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;다른 OS 또는 특정 H/W 구성이 필요한 경우, &lt;i&gt;&lt;b&gt;&amp;lsquo;self-hosted&amp;rsquo; runner&lt;/b&gt;&lt;/i&gt; 구성 가능 &lt;br /&gt;&amp;rarr; &lt;a href=&quot;https://docs.github.com/en/actions/hosting-your-own-runners&quot;&gt;https://docs.github.com/en/actions/hosting-your-own-runners&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&amp;lsquo;&lt;b&gt;larger runner&lt;/b&gt;&amp;rsquo; 에 대한 더 자세한 정보 &lt;br /&gt;&amp;rarr; &lt;a href=&quot;https://docs.github.com/en/actions/using-github-hosted-runners/using-larger-runners&quot;&gt;https://docs.github.com/en/actions/using-github-hosted-runners/using-larger-runners&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.github.com/en/actions/about-github-actions/understanding-github-actions&quot;&gt;https://docs.github.com/en/actions/about-github-actions/understanding-github-actions&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1740529731939&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Understanding GitHub Actions - GitHub Docs&quot; data-og-description=&quot;GitHub Actions is a continuous integration and continuous delivery (CI/CD) platform that allows you to automate your build, test, and deployment pipeline. You can create workflows that build and test every pull request to your repository, or deploy merged &quot; data-og-host=&quot;docs.github.com&quot; data-og-source-url=&quot;https://docs.github.com/en/actions/about-github-actions/understanding-github-actions&quot; data-og-url=&quot;https://docs-internal.github.com/en/actions/about-github-actions/understanding-github-actions&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cqmhba/hyYjxFgi9b/bQZjkl9qEUngyiTn2xU87k/img.png?width=1200&amp;amp;height=1200&amp;amp;face=0_0_1200_1200,https://scrap.kakaocdn.net/dn/AFbU6/hyYjjG3w3U/d4xod16cvISkaROySYBU41/img.png?width=1536&amp;amp;height=538&amp;amp;face=0_0_1536_538&quot;&gt;&lt;a href=&quot;https://docs.github.com/en/actions/about-github-actions/understanding-github-actions&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.github.com/en/actions/about-github-actions/understanding-github-actions&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cqmhba/hyYjxFgi9b/bQZjkl9qEUngyiTn2xU87k/img.png?width=1200&amp;amp;height=1200&amp;amp;face=0_0_1200_1200,https://scrap.kakaocdn.net/dn/AFbU6/hyYjjG3w3U/d4xod16cvISkaROySYBU41/img.png?width=1536&amp;amp;height=538&amp;amp;face=0_0_1536_538');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Understanding GitHub Actions - GitHub Docs&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;GitHub Actions is a continuous integration and continuous delivery (CI/CD) platform that allows you to automate your build, test, and deployment pipeline. You can create workflows that build and test every pull request to your repository, or deploy merged&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DevOps/Github</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/192</guid>
      <comments>https://co-no.tistory.com/entry/Actions-Github-Actions-%EB%A5%BC-%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0-%EC%A0%84-%EA%B8%B0%EB%B3%B8-%EA%B0%9C%EB%85%90-%EC%9D%B5%ED%9E%88%EA%B8%B0#entry192comment</comments>
      <pubDate>Sat, 22 Feb 2025 09:00:10 +0900</pubDate>
    </item>
    <item>
      <title>[MSSQL] 모든 유저 데이터베이스의 파일 사이즈 기록하는 Agent Job 만들기</title>
      <link>https://co-no.tistory.com/entry/MSSQL-%EB%AA%A8%EB%93%A0-%EC%9C%A0%EC%A0%80-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4%EC%9D%98-%ED%8C%8C%EC%9D%BC-%EC%82%AC%EC%9D%B4%EC%A6%88-%EA%B8%B0%EB%A1%9D%ED%95%98%EB%8A%94-Agent-Job-%EB%A7%8C%EB%93%A4%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;DB 마이그레이션이나 다른 유지보수성 작업을 할 때,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DB에서의 데이터 사용량이 날마다 얼마나 늘어나는 지 기록해 둘 필요가 있을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;물론, 요즘엔 &lt;b&gt;모니터링 Tool&lt;/b&gt; 이 너무나 잘 나와서 이런 프로시저나 Agent Job 을 굳이 생성해야 하나 싶지만,&amp;nbsp;&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;그런 모니터링 Tool 도입이나 사용이 어려운 상황이 있을 수 있으므로, &lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SQL Server 상에서 아래와 같이 &lt;b&gt;관리용 테이블과 프로시저를 생성&lt;/b&gt;하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;SQL Server Agent Job 을 활용&lt;/b&gt;하여 해당 DB의 사이즈들을 기록하는 방법에 대해 알아보자.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;1. 파일 사이즈 기록해 둘 테이블 [DBFileSizesLog] 생성&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1718686759776&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- 여러 관리 작업과 관련된 데이터가 저장되는 곳인 [msdb]에 테이블을 만들기로 했다.
USE [msdb];
GO

/* 각 DB들의 .mdf, .ldf 파일 사이즈를 기록해 둘 테이블 [DBFileSizesLog] 생성 */
CREATE TABLE DBFileSizesLog (
	[Log_Date] DATETIME DEFAULT GETDATE(),
	[DB_Name] NVARCHAR(50),
	[Logical_File_Name] NVARCHAR(50),
	[File_Storage_Path] NVARCHAR(200),
	[Current_File_Size_MB] DECIMAL(18,4),
	[Used_Space_MB] DECIMAL(18,4),
	[Free_Space_MB] DECIMAL(18,4),
	[Incremental_Usage_Daily_MB] DECIMAL(18,4)
);
GO&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필자가 생성할 테이블 내의 컬럼 설명은 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;Log_Date: DB 사이즈를 확인하는 쿼리를 수행한 후, INSERT INTO가 되는 순간에 시간이 기록되는 컬럼&lt;/li&gt;
&lt;li&gt;DB_Name: DB의 이름&lt;/li&gt;
&lt;li&gt;Logical_File_Name: DB의 Logical Name&lt;/li&gt;
&lt;li&gt;File_Storage_Path: 해당 DB의 파일이 저장되는 OS상 디스크 경로&lt;/li&gt;
&lt;li&gt;Current_File_Size_MB: 현재 DB가 디스크 상에서 점유 중인 파일의 사이즈&lt;/li&gt;
&lt;li&gt;Used_Space_MB: 디스크 상 점유 중인 파일의 사이즈 중에서 실제로 데이터가 사용 중인 사이즈&lt;/li&gt;
&lt;li&gt;Free_Space_MB: [Current_File_Size_MB] - [Used_Space_MB]&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Incremental_Usage_Daily_MB: 해당 DB의 (하루 전[Used_Space_MB]) - (오늘 확인된 [Used_Space_MB])&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1-1. [DBFileSizesLog] 테이블의 사이즈 측정&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;데이터베이스의 파일 사이즈를 기록하는 테이블 자체 사이즈가 크다면, 배보다 배꼽이 더 커질 수 있으므로,&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이 로깅을 위한 테이블의 사이즈가 얼마나 되는 지 가늠해보자.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;Log_Date&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;(DATETIME): 8 bytes&lt;/li&gt;
&lt;li&gt;&lt;b&gt;DB_Name&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;(NVARCHAR(50)): (최대 50 characters) * (2 bytes per character) = 100 bytes&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Logical_File_Name&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;(NVARCHAR(50)) : (최대 50 characters) * (2 bytes per character) = 100 bytes&lt;/li&gt;
&lt;li&gt;&lt;b&gt;File_Storage_Path&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;(NVARCHAR(20)) : (최대 200 characters) * (2 bytes per character) = 400 bytes&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Current_File_Size_MB&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;(DECIMAL(18,4)): 9 bytes&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Used_Space_MB&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;(DECIMAL(18,4)) : 9 bytes&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Free_Space_MB&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;(DECIMAL(18,4)) : 9 bytes&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Incremental_Usage_Daily_MB&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;(DECIMAL(18,4)) : 9 bytes&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;위 컬럼들의 사이즈를 모두 더하면, 한 Row의 최대 사이즈는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;644 bytes&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;가 된다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;유저 데이터베이스가 대충 10개 정도 있다고 하고, 각 DB당 .mdf 파일 1개, .ndf 파일 10개, .ldf 파일 1개로 가정한다면,&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;10 * (1+10+1) * 644 bytes&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;= 77,280 bytes =&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;75.47 KB&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;가 된다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;하루에 1번씩 위 프로시저를 수행하고 이 데이터들의 보관 주기를&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;2년&lt;/b&gt;으로 잡으면,&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;75.47 KB * 730&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;= 55,092 KB =&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;53 MB&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;정도 되므로, 사이즈를 그리 많이 차지하지 않는다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;하루에 1시간씩, 총 24번을 로깅&lt;/b&gt;한다고 하여도,&amp;nbsp;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;1&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;GB 를 조금 넘는 정도&lt;/b&gt;&lt;/span&gt;이다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;용량을 걱정하고 해당 테이블의 데이터를 주기적으로 삭제할 필요는 없을 듯 하다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;2. SQL Server Agnet Job으로 수행할 프로시저 생성&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 쿼리를 먼저 수행하여, 프로시저 안에 있는 @sql 구문이 제대로 동작하는 지부터 확인해 보자!&lt;/p&gt;
&lt;pre id=&quot;code_1718690447303&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt; USE [사이즈 측정할 DB Name];
 
INSERT INTO [msdb].[dbo].[DBFileSizesLog] (
    [Log_Date], 
    [DB_Name], 
    [Logical_File_Name], 
    [File_Storage_Path],
    [Current_File_Size_MB], 
    [Used_Space_MB], 
    [Free_Space_MB],
    [Incremental_Usage_Daily_MB]
)
SELECT 
	[Log_Date] = GETDATE(), 
	[DB_Name] = DB_NAME(), 
	[Logical_File_Name] = name,
	[File_Storage_Path] = physical_name,
	[Current_File_Size_MB] = size / 128.0, 
	[Used_Space_MB] = CAST(FILEPROPERTY(name, 'SpaceUsed') AS INT) / 128.0, 
	[Free_Space_MB] = size / 128.0 - CAST(FILEPROPERTY(name, 'SpaceUsed') AS INT) / 128.0,
	[Incremental_Usage_Daily_MB] = COALESCE(
		(CAST(FILEPROPERTY(name, 'SpaceUsed') AS INT) / 128.0) - (
			SELECT TOP 1 [Used_Space_MB]
			FROM [msdb].[dbo].[DBFileSizesLog]
			WHERE [DB_Name] = DB_NAME() AND [Logical_File_Name] = name
			ORDER BY [Log_Date] DESC
		),
		0
	)
FROM [sys].[database_files]
WHERE type IN (0, 1);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 쿼리가 제대로 동작한다면, 아래 쿼리로 생성되는 프로시저도 잘 동작할 것이다.&lt;/p&gt;
&lt;pre id=&quot;code_1718689336837&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* SQL Server Agent Job 으로 수행할 프로시저 생성 */
CREATE PROCEDURE USP_Logging_DB_Sizes
AS
BEGIN

	DECLARE @dbName NVARCHAR(128);
	DECLARE @sql	NVARCHAR(MAX);

	-- Cursor to loop through all database
	DECLARE db_cursor CURSOR FOR
	SELECT name
	FROM sys.databases
	WHERE state_desc = 'ONLINE'
	AND name NOT IN ('master', 'model', 'msdb', 'tempdb');

	OPEN db_cursor;
	FETCH NEXT FROM db_cursor INTO @dbName;

	WHILE @@FETCH_STATUS = 0
	BEGIN
		-- Dynamic SQL to switch to the target database and collect file size information
		SET @sql = '
            USE ' + QUOTENAME(@dbName) + ';
			INSERT INTO [msdb].[dbo].[DBFileSizesLog] (
				[Log_Date], 
				[DB_Name], 
				[Logical_File_Name], 
				[File_Storage_Path],
				[Current_File_Size_MB], 
				[Used_Space_MB], 
				[Free_Space_MB],
				[Incremental_Usage_Daily_MB]
			)
			SELECT 
				[Log_Date] = GETDATE(), 
				[DB_Name] = DB_NAME(), 
				[Logical_File_Name] = name,
				[File_Storage_Path] = physical_name,
				[Current_File_Size_MB] = size / 128.0, 
				[Used_Space_MB] = CAST(FILEPROPERTY(name, ''SpaceUsed'') AS INT) / 128.0, 
				[Free_Space_MB] = size / 128.0 - CAST(FILEPROPERTY(name, ''SpaceUsed'') AS INT) / 128.0,
				[Incremental_Usage_Daily_MB] = COALESCE(
					(CAST(FILEPROPERTY(name, ''SpaceUsed'') AS INT) / 128.0) - (
						SELECT TOP 1 [Used_Space_MB]
						FROM [msdb].[dbo].[DBFileSizesLog]
						WHERE [DB_Name] = DB_NAME() AND [Logical_File_Name] = name
						ORDER BY [Log_Date] DESC
						),
					0
				)
			FROM [sys].[database_files]
			WHERE type IN (0, 1);
        ';

		-- Execute the dynamic SQL
		EXEC sp_executesql @sql;

		FETCH NEXT FROM db_cursor INTO @dbName;
	END;

	CLOSE db_cursor;
	DEALLOCATE db_cursor;
END;&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;3. SQL Server Agent Job 등록&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 작성한 프로시저를 SQL Server Agent Job 으로서 주기적으로 수행하도록 만들자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Agent Job 생성은 아래와 같이 SSMS에서 GUI로 하도록 하자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;335&quot; data-origin-height=&quot;572&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJcJDb/btsH2JvB8NU/mn6uqMuUVmSNOIAIKocZT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJcJDb/btsH2JvB8NU/mn6uqMuUVmSNOIAIKocZT1/img.png&quot; data-alt=&quot;[SQL Server 에이전트] - [작업] - 마우스 우클릭하여 [새 작업]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJcJDb/btsH2JvB8NU/mn6uqMuUVmSNOIAIKocZT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJcJDb%2FbtsH2JvB8NU%2Fmn6uqMuUVmSNOIAIKocZT1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;335&quot; height=&quot;572&quot; data-origin-width=&quot;335&quot; data-origin-height=&quot;572&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[SQL Server 에이전트] - [작업] - 마우스 우클릭하여 [새 작업]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새로운 Agent Job 을 생성하는 창이 아래와 같이 나타났다면, 알아볼 수 있도록 적절한 Job 의 이름을 지어주도록 하자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;772&quot; data-origin-height=&quot;611&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EWLCE/btsH17RfM4U/kEyKQaCnPcIITEr05GMRSk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EWLCE/btsH17RfM4U/kEyKQaCnPcIITEr05GMRSk/img.png&quot; data-alt=&quot;[새 작업] 창에서 [일반] 탭 입력&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EWLCE/btsH17RfM4U/kEyKQaCnPcIITEr05GMRSk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEWLCE%2FbtsH17RfM4U%2FkEyKQaCnPcIITEr05GMRSk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;772&quot; height=&quot;611&quot; data-origin-width=&quot;772&quot; data-origin-height=&quot;611&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[새 작업] 창에서 [일반] 탭 입력&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 [단계] 에서 새로운 [작업]을 만들며, 여기에서도 해당 [단계] 를 알아보기 쉽도록 &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;'Run Procedures'&lt;/b&gt; &lt;/span&gt;와 같이 지어준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 가장 중요한 실제 프로시저를 실행하는 쿼리를 아래와 같이 작성해 준다. 위에서 우리가 만든 프로시저 이름을 호출하여 수행해 주어야 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1718692595212&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;EXEC [msdb].[dbo].[USP_Logging_DB_Sizes]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;775&quot; data-origin-height=&quot;611&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFtnJB/btsH2F7MOEV/xlGArSgDMMPJU4npWAIyKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFtnJB/btsH2F7MOEV/xlGArSgDMMPJU4npWAIyKK/img.png&quot; data-alt=&quot;[새 작업] 창에서의 [단계] - [새로 만들기] - [일반] 창 작성&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFtnJB/btsH2F7MOEV/xlGArSgDMMPJU4npWAIyKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFtnJB%2FbtsH2F7MOEV%2FxlGArSgDMMPJU4npWAIyKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;775&quot; height=&quot;611&quot; data-origin-width=&quot;775&quot; data-origin-height=&quot;611&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[새 작업] 창에서의 [단계] - [새로 만들기] - [일반] 창 작성&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 다음과 같이 &lt;b&gt;[작업 일정]&lt;/b&gt;에 대한 이름, 해당 agent job 이 어느 빈도로, 매번 몇시에, 몇 번이나 반복할 지 등을 다음과 같이 설정해 준다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;772&quot; data-origin-height=&quot;610&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ytrKd/btsH4FryNqh/NHkHYPzY4x3lzht8rrzTLK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ytrKd/btsH4FryNqh/NHkHYPzY4x3lzht8rrzTLK/img.png&quot; data-alt=&quot;[새 작업] 창의 [일정] - [새로 만들기] - [새 작업 일정] 창 작성&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ytrKd/btsH4FryNqh/NHkHYPzY4x3lzht8rrzTLK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FytrKd%2FbtsH4FryNqh%2FNHkHYPzY4x3lzht8rrzTLK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;772&quot; height=&quot;610&quot; data-origin-width=&quot;772&quot; data-origin-height=&quot;610&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[새 작업] 창의 [일정] - [새로 만들기] - [새 작업 일정] 창 작성&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 [새 작업] 창의 [확인]을 눌러주면, 당신이 지정한 Job 이름으로 새로운 SQL Server Agent Job 이 생성된 것을 확인할 수 있을 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Agent Job 생성을 완료했다면, 아래 그림처럼 반드시 해당 Job 을 한번 실행시켜 보도록 하자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1907&quot; data-origin-height=&quot;1085&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgQlCZ/btsH4quGTVH/WsJKEz25smgsmrCKJPVOQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgQlCZ/btsH4quGTVH/WsJKEz25smgsmrCKJPVOQ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgQlCZ/btsH4quGTVH/WsJKEz25smgsmrCKJPVOQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgQlCZ%2FbtsH4quGTVH%2FWsJKEz25smgsmrCKJPVOQ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1907&quot; height=&quot;1085&quot; data-origin-width=&quot;1907&quot; data-origin-height=&quot;1085&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 Agent Job이 별다른 에러 로그 없이 잘 실행이 되었다면, DB 사이즈를 로깅하는 위 과정을 모두 잘 수행한 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼, &lt;b&gt;다음 날에 DB 사이즈가 얼마나 변화했는 지 확인&lt;/b&gt;해보고, DB 사이즈의 추이를 파악해 보도록 하자!&lt;/p&gt;</description>
      <category>DB/SQL Server (MSSQL)</category>
      <category>sql server daily db file size</category>
      <category>sql server daily ldf size</category>
      <category>sql server daily mdf size</category>
      <category>sql server db size</category>
      <category>sql server db size agent job</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/189</guid>
      <comments>https://co-no.tistory.com/entry/MSSQL-%EB%AA%A8%EB%93%A0-%EC%9C%A0%EC%A0%80-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4%EC%9D%98-%ED%8C%8C%EC%9D%BC-%EC%82%AC%EC%9D%B4%EC%A6%88-%EA%B8%B0%EB%A1%9D%ED%95%98%EB%8A%94-Agent-Job-%EB%A7%8C%EB%93%A4%EA%B8%B0#entry189comment</comments>
      <pubDate>Fri, 21 Jun 2024 08:23:38 +0900</pubDate>
    </item>
    <item>
      <title>[Linux] nohup 로그를 주기적으로 rotation 및 삭제하는 방법</title>
      <link>https://co-no.tistory.com/entry/Linux-nohup-%EB%A1%9C%EA%B7%B8%EB%A5%BC-%EC%A3%BC%EA%B8%B0%EC%A0%81%EC%9C%BC%EB%A1%9C-rotation-%EB%B0%8F-%EC%82%AD%EC%A0%9C%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;WAS(JBoss)의 nohup 로그가 rotate되지 않고 기하급수적으로 쌓인 특정 서버를 발견하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 기회에 nohup 로그를 일 단위로 rotation 하고, 90일 지난 로그는 삭제하도록 설정하는 방법에 대해 정리해 보고자 한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;1. '&lt;span style=&quot;color: #409d00;&quot;&gt;log_management.sh&lt;/span&gt;' 쉘 스크립트 작성&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1716274984307&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#!/bin/bash

JVM_NAME=&quot;$1&quot;

LOG_FILE=&quot;/JVM_PATH/${JVM_NAME}/log/nohup/${JVM_NAME}.out&quot;
DATE=$(date +%y%m%d_%H%M%S)
ROTATED_FILE=&quot;/JVM_PATH/${JVM_NAME}/log/nohup/${JVM_NAME}.out.${DATE}&quot;


log_rotation() {

    if [[ -s $LOG_FILE ]]; then
        cp &quot;${LOG_FILE}&quot; &quot;${ROTATED_FILE}&quot;
        echo &quot;logfile backup completed!!! cp ${LOG_FILE} ${ROTATED_FILE}&quot;
        cat /dev/null &amp;gt; &quot;${LOG_FILE}&quot;
        
        chown {JBoss Service 계정}:{JBoss Service 그룹} ${ROTATED_FILE}
    else
        echo &quot;There aren't any logs in ${LOG_FILE}&quot;
    fi

    echo &quot;*******************************************************&quot;
}

log_delete() {
    find &quot;/JVM_PATH/${JVM_NAME}/log/nohup/&quot; -mtime +90 -name '*.out.*' | xargs rm
}

log_rotation
log_delete&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;nohup log의 rotation하는 로직은 간단하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재까지 쌓인 nohup log 파일을 쉘 스크립트가 수행되는 시점이 들어간 파일명으로 &lt;b&gt;복사&lt;/b&gt;한 후,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;현재 쌓이고 있는 nohup log 파일은 아무 내용이 없도록&lt;/b&gt;&lt;/span&gt; 만드는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 간단한 로직이므로, 이 포스팅에서는 &lt;u&gt;현재까지 쌓인 모든 nohup log를 날짜별로 파싱하여 해당 날짜별로 로그 파일을 따로 분리하는 것은 아님&lt;/u&gt;을 유의하자!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 구문들을 간략히 설명해 보자면 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;JVM_NAME=&quot;&lt;span style=&quot;color: #8a3db6;&quot;&gt;$1&lt;/span&gt;&quot;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;'&lt;b&gt;log_management.sh&lt;/b&gt;' 쉘 스크립트를 실행할 때, &lt;b&gt;argument&lt;/b&gt;로 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;JVM Name&lt;/b&gt;&lt;/span&gt;을 넣어 특정 JVM의 nohup log 파일만 rotation 및 삭제하도록 구현하였다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;LOG_FILE=&quot;&lt;span style=&quot;color: #409d00;&quot;&gt;/JVM_PATH/&lt;/span&gt;${JVM_NAME}&lt;span style=&quot;color: #409d00;&quot;&gt;/log/nohup/&lt;/span&gt;${JVM_NAME}&lt;span style=&quot;color: #409d00;&quot;&gt;.out&lt;/span&gt;&quot;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;nohup&lt;b&gt; log 파일이 쌓이는 절대 경로&lt;/b&gt;를 넣은 변수이다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;DATE=$(&lt;span style=&quot;color: #8a3db6;&quot;&gt;date&amp;nbsp;+&lt;span style=&quot;color: #409d00;&quot;&gt;%y%m%d_%H%M%S&lt;/span&gt;&lt;/span&gt;)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;b&gt;쉘 스크립트를 수행하는 시점&lt;/b&gt;의 시간을 &lt;span style=&quot;color: #409d00;&quot;&gt;'&lt;b&gt;20240521_160125&lt;/b&gt;&lt;/span&gt;' 와 같은 형태로 넣는 변수이다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;ROTATED_FILE=&quot;&lt;span style=&quot;color: #409d00;&quot;&gt;/JVM_PATH/&lt;/span&gt;${JVM_NAME}&lt;span style=&quot;color: #409d00;&quot;&gt;/log/nohup/&lt;/span&gt;${JVM_NAME}&lt;span style=&quot;color: #409d00;&quot;&gt;.out.&lt;/span&gt;${DATE}&quot;&lt;/b&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;nohup log 파일이&lt;b&gt; rotation 하여 복사될 log 파일의 절대 경로&lt;/b&gt;를 넣은 변수이다.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;cat&amp;nbsp;/dev/null&amp;nbsp;&amp;gt;&amp;nbsp;&quot;${LOG_FILE}&quot;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;b&gt;현재 쌓이고 있는 nohup log 파일을 비우는 명령어&lt;/b&gt;이다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;chown&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color: #409d00;&quot;&gt;{JBoss&amp;nbsp;Service&amp;nbsp;계정}:{JBoss&amp;nbsp;Service&amp;nbsp;그룹}&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color: #8a3db6;&quot;&gt;${ROTATED_FILE}&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;rotate된 &lt;b&gt;로그 파일의 소유권&lt;/b&gt;을&lt;b&gt; Jboss 서비스 계정 및 그룹에게 넘겨,&lt;/b&gt; 추후 JBoss start,stop 시 에러가 생기지 않도록 한다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;find&amp;nbsp;&quot;&lt;span style=&quot;color: #409d00;&quot;&gt;/JVM_PATH/&lt;/span&gt;${JVM_NAME}&lt;span style=&quot;color: #409d00;&quot;&gt;/log/nohup/&lt;/span&gt;&quot;&amp;nbsp;&lt;span style=&quot;color: #8a3db6;&quot;&gt;-mtime&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color: #409d00;&quot;&gt;+90&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color: #8a3db6;&quot;&gt;-name&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color: #409d00;&quot;&gt;'*.out.*'&lt;/span&gt;&amp;nbsp;|&amp;nbsp;xargs&amp;nbsp;rm&lt;br /&gt;&lt;/b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;nohup log가 쌓이는 경로에서&lt;b&gt; 파일명에 .out이 들어가는 모든 파일&lt;/b&gt;들 중 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;파일&lt;/b&gt; &lt;b&gt;수정&lt;/b&gt;&lt;b&gt;&amp;nbsp;timestamp가 90일 이상이 된 파일들&lt;/b&gt;&lt;/span&gt;을 삭제하도록 하는 명령어이다.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(번외) 로그 파일들을 gzip 으로 압축하는 방법&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;아래 쉘 스크립트를 추가하면, 현재 쓰여지고 있는 로그를 제외한 nohup log, &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;gclog,&lt;span&gt; &lt;/span&gt;&lt;/span&gt;server.log (Jboss log) 의 모든 로그들을 gzip으로 압축시킬 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1718182113953&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;find &quot;로그파일의 상위 디렉토리&quot; ! -name '*.gz' \( -name '*.out.*' -o -name '*.hprof' -o -name 'gc*.log' -o -name '*.log.*' \) -exec gzip {} \;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;2. 쉘 스크립트를 주기적으로 실행하도록 설정 - &lt;span style=&quot;color: #006dd7;&quot;&gt;crond&lt;/span&gt; 이용&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2.1. 현재 등록된 cron job 확인&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1716275992409&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;crontab -l&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 명령어를 수행하여, 현재 crond 로 어떤 job들이 수행되고 있는 지 확인해보자!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2.2. crontab에 'log_management.sh' 를 실행하도록 설정&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1716276280893&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# cron job 을 특정 주기로 등록하는 editor를 연다.
crontab -e

# 아래 내용을 넣고 저장
# minute hour day_of_month month weekday command
# 아래 문구는 매일 23시 59분으로 설정하여, 매일 nohup log가 rotation 및 삭제되도록 설정하는 것이다.
# 쉘 스크립트를 실행할 때, 마지막에 JVM Name에 해당하는 argument를 넣는 것을 잊지 말자!
59 23 * * * /PATH/log_management.sh JVM_NAME&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 crontab 내용을 설정하면 되는데, 해당 쉘 스크립트가 잘 동작하는 지 &lt;u&gt;23시 59분까지 기다릴 수 없다면,&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 방법으로 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;지금부터 매 분마다 수행되도록 하여 테스트&lt;/b&gt;&lt;/span&gt; 해보도록 하자!&lt;/p&gt;
&lt;pre id=&quot;code_1716276373260&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 테스트용 crontab 내용
* * * * * /PATH/log_management.sh JVM_NAME&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2.3. cron 데몬 재시작 (생략 가능)&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;crontab -e 명령어로 crontab 에디터를 연 후, 알맞게 설정하여 저장하였다면,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;해당 서버 내의 cron 데몬이 특이하게(?) 설정되어 있지 않다면, 특정 시간마다 crontab 내용을 읽어들여 자동으로 스케줄링을 하게 된다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 적용되었는 지 확실치 않아 찝찝하다면, 아래 명령어를 수행하여&lt;b&gt; cron 데몬을 재시작&lt;/b&gt; 하도록 하자.&lt;/p&gt;
&lt;pre id=&quot;code_1716276510790&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# cron 데몬 재시작
systemctl restart crond.service

# cron 데몬 서비스 상태 확인
systemctl status crond.service&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 과정을 모두 마쳤다면, 다음날에 반드시 nohup log의 rotation 과 삭제가 제대로 수행되었는 지 확인해보도록 하자!&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://green-joo.tistory.com/26&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://green-joo.tistory.com/26&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1716274706030&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;nohup 사용법과 nohup.out 파일 명 변경, 로그 없이, 날짜 별로 rotation 하는 방법 ( Linux )&quot; data-og-description=&quot;안녕하세요. 그린주입니다 ๑'ٮ'๑ 오늘도 힘차게 시작해보겠습니다! 개요 이번 글에서는 nohup 사용법과 nohup.out 로그 관련 설정, 프로세스를 종료하는 방법을 공유하고자 합니다. 목차 nohup 설명&quot; data-og-host=&quot;green-joo.tistory.com&quot; data-og-source-url=&quot;https://green-joo.tistory.com/26&quot; data-og-url=&quot;https://green-joo.tistory.com/26&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/Btx9T/hyV9VAwycy/KJPPceb07tLv9MpFFJNh80/img.png?width=564&amp;amp;height=564&amp;amp;face=0_0_564_564,https://scrap.kakaocdn.net/dn/I3ziy/hyV92zEO8M/MBPNCbQpzMaKlKSXfNK7P1/img.png?width=564&amp;amp;height=564&amp;amp;face=0_0_564_564&quot;&gt;&lt;a href=&quot;https://green-joo.tistory.com/26&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://green-joo.tistory.com/26&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/Btx9T/hyV9VAwycy/KJPPceb07tLv9MpFFJNh80/img.png?width=564&amp;amp;height=564&amp;amp;face=0_0_564_564,https://scrap.kakaocdn.net/dn/I3ziy/hyV92zEO8M/MBPNCbQpzMaKlKSXfNK7P1/img.png?width=564&amp;amp;height=564&amp;amp;face=0_0_564_564');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;nohup 사용법과 nohup.out 파일 명 변경, 로그 없이, 날짜 별로 rotation 하는 방법 ( Linux )&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;안녕하세요. 그린주입니다 ๑'ٮ'๑ 오늘도 힘차게 시작해보겠습니다! 개요 이번 글에서는 nohup 사용법과 nohup.out 로그 관련 설정, 프로세스를 종료하는 방법을 공유하고자 합니다. 목차 nohup 설명&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;green-joo.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>OS/Linux</category>
      <category>linux nohup log rotate</category>
      <category>linux nohup logrotate</category>
      <category>nohup log rotation</category>
      <category>nohup 로그 용량</category>
      <category>nohup 로그 용량 관리</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/188</guid>
      <comments>https://co-no.tistory.com/entry/Linux-nohup-%EB%A1%9C%EA%B7%B8%EB%A5%BC-%EC%A3%BC%EA%B8%B0%EC%A0%81%EC%9C%BC%EB%A1%9C-rotation-%EB%B0%8F-%EC%82%AD%EC%A0%9C%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95#entry188comment</comments>
      <pubDate>Tue, 21 May 2024 16:29:47 +0900</pubDate>
    </item>
    <item>
      <title>[httpd] https://{IP} 로 URL을 입력받았을 때, https://{domain name}으로 리다이렉션 시키는 방법</title>
      <link>https://co-no.tistory.com/entry/httpd-httpsIP-%EB%A1%9C-URL%EC%9D%84-%EC%9E%85%EB%A0%A5%EB%B0%9B%EC%95%98%EC%9D%84-%EB%95%8C-httpsdomain-name%EC%9C%BC%EB%A1%9C-%EB%A6%AC%EB%8B%A4%EC%9D%B4%EB%A0%89%EC%85%98-%EC%8B%9C%ED%82%A4%EB%8A%94-%EB%B0%A9%EB%B2%95</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;사내에 여러 보안 사항을 DEV 및 QA 서버에서 테스트 하기 위해,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 SSL이 적용되지 않은 DEV 및 QA 서버에 SSL을 적용하였는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;https://{IP}&lt;/b&gt; 로 입력하여 해당 서비스에 접근할 경우, 다음과 같이 SSL이 적용되지 않는 문제를 발견하였다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1023&quot; data-origin-height=&quot;544&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bd4Hw6/btsGwCrtsNa/upLs9gk167Nnj5jXMRMwbk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bd4Hw6/btsGwCrtsNa/upLs9gk167Nnj5jXMRMwbk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bd4Hw6/btsGwCrtsNa/upLs9gk167Nnj5jXMRMwbk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbd4Hw6%2FbtsGwCrtsNa%2FupLs9gk167Nnj5jXMRMwbk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1023&quot; height=&quot;544&quot; data-origin-width=&quot;1023&quot; data-origin-height=&quot;544&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;http&lt;/span&gt;://{IP}&lt;/b&gt; -&amp;gt; &lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;https&lt;/span&gt;://{domain name}&lt;/b&gt; 으로 리다이렉션하는 설정은 쉽게 넣었는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;https&lt;/span&gt;://{IP}&lt;/b&gt; -&amp;gt;&lt;b&gt;&lt;span style=&quot;color: #f89009;&quot;&gt; https&lt;/span&gt;://{domain name}&lt;/b&gt; 은 찾는게 쉽지 않았다...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로, &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;http&lt;/span&gt;://{IP}&lt;/b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;-&amp;gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;https&lt;/span&gt;://{domain name}&amp;nbsp;&lt;/b&gt;이 방법은, 다음과 같은 방법으로 진행하였다.&lt;/p&gt;
&lt;pre id=&quot;code_1712821427995&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;VirtualHost *:80&amp;gt;
    RewriteEngine on
    # IP가 123.123.123.123 이라고 가정
    RewriteCond %{HTTP_HOST} ^123\.123\.123\.123$
    RewriteRule (.*) https://service.mydomain.co.kr%{REQUEST_URI}
&amp;lt;/VirtualHost&amp;gt;

&amp;lt;VirtualHost *:80&amp;gt;
    DocumentRoot &quot;${Document_Root_Path}&quot;
    ServerName service.mydomain.co.kr
    ErrorLog &quot;|${HTTPD_HOME}/bin/rotatelogs ${HTTPD_HOME}/logs/site-error_log.%Y%m%d 86400 +540&quot;
    CustomLog &quot;|${HTTPD_HOME}/bin/rotatelogs ${HTTPD_HOME}/logs/site-access_log.%Y%m%d 86400 +540&quot; combined

    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteRule (.*) https://service.mydomain.co.kr%{REQUEST_URI} [L,R=301]

&amp;lt;/VirtualHost&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 사이트를 단순히 접속하는 목적이라면, &lt;b&gt;[고급]&lt;/b&gt; 탭을 눌러 안전하지 않은 연결을 통해 접속이 가능하지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사이트 관리자의 입장에서는 이런식으로 SSL을 우회할 가능성이 있기 때문에, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;https://{IP}&lt;/b&gt;&lt;/span&gt; 로 보내는 요청도 모두 DNS 서버에 등록된 domain name으로, 즉, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;https://{domain name}&lt;/b&gt;&lt;/span&gt; 으로 리다이렉션 시키고 싶어졌다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나와 같은 고민을 한 해외 서버 관리자들이 꽤 있는 것 같은데, 아래 방법이 나의 케이스와 가장 잘 맞아 참고하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://serverfault.com/questions/993925/redirect-ip-address-to-domain-name-on-apache&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://serverfault.com/questions/993925/redirect-ip-address-to-domain-name-on-apache&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1712820364528&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Redirect IP address to domain name on apache&quot; data-og-description=&quot;I am pretty computer savvy, but not with setting up web servers. I have a domain name that has an SSL certificate, so that https://example.org works and http://example.org redirects there. BUT, h...&quot; data-og-host=&quot;serverfault.com&quot; data-og-source-url=&quot;https://serverfault.com/questions/993925/redirect-ip-address-to-domain-name-on-apache&quot; data-og-url=&quot;https://serverfault.com/questions/993925/redirect-ip-address-to-domain-name-on-apache&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/1IWXN/hyVPNPXmVQ/kaQbuVVpGMjsN8VT1eNrnK/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316&quot;&gt;&lt;a href=&quot;https://serverfault.com/questions/993925/redirect-ip-address-to-domain-name-on-apache&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://serverfault.com/questions/993925/redirect-ip-address-to-domain-name-on-apache&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/1IWXN/hyVPNPXmVQ/kaQbuVVpGMjsN8VT1eNrnK/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Redirect IP address to domain name on apache&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;I am pretty computer savvy, but not with setting up web servers. I have a domain name that has an SSL certificate, so that https://example.org works and http://example.org redirects there. BUT, h...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;serverfault.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필자의 경우, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;https://{IP}의 리다이렉션 설정 전&lt;/b&gt;&lt;/span&gt;, 443 포트에 대한 VirtualHost 설정은 다음과 같았다.&lt;/p&gt;
&lt;pre id=&quot;code_1712820667785&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;VirtualHost *:443&amp;gt;
    DocumentRoot ${SITE_DOCUMENT_ROOT_PATH}
    ServerName service.mydomain.co.kr
    
    SSLEngine On
    
    SSLProtocol -all +TLSv1.2 +TLSv1.3
    SSLCipherSuite HIGH:MEDIUM:!SSLv2:!PSK:!SRP:!ADH:!AECDH:!3DES:!RC4

    SSLCertificateFile ${Certificate_Path}
    SSLCertificateKeyFile ${Certificate_Keyfile_Path}

    ErrorLog &quot;|${HTTPD_HOME}/bin/rotatelogs ${HTTPD_HOME}/logs/site-error_log.%Y%m%d 86400 +540&quot;
    CustomLog &quot;|${HTTPD_HOME}/bin/rotatelogs ${HTTPD_HOME}/logs/site-access_log.%Y%m%d 86400 +540&quot; combined

    
    # WebLogic과 연동하기 위한 설정
    &amp;lt;IfModule mod_weblogic.c&amp;gt;
     WebLogicCluster {Server IP}:{Service Port}
     ConnectRetrySecs 2
     ConnectTimeoutSecs 10
     FileCaching OFF
     WLIOTimeoutSecs 18000
     DynamicServerList OFF
     Idempotent OFF
     MatchExpression *
    &amp;lt;/IfModule&amp;gt;
    
&amp;lt;/VirtualHost&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 VirtualHost 설정을 아래와 같이, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;Rewrite 설정을 추가&lt;/b&gt;&lt;/span&gt;하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 주의할 점은, S&lt;b&gt;SL 설정 이전에 Rewrite 관련 설정을 넣고, &lt;span style=&quot;color: #ee2323;&quot;&gt;Rewrite의 조건을 원하는 domain name이 아닌 모든 요청일 경우&lt;/span&gt;, 원하는 domain name으로 무조건 리다이렉션 하도록 설정하는 것&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러면, 원하는 domain name으로 들어온 요청은 조건에 해당하지 않으므로, 자연스레 SSL 설정으로 넘어가게 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1712821078553&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;VirtualHost *:443&amp;gt;
    DocumentRoot ${SITE_DOCUMENT_ROOT_PATH}
    ServerName service.mydomain.co.kr
    
    RewriteEngine On
    RewriteCond %{HTTP_HOST} !^service\.mydomain\.co\.kr$
    RewriteRule ^(.*)$ https://service.mydomain.co.kr$1 [R=permanent,L]
    
    SSLEngine On
    
    SSLProtocol -all +TLSv1.2 +TLSv1.3
    SSLCipherSuite HIGH:MEDIUM:!SSLv2:!PSK:!SRP:!ADH:!AECDH:!3DES:!RC4

    SSLCertificateFile ${Certificate_Path}
    SSLCertificateKeyFile ${Certificate_Keyfile_Path}

    ErrorLog &quot;|${HTTPD_HOME}/bin/rotatelogs ${HTTPD_HOME}/logs/site-error_log.%Y%m%d 86400 +540&quot;
    CustomLog &quot;|${HTTPD_HOME}/bin/rotatelogs ${HTTPD_HOME}/logs/site-access_log.%Y%m%d 86400 +540&quot; combined

    
    # WebLogic과 연동하기 위한 설정
    &amp;lt;IfModule mod_weblogic.c&amp;gt;
     WebLogicCluster {Server IP}:{Service Port}
     ConnectRetrySecs 2
     ConnectTimeoutSecs 10
     FileCaching OFF
     WLIOTimeoutSecs 18000
     DynamicServerList OFF
     Idempotent OFF
     MatchExpression *
    &amp;lt;/IfModule&amp;gt;
    
&amp;lt;/VirtualHost&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이게 정석적인 방법인지는 모르겠으나, 부디 나와 같은 삽질을 다른 사람들은 많이 하지 않도록,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;https://{IP} -&amp;gt; https://{domain name}&lt;/b&gt; 방법을 이렇게 포스팅으로 공유해본다..!&lt;/p&gt;</description>
      <category>Middleware/웹서버</category>
      <category>apache ip redirection</category>
      <category>httpd ip redirection</category>
      <category>https ip redirection</category>
      <category>https ip to https domain name</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/184</guid>
      <comments>https://co-no.tistory.com/entry/httpd-httpsIP-%EB%A1%9C-URL%EC%9D%84-%EC%9E%85%EB%A0%A5%EB%B0%9B%EC%95%98%EC%9D%84-%EB%95%8C-httpsdomain-name%EC%9C%BC%EB%A1%9C-%EB%A6%AC%EB%8B%A4%EC%9D%B4%EB%A0%89%EC%85%98-%EC%8B%9C%ED%82%A4%EB%8A%94-%EB%B0%A9%EB%B2%95#entry184comment</comments>
      <pubDate>Thu, 11 Apr 2024 16:45:24 +0900</pubDate>
    </item>
    <item>
      <title>[MSSQL] SQL Server 점검 시 유용한 쿼리 모음</title>
      <link>https://co-no.tistory.com/entry/MSSQL-SQL-Server-%EC%A0%90%EA%B2%80-%EC%8B%9C-%EC%9C%A0%EC%9A%A9%ED%95%9C-%EC%BF%BC%EB%A6%AC-%EB%AA%A8%EC%9D%8C</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;DBA라고 하기 부끄러운 수준이지만, 그래도 다른 사람보다 DB를 조금 더 자주 접하면서 MSSQL에서 가지고 있으면 유용한 쿼리를 아래에 정리해 본다. 모두 &lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;sysadmin&lt;/b&gt;&lt;/span&gt;의 Server-level role을 가지고 수행하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;아&lt;/b&gt;&lt;b&gt;래 모든 쿼리들이 서버에 부하를 얼마나 유발하는 지 확인해 보지 않았고, 매우 심각한 상황(쿼리 하나가 서버를 죽이든,살리든 하는 상황)에서는 한 번도 사용해보지 않았으므로, 반드시 유의해서 사용해야 한다...!&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;부하를 최소화한다든지, 새로운 쿼리를 알아내게 되면 이 포스팅에 계속 업데이트할 예정이므로,&lt;u&gt; 이 포스팅 내용은 계속 변할 수 있다!&lt;/u&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;1. 현재 MSSQL의 상태 조회 쿼리&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;MSSQL 인스턴스 내 활성화되어 있는 &lt;span style=&quot;color: #8a3db6;&quot;&gt;모든 세션&lt;/span&gt; 정보 확인 - sys.dm_exec_sessions&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;sys.dm_exec_sessions&lt;/b&gt;&lt;/span&gt; 는 SQL Server 인스턴스에서 인증된 세션당 한 행을 반환하도록 하는 DMO(Dynamic Management Objects)이다. 즉 이 DMO를 통해 반환된 행은, SQL Server 인스턴스 내에서 활성화된 모든 세션에 대한 논리적인 정보를 담고 있으며, 이는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;사용자 세션뿐 아니라, SQL Server 자체의 내부 작업, 백그라운드 프로세스 ,시스템 세션 등이 포함될 수 있음&lt;/b&gt;&lt;/span&gt;을 의미한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1745988148316&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT *
FROM sys.dm_exec_sessions
-- WHERE login_name = 'SQL Login Name' -- 현재 SQL Server에 활성화되어 있는 SQL Login name 기준으로 보고 싶을 때&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;MSSQL 인스턴스에 &lt;span style=&quot;color: #8a3db6;&quot;&gt;connect 되어 있는 connection&lt;/span&gt; 정보 확인 - sys.dm_exec_sessions, sys.dm_exec_connections&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;sys.dm_exec_connections&lt;/b&gt;&lt;/span&gt; 는 SQL Server 인스턴스에 establish된 각 connection에 대한 세부 사항을 반환하도록 하는 DMO로, 여기에는 네트워크 프로토콜, Client IP Address, 연결 시간 등의 정보가 포함된다. SQL Server 에 연결된 하나의 세션은 여러 개의 connection을 가질 수 있는 구조이다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1712056186134&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT s.login_time
	, s.host_name
	, c.client_net_address
	, s.session_id
	, s.program_name
	, [DB Name] = db_name(st.dbid)
	, s.login_name
	, s.status
	, [CPU Time used by session (ms)] = s.cpu_time
	, [# of Pages In MEM] = s.memory_usage
	, [Total Scheduled Time (ms)] = s.total_scheduled_time
	, [Since Session established Time (ms)] = s.total_elapsed_time
	, s.last_request_start_time
	, s.last_request_end_time
	, [Physical Reads from Disk (Pages)] = s.reads
	, [Logical Reads from MEM (Pages)] = s.logical_reads
	, s.is_user_process
	, s.transaction_isolation_level
	, [해당 세션에서 현재까지 return된 행 수] = s.row_count
	, [가장 최근 수행한 sql문] = st.text
FROM sys.dm_exec_sessions s
JOIN sys.dm_exec_connections c 
	ON s.session_id = c.session_id
CROSS APPLY sys.dm_exec_sql_text(c.most_recent_sql_handle) st
ORDER BY s.cpu_time DESC, s.reads DESC&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;각 DB별 연결되어 있는 Connection 개수 및 Login 계정 확인&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1712056349185&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT 
    DB_NAME(dbid) as DBName, 
    COUNT(dbid) as NumberOfConnections,
    loginame as LoginName
FROM
    sys.sysprocesses
WHERE 
    dbid &amp;gt; 0
GROUP BY 
    dbid, loginame
;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;SQL Server 인스턴스 내에서 현재 수행되고 있는 쿼리 확인&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1772521265608&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT DISTINCT
    req.session_id,
    req.request_id,  -- (req.session_id, req.request_id) 값이 dm_exec_requests 에서 key 값으로 보고, 병렬 쿼리깢 있을 수 있는 상황 고려하여 request_id 까지 조회
    sqltext.TEXT AS executing_sql,
    req.command,
	req.status,
    req.wait_type,
    req.cpu_time,
    req.total_elapsed_time,
    sess.login_name,
    conn.client_net_address AS client_ip,
    sess.host_name,
    sess.program_name
FROM sys.dm_exec_requests req
INNER JOIN sys.dm_exec_sessions sess ON req.session_id = sess.session_id
INNER JOIN sys.dm_exec_connections conn ON req.session_id = conn.session_id
CROSS APPLY sys.dm_exec_sql_text(req.sql_handle) AS sqltext
WHERE sqltext.TEXT NOT LIKE '%sp_server_diagnostics%'
ORDER BY req.session_id, req.request_id;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Running 상태가 아닌, 문제가 있거나 Blocking 걸려 있는 트랜잭션 조회&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1712056863845&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT req.session_id
	, ses.host_name
	, ses.login_name
	, req.status
	, req.blocking_session_id	-- 이 값이 0이면 다음 중 하나. 1. root blocker / 2. block 되고 있지는 않은 상태
	, req.wait_type
	, SUBSTRING(sql_text.text,req.statement_start_offset/2, 
		(CASE 
			WHEN req.statement_end_offset = -1
			THEN LEN(CONVERT(NVARCHAR(max), sql_text.text)) * 2
			ELSE req.statement_end_offset 
			END - req.statement_start_offset)/2
	) AS [Query_Text] --- statement of batch or proc executing right now
	, DB_NAME(ses.database_id) AS [Current Used DB] -- &amp;lt;&amp;lt;----- 이 부분을 수정했습니다!
	, CAST(DATEDIFF(ss, req.start_time, GETDATE()) AS NVARCHAR)+ N'초' AS [Request 경과시간]
	, object_name(sql_text.objectid) AS [SP명]	-- ad-hoc 또는 prepared SQL statement 라면, Null 로 나옴
	, req.cpu_time AS [CPU_Time (ms단위)]
	, req.total_elapsed_time
	, req.reads
	, req.writes 
	, req.logical_reads 
	, req.scheduler_id
FROM sys.dm_exec_requests AS req WITH (NOLOCK)
INNER JOIN sys.dm_exec_sessions AS ses WITH (NOLOCK) ON req.session_id = ses.session_id
CROSS APPLY sys.dm_exec_sql_text(req.sql_handle) AS sql_text
WHERE req.session_id &amp;gt; 50 
	AND sql_text.text NOT LIKE '%sp_server_diagnostics%'
ORDER BY req.blocking_session_id, req.session_id, req.status, req.cpu_time, req.logical_reads&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;'STATS' 키워드를 넣지 못한 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;Backup 또는 Restore 진행 시, &lt;/span&gt;현재 진행상황 확인&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1712056984160&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT ER.session_id
	, ER.command
	, ER.start_time
	, ER.percent_complete
	, ER.total_elapsed_time
	, ER.status
	, ER.last_wait_type
	, ER.estimated_completion_time /1000/60 AS [남은 시간(분)]	-- ms 단위로 저장되므로 분 단위 표시를 위해 (1000*60)으로 나눠주는 것임
	, EST.text
FROM sys.dm_exec_requests AS ER WITH(NOLOCK)
CROSS APPLY sys.dm_exec_sql_text(ER.sql_handle) AS EST
WHERE ER.command = 'BACKUP DATABASE' 
	OR ER.command = 'RESTORE DATABASE'
	OR ER.command = 'BACKUP LOG'
	AND ER.percent_complete &amp;gt; 0;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;현재 tempdb의 사용량 확인 (Extent 기준으로 표시됨)&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1732867664906&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;USE [tempdb];
DBCC showfilestats&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;현재 tempdb를 사용하고 있는 세션별 각 resource 사용량 확인하는 쿼리&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1712057127460&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT
	es.session_id AS [SESSION ID]
  , DB_NAME(su.database_id) AS [DATABASE Name]
  , es.host_name AS [System Name]
  , es.program_name AS [Program Name]
  , est.text AS [Query_Text]
  , es.login_name AS [USER Name]
  , er.status
  , es.cpu_time AS [CPU TIME (in milisec)]
  , es.total_scheduled_time AS [Total Scheduled TIME (in milisec)]
  , es.total_elapsed_time AS    [Elapsed TIME (in milisec)]
  , (es.memory_usage * 8)      AS [Memory USAGE (in KB)]
  , (su.user_objects_alloc_page_count * 8) AS [SPACE Allocated FOR USER Objects (in KB)]
  , (su.user_objects_dealloc_page_count * 8) AS [SPACE Deallocated FOR USER Objects (in KB)]
  , (su.internal_objects_alloc_page_count * 8) AS [SPACE Allocated FOR Internal Objects (in KB)]
  , (su.internal_objects_dealloc_page_count * 8) AS [SPACE Deallocated FOR Internal Objects (in KB)]
  , CASE is_user_process
		WHEN 1	THEN 'user session'
		WHEN 0  THEN 'system session'
		END AS [SESSION Type]
  , er.row_count AS [ROW COUNT]
FROM 
	sys.dm_db_session_space_usage AS su
INNER JOIN sys.dm_exec_sessions AS es
	ON es.session_id = su.session_id
INNER JOIN sys.dm_exec_requests AS er
	ON er.session_id = es.session_id
CROSS APPLY sys.dm_exec_sql_text(er.sql_handle) AS est
ORDER BY [Total Scheduled TIME (in milisec)] DESC, [Elapsed TIME (in milisec)] DESC&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;최근 쿼리플랜에서 Hash Match, Sort, Spool 연산자로 인해 tempDB spill 가능성 높은 쿼리 찾기&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1748951651081&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT TOP 100
	DB_NAME(qp.dbid) AS database_name
	, qs.total_worker_time / qs.execution_count AS avg_cpu_tme
	, qs.total_logical_reads / qs.execution_count AS avg_reads
	, qs.total_elapsed_time / qs.execution_count AS avg_elapsed_time
	, qs.execution_count
	, qs.creation_time
	, qs.last_execution_time
	, qs.last_rows
	, qs.last_grant_kb
	, qs.last_spills
	, st.text AS query_text
	, qp.query_plan
FROM 
	sys.dm_exec_query_stats qs
CROSS APPLY 
	sys.dm_exec_sql_text(qs.sql_handle) st
CROSS APPLY 
	sys.dm_exec_query_plan(qs.plan_handle) qp
WHERE qp.query_plan.exist('
		declare namespace p=&quot;http://schemas.microsoft.com/sqlserver/2004/07/showplan&quot;;
		//p:RelOp[p:Spool or p:Hash or p:Sort]
		') = 1
ORDER BY last_spills DESC;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;SQL Server Instacne의 Uptime 확인 쿼리&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1712057654551&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;USE master
go
SELECT sqlserver_start_time AS [SQL Server Instance Uptime] 
FROM sys.dm_os_sys_info&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;평균 Blocking 당한 시간이 긴 쿼리 Top100 조회&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;sys.dm_exec_query_stats&lt;/b&gt;&lt;/span&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;SQL Server에서 캐시된 쿼리 계획에 대한 집계 성능 통계를 반환하는 DMV&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;이 DMV에서 반환되는 &lt;b&gt;Row의 유효 기간은 쿼리 플랜 자체와 연결&lt;/b&gt;되어 있다.&lt;br /&gt;따라서, &lt;u&gt;해당 플랜이 캐시에서 제거되면, 이 DMV 결과로도 확인할 수 없다는 점&lt;/u&gt;을 유의하자.&lt;/li&gt;
&lt;li&gt;이 DMV의 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;total_elapsed_time&lt;/b&gt;&lt;/span&gt; 은 &lt;b&gt;해당 플랜의 쿼리 실행이 완료되기까지 소요된 총 경과 시간&lt;/b&gt;을 &lt;span data-token-index=&quot;0&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;[&amp;mu;s](마이크로 초)&lt;/b&gt;&lt;/span&gt; 단위&lt;/span&gt;로 보여준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1712057937338&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;USE [DATABASE_NAME]
SELECT TOP(100)
	[Average Time Blocked (초)] = (total_elapsed_time - total_worker_time) / qs.execution_count / 1000000 -- 초 단위로 보여주기 위해 나눔
	, [Total Time Blocked (초)] = total_elapsed_time - total_worker_time / 1000000 -- 초 단위로 보여주기 위해 나눔
	, [Execution count] = qs.execution_count
	, [Individual Query] = SUBSTRING (qt.text,qs.statement_start_offset/2,
         (CASE WHEN qs.statement_end_offset = -1
            THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2
			ELSE qs.statement_end_offset END - qs.statement_start_offset)/2)
	, [Parent Query] = qt.text
	, [DatabaseName] = DB_NAME(qt.dbid)
  , [마지막 실행 시점] = qs.last_execution_time
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
ORDER BY [Average Time Blocked (초)] DESC, [Execution count] DESC;&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;2. 권한 관리 관련 쿼리 (주로 Audit 또는 보안 상태 점검 시 사용)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Public을 제외한 다른 서버 고정 역할을 가지고 있는 SQL Login의 Role, Default Database 조회&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1712056424566&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT [Login Name] = B.name 
	, [Principal ID] = B.principal_id
	, [Role] = A.name
	, B.type_desc
	, B.default_database_name
FROM sys.server_role_members rm
INNER JOIN sys.server_principals A
	ON A.principal_id = rm.role_principal_id
INNER JOIN sys.server_principals  B 
	ON B.principal_id = rm.member_principal_id
WHERE B.name = '조회를 원하는 SQL Login Name'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;고정 데이터베이스 역할 리스트 조회&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1712056550324&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT DP1.name AS DatabaseRoleName,   
   isnull (DP2.name, 'No members') AS DatabaseUserName   
 FROM sys.database_role_members AS DRM  
 RIGHT OUTER JOIN sys.database_principals AS DP1  
   ON DRM.role_principal_id = DP1.principal_id  
 LEFT OUTER JOIN sys.database_principals AS DP2  
   ON DRM.member_principal_id = DP2.principal_id  
WHERE DP1.type = 'R'
ORDER BY DP1.name;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;특정 유저의 user mapping DB 및 해당 DB에서의 Database-level roles 확인&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1715585257464&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;DECLARE @command nvarchar(4000) 
DECLARE @DBRole TABLE (DBName sysname, UserName sysname, RoleName varchar(255))
SELECT @command = '
USE [?]
SELECT ''?'' AS DB_Name
	, (CASE prin.name
		WHEN ''dbo'' THEN (
			SELECT SUSER_SNAME(owner_sid)
			FROM master.sys.databases
			WHERE name = ''?'')
			ELSE prin.name
			END
		) AS UserName
	, ISNULL(USER_NAME(mem.role_principal_id), '''')  AS AssociatedRole
FROM sys.database_principals prin
LEFT OUTER JOIN sys.database_role_members mem
	ON prin.principal_id = mem.member_principal_id
'

INSERT INTO @DBRole
EXEC sp_MSforeachdb @command 

SELECT * FROM @DBRole t 
WHERE t.UserName LIKE '%특정 유저 네임%'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 쿼리를 수행하면 아래와 같은 결과를 얻을 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;361&quot; data-origin-height=&quot;185&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MulSV/btsHpzFyCql/6nFzgOpPYHndYjkMxtv2w0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MulSV/btsHpzFyCql/6nFzgOpPYHndYjkMxtv2w0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MulSV/btsHpzFyCql/6nFzgOpPYHndYjkMxtv2w0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMulSV%2FbtsHpzFyCql%2F6nFzgOpPYHndYjkMxtv2w0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;361&quot; height=&quot;185&quot; data-origin-width=&quot;361&quot; data-origin-height=&quot;185&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;특정 DB 내에서 특정 사용자가 어떠한 오브젝트들에 대해 어떤 권한들을 가지고 있는 지 확인&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1728888632679&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;USE [Database Name]; -- DB Name

SELECT 
    dp.name AS UserName,
    s.name AS SchemaName,
    o.name AS ObjectName,
    p.permission_name AS PermissionType,
    p.state_desc AS PermissionState
FROM 
    sys.database_permissions p
JOIN 
    sys.objects o ON p.major_id = o.object_id
JOIN 
    sys.schemas s ON o.schema_id = s.schema_id
JOIN 
    sys.database_principals dp ON p.grantee_principal_id = dp.principal_id
WHERE 
    dp.name = 'User Name' -- 특정 사용자명
ORDER BY 
    s.name, o.name, p.permission_name;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;특정 유저가 해당 오브젝트에 대해서 어떤 권한을 가지고 있는 지 확인&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;fn_my_permissions&lt;/b&gt;&lt;/span&gt;의 경우, &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;임시 테이블을 Insert, Delete 하는 과정이 수반&lt;/span&gt;&lt;/b&gt;되므로, Audit Scope에 해당하는 DB에 대해서 사용하는 것에는&lt;u&gt; 각별한 주의&lt;/u&gt;가 필요하다.&lt;/p&gt;
&lt;pre id=&quot;code_1712056722030&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;EXECUTE AS LOGIN = 'LOGIN USER NAME';

SELECT * 
FROM fn_my_permissions('[DATABASE NAME].[SCHEMA NAME].[TABLE | VIEW NAME]', 'OBJECT')
ORDER BY subentity_name, permission_name;

REVERT;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;유저가 생성한 Stored Procedure에 대한 권한에 대해 특정 유저가 어떠한 권한을 가지고 있는 지 확인&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1715832977902&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT
	[SQL Login Name] = USER_NAME(dp.grantee_principal_id)
	, [Permission_State] = dp.state_desc
	, [Permission_Name] = dp.permission_name
	, [Schema_Name] = s.name
	, [Object_Name] = o.name
FROM 
    sys.database_permissions dp
JOIN sys.objects o 
	ON dp.major_id = o.object_id
JOIN sys.schemas s 
	ON o.schema_id = s.schema_id
WHERE 
    dp.grantee_principal_id = USER_ID('%USER_NAME%')
    AND o.type = 'P' -- 'P'는 저장 프로시저를 의미
ORDER BY [Object_Name]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;548&quot; data-origin-height=&quot;196&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1yk9n/btsHrTjSZF3/afIlWpGgKiALvlU7DOtgm1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1yk9n/btsHrTjSZF3/afIlWpGgKiALvlU7DOtgm1/img.png&quot; data-alt=&quot;위 쿼리 수행 결과 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1yk9n/btsHrTjSZF3/afIlWpGgKiALvlU7DOtgm1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1yk9n%2FbtsHrTjSZF3%2FafIlWpGgKiALvlU7DOtgm1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;548&quot; height=&quot;196&quot; data-origin-width=&quot;548&quot; data-origin-height=&quot;196&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;위 쿼리 수행 결과 예시&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;3. Size 또는 Index 관련 쿼리&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;현재 MSSQL 인스턴스 내 모든 DB의 용량 확인&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1712057422873&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;USE master
GO
 
SELECT sys.databases.name
	, [Disk Usage (MB)] = CONVERT(VARCHAR,SUM(CAST(mf.size AS bigint))*8/1024) +' MB'
	, [Disk Usage (GB)] = CONVERT(VARCHAR,SUM(CAST(mf.size AS bigint))*8/1024/1024) +' GB'
FROM sys.databases
JOIN sys.master_files AS mf
	ON sys.databases.database_id = mf.database_id
WHERE sys.databases.name != 'tempdb'	-- sys.master_files 뷰에서의 tempdb 의 사이즈는 initial size를 의미한다. 그러므로 현재 tempdb 사이즈가 아니기 때문에 제외하였다.
GROUP BY sys.databases.name
ORDER BY SUM(CAST(mf.size AS bigint))*8/1024 DESC		-- DB 총 사이즈별로 내림차순 정렬&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;해당 DB의 mdf, ldf 전체 사이즈 및 실제 남은 공간 확인&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1712057459643&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;USE [DB_NAME]
SELECT [DB NAME] = DB_NAME() 
	, [Logical File Name] = name
	, type_desc
	, [Physical File Path] = physical_name
	, [Current File Size (MB)] = size / 128.0
	, [Used Space (MB)] = CAST(FILEPROPERTY(name, 'SpaceUsed') AS INT) / 128.0
	, [Free Space (MB)] = size/128.0 - CAST(FILEPROPERTY(name, 'SpaceUsed') AS INT) / 128.0
	, [사용률] = (CAST(FILEPROPERTY(name, 'SpaceUsed') AS INT) / 128.0) / (size / 128.0) * 100.00
FROM sys.database_files
WHERE type IN (0,1);

-- Log space만 확인하고 싶을때
DBCC SQLPERF(LOGSPACE)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;해당 DB의 테이블별 사이즈 확인&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1712057494677&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;USE [DB_NAME];

WITH PartitionStats AS (
    SELECT 
        ps.object_id,
        SUM(CASE WHEN (ps.index_id &amp;lt; 2) THEN row_count ELSE 0 END) AS [rows],
        SUM(ps.reserved_page_count) AS [reserved],
        SUM(CASE 
                WHEN (ps.index_id &amp;lt; 2) THEN (ps.in_row_data_page_count + ps.lob_used_page_count + ps.row_overflow_used_page_count)
                ELSE (ps.lob_used_page_count + ps.row_overflow_used_page_count)
            END) AS [data],
        SUM(ps.used_page_count) AS [used]
    FROM sys.dm_db_partition_stats ps
    GROUP BY ps.object_id
),
InternalTableStats AS (
    SELECT 
        it.parent_id,
        SUM(ps.reserved_page_count) AS [reserved],
        SUM(ps.used_page_count) AS [used]
    FROM sys.dm_db_partition_stats ps
    INNER JOIN sys.internal_tables it ON (it.object_id = ps.object_id)
    WHERE it.internal_type IN (202, 204)
    GROUP BY it.parent_id
)
SELECT
    [Schema Name] = OBJECT_SCHEMA_NAME(a2.object_id),
    [Table Name] = a2.name,
    [Rows] = FORMAT(a1.rows, '#,#'),
    [Reserved Size (MB)] = FORMAT(CAST(ROUND(((a1.reserved + ISNULL(a4.reserved, 0)) * 8) / 1024.00, 2) AS NUMERIC(36,2)), '#,#'),
    [Data Size (MB)] = FORMAT(CAST(ROUND(a1.data * 8 / 1024.00, 2) AS NUMERIC(36, 2)), '#,#'),
    [Index Size (MB)] = FORMAT(CAST(ROUND((CASE WHEN (a1.used + ISNULL(a4.used, 0)) &amp;gt; a1.data 
        THEN (a1.used + ISNULL(a4.used, 0)) - a1.data ELSE 0 END) * 8 / 1024.00, 2) AS NUMERIC(36, 2)), '#,#'),
    [Unused Size (MB)] = FORMAT(CAST(ROUND((CASE WHEN (a1.reserved + ISNULL(a4.reserved, 0)) &amp;gt; a1.used 
        THEN (a1.reserved + ISNULL(a4.reserved, 0)) - a1.used ELSE 0 END) * 8 / 1024.00, 2) AS NUMERIC(36, 2)), '#,#')
FROM PartitionStats a1
LEFT OUTER JOIN InternalTableStats a4 
	ON a4.parent_id = a1.object_id
INNER JOIN sys.all_objects a2 
	ON a1.object_id = a2.object_id
WHERE a2.type &amp;lt;&amp;gt; N'S' AND a2.type &amp;lt;&amp;gt; N'IT' 
	--	AND a2.name = N'TABLE NAME'  -- 원하는 테이블 있으면 해당 조건 넣기
ORDER BY CAST(ROUND(((a1.reserved + ISNULL(a4.reserved, 0)) * 8) / 1024.00, 2) AS NUMERIC(36,2)) DESC;
	-- FORMAT 함수 사용한 컬럼 기준으로 정렬 시, 숫자 기준으로 정렬하기 위해 계산식 그대로 사용&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;특정 테이블 내의 인덱스의 사용 빈도 확인&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1712057570458&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT a.object_id
	, [Table Name] = object_name(a.object_id)
	, a.index_id
	, [Index Name] = b.name
	, a.user_seeks									-- 사용자 쿼리별 Seek 연산 횟수
	, a.last_user_seek								-- 사용자 쿼리에 따른 마지막 Seek 연산 수행 시간
	, a.user_scans									-- 사용자 쿼리별 Scan 연산 횟수
	, a.last_user_scan								-- 사용자 쿼리에 따른 마지막 Scan 연산 수행 시간
FROM sys.dm_db_index_usage_stats AS a
INNER JOIN sys.indexes AS b
	ON a.object_id = b.object_id
	AND a.index_id = b.index_id
WHERE a.database_id = DB_ID(N'DATABASE_NAME')
	AND OBJECT_NAME(a.object_id) = N'TABLE_NAME'  -- 스키마명 제외한 순수 테이블명만 넣을 것.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;특정 테이블 내 인덱스들의 조각화 정도 확인&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1712057617699&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT a.object_id
	, [Table Name] = object_name(a.object_id)
	, a.index_id
	, [Index Name] = b.name
	, avg_page_space_used_in_percent
	, avg_fragmentation_in_percent
FROM sys.dm_db_index_physical_stats(
	DB_ID (N'DB_NAME')
	, OBJECT_ID(N'TABLE_NAME')     -- 스키마 네임은 빼고 순수 테이블명만 넣기
	, NULL
	, NULL
	, 'SAMPLED'
	) AS a
INNER JOIN sys.indexes AS b
	ON a.object_id = b.object_id
	AND a.index_id = b.index_id&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Compression Backup 시에, 압축 비율 및 현재 백업 파일 사이즈 확인&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1712057736834&quot; class=&quot;pgsql&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;sql&quot;&gt;&lt;code&gt;SELECT name 
	, backup_start_date
	, [compressed_backup_size (MB)] = CONVERT(DECIMAL(10, 2), compressed_backup_size / 1024. / 1024.)
	, [compression ratio] = compressed_backup_size/backup_size * 100
FROM msdb..backupset
WHERE backup_start_date &amp;gt;= '2023-12-11'  -- 확인이 필요한 특정 날짜를 조건절에 꼭 넣어서 쿼리할 것.
ORDER BY backup_start_date DESC&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;4. 기타 등등?&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;프로시저 조회&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1712056837695&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;USE [데이터베이스명]

-- 전체 프로시저 오브젝트 조회
SELECT *
FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_TYPE='PROCEDURE'

-- 프로시저 이름, 프로시저 내용만 조회
SELECT [ProcedureName] = ROUTINE_NAME
	, [ProcedureContents] = ROUTINE_DEFINITION
FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_TYPE='PROCEDURE'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://99lib.tistory.com/541&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://99lib.tistory.com/541&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1712057961825&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;문제상황시 유용한 sql쿼리들&quot; data-og-description=&quot;--get the connections select st.text, c.connect_time, c.net_transport, c.auth_scheme, c.num_reads, c.num_writes, c.last_read, c.last_write, c.connection_id, c.parent_connection_id, st.dbid, st.objectid from sys.dm_exec_connections c cross apply sys.dm_exec&quot; data-og-host=&quot;99lib.tistory.com&quot; data-og-source-url=&quot;https://99lib.tistory.com/541&quot; data-og-url=&quot;https://99lib.tistory.com/541&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/fDzJm/hyVGHxAsSm/1iU77xyPutPTRyA4Mh6uM1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/tUXjm/hyVGTx10dI/rtcFH2XXGxatzN7Rh8WouK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bEECK2/hyVJVnpnBp/l3XF7MyqRQByFh1amnfb61/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400&quot;&gt;&lt;a href=&quot;https://99lib.tistory.com/541&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://99lib.tistory.com/541&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/fDzJm/hyVGHxAsSm/1iU77xyPutPTRyA4Mh6uM1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/tUXjm/hyVGTx10dI/rtcFH2XXGxatzN7Rh8WouK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bEECK2/hyVJVnpnBp/l3XF7MyqRQByFh1amnfb61/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;문제상황시 유용한 sql쿼리들&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;--get the connections select st.text, c.connect_time, c.net_transport, c.auth_scheme, c.num_reads, c.num_writes, c.last_read, c.last_write, c.connection_id, c.parent_connection_id, st.dbid, st.objectid from sys.dm_exec_connections c cross apply sys.dm_exec&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;99lib.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://sharedstoryit.tistory.com/entry/MSSQL-%EC%BF%BC%EB%A6%AC-%ED%8A%9C%EB%8B%9D%EC%9D%84-%EC%9C%84%ED%95%9C-%EC%BF%BC%EB%A6%AC-%EB%B0%8F-%EC%8B%9C%EC%8A%A4%ED%85%9C-%ED%85%8C%EC%9D%B4%EB%B8%94&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://sharedstoryit.tistory.com/entry/MSSQL-%EC%BF%BC%EB%A6%AC-%ED%8A%9C%EB%8B%9D%EC%9D%84-%EC%9C%84%ED%95%9C-%EC%BF%BC%EB%A6%AC-%EB%B0%8F-%EC%8B%9C%EC%8A%A4%ED%85%9C-%ED%85%8C%EC%9D%B4%EB%B8%94&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1712057968548&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[MSSQL] 쿼리 튜닝을 위한 쿼리 및 시스템 테이블&quot; data-og-description=&quot;데이터베이스별 누락된 인덱스SQL Server가 쿼리를 처리할 때 최적화 프로그램은 쿼리를 수행하기 위해 사용하려고 시도한 인덱스에 대한 기록을 보관합니다. 이러한 인덱스가 없는 경우 SQL Server&quot; data-og-host=&quot;sharedstoryit.tistory.com&quot; data-og-source-url=&quot;https://sharedstoryit.tistory.com/entry/MSSQL-%EC%BF%BC%EB%A6%AC-%ED%8A%9C%EB%8B%9D%EC%9D%84-%EC%9C%84%ED%95%9C-%EC%BF%BC%EB%A6%AC-%EB%B0%8F-%EC%8B%9C%EC%8A%A4%ED%85%9C-%ED%85%8C%EC%9D%B4%EB%B8%94&quot; data-og-url=&quot;https://sharedstoryit.tistory.com/entry/MSSQL-%EC%BF%BC%EB%A6%AC-%ED%8A%9C%EB%8B%9D%EC%9D%84-%EC%9C%84%ED%95%9C-%EC%BF%BC%EB%A6%AC-%EB%B0%8F-%EC%8B%9C%EC%8A%A4%ED%85%9C-%ED%85%8C%EC%9D%B4%EB%B8%94&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/O8own/hyVJ5Q63uZ/iyWZlmsixwB5nZCYygeo40/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bD8l8n/hyVJTJUKJ4/KTxBdKdkNCFh80v7xK3Jk1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://sharedstoryit.tistory.com/entry/MSSQL-%EC%BF%BC%EB%A6%AC-%ED%8A%9C%EB%8B%9D%EC%9D%84-%EC%9C%84%ED%95%9C-%EC%BF%BC%EB%A6%AC-%EB%B0%8F-%EC%8B%9C%EC%8A%A4%ED%85%9C-%ED%85%8C%EC%9D%B4%EB%B8%94&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://sharedstoryit.tistory.com/entry/MSSQL-%EC%BF%BC%EB%A6%AC-%ED%8A%9C%EB%8B%9D%EC%9D%84-%EC%9C%84%ED%95%9C-%EC%BF%BC%EB%A6%AC-%EB%B0%8F-%EC%8B%9C%EC%8A%A4%ED%85%9C-%ED%85%8C%EC%9D%B4%EB%B8%94&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/O8own/hyVJ5Q63uZ/iyWZlmsixwB5nZCYygeo40/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bD8l8n/hyVJTJUKJ4/KTxBdKdkNCFh80v7xK3Jk1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[MSSQL] 쿼리 튜닝을 위한 쿼리 및 시스템 테이블&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;데이터베이스별 누락된 인덱스SQL Server가 쿼리를 처리할 때 최적화 프로그램은 쿼리를 수행하기 위해 사용하려고 시도한 인덱스에 대한 기록을 보관합니다. 이러한 인덱스가 없는 경우 SQL Server&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;sharedstoryit.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DB/SQL Server (MSSQL)</category>
      <category>MSSQL DBA</category>
      <category>MSSQL DBA 쿼리</category>
      <category>MSSQL 각종 쿼리</category>
      <category>MSSQL 유용한 쿼리</category>
      <category>MSSQL 장애시 쿼리</category>
      <category>MSSQL 점검 쿼리</category>
      <category>MSSQL 현재 상태 점검</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/173</guid>
      <comments>https://co-no.tistory.com/entry/MSSQL-SQL-Server-%EC%A0%90%EA%B2%80-%EC%8B%9C-%EC%9C%A0%EC%9A%A9%ED%95%9C-%EC%BF%BC%EB%A6%AC-%EB%AA%A8%EC%9D%8C#entry173comment</comments>
      <pubDate>Mon, 8 Apr 2024 09:13:42 +0900</pubDate>
    </item>
    <item>
      <title>[httpd] RedHat JBCS httpd 에서 Apache httpd로 이전하기 (1)</title>
      <link>https://co-no.tistory.com/entry/httpd-RedHat-JBCS-httpd-%EC%97%90%EC%84%9C-Apache-httpd%EB%A1%9C-%EC%9D%B4%EC%A0%84%ED%95%98%EA%B8%B0-1</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;364&quot; data-origin-height=&quot;138&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7GGom/btsGqyCnjka/sTVJayzCngooBO7iEaZyK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7GGom/btsGqyCnjka/sTVJayzCngooBO7iEaZyK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7GGom/btsGqyCnjka/sTVJayzCngooBO7iEaZyK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7GGom%2FbtsGqyCnjka%2FsTVJayzCngooBO7iEaZyK1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;364&quot; height=&quot;138&quot; data-origin-width=&quot;364&quot; data-origin-height=&quot;138&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사내 취약성 기준이 httpd 버전을 2.4.58 이상으로 반드시 쓰라는 얘기가 나와서,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에 설치되어 있던 RedHat JBCS httpd 에서 Apache httpd 로 이전해보고자 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RedHat JBCS httpd도 분명 꾸준히 업데이트가 되고 있지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순 버전 차이에서 오는 문제라든지, OpenSSL의 종속성 문제라든지, 대부분의 구글링 문서들이 Apache httpd 문서 기준이라든지(&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;RedHat JBCS httpd와 Apache httpd의 디렉토리 구조가 다르다.&lt;/b&gt;&lt;/span&gt;), 앞으로도 계속 이런 자잘자잘한 문제들이 나를 괴롭힐 수 있을 것 같다는 생각에,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Apache httpd 를 컴파일 설치하여, RedHat JBCS httpd를 걷어내보고자(?) 한다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;참고로, 필자의 경우, &lt;u&gt;RHEL 7,8,9 에서 OpenSSL 1.0.2k, 1.1.1k, 3.2.1 버전 모두 Apache httpd 컴파일 설치를 진행해본 결과, &lt;/u&gt;&lt;u&gt;몇몇 에러들만 잡으면, 구동 및 운영에는 문제가 없는 것으로 보였다.&lt;/u&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;따라서, &lt;b&gt;RHEL 7 이상&lt;/b&gt;, &lt;b&gt;OpenSSL은 3.2.1. 버전 이상&lt;/b&gt; 기준으로 설명한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;아래 명령어는 모두 &lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;root와 동등한 권한으로 수행&lt;/b&gt;&lt;/span&gt;하고, 추후에 '&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;apache&lt;/b&gt;&lt;/span&gt;' &lt;u&gt;계정으로 권한 및 소유권을 조정&lt;/u&gt;할 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;1. openssl 1.1.1 컴파일 설치&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1.1. openssl 컴파일 설치 진행되는 디렉토리 생성&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1712284757151&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;mkdir /opt/openssl_compile
cd /opt/openssl_compile&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1.2. openssl 공식 홈페이지에서 tar.gz 파일 받기&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글 작성일 기준(2024.04.05.)으로 &lt;b&gt;openssl3&lt;/b&gt; 버전의 latest stable version은 &amp;lsquo;&lt;b&gt;3.2.1&lt;/b&gt;&amp;rsquo; 이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;openssl 다운로드는 아래 사이트를 참조한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.openssl.org/source/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.openssl.org/source/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1712284858834&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;[ Downloads ] - /source/index.html&quot; data-og-description=&quot;Downloads The master sources are maintained in our git repository, which is accessible over the network and cloned on GitHub, at https://github.com/openssl/openssl. Bugs and pull patches (issues and pull requests) should be filed on the GitHub repo. Please&quot; data-og-host=&quot;www.openssl.org&quot; data-og-source-url=&quot;https://www.openssl.org/source/&quot; data-og-url=&quot;https://www.openssl.org/source/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.openssl.org/source/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.openssl.org/source/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[ Downloads ] - /source/index.html&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Downloads The master sources are maintained in our git repository, which is accessible over the network and cloned on GitHub, at https://github.com/openssl/openssl. Bugs and pull patches (issues and pull requests) should be filed on the GitHub repo. Please&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.openssl.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;pre id=&quot;code_1712284892579&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;wget https://www.openssl.org/source/openssl-3.2.1.tar.gz
tar xvf openssl-3.2.1.tar.gz&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt; 1.3. 소스 컴파일 전, Makefile(환경설정 파일) 생성 &lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1712284979543&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cd openssl-3.2.1

# 서버에 기존 사용하는 openssl이 있을 수 있으니, 
# 컴파일 설치하는 openssl3는 다음과 같이 설정하여, 기존 설치된 openssl과 구분하도록 하자!
./config --prefix=/usr/local/openssl3 --openssldir=/usr/local/openssl3 shared&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;--prefix&lt;/b&gt; : 설치할 위치 지정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;--openssldir&lt;/b&gt; : openssl 실행 시, 참조할 기본 디렉토리 지정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같은 문구가 나타났다면, openssl config가 정상적으로 수행된 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;848&quot; data-origin-height=&quot;346&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ba4yw6/btsGoR1Q4P4/EqkMBfy9vQo8vSklg1iWC0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ba4yw6/btsGoR1Q4P4/EqkMBfy9vQo8vSklg1iWC0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ba4yw6/btsGoR1Q4P4/EqkMBfy9vQo8vSklg1iWC0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fba4yw6%2FbtsGoR1Q4P4%2FEqkMBfy9vQo8vSklg1iWC0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;566&quot; height=&quot;231&quot; data-origin-width=&quot;848&quot; data-origin-height=&quot;346&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt; &lt;span style=&quot;background-color: #dddddd; color: #ef6f53;&quot;&gt;&lt;i&gt;&lt;b&gt;Cant' locate IPC/Cmd.pm in @INC (you may need to install the IPC::Cmd module)&lt;/b&gt; &lt;/i&gt;&lt;/span&gt;&lt;b&gt;에러&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IPC-Cmd 가 없는 문제이므로, yum으로 해당 패키지를 설치한다.&lt;/p&gt;
&lt;pre id=&quot;code_1712285491444&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;yum install perl-IPC-Cmd perl-Pod-Html

# 기존 configure 및 캐시 삭제
make distclean

# make 파일 재설정
./config --prefix=/usr/local/openssl3 --openssldir=/usr/local/openssl3 shared&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt; &lt;span style=&quot;background-color: #dddddd; color: #ef6f53;&quot;&gt;&lt;i&gt;&lt;b&gt;No C compiler found, please specify one with the environment variable CC&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;b&gt;에러&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C 및 C++ 에 대한 컴파일러가 없어서 나타나는 문제이므로, 아래와 같이 컴파일 설치에 필요한 패키지를 설치한다.&lt;/p&gt;
&lt;pre id=&quot;code_1715556940562&quot; class=&quot;shell&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;shell&quot;&gt;&lt;code&gt;yum install gcc gcc-c++

# 기존 configure 및 캐시 삭제
make distclean

# make 파일 재설정
./config --prefix=/usr/local/openssl3 --openssldir=/usr/local/openssl3 shared&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt; 1.4. Makefile 을 이용한 파일 컴파일 설치&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1712285105218&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;make &amp;amp;&amp;amp; make install&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모두 컴파일 하는 데에 시간이 꽤나 걸린다. 차분히 기다리자!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같은 &amp;lsquo;&lt;b&gt;Leaving directory&lt;/b&gt;&amp;rsquo; 문구가 나타나면, 컴파일이 끝난 것이다!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1540&quot; data-origin-height=&quot;62&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lLcPq/btsGmX3eR7a/vDWyJFwdeNi44Ff40L7U5K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lLcPq/btsGmX3eR7a/vDWyJFwdeNi44Ff40L7U5K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lLcPq/btsGmX3eR7a/vDWyJFwdeNi44Ff40L7U5K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlLcPq%2FbtsGmX3eR7a%2FvDWyJFwdeNi44Ff40L7U5K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1540&quot; height=&quot;62&quot; data-origin-width=&quot;1540&quot; data-origin-height=&quot;62&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1.5. 공유 라이브러리 등록&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;openssl 설치 시, &lt;b&gt;동적 라이브러리를 이용하도록 설정&lt;/b&gt;(&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;shared&lt;/b&gt;&lt;/span&gt; 옵션)했기 때문에, 동적 라이브러리 로딩 정보에 새로 설치한 openssl과 관련된 라이브러리 디렉토리를 추가해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1.5.1. Linux 공유 라이브러리 conf 파일 설정&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1712285259498&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;vim /etc/ld.so.conf.d/openssl3.conf 
# 여기서 파일명을 'openssl3.conf'로 지정했지만, 임의로 지정 가능

# openssl3.conf 에 아래 문구 넣기
/usr/local/openssl3/lib64&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1.5.2. 공유 라이브러리 캐시를 재설정 및 확인&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1712290510460&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ldconfig -v | grep -E &quot;libssl.so|libcrypto.so&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;ldconfig -v&lt;/b&gt; 명령어를 사용하면, 현재 모든 shared library cache 목록이 나타나게 되는데, 이러면 openssl3와 관련된 shared library는 확인이 어려우므로, &lt;b&gt;grep -E &quot;libssl.so|libcrypto.so&quot;&lt;/b&gt; 명령어를 사용하였다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;336&quot; data-origin-height=&quot;68&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cjWKef/btsGoTFvJLu/nN3pC9OrfKLtimhWMYuKK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cjWKef/btsGoTFvJLu/nN3pC9OrfKLtimhWMYuKK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cjWKef/btsGoTFvJLu/nN3pC9OrfKLtimhWMYuKK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcjWKef%2FbtsGoTFvJLu%2FnN3pC9OrfKLtimhWMYuKK1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;336&quot; height=&quot;68&quot; data-origin-width=&quot;336&quot; data-origin-height=&quot;68&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1.6. /usr/lib64 디렉토리에도 라이브러리의 링크 추가&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 명령어를 통해, 동적 라이브러리를 처음 찾는 디렉토리인 /usr/lib64에도 해당 라이브러리가 존재하는 지 확인해보자.&lt;/p&gt;
&lt;pre id=&quot;code_1712290832902&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ls -al /usr/lib64 | grep -E &quot;libssl|libcrypto&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;809&quot; data-origin-height=&quot;169&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcoy3r/btsGnOEVXzx/cG5lhjX1AQ80taNjrKJmc0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcoy3r/btsGnOEVXzx/cG5lhjX1AQ80taNjrKJmc0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcoy3r/btsGnOEVXzx/cG5lhjX1AQ80taNjrKJmc0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbcoy3r%2FbtsGnOEVXzx%2FcG5lhjX1AQ80taNjrKJmc0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;809&quot; height=&quot;169&quot; data-origin-width=&quot;809&quot; data-origin-height=&quot;169&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 필자의 경우, 위와 같이 openssl3 설치와 함께 생긴 library는 아직 /usr/lib64에는 없는 것으로 보인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이럴 경우, 아래 과정을 거쳐 심볼릭 링크로 등록해주어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1.6.1. /usr/lib64 디렉토리에 새로 설치한 openssl3 의 동적 라이브러리 심볼릭 링크 추가&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1712290996444&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ln -s /usr/local/openssl3/lib64/libssl.so /usr/lib64/libssl.so.3
ln -s /usr/local/openssl3/lib64/libcrypto.so /usr/lib64/libcrypto.so.3

# 위 명령어 수행 후, 동적 라이브러리 디렉토리 다시 확인
ls -al /usr/lib64 | grep -E &quot;libssl|libcrypto&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;2. 기존 'openssl' 명령어가 실행되는 경로를 새로 설치한 openssl3 경로로 변경&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2.1. 현재 시스템의 'openssl' 명령어 실행 경로 확인&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1712291716014&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;which oepnssl
openssl version&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;571&quot; data-origin-height=&quot;106&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/k4QYM/btsGpL79Kfr/eqwQnUJ0WEvqleEF6OjVF0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/k4QYM/btsGpL79Kfr/eqwQnUJ0WEvqleEF6OjVF0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/k4QYM/btsGpL79Kfr/eqwQnUJ0WEvqleEF6OjVF0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fk4QYM%2FbtsGpL79Kfr%2FeqwQnUJ0WEvqleEF6OjVF0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;571&quot; height=&quot;106&quot; data-origin-width=&quot;571&quot; data-origin-height=&quot;106&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 openssl은 openssl 1.1.1k 버전으로 설정되어 있으므로, 이 경로를 openssl3 로 변경해 줄 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2.2. 기존 명령어의 이름을 변경&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1712291929057&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;mv /usr/bin/openssl /usr/bin/openssl_1.1.1k&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2.3. 새로 설치한 openssl3 버전의 명령어를 '/usr/bin/openssl' 로 만들기&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1712291973051&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cp /usr/local/openssl3/bin/openssl /usr/bin/openssl&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2.4. 'openssl' 명령어가 openssl3로 제대로 업데이트 되었는 지 확인&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1712292085772&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;openssl version&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;757&quot; data-origin-height=&quot;56&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bG3mU0/btsGn6ZRt7Y/OeLmUepTK3AVJDdmy8N1H1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bG3mU0/btsGn6ZRt7Y/OeLmUepTK3AVJDdmy8N1H1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bG3mU0/btsGn6ZRt7Y/OeLmUepTK3AVJDdmy8N1H1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbG3mU0%2FbtsGn6ZRt7Y%2FOeLmUepTK3AVJDdmy8N1H1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;757&quot; height=&quot;56&quot; data-origin-width=&quot;757&quot; data-origin-height=&quot;56&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 명령어 수행 결과가 나온다면, 새로 설치한 OpenSSL3의 동적 라이브러리를 불러와서 잘 동작하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;3. Apache httpd 2.4.59 수동 설치&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3.1. httpd 수동(컴파일) 설치 위한 사전 준비&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1712292211360&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Apache httpd 컴파일 설치 시 필요한 유틸리티 설치
yum install gcc-c++ expat-devel

# Apache httpd 컴파일 설치에 필요한 라이브러리들을 설치할 디렉토리 생성
mkdir /opt/apache_compile
cd /opt/apache_compile&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3.2. apr, apr-util, pcre 라이브러리 설치&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;httpd 를 수동으로 빌드하기 위해서는 &lt;b&gt;apr, apr-util, pcre&lt;/b&gt; 라이브러리가 필수적으로 필요한데, httpd 설치파일에 포함되어 있지 않다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서, 해당 라이브러리들의 설치가 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 경로를 참고해서 &lt;b&gt;apr&lt;/b&gt;과 &lt;b&gt;apr-util&lt;/b&gt; 을 설치하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://apr.apache.org/download.cgi&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://apr.apache.org/download.cgi&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1712292279010&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Download - The Apache Portable Runtime Project&quot; data-og-description=&quot;The currently selected mirror is https://dlcdn.apache.org/. If you encounter a problem with this mirror, please select another mirror. If all mirrors are failing, there are backup mirrors (at the end of the mirrors list) that should be available. You may a&quot; data-og-host=&quot;apr.apache.org&quot; data-og-source-url=&quot;https://apr.apache.org/download.cgi&quot; data-og-url=&quot;https://apr.apache.org/download.cgi&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://apr.apache.org/download.cgi&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://apr.apache.org/download.cgi&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Download - The Apache Portable Runtime Project&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The currently selected mirror is https://dlcdn.apache.org/. If you encounter a problem with this mirror, please select another mirror. If all mirrors are failing, there are backup mirrors (at the end of the mirrors list) that should be available. You may a&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;apr.apache.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;3.2.1. apr 라이브러리 설치&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 명령어로 apache_compile 디렉토리를 새로 생성하여, 해당 디렉토리에 apr을 설치하자!&lt;/p&gt;
&lt;pre id=&quot;code_1712292338320&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# apr 라이브러리 tarball 다운로드
wget https://dlcdn.apache.org//apr/apr-1.7.4.tar.gz
tar xvf ./apr-1.7.4.tar.gz

# apr 라이브러리 설치 디렉토리로 이동
cd ./apr-1.7.4

# apr 설치 위한 make 파일 설정
./configure --prefix=/usr/local/apr&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt; &lt;span style=&quot;background-color: #dddddd; color: #ef6f53;&quot;&gt;&lt;i&gt;&lt;b&gt;rm: cannot remove 'libtoolT' : No such file or directory&lt;/b&gt;&lt;/i&gt;&lt;i&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;b&gt;에러&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;gt; &lt;b&gt;현 디렉토리&lt;/b&gt;(/opt/apache_compile/apr-1.7.4.tar.gz) 에서 아래 명령어 수행한다.&lt;/p&gt;
&lt;pre id=&quot;code_1712292634037&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 에러 해결 위함
cp -arp libtool libtoolT

# 기존 configure 설정 및 캐시 제거
make distclean

# apr 설치 위한 make 파일 재설정
./configure --prefix=/usr/local/apr&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 명령어 통해 컴파일 설치&lt;/p&gt;
&lt;pre id=&quot;code_1712293167345&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;make &amp;amp;&amp;amp; make install&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1730&quot; data-origin-height=&quot;834&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dBTh3f/btsGppLdAch/jk7ItZr3OEH0OcaxsEdbEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dBTh3f/btsGppLdAch/jk7ItZr3OEH0OcaxsEdbEK/img.png&quot; data-alt=&quot;이러한 문구가 나온다면 apr 설치가 잘 된 것이다!&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dBTh3f/btsGppLdAch/jk7ItZr3OEH0OcaxsEdbEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdBTh3f%2FbtsGppLdAch%2Fjk7ItZr3OEH0OcaxsEdbEK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;665&quot; height=&quot;321&quot; data-origin-width=&quot;1730&quot; data-origin-height=&quot;834&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이러한 문구가 나온다면 apr 설치가 잘 된 것이다!&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;3.2.2. apr-util 라이브러리 설치&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1712293314472&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cd /opt/apache_compile

# apr-util 라이브러리 tarball 다운로드
wget https://dlcdn.apache.org//apr/apr-util-1.6.3.tar.gz
tar xvf ./apr-util-1.6.3.tar.gz

# 압축 푼 apr-util 라이브러리 설치 디렉토리로 이동
cd ./apr-util-1.6.3

# make 파일 설정
./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr

# 컴파일 및 설치
make &amp;amp;&amp;amp; make install&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1930&quot; data-origin-height=&quot;933&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/biO7nk/btsGnEQkcwy/R5qckfmMKcf5K6xnDuzq01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/biO7nk/btsGnEQkcwy/R5qckfmMKcf5K6xnDuzq01/img.png&quot; data-alt=&quot;이러한 문구가 나온다면 apr-util 라이브러리가 잘 설치된 것이다!&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/biO7nk/btsGnEQkcwy/R5qckfmMKcf5K6xnDuzq01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbiO7nk%2FbtsGnEQkcwy%2FR5qckfmMKcf5K6xnDuzq01%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;628&quot; height=&quot;304&quot; data-origin-width=&quot;1930&quot; data-origin-height=&quot;933&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이러한 문구가 나온다면 apr-util 라이브러리가 잘 설치된 것이다!&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;3.2.3. pcre 라이브러리 설치&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.pcre.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.pcre.org/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1712293572363&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;PCRE - Perl Compatible Regular Expressions&quot; data-og-description=&quot;PCRE - Perl Compatible Regular Expressions The PCRE library is a set of functions that implement regular expression pattern matching using the same syntax and semantics as Perl&amp;nbsp;5. PCRE has its own native API, as well as a set of wrapper functions that cor&quot; data-og-host=&quot;www.pcre.org&quot; data-og-source-url=&quot;https://www.pcre.org/&quot; data-og-url=&quot;https://www.pcre.org/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.pcre.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.pcre.org/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;PCRE - Perl Compatible Regular Expressions&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;PCRE - Perl Compatible Regular Expressions The PCRE library is a set of functions that implement regular expression pattern matching using the same syntax and semantics as Perl&amp;nbsp;5. PCRE has its own native API, as well as a set of wrapper functions that cor&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.pcre.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 링크를 통해 pcre 라이브러리 tarball 다운로드 링크를 참고하자.&lt;/p&gt;
&lt;pre id=&quot;code_1712293894601&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cd /opt/apache_compile

# pcre 라이브러리 tarball 다운로드
wget https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.43/pcre2-10.43.tar.gz
tar xvf ./pcre2-10.43.tar.gz

# 압축 푼 pcre 라이브러리 설치 디렉토리로 이동
cd ./pcre2-10.43

# make 파일 설정
./configure --prefix=/usr/local/pcre2

# 컴파일 및 설치
make &amp;amp;&amp;amp; make install&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3.3. httpd 2.4.59 설치 (2024.04.05 기준 latest version)&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;mpm module을 선택하기 위해, 기존에 사용하고 있던 RedHat JBCS httpd가 어떤 mpm module을 사용하고 있었는지,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 명령어를 통해 조회 가능하다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1713162200456&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cd ${RedHat JBCS HTTPD DIR}/bin
./httpd -V&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 아래 링크를 참고하여 Apache httpd 소스 tarball을 다운로드하자!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://httpd.apache.org/download.cgi#apache24&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://httpd.apache.org/download.cgi#apache24&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1712330521990&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Download - The Apache HTTP Server Project&quot; data-og-description=&quot;Downloading the Apache HTTP Server Use the links below to download the Apache HTTP Server from our download servers. You must verify the integrity of the downloaded files using signatures downloaded from our main distribution directory. The signatures can &quot; data-og-host=&quot;httpd.apache.org&quot; data-og-source-url=&quot;https://httpd.apache.org/download.cgi#apache24&quot; data-og-url=&quot;https://httpd.apache.org/download.cgi#apache24&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://httpd.apache.org/download.cgi#apache24&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://httpd.apache.org/download.cgi#apache24&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Download - The Apache HTTP Server Project&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Downloading the Apache HTTP Server Use the links below to download the Apache HTTP Server from our download servers. You must verify the integrity of the downloaded files using signatures downloaded from our main distribution directory. The signatures can&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;httpd.apache.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;pre id=&quot;code_1712330578906&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cd /opt/apache_compile

# Apache httpd 소스 tarball 다운로드
wget https://dlcdn.apache.org/httpd/httpd-2.4.59.tar.gz
tar xvf ./httpd-2.4.59.tar.gz

cd ./httpd-2.4.59

# httpd의 설치 경로를 /opt/httpd 로 한다고 가정하고, make 파일 설정 위한 다음 명령어 수행
# httpd가 사용하는 openssl의 경로는 /usr/local/openssl3
# --with-mpm : 2.4.x 버전 기준, default로 'Event' MPM Module로 설정되며, 다음과 같이 플래그를 주면, 해당 MPM Module을 사용하게끔 설치된다.
# MPM Module의 경우, Thread-Safety한 상황이라면, 'Event' MPM Module이 성능이 가장 좋다. 
./configure --prefix=/opt/httpd \
--with-ssl=/usr/local/openssl3 \
--enable-mods-shared=all \
--enable-modules=all \
--with-apr=/usr/local/apr/bin/apr-1-config \
--with-apr-util=/usr/local/apr-util/bin/apu-1-config \
--with-pcre=/usr/local/pcre2/bin/pcre2-config \
--with-mpm=prefork 

# 컴파일 및 설치
make &amp;amp;&amp;amp; make install&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 명령어를 통해 Apache httpd가 제대로 설치되었는 지 확인해보자!&lt;/p&gt;
&lt;pre id=&quot;code_1712330998818&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cd /opt/httpd/bin

# httpd 버전 확인
./httpd -v&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;304&quot; data-origin-height=&quot;53&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lK6tF/btsGqyIslvv/a4c2gNk4JKdRBa6Qd1mH50/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lK6tF/btsGqyIslvv/a4c2gNk4JKdRBa6Qd1mH50/img.png&quot; data-alt=&quot;Apache httpd의 성공적인 설치!&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lK6tF/btsGqyIslvv/a4c2gNk4JKdRBa6Qd1mH50/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlK6tF%2FbtsGqyIslvv%2Fa4c2gNk4JKdRBa6Qd1mH50%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;304&quot; height=&quot;53&quot; data-origin-width=&quot;304&quot; data-origin-height=&quot;53&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Apache httpd의 성공적인 설치!&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3.4. Apache 기본적인 설정 및 구동 테스트&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 Apache httpd 설치가 모두 완료되었으니, 다음 명령어를 입력하여, httpd가 제대로 실행되는 지를 확인해보자!&lt;/p&gt;
&lt;pre id=&quot;code_1712494140019&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cd /opt/httpd/bin

# httpd 실행
./apachectl -k start

# httpd 프로세스 확인
ps -ef | grep httpd&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1007&quot; data-origin-height=&quot;176&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tkICP/btsGqybf0qd/ayus2pBxyKvC67MxXkFpq0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tkICP/btsGqybf0qd/ayus2pBxyKvC67MxXkFpq0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tkICP/btsGqybf0qd/ayus2pBxyKvC67MxXkFpq0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtkICP%2FbtsGqybf0qd%2Fayus2pBxyKvC67MxXkFpq0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1007&quot; height=&quot;176&quot; data-origin-width=&quot;1007&quot; data-origin-height=&quot;176&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 httpd 프로세스가 떠 있는 것을 확인했다면, &lt;b&gt;httpd://&lt;span style=&quot;color: #409d00;&quot;&gt;{httpd 가동한 서버 IP}&lt;/span&gt;:&lt;span style=&quot;color: #006dd7;&quot;&gt;80&lt;/span&gt;/&lt;/b&gt; 을 주소창에 입력하면 아래와 같은 문구가 나타날 것이다. 그럼 httpd가 정말 제대로 실행된 것이다!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;174&quot; data-origin-height=&quot;66&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cvXtiW/btsGsTLRbWV/HxpbdkKfPwtrPChiks7WVK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cvXtiW/btsGsTLRbWV/HxpbdkKfPwtrPChiks7WVK/img.png&quot; data-alt=&quot;httpd 실행 성공 브라우저 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cvXtiW/btsGsTLRbWV/HxpbdkKfPwtrPChiks7WVK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcvXtiW%2FbtsGsTLRbWV%2FHxpbdkKfPwtrPChiks7WVK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;174&quot; height=&quot;66&quot; data-origin-width=&quot;174&quot; data-origin-height=&quot;66&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;httpd 실행 성공 브라우저 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 그럼 아래 포스팅을 통해, RedHat JBCS httpd 에서 Apache httpd로 변경할 때,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세부 configuration들을 어떻게 이전시키고 설정해야 할지에 대해 알아보자!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://blog.jiniworld.me/135&quot;&gt;[CentOS 7] Apache 2.4.48 웹서버 수동 설치 및 TLS 1.3 적용하기&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1712494243039&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[CentOS 7] Apache 2.4.48 웹서버 수동 설치 및 TLS 1.3 적용하기&quot; data-og-description=&quot;TLS 1.3 을 지원하려면? openssl 1.1.1 수동설치 openssl 1.1.1 설치 공유 라이브러리 등록 openssl 관련 라이브러리 확인 및 추가 openssl 관련 라이브러리 확인 및 등록 httpd 2.4.51 수동설치 필수 패키지 사전 &quot; data-og-host=&quot;blog.jiniworld.me&quot; data-og-source-url=&quot;https://blog.jiniworld.me/135&quot; data-og-url=&quot;https://blog.jiniworld.me/135&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/crNIi2/hyVJ4TGCBy/8u8VR5v2Jna7npZ14qosEk/img.png?width=800&amp;amp;height=405&amp;amp;face=0_0_800_405,https://scrap.kakaocdn.net/dn/OgrSl/hyVJZY88iI/Q1nTQ6qiy3bAmiw4dYmE10/img.png?width=800&amp;amp;height=405&amp;amp;face=0_0_800_405,https://scrap.kakaocdn.net/dn/3oIMd/hyVMYxxc4h/zA5ZFFgnjIaRwibk70xzsk/img.png?width=874&amp;amp;height=528&amp;amp;face=0_0_874_528&quot;&gt;&lt;a href=&quot;https://blog.jiniworld.me/135&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://blog.jiniworld.me/135&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/crNIi2/hyVJ4TGCBy/8u8VR5v2Jna7npZ14qosEk/img.png?width=800&amp;amp;height=405&amp;amp;face=0_0_800_405,https://scrap.kakaocdn.net/dn/OgrSl/hyVJZY88iI/Q1nTQ6qiy3bAmiw4dYmE10/img.png?width=800&amp;amp;height=405&amp;amp;face=0_0_800_405,https://scrap.kakaocdn.net/dn/3oIMd/hyVMYxxc4h/zA5ZFFgnjIaRwibk70xzsk/img.png?width=874&amp;amp;height=528&amp;amp;face=0_0_874_528');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[CentOS 7] Apache 2.4.48 웹서버 수동 설치 및 TLS 1.3 적용하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;TLS 1.3 을 지원하려면? openssl 1.1.1 수동설치 openssl 1.1.1 설치 공유 라이브러리 등록 openssl 관련 라이브러리 확인 및 추가 openssl 관련 라이브러리 확인 및 등록 httpd 2.4.51 수동설치 필수 패키지 사전&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;blog.jiniworld.me&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://access.redhat.com/solutions/445713&quot;&gt;Apache HTTPD versions supported by Red Hat - Red Hat Customer Portal&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1712494242179&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Apache HTTPD versions supported by Red Hat - Red Hat Customer Portal&quot; data-og-description=&quot;What version of httpd is supported on RHEL? Is the community version of Apache httpd supported? Which versions of Apache httpd are supported? How can I install Apache 2.5/2.6? Is Apache httpd 2.5/2.6 supported? Does Redhat support self compiled apache inst&quot; data-og-host=&quot;access.redhat.com&quot; data-og-source-url=&quot;https://access.redhat.com/solutions/445713&quot; data-og-url=&quot;https://access.redhat.com/solutions/445713&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/DWBqD/hyVMYEiHCc/YEVxG5nC0zyrmOOObaQjKk/img.png?width=200&amp;amp;height=200&amp;amp;face=0_0_200_200&quot;&gt;&lt;a href=&quot;https://access.redhat.com/solutions/445713&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://access.redhat.com/solutions/445713&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/DWBqD/hyVMYEiHCc/YEVxG5nC0zyrmOOObaQjKk/img.png?width=200&amp;amp;height=200&amp;amp;face=0_0_200_200');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Apache HTTPD versions supported by Red Hat - Red Hat Customer Portal&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;What version of httpd is supported on RHEL? Is the community version of Apache httpd supported? Which versions of Apache httpd are supported? How can I install Apache 2.5/2.6? Is Apache httpd 2.5/2.6 supported? Does Redhat support self compiled apache inst&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;access.redhat.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Middleware/웹서버</category>
      <category>Apache httpd 설치</category>
      <category>httpd 수동 설치</category>
      <category>httpd 컴파일 설치</category>
      <category>JBCS httpd migration</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/182</guid>
      <comments>https://co-no.tistory.com/entry/httpd-RedHat-JBCS-httpd-%EC%97%90%EC%84%9C-Apache-httpd%EB%A1%9C-%EC%9D%B4%EC%A0%84%ED%95%98%EA%B8%B0-1#entry182comment</comments>
      <pubDate>Sun, 7 Apr 2024 21:52:59 +0900</pubDate>
    </item>
    <item>
      <title>[Ansible] playbook으로 ansible managed node들에 ssh 패스워드 없이 접속하도록 자동화하기</title>
      <link>https://co-no.tistory.com/entry/Ansible-ssh-copy-id-Playbook%EC%9C%BC%EB%A1%9C-ansible-node-%EC%B4%88%EA%B8%B0-%EC%84%B8%ED%8C%85%ED%95%B4%EB%86%93%EA%B8%B0</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;Ansible Playbook 으로 ssh-copy-id 자동화하기&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에는 뭣도 모르고, 80대가 넘는 managed node에 직접 ssh-copy-id 로 ssh public key를 전송하고, ssh 접속 테스트까지 했다&amp;hellip; 근데 이것 또한 Ansible로 자동화가 가능하다! Ansible은 정말 미쳤다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래에서 설명할 playbook yml 파일에서 사용되는 &lt;b&gt;hosts 파일의 내용&lt;/b&gt;은 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래처럼 hosts 파일에 그룹별로 나누어 IP를 작성하면, 아래 단계를 모두 적용시켜야 하는지, 부분 적용시켜야 하는 지를 hosts 파일 수정만으로 구분이 가능하게 되므로 참고하자!&lt;/p&gt;
&lt;pre class=&quot;yaml&quot; data-ke-language=&quot;html&quot;&gt;&lt;code&gt;[KNOWN_HOSTS]
10.123.123.11

[AUTHORIZED_KEYS]
10.123.123.12

[EXISTING_RSA_KEYS]
10.123.123.13

[PLAYBOOK_TEST]
10.123.123.14&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;[KNOWN_HOSTS]&lt;/b&gt; : 아래에서 설명할 '&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;auto_add_known_hosts.yml&lt;/b&gt;&lt;/span&gt;' playbook 을 실행시킬 대상&lt;br /&gt;-&amp;gt; Control Node 상에서 ~/.ssh/known_hosts 파일에 Managed Node(Remote Host) 정보들이 등록되지 않아 있는 상태이므로, 첫 번째 playbook 의 수행 대상이 되는 그룹이다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;[AUTHORIZED_KEYS]&lt;/b&gt; : 아래에서 설명할 '&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;auto_authorized_keys.yml&lt;/b&gt;&lt;/span&gt;' playbook 을 실행시킬 대상&lt;br /&gt;-&amp;gt; Control Node 상의 ~/.ssh/known_hosts 파일에는 기재가 되었고, 이후에 Managed Node의 ~/.ssh/authorized_keys 파일에 Control Node의 ssh public key 파일 내용을 기재해주어야 하므로, 이 작업 대상이 되는 그룹이다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;[EXISTING_RSA_KEYS]&lt;/b&gt; : 아래에서 설명할 '&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;remove_rsa_authorized_keys.yml'&lt;/b&gt;&lt;/span&gt; playbook 을 실행시킬 대상&lt;br /&gt;-&amp;gt; 이미 Control Node의 RSA 방식의 public key 값의 내용을 ~/.ssh/authorized_keys 파일에 가지고 있는 Managed Node들이 들어가는 그룹이다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;[PLAYBOOK_TEST]&lt;/b&gt; : 아래에서 설명할 '&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;uptime_test.yml&lt;/b&gt;&lt;/span&gt;' playbook 을 실행시킬 대상&lt;br /&gt;-&amp;gt; known_hosts, authorized_keys 파일 작업 수행 후에, 이 그룹에 있는 Managed Node 들에 대해 ssh 로 테스트 명령어를 수행하도록 하는 playbook 을 실행시킬 대상이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래에 Ansible Playbook 으로 동작시킬 YAML 파일 코드를 첨부한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;1. known_hosts 등록&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;: Control Node의 ~/.ssh/known_hosts 에 Managed-Node들을 등록&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;yaml&quot; data-ke-language=&quot;html&quot;&gt;&lt;code&gt;# auto_add_known_hosts.yml

---
- hosts: KNOWN_HOSTS
  connection: local
  serial: 1
  gather_facts: no

  tasks:
    - name : Get known_hosts fingerprint for remote nodes from local host (Ansible Server)
      command: &quot;/usr/bin/ssh-keyscan -t ed25519 {{ ansible_host }}&quot;
	    register: keyscan    # 원격지 호스트에 대한 fingerprint 를 스캔

    - name: Add ansible_host to known_hosts
      lineinfile:
        path: ~/.ssh/knwon_hosts
        line: &quot;{{ item }}&quot;
        create: yes
      with_items:
        - &quot;{{ keyscan.stdout_lines }}&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;playbook 수행 명령어&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;ansible-playbook -i [hosts 파일 path] ['auto_add_known_hosts.yml' path] -k&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;2. SSH Server에 SSH Client의 pub 파일 등록&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2.1. Managed-Node들이 PW방식이 아닌 Key파일 방식으로 ansible 수행되도록 설정하기&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;Managed Node들에 &lt;b&gt;SSH Password 입력 없이 스크립트 수행을 하게 하기 위한 사전 작업&lt;/b&gt;이라고 생각하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;key파일을 이용하여 ansible을 사용하지 않을거라면, 이 과정은 생략해도 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;key파일 방식으로 변경을 원치 않으면, 2.2.의 과정 또한 진행하지 않아도 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;Managed Node에 로그인할 &lt;b&gt;user에 대한 ~/.ssh/authorized_keys&lt;/b&gt; 파일에 Control Node 가 생성한 SSH Public Key 내용 복사&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;yaml&quot; data-ke-language=&quot;html&quot;&gt;&lt;code&gt;# auto_authorized_keys.yml

---
- hosts: AUTHORIZED_KEYS    # {Inventory 파일에 있는 그룹명 또는 호스트명} ex) CentOS or 10.0.2.15
	gather_facts: no    # Facts : Remote host의 Hostname, CPU, Memory 정보 등을 수집하는 setup 모듈
  
  tasks:
    - name: Copy SSH Public Key from Control Node to Managed-Node
      authorized_key: 
        user: root # Managed-Node의 로그인할 user를 지정
        state: present
        key: &quot;{{ lookup('file', '/root/.ssh/id_ed25519.pub') }}&quot;
				# lookup: Control Node의 /root/.ssh/id_ed25519.pub 파일의 모든 내용을 찾는다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;playbook 수행 명령어&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;ansible-playbook -i [hosts 파일 path] ['auto_authorized_keys.yml' path] -k [-c paramiko]&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&amp;lsquo;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;-c paramiko&lt;/b&gt;&lt;/span&gt;&amp;rsquo; 를 사용하는 이유&lt;br /&gt;&lt;a style=&quot;letter-spacing: 0px;&quot; href=&quot;https://knight76.tistory.com/entry/ansible-ansible%EC%9D%98-paramiko&quot;&gt;[ansible] ansible의 paramiko&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 과정이 정상적으로 수행되었다면, 이제 ssh-agent가 가동되어 있고, 올바른 key파일로 캐싱되어 있다면, &lt;br /&gt;&lt;b&gt;ansible-playbook&lt;/b&gt; 수행 시, &lt;b&gt;-k&lt;/b&gt; &lt;b&gt;옵션을 넣지 않아도 된다!&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 아무 반응 없이 위 playbook이 수행되지 않는다면 아래 2.2 방법으로 수행해본다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2.2. 만약 Managed Node에 이미 key 파일로 로그인하도록 등록되어 있다면?&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;ansible의 특성상, ansible-playbook -k 옵션을 수행하면, SSH Password 방식으로 connection이 맺어지기 때문에, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;이미 Managed Node에 key파일 방식으로 connection이 맺어지도록 설정되어 있다면, ansible-playbook -k&lt;/b&gt; &lt;b&gt;명령어가 수행되지 못한다.&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;따라서 이런 경우에는, &lt;u&gt;Managed Node의 authorized_keys 파일에서 이미 등록되어 있는 key파일 내용을 지워줘야 한다.&lt;/u&gt; 이 과정 또한 ansible-playbook 으로 진행이 가능하므로, 아래 과정으로 진행해보자.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;2.2.1. ssh-agent 가동&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# eval : &quot;&quot; 안에 내용을 한번 검증 후 백그라운드로 실행하겠다.
# ssh-agent -s : ssh-agent 시작
eval &quot;$(ssh-agent -s)&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;2.2.2. ssh-agent에 key파일 캐싱&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;dockerfile&quot;&gt;&lt;code&gt;# ssh-keygen 으로 생성한 SSH Key 파일을 ssh-agent 에 캐싱하는 명령어
# 명령어 수행시, 최초에만 ssh-keygen 으로 key 파일 생성할 때 넣은 passphrase 입력해야 함
ssh-add ~/.ssh/id_rsa
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;2.2.3. 기존 key파일 제거하는 playbook 수행&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;참고로 아래 플레이북은 &lt;b&gt;Managed Node의 RSA 알고리즘을 사용한, root 유저 접속에 대한 키 파일&lt;/b&gt;의 내용을 삭제하는 것이다. 다른 유저로 되어 있다면, 아래 'user' key 의 값을 해당 유저로 설정해 주면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;yaml&quot; data-ke-language=&quot;html&quot;&gt;&lt;code&gt;# remove_rsa_authorized_keys.yml

---
- hosts: RSA_HOSTS
  serial: 1
  gather_facts: no

  tasks:
    - name: Remove root's public key from the authorized_keys file on the Managed-Node
      authorized_key:
        user: root
        state: absent
        key: &quot;{{ lookup('file', '/root/.ssh/id_rsa.pub') }}&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;playbook 수행 명령어&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;html&quot;&gt;&lt;code&gt;ansible-playbook -i [hosts 파일 path] ['remove_rsa_authorized_keys.yml' path] -k [-c paramiko]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;이 과정이 완료되고, 다른 알고리즘의 key 파일 방식으로 Managed Node들을 설정하고 싶다면, &lt;b&gt;hosts 파일의 [AUTHORIZED_HOSTS] 그룹에 해당 호스트의 IP들을 넣고, 2.1.의 내용을 다시 수행&lt;/b&gt;하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;3. Managed Node 들에 Ansible playbook SSH password 없이 가능한 지 테스트&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 playbook 으로 known_hosts, authorized_keys 파일 작업 수행 후에 다음과 같은 playbook 실행으로 테스트 해보도록 하자!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 playbook 은 Managed Node 들의 uptime 을 간단하게 조회하는 playbook 이다.&lt;/p&gt;
&lt;pre id=&quot;code_1745368103142&quot; class=&quot;yaml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# uptime_test.yml

---
- name: Test passwordless ssh command on managed nodes
  hosts: PLAYBOOK_TEST
  gather_facts: no
  tasks:
    - name: Run uptime command via ssh without password
      shell: ssh root@{{ inventory_hostname }} uptime
      register: uptime_output

    - name: Show uptime command result
      debug:
        msg: &quot;{{ inventory_hostname }} uptime: {{ uptime_output.stdout }}&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;playbook 수행 명령어&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1745368528434&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ansible-playbook -i [hosts 파일 path] ['uptime_test.yml' path] -k [-c paramiko]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.ansible.com/ansible/latest/plugins/lookup.html&quot;&gt;Lookup plugins &amp;mdash; Ansible Documentation&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1712068180006&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Lookup plugins &amp;mdash; Ansible Community Documentation&quot; data-og-description=&quot;Ansible Community Documentation Ansible Lookup plugins Lookup plugins are an Ansible-specific extension to the Jinja2 templating language. You can use lookup plugins to access data from outside sources (files, databases, key/value stores, APIs, and other s&quot; data-og-host=&quot;docs.ansible.com&quot; data-og-source-url=&quot;https://docs.ansible.com/ansible/latest/plugins/lookup.html&quot; data-og-url=&quot;https://docs.ansible.com/ansible/latest/plugins/lookup.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://docs.ansible.com/ansible/latest/plugins/lookup.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.ansible.com/ansible/latest/plugins/lookup.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Lookup plugins &amp;mdash; Ansible Community Documentation&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Ansible Community Documentation Ansible Lookup plugins Lookup plugins are an Ansible-specific extension to the Jinja2 templating language. You can use lookup plugins to access data from outside sources (files, databases, key/value stores, APIs, and other s&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.ansible.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.ansible.com/ansible/latest/collections/ansible/posix/authorized_key_module.html&quot;&gt;ansible.posix.authorized_key module &amp;ndash; Adds or removes an SSH authorized key &amp;mdash; Ansible Documentation&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1712068175353&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;ansible.posix.authorized_key module &amp;ndash; Adds or removes an SSH authorized key &amp;mdash; Ansible Community Documentation&quot; data-og-description=&quot;Ansible Community Documentation Ansible ansible.posix.authorized_key module &amp;ndash; Adds or removes an SSH authorized key Note This module is part of the ansible.posix collection (version 1.5.4). You might already have this collection installed if you are usin&quot; data-og-host=&quot;docs.ansible.com&quot; data-og-source-url=&quot;https://docs.ansible.com/ansible/latest/collections/ansible/posix/authorized_key_module.html&quot; data-og-url=&quot;https://docs.ansible.com/ansible/latest/collections/ansible/posix/authorized_key_module.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://docs.ansible.com/ansible/latest/collections/ansible/posix/authorized_key_module.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.ansible.com/ansible/latest/collections/ansible/posix/authorized_key_module.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;ansible.posix.authorized_key module &amp;ndash; Adds or removes an SSH authorized key &amp;mdash; Ansible Community Documentation&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Ansible Community Documentation Ansible ansible.posix.authorized_key module &amp;ndash; Adds or removes an SSH authorized key Note This module is part of the ansible.posix collection (version 1.5.4). You might already have this collection installed if you are usin&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.ansible.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a style=&quot;background-color: #e6f5ff; color: #0070d1;&quot; href=&quot;https://docs.ansible.com/ansible/latest/collections/ansible/posix/authorized_key_module.html&quot;&gt;ansible.posix.authorized_key module &amp;ndash; Adds or removes an SSH authorized key &amp;mdash; Ansible Documentation&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1712068175457&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;ansible.posix.authorized_key module &amp;ndash; Adds or removes an SSH authorized key &amp;mdash; Ansible Community Documentation&quot; data-og-description=&quot;Ansible Community Documentation Ansible ansible.posix.authorized_key module &amp;ndash; Adds or removes an SSH authorized key Note This module is part of the ansible.posix collection (version 1.5.4). You might already have this collection installed if you are usin&quot; data-og-host=&quot;docs.ansible.com&quot; data-og-source-url=&quot;https://docs.ansible.com/ansible/latest/collections/ansible/posix/authorized_key_module.html&quot; data-og-url=&quot;https://docs.ansible.com/ansible/latest/collections/ansible/posix/authorized_key_module.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://docs.ansible.com/ansible/latest/collections/ansible/posix/authorized_key_module.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.ansible.com/ansible/latest/collections/ansible/posix/authorized_key_module.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;ansible.posix.authorized_key module &amp;ndash; Adds or removes an SSH authorized key &amp;mdash; Ansible Community Documentation&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Ansible Community Documentation Ansible ansible.posix.authorized_key module &amp;ndash; Adds or removes an SSH authorized key Note This module is part of the ansible.posix collection (version 1.5.4). You might already have this collection installed if you are usin&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.ansible.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a style=&quot;color: #0070d1;&quot; href=&quot;http://www.freekb.net/Article?id=2704&quot;&gt;Append or remove SSH public certificates from&amp;nbsp;an authorized_keys file&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1712068184287&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;FreeKB&quot; data-og-description=&quot;my Interwebs Free Knowledge Base&quot; data-og-host=&quot;www.freekb.net&quot; data-og-source-url=&quot;http://www.freekb.net/Article?id=2704&quot; data-og-url=&quot;https://www.freekb.net&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cDtA7z/hyVGEAVbQf/40i3bNkYMaXg1cXCgLul31/img.png?width=1000&amp;amp;height=750&amp;amp;face=0_0_1000_750&quot;&gt;&lt;a href=&quot;http://www.freekb.net/Article?id=2704&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;http://www.freekb.net/Article?id=2704&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cDtA7z/hyVGEAVbQf/40i3bNkYMaXg1cXCgLul31/img.png?width=1000&amp;amp;height=750&amp;amp;face=0_0_1000_750');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;FreeKB&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;my Interwebs Free Knowledge Base&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.freekb.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DevOps/Ansible</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/180</guid>
      <comments>https://co-no.tistory.com/entry/Ansible-ssh-copy-id-Playbook%EC%9C%BC%EB%A1%9C-ansible-node-%EC%B4%88%EA%B8%B0-%EC%84%B8%ED%8C%85%ED%95%B4%EB%86%93%EA%B8%B0#entry180comment</comments>
      <pubDate>Tue, 2 Apr 2024 23:28:53 +0900</pubDate>
    </item>
    <item>
      <title>[Java] Java의 메모리 영역(Runtime Data Area)과 OOM 종류</title>
      <link>https://co-no.tistory.com/entry/Java-Java%EC%9D%98-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EC%98%81%EC%97%ADRuntime-Data-Area%EA%B3%BC-OOM-%EC%A2%85%EB%A5%98</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;WAS에 올라와 있는 한 애플리케이션에서 *Heap Dump 파일(&lt;b&gt;.hprof&lt;/b&gt; 파일)이 떨어져, 이번 포스팅을 계기로 Java의 Heap 메모리 영역에 대해 정리하고, OOM을 어떻게 해결할 수 있을 지 알아보려고 한다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;*Heap Dump 파일&lt;/b&gt; : Runtime 중인 애플리케이션의 힙 메모리 영역에 대한 스냅샷을 찍어 해당 내역을 저장한 파일을 일컫는다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;Java에서의 메모리 영역&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Java로 짜여진 프로그램이 실행되려면, JVM(Java Virtual Machine)이 OS로부터 정해진 메모리를 할당 받고, 해당 JVM 위에서 Java로 짜여진 프로그램이 실행되는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때, JVM에 할당된 메모리 영역(Runtime Data Area)은 용도에 따라 여러 영역으로 나누어 관리되는데, Data type별로 Stack 영역, Heap 영역, Static 영역 등으로 나뉘게 된다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;614&quot; data-origin-height=&quot;453&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cfKlSh/btsFS2RYfgq/fKa82qasMengCkySkj2Vx0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cfKlSh/btsFS2RYfgq/fKa82qasMengCkySkj2Vx0/img.png&quot; data-alt=&quot;한 JVM 에서의 Runtime Data Area 도식화 / 출처 :&amp;amp;amp;nbsp;https://velog.io/@indongcha/Runtime-Data-Area%EC%9D%98-%EA%B5%AC%EC%84%B1&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cfKlSh/btsFS2RYfgq/fKa82qasMengCkySkj2Vx0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcfKlSh%2FbtsFS2RYfgq%2FfKa82qasMengCkySkj2Vx0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;614&quot; height=&quot;453&quot; data-origin-width=&quot;614&quot; data-origin-height=&quot;453&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;한 JVM 에서의 Runtime Data Area 도식화 / 출처 :&amp;amp;nbsp;https://velog.io/@indongcha/Runtime-Data-Area%EC%9D%98-%EA%B5%AC%EC%84%B1&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;697&quot; data-origin-height=&quot;380&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgttZz/btsFTfDS3kt/24oVigPEkN8KHlDvprqp60/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgttZz/btsFTfDS3kt/24oVigPEkN8KHlDvprqp60/img.png&quot; data-alt=&quot;출처 :&amp;amp;amp;nbsp;https://www.devkuma.com/docs/jvm/memory-structure/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgttZz/btsFTfDS3kt/24oVigPEkN8KHlDvprqp60/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgttZz%2FbtsFTfDS3kt%2F24oVigPEkN8KHlDvprqp60%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;697&quot; height=&quot;380&quot; data-origin-width=&quot;697&quot; data-origin-height=&quot;380&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 :&amp;amp;nbsp;https://www.devkuma.com/docs/jvm/memory-structure/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴퓨터의 메모리는 사용할 수 있는 공간이 무한하지 않으므로, 어떻게 관리하느냐에 따라 프로그램의 성능이 좌우되며,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;이 Java 메모리 영역이 제대로 관리되지 않으면 심할 경우 서비스가 down되기도 한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서, Java 애플리케이션에서 잘 만들기 위해서는 메모리 구조와 특징에 대해 이해하고 코딩할 필요가 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;Java 변수의 종류&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Java에서는 Data type 별로 메모리 영역이 나뉜다고 하였으므로, Java에서의 Data type이 어떻게 정의되는 지 볼 필요가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Java에서의 변수는 크게 4가지로 다음과 같이 나뉜다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;클래스 변수(Class Variable, Static Variable)&lt;/b&gt;&lt;br /&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;클래스 영역에서 타입 앞에 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;static 키워드&lt;/b&gt;&lt;/span&gt;가 붙는 변수&lt;/li&gt;
&lt;li&gt;객체를 공유하는 변수로, &lt;u&gt;여러 객체에서 공통으로 사용하고 싶을 때 정의&lt;/u&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;인스턴스 변수(Instance Variable)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;클래스 영역에서&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt; static이 아닌 변수&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;개별적인 저장 공간으로, &lt;b&gt;객체/인스턴스마다 다른 값을 저장&lt;/b&gt;할 수 있음&lt;/li&gt;
&lt;li&gt;인스턴스 생성만 하고 참조 변수가 없는 경우에는 GC(Garbage Collector)에 의해 자동 제거된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;지역 변수 (Local Variable)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;메서드 내에서 선언되고, 메서드 수행이 끝나면 소멸되는 변수&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;초기값을 지정한 후에만 사용 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;매개 변수(parameter)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;메서드 호출 시, &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;'전달하는 값'을 가지고 있는 인수&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;지역 변수와 동일하게, 선언된 곳부터 수행이 끝날때까지만 유효하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;1. Method 영역&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: JVM이 동작하여 클래스 로더가 클래스를 로딩할 때 곧바로 생성되는 영역으로, JVM이 읽어들인 클래스와 인터페이스에 대한 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;Runtime Constant Pool, 멤버 변수(필드), 클래스 변수(Static 변수), 상수(final), 생성자(constructor), 메소드(method)&lt;/b&gt;&lt;/span&gt; 등을 저장하는 공간이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Method(Static) 영역에 있는 것은 &lt;u&gt;어느 곳에서나 접근이 가능&lt;/u&gt;&lt;/li&gt;
&lt;li&gt;Method(Static) 영역의 데이터는 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;프로그램의 시작부터 종료까지 컴퓨터의 메모리에 상주&lt;/b&gt;&lt;/span&gt;한다.&lt;br /&gt;-&amp;gt; Method 데이터를 무분별하게 많이 사용할 경우, 메모리 부족 현상이 일어날 수 있게 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1171&quot; data-origin-height=&quot;709&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FItq3/btsFR0mBsGq/M7mj09tb2l9Pfsvzfk7Qck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FItq3/btsFR0mBsGq/M7mj09tb2l9Pfsvzfk7Qck/img.png&quot; data-alt=&quot;출처 :&amp;amp;amp;nbsp;https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EA%B7%B8%EB%A6%BC%EC%9C%BC%EB%A1%9C-%EB%B3%B4%EB%8A%94-%EC%9E%90%EB%B0%94-%EC%BD%94%EB%93%9C%EC%9D%98-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EC%98%81%EC%97%AD%EC%8A%A4%ED%83%9D-%ED%9E%99#recentEntries&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FItq3/btsFR0mBsGq/M7mj09tb2l9Pfsvzfk7Qck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFItq3%2FbtsFR0mBsGq%2FM7mj09tb2l9Pfsvzfk7Qck%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;766&quot; height=&quot;464&quot; data-origin-width=&quot;1171&quot; data-origin-height=&quot;709&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 :&amp;amp;nbsp;https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EA%B7%B8%EB%A6%BC%EC%9C%BC%EB%A1%9C-%EB%B3%B4%EB%8A%94-%EC%9E%90%EB%B0%94-%EC%BD%94%EB%93%9C%EC%9D%98-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EC%98%81%EC%97%AD%EC%8A%A4%ED%83%9D-%ED%9E%99#recentEntries&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;2. Stack 영역&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;메소드 내에서 정의하는 기본 자료형에 해당되는 지역변수의 데이터 값이 저장되는 공간&lt;/b&gt;&lt;/span&gt;이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;메소드가 호출될 때, 스택 영역에 스택 프레임이 생기고, 스택 프레임 안에 메소드를 호출하게 됨&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;primitive 타입의 데이터(int, double, byte, long, boolean 등)&lt;/b&gt;&lt;/span&gt;에 해당되는 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;지역변수, parameter 데이터 값&lt;/b&gt;&lt;/span&gt;이 저장됨&lt;/li&gt;
&lt;li&gt;메소드가 호출될 때 메모리에 할당되고, 종료되면 메모리에서 사라짐&lt;/li&gt;
&lt;li&gt;Stack은 &lt;b&gt;LIFO(Last-In-First-Out)의 특성&lt;/b&gt;을 가지므로, &lt;u&gt;스코프의 범위를 벗어나면 스택 메모리에서 사라지게 된다.&lt;/u&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1105&quot; data-origin-height=&quot;485&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/do7MgP/btsFUGtRgRQ/KekRVl4oyDfpIAQySKzAD1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/do7MgP/btsFUGtRgRQ/KekRVl4oyDfpIAQySKzAD1/img.png&quot; data-alt=&quot;출처 :&amp;amp;amp;nbsp;https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EA%B7%B8%EB%A6%BC%EC%9C%BC%EB%A1%9C-%EB%B3%B4%EB%8A%94-%EC%9E%90%EB%B0%94-%EC%BD%94%EB%93%9C%EC%9D%98-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EC%98%81%EC%97%AD%EC%8A%A4%ED%83%9D-%ED%9E%99#recentEntries&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/do7MgP/btsFUGtRgRQ/KekRVl4oyDfpIAQySKzAD1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdo7MgP%2FbtsFUGtRgRQ%2FKekRVl4oyDfpIAQySKzAD1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;744&quot; height=&quot;327&quot; data-origin-width=&quot;1105&quot; data-origin-height=&quot;485&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 :&amp;amp;nbsp;https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EA%B7%B8%EB%A6%BC%EC%9C%BC%EB%A1%9C-%EB%B3%B4%EB%8A%94-%EC%9E%90%EB%B0%94-%EC%BD%94%EB%93%9C%EC%9D%98-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EC%98%81%EC%97%AD%EC%8A%A4%ED%83%9D-%ED%9E%99#recentEntries&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;3. Heap 영역&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: JVM이 관리하는 프로그램 상에서 데이터를 저장하기 위해, &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;Runtime 시 동적으로 할당하여 사용하는 영역&lt;/b&gt;&lt;/span&gt;이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;참조형(Reference Type) 데이터 타입을 갖는 객체(인스턴스), 배열&lt;/b&gt;&lt;/span&gt; 등이 저장되는 공간&lt;/li&gt;
&lt;li&gt;Heap 영역에 있는 인스턴스들을 가리키는 레퍼런스 변수는 Stack 영역에 적재된다.&lt;/li&gt;
&lt;li&gt;Heap 영역은 Stack 영역과 다르게, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;해당 인스턴스 또는 배열의 호출이 끝나더라도 메모리 할당이 곧바로 해제되지 않는다.&lt;/b&gt;&lt;/span&gt; 그러다 &lt;b&gt;어떤 참조 변수도 Heap 영역에 있는 인스턴스를 참조하게 않게 되었을 때, GC에 의해 메모리에서 제거&lt;/b&gt;된다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;Stack 영역은 스레드 갯수마다 각각 생성&lt;/b&gt;&lt;/span&gt;되는 반면, Heap 영역은 몇개의 스레드가 존재하든 상관없이 &lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;JVM 당 하나의 Heap 영역만 존재&lt;/b&gt;&lt;/span&gt;하게 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;OOME(Out Of Memory Error)란?&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;JVM의 메모리가 부족하여 발생한 에러&lt;/b&gt;&lt;/span&gt;로, GC의 한계점에 이르면 OOME가 나타나고, 이때 Heap Dump가 떨어지게 된다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;객체를 생성하는 과정에서 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;Heap영역에 객체를 할당하기 위한 공간이 부족&lt;/b&gt;&lt;/span&gt;한 경우 발생&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;GC를 수행하는 데 과도한 시간이 소비&lt;/b&gt;&lt;/span&gt;되어 메모리를 사용하지 못하는 경우 발생&lt;/li&gt;
&lt;li&gt;기본 할당 조건을 충족하지 못하는 경우, 네이티브 라이브러리 코드에 의해서도 발생 가능 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;(Swap 공간 부족)&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;OOME의 종류&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt; OutOfMemoryError : Java Heap space&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;◎ 원인&lt;/b&gt; : 자바 Heap 영역의 공간이 부족하여, 새로운 객체를 생성할 수 없는 경우에 발생한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Heap 영역에 대한 공간 확보는 GC를 통해 이루어지는 데,&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt; GC를 수행하기 이전에 Heap 메모리 영역이 부족할 경우&lt;/b&gt;&lt;/span&gt; 발생&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;가장 많이 확인되는 케이스&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;메모리 누수가 아닌, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;지정된 Heap size가 애플리케이션에 충분히 할당되지 않은 경&lt;/b&gt;&lt;/span&gt;우에도 발생&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;LifeCycle이 긴 애플리케이션&lt;/b&gt;&lt;/span&gt;의 경우,&lt;b&gt; finalize&lt;/b&gt;를 과도하게 사용할 때 발생하기도 함 &lt;br /&gt;&amp;rarr; finalize는 소멸을 명시적으로 할 때 사용하나, GC에 마킹하는 데 오래 걸리는 단점이 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt; OutOfMemoryError : GC Overhead limit exceeded &lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;◎ 원인&lt;/b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;:&lt;/span&gt; Heap 공간이 부족하여 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;GC가 이루어졌지만, 새로 확보된 Heap 공간이 전체 메모리의 2% 미만&lt;/b&gt;&lt;/span&gt;일 때 발생&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&amp;lsquo;Java Heap Space&amp;rsquo; 케이스와 유사하게 &lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;자주 발생하는 이슈&lt;/b&gt;&lt;/span&gt;로,&lt;b&gt; &lt;span style=&quot;color: #f89009;&quot;&gt;무분별하게 객체를 생성할 경우&lt;/span&gt;&lt;/b&gt; 발생&lt;/li&gt;
&lt;li&gt;&lt;u&gt;더 이상 GC를 할 수 없을 정도로 메모리를 과도하게 사용한다는 것&lt;/u&gt;&lt;/li&gt;
&lt;li&gt;문제점을 해결하고, 경우에 따라 Heap 메모리 사이즈를 늘리는 것을 추천&lt;/li&gt;
&lt;li&gt;-XX:-UseGCOverheadLimit 옵션을 사용하여, GC Overhead에 대한 limit 자체를 꺼버릴 수도 있지만, 추천하지 않음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt; OutOfMemoryError : Requested array size exceeds VM limit &lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;◎ 원인&lt;/b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;:&amp;nbsp;&lt;/span&gt;애플리케이션 혹은 애플리케이션을 사용하는 API가 할당된 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;Heap 공간보다 큰 사이즈의 배열 할당을 시도&lt;/b&gt;&lt;/span&gt;하는 경우 발생&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;배열 사이즈를 조정&lt;/b&gt;&lt;/span&gt;하거나 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;Heap 메모리 사이즈를 증가시켜서&lt;/b&gt;&lt;/span&gt; 해결&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt; OutOfMemoryError : Metaspace &lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;◎ 원인 &lt;/b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;: &lt;/span&gt;자바 클래스의 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;메타데이터(클래스 이름, 생성 정보, 필드 정보, 메서드 정보 등)가 저장되는 *PermGen 또는 *Metaspace의 공간이 부족할 경우&lt;/b&gt;&lt;/span&gt; 발생. Metaspace의 경우, 자동으로 크기를 증가하는 과정보다 더 많은 메타 데이터들이 저장되면 이 에러가 발생할 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;u&gt;클래스의 메타데이터가 저장되는 공간&lt;/u&gt;으로, JDK7 이전에는 PermGen으로 정의되었음&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;-XX:MetaspaceSize, -XX:MaxMetaspaceSize 설정&lt;/b&gt;&lt;/span&gt;을 추가하여 오류를 해결할 수도 있음 (default는 20MB)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;*PermGen(Permanent Generation)&lt;/b&gt; : &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;Java7&lt;/b&gt; &lt;/span&gt;에서의 메타데이터가 저장되는 영역&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;**Metaspace&lt;/b&gt; : PermGen 영역은 Heap 메모리에 포함되어, 작은 사이즈로 설정되었기 때문에, GC가 빈번히 발생하였는데, 이러한 문제를 개선하고자 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;Java8&lt;/b&gt;&lt;/span&gt;에서는 Heap 메모리 영역에서 분리하여,&lt;b&gt; OS에서 제공하는 native 메모리 영역을 사용하도록 한 영역.&lt;/b&gt; GC를 수행하지 않고도 자동으로 크기를 증가 시켜 공간을 확보할 수 있게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt; OutOfMemoryError : request size bytes for reason. Out of swap space?&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;◎ 원인&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;:&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;자바 HotSpot VM 코드가 Native heap을 고갈시켜&lt;/b&gt;&lt;/span&gt;, Native heap에 할당할 수 없는 경우 발생&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이 에러 코드와 함께 실패한 요청의 바이트 크기와 메모리 요청의 이유를 나타내며, &lt;u&gt;대개의 경우 메모리 할당에 실패한 소스 모듈의 이름을 출력한다.&lt;/u&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;Heap 메모리 로그&lt;/b&gt;&lt;/span&gt; 또는 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;Memory-map 정보를 분석하는 것이 유용&lt;/b&gt;&lt;/span&gt;하다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;OS의 문제 유틸리티(Native Operation System tools 등)&lt;/b&gt;를 사용하여 문제를 진단할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt; OutOfMemoryError : unable to create native thread&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;◎ 원인&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;:&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt; 시스템 리소스 제한에 도달하여 새로운 네이티브 스레드를 생성할 수 없을 때 발생&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;Thread를 과도하게 많이 사용하는 경우&lt;/b&gt;&lt;/span&gt; 발생할 수 있음&lt;/li&gt;
&lt;li&gt;&lt;u&gt;OS의 메모리가 부족해서일 수도 있고, OS 자체적으로 쓰레드 개수를 제한해서일 수도&lt;/u&gt; 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EA%B7%B8%EB%A6%BC%EC%9C%BC%EB%A1%9C-%EB%B3%B4%EB%8A%94-%EC%9E%90%EB%B0%94-%EC%BD%94%EB%93%9C%EC%9D%98-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EC%98%81%EC%97%AD%EC%8A%A4%ED%83%9D-%ED%9E%99#recentEntries&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EA%B7%B8%EB%A6%BC%EC%9C%BC%EB%A1%9C-%EB%B3%B4%EB%8A%94-%EC%9E%90%EB%B0%94-%EC%BD%94%EB%93%9C%EC%9D%98-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EC%98%81%EC%97%AD%EC%8A%A4%ED%83%9D-%ED%9E%99#recentEntries&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1710858840943&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;☕ 그림으로 보는 자바 코드의 메모리 영역(스택 &amp;amp; 힙)&quot; data-og-description=&quot;자바의 메모리 영역 이번 포스팅에선 자바(JAVA)를 사용하는 입장에서 알아야 할 메모리 구조 및 특징에 대해서 알아보려고 한다. 자바 프로그램이 실행되면 JVM(자바 가상 머신)은 OS로부터 메모&quot; data-og-host=&quot;inpa.tistory.com&quot; data-og-source-url=&quot;https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EA%B7%B8%EB%A6%BC%EC%9C%BC%EB%A1%9C-%EB%B3%B4%EB%8A%94-%EC%9E%90%EB%B0%94-%EC%BD%94%EB%93%9C%EC%9D%98-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EC%98%81%EC%97%AD%EC%8A%A4%ED%83%9D-%ED%9E%99#recentEntries&quot; data-og-url=&quot;https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EA%B7%B8%EB%A6%BC%EC%9C%BC%EB%A1%9C-%EB%B3%B4%EB%8A%94-%EC%9E%90%EB%B0%94-%EC%BD%94%EB%93%9C%EC%9D%98-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EC%98%81%EC%97%AD%EC%8A%A4%ED%83%9D-%ED%9E%99&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bKZyOM/hyVDtK2Jg4/X1FI8I2BGrGzrDCmocnr4k/img.png?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/wyvkD/hyVDFkpNXX/9fE3q2nfqLCgPouhsZ9gq1/img.png?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/bC4E8d/hyVDHCwzkP/irDgUKojiarNvGIcnjFuv0/img.png?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot;&gt;&lt;a href=&quot;https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EA%B7%B8%EB%A6%BC%EC%9C%BC%EB%A1%9C-%EB%B3%B4%EB%8A%94-%EC%9E%90%EB%B0%94-%EC%BD%94%EB%93%9C%EC%9D%98-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EC%98%81%EC%97%AD%EC%8A%A4%ED%83%9D-%ED%9E%99#recentEntries&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EA%B7%B8%EB%A6%BC%EC%9C%BC%EB%A1%9C-%EB%B3%B4%EB%8A%94-%EC%9E%90%EB%B0%94-%EC%BD%94%EB%93%9C%EC%9D%98-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EC%98%81%EC%97%AD%EC%8A%A4%ED%83%9D-%ED%9E%99#recentEntries&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bKZyOM/hyVDtK2Jg4/X1FI8I2BGrGzrDCmocnr4k/img.png?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/wyvkD/hyVDFkpNXX/9fE3q2nfqLCgPouhsZ9gq1/img.png?width=800&amp;amp;height=450&amp;amp;face=0_0_800_450,https://scrap.kakaocdn.net/dn/bC4E8d/hyVDHCwzkP/irDgUKojiarNvGIcnjFuv0/img.png?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;☕ 그림으로 보는 자바 코드의 메모리 영역(스택 &amp;amp; 힙)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;자바의 메모리 영역 이번 포스팅에선 자바(JAVA)를 사용하는 입장에서 알아야 할 메모리 구조 및 특징에 대해서 알아보려고 한다. 자바 프로그램이 실행되면 JVM(자바 가상 머신)은 OS로부터 메모&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;inpa.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;a href=&quot;https://incheol-jung.gitbook.io/docs/q-and-a/java/heap-dump-feat.-oom&quot;&gt;https://incheol-jung.gitbook.io/docs/q-and-a/java/heap-dump-feat.-oom&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1710858861318&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;heap dump 분석하기 (feat. OOM) | Incheol's TECH BLOG&quot; data-og-description=&quot;  만약 메모리가 8 GB의 인스턴스에서 아무런 설정 없이 애플리케이션을 운영한다면? 최대 메모리 사이즈 : 8GB / 4 = 2GB 초기 메모리 사이즈 : 8GB / 64 = 127MB&quot; data-og-host=&quot;incheol-jung.gitbook.io&quot; data-og-source-url=&quot;https://incheol-jung.gitbook.io/docs/q-and-a/java/heap-dump-feat.-oom&quot; data-og-url=&quot;https://incheol-jung.gitbook.io/docs/q-and-a/java/heap-dump-feat.-oom&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://incheol-jung.gitbook.io/docs/q-and-a/java/heap-dump-feat.-oom&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://incheol-jung.gitbook.io/docs/q-and-a/java/heap-dump-feat.-oom&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;heap dump 분석하기 (feat. OOM) | Incheol's TECH BLOG&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;  만약 메모리가 8 GB의 인스턴스에서 아무런 설정 없이 애플리케이션을 운영한다면? 최대 메모리 사이즈 : 8GB / 4 = 2GB 초기 메모리 사이즈 : 8GB / 64 = 127MB&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;incheol-jung.gitbook.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://devhtak.github.io/java%20study/2021/07/29/Java_OOM.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://devhtak.github.io/java%20study/2021/07/29/Java_OOM.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1710858879488&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Java - OOM 종류 및 조치&quot; data-og-description=&quot;Heap&quot; data-og-host=&quot;devhtak.github.io&quot; data-og-source-url=&quot;https://devhtak.github.io/java%20study/2021/07/29/Java_OOM.html&quot; data-og-url=&quot;https://devhtak.github.io/java%20study/2021/07/29/Java_OOM.html&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bDdBhY/hyVAAyhklz/shozRjqZi3mKlthyb8Ljxk/img.png?width=756&amp;amp;height=243&amp;amp;face=0_0_756_243&quot;&gt;&lt;a href=&quot;https://devhtak.github.io/java%20study/2021/07/29/Java_OOM.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://devhtak.github.io/java%20study/2021/07/29/Java_OOM.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bDdBhY/hyVAAyhklz/shozRjqZi3mKlthyb8Ljxk/img.png?width=756&amp;amp;height=243&amp;amp;face=0_0_756_243');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Java - OOM 종류 및 조치&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Heap&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;devhtak.github.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Java</category>
      <category>Java OOM 종류</category>
      <category>Java OOM 해결방법</category>
      <category>자바 메모리 스택</category>
      <category>자바 힙 메모리</category>
      <category>자바 힙 스택</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/171</guid>
      <comments>https://co-no.tistory.com/entry/Java-Java%EC%9D%98-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EC%98%81%EC%97%ADRuntime-Data-Area%EA%B3%BC-OOM-%EC%A2%85%EB%A5%98#entry171comment</comments>
      <pubDate>Wed, 20 Mar 2024 09:00:24 +0900</pubDate>
    </item>
    <item>
      <title>[개념] 프롬프트 엔지니어링의 개념과 LLM 활용 시 꿀팁</title>
      <link>https://co-no.tistory.com/entry/%EA%B0%9C%EB%85%90-%ED%94%84%EB%A1%AC%ED%94%84%ED%8A%B8-%EC%97%94%EC%A7%80%EB%8B%88%EC%96%B4%EB%A7%81%EC%9D%98-%EA%B0%9C%EB%85%90%EA%B3%BC-LLM-%ED%99%9C%EC%9A%A9-%EC%8B%9C-%EA%BF%80%ED%8C%81</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;프롬프트 엔지니어링을 얘기하기 전에, LLM이 무엇인지 정확히 알고 가자!&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;LLM(Large Language Model, 대규모 언어 모델)이란?&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: 빅데이터 시대에 등장한 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;수억 개의 매개 변수를 가진 인공신경망으로 이루어진 거대한 언어모&lt;/b&gt;&lt;/span&gt;델로, 대량의 텍스트 데이터, 특히 &lt;b&gt;인간의 자연어 처리를 위해 학습된다.&lt;/b&gt; 이러한 언어 모델은, &lt;b&gt;주어진 문맥 정보를 바탕으로 텍스트를 생성하거나 이해하는 데에 사용&lt;/b&gt;된다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;LLM의 주요 특징&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;대량의 데이터 학습&lt;/b&gt; : 웹상의 텍스트(Wikipedia, Github, Twittwer 등), 책, 기사 등 다양한 소스에서 수십 또는 수백 GB의 텍스트 데이터에 대해 학습한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;수억 개의 매개 변수&lt;/b&gt; : LLM은 수억 또는 그 이상의 매개변수를 포함할 수 있으며, 이로 인해 더 복잡한 패턴과 구조를 학습할 수 있게 된다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;다양한 태스크 수행&lt;/b&gt; : LLM은 다양한 자연어 처리 태스크를 수행할 수 있는데, 이를테면, 텍스트 생성, 질문 응답, 번역, 요약 등의 작업을 수행할 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;전이 학습(Transfer Learning)&lt;/b&gt; : 하나의 문제를 해결하고 이와 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;다르면서 관련된 문제에 적용하는 동안 얻은 지식을 저장하는 데에 집중&lt;/b&gt;&lt;/span&gt;하는 기계 학습 기법이다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ef6f53;&quot;&gt;&lt;b&gt;Emergent Ability&lt;/b&gt;&lt;/span&gt; : 데이터의 학습량에 따라 성능이 미미하다가, &lt;span style=&quot;color: #ef6f53;&quot;&gt;&lt;b&gt;특정 임계점을 지나면 급작스럽게 뛰어난 퍼포먼스 및 자연어 처리 능력을 갖추게 되는 것&lt;/b&gt;&lt;/span&gt;이 &lt;b&gt;LLM의 특징&lt;/b&gt;이다. Emergent Ability를 갖게 되면, 다음과 같은 3가지 특징을 띄게 된다.
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;Instruction Following&lt;/b&gt;&lt;/span&gt; : &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;명령어를 그대로 따르는 특성&lt;/b&gt;&lt;/span&gt;이다.&lt;b&gt; Emergent Ability 단계 이전&lt;/b&gt;의 언어 모델은, &lt;u&gt;앞뒤 문맥을 파악하여 정답일 확률이 높은 문장들을 내어주거나 학습된 문장들 중 비슷한 문장을 쿼리해주는 역할&lt;/u&gt;이 위주인 반면, &lt;b&gt;Emergent Ability 단계 이후&lt;/b&gt;의 언어 모델은, 단순 확률 및 쿼리에 그치지 않고, &lt;b&gt;앞에 있던 문장을 이해해서 그것의 지시를 따르는 수준까지 이르게 되는 것&lt;/b&gt;이다.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;프롬프트 예시)&lt;/b&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;&lt;span style=&quot;color: #409d00;&quot;&gt; &lt;b&gt;양자역학의 불확정성의 원리에 대해 200자 이내로 설명해줘.&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;In-Context Learning(ICL)&lt;/b&gt; : &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;맥락&lt;/b&gt;&lt;/span&gt;을 굉장히 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;잘 파악&lt;/b&gt;&lt;/span&gt;하고, 해당 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;맥락에 맞는 텍스트를 생성&lt;/b&gt;&lt;/span&gt;할 줄 안다. 이를 통해, &lt;u&gt;문서에 대한 유사도 검색까지도 가능&lt;/u&gt;해진다.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;프롬프트 예시1)&lt;/b&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;&lt;span style=&quot;color: #409d00;&quot;&gt; &lt;b&gt;너는 리처드 파인만이고, 나는 물리학에 대해 아무것도 모르는 일반인이다. 일반인도 이해하기 쉽게 불확정성 원리에 대해 200자 이내로 설명해줘.&lt;/b&gt; &lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;&lt;b&gt;프롬프트 예시2)&lt;/b&gt; &lt;br /&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt; &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;다음 글을 참고하여 홍길동이 밥을 언제 먹었는지 알려줘라.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;&quot;&quot;&quot;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;새벽녘, 홍길동은 쌀로 만든 따뜻한 국물 요리와 신선한 야채 샐러드로 아침을 시작했다. 향긋한 녹차로 마무리 지으며, 하루를 여는 에너지를 얻었다. 정오가 되자, 그는 해산물과 여러 채소가 들어간 김치찌개와 바삭한 김 몇 조각을 즐겼다. 오후 시간에는 과일과 견과류로 달콤하고 건강한 간식을 골랐다.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;저녁이 되어, 홍길동은 구운 닭고기와 다양한 야채를 곁들인 샐러드를 택했다. 밤이 깊어감에 따라, 그는 가벼운 야식으로 우유와 쿠키를 조금 취했다. 이렇게 홍길동은 하루 종일 다양한 음식을 취하며 건강하고 활기찬 하루를 보냈다.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;&quot;&quot;&quot;&lt;/b&gt;&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Step-by-step Reasoning&lt;/b&gt; : LLM의 단점에서 기인한 것으로,&lt;span style=&quot;color: #ef6f53;&quot;&gt;&lt;b&gt; LLM은 논리적 추론 능력은 뛰어나지 못하다.&lt;/b&gt;&lt;/span&gt; 그래서 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;커다란 질의를 단계별 또는 작은 단위의 태스크들로 수행하게끔&lt;/b&gt;&lt;/span&gt; 하면, 작은 단위에서의 &lt;u&gt;파악할 문맥 및 논리가 급격히 줄어들기 때문&lt;/u&gt;에 더 잘 수행하는 특징이 있다.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;프롬프트 예시)&lt;/b&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;다음 문제를 보고 Data analysis를 사용하지 말고, 문제를 다시 말하거나 풀이과정 없이 답만 말해라.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;&quot;&quot;&quot;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;A는 현재 총 5개의 테니스공을 가지고 있다.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;테니스를 칠 때마다 시간당 1개의 공을 잃어버린다.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;테니스를 치기 전 다음의 규칙에 따라 공을 구매해야 한다.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;1. 공이 2개 이하로 남아있다.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;2. 해당 주에 공을 구매한 적이 없어야 한다. (월요일부터 일요일까지를 한 주로 본다.)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;3. 공은 한 번 구매할 때 5개씩 구매한다.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;평일에는 1시간씩 테니스를 치고, 토/일요일에는 하루에 2시간씩 친다.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;오늘은 월요일이며 오늘부터 1일차라고 했을 때, A가 공이 없어서 테니스를 치지 못하는 날은 몇일차인가?&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;&quot;&quot;&quot;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;b&gt;프롬프트 보완)&lt;/b&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;&lt;b&gt; 날짜별로 다음의 항목을 표시하여 다시 계산하여라.&lt;/b&gt;&lt;br /&gt;&lt;b&gt;[n]주차 {요일} : 공 m개가 남아 있음. {공을 구매함} l개 소모. 총 K개 남음. 이번주 구매내역 {있음/없음}&lt;/b&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;LLM의 한계&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;최신의 데이터&lt;/b&gt;&lt;/span&gt;가 학습되어 있지 않다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;할루시네이션(Hallucination)&lt;/b&gt; : AI 모델이 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;정확하지 않거나 사실이 아닌 조작된 정보를 생성&lt;/b&gt;&lt;/span&gt;하는 것을 의미&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;근거자료가 부족&lt;/b&gt;&lt;/span&gt;하다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;커스터마이징에 어려움&lt;/span&gt;&lt;/b&gt;이 있다. 다시 학습시키거나 fine-tuning조차도 비용이 상당히 많이 든다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;프롬프트 엔지니어링(Prompt Engineering)이란?&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;: NLP 분야의 개념으로, &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;AI가 생성하는 결과물의 품질을 높일 수 있는 *프롬프트 입력값들의 조합을 찾는 작업&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;*프롬프트(Prompt)&lt;/b&gt; : AI 분야에서의 프롬프트는, &lt;b&gt;AI 모델로부터 응답을 생성하기 위한 입력값&lt;/b&gt;이라고 정의할 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;프롬프트는 다음과 같은 구성 요소를 가지며, 해당 요소들을 반드시 모두 포함하여야 하는 것은 아니다.&lt;/p&gt;
&lt;h4 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;프롬프트의 구성 요소&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;Instruction&lt;/b&gt; : 모델이 수행하기를 원하는 특정 Task 또는 지시 사항&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Context&lt;/b&gt; : 모델이 보다 더 나은 답변을 하도록 유도하는 외부 정보 또는 추가 내용&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Input Data&lt;/b&gt; : 답을 구하고자 하는 것에 대한 Input 또는 Query문&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Output Indicator&lt;/b&gt; : 결과물의 유형 또는 형식을 나타내는 요소&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;프롬프트를 잘 사용하는 방법은, LLM의 특성을 얼마나 최대한으로 활용하는가로 볼 수 있다.&lt;/p&gt;
&lt;h3 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;프롬프트 작성을 위한 기본 가이드라인&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1. &lt;span style=&quot;color: #006dd7;&quot;&gt;대화 스타일&lt;/span&gt; 조정&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;API를 호출하여 사용할 경우, AI 모델의 대화 스타일을 조정할 수 있는 주요 값들이 있는데, 이것들을 적절히 조율할 경우, 프롬프트 결과의 정확도를 높일 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Temperature&lt;/b&gt; : 답변의 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;창의성과 무작위성을 조정&lt;/b&gt;&lt;/span&gt;하는 값. &lt;br /&gt;최소 &lt;b&gt;0&lt;/b&gt;, 최대&lt;b&gt; 1&lt;/b&gt;의 값을 가지며, &lt;u&gt;해당값이 낮을수록 사실에 근거한 정확한 답변을 제공&lt;/u&gt;하고, 높을수록 보다 창의적인 결과물을 생성하게 된다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Top_p&lt;/b&gt; : &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;답변의 무작위성&lt;/b&gt;&lt;/span&gt;을 제어하는 조정값.&lt;br /&gt;Temperature와 마찬가지로,&lt;u&gt; 값이 낮을수록 답변이 보다 정확&lt;/u&gt;하고 높아질수록 창의적이고 광범위해진다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;frequency_penalty&lt;/b&gt; : &lt;u&gt;값이 높을수록 AI가 기존 답변에서 많이 사용하는 단어를 답변에 포함하도록&lt;/u&gt; 한다.&lt;br /&gt;반대로 값이 0이라면, 페널티가 전혀 주어지지 않아, AI가 흔히 사용되지 않는 단어를 답변에 포함할 가능성을 높이게 된다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;presence_penalty&lt;/b&gt; : &lt;u&gt;값이 높을수록 AI가 유사하거나 동일한 단어 및 문구를 답변 시 반복할 가능성을 낮추게&lt;/u&gt; 된다.&lt;br /&gt;반대로 값이 0이라면, 페널티가 전혀 주어지지 않아,&amp;nbsp; AI가 단어나 문구를 반복할 가능성이 높아지게 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2. &lt;span style=&quot;color: #006dd7;&quot;&gt;미사여구를 최소화&lt;/span&gt;하여 &lt;span style=&quot;color: #006dd7;&quot;&gt;쉽고 간결&lt;/span&gt;하게 표현&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;프롬프트로서 &lt;span style=&quot;color: #ee2323;&quot;&gt;비추천&lt;/span&gt; 예시)&lt;/b&gt;&amp;nbsp;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; &lt;span style=&quot;color: #409d00; text-align: start;&quot;&gt;혹시 가능하다면, 인공지능 분야에서 트랜스포머가 어떤 개념인지, 파이썬이나 C++같은 프로그래밍 언어들을 한 번도 활용 해본 적 없는 모든 사람들을 대상으로 알아듣기 쉽게 글로 설명해줄 수 있어?&lt;/span&gt; &lt;/b&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;위 예시를 &lt;span style=&quot;color: #006dd7;&quot;&gt;개선&lt;/span&gt;한 프롬프트)&lt;/b&gt;&amp;nbsp;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; &lt;span style=&quot;color: #409d00; text-align: start;&quot;&gt;비개발자들을 대상으로 트랜스포머의 개념을 쉽게 설명해줘.&lt;/span&gt; &lt;/b&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3. &lt;span style=&quot;color: #ee2323;&quot;&gt;열린 질문&lt;/span&gt;보다는 &lt;span style=&quot;color: #006dd7;&quot;&gt;닫힌 지시문을 사용&lt;/span&gt;할 것&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;LLM의 &lt;b&gt;Instruction Following 특징을 잘 활용하기 위해&lt;/b&gt; 지정된 프롬프트 가이드라인이라고 볼 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;다음과 같이, 모호하고 주관적인 답변이 많이 가능할 것 같은 질문보다는, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;LLM이 적절한 근거를 들어 답변을 낼 수 있도록 보고서와 같은 Form을 함께 제시하여&amp;nbsp;&lt;/b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;지시문을 사용해야, 맥락을 이해하고 해당 지시를 잘 따를 수 있게 된다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;프롬프트로서 &lt;span style=&quot;color: #ee2323;&quot;&gt;비추천&lt;/span&gt; 예시)&lt;/b&gt;&amp;nbsp;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; &lt;span style=&quot;color: #409d00; text-align: start;&quot;&gt;프롬프트 엔지니어라는 직업이 미래에도 지속될 수 있을까?&lt;/span&gt; &lt;/b&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;위 예시를 &lt;span style=&quot;color: #006dd7;&quot;&gt;개선&lt;/span&gt;한 프롬프트)&lt;/b&gt;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; &lt;span style=&quot;color: #409d00; text-align: start;&quot;&gt;프롬프트 엔지니어가 미래에도 지속될 수 있는 직업인지에 대한 보고서를 써줘.&lt;/span&gt; &lt;/b&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;4. &lt;span style=&quot;color: #006dd7;&quot;&gt;Instruction&lt;/span&gt;과 &lt;span style=&quot;color: #006dd7;&quot;&gt;Context&lt;/span&gt;를 구체적으로 명시&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;구분 기호를 사용하여 참고 문장 또는 &lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;맥락 문장(Context)&lt;/span&gt;를 &lt;span style=&quot;color: #ef6f53;&quot;&gt;앞&lt;/span&gt;에 작성&lt;/b&gt;하며, &lt;b&gt;지시 문장(Instruction)&lt;/b&gt;은 가능한 &lt;b&gt;&lt;span style=&quot;color: #ef6f53;&quot;&gt;맨 뒤&lt;/span&gt;&lt;/b&gt;에 사용하는 것이 좋다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;아래 링크의 예시를 통해 살펴보자!&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://chatx.ai/marketplace/chatgpt/write-a-novel-with-chatgpt/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://chatx.ai/marketplace/chatgpt/write-a-novel-with-chatgpt/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1705313574250&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Write a novel with ChatGPT - ChatX&quot; data-og-description=&quot;This ChatGPT prompt can help you with a starting point. By using this prompt, you can generate ideas for characters, storylines, and settings.&quot; data-og-host=&quot;chatx.ai&quot; data-og-source-url=&quot;https://chatx.ai/marketplace/chatgpt/write-a-novel-with-chatgpt/&quot; data-og-url=&quot;https://chatx.ai/marketplace/chatgpt/write-a-novel-with-chatgpt/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b7QZgI/hyU5T5eWMQ/2raOrlNneKPuA8XRPhiBK0/img.jpg?width=750&amp;amp;height=500&amp;amp;face=0_0_750_500,https://scrap.kakaocdn.net/dn/sWfk7/hyU5KULIk5/h5EWn2EzJ1zUv12poibqq1/img.jpg?width=750&amp;amp;height=500&amp;amp;face=0_0_750_500,https://scrap.kakaocdn.net/dn/cJX62L/hyU5LzmPNA/Krz0g7NHbECA29UNAk68u0/img.jpg?width=750&amp;amp;height=500&amp;amp;face=0_0_750_500&quot;&gt;&lt;a href=&quot;https://chatx.ai/marketplace/chatgpt/write-a-novel-with-chatgpt/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://chatx.ai/marketplace/chatgpt/write-a-novel-with-chatgpt/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b7QZgI/hyU5T5eWMQ/2raOrlNneKPuA8XRPhiBK0/img.jpg?width=750&amp;amp;height=500&amp;amp;face=0_0_750_500,https://scrap.kakaocdn.net/dn/sWfk7/hyU5KULIk5/h5EWn2EzJ1zUv12poibqq1/img.jpg?width=750&amp;amp;height=500&amp;amp;face=0_0_750_500,https://scrap.kakaocdn.net/dn/cJX62L/hyU5LzmPNA/Krz0g7NHbECA29UNAk68u0/img.jpg?width=750&amp;amp;height=500&amp;amp;face=0_0_750_500');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Write a novel with ChatGPT - ChatX&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;This ChatGPT prompt can help you with a starting point. By using this prompt, you can generate ideas for characters, storylines, and settings.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;chatx.ai&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;소설가로서의 역할과 목표&lt;/b&gt;&lt;/span&gt;를 chatgpt에게 &lt;b&gt;Context&lt;/b&gt;로 알려주고, 이후 &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;사용자가 실제 원하는&lt;/b&gt;&lt;/span&gt; &lt;b&gt;Instruction&lt;/b&gt;에 대해서는 특수 문자로 묶어준 &lt;b&gt;예시)&lt;/b&gt;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;소설가로서 너의 임무는 독자의 마음을 사로잡고 오랜 시간동안 몰입할 수 있는 이야기를 만드는거야.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;장르는 판타지, 로맨스, 역사 소설 등 어떤 장르든 자유롭게 선택 가능해.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;주요 목표는 매력적인 줄거리, 잘 발달된 캐릭터, 놀라운 클라이맥스로 눈에 띄는 이야기를 만드는 거야.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;너의 첫 번째 과제는,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;[다른 행성에 사는 한 남자의 이야기를 다룬 공상과학 소설을 작성하는 것으로, 미래 기술, 외계 생명체, 환상적인 개념을 다룰 수 있어. 너의 이야기는 독자들을 모험과 미스터리 흥분으로 가득 찬 흥미진진한 신세계로 안내해야 해. 목표는 독자들에게 깊은 인상을 남길 수 있는, 생각을 자극하는 동시에 재미있는 공상 과학 소설을 만드는거야.]&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h4 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;5. &lt;span style=&quot;color: #006dd7;&quot;&gt;예제&lt;/span&gt;를 함께 제공&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Main-Task 또는 Instruction을 요청하기 전, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;올바른 질문과 답변 예제를 한 개 또는 다수 제공&lt;/b&gt;&lt;/span&gt;하는 기법을 활용할 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;6. &lt;span style=&quot;color: #006dd7;&quot;&gt;RAG&lt;/span&gt;를 활용&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;RAG(Retrieval Augmented Generation, 검색 증강 생성)&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #ef6f53;&quot;&gt;&lt;b&gt;외부 소스에서 가져온 정보&lt;/b&gt;&lt;/span&gt;로 생성형 AI 모델의 &lt;b&gt;정확성과 신뢰성을 향상&lt;/b&gt;시키는 기술&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;gt; LLM 모델의 학습되어 있는 데이터만 활용하지 않고, &lt;b&gt;모델 외부의 자료&lt;/b&gt;도 답을 도출하는 데에 함께 사용할 수 있도록 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;gt; 모델 학습 없이도 외부 데이터를 사용함으로써 &lt;b&gt;최신 데이터에 기반&lt;/b&gt;으로 한 정답에 대한 정확도가 올라간다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;gt; 이에 따라 &lt;b&gt;최신 회사 정보도 활용이 가능&lt;/b&gt;하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;RAG의 한계점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;내부 데이터&lt;/b&gt;의 DB/검색엔진의 &lt;span style=&quot;color: #ef6f53;&quot;&gt;&lt;b&gt;성능이 매우 중요&lt;/b&gt;&lt;/span&gt;하다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;RAG을 위한 &lt;span style=&quot;color: #ef6f53;&quot;&gt;별도의 내부 시스템&lt;/span&gt;&lt;/b&gt; 구축이 필요하다.&lt;/li&gt;
&lt;li&gt;Hallucination 및 부정확한 결과 출력을 &lt;span style=&quot;color: #ef6f53;&quot;&gt;&lt;u&gt;&lt;b&gt;100% 막을 수는 없다.&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=rMJErYfGLCU&amp;amp;t=310s&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.youtube.com/watch?v=rMJErYfGLCU&amp;amp;t=310s&lt;/a&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=rMJErYfGLCU&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/g9bTh/hyU2pQwLeN/DStWBi1oFZvX6SaAaCQG4K/img.jpg?width=640&amp;amp;height=480&amp;amp;face=0_0_640_480&quot; data-video-width=&quot;640&quot; data-video-height=&quot;480&quot; data-video-origin-width=&quot;640&quot; data-video-origin-height=&quot;480&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-original-url=&quot;&quot; data-video-title=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/rMJErYfGLCU&quot; width=&quot;640&quot; height=&quot;480&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption style=&quot;display: none;&quot;&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://tech.kakaoenterprise.com/188&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://tech.kakaoenterprise.com/188&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1704719032081&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[IT TREND] 프롬프트 엔지니어링, AI라는 도구를 잘 사용하는 방법&quot; data-og-description=&quot;시작하며 생성형 AI, 그 중에서도 특히 거대 언어 모델들을 중심으로 기술 시장은 이례없던 속도로 움직이고 있습니다. 대중의 생성형 AI에 대한 높아진 관심을 기반으로 다양한 애플리케이션 사&quot; data-og-host=&quot;tech.kakaoenterprise.com&quot; data-og-source-url=&quot;https://tech.kakaoenterprise.com/188&quot; data-og-url=&quot;https://tech.kakaoenterprise.com/188&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ODnmm/hyU2r8EWbV/gdqYcwJxtLDQ7RxJBGljkk/img.png?width=800&amp;amp;height=360&amp;amp;face=0_0_800_360,https://scrap.kakaocdn.net/dn/nFMf0/hyU2mfbvkm/nF94sgoevfcIZlw1TuGC8k/img.png?width=800&amp;amp;height=360&amp;amp;face=0_0_800_360,https://scrap.kakaocdn.net/dn/pu2H2/hyU2jbHMiH/My8oe6kDRJLeNgSFIPoa8k/img.png?width=2048&amp;amp;height=1090&amp;amp;face=0_0_2048_1090&quot;&gt;&lt;a href=&quot;https://tech.kakaoenterprise.com/188&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://tech.kakaoenterprise.com/188&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ODnmm/hyU2r8EWbV/gdqYcwJxtLDQ7RxJBGljkk/img.png?width=800&amp;amp;height=360&amp;amp;face=0_0_800_360,https://scrap.kakaocdn.net/dn/nFMf0/hyU2mfbvkm/nF94sgoevfcIZlw1TuGC8k/img.png?width=800&amp;amp;height=360&amp;amp;face=0_0_800_360,https://scrap.kakaocdn.net/dn/pu2H2/hyU2jbHMiH/My8oe6kDRJLeNgSFIPoa8k/img.png?width=2048&amp;amp;height=1090&amp;amp;face=0_0_2048_1090');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[IT TREND] 프롬프트 엔지니어링, AI라는 도구를 잘 사용하는 방법&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;시작하며 생성형 AI, 그 중에서도 특히 거대 언어 모델들을 중심으로 기술 시장은 이례없던 속도로 움직이고 있습니다. 대중의 생성형 AI에 대한 높아진 관심을 기반으로 다양한 애플리케이션 사&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;tech.kakaoenterprise.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;</description>
      <category>CS 지식 | 기초 용어,개념</category>
      <category>AI 프롬프트 팁</category>
      <category>Chatgpt 잘 쓰는 법</category>
      <category>LLM 잘 쓰는 법</category>
      <category>LLM 프롬프트 팁</category>
      <category>프롬프트 엔지니어링</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/164</guid>
      <comments>https://co-no.tistory.com/entry/%EA%B0%9C%EB%85%90-%ED%94%84%EB%A1%AC%ED%94%84%ED%8A%B8-%EC%97%94%EC%A7%80%EB%8B%88%EC%96%B4%EB%A7%81%EC%9D%98-%EA%B0%9C%EB%85%90%EA%B3%BC-LLM-%ED%99%9C%EC%9A%A9-%EC%8B%9C-%EA%BF%80%ED%8C%81#entry164comment</comments>
      <pubDate>Wed, 17 Jan 2024 12:10:22 +0900</pubDate>
    </item>
    <item>
      <title>[Terraform] AWS 3-tier Achitecture를 구성하기 위한 Terraform 프로젝트 구조 잡기</title>
      <link>https://co-no.tistory.com/entry/Terraform-AWS-3-tier-Achitecture%EB%A5%BC-%EA%B5%AC%EC%84%B1%ED%95%98%EA%B8%B0-%EC%9C%84%ED%95%9C-Terraform-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EA%B5%AC%EC%A1%B0-%EC%9E%A1%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;아직 Terraform을 통해 AWS의 VPC 생성 조차 해보지 않았다면, 아래 링크인 이전 포스팅을 참고하길 바란다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://co-no.tistory.com/entry/Terraform-%ED%85%8C%EB%9D%BC%ED%8F%BC%EC%9D%84-%ED%86%B5%ED%95%9C-AWS-%EA%B5%AC%EC%84%B1-VPC-%EC%83%9D%EC%84%B1&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://co-no.tistory.com/entry/Terraform-%ED%85%8C%EB%9D%BC%ED%8F%BC%EC%9D%84-%ED%86%B5%ED%95%9C-AWS-%EA%B5%AC%EC%84%B1-VPC-%EC%83%9D%EC%84%B1&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1704812036042&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[Terraform] 테라폼을 통한 AWS 3-tier 구성 (1) - AWS CLI 설정 및 VPC 생성&quot; data-og-description=&quot;0. AWS CLI 및 AWS Configure 테라폼으로 aws 리소스를 관리하기 위해서는, 테라폼이 구동되는 동일한 환경 내에서 AWS CLI가 설치되어 있고, AWS CLI를 통해 모든 리소스의 접근 권한을 가진 AWS IAM User와의 &quot; data-og-host=&quot;co-no.tistory.com&quot; data-og-source-url=&quot;https://co-no.tistory.com/entry/Terraform-%ED%85%8C%EB%9D%BC%ED%8F%BC%EC%9D%84-%ED%86%B5%ED%95%9C-AWS-%EA%B5%AC%EC%84%B1-VPC-%EC%83%9D%EC%84%B1&quot; data-og-url=&quot;https://co-no.tistory.com/entry/Terraform-%ED%85%8C%EB%9D%BC%ED%8F%BC%EC%9D%84-%ED%86%B5%ED%95%9C-AWS-%EA%B5%AC%EC%84%B1-VPC-%EC%83%9D%EC%84%B1&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/c9rNiG/hyU2khMe3u/8nWWvSkmKpbaYlv3wScZMK/img.png?width=682&amp;amp;height=370&amp;amp;face=0_0_682_370,https://scrap.kakaocdn.net/dn/Q24FT/hyU2sUqoCA/ObhwsNkUHddARR5kGzjfy1/img.png?width=682&amp;amp;height=370&amp;amp;face=0_0_682_370,https://scrap.kakaocdn.net/dn/kRQ6d/hyU2oR1i0Z/kK2IILe0dZi1lP2EcPwti0/img.png?width=1114&amp;amp;height=752&amp;amp;face=0_0_1114_752&quot;&gt;&lt;a href=&quot;https://co-no.tistory.com/entry/Terraform-%ED%85%8C%EB%9D%BC%ED%8F%BC%EC%9D%84-%ED%86%B5%ED%95%9C-AWS-%EA%B5%AC%EC%84%B1-VPC-%EC%83%9D%EC%84%B1&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://co-no.tistory.com/entry/Terraform-%ED%85%8C%EB%9D%BC%ED%8F%BC%EC%9D%84-%ED%86%B5%ED%95%9C-AWS-%EA%B5%AC%EC%84%B1-VPC-%EC%83%9D%EC%84%B1&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/c9rNiG/hyU2khMe3u/8nWWvSkmKpbaYlv3wScZMK/img.png?width=682&amp;amp;height=370&amp;amp;face=0_0_682_370,https://scrap.kakaocdn.net/dn/Q24FT/hyU2sUqoCA/ObhwsNkUHddARR5kGzjfy1/img.png?width=682&amp;amp;height=370&amp;amp;face=0_0_682_370,https://scrap.kakaocdn.net/dn/kRQ6d/hyU2oR1i0Z/kK2IILe0dZi1lP2EcPwti0/img.png?width=1114&amp;amp;height=752&amp;amp;face=0_0_1114_752');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[Terraform] 테라폼을 통한 AWS 3-tier 구성 (1) - AWS CLI 설정 및 VPC 생성&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;0. AWS CLI 및 AWS Configure 테라폼으로 aws 리소스를 관리하기 위해서는, 테라폼이 구동되는 동일한 환경 내에서 AWS CLI가 설치되어 있고, AWS CLI를 통해 모든 리소스의 접근 권한을 가진 AWS IAM User와의&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;co-no.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 Terraform 파일을 작성하기 전에, 깔끔한 Terraform 프로젝트 관리를 위해 Terraform 공식 홈페이지에서 권장하는 '&lt;b&gt;Standard Module Structure&lt;/b&gt;' 를 참고하여 다음과 같이 디렉토리를 구성하자.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.hashicorp.com/terraform/language/modules/develop/structure&quot;&gt;https://developer.hashicorp.com/terraform/language/modules/develop/structure&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1704812110553&quot; style=&quot;color: #333333; text-align: start;&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Standard Module Structure | Terraform | HashiCorp Developer&quot; data-og-description=&quot;Learn about the recommended file and directory structure for developing reusable modules distributed as separate repositories.&quot; data-og-host=&quot;developer.hashicorp.com&quot; data-og-source-url=&quot;https://developer.hashicorp.com/terraform/language/modules/develop/structure&quot; data-og-url=&quot;https://developer.hashicorp.com/terraform/language/modules/develop/structure&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b0RyLQ/hyU2sUgQL6/zhzTHJf7ikYSVsTEEOZQg0/img.jpg?width=3200&amp;amp;height=1800&amp;amp;face=0_0_3200_1800,https://scrap.kakaocdn.net/dn/L0al6/hyU2mmcdvS/SMuEJSQHuFB455U2pvuJ50/img.jpg?width=3200&amp;amp;height=1800&amp;amp;face=0_0_3200_1800&quot;&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://developer.hashicorp.com/terraform/language/modules/develop/structure&quot; data-source-url=&quot;https://developer.hashicorp.com/terraform/language/modules/develop/structure&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b0RyLQ/hyU2sUgQL6/zhzTHJf7ikYSVsTEEOZQg0/img.jpg?width=3200&amp;amp;height=1800&amp;amp;face=0_0_3200_1800,https://scrap.kakaocdn.net/dn/L0al6/hyU2mmcdvS/SMuEJSQHuFB455U2pvuJ50/img.jpg?width=3200&amp;amp;height=1800&amp;amp;face=0_0_3200_1800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; style=&quot;color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;Standard Module Structure | Terraform | HashiCorp Developer&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; style=&quot;color: #909090;&quot; data-ke-size=&quot;size16&quot;&gt;Learn about the recommended file and directory structure for developing reusable m&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;598&quot; data-origin-height=&quot;342&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/p4Ohv/btsDhgD63G7/wvk2NxHEMRVV1JhKBCYu4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/p4Ohv/btsDhgD63G7/wvk2NxHEMRVV1JhKBCYu4k/img.png&quot; data-alt=&quot;테라폼 프로젝트 '3-tier-aws' 의 디렉토리 구조&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/p4Ohv/btsDhgD63G7/wvk2NxHEMRVV1JhKBCYu4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fp4Ohv%2FbtsDhgD63G7%2Fwvk2NxHEMRVV1JhKBCYu4k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;598&quot; height=&quot;342&quot; data-origin-width=&quot;598&quot; data-origin-height=&quot;342&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;테라폼 프로젝트 '3-tier-aws' 의 디렉토리 구조&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전 포스팅에서 테스트한 &lt;b&gt;AWS VPC 만드는 과정&lt;/b&gt;을, 테라폼 프로젝트를 깔끔하게 관리하기 위해 다음과 같이 구성하였다. 구성할 때, 외국 개발자 깃헙 중 테라폼 프로젝트가 아주 깔끔해 보여 해당 구조를 차용하였다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/BJWRD/three-tier-architecture/blob/main/main.tf&quot;&gt;https://github.com/BJWRD/three-tier-architecture/blob/main/main.tf&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1704812376937&quot; style=&quot;color: #333333; text-align: start;&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Standard Module Structure | Terraform | HashiCorp Developer&quot; data-og-description=&quot;Learn about the recommended file and directory structure for developing reusable modules distributed as separate repositories.&quot; data-og-host=&quot;developer.hashicorp.com&quot; data-og-source-url=&quot;https://developer.hashicorp.com/terraform/language/modules/develop/structure&quot; data-og-url=&quot;https://developer.hashicorp.com/terraform/language/modules/develop/structure&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b0RyLQ/hyU2sUgQL6/zhzTHJf7ikYSVsTEEOZQg0/img.jpg?width=3200&amp;amp;height=1800&amp;amp;face=0_0_3200_1800,https://scrap.kakaocdn.net/dn/L0al6/hyU2mmcdvS/SMuEJSQHuFB455U2pvuJ50/img.jpg?width=3200&amp;amp;height=1800&amp;amp;face=0_0_3200_1800&quot;&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://developer.hashicorp.com/terraform/language/modules/develop/structure&quot; data-source-url=&quot;https://developer.hashicorp.com/terraform/language/modules/develop/structure&quot;&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-desc&quot; style=&quot;color: #909090;&quot; data-ke-size=&quot;size16&quot;&gt;odules distributed as separate repositories.&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;잘 이해가 가지 않더라도, 일단 아래 tf 파일들을 우선 다 작성하자!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1. 프로젝트 *루트 모듈의 main.tf&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*루트 모듈 : 테라폼이 실행되는 디렉토리를 '모듈'이라 하는데, 이때 루트 모듈이란, 기본 작업 디렉터리의 정의된 파일 집합을 '루트 모듈'이라고 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1704789372884&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# main.tf

provider &quot;aws&quot; {
  region = var.region
}

module &quot;vpc&quot; {
  source       = &quot;./modules/network&quot;
  project_name = var.project_name
  environment  = var.environment
  vpc_id       = module.vpc.vpc_id
  vpc_cidr     = var.vpc_cidr
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2. 프로젝트 *루트 모듈의 variables.tf&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1704807413337&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# variables.tf

variable &quot;region&quot; {
  description = &quot;AWS Region&quot;
  type        = string
  default     = &quot;ap-northeast-2&quot;
}

variable &quot;project_name&quot; {
  description = &quot;Name of Terraform Project&quot;
  type        = string
  default     = &quot;AWS_3-Tier-Architecture&quot;
}

variable &quot;environment&quot; {
  description = &quot;Environment Type&quot;
  type        = string
  default     = &quot;dev&quot;
}

################################################################################
# VPC Module - Variables 
################################################################################

variable &quot;vpc_id&quot; {
  description = &quot;The VPC to be deployed&quot;
  type        = string
  default     = &quot;aws_vpc.VPC_3Tier.id&quot;  
  # vpc module의 main.tf에서 지정한 aws_vpc 리소스의 name을 가지고 id를 조회해야 함.
}

variable &quot;vpc_cidr&quot; {
  description = &quot;The VPC Network Range&quot;
  type        = string
  default     = &quot;10.0.0.0/16&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3. modules/network/variables.tf&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1704869338990&quot; class=&quot;routeros&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;go&quot;&gt;&lt;code&gt;variable &quot;project_name&quot; {
  description = &quot;Name of Terraform Proejct&quot;
  type        = string
}

variable &quot;environment&quot; {
  description = &quot;Environment Type&quot;
  type        = string
}

variable &quot;vpc_id&quot; {
  description = &quot;The VPC to be deployed&quot;
  type        = string
}

variable &quot;vpc_cidr&quot; {
  description = &quot;The VPC Network Range&quot;
  type        = string
}&lt;/code&gt;&lt;/pre&gt;
&lt;h4 style=&quot;color: #000000;&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 style=&quot;color: #000000;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;4. modules/network/main.tf&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1704866015074&quot; class=&quot;clean&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;go&quot;&gt;&lt;code&gt;locals {
  required_tags = {
    project      = &quot;AWS_3-tier-architecture&quot;
    environment  = &quot;dev&quot;
  }
}

################################################################################
# VPC
################################################################################
resource &quot;aws_vpc&quot; &quot;VPC_3Tier&quot; {
  cidr_block = var.vpc_cidr
  
  tags = merge(local.required_tags, { Name = &quot;VPC-3Tier&quot; })
}&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;5. modules/network/output.tf&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1704811430463&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;output &quot;vpc_id&quot; {
  description = &quot;The VPC to be deployed&quot;
  value       = aws_vpc.VPC_3Tier.id
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테라폼은 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;관리하는 인프라 인스턴스마다 모듈별로 나누어 관리&lt;/b&gt;&lt;/span&gt;할 수 있으며, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;하위 모듈(디렉토리)에 작성한 tf 파일은 직접 실행이 되지 않는다.&lt;/b&gt;&lt;/span&gt; &lt;b&gt;루트 모듈에서 해당 하위 모듈을 호출하는 방식&lt;/b&gt;으로, &lt;b&gt;실제적으로 '실행'되는 것은 &lt;span style=&quot;color: #006dd7;&quot;&gt;루트 모듈(main.tf) 하나&lt;/span&gt;&lt;/b&gt;인 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Visual Studio Code의 'Graphviz Interactive Preview' 라는 플러그인을 활용하여, &lt;b&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;i&gt;t&lt;/i&gt;&lt;i&gt;erraform graph &amp;gt; graph.dot&lt;/i&gt;&lt;/span&gt;&lt;/b&gt; 명령어 수행을 통해 생성된 graph.dot 파일을 아래 그림과 같이 확인해 보자!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1574&quot; data-origin-height=&quot;430&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ztUb2/btsDdFyie1s/ZSiky3jlO04VNFh20q8kV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ztUb2/btsDdFyie1s/ZSiky3jlO04VNFh20q8kV1/img.png&quot; data-alt=&quot;위 테라폼 프로젝트의 graph&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ztUb2/btsDdFyie1s/ZSiky3jlO04VNFh20q8kV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FztUb2%2FbtsDdFyie1s%2FZSiky3jlO04VNFh20q8kV1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1574&quot; height=&quot;430&quot; data-origin-width=&quot;1574&quot; data-origin-height=&quot;430&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;위 테라폼 프로젝트의 graph&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테라폼 코드의 실행 순서는&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;i&gt;&lt;b&gt; terraform init&lt;/b&gt; &lt;/i&gt;&lt;/span&gt;명령을 수행한 디렉토리를 루트 모듈(디렉토리)로 잡고, 그 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;하위에 있는 모든 .tf 파일을 스캔&lt;/b&gt;&lt;/span&gt;한다. 이때 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;해당 코드를 분석하여 실행 순서를 결정&lt;/b&gt;&lt;/span&gt;하는데, 만약 코드 실행 선후관계까 없다면 해당 코드는 병렬로 수행되고, 반대로 선후관계가 존재한다면 해당 코드는 순서대로 실행되게끔 &lt;b&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;종속성 그래프&lt;/span&gt;에 해당 정보가 들어간다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 테라폼 수행 방식을 이해했다면, 다음과 같이 테라폼 코드를 작성하는 순서를 어느정도 결정할 수 있다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;루트 모듈의 main.tf&lt;/b&gt;&lt;/span&gt;를 작성한다. 이때, main.tf는 서브 모듈을 호출하는 방식으로만 작성한다.&lt;/li&gt;
&lt;li&gt;루트 모듈의 main.tf 실행에 필요한 변수들을 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;루트 모듈의 variables.tf&lt;/b&gt;&lt;/span&gt; 파일로 작성한다.&lt;/li&gt;
&lt;li&gt;루트 모듈의 variables.tf를 통해 유저로부터 입력받은 또는 정의된&amp;nbsp; 변수를 실제 인스턴스 생성에 관여하는 서브 모듈(main.tf)의 속성값으로 넣어주어야 하는데, 이에 대한 매개체 역할이 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;서브 모듈의 variables.tf&lt;/b&gt;&lt;/span&gt; 파일이다.&lt;br /&gt;따라서 우선 서브 모듈의variables.tf 파일을 &lt;b&gt;루트 모듈의 variables.tf 타입과 맞추어 작성&lt;/b&gt;해 준다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;서브 모듈의 main.tf&lt;/b&gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;를 작성한다. 서브 모듈의 main.tf는 루트 모듈에서 호출하는 module에 대한 실제 구현방식(?)인 &lt;b&gt;resource 구문으로 작성&lt;/b&gt;한다. 그리고 루트 모듈에서의 변수 입력이 아닌, 서브 모듈의 resource 구문에서 곧바로 필요한 변수를 local 변수로 작성한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;서브 모듈의 resource 구현 이후 (실제 인스턴스 생성 이후)에 발생하는 variable&lt;/b&gt;이 루트 모듈에서 사용되어야 한다면, &lt;b&gt;해당 서브 모듈의 output.tf 파일로&lt;/b&gt; 작성한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 구조를 잡고 테라폼 일단 테라폼 프로젝트를 작성하면, 반복되는 코드의 사용 및 수정이나 종속성에 영향이 생기는 문제는 많이 줄일 것으로 예상된다.혹여나 중간에 큰 문제가 생기면, 다시 프로젝트 구조를 변경해야 할 수도 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더 좋은 프로젝트 구조를 발견하고 테라폼 동작 방식을 좀 더 명료하게 설명할 수 있다면, 이 포스팅을 수정될 수도 있다..!&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;참고&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/BJWRD/three-tier-architecture&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/BJWRD/three-tier-architecture&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1704865668146&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - BJWRD/three-tier-architecture: Highly Available, Fault Tolerant, Three-Tier-Architecture on AWS provisioned via Terrafo&quot; data-og-description=&quot;Highly Available, Fault Tolerant, Three-Tier-Architecture on AWS provisioned via Terraform - GitHub - BJWRD/three-tier-architecture: Highly Available, Fault Tolerant, Three-Tier-Architecture on AWS...&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/BJWRD/three-tier-architecture&quot; data-og-url=&quot;https://github.com/BJWRD/three-tier-architecture&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/y33Fx/hyU2ehJ0Sv/Uwdl8h4A7wt7JK0A9oN4Zk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/BJWRD/three-tier-architecture&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/BJWRD/three-tier-architecture&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/y33Fx/hyU2ehJ0Sv/Uwdl8h4A7wt7JK0A9oN4Zk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - BJWRD/three-tier-architecture: Highly Available, Fault Tolerant, Three-Tier-Architecture on AWS provisioned via Terrafo&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Highly Available, Fault Tolerant, Three-Tier-Architecture on AWS provisioned via Terraform - GitHub - BJWRD/three-tier-architecture: Highly Available, Fault Tolerant, Three-Tier-Architecture on AWS...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://malwareanalysis.tistory.com/619&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://malwareanalysis.tistory.com/619&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1704865599003&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;테라폼으로 EKS만들기 프로젝트 3-2편 - 테라폼 동작원리&quot; data-og-description=&quot;이 글은 테라폼이 어떻게 동작하는지 설명합니다. 3편에서 실행했던 hello world예제를 참고합니다. ▶ 테라폼 동작원리 유투브 영상: https://youtu.be/47FJVP437nk 1. 동작원리 테라폼은 코드를 읽어 코드&quot; data-og-host=&quot;malwareanalysis.tistory.com&quot; data-og-source-url=&quot;https://malwareanalysis.tistory.com/619&quot; data-og-url=&quot;https://malwareanalysis.tistory.com/619&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ePlhh/hyU2hesAwo/ppwVOhlxWaBRUqqfKi35a0/img.png?width=506&amp;amp;height=238&amp;amp;face=0_0_506_238,https://scrap.kakaocdn.net/dn/dBSdzc/hyU2iRZjFW/JblIeHvq3wOvMGHeqDQ4AK/img.png?width=506&amp;amp;height=238&amp;amp;face=0_0_506_238,https://scrap.kakaocdn.net/dn/czV6Zw/hyU2oEFPsM/ZlACMHFllajrltM8b8Sikk/img.png?width=921&amp;amp;height=475&amp;amp;face=0_0_921_475&quot;&gt;&lt;a href=&quot;https://malwareanalysis.tistory.com/619&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://malwareanalysis.tistory.com/619&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ePlhh/hyU2hesAwo/ppwVOhlxWaBRUqqfKi35a0/img.png?width=506&amp;amp;height=238&amp;amp;face=0_0_506_238,https://scrap.kakaocdn.net/dn/dBSdzc/hyU2iRZjFW/JblIeHvq3wOvMGHeqDQ4AK/img.png?width=506&amp;amp;height=238&amp;amp;face=0_0_506_238,https://scrap.kakaocdn.net/dn/czV6Zw/hyU2oEFPsM/ZlACMHFllajrltM8b8Sikk/img.png?width=921&amp;amp;height=475&amp;amp;face=0_0_921_475');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;테라폼으로 EKS만들기 프로젝트 3-2편 - 테라폼 동작원리&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;이 글은 테라폼이 어떻게 동작하는지 설명합니다. 3편에서 실행했던 hello world예제를 참고합니다. ▶ 테라폼 동작원리 유투브 영상: https://youtu.be/47FJVP437nk 1. 동작원리 테라폼은 코드를 읽어 코드&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;malwareanalysis.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DevOps/Terraform</category>
      <category>테라폼 모듈 동작 순서</category>
      <category>테라폼 변수 선언</category>
      <category>테라폼 코드 작성 순서</category>
      <category>테라폼 프로젝트 구조</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/165</guid>
      <comments>https://co-no.tistory.com/entry/Terraform-AWS-3-tier-Achitecture%EB%A5%BC-%EA%B5%AC%EC%84%B1%ED%95%98%EA%B8%B0-%EC%9C%84%ED%95%9C-Terraform-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EA%B5%AC%EC%A1%B0-%EC%9E%A1%EA%B8%B0#entry165comment</comments>
      <pubDate>Wed, 10 Jan 2024 15:12:52 +0900</pubDate>
    </item>
    <item>
      <title>[RDBMS] DB의 정규화 단계(1NF, 2NF, 3NF, BCNF, 4NF, 5NF)의 개념 및 예시</title>
      <link>https://co-no.tistory.com/entry/RDBMS</link>
      <description>&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이번 포스팅에서는 테이블 설계에 있어, 데이터베이스 이론가들이 확립시켜 놓은 일종의 규칙,&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;즉, 정규화 단계가 무엇이 있는지 살펴볼 것이다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;우선 이러한 정규화를 하는 목적에 대해 먼저 살펴 보자.&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;정규화 목적&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;중복 데이터를 최소화&lt;/b&gt;&lt;/span&gt;하여 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;테이블 불일치 위험을 최소화&lt;/b&gt;&lt;/span&gt;한다.&lt;/li&gt;
&lt;li&gt;수정, 삭제 시 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;이상 현상을 방지&lt;/b&gt;&lt;/span&gt;함으로써, 데이터 구조의 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;일관성을 최대화&lt;/b&gt;&lt;/span&gt;한다.&lt;/li&gt;
&lt;li&gt;데이터 삽입 시 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;릴레이션의 재구성에 대한 필요성을 줄인다.&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;효과적인 검색 알고리즘&lt;/b&gt;&lt;/span&gt;을 생성하도록 돕는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 데이터베이스 이론가들이 확립시켜 놓은 정규화 단계가 어떻게 구성되는 지 살펴보자.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1. 제 1정규화 (1NF, 1st Normal Form)&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;비정규형 -&amp;gt; 1NF&lt;/b&gt;&lt;/span&gt;로 바꾸는 것을 말하며, &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;테이블 내의 속성값이 모두 원자값(Atomic Value)만으로 구성되어야 한다&lt;/b&gt;&lt;/span&gt;는 원칙을 가지고 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;여기에서 &lt;b&gt;원자값&lt;/b&gt;이란, &lt;b&gt;더 이상 쪼개질 수 없는 단위&lt;/b&gt;를 말하며, 다음과 같은 조건을 만족한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;각 속성은&lt;b&gt;&lt;/b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt; 하나의 값만&lt;/b&gt;&lt;/span&gt;을 가진다.&lt;/li&gt;
&lt;li&gt;하나의 속성은 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;같은 종류나 타입(type)&lt;/b&gt;&lt;/span&gt;을 가져야 한다.&lt;/li&gt;
&lt;li&gt;각 &lt;span style=&quot;color: #333333;&quot;&gt;속성은&lt;/span&gt;&lt;b&gt;&lt;/b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt; 유일(unique)한 이름&lt;/b&gt;&lt;/span&gt;을 가져야 한다.&lt;/li&gt;
&lt;li&gt;각 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;속성 간의 순서가 상관이 없어야&lt;/b&gt; &lt;/span&gt;한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;비정규형의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;[학생]&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;테이블&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 115px;&quot; border=&quot;1&quot; width=&quot;511&quot; data-ke-style=&quot;style10&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 23px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot; width=&quot;70&quot; height=&quot;23&quot;&gt;&lt;b&gt;학번&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot; width=&quot;70&quot;&gt;&lt;b&gt;지도교수&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot; width=&quot;99&quot;&gt;&lt;b&gt;학과&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot; width=&quot;202&quot;&gt;&lt;b&gt;수강 과목&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot; width=&quot;70&quot;&gt;&lt;b&gt;성적&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 23px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot; height=&quot;23&quot;&gt;100&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot;&gt;이상철&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot;&gt;컴퓨터공학과&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;데이터베이스개론, 자료구조&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot;&gt;A, B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 23px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot; height=&quot;23&quot;&gt;200&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot;&gt;박종인&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot;&gt;컴퓨터공학과&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot;&gt;클라우드&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot;&gt;B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 23px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot; height=&quot;23&quot;&gt;300&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot;&gt;안주은&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot;&gt;전자공학과&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot;&gt;통신공학&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot;&gt;A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 23px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot; height=&quot;23&quot;&gt;400&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot;&gt;김유이&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot;&gt;수학과&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot;&gt;미적분학&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot;&gt;C&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;위 테이블은 '100'이라는 학번을 가진 학생의 '수강 과목'이 '데이터베이스개론, 자료구조'로 &lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;2개의 값을 가지고 있기 때문&lt;/b&gt;&lt;/span&gt;에, 원자값을 가져야 한다는 1NF의 조건을 만족하지 못한다. 따라서 다음과 같이 테이블을 분리해주어야 한다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 138px;&quot; border=&quot;1&quot; width=&quot;511&quot; data-ke-style=&quot;style10&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 23px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot; width=&quot;70&quot; height=&quot;23&quot;&gt;&lt;b&gt;학번&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot; width=&quot;70&quot;&gt;&lt;b&gt;지도교수&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot; width=&quot;99&quot;&gt;&lt;b&gt;학과&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot; width=&quot;202&quot;&gt;&lt;b&gt;수강 과목&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot; width=&quot;70&quot;&gt;&lt;b&gt;성적&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 23px;&quot;&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot; height=&quot;23&quot;&gt;100&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot;&gt;이상철&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot;&gt;컴퓨터공학과&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;데이터베이스개론&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot;&gt;A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 23px;&quot;&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot; height=&quot;23&quot;&gt;100&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot;&gt;이상철&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot;&gt;컴퓨터공학과&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;자료구조&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot;&gt;B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 23px;&quot;&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot; height=&quot;23&quot;&gt;200&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot;&gt;박종인&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot;&gt;컴퓨터공학과&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot;&gt;클라우드&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot;&gt;B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 23px;&quot;&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot; height=&quot;23&quot;&gt;300&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot;&gt;안주은&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot;&gt;전자공학과&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot;&gt;통신공학&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot;&gt;A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 23px;&quot;&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot; height=&quot;23&quot;&gt;400&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot;&gt;김유이&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot;&gt;수학과&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot;&gt;미적분학&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot;&gt;C&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2. 제 2정규화 (2NF, 2nd Normal Form)&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;1NF -&amp;gt; 2NF&lt;/b&gt;&lt;/span&gt;로 바꾸는 것을 말하며, *&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;부분 함수 종속을 제거한다&lt;/b&gt;&lt;/span&gt;는 원칙을 가지고 있다. 그리고 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;2NF는 1NF의 조건도 반드시 만족&lt;/b&gt;&lt;/span&gt;해야 한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;제 1정규형까지만 정규화할 경우, 위에서 언급한 삽입이상, 삭제이상, 갱신이상이 발생할 수 있게 된다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Case 1.&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;학생이 새 과목을 수강 신청할 때는 반드시 학생의 지도교수까지 알아야 한다.&lt;/b&gt; &lt;/span&gt;(과목이랑 지도교수는 연관성이 없는 데이터인데, 하나의 데이터를 삽입하기 위해 불필요한 정보를 알아야 한다.)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;=&amp;gt;&lt;/b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt; 삽입 이상&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Case 2.&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;'300'번 학생이 '통신공학' 과목을 취소하면, '300'번 학생의 레코드가 사라질 수 있다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;=&amp;gt;&lt;/b&gt; &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;삭제 이상&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Case 3.&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;'100'번 학생이 지도교수를 변경할 때, 위 테이블의 예시에서는 2개의 레코드 값을 모두 변경해주어야 한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;=&amp;gt;&lt;/b&gt; &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;갱신 이상&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이러한 이상 현상이 발생하는 이유는, 기본키('학번'과 '수강과목')가 아닌 속성들이 기본키에&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt; *완전 함수 종속되지 못하고, 부분 함수 종속되어 있기 때문&lt;/b&gt;&lt;/span&gt;이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;767&quot; data-origin-height=&quot;318&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bSJPNs/btsCX37h5OC/YRauMHkr3QdYWV4GzMCnN1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bSJPNs/btsCX37h5OC/YRauMHkr3QdYWV4GzMCnN1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bSJPNs/btsCX37h5OC/YRauMHkr3QdYWV4GzMCnN1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbSJPNs%2FbtsCX37h5OC%2FYRauMHkr3QdYWV4GzMCnN1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;437&quot; height=&quot;181&quot; data-origin-width=&quot;767&quot; data-origin-height=&quot;318&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;* 완전 함수 종속&lt;/b&gt; : &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;종속자가 기본키에만 종속&lt;/b&gt;&lt;/span&gt;되며, 기본키가 여러 속성으로 구성되어 있을 경우, 기본키를 구성하는 모든 속성이 포함된 기본키의 부분집합에 종속된 경우&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;* 부분 함수 종속&lt;/b&gt; : 테이블에서 기본키가 &lt;b&gt;복합키&lt;/b&gt;일 경우,종속자가 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;기본키를 구성하는 속성 중 일부에게만 종속&lt;/b&gt;&lt;/span&gt;된 경우&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;위 예시로 보면 다음과 같이 테이블을 분리하는 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1758&quot; data-origin-height=&quot;807&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baP1oB/btsCZ3lDq9X/Kb9esDcQs4GIIMXJoKKxb0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baP1oB/btsCZ3lDq9X/Kb9esDcQs4GIIMXJoKKxb0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baP1oB/btsCZ3lDq9X/Kb9esDcQs4GIIMXJoKKxb0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaP1oB%2FbtsCZ3lDq9X%2FKb9esDcQs4GIIMXJoKKxb0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1758&quot; height=&quot;807&quot; data-origin-width=&quot;1758&quot; data-origin-height=&quot;807&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[학생]&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;테이블&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 58.7209%; height: 242px;&quot; border=&quot;1&quot; width=&quot;371&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style10&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;70&quot; height=&quot;23&quot;&gt;&lt;b&gt;학번&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;202&quot;&gt;&lt;b&gt;지도교수&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;99&quot;&gt;&lt;b&gt;학과&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; height=&quot;23&quot;&gt;100&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;이상철&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;컴퓨터공학과&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; height=&quot;23&quot;&gt;100&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;이상철&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;컴퓨터공학과&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; height=&quot;23&quot;&gt;200&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;박종인&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;컴퓨터공학과&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; height=&quot;23&quot;&gt;300&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;안주은&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;전자공학과&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; height=&quot;23&quot;&gt;400&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;김유이&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;수학과&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[성적]&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;테이블&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 58.2558%; height: 234px;&quot; border=&quot;1&quot; width=&quot;371&quot; data-ke-style=&quot;style10&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;70&quot; height=&quot;23&quot;&gt;&lt;b&gt;학번&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;202&quot;&gt;&lt;b&gt;수강 과목&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;99&quot;&gt;&lt;b&gt;성적&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; height=&quot;23&quot;&gt;100&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;데이터베이스개론&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; height=&quot;23&quot;&gt;100&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;자료구조&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; height=&quot;23&quot;&gt;200&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;클라우드&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; height=&quot;23&quot;&gt;300&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;통신공학&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; height=&quot;23&quot;&gt;400&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;미적분학&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;C&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3. 제 3정규화 (3NF, 3rd Normal Form)&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;2NF -&amp;gt; 3NF&lt;/b&gt;&lt;/span&gt;로 바꾸는 것을 말하며, &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;*이행 함수 종속을 제거한다&lt;/b&gt;&lt;/span&gt;는 원칙을 가지고 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;위 예시를 다시 살펴보면, 2NF를 만족하는&lt;b&gt; [학생]&lt;/b&gt; 테이블에서 &lt;b&gt;이행 함수 종속&lt;/b&gt;이 생기는 것을 볼 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;즉, '학번' 데이터를 알면, '지도교수' 데이터를 알고, 그에 따라 '학과' 데이터도 알 수 있게 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;656&quot; data-origin-height=&quot;381&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/YxtWK/btsCX4SDeD2/KXBX1HSrau8wlGoZIPUJsk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/YxtWK/btsCX4SDeD2/KXBX1HSrau8wlGoZIPUJsk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/YxtWK/btsCX4SDeD2/KXBX1HSrau8wlGoZIPUJsk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYxtWK%2FbtsCX4SDeD2%2FKXBX1HSrau8wlGoZIPUJsk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;388&quot; height=&quot;225&quot; data-origin-width=&quot;656&quot; data-origin-height=&quot;381&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;*이행 함수 종속&lt;/b&gt; : 한 테이블 내에서 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;X, Y, Z 라는 3개의 속성&lt;/b&gt;&lt;/span&gt;이 있을 때, &lt;b&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;X-&amp;gt;Y,&lt;/span&gt; &lt;span style=&quot;color: #ef6f53;&quot;&gt;Y-&amp;gt;Z &lt;/span&gt;란 종속 관계가 있고 &lt;span style=&quot;color: #ee2323;&quot;&gt;X-&amp;gt;Z&lt;/span&gt;가 성립한다면&lt;/b&gt;, 이를 이행 함수 종속이라고 말한다. 즉, &lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;X를 알면, Y도 알고 그를 통해 Z도 알 수 있는 경우&lt;/b&gt;&lt;/span&gt;를 말하는 것이다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;위 예시처럼 이행 함수 종속이 생기면,&lt;b&gt; 다음과 같은 문제&lt;/b&gt;가 발생한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Case 1.&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;신설 학과가 생성되었는데, 아직 학생(학번)이 없으므로, 신설 학과에 대한 데이터를 추가할 수 없다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;=&amp;gt;&lt;/b&gt; &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;삽입 이상&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Case 2.&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;기존 학과가 다른 학과로 통폐합되었는데, 지도교수와 학생은 여전히 학교에 존재한다. 이럴 경우, 기존 학과 데이터를 삭제하면 학생과 지도교수 데이터가 모두 사라지게 된다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;=&amp;gt;&lt;/b&gt; &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;삭제 이상&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Case 3.&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;기존 학과 이름이 바뀌었는데, 이럴 경우 해당 학과에 속하는 학생들의 모든 '학과' 데이터를 변경해야 한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;=&amp;gt;&lt;/b&gt; &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;갱신 이상&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;따라서 2NF만을 만족하는 테이블은 3NF도 만족하도록 테이블 설계를 업그레이드(?) 해야 한다. 위 예시의 [학생] 테이블을 다음과 같이, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;[학생] 테이블, [지도교수] 테이블로 나누면&lt;/b&gt;&lt;/span&gt;, 이행 함수 종속을 탈피할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1715&quot; data-origin-height=&quot;519&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SyQXN/btsC4qNJGGa/xyC4m8LgUWAAuQ54kTAN2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SyQXN/btsC4qNJGGa/xyC4m8LgUWAAuQ54kTAN2k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SyQXN/btsC4qNJGGa/xyC4m8LgUWAAuQ54kTAN2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSyQXN%2FbtsC4qNJGGa%2FxyC4m8LgUWAAuQ54kTAN2k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1715&quot; height=&quot;519&quot; data-origin-width=&quot;1715&quot; data-origin-height=&quot;519&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[학생]&lt;/b&gt; 테이블&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 40.5814%; height: 173px;&quot; border=&quot;1&quot; width=&quot;138&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style10&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;69&quot; height=&quot;23&quot;&gt;&lt;b&gt;학번&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;69&quot;&gt;&lt;b&gt;지도교수&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; height=&quot;23&quot;&gt;100&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;이상철&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; height=&quot;23&quot;&gt;200&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;박종인&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; height=&quot;23&quot;&gt;300&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;안주은&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; height=&quot;23&quot;&gt;400&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;김유이&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[지도교수]&lt;/b&gt; 테이블&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 115px;&quot; border=&quot;1&quot; width=&quot;138&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style10&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 23px;&quot;&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot; width=&quot;69&quot; height=&quot;23&quot;&gt;&lt;b&gt;지도교수&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot; width=&quot;69&quot;&gt;&lt;b&gt;학과&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 23px;&quot;&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot; height=&quot;23&quot;&gt;이상철&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot;&gt;컴퓨터공학과&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 23px;&quot;&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot; height=&quot;23&quot;&gt;박종인&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot;&gt;컴퓨터공학과&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 23px;&quot;&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot; height=&quot;23&quot;&gt;안주은&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot;&gt;전자공학과&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 23px;&quot;&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot; height=&quot;23&quot;&gt;김유이&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot;&gt;수학과&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3.5 BCNF (Boyce and Codde Nor&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;mal Form)&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;3NF를 조금 더 강화시킨&lt;/b&gt;&lt;/span&gt; 개념으로, &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;강한 제3 정규형&lt;/b&gt;&lt;/span&gt;이라고도 한다. &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;모든 결정자는 항상 *후보키가 된다&lt;/b&gt;&lt;/span&gt;는 원칙을 가지고 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;*후보키&lt;/b&gt; : 각 행을 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;유일하게 식별&lt;/b&gt;&lt;/span&gt;할 수 있는 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;최소한의 속성들을 가진 집합&lt;/b&gt;&lt;/span&gt;으로, 기본키가 될 수 있는 후보들이다. &lt;b&gt;*슈퍼키 중 더 이상 줄일 수 없는 형태&lt;/b&gt;이기 때문에, 유일성과 최소성을 동시에 만족한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;*슈퍼키&lt;/b&gt; : 각 행을 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;유일하게 식별&lt;/b&gt;&lt;/span&gt;할 수 있는 속성들의 집합으로, &lt;b&gt;유일성은 만족&lt;/b&gt;하나, &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;최소성은 만족하지 못한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;BCNF는 왜 필요할까? 다음과 같이 3NF를 만족하는 &lt;b&gt;[학생수강]&lt;/b&gt; 테이블이 있다고 가정하자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1484&quot; data-origin-height=&quot;417&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sW5ST/btsC4JmdiPS/wKcgISWuHvjDagcnmJxqK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sW5ST/btsC4JmdiPS/wKcgISWuHvjDagcnmJxqK0/img.png&quot; data-alt=&quot;[학생수강] 테이블&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sW5ST/btsC4JmdiPS/wKcgISWuHvjDagcnmJxqK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsW5ST%2FbtsC4JmdiPS%2FwKcgISWuHvjDagcnmJxqK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1484&quot; height=&quot;417&quot; data-origin-width=&quot;1484&quot; data-origin-height=&quot;417&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[학생수강] 테이블&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이런식의 테이블 설계는 왜 문제일까?&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Case 1.&lt;/b&gt; &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;새로운 교수가 특정 과목을 담당하게 되어, 데이터를 추가하려고 하면, 아직 수강 학생이 없기 때문에, 새로운 교수 및 과목에 대한 레코드 삽입이 불가하다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;=&amp;gt; &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;삽입 이상&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Case 2.&lt;/b&gt; &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;학번 '100'이 '자료구조' 과목을 취소하면, '이상철' 교수가 '자료구조'를 담당한다는 정보도 삭제되어 버린다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;=&amp;gt; &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;삭제 이상&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Case 3.&lt;/b&gt; &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;'이상철' 교수의 과목이 '자료구조'에서 '알고리즘'으로 바뀐다면, 담당교수가 '이상철'인 레코드를 모두 바꿔야 하는 문제가 생겨 버린다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;=&amp;gt; &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;갱신 이상&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이러한 이상현상은 결국 &lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;결정자가 후보키로 취급되고 있지 않기 때문에 발생&lt;/b&gt;&lt;/span&gt;한다. 다음과 같은 테이블 구성을 통해&lt;b&gt; (학번, 과목명)&lt;/b&gt;, &lt;b&gt;(담당교수)&lt;/b&gt;의 집합을 기본키로 지정하면, 위와 같은 이상현상을 해결할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1716&quot; data-origin-height=&quot;547&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sjLyY/btsC87T0A1j/fVUGShOWrsIJrQUdES4IKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sjLyY/btsC87T0A1j/fVUGShOWrsIJrQUdES4IKk/img.png&quot; data-alt=&quot;BCNF를 만족하기 위한 과정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sjLyY/btsC87T0A1j/fVUGShOWrsIJrQUdES4IKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsjLyY%2FbtsC87T0A1j%2FfVUGShOWrsIJrQUdES4IKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1716&quot; height=&quot;547&quot; data-origin-width=&quot;1716&quot; data-origin-height=&quot;547&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;BCNF를 만족하기 위한 과정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;보통 실무에서는, BCNF 단계까지만 수행하는 경우가 많다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대부분의 릴레이션의 경우, BCNF까지만 수행하여도 5NF의 요건을 만족하게 되기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4NF, 5NF로의 정규화&lt;/b&gt;는, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;릴레이션 내의 모든 속성이 키에 해당되는 릴레이션일 경우&lt;/b&gt;&lt;/span&gt;에만 진행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 릴레이션 내에 존재하는 후보키가 복합키일 때만 필요한 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;BCNF 이상으로 정규화를 수행하여 테이블을 쪼개놓으면, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;장점보다는 단점이 더 많이 작용할 수 있다&lt;/b&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt; *연결의 함정(Connection Trap)&lt;/b&gt;&lt;/span&gt;이 발생할 여지가 다분하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래도 개념은 알아두면 좋으니, 제 4정규화와 제 5정규화까지 뭔지 살펴보도록 하자!&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;4. 제 4정규화 (4NF, 4th Normal Form)&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;3NF(or BCNF) -&amp;gt; 4NF의 과정&lt;/b&gt;&lt;/span&gt;으로, *&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;다치 종속(Multi-valued Dependency)이 없어야 한다&lt;/b&gt;&lt;/span&gt;는 원칙을 가지고 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;아래와 같은 다치 종속을 만족하는&lt;b&gt; [학생]&lt;/b&gt; 테이블을 살펴보자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1513&quot; data-origin-height=&quot;438&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uexwB/btsC4egl73D/i2SFIf2iHNekuj9vbHtwr1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uexwB/btsC4egl73D/i2SFIf2iHNekuj9vbHtwr1/img.png&quot; data-alt=&quot;[학생] 테이블&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uexwB/btsC4egl73D/i2SFIf2iHNekuj9vbHtwr1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuexwB%2FbtsC4egl73D%2Fi2SFIf2iHNekuj9vbHtwr1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1513&quot; height=&quot;438&quot; data-origin-width=&quot;1513&quot; data-origin-height=&quot;438&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[학생] 테이블&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;*다치 종속(Multi-valued Dependency)&lt;/b&gt;&amp;nbsp;: 어떠한 조건을 만족하는 튜플이 릴레이션 안에 있을 것을 요구하는 일종의 제약조건. 함수적 종속성에 속하는 것이 아닌, 별도로 구분되는 개념으로 본다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'학과'와 '동아리'는 서로 관계가 없는 독립적인 관계인데, '학번'에 따라 결정되는 특성이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Case 1.&lt;span style=&quot;color: #409d00;&quot;&gt; 학번 '100' 학생의 경우, 컴퓨터공학과 전자공학 복수전공을 하고 있는데, 동아리도 2개를 가입하고 있다. 이런 상황에서, 학번 '100' 학생이 동아리 하나를 더 가입하면, '100' 학생에 대한 레코드를 의미없이 2개나 더 추가해야 하는 상황이 생겨버린다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;=&amp;gt; &lt;span style=&quot;color: #ee2323;&quot;&gt;삽입 이상&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 서로 연관이 없는 여러 컬럼들이 결정자에 대해서 종속자의 관계를 가지고 있다면, 다음과 같이 결정자와 종속자가 1:1 관계가 되도록 테이블을 분해해주면 4NF를 만족한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1594&quot; data-origin-height=&quot;655&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b2S5iU/btsC6UuG3La/eLZktsHxlWK0DFIJ4GlWIK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b2S5iU/btsC6UuG3La/eLZktsHxlWK0DFIJ4GlWIK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b2S5iU/btsC6UuG3La/eLZktsHxlWK0DFIJ4GlWIK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb2S5iU%2FbtsC6UuG3La%2FeLZktsHxlWK0DFIJ4GlWIK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1594&quot; height=&quot;655&quot; data-origin-width=&quot;1594&quot; data-origin-height=&quot;655&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1048&quot; data-origin-height=&quot;465&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d9mwRI/btsC9A94tlf/ZKne4wMLSPZEIJAuqgKbT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d9mwRI/btsC9A94tlf/ZKne4wMLSPZEIJAuqgKbT1/img.png&quot; data-alt=&quot;제 4정규화를 거쳐 생성된 [학생학과] 테이블과 [학생동아리] 테이블&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d9mwRI/btsC9A94tlf/ZKne4wMLSPZEIJAuqgKbT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd9mwRI%2FbtsC9A94tlf%2FZKne4wMLSPZEIJAuqgKbT1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;624&quot; height=&quot;277&quot; data-origin-width=&quot;1048&quot; data-origin-height=&quot;465&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;제 4정규화를 거쳐 생성된 [학생학과] 테이블과 [학생동아리] 테이블&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로, [학생학과] 테이블은 복수전공을 한 학생은 학번 데이터가 2개 이상일 수 있으며, [학생동아리] 테이블은 한 학생이 동아리를 여러 개 가입했다면 학번 데이터가 2개 이상일 수 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h4 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;5. 제 5정규화 (5NF, 5th Normal Form)&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;4NF -&amp;gt; 5NF&lt;/b&gt;&lt;/span&gt;의 과정으로, &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;*JOIN 종속을 제거한다&lt;/b&gt;&lt;/span&gt;는 원칙을 가지고 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;위에서 예시로 나온 4NF 형태의 &lt;b&gt;[학생학과]&lt;/b&gt; 테이블과&lt;b&gt; [학생동아리]&lt;/b&gt; 테이블을 '학번'을 기준으로 JOIN 연산하면, 다음과 같은 테이블이 생성된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;632&quot; data-origin-height=&quot;619&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cwxsRE/btsDaw0GvW7/JGV0rC1nNYkacMLR37C7Xk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cwxsRE/btsDaw0GvW7/JGV0rC1nNYkacMLR37C7Xk/img.png&quot; data-alt=&quot;4NF의 테이블들을 '학번' 기준으로 JOIN한 테이블&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cwxsRE/btsDaw0GvW7/JGV0rC1nNYkacMLR37C7Xk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcwxsRE%2FbtsDaw0GvW7%2FJGV0rC1nNYkacMLR37C7Xk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;356&quot; height=&quot;349&quot; data-origin-width=&quot;632&quot; data-origin-height=&quot;619&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;4NF의 테이블들을 '학번' 기준으로 JOIN한 테이블&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;*JOIN 종속&lt;/b&gt; : 하나의 테이블을 여러 개의 테이블로 분해하였다가,&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt; 다시 조인했을 때 데이터 손실은 없지만, 필요없는 데이터가 생기는 것&lt;/b&gt;&lt;/span&gt;을 말한다. 다치 종속의 개념을 더 일반화시킨 것이라 볼 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;위 테이블과 같이 중복된 데이터가 많아지면, 하나의 튜플이 가지는 특별한 의미도 없고, DB에서의 불필요한 연산도 증가하게 된다. 따라서 아래와 같이 3개의 테이블로 분해하여 JOIN 종속을 없앨 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1894&quot; data-origin-height=&quot;454&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/s0hD9/btsC2wVU9BX/h3Wi6i8J6vXbc6D2nMWBG1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/s0hD9/btsC2wVU9BX/h3Wi6i8J6vXbc6D2nMWBG1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/s0hD9/btsC2wVU9BX/h3Wi6i8J6vXbc6D2nMWBG1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fs0hD9%2FbtsC2wVU9BX%2Fh3Wi6i8J6vXbc6D2nMWBG1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1894&quot; height=&quot;454&quot; data-origin-width=&quot;1894&quot; data-origin-height=&quot;454&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1639&quot; data-origin-height=&quot;882&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dukC8m/btsC2CWbmXS/YvSk2HzhtnK5UXe2wyB5qk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dukC8m/btsC2CWbmXS/YvSk2HzhtnK5UXe2wyB5qk/img.png&quot; data-alt=&quot;제 5정규화 과정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dukC8m/btsC2CWbmXS/YvSk2HzhtnK5UXe2wyB5qk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdukC8m%2FbtsC2CWbmXS%2FYvSk2HzhtnK5UXe2wyB5qk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;674&quot; height=&quot;363&quot; data-origin-width=&quot;1639&quot; data-origin-height=&quot;882&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;제 5정규화 과정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@wisdom-one/%EC%A0%95%EA%B7%9C%ED%99%94Normalization&quot;&gt;https://velog.io/@wisdom-one/%EC%A0%95%EA%B7%9C%ED%99%94Normalization&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1704417191968&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cv2bVP/hyUXMFY250/QKyvZymAoLYLjoukAADNK0/img.png?width=768&amp;amp;height=402&amp;amp;face=0_0_768_402,https://scrap.kakaocdn.net/dn/cylXIH/hyU2p3owzi/tWuJwBvIJUR1ga66rSKrrK/img.png?width=768&amp;amp;height=402&amp;amp;face=0_0_768_402,https://scrap.kakaocdn.net/dn/b9UDCV/hyUXQVUyi0/b1k3kR3Df99kPZ7mFf3KL0/img.png?width=1536&amp;amp;height=401&amp;amp;face=0_0_1536_401&quot; data-og-url=&quot;https://velog.io/@wisdom-one/정규화Normalization&quot; data-og-source-url=&quot;https://velog.io/@wisdom-one/%EC%A0%95%EA%B7%9C%ED%99%94Normalization&quot; data-og-host=&quot;velog.io&quot; data-og-description=&quot;1. 정의 Normalization 관계형 데이터 모델에서 데이터의 중복성을 제거하여 이상 현상(Anomaly)을 방지하고, 데이터의 일관성과 정확성을 유지하기 위해 무손실 분해하는 과정을 말한다. &amp;gt; ####   이&quot; data-og-title=&quot;정규화 (1NF, 2NF, 3NF, BCNF, 4NF, 5NF)&quot; data-og-type=&quot;article&quot; data-ke-align=&quot;alignCenter&quot; data-ke-type=&quot;opengraph&quot;&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://velog.io/@wisdom-one/%EC%A0%95%EA%B7%9C%ED%99%94Normalization&quot; data-source-url=&quot;https://velog.io/@wisdom-one/%EC%A0%95%EA%B7%9C%ED%99%94Normalization&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cv2bVP/hyUXMFY250/QKyvZymAoLYLjoukAADNK0/img.png?width=768&amp;amp;height=402&amp;amp;face=0_0_768_402,https://scrap.kakaocdn.net/dn/cylXIH/hyU2p3owzi/tWuJwBvIJUR1ga66rSKrrK/img.png?width=768&amp;amp;height=402&amp;amp;face=0_0_768_402,https://scrap.kakaocdn.net/dn/b9UDCV/hyUXQVUyi0/b1k3kR3Df99kPZ7mFf3KL0/img.png?width=1536&amp;amp;height=401&amp;amp;face=0_0_1536_401');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; style=&quot;color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;정규화 (1NF, 2NF, 3NF, BCNF, 4NF, 5NF)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; style=&quot;color: #909090;&quot; data-ke-size=&quot;size16&quot;&gt;1. 정의 Normalization 관계형 데이터 모델에서 데이터의 중복성을 제거하여 이상 현상(Anomaly)을 방지하고, 데이터의 일관성과 정확성을 유지하기 위해 무손실 분해하는 과정을 말한다. &amp;gt; ####   이&lt;/p&gt;
&lt;p class=&quot;og-host&quot; style=&quot;color: #909090;&quot; data-ke-size=&quot;size16&quot;&gt;velog.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://rebro.kr/160&quot;&gt;https://rebro.kr/160&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1704417191969&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/UCFT1/hyU2poN69R/N30MbYWmnP9zUYylwPaeEk/img.png?width=796&amp;amp;height=356&amp;amp;face=0_0_796_356,https://scrap.kakaocdn.net/dn/qVi0c/hyUXVpnbzz/MuVafoKskawNlGXmOkt691/img.png?width=796&amp;amp;height=356&amp;amp;face=0_0_796_356,https://scrap.kakaocdn.net/dn/sqUOM/hyU2p3pAUq/B6vAOtiK1qiAsbLCEcHTjK/img.png?width=1088&amp;amp;height=347&amp;amp;face=0_0_1088_347&quot; data-og-url=&quot;https://rebro.kr/160&quot; data-og-source-url=&quot;https://rebro.kr/160&quot; data-og-host=&quot;rebro.kr&quot; data-og-description=&quot;[목차] 1. 제1 정규형 2. 제2 정규형 3. 제3 정규형 4. BCNF 정규형이란 정규화된 결과를 말하며, 제1 정규형, 제2 정규형, 제3 정규형, BCNF, 제4 정규형, 제5 정규형이 있다. 실무적으로 제4, 제5 정규형은&quot; data-og-title=&quot;[DB] 8. 정규형 (1NF, 2NF, 3NF, BCNF)&quot; data-og-type=&quot;article&quot; data-ke-align=&quot;alignCenter&quot; data-ke-type=&quot;opengraph&quot;&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://rebro.kr/160&quot; data-source-url=&quot;https://rebro.kr/160&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/UCFT1/hyU2poN69R/N30MbYWmnP9zUYylwPaeEk/img.png?width=796&amp;amp;height=356&amp;amp;face=0_0_796_356,https://scrap.kakaocdn.net/dn/qVi0c/hyUXVpnbzz/MuVafoKskawNlGXmOkt691/img.png?width=796&amp;amp;height=356&amp;amp;face=0_0_796_356,https://scrap.kakaocdn.net/dn/sqUOM/hyU2p3pAUq/B6vAOtiK1qiAsbLCEcHTjK/img.png?width=1088&amp;amp;height=347&amp;amp;face=0_0_1088_347');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; style=&quot;color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;[DB] 8. 정규형 (1NF, 2NF, 3NF, BCNF)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; style=&quot;color: #909090;&quot; data-ke-size=&quot;size16&quot;&gt;[목차] 1. 제1 정규형 2. 제2 정규형 3. 제3 정규형 4. BCNF 정규형이란 정규화된 결과를 말하며, 제1 정규형, 제2 정규형, 제3 정규형, BCNF, 제4 정규형, 제5 정규형이 있다. 실무적으로 제4, 제5 정규형은&lt;/p&gt;
&lt;p class=&quot;og-host&quot; style=&quot;color: #909090;&quot; data-ke-size=&quot;size16&quot;&gt;rebro.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.sunny-son.space/MySQL/RDBMstart04/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.sunny-son.space/MySQL/RDBMstart04/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1704590343031&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;관계형 데이터베이스 실전 입문 - 04. 정규화 논리(두 번째) - 결합 종속성&quot; data-og-description=&quot;1. 결합 종속성(JD) 함수 종속성을 사용한 정규화는 후보키가 되는 속성을 찾아내는 작업이다. 그리고 이런 숨겨진 후보키가 발견됐을 때에는 릴레이션을 무손실 분해해 릴레이션 내부의 중복을 &quot; data-og-host=&quot;www.sunny-son.space&quot; data-og-source-url=&quot;https://www.sunny-son.space/MySQL/RDBMstart04/&quot; data-og-url=&quot;https://www.sunny-son.space/mysql/rdbmstart04/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.sunny-son.space/MySQL/RDBMstart04/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.sunny-son.space/MySQL/RDBMstart04/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;관계형 데이터베이스 실전 입문 - 04. 정규화 논리(두 번째) - 결합 종속성&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;1. 결합 종속성(JD) 함수 종속성을 사용한 정규화는 후보키가 되는 속성을 찾아내는 작업이다. 그리고 이런 숨겨진 후보키가 발견됐을 때에는 릴레이션을 무손실 분해해 릴레이션 내부의 중복을&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.sunny-son.space&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DB</category>
      <category>DB 1NF</category>
      <category>DB 2NF</category>
      <category>DB 3NF</category>
      <category>DB 4NF</category>
      <category>DB 5NF</category>
      <category>DB 정규화</category>
      <category>DB 정규화 예시</category>
      <category>부분함수종속</category>
      <category>완전함수종속</category>
      <category>이행함수종속</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/162</guid>
      <comments>https://co-no.tistory.com/entry/RDBMS#entry162comment</comments>
      <pubDate>Sun, 7 Jan 2024 11:12:00 +0900</pubDate>
    </item>
    <item>
      <title>[RDBMS] RDB 정규화와 이상(Anomaly)현상의 개념 및 예시</title>
      <link>https://co-no.tistory.com/entry/%EA%B0%9C%EB%85%90-%EC%A0%95%EA%B7%9C%ED%99%94%EC%99%80-%EB%B9%84%EC%A0%95%EA%B7%9C%ED%99%94%EC%9D%98-%EA%B0%9C%EB%85%90-%ED%95%84%EC%9A%94%EC%84%B1-%EC%98%88%EC%8B%9C</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;정규화(Normalization)란?&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: 어떤 대상을 일정한 규칙이나 기준에 따르는 '정규적인' 상태로 바꾸거나, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;비정상적인 대상&lt;/b&gt;&lt;/span&gt;을 정상적으로 되돌리는 과정을 뜻한다. 특히, RDB(관계형 데이터베이스)에서는, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;이상 현상&lt;/b&gt;&lt;/span&gt;이 존재하는 릴레이션을 분해하여, 여러 개의 릴레이션으로 생성하는데, 이를 단계별로 구분하여 정규화 과정이 고도화될 수록 이러한 이상 현상을 줄일 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면, DB에서의 '&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;이상 현상(Anomaly)&lt;/b&gt;&lt;/span&gt;'이란 무엇일까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;불필요한 데이터 중복&lt;/b&gt;으로 인해 릴레이션에 대한 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;데이터 삽입, 수정, 삭제 연산을 할 때 발생할 수 있는 문제&lt;/b&gt;&lt;/span&gt; 또는 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;DB의 무결성을 저해하는 부작용&lt;/b&gt;&lt;/span&gt;을 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적으로 DB에서 말하는 이상 현상은 크게 다음과 같이 3가지이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;삽입 이상(Insertion Anomaly)&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;삭제 이상(Deletion Anomaly)&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;갱신 이상(Update Anomaly)&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1. 삽입 이상이란?&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;b&gt;레코드를 테이블에 &lt;span style=&quot;color: #8a3db6;&quot;&gt;삽입할 때&lt;/span&gt;, &lt;span style=&quot;color: #8a3db6;&quot;&gt;의도하지 않은 데이터까지 삽입을 해야만&lt;/span&gt;, 해당 레코드를 테이블에 추가가 가능한 현상&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;예시)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Q.&lt;/b&gt; 사원 테이블을 다음과 같이 구성했을 때, 새로운 부서에 대한 &lt;b&gt;부서 이름만 추가하고 싶어요&lt;/b&gt;. 그런데, &lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;주민등록번호가 기본키&lt;/b&gt;&lt;/span&gt;여서, Not null 제약조건이 걸려 있어요. 어떻게 해야 할까요?&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;753&quot; data-origin-height=&quot;388&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bnfv1N/btsC1FK3FOZ/8wH5YFvMXhiqk1KclgsRd0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bnfv1N/btsC1FK3FOZ/8wH5YFvMXhiqk1KclgsRd0/img.png&quot; data-alt=&quot;잘못 구성한 [사원] 테이블&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bnfv1N/btsC1FK3FOZ/8wH5YFvMXhiqk1KclgsRd0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbnfv1N%2FbtsC1FK3FOZ%2F8wH5YFvMXhiqk1KclgsRd0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;369&quot; height=&quot;190&quot; data-origin-width=&quot;753&quot; data-origin-height=&quot;388&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;잘못 구성한 [사원] 테이블&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;A.&lt;/b&gt; 그 &lt;b&gt;[사원]&lt;/b&gt; 테이블을 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;둘로 쪼개세요!&lt;/b&gt;&lt;/span&gt; &lt;b&gt;[사원]&lt;/b&gt; 테이블과 &lt;b&gt;[부서]&lt;/b&gt; 테이블을 따로 관리하면 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1540&quot; data-origin-height=&quot;891&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0taR7/btsCTVhgmkH/ehy3bxmtElHabk2fhl6ndK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0taR7/btsCTVhgmkH/ehy3bxmtElHabk2fhl6ndK/img.png&quot; data-alt=&quot;삽입 이상을 개선한 [사원] 테이블과 [부서] 테이블&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0taR7/btsCTVhgmkH/ehy3bxmtElHabk2fhl6ndK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0taR7%2FbtsCTVhgmkH%2Fehy3bxmtElHabk2fhl6ndK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;596&quot; height=&quot;345&quot; data-origin-width=&quot;1540&quot; data-origin-height=&quot;891&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;삽입 이상을 개선한 [사원] 테이블과 [부서] 테이블&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2. 삭제 이상이란?&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;b&gt;어떤 레코드를 삭제하면, &lt;span style=&quot;color: #8a3db6;&quot;&gt;의도하지 않은 다른 데이터까지 삭제&lt;/span&gt;되어 버리는 현상&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시) &lt;b&gt;[사원]&lt;/b&gt; 테이블&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 97.5581%; height: 199px;&quot; border=&quot;1&quot; width=&quot;626&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;70&quot; height=&quot;23&quot;&gt;&lt;b&gt;E_NAME&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;82&quot;&gt;&lt;b&gt;B_DATE&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;136&quot;&gt;&lt;b&gt;ADDRESS&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;89&quot;&gt;&lt;b&gt;D_NUMBER&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;149&quot;&gt;&lt;b&gt;D_NAME&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;100&quot;&gt;&lt;b&gt;D_MANAGER&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; height=&quot;23&quot;&gt;정재호&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;2024.01.04&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;인천&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;101&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;IT팀 운영파트&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;이상철&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; height=&quot;23&quot;&gt;홍인광&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;2024.01.04&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;김포&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;102&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;IT팀 개발파트&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;박종인&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; height=&quot;23&quot;&gt;김가희&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;2023.05.01&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;서울 광진구&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;103&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;인사총무팀 인사파트&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;안주은&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; height=&quot;23&quot;&gt;연동호&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;2003.01.03&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;파주&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;104&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;QA팀&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;김유이&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Q.&lt;/b&gt; &lt;b&gt;'김유이'&lt;/b&gt;라는 매니저가 퇴사해서, [사원] 테이블에서 '김유이'라는 데이터를 &lt;b&gt;삭제&lt;/b&gt;하고 싶은데, 그러면&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt; '연동호' 사원 데이터까지 모두 사라져버려요.&lt;/b&gt;&lt;/span&gt; 어떻게 해야 될까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;A.&lt;/b&gt; 다음과 같이 &lt;b&gt;[사원]&lt;/b&gt; 테이블과&lt;b&gt; [부서]&lt;/b&gt; 테이블로 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;나누세요!&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[사원]&lt;/b&gt; 테이블&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 59.0698%; height: 203px;&quot; border=&quot;1&quot; width=&quot;362&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;90&quot; height=&quot;23&quot;&gt;&lt;b&gt;E_NAME&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;136&quot;&gt;&lt;b&gt;B_DATE&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;136&quot;&gt;&lt;b&gt;ADDRESS&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; height=&quot;23&quot;&gt;정재호&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;2024.01.04&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;인천&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; height=&quot;23&quot;&gt;홍인광&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;2024.01.04&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;김포&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; height=&quot;23&quot;&gt;김가희&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;2023.05.01&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;서울 광진구&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; height=&quot;23&quot;&gt;연동호&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;2003.01.03&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;파주&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[부서]&lt;/b&gt; 테이블&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 59.1861%; height: 215px;&quot; border=&quot;1&quot; width=&quot;362&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style14&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;90&quot; height=&quot;23&quot;&gt;&lt;b&gt;D_NUMBER&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;136&quot;&gt;&lt;b&gt;D_NAME&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;136&quot;&gt;&lt;b&gt;D_MANAGER&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; height=&quot;23&quot;&gt;101&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;IT팀 운영파트&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;이상철&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; height=&quot;23&quot;&gt;102&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;IT팀 개발파트&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;박종인&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; height=&quot;23&quot;&gt;103&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;인사총무팀 인사파트&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;안주은&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; height=&quot;23&quot;&gt;104&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;QA팀&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;김유이&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3. 갱신 이상이란?&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: 중복된 데이터 중 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;일부만 수정되어 데이터 모순&lt;/b&gt;&lt;/span&gt;이 일어나거나, &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;한 데이터 수정이 불필요한 수많은 데이터 수정을 야기&lt;/b&gt;&lt;/span&gt;하는 현상&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시) &lt;b&gt;[주문]&lt;/b&gt; 테이블 &lt;b&gt;ver.1&lt;/b&gt; (&lt;b&gt;총 매출 : 38,000원 / 입금된 금액 : 38,000원&lt;/b&gt;)&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 104.884%; height: 197px;&quot; border=&quot;1&quot; width=&quot;600&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;90&quot; height=&quot;23&quot;&gt;&lt;b&gt;주문자명&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;136&quot;&gt;&lt;b&gt;주문상품&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;136&quot;&gt;&lt;b&gt;상품 금액&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;89&quot;&gt;&lt;b&gt;배송지&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;149&quot;&gt;&lt;b&gt;배송상태&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; height=&quot;23&quot;&gt;정재호&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;닭가슴살&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;10,000&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;인천&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;배송 중&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; height=&quot;23&quot;&gt;정재호&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;닭가슴살&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;10,000&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;진천&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;배송 준비중&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; height=&quot;23&quot;&gt;홍인광&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;고구마&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;3,000&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;김포&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;배송 중&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; height=&quot;23&quot;&gt;홍인광&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;소고기&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;15,000&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;김포&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;배송 완료&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[주문]&lt;/b&gt; 테이블 &lt;b&gt;ver.2&lt;/b&gt; (&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;총 매출 : 78,000원 / 입금된 금액 : 58,000원&lt;/b&gt;&lt;/span&gt;)&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 104.767%; height: 240px;&quot; border=&quot;1&quot; width=&quot;600&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 23px;&quot;&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot; width=&quot;90&quot; height=&quot;23&quot;&gt;&lt;b&gt;주문자명&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot; width=&quot;136&quot;&gt;&lt;b&gt;주문상품&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot; width=&quot;136&quot;&gt;&lt;b&gt;상품 금액&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot; width=&quot;89&quot;&gt;&lt;b&gt;배송지&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot; width=&quot;149&quot;&gt;&lt;b&gt;배송상태&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 23px;&quot;&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot; height=&quot;23&quot;&gt;정재호&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot;&gt;닭가슴살&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;20,000&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot;&gt;인천&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot;&gt;배송 완료&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 23px;&quot;&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot; height=&quot;23&quot;&gt;정재호&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot;&gt;닭가슴살&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;20,000&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot;&gt;진천&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot;&gt;배송 완료&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 23px;&quot;&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot; height=&quot;23&quot;&gt;홍인광&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot;&gt;고구마&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot;&gt;3,000&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot;&gt;김포&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot;&gt;배송 완료&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 23px;&quot;&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot; height=&quot;23&quot;&gt;홍인광&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot;&gt;소고기&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot;&gt;15,000&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot;&gt;김포&lt;/td&gt;
&lt;td style=&quot;height: 23px; text-align: center;&quot;&gt;배송 완료&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 20px;&quot;&gt;정재호&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 20px;&quot;&gt;닭가슴살&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 20px;&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;20,000&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 20px;&quot;&gt;인천&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 20px;&quot;&gt;배송 준비중&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Q.&lt;/b&gt; 미친 인플레이션 때문에 닭가슴살 가격을 10,000원 -&amp;gt; 20,000원으로 인상해야 해요. 그런데 이렇게 올리고 나면, [주문] 테이블을 기준으로 매출을 계산하는 저희 회사는, &lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;입금된 금액이랑 총 매출이랑 맞지 않게 돼요.&lt;/b&gt;&lt;/span&gt; 어떻게 해야 할까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;A.&lt;/b&gt; &lt;b&gt;[상품]&lt;/b&gt; 테이블 &lt;b&gt;[주문]&lt;/b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;테이블&lt;/span&gt;을 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;나눠서 관리하세요!&lt;/b&gt;&lt;/span&gt; 그럼 상품 가격의 변동이 있을 때, [상품] 테이블에서의 '상품 가격' 컬럼만 수정하면, 상품 가격 변동 이전에 [주문] 테이블에 들어간 데이터는 변경되지 않을 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[상품]&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;테이블&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 34.3023%; height: 156px;&quot; border=&quot;1&quot; width=&quot;226&quot; data-ke-style=&quot;style14&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;90&quot; height=&quot;23&quot;&gt;&lt;b&gt;상품명&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;136&quot;&gt;&lt;b&gt;상품 가격&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; height=&quot;23&quot;&gt;닭가슴살&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;20,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; height=&quot;23&quot;&gt;고구마&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;3,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; height=&quot;23&quot;&gt;소고기&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;15,000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[주문]&lt;/b&gt; 테이블 (총 매출 : 58,000원 / 입금된 금액 : 58,000원)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(닭가슴살 가격이 10,000 -&amp;gt; 20,000 원으로 인상되어도, 이전에 주문된 닭가슴살의 주문 금액은 바뀌지 않으므로, 입금된 금액이랑 총 매출이 다르게 될 위험이 없음.)&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100.349%; height: 215px;&quot; border=&quot;1&quot; width=&quot;600&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 23px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot; width=&quot;90&quot; height=&quot;23&quot;&gt;&lt;b&gt;주문자명&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot; width=&quot;136&quot;&gt;&lt;b&gt;주문상품&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot; width=&quot;136&quot;&gt;&lt;b&gt;주문 금액&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot; width=&quot;89&quot;&gt;&lt;b&gt;배송지&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot; width=&quot;149&quot;&gt;&lt;b&gt;배송상태&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 23px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot; height=&quot;23&quot;&gt;정재호&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot;&gt;닭가슴살&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot;&gt;10,000&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot;&gt;인천&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot;&gt;배송 완료&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 23px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot; height=&quot;23&quot;&gt;정재호&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot;&gt;닭가슴살&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot;&gt;10,000&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot;&gt;진천&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot;&gt;배송 완료&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 23px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot; height=&quot;23&quot;&gt;홍인광&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot;&gt;고구마&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot;&gt;3,000&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot;&gt;김포&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot;&gt;배송 완료&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 23px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot; height=&quot;23&quot;&gt;홍인광&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot;&gt;소고기&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot;&gt;15,000&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot;&gt;김포&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 23px;&quot;&gt;배송 완료&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 21px;&quot; height=&quot;23&quot;&gt;정재호&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 21px;&quot;&gt;닭가슴살&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 21px;&quot;&gt;20,000&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 21px;&quot;&gt;인천&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 21px;&quot;&gt;배송 준비중&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기까지 봤다면, 이런 궁금증이 생길 것이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt;&quot;대체 테이블을 쪼개는 기준이 뭐지? 그때그때의 상황마다 다른건가?&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt;그런데, 그렇게 상황마다 테이블 스키마를 변경하려면 DB 작업 시간 잡느라 Downtime도 잡아야 하고, 컬럼을 늘릴 때 데이터 제약조건은 어떻게 잡을 지, 제약조건에 따른 Null값은 어떻게 처리할지, 만약 다른 상황이 생긴다면 설계된 테이블을 계속 쪼개기만 하면 되나...? 하아.. 이거 수정하는 거에 따라서 애플리케이션도 다 변경해야 하는데...&quot;&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;와 같은 수많은 문제에 직면하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 문제를 여러 번 경험한 데이터베이스 이론가들은 일종의 정규화에 대한 규칙이 고민하고 확립하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 다음 포스팅에서 알아보도록 하자!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://co-no.tistory.com/entry/RDBMS&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://co-no.tistory.com/entry/RDBMS&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@kon6443/DB-%EC%A0%95%EA%B7%9C%ED%99%94%EC%9D%98-%ED%95%84%EC%9A%94%EC%84%B1-%EB%B0%8F-%EA%B0%9C%EB%85%90&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://velog.io/@kon6443/DB-%EC%A0%95%EA%B7%9C%ED%99%94%EC%9D%98-%ED%95%84%EC%9A%94%EC%84%B1-%EB%B0%8F-%EA%B0%9C%EB%85%90&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1704291959642&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[DB] 정규화의 필요성 및 개념&quot; data-og-description=&quot;정규화(Normalization)란 중복된 데이터 방지, 부모와 자식 데이터 간의 논리적 관계 유지, 에러 감소 및 재개발 비용 감소 등을 위해 존재한다.어려운 말로는, 테이블 간 중복된 데이터를 줄이며 데&quot; data-og-host=&quot;velog.io&quot; data-og-source-url=&quot;https://velog.io/@kon6443/DB-%EC%A0%95%EA%B7%9C%ED%99%94%EC%9D%98-%ED%95%84%EC%9A%94%EC%84%B1-%EB%B0%8F-%EA%B0%9C%EB%85%90&quot; data-og-url=&quot;https://velog.io/@kon6443/DB-정규화의-필요성-및-개념&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bxhuXb/hyUXLfGAAd/FsGrfvDvFDGOE9HJmSisY0/img.png?width=950&amp;amp;height=500&amp;amp;face=0_0_950_500,https://scrap.kakaocdn.net/dn/GZLRg/hyUXWBtMgY/VzWpEgsKRZKUKEiHRsxXGK/img.png?width=1536&amp;amp;height=401&amp;amp;face=0_0_1536_401,https://scrap.kakaocdn.net/dn/fOGXe/hyUXWan7TO/WygdRBMerUHdsBvE18zYF1/img.png?width=1536&amp;amp;height=401&amp;amp;face=0_0_1536_401&quot;&gt;&lt;a href=&quot;https://velog.io/@kon6443/DB-%EC%A0%95%EA%B7%9C%ED%99%94%EC%9D%98-%ED%95%84%EC%9A%94%EC%84%B1-%EB%B0%8F-%EA%B0%9C%EB%85%90&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://velog.io/@kon6443/DB-%EC%A0%95%EA%B7%9C%ED%99%94%EC%9D%98-%ED%95%84%EC%9A%94%EC%84%B1-%EB%B0%8F-%EA%B0%9C%EB%85%90&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bxhuXb/hyUXLfGAAd/FsGrfvDvFDGOE9HJmSisY0/img.png?width=950&amp;amp;height=500&amp;amp;face=0_0_950_500,https://scrap.kakaocdn.net/dn/GZLRg/hyUXWBtMgY/VzWpEgsKRZKUKEiHRsxXGK/img.png?width=1536&amp;amp;height=401&amp;amp;face=0_0_1536_401,https://scrap.kakaocdn.net/dn/fOGXe/hyUXWan7TO/WygdRBMerUHdsBvE18zYF1/img.png?width=1536&amp;amp;height=401&amp;amp;face=0_0_1536_401');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[DB] 정규화의 필요성 및 개념&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;정규화(Normalization)란 중복된 데이터 방지, 부모와 자식 데이터 간의 논리적 관계 유지, 에러 감소 및 재개발 비용 감소 등을 위해 존재한다.어려운 말로는, 테이블 간 중복된 데이터를 줄이며 데&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;velog.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://dev-coco.tistory.com/63&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://dev-coco.tistory.com/63&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1704378298122&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[DataBase] 이상 현상(Anomaly)이란?&quot; data-og-description=&quot;좋은 관계형데이터베이스를 설계하는 목적 중 하나가 정보의 이상 현상(Anomaly)이 생기지 않도록 고려해 설계하는 것입니다. 이상 현상은 테이블을 설계할 때 잘못 설계하여 데이터를 삽입, 삭제&quot; data-og-host=&quot;dev-coco.tistory.com&quot; data-og-source-url=&quot;https://dev-coco.tistory.com/63&quot; data-og-url=&quot;https://dev-coco.tistory.com/63&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bAEGqC/hyUXL1knj8/LdZk6sjnmsEywTjkhhK3q1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/dtJawZ/hyUXVJFAKt/4YEBxetB7CkkQm8piZnHAK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://dev-coco.tistory.com/63&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://dev-coco.tistory.com/63&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bAEGqC/hyUXL1knj8/LdZk6sjnmsEywTjkhhK3q1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/dtJawZ/hyUXVJFAKt/4YEBxetB7CkkQm8piZnHAK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[DataBase] 이상 현상(Anomaly)이란?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;좋은 관계형데이터베이스를 설계하는 목적 중 하나가 정보의 이상 현상(Anomaly)이 생기지 않도록 고려해 설계하는 것입니다. 이상 현상은 테이블을 설계할 때 잘못 설계하여 데이터를 삽입, 삭제&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;dev-coco.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DB</category>
      <category>DB 갱신이상</category>
      <category>DB 삭제이상</category>
      <category>DB 삽입이상</category>
      <category>RDB 이상현상</category>
      <category>RDB 정규화</category>
      <category>RDB 정규화 필요성</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/161</guid>
      <comments>https://co-no.tistory.com/entry/%EA%B0%9C%EB%85%90-%EC%A0%95%EA%B7%9C%ED%99%94%EC%99%80-%EB%B9%84%EC%A0%95%EA%B7%9C%ED%99%94%EC%9D%98-%EA%B0%9C%EB%85%90-%ED%95%84%EC%9A%94%EC%84%B1-%EC%98%88%EC%8B%9C#entry161comment</comments>
      <pubDate>Wed, 3 Jan 2024 23:18:55 +0900</pubDate>
    </item>
    <item>
      <title>[Terraform] 테라폼을 통한 AWS 3-tier 구성 (1) - AWS CLI 설정 및 VPC 생성</title>
      <link>https://co-no.tistory.com/entry/Terraform-%ED%85%8C%EB%9D%BC%ED%8F%BC%EC%9D%84-%ED%86%B5%ED%95%9C-AWS-%EA%B5%AC%EC%84%B1-VPC-%EC%83%9D%EC%84%B1</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;0. AWS CLI 및 AWS Configure&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테라폼으로 aws 리소스를 관리하기 위해서는, 테라폼이 구동되는 &lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;동일한 환경 내에서 AWS CLI가 설치되어 있고, AWS CLI를 통해 모든 리소스의 접근 권한을 가진 AWS IAM User와의 연동이 필요하다.&lt;/b&gt;&lt;/span&gt; AWS 루트사용자와 동일한 권한을 가진 IAM User 설정이 되지 않았다면, 아래 포스팅을 참고하길 바란다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://co-no.tistory.com/entry/AWS-AWS-%EA%B0%80%EC%9E%85-%ED%9B%84-%EC%B4%88%EA%B8%B0-%EC%84%B8%ED%8C%851-IAM&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://co-no.tistory.com/entry/AWS-AWS-%EA%B0%80%EC%9E%85-%ED%9B%84-%EC%B4%88%EA%B8%B0-%EC%84%B8%ED%8C%851-IAM&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1703809146578&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[AWS] AWS 가입 후 초기 세팅 - IAM, Budgets 설정&quot; data-og-description=&quot;IAM(Identity and Access Management)이란 무엇인가? : AWS를 사용하는 데에 가장 기초적인 서비스 중 하나로, AWS의 리소스들을 관리하고 권한을 설정하며, 각 리소스 간의 연계를 위해 필수적인 시스템이다&quot; data-og-host=&quot;co-no.tistory.com&quot; data-og-source-url=&quot;https://co-no.tistory.com/entry/AWS-AWS-%EA%B0%80%EC%9E%85-%ED%9B%84-%EC%B4%88%EA%B8%B0-%EC%84%B8%ED%8C%851-IAM&quot; data-og-url=&quot;https://co-no.tistory.com/entry/AWS-AWS-%EA%B0%80%EC%9E%85-%ED%9B%84-%EC%B4%88%EA%B8%B0-%EC%84%B8%ED%8C%851-IAM&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bnJ9Za/hyUTH5KxGU/PCnJ2fKRgkHk0kOJPCYksk/img.png?width=371&amp;amp;height=660&amp;amp;face=0_0_371_660,https://scrap.kakaocdn.net/dn/kUeRU/hyUTzUaGwu/EJvCQGqzKjItTsoMkt6khK/img.png?width=371&amp;amp;height=660&amp;amp;face=0_0_371_660,https://scrap.kakaocdn.net/dn/dwDWyP/hyUTxINRHz/dN0DHhSaXY8YBU5HZm4wkk/img.png?width=1918&amp;amp;height=913&amp;amp;face=0_0_1918_913&quot;&gt;&lt;a href=&quot;https://co-no.tistory.com/entry/AWS-AWS-%EA%B0%80%EC%9E%85-%ED%9B%84-%EC%B4%88%EA%B8%B0-%EC%84%B8%ED%8C%851-IAM&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://co-no.tistory.com/entry/AWS-AWS-%EA%B0%80%EC%9E%85-%ED%9B%84-%EC%B4%88%EA%B8%B0-%EC%84%B8%ED%8C%851-IAM&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bnJ9Za/hyUTH5KxGU/PCnJ2fKRgkHk0kOJPCYksk/img.png?width=371&amp;amp;height=660&amp;amp;face=0_0_371_660,https://scrap.kakaocdn.net/dn/kUeRU/hyUTzUaGwu/EJvCQGqzKjItTsoMkt6khK/img.png?width=371&amp;amp;height=660&amp;amp;face=0_0_371_660,https://scrap.kakaocdn.net/dn/dwDWyP/hyUTxINRHz/dN0DHhSaXY8YBU5HZm4wkk/img.png?width=1918&amp;amp;height=913&amp;amp;face=0_0_1918_913');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[AWS] AWS 가입 후 초기 세팅 - IAM, Budgets 설정&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;IAM(Identity and Access Management)이란 무엇인가? : AWS를 사용하는 데에 가장 기초적인 서비스 중 하나로, AWS의 리소스들을 관리하고 권한을 설정하며, 각 리소스 간의 연계를 위해 필수적인 시스템이다&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;co-no.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;0.1. AWS CLI 설치&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;테라폼이 작동할 동일한 환경에서 AWS CLI를 설치&lt;/b&gt;&lt;/span&gt;해보자!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필자의 경우, 테라폼을 AWS와 전혀 상관 없는 개인 랩탑에서 사용할 것이고, &lt;b&gt;WSL의 Ubuntu22.04&lt;/b&gt; 를 이용할 것이므로,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음과 같이 진행한다.&lt;/p&gt;
&lt;pre id=&quot;code_1703809549733&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# aws 공식홈페이지의 awscli-exe-linux-x86_64.zip 파일을 awscliv2.zip 파일로 내려받기
curl &quot;https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip&quot; -o &quot;awscliv2.zip&quot;

# 내려받은 압축 파일 압축 해제
unzip awscliv2.zip

# aws cli 설치
sudo ./aws/install

# aws cli 설치 완료 후, 버전 확인하여 설치 제대로 되었는지 확인
aws --version&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;0.2. AWS Configure 설정&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 명령어를 통해, AWS CLI와 연동시키려는 AWS 환경에 대한 'AWS Access Key ID'와 'AWS Secret Access Key' 입력이 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로,&lt;b&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt; --profile&lt;/span&gt; 옵션&lt;/b&gt;을 주어, AWS CLI 상에서 해당 키 값을 프로필 config로 설정할 것이고, 이 프로필을 테라폼의 provider 설정에도 사용할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리전은 한국에서만 테스트 할테니, '&lt;b&gt;ap-northeast-2&lt;/b&gt;'로 설정해주자. output format은 &lt;b&gt;json&lt;/b&gt;으로 설정하여 범용적으로 사용해보자!&lt;/p&gt;
&lt;pre id=&quot;code_1703810213312&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;aws configure --profile [원하는 profile name]
# 필자의 경우, 'myAWSIAM' 이라고 프로필 이름을 설정

# AWS Access KEY ID [None] : &amp;lt;루트사용자와 동등한 권한의 IAM User 통해 발급받은 액세스 키ID&amp;gt;
# AWS Secret Access Key [None] : &amp;lt;루트사용자와 동등한 권한의 IAM User 통해 발급받은 private 액세스 키&amp;gt;
# Default region name [None] : ap-northeast-2
# Default outpu format [None] : json

# 생성한 프로필 목록 확인
aws configure list-profiles

# 프로필 지정에서 값이 잘 들어갔는지 확인하기 위한 해당 프로필의 region 값 확인하기
aws configure get region --profile [생성한 profile name]

# 생성한 프로필을 AWS CLI의 기본 프로필로 지정
export AWS_DEFAULT_PROFILE=[생성한 profile name]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 과정을 마친 후, 아래 명령어를 수행하여 AWS CLI와 실제 AWS 환경과 연동이 잘 되었는 지 확인한다.&lt;/p&gt;
&lt;pre id=&quot;code_1703810266269&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;aws s3 ls&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 명령어는 연동한 AWS 환경에서의 S3에 'ls' 명령어를 날리는 것으로,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffc9af;&quot;&gt;&lt;b&gt;해당 AWS 환경에 S3가 셋업되어 있다면, 어떤 결과물이 출력될 것이고, 그게 아니라면 아무것도 나타나지 않을 것이다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 &quot;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;Invalid Access Key&lt;/b&gt;&lt;/span&gt;&quot; 와 같은 에러가 나타난다면, &lt;u&gt;키 값이 잘못 입력되었거나, 유효하지 않은 키 값이므로 상황에 맞춰 이를 해결해야 한다.&lt;/u&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;1.&amp;nbsp; AWS provider 셋업&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;테라폼이 AWS 서비스의 api 액세스를 하기 위해서는, 내가 구성한 AWS의 Key 값을 테라폼이 인식하여야&lt;/b&gt;&lt;/span&gt; 한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그 과정을 .tf 파일에 하드코딩으로 넣어두면 보안이 매우 취약해지니,&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;다음과 같이 테라폼 provider 파일에서 AWS CLI에서 설정한 프로필 네임을 가져오자.&lt;/p&gt;
&lt;pre id=&quot;code_1703811909570&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 테라폼 working 디렉토리로 이동 (필자의 경우, WSL 환경이므로, /mnt/c/Terraform 이라는 디렉토리를 만들었음.)
cd /mnt/c/Terraform&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1703811992344&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# provider.tf 작성 (vi provider.tf)
provider &quot;aws&quot; {
  profile = &quot;myAWSIAM&quot;
  region = &quot;ap-northeast-2&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1703740206166&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# terraform init을 통한 provider 환경 구축
# init 시에 등록되어 있는 'AWS_ACCESS_KEY_ID', 'AWS_SECRET_ACCESS_KEY', 'AWS_DEFAULT_REGION' 환경변수를 읽어옴.
terraform init&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;682&quot; data-origin-height=&quot;370&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdgHYZ/btsCQoWeGQF/PO4zLyUfMAjK3OrBtfgHpK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdgHYZ/btsCQoWeGQF/PO4zLyUfMAjK3OrBtfgHpK/img.png&quot; data-alt=&quot;terraform init 성공시 나오는 메시지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdgHYZ/btsCQoWeGQF/PO4zLyUfMAjK3OrBtfgHpK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdgHYZ%2FbtsCQoWeGQF%2FPO4zLyUfMAjK3OrBtfgHpK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;682&quot; height=&quot;370&quot; data-origin-width=&quot;682&quot; data-origin-height=&quot;370&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;terraform init 성공시 나오는 메시지&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;2. VPC 생성을 위한 테라폼 resource 파일 작성&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1703741382766&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# vpc.tf

resource &quot;aws_vpc&quot; &quot;VPC_TEST&quot; {
  cidr_block           = &quot;10.0.0.0/16&quot;
  enable_dns_hostnames = &quot;true&quot;
  instance_tenancy     = &quot;default&quot;
  
  
  tags = {
    Name = &quot;3-Tier 구성을 위한 테스트 VPC&quot;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;cidr_block :&amp;nbsp;&lt;/b&gt;VPC의 IP주소 대역을 Classless Inter-Domain Routing(CIDR) 표기법을 사용하여 설정하는 것&lt;br /&gt;참고로, AWS에서는 VPC의 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;10.0.0.0 대역은 10.0.0.0/16 ~ 10.0.0.0/28 까지만 지원&lt;/b&gt;&lt;/span&gt;한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;enable_dns_hostnames (Optional)&lt;/b&gt; : &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;VPC가 Public IP 주소가 있는 인스턴스에 대해서는 Public DNS hostnam을 할당하는 것에 대한 지원 여부를 결정&lt;/b&gt;&lt;/span&gt;하는 옵션. Default는 false&lt;/li&gt;
&lt;li&gt;&lt;b&gt;instance_tenancy&lt;/b&gt; : VPC 내부에서 동작하는 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;인스턴스에 대한 테넌시 옵션&lt;/b&gt;&lt;/span&gt;.
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;default&lt;/b&gt; : 인스턴스가 기본 테넌시로 배치됨 = 인스턴스가 공유 호스트에 배치됨 = 사용자가 누구인지 상관없이 AWS의 인스턴스가 모두 한 동일한 물리적 하드웨어에 배치된다는 의미&lt;/li&gt;
&lt;li&gt;&lt;b&gt;dedicated&lt;/b&gt; : 인스턴스가 전용 테넌시로 배치됨 = 특정 유저별로 인스턴스가 위치하는 물리적 하드웨어가 달라짐&lt;/li&gt;
&lt;li&gt;&lt;b&gt;host&lt;/b&gt; : 인스턴스가 전용 호스트 테넌시로 배치됨 = 어떤 인스턴스도 들어갈 수 없는, 한 호스트만을 위한 물리적 하드웨어에 인스턴스가 배치됨&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;3. resource 파일 작성 후, &lt;i&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;terraform plan&lt;/span&gt;&lt;/i&gt; 으로 resource 파일 디버깅 및 apply 준비&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;resource 파일 작성이 완료되었다면, 아래 명령어를 수행하여 .tf 파일의 문법 오류나 문제가 되는 부분이 없는지 검증한다.&lt;/p&gt;
&lt;pre id=&quot;code_1703808767580&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;terraform plan&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 작성한 vpc.tf의 plan이 성공적으로 이루어졌다면, 아래 이미지와 같은 문구가 출력될 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;996&quot; data-origin-height=&quot;671&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXLzOi/btsDdDMXwUW/q93c2gh2rPBHKbRpEa3bG0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXLzOi/btsDdDMXwUW/q93c2gh2rPBHKbRpEa3bG0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXLzOi/btsDdDMXwUW/q93c2gh2rPBHKbRpEa3bG0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXLzOi%2FbtsDdDMXwUW%2Fq93c2gh2rPBHKbRpEa3bG0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;996&quot; height=&quot;671&quot; data-origin-width=&quot;996&quot; data-origin-height=&quot;671&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;트러블슈팅)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필자의 경우, 아래와 같은 &quot;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;Invalid provider configuration&lt;/b&gt;&lt;/span&gt;&quot; 에러와 &quot;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;No valid credential sources found&lt;/b&gt;&lt;/span&gt;&quot; 에러가 나왔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;aws configuration 과정을 빼먹어서 그런 듯&lt;/b&gt;&lt;/span&gt; 하다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;953&quot; data-origin-height=&quot;377&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bmMLBO/btsCN6IR9fb/E427dxWvihnNW15JlQcXCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bmMLBO/btsCN6IR9fb/E427dxWvihnNW15JlQcXCK/img.png&quot; data-alt=&quot;Provider &amp;quot;registry.terraform.io/hashicorp/aws&amp;quot; requires explicit configuration 에러&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bmMLBO/btsCN6IR9fb/E427dxWvihnNW15JlQcXCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbmMLBO%2FbtsCN6IR9fb%2FE427dxWvihnNW15JlQcXCK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;953&quot; height=&quot;377&quot; data-origin-width=&quot;953&quot; data-origin-height=&quot;377&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Provider &quot;registry.terraform.io/hashicorp/aws&quot; requires explicit configuration 에러&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 에러 해결방법은 &lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;0.AWS CLI 및 AWS Configure &lt;/b&gt;&lt;/span&gt;과정을 다시 진행해보길 바란다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;4. terraform apply 수행하여 실제 AWS에 VPC 생성하기&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 plna 과정이 정상적으로 되었다면, 아래 명령어를 수행하여 실제 나의 AWS 환경에 VPC를 구축해보자!&lt;/p&gt;
&lt;pre id=&quot;code_1703812578919&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;terraform apply&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;명령어를 수행하면 다음과 같은 문구들이 출력되고, '&lt;b&gt;yes&lt;/b&gt;'라는 값을 입력하라고 나올 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 'yes'라고 입력하고 terraform apply가 성공적으로 수행되었을 때, &quot;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;Apply complete! Resources: [수] added&lt;/b&gt;&lt;/span&gt;&quot; 라는 문구가 출력될 것이다!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1114&quot; data-origin-height=&quot;752&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dv6swg/btsC6UJnycl/AAakQKHdQvuzS6YLt9lfGk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dv6swg/btsC6UJnycl/AAakQKHdQvuzS6YLt9lfGk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dv6swg/btsC6UJnycl/AAakQKHdQvuzS6YLt9lfGk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdv6swg%2FbtsC6UJnycl%2FAAakQKHdQvuzS6YLt9lfGk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1114&quot; height=&quot;752&quot; data-origin-width=&quot;1114&quot; data-origin-height=&quot;752&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테라폼을 통해 AWS의 VPC가 성공적으로 구축되었다면, 실제 나의 AWS에 접속하여 VPC가 생성되었는지 다음과 같이 확인해주자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1914&quot; data-origin-height=&quot;244&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kCGBQ/btsDdELV5Vo/gti0D6y1Q43WXwLdIz6z1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kCGBQ/btsDdELV5Vo/gti0D6y1Q43WXwLdIz6z1k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kCGBQ/btsDdELV5Vo/gti0D6y1Q43WXwLdIz6z1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkCGBQ%2FbtsDdELV5Vo%2Fgti0D6y1Q43WXwLdIz6z1k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1914&quot; height=&quot;244&quot; data-origin-width=&quot;1914&quot; data-origin-height=&quot;244&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 AWS에서도 VPC가 잘 생성된 것을 확인할 수 있다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기까지 하면 테라폼을 통해 VPC를 성공적으로 생성한 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 포스팅을 통해 3-tier 구축을 위한 Subnet, IGW, NAT Gateway, Route Table, Network ACL을 구성해 보자!&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://aws.amazon.com/ko/cli/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://aws.amazon.com/ko/cli/&lt;/a&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1703808984012&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;company&quot; data-og-title=&quot;Command Line Interface - AWS CLI - AWS&quot; data-og-description=&quot;aws-shell은 명령줄 셸 프로그램으로서, AWS 명령줄 인터페이스를 사용하는 새로운 사용자와 고급 사용자 모두에게 도움이 되는 편의 기능 및 생산성 기능을 제공합니다. 주요 기능은 다음과 같습&quot; data-og-host=&quot;aws.amazon.com&quot; data-og-source-url=&quot;https://aws.amazon.com/ko/cli/&quot; data-og-url=&quot;https://aws.amazon.com/ko/cli/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bcWoSl/hyUTBYJpU8/iPtC4wHounk9fYU380fMk1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/c2jGWX/hyUTzGDlwB/LPavTDKx0tTriGpsDSfk0k/img.png?width=179&amp;amp;height=109&amp;amp;face=0_0_179_109&quot;&gt;&lt;a href=&quot;https://aws.amazon.com/ko/cli/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://aws.amazon.com/ko/cli/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bcWoSl/hyUTBYJpU8/iPtC4wHounk9fYU380fMk1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/c2jGWX/hyUTzGDlwB/LPavTDKx0tTriGpsDSfk0k/img.png?width=179&amp;amp;height=109&amp;amp;face=0_0_179_109');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Command Line Interface - AWS CLI - AWS&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;aws-shell은 명령줄 셸 프로그램으로서, AWS 명령줄 인터페이스를 사용하는 새로운 사용자와 고급 사용자 모두에게 도움이 되는 편의 기능 및 생산성 기능을 제공합니다. 주요 기능은 다음과 같습&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;aws.amazon.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://engmisankim.tistory.com/68&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://engmisankim.tistory.com/68&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1703736585680&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;terraform 을 통한 클라우드 인프라 관리&quot; data-og-description=&quot;AWS의 클라우드포메이션처럼 AWS를 포함한 여러 클라우드 환경 및 컨테이너 환경의 인프라를 제어할 수 있는 infrastructure as code 도구인 terraform을 이용하여 AWS 인프라를 제어하는 방법에 대해 공유&quot; data-og-host=&quot;engmisankim.tistory.com&quot; data-og-source-url=&quot;https://engmisankim.tistory.com/68&quot; data-og-url=&quot;https://engmisankim.tistory.com/68&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bdHrn0/hyUTBYrJRC/d8U2gfyI4U2dDG9t3hQIe1/img.jpg?width=658&amp;amp;height=478&amp;amp;face=0_0_658_478,https://scrap.kakaocdn.net/dn/dP4Q04/hyUTAytxyg/BwifreTA2b3C1luIa3tRAK/img.jpg?width=658&amp;amp;height=478&amp;amp;face=0_0_658_478,https://scrap.kakaocdn.net/dn/bpzb0r/hyUTEVd4EF/lKcicAzLsgKQzeQsYBuzXk/img.jpg?width=938&amp;amp;height=540&amp;amp;face=0_0_938_540&quot;&gt;&lt;a href=&quot;https://engmisankim.tistory.com/68&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://engmisankim.tistory.com/68&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bdHrn0/hyUTBYrJRC/d8U2gfyI4U2dDG9t3hQIe1/img.jpg?width=658&amp;amp;height=478&amp;amp;face=0_0_658_478,https://scrap.kakaocdn.net/dn/dP4Q04/hyUTAytxyg/BwifreTA2b3C1luIa3tRAK/img.jpg?width=658&amp;amp;height=478&amp;amp;face=0_0_658_478,https://scrap.kakaocdn.net/dn/bpzb0r/hyUTEVd4EF/lKcicAzLsgKQzeQsYBuzXk/img.jpg?width=938&amp;amp;height=540&amp;amp;face=0_0_938_540');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;terraform 을 통한 클라우드 인프라 관리&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;AWS의 클라우드포메이션처럼 AWS를 포함한 여러 클라우드 환경 및 컨테이너 환경의 인프라를 제어할 수 있는 infrastructure as code 도구인 terraform을 이용하여 AWS 인프라를 제어하는 방법에 대해 공유&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;engmisankim.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://cloudbim.tistory.com/14&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://cloudbim.tistory.com/14&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1703737797268&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;#010) 테라폼 terraform 으로 VPC, EC2 생성하기&quot; data-og-description=&quot;https://www.terraform.io/intro What is Terraform | Terraform by HashiCorp Terraform is an infrastructure as code tool that lets you build, change, and version cloud and on-prem resources safely and efficiently. www.terraform.io 사이트로 가서 테라&quot; data-og-host=&quot;cloudbim.tistory.com&quot; data-og-source-url=&quot;https://cloudbim.tistory.com/14&quot; data-og-url=&quot;https://cloudbim.tistory.com/14&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cVFFih/hyUTK2bMFL/GjIhLzlnyH414qIsfFVmBk/img.png?width=800&amp;amp;height=712&amp;amp;face=0_0_800_712,https://scrap.kakaocdn.net/dn/bGLKkX/hyUTASNmyd/ffxmeqeiFObDxPLlPyBsjk/img.png?width=800&amp;amp;height=712&amp;amp;face=0_0_800_712,https://scrap.kakaocdn.net/dn/iy7UW/hyUTEnmhee/Cd28r3izCE9eprLqq8k0q0/img.png?width=927&amp;amp;height=826&amp;amp;face=0_0_927_826&quot;&gt;&lt;a href=&quot;https://cloudbim.tistory.com/14&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://cloudbim.tistory.com/14&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cVFFih/hyUTK2bMFL/GjIhLzlnyH414qIsfFVmBk/img.png?width=800&amp;amp;height=712&amp;amp;face=0_0_800_712,https://scrap.kakaocdn.net/dn/bGLKkX/hyUTASNmyd/ffxmeqeiFObDxPLlPyBsjk/img.png?width=800&amp;amp;height=712&amp;amp;face=0_0_800_712,https://scrap.kakaocdn.net/dn/iy7UW/hyUTEnmhee/Cd28r3izCE9eprLqq8k0q0/img.png?width=927&amp;amp;height=826&amp;amp;face=0_0_927_826');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;#010) 테라폼 terraform 으로 VPC, EC2 생성하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;https://www.terraform.io/intro What is Terraform | Terraform by HashiCorp Terraform is an infrastructure as code tool that lets you build, change, and version cloud and on-prem resources safely and efficiently. www.terraform.io 사이트로 가서 테라&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;cloudbim.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://gurumee92.tistory.com/230&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://gurumee92.tistory.com/230&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1703809839516&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;04장. Terraform으로 AWS 관리하기 (01) AWS 준비하기&quot; data-og-description=&quot;이번 장은 추후 진행될 실습을 위해서 Terraform으로 AWS 리소스들을 관리하기 위한 준비 작업을 진행한다. 이를 위해서 AWS CLI를 설치하고 AWS의 모든 리소스의 접근을 할 수 있도록 해당 권한을 가&quot; data-og-host=&quot;gurumee92.tistory.com&quot; data-og-source-url=&quot;https://gurumee92.tistory.com/230&quot; data-og-url=&quot;https://gurumee92.tistory.com/230&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ch3lan/hyUTHkl01l/CpvcBpz7hez4jELXqsbgBK/img.png?width=499&amp;amp;height=265&amp;amp;face=0_0_499_265,https://scrap.kakaocdn.net/dn/oHUuT/hyUTL8arRv/pnFwN4fS6G1rFUZt092yu0/img.png?width=499&amp;amp;height=265&amp;amp;face=0_0_499_265,https://scrap.kakaocdn.net/dn/bmOVEA/hyUTxvhEIw/W8dzuzYjcTJs1PM6CjWR9k/img.png?width=889&amp;amp;height=894&amp;amp;face=0_0_889_894&quot;&gt;&lt;a href=&quot;https://gurumee92.tistory.com/230&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://gurumee92.tistory.com/230&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ch3lan/hyUTHkl01l/CpvcBpz7hez4jELXqsbgBK/img.png?width=499&amp;amp;height=265&amp;amp;face=0_0_499_265,https://scrap.kakaocdn.net/dn/oHUuT/hyUTL8arRv/pnFwN4fS6G1rFUZt092yu0/img.png?width=499&amp;amp;height=265&amp;amp;face=0_0_499_265,https://scrap.kakaocdn.net/dn/bmOVEA/hyUTxvhEIw/W8dzuzYjcTJs1PM6CjWR9k/img.png?width=889&amp;amp;height=894&amp;amp;face=0_0_889_894');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;04장. Terraform으로 AWS 관리하기 (01) AWS 준비하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;이번 장은 추후 진행될 실습을 위해서 Terraform으로 AWS 리소스들을 관리하기 위한 준비 작업을 진행한다. 이를 위해서 AWS CLI를 설치하고 AWS의 모든 리소스의 접근을 할 수 있도록 해당 권한을 가&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;gurumee92.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.hashicorp.com/terraform/language/modules/develop/structure&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://developer.hashicorp.com/terraform/language/modules/develop/structure&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1704784631619&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Standard Module Structure | Terraform | HashiCorp Developer&quot; data-og-description=&quot;Learn about the recommended file and directory structure for developing reusable modules distributed as separate repositories.&quot; data-og-host=&quot;developer.hashicorp.com&quot; data-og-source-url=&quot;https://developer.hashicorp.com/terraform/language/modules/develop/structure&quot; data-og-url=&quot;https://developer.hashicorp.com/terraform/language/modules/develop/structure&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b0RyLQ/hyU2sUgQL6/zhzTHJf7ikYSVsTEEOZQg0/img.jpg?width=3200&amp;amp;height=1800&amp;amp;face=0_0_3200_1800,https://scrap.kakaocdn.net/dn/L0al6/hyU2mmcdvS/SMuEJSQHuFB455U2pvuJ50/img.jpg?width=3200&amp;amp;height=1800&amp;amp;face=0_0_3200_1800&quot;&gt;&lt;a href=&quot;https://developer.hashicorp.com/terraform/language/modules/develop/structure&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.hashicorp.com/terraform/language/modules/develop/structure&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b0RyLQ/hyU2sUgQL6/zhzTHJf7ikYSVsTEEOZQg0/img.jpg?width=3200&amp;amp;height=1800&amp;amp;face=0_0_3200_1800,https://scrap.kakaocdn.net/dn/L0al6/hyU2mmcdvS/SMuEJSQHuFB455U2pvuJ50/img.jpg?width=3200&amp;amp;height=1800&amp;amp;face=0_0_3200_1800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Standard Module Structure | Terraform | HashiCorp Developer&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Learn about the recommended file and directory structure for developing reusable modules distributed as separate repositories.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer.hashicorp.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DevOps/Terraform</category>
      <category>AWS CLI</category>
      <category>aws configure</category>
      <category>terraform aws vpc</category>
      <category>terraform aws vpc 생성</category>
      <category>terraform aws 연동</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/160</guid>
      <comments>https://co-no.tistory.com/entry/Terraform-%ED%85%8C%EB%9D%BC%ED%8F%BC%EC%9D%84-%ED%86%B5%ED%95%9C-AWS-%EA%B5%AC%EC%84%B1-VPC-%EC%83%9D%EC%84%B1#entry160comment</comments>
      <pubDate>Fri, 29 Dec 2023 10:25:32 +0900</pubDate>
    </item>
    <item>
      <title>[Terraform] Terraform 개념, Architecture, 설치</title>
      <link>https://co-no.tistory.com/entry/Terraform-Terraform-%EA%B0%9C%EB%85%90-Architecture-%EC%84%A4%EC%B9%98</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;Terraform이란?&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: 테라폼(Terraform)은 &lt;b&gt;하시코프(Hashicorp)&lt;/b&gt;에서 오픈소스로 개발 중인 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;*IaC 도구&lt;/b&gt;&lt;/span&gt;로, &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;인프라를 안전하고 효율적으로 구축, 변경, 버전 관리할 수 있게끔 한다.&lt;/b&gt;&lt;/span&gt; 여기에서 말하는 인프라는, 컴퓨팅 인스턴스, 스토리지, 네트워킹과 같은 low-level 컴포넌트와 DNS 항목 및 SaaS 기능과 같은 High-level의 컴포넌트를 모두 포함한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;*IaC(Infrastructure as Code)&lt;/b&gt; : &lt;u&gt;&lt;b&gt;수동 프로세스가 아닌&lt;/b&gt;&lt;/u&gt;, &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;코드를 통해 인프라를 관리하고 프로비저닝하는 것&lt;/b&gt;&lt;/span&gt;을 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;Terraform의 Arhictecture&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;794&quot; data-origin-height=&quot;379&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bg6d04/btsCLo3NquE/hWAmMA19B5J0CvbbZiYHmK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bg6d04/btsCLo3NquE/hWAmMA19B5J0CvbbZiYHmK/img.png&quot; data-alt=&quot;Terraform Architecture / 출처 :&amp;amp;amp;nbsp;https://spacelift.io/blog/terraform-architecture&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bg6d04/btsCLo3NquE/hWAmMA19B5J0CvbbZiYHmK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbg6d04%2FbtsCLo3NquE%2FhWAmMA19B5J0CvbbZiYHmK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;794&quot; height=&quot;379&quot; data-origin-width=&quot;794&quot; data-origin-height=&quot;379&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Terraform Architecture / 출처 :&amp;amp;nbsp;https://spacelift.io/blog/terraform-architecture&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Terraform Core&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;Terraform CLI&lt;/b&gt;&lt;/span&gt;라고도 하는 Terraform Core는 &lt;b&gt;Go 언어를 사용&lt;/b&gt;하여 개발된 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;정적으로 컴파일된 바이너리&lt;/b&gt;&lt;/span&gt;를 기반으로 만들어졌다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이 바이너리는 '&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;terraform&lt;/b&gt;&lt;/span&gt;' 이라는 CLI 도구를 생성하며, 이 CLI 도구가 테라폼 사용자를 위한 &lt;b&gt;기본 인터페이스 역할&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;이 바이너리는 &lt;b&gt;오픈 소스&lt;/b&gt;이며, &lt;u&gt;Terraform GitHub 리포지토리를 통해 접근 가능&lt;/u&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Terraform Provider&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: Terraform provider는 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;테라폼이 다양한 범주의 서비스 및 리소스와 통신을 가능하게끔 해주는 모듈&lt;/b&gt;&lt;/span&gt;이다. 이러한 서비스 및 리소스는 단순히 Cloud providers, 데이터베이스, DNS 서비스 등으로만 제한되지 않는다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;각 Provider는 특정 서비스 내에서 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;Terraform이 관리할 수 있는 리소스에 대한 정의&lt;/b&gt;&lt;/span&gt; 및 Terraform configuration 내용을 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;해당 서비스에 대한&lt;/b&gt; &lt;b&gt;특정 API 호출로 변환하는 역할&lt;/b&gt;&lt;/span&gt;을 가지고 있다.&lt;/li&gt;
&lt;li&gt;Provider는 &lt;b&gt;AWS, Azure, Goolge Colud와 같은 주요 클라우드 공급자&lt;/b&gt;에 의해 개발된 서비스 및 리소스는 물론이고, &lt;b&gt;community-supported provider&lt;/b&gt;를 통해 &lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;다양한 서비스에 대해서도 사용이 가능하다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;State file&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;: state file은 테라폼의 기능 중 &lt;b&gt;필수 요소&lt;/b&gt;로, &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;테라폼이 관리하는 리소스 정보&lt;/b&gt;&lt;/span&gt;뿐만 아니라, &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;리소스에 대한 현재 상태, 종속성 등을 저장하는 JSON 파일&lt;/b&gt;&lt;/span&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Terraform은 State file을 활용하여&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt; 새로운 테라폼 configuration이 적용될 때에 실제 인프라 리소스에 반영되어야 할 변경사항을 결정&lt;/b&gt;&lt;/span&gt;한다.&lt;/li&gt;
&lt;li&gt;State file은 Terraform Core를 실행하는 &lt;b&gt;Machine에 로컬로 보관할 수도&lt;/b&gt; 있고, Azure 스토리지 계정, AWS S3, 하시코프 Consul과 같은 원격 백엔드를 사용하여&lt;b&gt; 원격으로 보관할 수도&lt;/b&gt; 있다.&lt;/li&gt;
&lt;li&gt;State file에는 현재 관리 중인 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;인프라에 대한 민감한 정보가 포함되어 있으므로, 안전하게 보호 및 보관되어야&lt;/b&gt;&lt;/span&gt; 하고, &lt;b&gt;자주 백업하는 것이 좋다.&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Terraform Provisioners&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;새로 생성된 리소스나 인스턴스에 대해 스크립트나 명령을 실행할 수 있도록 하는 기능&lt;/b&gt;&lt;/span&gt;. 여기에 사용되는 스크립트는 인프라 설정 및 구성, 소프트웨어 설치, 테스트 실행, 기타 필요한 작업 수행 등의 다양한 용도로 사용될 수 있음.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Provisioner는 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;리소스가 생성된 후에 실행&lt;/b&gt;&lt;/span&gt;되며, 리소스가 파괴될 때에 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;트리거되는 것도 가능&lt;/b&gt;&lt;/span&gt;하다.&lt;/li&gt;
&lt;li&gt;테라폼에는 해당 리소스에 파일을 복사하기 위한 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;file provisioner&lt;/b&gt;&lt;/span&gt;와 원격 명령 실행을 위한 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;remote-exec provisioner&lt;/b&gt;&lt;/span&gt;를 비롯한 &lt;b&gt;여러 가지 기본 제공 provisioner가 포함되어 있다.&amp;nbsp;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;또한, 더 다양한 유즈케이스에 대한&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;커스텀 provisioner를 생성&lt;/b&gt;&lt;/span&gt;하는 것도 가능하다. 그런데 이러한 커스텀 provisioner는 테라폼에 존재하는 기존 리소스 블록으로 원하는 결과를 얻을 수 없는 경우에 최후의 수단으로 사용하는 것이 좋다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;Terraform의 동작 방식&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;647&quot; data-origin-height=&quot;559&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8rBE7/btsCCzZQIl9/SdjCie6jkvJlolDblPcDu0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8rBE7/btsCCzZQIl9/SdjCie6jkvJlolDblPcDu0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8rBE7/btsCCzZQIl9/SdjCie6jkvJlolDblPcDu0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8rBE7%2FbtsCCzZQIl9%2FSdjCie6jkvJlolDblPcDu0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;647&quot; height=&quot;559&quot; data-origin-width=&quot;647&quot; data-origin-height=&quot;559&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Write&lt;/b&gt; : &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;다수의 클라우드 provider 및 서비스에 걸쳐 있을 수 있는 리소스에 대해서 정의&lt;/b&gt;&lt;/span&gt;하는 단계&lt;br /&gt;ex) 보안 그룹과 로드밸런서가 있는 VPC(Virtual Private Cloud) 네트워크 안에 있는 VM에 애플리케이션을 배포하도록 &lt;b&gt;configuration 생성&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Plan&lt;/b&gt; : 기존 인프라와 사용자가 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;작성한 configuration을 기반으로, 인프라스트럭처에 생성, 업데이트 ,삭제에 관한 실행 계획을 테라폼이 생성하고 리뷰&lt;/b&gt;&lt;/span&gt;하는 단계&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Apply&lt;/b&gt; : Plan에 대한 리뷰 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;승인 후, 리소스에 대한 종속성을 고려하여 Plan에서 제안된 작업을 올바른 순서대로 수행&lt;/b&gt;&lt;/span&gt;하는 단계&lt;br /&gt;ex) VPC의 property값과 VPC 내부의 VM 개수를 변경한다고 가정하면, 이 apply 단계에서 테라폼은 VM 스케일링 작업 이전에 VPC를 먼저 다시 만든다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음은 테라폼 설치에 대해 알아보자!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필자의 경우, AWS의 다양한 리소스를 프로비저닝하기 위해 테라폼을 사용할 것이며, 사용 환경에 별도의 VM을 만들지 않고, 윈도우에서 제공하는 &lt;b&gt;WSL을 이용하여 ubuntu 22.04 의 리눅스 OS 환경&lt;/b&gt;을 구성 후, 테라폼을 실행할 예정이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 아래 Linux 기반으로 수행되는 명령어들은 모두 ubuntu 22.04 임을 참고하자!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;Terraform 설치&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;a href=&quot;https://developer.hashicorp.com/terraform/install?product_intent=terraform&quot;&gt;https://developer.hashicorp.com/terraform/install?product_intent=terraform&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1703730888302&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Install | Terraform | HashiCorp Developer&quot; data-og-description=&quot;Explore Terraform product documentation, tutorials, and examples.&quot; data-og-host=&quot;developer.hashicorp.com&quot; data-og-source-url=&quot;https://developer.hashicorp.com/terraform/install?product_intent=terraform&quot; data-og-url=&quot;https://developer.hashicorp.com/terraform/install?product_intent=terraform&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/gdQGK/hyUTzzxFu6/LFpGnloW4RTZAxwYiO2jU0/img.jpg?width=3200&amp;amp;height=1800&amp;amp;face=0_0_3200_1800,https://scrap.kakaocdn.net/dn/bYuHQA/hyUTAebu9w/MjBcrp8UbsjCosMhKuUOvK/img.jpg?width=3200&amp;amp;height=1800&amp;amp;face=0_0_3200_1800&quot;&gt;&lt;a href=&quot;https://developer.hashicorp.com/terraform/install?product_intent=terraform&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.hashicorp.com/terraform/install?product_intent=terraform&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/gdQGK/hyUTzzxFu6/LFpGnloW4RTZAxwYiO2jU0/img.jpg?width=3200&amp;amp;height=1800&amp;amp;face=0_0_3200_1800,https://scrap.kakaocdn.net/dn/bYuHQA/hyUTAebu9w/MjBcrp8UbsjCosMhKuUOvK/img.jpg?width=3200&amp;amp;height=1800&amp;amp;face=0_0_3200_1800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Install | Terraform | HashiCorp Developer&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Explore Terraform product documentation, tutorials, and examples.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer.hashicorp.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Terraform 공식 홈페이지의 Download 페이지(위 링크)로 가면, Linux에서 테라폼을 설치하는 방법이 나온다. 다음과 같이 명령어를 수행해 주자.&lt;/p&gt;
&lt;pre id=&quot;code_1703731072912&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 미리 생성해둔 Terraform 디렉토리로 이동하여 명령어 수행
# Terraform 디렉토리는 어디에 놔도 상관 없음

# 테라폼 설치
wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo &quot;deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main&quot; | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update &amp;amp;&amp;amp; sudo apt install terraform

# 테라폼 설치 완료 확인(버전 확인)
terraform version&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;475&quot; data-origin-height=&quot;67&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ugcaE/btsCP6unOwo/bSRrU0STqtVv2uNFKo4myk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ugcaE/btsCP6unOwo/bSRrU0STqtVv2uNFKo4myk/img.png&quot; data-alt=&quot;설치된 Terraform 버전 확인&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ugcaE/btsCP6unOwo/bSRrU0STqtVv2uNFKo4myk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FugcaE%2FbtsCP6unOwo%2FbSRrU0STqtVv2uNFKo4myk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;475&quot; height=&quot;67&quot; data-origin-width=&quot;475&quot; data-origin-height=&quot;67&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;설치된 Terraform 버전 확인&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 버전 확인이 된다면, 테라폼 설치가 완료된 것이다!&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.hashicorp.com/terraform/intro&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://developer.hashicorp.com/terraform/intro&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1703725801257&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;What is Terraform | Terraform | HashiCorp Developer&quot; data-og-description=&quot;Terraform is an infrastructure as code tool that lets you build, change, and version cloud and on-prem resources safely and efficiently.&quot; data-og-host=&quot;developer.hashicorp.com&quot; data-og-source-url=&quot;https://developer.hashicorp.com/terraform/intro&quot; data-og-url=&quot;https://developer.hashicorp.com/terraform/intro&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/fMhux/hyUTGSYhlF/lsRwyvTPzeEnXsFB7FfAJk/img.jpg?width=3200&amp;amp;height=1800&amp;amp;face=0_0_3200_1800,https://scrap.kakaocdn.net/dn/ed0P0n/hyUTwpgIKZ/f7wGuHluqE9d4VpENdOXck/img.jpg?width=3200&amp;amp;height=1800&amp;amp;face=0_0_3200_1800&quot;&gt;&lt;a href=&quot;https://developer.hashicorp.com/terraform/intro&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.hashicorp.com/terraform/intro&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/fMhux/hyUTGSYhlF/lsRwyvTPzeEnXsFB7FfAJk/img.jpg?width=3200&amp;amp;height=1800&amp;amp;face=0_0_3200_1800,https://scrap.kakaocdn.net/dn/ed0P0n/hyUTwpgIKZ/f7wGuHluqE9d4VpENdOXck/img.jpg?width=3200&amp;amp;height=1800&amp;amp;face=0_0_3200_1800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;What is Terraform | Terraform | HashiCorp Developer&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Terraform is an infrastructure as code tool that lets you build, change, and version cloud and on-prem resources safely and efficiently.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer.hashicorp.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://spacelift.io/blog/terraform-architecture&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://spacelift.io/blog/terraform-architecture&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1703726062469&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Terraform Architecture Introduction - Structure and Workflow&quot; data-og-description=&quot;See the beginner friendly introduction to Terraform architecture and it's several key components.&quot; data-og-host=&quot;spacelift.io&quot; data-og-source-url=&quot;https://spacelift.io/blog/terraform-architecture&quot; data-og-url=&quot;https://spacelift.io/blog/[slug]&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ndaGU/hyUTwpgN9w/AUEFQ8Oq2jCeQFNNhUYJDK/img.png?width=834&amp;amp;height=508&amp;amp;face=0_0_834_508&quot;&gt;&lt;a href=&quot;https://spacelift.io/blog/terraform-architecture&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://spacelift.io/blog/terraform-architecture&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ndaGU/hyUTwpgN9w/AUEFQ8Oq2jCeQFNNhUYJDK/img.png?width=834&amp;amp;height=508&amp;amp;face=0_0_834_508');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Terraform Architecture Introduction - Structure and Workflow&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;See the beginner friendly introduction to Terraform architecture and it's several key components.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;spacelift.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DevOps/Terraform</category>
      <category>IaC 개념</category>
      <category>Terraform Architecture</category>
      <category>Terraform ubuntu 22.04</category>
      <category>Terraform 개념</category>
      <category>terraform 설치</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/159</guid>
      <comments>https://co-no.tistory.com/entry/Terraform-Terraform-%EA%B0%9C%EB%85%90-Architecture-%EC%84%A4%EC%B9%98#entry159comment</comments>
      <pubDate>Thu, 28 Dec 2023 11:41:51 +0900</pubDate>
    </item>
    <item>
      <title>[AWS] AWS 가입 후 초기 세팅 - IAM, Budgets 설정</title>
      <link>https://co-no.tistory.com/entry/AWS-AWS-%EA%B0%80%EC%9E%85-%ED%9B%84-%EC%B4%88%EA%B8%B0-%EC%84%B8%ED%8C%851-IAM</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;IAM(Identity and Access Management)이란 무엇인가?&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: AWS를 사용하는 데에 가장 기초적인 서비스 중 하나로, &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;AWS의 리소스들을 관리하고 권한을 설정하며, 각 리소스 간의 연계를 위해 필수적인 시스템&lt;/b&gt;&lt;/span&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 기초적으로 세팅해야 하는 서비스이고, &lt;b&gt;유저 로그인, 유저 간 권한 관리, 패스워드 설정, 리소스 간 연계 시 권한 등의 세밀한 설정이 가능&lt;/b&gt;하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS를 가입한 후에, 처음 다시 로그인하게 되면, 아래와 같은 창을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IAM이란 것을 설정하기 전에는 '&lt;b&gt;루트 사용자&lt;/b&gt;'에 체크하고, 처음 가입할 때 넣었던 이메일 주소로 로그인할 텐데, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;이 '루트 사용자'는 Linux의 root 라고 생각해보면 된다.&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;내가 만든 AWS 시스템의 모든 권한을 다 가지고 있다는 것이다.&lt;/b&gt;&lt;/span&gt; &lt;br /&gt;특히 돈과 관련된, billing과 관련된 모든 설정을 변경하는 것도 가능하므로, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;가능한 한 IAM을 만들어 해당 IAM 계정으로 로그인을 하고, 루트 사용자는 MFA를 적용하고, 반드시 필요할 때만 사용하도록 하는 것&lt;/b&gt;&lt;/span&gt;이 &lt;b&gt;보안상 필수적으로 필요한 과정&lt;/b&gt;이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;371&quot; data-origin-height=&quot;660&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUBOsR/btsCLreREIi/QbSGQzujLbrMxjgU6YoNgk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUBOsR/btsCLreREIi/QbSGQzujLbrMxjgU6YoNgk/img.png&quot; data-alt=&quot;AWS 로그인 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUBOsR/btsCLreREIi/QbSGQzujLbrMxjgU6YoNgk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUBOsR%2FbtsCLreREIi%2FQbSGQzujLbrMxjgU6YoNgk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;371&quot; height=&quot;660&quot; data-origin-width=&quot;371&quot; data-origin-height=&quot;660&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;AWS 로그인 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;1. [&lt;/b&gt;&lt;b&gt;IAM user and role access to Billing information] 활성화&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IAM 계정을 생성하기 전, 해당 옵션을 루트 사용자에서 활성화함으로써, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;IAM 유저가 billing과 관련된 설정에 접근할 수 있도록 해야 한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1.1. [Account] 메뉴 진입&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 그림처럼 AWS에 가입한 사용자로 로그인(루트 사용자)을 한 후, 계정 옆 &lt;b&gt;[화살표]&lt;/b&gt; - &lt;b&gt;[Account]&lt;/b&gt; 를 클릭한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1919&quot; data-origin-height=&quot;910&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/by1wzI/btsCBJ8ZJxH/78iwp8ZYBfxfKRw6XmyRdK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/by1wzI/btsCBJ8ZJxH/78iwp8ZYBfxfKRw6XmyRdK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/by1wzI/btsCBJ8ZJxH/78iwp8ZYBfxfKRw6XmyRdK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fby1wzI%2FbtsCBJ8ZJxH%2F78iwp8ZYBfxfKRw6XmyRdK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1919&quot; height=&quot;910&quot; data-origin-width=&quot;1919&quot; data-origin-height=&quot;910&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1.2. [IAM user and role access to Billing information] - [Edit] 버튼 클릭&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Account 메뉴에서 보면, &lt;b&gt;[IAM user and role access to Billing information]&lt;/b&gt; 이 보일텐데, 이 설정을 활성화 해줌으로써, 루트 사용자가 아닌 특정 IAM 사용자가 Billing 및 Cost와 관련된 관리 설정에 접근할 수 있도록 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;우리는 최종적으로 루트사용자 최대한 사용하지 않도록 할 것이므로&lt;/b&gt;&lt;/span&gt;, 특정 IAM 사용자는 Billing 및 Cost와 관련된 관리 설정에 접근할 수 있도록 해야 한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1915&quot; data-origin-height=&quot;908&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cG4t2r/btsCCxHrxxR/zXrfUUWHmEdMjXytVOkLMK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cG4t2r/btsCCxHrxxR/zXrfUUWHmEdMjXytVOkLMK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cG4t2r/btsCCxHrxxR/zXrfUUWHmEdMjXytVOkLMK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcG4t2r%2FbtsCCxHrxxR%2FzXrfUUWHmEdMjXytVOkLMK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1915&quot; height=&quot;908&quot; data-origin-width=&quot;1915&quot; data-origin-height=&quot;908&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1.3. 'Activate IAM Access' 체크 - [Update] 버튼 클릭&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1921&quot; data-origin-height=&quot;910&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bm4iCM/btsCBKmt6HQ/2SoUrqVwBrJ1k690SJ3Qa0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bm4iCM/btsCBKmt6HQ/2SoUrqVwBrJ1k690SJ3Qa0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bm4iCM/btsCBKmt6HQ/2SoUrqVwBrJ1k690SJ3Qa0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbm4iCM%2FbtsCBKmt6HQ%2F2SoUrqVwBrJ1k690SJ3Qa0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1921&quot; height=&quot;910&quot; data-origin-width=&quot;1921&quot; data-origin-height=&quot;910&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;2.&amp;nbsp; MFA 등록&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;여기에서 등록하는 MFA는, &lt;b&gt;[IAM Identity Center]&lt;/b&gt;에 대한 MFA가 아닌, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;[IAM]에 대한 MFA&lt;/b&gt;&lt;/span&gt;임을 주의하자.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;여기에서 MFA를 등록하면, 루트 사용자에 대한 MFA도 등록되어, 루트 사용자로 함부로 로그인되는 것을 막을 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2.1. [서비스 검색] 란에서 'IAM' 이라고 검색 - [IAM] 서비스로 접근&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1919&quot; data-origin-height=&quot;908&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bIOmEz/btsCAjW1D18/f77b1Kypnm22vT8EDHEK6k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bIOmEz/btsCAjW1D18/f77b1Kypnm22vT8EDHEK6k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bIOmEz/btsCAjW1D18/f77b1Kypnm22vT8EDHEK6k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbIOmEz%2FbtsCAjW1D18%2Ff77b1Kypnm22vT8EDHEK6k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1919&quot; height=&quot;908&quot; data-origin-width=&quot;1919&quot; data-origin-height=&quot;908&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2.2. MFA 추가&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1918&quot; data-origin-height=&quot;913&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CFn8P/btsCIFrelHd/v8KbWv5oSNXQzW9B6ee8hk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CFn8P/btsCIFrelHd/v8KbWv5oSNXQzW9B6ee8hk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CFn8P/btsCIFrelHd/v8KbWv5oSNXQzW9B6ee8hk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCFn8P%2FbtsCIFrelHd%2Fv8KbWv5oSNXQzW9B6ee8hk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1918&quot; height=&quot;913&quot; data-origin-width=&quot;1918&quot; data-origin-height=&quot;913&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2.3. MFA 추가 시 필요한 정보 입력&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Device name에는 필자가 알아보기 쉽게 Galaxy S23 등으로 지정하였고, 인증 수단을 3가지 중에 선택할 수 있는 데, 필자의 경우,&lt;b&gt; [Authenticator app]&lt;/b&gt;을 선택하여 &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;Google&lt;/b&gt;&lt;b&gt;의 Authenticator App으로 등록&lt;/b&gt;&lt;/span&gt;하였다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1916&quot; data-origin-height=&quot;863&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bM8DEU/btsCN4KiPaW/9dgYAVt41Slk97Ln5zlYcK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bM8DEU/btsCN4KiPaW/9dgYAVt41Slk97Ln5zlYcK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bM8DEU/btsCN4KiPaW/9dgYAVt41Slk97Ln5zlYcK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbM8DEU%2FbtsCN4KiPaW%2F9dgYAVt41Slk97Ln5zlYcK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1916&quot; height=&quot;863&quot; data-origin-width=&quot;1916&quot; data-origin-height=&quot;863&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;3. IAM 생성&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3.1. [서비스 검색] 란에서 'IAM' 이라고 검색 - [IAM] 서비스로 접근&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1919&quot; data-origin-height=&quot;908&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bIOmEz/btsCAjW1D18/f77b1Kypnm22vT8EDHEK6k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bIOmEz/btsCAjW1D18/f77b1Kypnm22vT8EDHEK6k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bIOmEz/btsCAjW1D18/f77b1Kypnm22vT8EDHEK6k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbIOmEz%2FbtsCAjW1D18%2Ff77b1Kypnm22vT8EDHEK6k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1919&quot; height=&quot;908&quot; data-origin-width=&quot;1919&quot; data-origin-height=&quot;908&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3.2. [IAM] 서비스 -&amp;nbsp; [Users] 메뉴 선택 - [Create user] 클릭&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;912&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WrhHl/btsCKrzsTpG/9OEeCxqRKrZXBITaNWDeC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WrhHl/btsCKrzsTpG/9OEeCxqRKrZXBITaNWDeC1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WrhHl/btsCKrzsTpG/9OEeCxqRKrZXBITaNWDeC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWrhHl%2FbtsCKrzsTpG%2F9OEeCxqRKrZXBITaNWDeC1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;912&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;912&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3.3. [User name]에 원하는 로그인 name 입력 &lt;br /&gt;- 'Provide user access to the AWS Management Console' 체크(루트사용자와 동등한 권한 갖게 하기 위함) &lt;br /&gt;- 'Specify a user in Identity Center' 클릭&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1919&quot; data-origin-height=&quot;908&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baPLxY/btsCMp2c5NA/t41rtiqKkTwC0BRJbmacik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baPLxY/btsCMp2c5NA/t41rtiqKkTwC0BRJbmacik/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baPLxY/btsCMp2c5NA/t41rtiqKkTwC0BRJbmacik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaPLxY%2FbtsCMp2c5NA%2Ft41rtiqKkTwC0BRJbmacik%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1919&quot; height=&quot;908&quot; data-origin-width=&quot;1919&quot; data-origin-height=&quot;908&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 아래와 같은 창이 뜰텐데, 'Manage in Identity Center' 를 클릭해준다. &lt;s&gt;(아놔, 결국 AWS Identity Center 콘솔에서 다시 계정 추가를 해줘야 하나보다.)&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[IAM Identity Center]에서 생성한 IAM 계정&lt;/b&gt;은, 여기에서 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;공유되는 특정 Access URL을 통해서만 해당 AWS 서비스로 접근이 가능&lt;/b&gt;&lt;/span&gt;하다. 이 점을 유의하고 &lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;[IAM Identity Center]와 [IAM]을 구분하자!&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;913&quot; data-origin-height=&quot;268&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b3mR8r/btsCzTdcfL3/GizzxbcKlv8eg518PYc8M1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b3mR8r/btsCzTdcfL3/GizzxbcKlv8eg518PYc8M1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b3mR8r/btsCzTdcfL3/GizzxbcKlv8eg518PYc8M1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb3mR8r%2FbtsCzTdcfL3%2FGizzxbcKlv8eg518PYc8M1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;913&quot; height=&quot;268&quot; data-origin-width=&quot;913&quot; data-origin-height=&quot;268&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3.4. 'Enable IAM Identity Center'의 [Enable] 버튼 클릭&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1911&quot; data-origin-height=&quot;819&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/A2MuP/btsCG4x3Cfn/u7yeFAd88UyH3reYqNGoG0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/A2MuP/btsCG4x3Cfn/u7yeFAd88UyH3reYqNGoG0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/A2MuP/btsCG4x3Cfn/u7yeFAd88UyH3reYqNGoG0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FA2MuP%2FbtsCG4x3Cfn%2Fu7yeFAd88UyH3reYqNGoG0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1911&quot; height=&quot;819&quot; data-origin-width=&quot;1911&quot; data-origin-height=&quot;819&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3.5. [Enable with AWS Organizations] 선택 - [Continue] 버튼 클릭&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;825&quot; data-origin-height=&quot;675&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KsdDm/btsCK9L7rl6/QZ2oRkUZJTgvjzhGBwrbF0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KsdDm/btsCK9L7rl6/QZ2oRkUZJTgvjzhGBwrbF0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KsdDm/btsCK9L7rl6/QZ2oRkUZJTgvjzhGBwrbF0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKsdDm%2FbtsCK9L7rl6%2FQZ2oRkUZJTgvjzhGBwrbF0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;825&quot; height=&quot;675&quot; data-origin-width=&quot;825&quot; data-origin-height=&quot;675&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3.6. IAM Identity Center 활성화 후 - [IAM Identity Center] 웹 콘솔 진입 &lt;br /&gt;- [Users] 메뉴 클릭 - [Add user] 버튼 클릭&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1919&quot; data-origin-height=&quot;909&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bCSf4R/btsCMq08gRH/nL3jhqsSzyUGuJjidiKab1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bCSf4R/btsCMq08gRH/nL3jhqsSzyUGuJjidiKab1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bCSf4R/btsCMq08gRH/nL3jhqsSzyUGuJjidiKab1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbCSf4R%2FbtsCMq08gRH%2FnL3jhqsSzyUGuJjidiKab1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1919&quot; height=&quot;909&quot; data-origin-width=&quot;1919&quot; data-origin-height=&quot;909&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3.7. 유저 생성 양식 작성&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필자는 [Primary information]을 모두 작성한 후에, 추가로 [Preferences]의 'Nickname'과 'Timezone'만 설정해 주었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1918&quot; data-origin-height=&quot;908&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcE0QN/btsCBLTkaZA/44ul17UKXwLLK2nZ9lKPKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcE0QN/btsCBLTkaZA/44ul17UKXwLLK2nZ9lKPKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcE0QN/btsCBLTkaZA/44ul17UKXwLLK2nZ9lKPKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcE0QN%2FbtsCBLTkaZA%2F44ul17UKXwLLK2nZ9lKPKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1918&quot; height=&quot;908&quot; data-origin-width=&quot;1918&quot; data-origin-height=&quot;908&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 하고 넥스트~ 넥스트~ 눌러주면, [IAM Identity Center] 웹 콘솔의 홈 화면으로 이동하면서, 아래와 같은 메시지가 상단에 노출될 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;[Primary information]에 입력한 이메일을 확인하여, 인증 과정을 마쳐야만 IAM 유저가 정상적으로 추가된다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메일에서 Accept를 클릭해주면, 해당 IAM 계정으로 로그인되고, 새로운 비밀번호를 설정하는 창으로 &lt;b&gt;리다이렉션&lt;/b&gt;된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;거기에서 새로운 비밀번호로 설정해주자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;그리고 아직 루트사용자 로그인은 로그아웃하지 말자!!&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1601&quot; data-origin-height=&quot;96&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xtmgH/btsCzRGq4cg/Z2LMkEA1bQH54I5sO3QlK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xtmgH/btsCzRGq4cg/Z2LMkEA1bQH54I5sO3QlK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xtmgH/btsCzRGq4cg/Z2LMkEA1bQH54I5sO3QlK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxtmgH%2FbtsCzRGq4cg%2FZ2LMkEA1bQH54I5sO3QlK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1601&quot; height=&quot;96&quot; data-origin-width=&quot;1601&quot; data-origin-height=&quot;96&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt; 3.8. [IAM Identity Center] 웹 콘솔 - [Groups] 메뉴 - [Create group] 버튼 클릭&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1193&quot; data-origin-height=&quot;1232&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cNUbAQ/btsCK9rWZYW/lZt5EMZr2KbuMajAkXxtu0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cNUbAQ/btsCK9rWZYW/lZt5EMZr2KbuMajAkXxtu0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cNUbAQ/btsCK9rWZYW/lZt5EMZr2KbuMajAkXxtu0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcNUbAQ%2FbtsCK9rWZYW%2FlZt5EMZr2KbuMajAkXxtu0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;648&quot; height=&quot;669&quot; data-origin-width=&quot;1193&quot; data-origin-height=&quot;1232&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3.9. [Create Group] 화면에서 Group name 설정 - [Add users to group] 에서 생성한 계정 추가&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필자는 그룹명을 'Administrators'라고 지었는데, 이건 원하는대로 아무렇게나 지어도 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1189&quot; data-origin-height=&quot;1039&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/belsiv/btsCODeK3Ht/WamxcHB0tTcBoV33OkEhTk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/belsiv/btsCODeK3Ht/WamxcHB0tTcBoV33OkEhTk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/belsiv/btsCODeK3Ht/WamxcHB0tTcBoV33OkEhTk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbelsiv%2FbtsCODeK3Ht%2FWamxcHB0tTcBoV33OkEhTk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;694&quot; height=&quot;606&quot; data-origin-width=&quot;1189&quot; data-origin-height=&quot;1039&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3.10. [IAM Identity Center] 웹 콘솔 &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;- [Multi-account permissions]의 [AWS accounts] 메뉴 &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;- 3.7.에서 생성한 계정 선택 - [Assign users or groups] 버튼 클릭&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리가 추가한 계정 및 그룹이 루트 사용자의 권한처럼 로그인하려면, 루트 사용자 하위에 '&lt;b&gt;management account&lt;/b&gt;'에 대한 &lt;b&gt;Multi-account permission&lt;/b&gt;이 필요하다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1186&quot; data-origin-height=&quot;924&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXzEzP/btsCCwaTwct/5fRRImBZqIpG5zqodJVm0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXzEzP/btsCCwaTwct/5fRRImBZqIpG5zqodJVm0k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXzEzP/btsCCwaTwct/5fRRImBZqIpG5zqodJVm0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXzEzP%2FbtsCCwaTwct%2F5fRRImBZqIpG5zqodJVm0k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;708&quot; height=&quot;552&quot; data-origin-width=&quot;1186&quot; data-origin-height=&quot;924&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3.11. Multi-account permission을 추가할 [IAM Identity Center]의 계정 및 그룹 선택&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1187&quot; data-origin-height=&quot;905&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Spy98/btsCN35RalG/kNZjuVBD4YQiWUK9NkCBH0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Spy98/btsCN35RalG/kNZjuVBD4YQiWUK9NkCBH0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Spy98/btsCN35RalG/kNZjuVBD4YQiWUK9NkCBH0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSpy98%2FbtsCN35RalG%2FkNZjuVBD4YQiWUK9NkCBH0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;650&quot; height=&quot;496&quot; data-origin-width=&quot;1187&quot; data-origin-height=&quot;905&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1192&quot; data-origin-height=&quot;1111&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bufQtH/btsCG3lJiDg/oTMWQD3aY8gFJ8IGjIdkDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bufQtH/btsCG3lJiDg/oTMWQD3aY8gFJ8IGjIdkDK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bufQtH/btsCG3lJiDg/oTMWQD3aY8gFJ8IGjIdkDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbufQtH%2FbtsCG3lJiDg%2FoTMWQD3aY8gFJ8IGjIdkDK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;628&quot; height=&quot;585&quot; data-origin-width=&quot;1192&quot; data-origin-height=&quot;1111&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3.12. [Select permissions sets] 화면 - [Create permissions set] 클릭&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1188&quot; data-origin-height=&quot;963&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cG0piy/btsCAOiAJoK/MnEhJ1crBrdN6utDXKRK51/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cG0piy/btsCAOiAJoK/MnEhJ1crBrdN6utDXKRK51/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cG0piy/btsCAOiAJoK/MnEhJ1crBrdN6utDXKRK51/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcG0piy%2FbtsCAOiAJoK%2FMnEhJ1crBrdN6utDXKRK51%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;623&quot; height=&quot;505&quot; data-origin-width=&quot;1188&quot; data-origin-height=&quot;963&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 [Create permissions set] 버튼을 클릭하면 창이 하나 뜨는데, 다음 이미지와 같이 진행하자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2539&quot; data-origin-height=&quot;1625&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HT1xp/btsCLpVWrGD/BH5yzlkTCXFcNIO0rLY6eK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HT1xp/btsCLpVWrGD/BH5yzlkTCXFcNIO0rLY6eK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HT1xp/btsCLpVWrGD/BH5yzlkTCXFcNIO0rLY6eK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHT1xp%2FbtsCLpVWrGD%2FBH5yzlkTCXFcNIO0rLY6eK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2539&quot; height=&quot;1625&quot; data-origin-width=&quot;2539&quot; data-origin-height=&quot;1625&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;[Types] 에서 'Predefined permissions set' 을 선택하고, &lt;b&gt;[Policy for predefined persmission set]&lt;/b&gt; 에서 '&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;AdministratorAccess&lt;/b&gt;&lt;/span&gt;'를 선택하면 루트사용자와 동일한 권한을 가지게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이 다음 Step 2인 [Specify permission set details] 에서도 디폴트로 설정되어 있는 것을 그대로 두고, &lt;b&gt;[Next]&lt;/b&gt; 버튼을 클릭하자.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;역시 그다음 Step 3인 [Review and create] 에서 &lt;b&gt;[Create]&lt;/b&gt; 버튼을 클릭하면 [permissions set]이 생성 완료된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;[Assign users and groups] 창으로 돌아와, 새로고침 버튼을 눌러주면 다음과 같이 'Permission set'이 생긴 걸 확인할 수 있고, 이를 체크하고 [Next]버튼 클릭 - 다음 Step 3 [Review and submit]에서 &lt;b&gt;[Submit]&lt;/b&gt; 버튼 클릭하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1265&quot; data-origin-height=&quot;965&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wPb7Y/btsCF7ItTFi/zrGpKzNjfDw76eJtB7UD4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wPb7Y/btsCF7ItTFi/zrGpKzNjfDw76eJtB7UD4k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wPb7Y/btsCF7ItTFi/zrGpKzNjfDw76eJtB7UD4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwPb7Y%2FbtsCF7ItTFi%2FzrGpKzNjfDw76eJtB7UD4k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;673&quot; height=&quot;513&quot; data-origin-width=&quot;1265&quot; data-origin-height=&quot;965&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;그럼 다음과 같이 성공 문구와 함께 AdministratorAccess 권한이 들어간 것을 볼 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1269&quot; data-origin-height=&quot;906&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PbO07/btsCCzMgXyF/oZrMmekz2rGT04suJ1Nn6K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PbO07/btsCCzMgXyF/oZrMmekz2rGT04suJ1Nn6K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PbO07/btsCCzMgXyF/oZrMmekz2rGT04suJ1Nn6K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPbO07%2FbtsCCzMgXyF%2FoZrMmekz2rGT04suJ1Nn6K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;719&quot; height=&quot;513&quot; data-origin-width=&quot;1269&quot; data-origin-height=&quot;906&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3.13. 인증 메일 통해서 리다이렉션 되는 로그인 화면에서 로그인&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인증 메일의 링크를 클릭하면, AWS 로그인 창으로 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;리다이렉션&lt;/b&gt;&lt;/span&gt; 되는데, 여기에서 IAM &lt;b&gt;Username과 Password를 입력&lt;/b&gt;하여 로그인 성공 되는 것을 확인하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 이때, MFA를 또 등록하게 되는데, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;이 MFA는 IAM 전체(?)에 대한 MFA와 별개&lt;/b&gt;&lt;/span&gt;이므로, 별도로 또 등록을 해주는 것이 맞다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또 한가지 주의할 점은,&lt;b&gt; [IAM Identity Center]를 통해 생성한 계정&lt;/b&gt;은, 아래 그림에서 보이는 '&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;AWS 액세스 포털 URL&lt;/b&gt;&lt;/span&gt;'을 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;통해서만 로그인이 가능하다는 것&lt;/b&gt;&lt;/span&gt;이다. 따라서 저 액세스 포털 URL을 Admin만이 아는 어떤 곳에 &lt;b&gt;잘 복사해두고 사용&lt;/b&gt;하도록 하자!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2559&quot; data-origin-height=&quot;1235&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SU8Xp/btsCMxszmQX/Y3kk6c0sEIBhthpk4mKaa1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SU8Xp/btsCMxszmQX/Y3kk6c0sEIBhthpk4mKaa1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SU8Xp/btsCMxszmQX/Y3kk6c0sEIBhthpk4mKaa1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSU8Xp%2FbtsCMxszmQX%2FY3kk6c0sEIBhthpk4mKaa1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2559&quot; height=&quot;1235&quot; data-origin-width=&quot;2559&quot; data-origin-height=&quot;1235&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;Budgets이란 무엇인가?&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: AWS에서 제공하는 유동적인 예산 및 예측 기능으로, 비용적인 측면에서의 계획 및 비용 제어 과정을 개선할 수 있는 서비스이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사용자 지정 예산을 통해 비용, 사용량, 적용 범위를 추적할 수 있다.&lt;/li&gt;
&lt;li&gt;지출 및 리소스 사용에 대한 예측 정보를 계속 제공받을 수 있다.&lt;/li&gt;
&lt;li&gt;사용자 지정 작업을 생성하여 초과 요금, 비효율적인 리소스 사용 또는 적용 범위 부족을 방지할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS에 대한 학습은 최대한 프리 티어를 이용할 것이기 때문에,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;0.01$ 이상의 비용이 발생하면 메일로 알림을 오도록 설정할 것이다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;4. Budgets 설정&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;4.1. [Account] - [Billing and Cost Management] 화면에서 [Budgets] 메뉴 클릭 - [Create a budget] 버튼 클릭&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;951&quot; data-origin-height=&quot;851&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ChvTA/btsCQoPhmuu/k9KWL0JjkydsOvpDXTC9o0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ChvTA/btsCQoPhmuu/k9KWL0JjkydsOvpDXTC9o0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ChvTA/btsCQoPhmuu/k9KWL0JjkydsOvpDXTC9o0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FChvTA%2FbtsCQoPhmuu%2Fk9KWL0JjkydsOvpDXTC9o0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;767&quot; height=&quot;686&quot; data-origin-width=&quot;951&quot; data-origin-height=&quot;851&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;4.2. Budgets 양식 작성&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;친절하게도, Budgets 생성을 하면 '&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;Zero spend budget&lt;/b&gt;&lt;/span&gt;' 이라는 템플릿이 이미 있어, 해당 템플릿으로 적용하면 AWS 프리 티어 초과 사용량에 대한 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;0.01$ 이상의 비용이라도 발생하면 알림을 발생&lt;/b&gt;&lt;/span&gt;할 수 있게 해준다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1652&quot; data-origin-height=&quot;1427&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHgXjZ/btsCG2NY9hj/7o2WTl4GtDTWAODynSvoFk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHgXjZ/btsCG2NY9hj/7o2WTl4GtDTWAODynSvoFk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHgXjZ/btsCG2NY9hj/7o2WTl4GtDTWAODynSvoFk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHgXjZ%2FbtsCG2NY9hj%2F7o2WTl4GtDTWAODynSvoFk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;751&quot; height=&quot;649&quot; data-origin-width=&quot;1652&quot; data-origin-height=&quot;1427&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;4.3.생성된 Budgets 확인&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 다음과 같이 생성된 것을 확인할 수 있다!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1917&quot; data-origin-height=&quot;881&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bQmmwP/btsCEJHUOgb/6Z4W0MAwgbGNo9PJOHvYY1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bQmmwP/btsCEJHUOgb/6Z4W0MAwgbGNo9PJOHvYY1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bQmmwP/btsCEJHUOgb/6Z4W0MAwgbGNo9PJOHvYY1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbQmmwP%2FbtsCEJHUOgb%2F6Z4W0MAwgbGNo9PJOHvYY1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1917&quot; height=&quot;881&quot; data-origin-width=&quot;1917&quot; data-origin-height=&quot;881&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jodev.kr/entry/AWS-AWS-%EA%B0%80%EC%9E%85-%ED%9B%84-%EC%A0%9C%EC%9D%BC-%EB%A8%BC%EC%A0%80-%ED%95%B4%EC%95%BC%ED%95%A0-%EC%9D%BC&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://jodev.kr/entry/AWS-AWS-%EA%B0%80%EC%9E%85-%ED%9B%84-%EC%A0%9C%EC%9D%BC-%EB%A8%BC%EC%A0%80-%ED%95%B4%EC%95%BC%ED%95%A0-%EC%9D%BC&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1703658636051&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[AWS] AWS 가입 후, 제일 먼저 해야할 일&quot; data-og-description=&quot;본 글은 AWS에서 제공하는 AWS Documentation (user guides, developer guides, API references, tutorials, etc)를 참고하여 작성하였습니다. https://docs.aws.amazon.com/ IAM (Identity and Access Management) AWS에서는 IAM (Identity and Acce&quot; data-og-host=&quot;jodev.kr&quot; data-og-source-url=&quot;https://jodev.kr/entry/AWS-AWS-%EA%B0%80%EC%9E%85-%ED%9B%84-%EC%A0%9C%EC%9D%BC-%EB%A8%BC%EC%A0%80-%ED%95%B4%EC%95%BC%ED%95%A0-%EC%9D%BC&quot; data-og-url=&quot;https://jodev.kr/entry/AWS-AWS-%EA%B0%80%EC%9E%85-%ED%9B%84-%EC%A0%9C%EC%9D%BC-%EB%A8%BC%EC%A0%80-%ED%95%B4%EC%95%BC%ED%95%A0-%EC%9D%BC&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dNoY8x/hyUTJomIJM/ACpOwku4PrcKtEt8jToIZ1/img.png?width=800&amp;amp;height=533&amp;amp;face=0_0_800_533,https://scrap.kakaocdn.net/dn/deORfB/hyUTxnUXXf/D9yZ7olTvvsKGIpJCGZfH0/img.png?width=800&amp;amp;height=533&amp;amp;face=0_0_800_533,https://scrap.kakaocdn.net/dn/cxQTTZ/hyUTAZetYT/hK5nzD7PANIzccnn6yOSc1/img.png?width=3000&amp;amp;height=2000&amp;amp;face=0_0_3000_2000&quot;&gt;&lt;a href=&quot;https://jodev.kr/entry/AWS-AWS-%EA%B0%80%EC%9E%85-%ED%9B%84-%EC%A0%9C%EC%9D%BC-%EB%A8%BC%EC%A0%80-%ED%95%B4%EC%95%BC%ED%95%A0-%EC%9D%BC&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jodev.kr/entry/AWS-AWS-%EA%B0%80%EC%9E%85-%ED%9B%84-%EC%A0%9C%EC%9D%BC-%EB%A8%BC%EC%A0%80-%ED%95%B4%EC%95%BC%ED%95%A0-%EC%9D%BC&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dNoY8x/hyUTJomIJM/ACpOwku4PrcKtEt8jToIZ1/img.png?width=800&amp;amp;height=533&amp;amp;face=0_0_800_533,https://scrap.kakaocdn.net/dn/deORfB/hyUTxnUXXf/D9yZ7olTvvsKGIpJCGZfH0/img.png?width=800&amp;amp;height=533&amp;amp;face=0_0_800_533,https://scrap.kakaocdn.net/dn/cxQTTZ/hyUTAZetYT/hK5nzD7PANIzccnn6yOSc1/img.png?width=3000&amp;amp;height=2000&amp;amp;face=0_0_3000_2000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[AWS] AWS 가입 후, 제일 먼저 해야할 일&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;본 글은 AWS에서 제공하는 AWS Documentation (user guides, developer guides, API references, tutorials, etc)를 참고하여 작성하였습니다. https://docs.aws.amazon.com/ IAM (Identity and Access Management) AWS에서는 IAM (Identity and Acce&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;jodev.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://growth-coder.tistory.com/115&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://growth-coder.tistory.com/115&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1703688393676&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[AWS] Identity Center를 활용한 관리자 IAM 사용자 생성 (관리자 IAM 사용자를 사용하는 이유)&quot; data-og-description=&quot;이전 포스팅에서 AWS에서 S3 스토리지를 생성하고 업로드 및 정책 설정을 해보았다. 루트 사용자 계정으로 콘솔에서 S3 스토리지를 생성하고 사용해보았는데 실제로는 이렇게 사용하는 경우가 많&quot; data-og-host=&quot;growth-coder.tistory.com&quot; data-og-source-url=&quot;https://growth-coder.tistory.com/115&quot; data-og-url=&quot;https://growth-coder.tistory.com/115&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/mKfNd/hyUTvX7AAi/EPKQPY4GVabAlkOKAMShhk/img.png?width=800&amp;amp;height=312&amp;amp;face=0_0_800_312,https://scrap.kakaocdn.net/dn/bJqM5P/hyUTLUba5w/dyQkITV8nH4FHw8gKeahe1/img.png?width=800&amp;amp;height=312&amp;amp;face=0_0_800_312,https://scrap.kakaocdn.net/dn/cgwKjs/hyUTFzEPZS/l7YIPdCVKFKCvqyesK1K71/img.png?width=1423&amp;amp;height=555&amp;amp;face=0_0_1423_555&quot;&gt;&lt;a href=&quot;https://growth-coder.tistory.com/115&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://growth-coder.tistory.com/115&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/mKfNd/hyUTvX7AAi/EPKQPY4GVabAlkOKAMShhk/img.png?width=800&amp;amp;height=312&amp;amp;face=0_0_800_312,https://scrap.kakaocdn.net/dn/bJqM5P/hyUTLUba5w/dyQkITV8nH4FHw8gKeahe1/img.png?width=800&amp;amp;height=312&amp;amp;face=0_0_800_312,https://scrap.kakaocdn.net/dn/cgwKjs/hyUTFzEPZS/l7YIPdCVKFKCvqyesK1K71/img.png?width=1423&amp;amp;height=555&amp;amp;face=0_0_1423_555');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[AWS] Identity Center를 활용한 관리자 IAM 사용자 생성 (관리자 IAM 사용자를 사용하는 이유)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;이전 포스팅에서 AWS에서 S3 스토리지를 생성하고 업로드 및 정책 설정을 해보았다. 루트 사용자 계정으로 콘솔에서 S3 스토리지를 생성하고 사용해보았는데 실제로는 이렇게 사용하는 경우가 많&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;growth-coder.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://aws.amazon.com/ko/aws-cost-management/aws-budgets/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://aws.amazon.com/ko/aws-cost-management/aws-budgets/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1703722679823&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;company&quot; data-og-title=&quot;사용자 지정 비용 및 사용 예산 설정 - AWS Budgets - Amazon Web Services&quot; data-og-description=&quot;AWS Budgets를 사용하면 사용자 지정 예산을 설정하여 비용 및 사용량을 추적하고, 임계값 초과 시 이메일 또는 SNS 알림에서 수신된 알림에 빠르게 대응할 수 있습니다.&quot; data-og-host=&quot;aws.amazon.com&quot; data-og-source-url=&quot;https://aws.amazon.com/ko/aws-cost-management/aws-budgets/&quot; data-og-url=&quot;https://aws.amazon.com/ko/aws-cost-management/aws-budgets/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bA6JoV/hyUTB5bgJU/FixyuKhHw4vQ5vEECbyF40/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/gg1Bm/hyUTFfrDkw/EJGFr07aXledKdAPOvuoc0/img.png?width=179&amp;amp;height=109&amp;amp;face=0_0_179_109,https://scrap.kakaocdn.net/dn/8YZ9a/hyUTLNu4jW/cHx8VLbXHuEF37WahNftZK/img.png?width=2376&amp;amp;height=768&amp;amp;face=0_0_2376_768&quot;&gt;&lt;a href=&quot;https://aws.amazon.com/ko/aws-cost-management/aws-budgets/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://aws.amazon.com/ko/aws-cost-management/aws-budgets/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bA6JoV/hyUTB5bgJU/FixyuKhHw4vQ5vEECbyF40/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/gg1Bm/hyUTFfrDkw/EJGFr07aXledKdAPOvuoc0/img.png?width=179&amp;amp;height=109&amp;amp;face=0_0_179_109,https://scrap.kakaocdn.net/dn/8YZ9a/hyUTLNu4jW/cHx8VLbXHuEF37WahNftZK/img.png?width=2376&amp;amp;height=768&amp;amp;face=0_0_2376_768');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;사용자 지정 비용 및 사용 예산 설정 - AWS Budgets - Amazon Web Services&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;AWS Budgets를 사용하면 사용자 지정 예산을 설정하여 비용 및 사용량을 추적하고, 임계값 초과 시 이메일 또는 SNS 알림에서 수신된 알림에 빠르게 대응할 수 있습니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;aws.amazon.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Cloud/AWS</category>
      <category>AWS IAM</category>
      <category>AWS 가입 후 보안</category>
      <category>AWS 루트사용자 MFA</category>
      <category>aws 초기 세팅</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/157</guid>
      <comments>https://co-no.tistory.com/entry/AWS-AWS-%EA%B0%80%EC%9E%85-%ED%9B%84-%EC%B4%88%EA%B8%B0-%EC%84%B8%ED%8C%851-IAM#entry157comment</comments>
      <pubDate>Thu, 28 Dec 2023 08:30:03 +0900</pubDate>
    </item>
    <item>
      <title>[개념] DDD와 SQL 중심 설계 (feat. ORM과 SQL Mapper)</title>
      <link>https://co-no.tistory.com/entry/%EA%B0%9C%EB%85%90-DDD-%EC%84%A4%EA%B3%84%EC%99%80-SQL-%EC%A4%91%EC%8B%AC-%EC%84%A4%EA%B3%84-feat-ORM%EA%B3%BC-SQL-Mapper</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 모델링의 원칙 등을 공부해서 정리하려다가, 실무적으로 접근할 필요가 있을 것 같아, 최근 웹 개발의 90% 이상을 차지하고 있는(&lt;s&gt;국내 대기업도 이정도일까...?&lt;/s&gt;) DDD 설계와 정통적인 방법인 SQL 중심 설계의 차이점을 먼저 정리해보고자 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;이번 포스팅은 더더욱이 DDD, ORM, DB 설계 등의 매우 깊은 내용을 담고 있기에, 내가 쓰는 내용이 틀릴 확률이 상당히 높다.&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;그러니 읽으시는 독자 분들께서 틀린 내용이 있다면, 꼭 지적해주셨으면 한다.&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;DDD(Domain Driven Design)란 무엇인가?&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: Domain의 사전적 의미는 &lt;b&gt;'영역, 집합'&lt;/b&gt;으로, &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;비즈니스 Domain에 기반한 애플리케이션의 디자인 패턴&lt;/b&gt;&lt;/span&gt;을 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 &lt;b&gt;비즈니스 Domain&lt;/b&gt;이란, &lt;b&gt;유사한 업무의 집합&lt;/b&gt;을 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도메인은 다시 하위의 여러 도메인으로 나누어지곤 하는데, 예를 들면 아래 이미지와 같다. '온라인 쇼핑' 도메인은 '상품',' 주문', '회원'과 같은 하위 도메인으로 나뉘고, 이 중 '주문' 도메인은 다시 '주문자', '주문 상품', '배송'과 같은 하위 도메인으로 나눠질 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;675&quot; data-origin-height=&quot;453&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b7OseE/btsCAOI1IxQ/5UNgT6qwmcbXiIpAWPJcxk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b7OseE/btsCAOI1IxQ/5UNgT6qwmcbXiIpAWPJcxk/img.png&quot; data-alt=&quot;'온라인 쇼핑' 도메인과 그의 하위 도메인 / 출처 :&amp;amp;amp;nbsp;https://medium.com/myrealtrip-product/what-is-domain-driven-design-f6fd54051590&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b7OseE/btsCAOI1IxQ/5UNgT6qwmcbXiIpAWPJcxk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb7OseE%2FbtsCAOI1IxQ%2F5UNgT6qwmcbXiIpAWPJcxk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;675&quot; height=&quot;453&quot; data-origin-width=&quot;675&quot; data-origin-height=&quot;453&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;'온라인 쇼핑' 도메인과 그의 하위 도메인 / 출처 :&amp;amp;nbsp;https://medium.com/myrealtrip-product/what-is-domain-driven-design-f6fd54051590&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 &lt;b&gt;'집합'&lt;/b&gt;이라는 의미에 좀 더 초점을 두고 싶다. 필자가 생각하기에, 기존의 데이터 기반 설계(SQL 기반 설계)와 비교하면, 데이터가 RDBMS의 특징을 잘 살려 어떻게 저장될 지는 설계 과정에서 크게 고려하지 않고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ef6f53;&quot;&gt;&lt;b&gt;데이터가 처리되는 단위들 즉, 비즈니스를 애플리케이션 로직으로 어떤 단위로 어떻게 처리할 지를 기준으로 설계하는 방식으로 보인다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DDD는, &lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;기존의 애플리케이션 설계가 비즈니스 Domain에 대한 이해가 부족한 상태에서 설계 및 개발되었다는 반성&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;에서 출발하게 된다. 그렇기에, DDD에서는 기존의 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;현업-&amp;gt;IT로의 일방향 소통 구조를 탈피&lt;/b&gt;&lt;/span&gt;함으로써, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;현업&amp;lt;-&amp;gt;IT 라는 쌍방향 커뮤니케이션&lt;/b&gt;&lt;/span&gt;을 매우 중요하게 생각하는 철학이 담겨 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;DDD의 특징&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기존에 많이 사용되어 왔던 '데이터' 중심의 접근법을 탈피하여, 순수한 도메인의 모델과 로직에 집중한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;*유비쿼터스(Ubiquitous, 보편적인) 언어&lt;/b&gt;를 사용하는 걸 원칙으로 한다. &lt;br /&gt;이는, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;도메인 전문가(현업 전문가)와 소프트웨어 개발자 간의 커뮤니케이션 문제를 없애고&lt;/b&gt;&lt;/span&gt;, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;양쪽 모두가 직관적으로 이해&lt;/b&gt;&lt;/span&gt;할 수 있으며,&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt; 모든 문서와 코드에 이르기까지 동일한 표현과 단어로 구성된 단일화된 언어 체계&lt;/b&gt;&lt;/span&gt;를 구축해 나가는 과정을 말한다. 이로써, 분석 작업과 설계 그리고 구현에 이르기까지 &lt;b&gt;통일된 방식으로 커뮤니케이션&lt;/b&gt;이 가능해지는 것을 지향한다.&lt;/li&gt;
&lt;li&gt;소프트웨어 &lt;b&gt;엔티티(Entity)와 도메인 Concept을 가능한 한 가장 가까이 일치시키는 것&lt;/b&gt;을 목표로 한다.&lt;br /&gt;분석 모델과 설계가 다르고, 그로 인해 비즈니스 요구사항과 실제 코드가 다른 구조로 진행되는 것이 아니라, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;도메인 모델부터 코드까지 항상 함께 움직이는 구조의 모델을 지향하는 것이 DDD의 핵심 원리&lt;/b&gt;&lt;/span&gt;이다.&lt;/li&gt;
&lt;li&gt;DDD의 소프트웨어 아키텍처 측면에서의 핵심 목표는, &quot;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;Loosly coupling, High cohension&lt;/b&gt;&lt;/span&gt;&quot; 으로, 애플리케이션 또는 작은 단위의 &lt;b&gt;모듈 각각은 서로간 &lt;span style=&quot;color: #ee2323;&quot;&gt;의존성을 최소화&lt;/span&gt;&lt;/b&gt;시키고, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;응집도는 최대화&lt;/b&gt;&lt;/span&gt;하는 것이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;*유비쿼터스 언어(Ubiquitous Language)&lt;/b&gt; : &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;도메인에서 사용하는 용어를 코드에 반영하지 않으면, 그 코드는 개발자에게 코드의 의미를 해석해야만 하는 부담을 준다.&lt;/b&gt;&lt;/span&gt; 보편적인 언어를 사용함으로써, 개발자로서는 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;코드의 가독성&lt;/b&gt;&lt;/span&gt;을 높여 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;코드를 분석 및 이해하는 시간을 절약&lt;/b&gt;&lt;/span&gt;하고, 도메인 전문가와의 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;소통의 어려움을 많이 낮춘다.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;또한, 도메인 전문가와 소통하며 용어가 정의될 때마다 &lt;b&gt;용어 사전에 이를 기록하여 명확히 정의&lt;/b&gt;함으로써, 다른 사람이 이 프로젝트에 합류하여도 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;공통된 언어를 사용&lt;/b&gt;&lt;/span&gt;할 수 있도록 도와준다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DDD를 올바르게 설계하고 이행하려면, 다음과 같은 과정을 거치게 된다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;핵심 도메인을 나누고, 해당 도메인에 집중한다.&lt;/li&gt;
&lt;li&gt;각각의 도메인을 정교하게 구축하고 세분화한다.&lt;/li&gt;
&lt;li&gt;해당 도메인의 문제를 해결할 수 있는 전문가와 적극적인 협업을 한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 과정에서 다음과 같이 전략적 설계와 전술적 설계의 단계로 나뉘게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;DDD의 전략적(Strategic) 설계와 전술적(Tactical) 설계&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;전략적 설계(Strategic Design)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;*Model과 **Bounded Context를 나누는 설계&lt;/b&gt;&lt;/span&gt;로, 협업을 위한 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;Ubiquitous Language의 정리&lt;/b&gt;&lt;/span&gt;도 여기에 포함된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;현실에서의 개념을 시스템 상의 코드로 구현하기 전&lt;/b&gt;&lt;/span&gt;, 모델들 사이의 상호작용을 고려하여 인터페이스 등을 정의하거나,&lt;br /&gt;전체적인 흐름을 파악하고 경계를 나누면서 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;여러 문제를 명확히 이해할 수 있도록 하는 과정&lt;/b&gt;&lt;/span&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;전술적 설계(Tactical Design)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;시스템 상에서 실제 구현하기 위한 세부 아키텍처를 설계하는 단계&lt;/b&gt;&lt;/span&gt;로, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;코드의 구현과 직접적으로 연관된 부분&lt;/b&gt;&lt;/span&gt;이며,&amp;nbsp;&lt;br /&gt;전략적 설계에서 나뉜 경계와 모델 등을 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;유지보수성과 확장성을 고려하여 코드를 구성하는 등의 작업 과정&lt;/b&gt;&lt;/span&gt;을 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 흐름 등을 고려한 세부적인 설계를 수행하고, 구현 과정에서 발생할 수 있는 다양한 문제들을 해결하며,&lt;br /&gt;코드의 유연성과 유지보수성을 개선시키는 과정이 핵심이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;*Model(모델)&lt;/b&gt; : 도메인에 대한 이해화 복잡성을 해결하기 위해 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;해당 도메인의 규칙, 개념, 프로세스 등을 포함하는 추상적 개념&lt;/b&gt;&lt;/span&gt;. 각각의 모델은 &lt;u&gt;서로 간 경계가 확실해야 하며&lt;/u&gt;, &lt;u&gt;개발자와 해당 도메인 전문가가 함께 구축해 나가야 하는 개념&lt;/u&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;**Bounded Context(바운디드 컨텍스트)&lt;/b&gt; : &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;같은 용어라도 어떤 도메인인지에 따라 의미가 다르고, 용어가 다름에도 서로 다른 도메인 간 비슷한 역할을 하는 용어들이 있다.&lt;/b&gt;&lt;/span&gt; DDD의 철학을 위배하지 않으려면, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;각 모델은 명시적으로 구분되는 경계를 가짐으로써 서로 섞이지 않아야&lt;/b&gt;&lt;/span&gt; 하는데, 이렇게 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;섞이지 않는 특정한 Context 내에서의 완전한 의미를 갖도록 하는 경계&lt;/b&gt;&lt;/span&gt;를 Bounded Context라고 한다.&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;(ex) [카탈로그] 도메인에서의 '상품' - [재고 관리] 도메인에서의 '상품' / [회원] 도메인에서의 '회원' - [주문] 도메인에서의 '주문자')&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;772&quot; data-origin-height=&quot;478&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7UJWj/btsCKr0dXaH/M73er4i1d4fAWcE0Slm8QK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7UJWj/btsCKr0dXaH/M73er4i1d4fAWcE0Slm8QK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7UJWj/btsCKr0dXaH/M73er4i1d4fAWcE0Slm8QK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7UJWj%2FbtsCKr0dXaH%2FM73er4i1d4fAWcE0Slm8QK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;772&quot; height=&quot;478&quot; data-origin-width=&quot;772&quot; data-origin-height=&quot;478&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;SQL 중심 설계란 무엇인가?&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: SQL-DD(SQL Driven Design)이란, &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;RDBMS 측면(인프라적 측면)에서의 데이터베이스 구조와 데이터의 흐름을 중심에 놓고 설계하는 패턴&lt;/b&gt;&lt;/span&gt;을 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;정통적인 거의 모든 애플리케이션의 전형적인 설계 패턴&lt;/b&gt;이었으며, 이는 DB가 올라가는 물리적 서버의 스펙이 가장 좋았기 때문에, 대부분의 비즈니스 로직 처리를 DB 쿼리로서 처리하고자 한 것에서 기인한 걸로 보인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;SQL-DD의 특징&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;u&gt;&lt;b&gt;데이터베이스에 대한 전문적인 지식이 있다면&lt;/b&gt;&lt;/u&gt;, 도메인 모델과 관계형 데이터베이스 간의 일관성을 유지하여&lt;b&gt; 도메인 모델링과 관계형 데이터베이스 설계 간의 간극을 줄이는 것이 가능하며, 이것이 곧 목적&lt;/b&gt;이기도 하다.&lt;/li&gt;
&lt;li&gt;데이터에 초점을 두고 설계를 하기 때문에,&lt;b&gt; 애플리케이션 로직에서는 객체 자신이 포함하고 있는 데이터를 조작하는 데에 필요한 행동을 정의하여야&lt;/b&gt; 한다.&lt;br /&gt;설계 시, 협력에는 큰 중요성을 두지 않았기 때문에, 과도한 접근자와 수정자가 탄생하게 된다. 이는 결과적으로, 애플리케이션 구현에 있어 대부분의 객체 구조 및 구현이 노출되므로, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;캡슐화의 원칙을 위반&lt;/b&gt;&lt;/span&gt;하게 된다. 따라서, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;API를 설계하고 공개하는 것도 불가능&lt;/b&gt;&lt;/span&gt;하게 된다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;추상적인 개념 대신 직관적인 데이터를 위주로 개발&lt;/b&gt;&lt;/span&gt;이 가능하며, 직관적인 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;SQL 쿼리 작성으로 빠른 개발이 가능&lt;/b&gt;&lt;/span&gt;하다.&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;But, DB에 대한 낮은 이해&lt;/b&gt;&lt;/span&gt;로 인해 마구잡이로 개발되어 오히려&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt; 서비스 전체의 성능을 악화시키는 요인&lt;/b&gt;&lt;/span&gt;이 되기도 한다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;역정규화를 통해 도메인 모델과 데이터베이스 구조 간의 일관성을 유지&lt;/b&gt;&lt;/span&gt;할 수 있으며, 이에 따른 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;개발 생산성과 성능&lt;/b&gt;&lt;/span&gt;을 높일 수 있다.&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;But,&lt;/b&gt;&lt;/span&gt; 역정규화를 거듭할수록 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;중복된 코드의 양이 늘어나거나 데이터 무결성을 저해&lt;/b&gt;&lt;/span&gt;할 가능성이 높아질 수 있다.&lt;br /&gt;또한, 데이터의 일관성, 코드 컨벤션의 유지가 역정규화가 이뤄질수록 어려워지기 때문에, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;유지 보수의 어려움&lt;/b&gt;&lt;/span&gt;과 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;Scale-out의 어려움&lt;/b&gt;&lt;/span&gt;, 그에 따른 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;성능에 악역향&lt;/b&gt;&lt;/span&gt;을 불러올 수도 있다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;서비스 자체가 동적인 변화가 잦다면, 대응이 매우 어렵다.&lt;/b&gt;&lt;/span&gt; 예를 들면, '학생', '교사' 이외의 '교환학생', '강사' 라는 도메인이 추가된다면, 새로운 DB 스키마가 필요하며, 그에 따라 모든 쿼리문 및 애플리케이션 로직의 수정이 불가피할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;여기까지 잘 읽었다면, 어려운 개념을 소화해 낸 당신 참 대단하다는 말을 해주고 싶다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;아키텍처 관점에서의 모델링이 어떻게 되는 지를 알았다면, 이 모델링 결과가 애플리케이션에서 어떤 것을 통해 활용되는 지를 알아야, 모델링을 더 잘 수행할 수 있을 것이라 생각한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그래서 모델링의 결과를 개발 과정에서 '어떤 것'을 통해 활용하는지, 그 '어떤 것'이 무엇인지 확인해보도록 하자!&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;ORM(Object Relational Mapping)이란 무엇인가?&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;b&gt;객체-관계 매핑&lt;/b&gt;으로,&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt; 객체와 관계형 데이터베이스의 데이터를 자동으로 매핑해주는 것&lt;/b&gt;&lt;/span&gt;을 말한다.&lt;br /&gt;Java 진영에서는 가장 대표적으로&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt; JPA(Java PersistAnce)&lt;/b&gt;&lt;/span&gt;가 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;객체 지향 프로그래밍(특히 Java)은 클래스를 사용하고, 관계형 데이터베이스는 테이블을 사용한다.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;이에 따른, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;객체 모델과 관계형 모델 간 불일치가 필연적으로 존재하게 된다.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;b&gt;이에 대한 해결책으로 나온 것이 ORM&lt;/b&gt;으로, 객체 간의 관계를 바탕으로 SQL을 자동으로 생성하여 &lt;br /&gt;이러한 불일치 문제를 해결한다.&lt;/li&gt;
&lt;li&gt;Persistant API라고도 하는데, 여기서 말하는 Persistant(영속적인) 즉, Persistance(영속성)란, 다음과 같다.
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;영속성(Persistance)&lt;/b&gt; : &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;데이터를 생성한 프로그램이 종료되더라도, 그 데이터는 사라지지 않는 데이터의 특성&lt;/b&gt;&lt;/span&gt;을 의미.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;장점)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;객체 지향적인 코드로 인해 더 직관적이고 비즈니스 로직에 더 집중할 수 있게 도와줌&lt;/span&gt;&lt;br /&gt;=&amp;gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt; S&lt;/b&gt;&lt;b&gt;QL 쿼리가 아닌, 직관적인 코드(메서드)로 데이터를 조작&lt;/b&gt;&lt;/span&gt;하게 됨.&lt;/li&gt;
&lt;li&gt;재사용 및 유지보수의 편리성이 증가함&lt;br /&gt;=&amp;gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt; ORM은 독립적으로 작성되어 있으며, 해당 객체들을 재활용&lt;/b&gt;&lt;/span&gt;할 수 있음. (객체의 특징)&lt;/li&gt;
&lt;li&gt;DBMS에 대한 종속성이 줄어듦&lt;br /&gt;=&amp;gt; &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;DBMS에 따른 자료형의 종속성에서 많이 벗어날 수&lt;/b&gt;&lt;/span&gt; 있으며, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;이기종 DB&lt;/b&gt; &lt;/span&gt;사용가능.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;단점)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;100% ORM만으로 서비스를 구현하기는 어려움&lt;br /&gt;=&amp;gt; &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;설계부터 매우 신중해야 하기 때문에, 100% 완벽한 설계는 존재할 수가 없으며&lt;/b&gt;&lt;/span&gt;, 프로젝트의 복잡성이 커질 경우 난이도 또한 올라가게 됨.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;프로시저가 많은 시스템&lt;/b&gt;&lt;/span&gt;에서는 ORM의 객체 지향적인 장점을 활용하기가 어려움&lt;br /&gt;=&amp;gt; 이미 프로시저가 많은 시스템에서는, 해당 프로시저를 구현하는 데에 필요한 객체들을 다시 설계하고 바꿔야 하므로, 생산성 저하 및 리스크가 발생할 수 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;SQL Mapper란 무엇인가?&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;객체와 관계형 데이터베이스의 데이터를 개발자가 작성한 SQL로 매핑시켜주는 프레임워크.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;대표적으로&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;MyBatis&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;라는 프레임워크가 있다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ORM과 동일한 기능으로 보이나, 가장 큰 차이점은 이 프레임워크에서&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt; 객체와 관계를&lt;/span&gt; 매핑하여 &lt;span style=&quot;color: #ee2323;&quot;&gt;사용하기 편한 메서드 등을 제공해주는 것이 아닌&lt;/span&gt;, 개발자가 직접 작성한 &lt;span style=&quot;color: #ee2323;&quot;&gt;SQL문의 결과와 객체의 필드를 매핑&lt;/span&gt;&lt;/b&gt;하여 데이터를 객체화 시킨다는 점이다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;장점)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;JDBC를 사용했을 때 발생하는 불필요한 코드들을 줄일 수&lt;/b&gt;&lt;/span&gt; 있다. (&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;Connection 관리, Checked Exception 처리&lt;/b&gt;&lt;/span&gt; 등)&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;DAO로부터 SQL문을 분리&lt;/b&gt;&lt;/span&gt;함으로써, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;코드의 간결성 및 유지보수성&lt;/b&gt;&lt;/span&gt;을 향상할 수 있다.&lt;/li&gt;
&lt;li&gt;DBMS에 대한 지식이 해박하다면, 쿼리를 직접 작성하여 그대로 적용할 수 있으므로,&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt; 복잡한 JOIN, 튜닝 등을 좀 더 수월하게 작성&lt;/b&gt;&lt;/span&gt;이 가능하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;단점)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;SQL문을 직접 모두 작성해야&lt;/b&gt;&lt;/span&gt; 한다.&amp;nbsp;&lt;br /&gt;=&amp;gt; DB 설정 변경 또는 DBMS가 바뀔 시, 수정할 부분이 너무나도 많아지게 된다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;객체 모델과 관계 모델을 각각 따로 개발&lt;/b&gt;&lt;/span&gt;해야 함으로써, 유지보수성이 하락된다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;DBMS에 대한 종속성&lt;/b&gt;&lt;/span&gt;이 매우 크므로, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;이기종 DB&lt;/b&gt;&lt;/span&gt;를 사용하는 것 자체가 &lt;b&gt;리스크&lt;/b&gt;가 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;우리 회사 또는 우리 팀이 개발한 프로젝트에서 지금 사용하고 있는 아키텍처는 뭐지?&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;약 8년 전, 실제 Spring, JPA 강의의 대가 김영한 님이 OKKY라는 IT 커뮤니티 사이트에 썼던 글이기도 하고, 그에 대한 댓글들에서 많은 인사이트들을 얻을 수 있는 것 같아 아래 글을 첨부한다. 여기에서 'fender' 님의 댓글이 인상깊어서 가져와본다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Q. 현재 개발 중인 프로젝트에 대해 '퇴사 처리'는 어떻게 해야 하지?&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;A1. 회원 테이블 또는 그와 관련된 레코드를 찾아 이 컬럼값을 바꾸면 되지!&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=&amp;gt; 해당 프로젝트는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;데이터베이스 중심적(SQL-DD)으로 설계되고 구현되고 있다는 것에 대한 반증일 가능성이 매우 높다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;A2. 회원 클래스를 가져와서 이 속성을 이렇게 바꾸면 되지!&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=&amp;gt; 해당 도메인 클래스의 인스턴스에 대한 영속성을 확보한다는 측면에서 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;JPA와 같은 본격적인 ORM 라이브러리 도입이 자연스러운 선택이 되는 프로젝트일 가능성이 높다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://okky.kr/questions/286812&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://okky.kr/questions/286812&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1703653798167&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;OKKY - ORM의 사실과 오해&quot; data-og-description=&quot;ORM의 사실과 오해 http://okky.kr/article/286531 개시물에 댓글을 해주신 자유로운 새님의 글에 대해 질답 하는 형식으로 한 말씀 올리겠습니다. 먼저 은탄환은 없다는 것을 말씀드립니다. ORM은 절대 만&quot; data-og-host=&quot;okky.kr&quot; data-og-source-url=&quot;https://okky.kr/questions/286812&quot; data-og-url=&quot;https://okky.kr/questions/286812&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://okky.kr/questions/286812&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://okky.kr/questions/286812&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;OKKY - ORM의 사실과 오해&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;ORM의 사실과 오해 http://okky.kr/article/286531 개시물에 댓글을 해주신 자유로운 새님의 글에 대해 질답 하는 형식으로 한 말씀 올리겠습니다. 먼저 은탄환은 없다는 것을 말씀드립니다. ORM은 절대 만&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;okky.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;그래서 무엇이 기본으로 지향해야 하는 아키텍처일까?&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현대 사회에서의 웹 개발자라면 DDD가 더 옳은 방향이라고 생각한다. 대부분의 웹 개발이 Java로 이루어지며, 이 'Java'라는 언어 자체가 '객체 지향'이다. 그런데, RDBMS는 '관계 지향'이며, 데이터를 중심으로 잘 정규화하여 '저장'하는 것에 기본적인 의미를 두고 설계되었기 때문에, 이 둘이 서로 지향하는 방향이 약간 다르다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인프라 엔지니어의 입장에서 보면, DB 서버는 Scale-out이 매우 어렵고 신경 써야할 것이 매우 많은 반면, APP 서버는 Scale-out이 비교적 쉽고, 신경 써야할 것이 DB 서버에 비해 상당히 적다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서, 데이터는 최대한 가볍게 꺼내 쓰고 가볍게 저장하며, 이를 기반으로 APP 서버가 열심히 일하여 비즈니스 로직을 처리하도록 개발하는 것이, 기업의 비용을 절감하고, 추후의 인적 리소스를 확보하는 데에 있어서도 더 옳은 방향이라고 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;참고&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;a href=&quot;https://happycloud-lee.tistory.com/94&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://happycloud-lee.tistory.com/94&lt;/a&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1703599319522&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;DDD 핵심만 빠르게 이해하기&quot; data-og-description=&quot;마이크로서비스의 설계 방법론인 DDD(Domain Driven Design)에 대해 제가 가진 지식과 그간의 경험을 기반으로 정리하였습니다. 이 글을 읽기 전에 먼저 일하는 방식 변화를 이끌고 있는 애자일, 마이&quot; data-og-host=&quot;happycloud-lee.tistory.com&quot; data-og-source-url=&quot;https://happycloud-lee.tistory.com/94&quot; data-og-url=&quot;https://happycloud-lee.tistory.com/94&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/uSV82/hyUTEf3ZC4/zV6hl0136g3iqRrKQItkrk/img.png?width=772&amp;amp;height=478&amp;amp;face=0_0_772_478,https://scrap.kakaocdn.net/dn/tG0cm/hyUTL7mC4a/2V9CZDnKJSKkS5uQ2cKSX0/img.png?width=772&amp;amp;height=478&amp;amp;face=0_0_772_478,https://scrap.kakaocdn.net/dn/eCaRU/hyUTBRcuX1/2WsUyvUEr6cvq2JI1YZfnk/img.png?width=1570&amp;amp;height=680&amp;amp;face=0_0_1570_680&quot;&gt;&lt;a href=&quot;https://happycloud-lee.tistory.com/94&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://happycloud-lee.tistory.com/94&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/uSV82/hyUTEf3ZC4/zV6hl0136g3iqRrKQItkrk/img.png?width=772&amp;amp;height=478&amp;amp;face=0_0_772_478,https://scrap.kakaocdn.net/dn/tG0cm/hyUTL7mC4a/2V9CZDnKJSKkS5uQ2cKSX0/img.png?width=772&amp;amp;height=478&amp;amp;face=0_0_772_478,https://scrap.kakaocdn.net/dn/eCaRU/hyUTBRcuX1/2WsUyvUEr6cvq2JI1YZfnk/img.png?width=1570&amp;amp;height=680&amp;amp;face=0_0_1570_680');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;DDD 핵심만 빠르게 이해하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;마이크로서비스의 설계 방법론인 DDD(Domain Driven Design)에 대해 제가 가진 지식과 그간의 경험을 기반으로 정리하였습니다. 이 글을 읽기 전에 먼저 일하는 방식 변화를 이끌고 있는 애자일, 마이&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;happycloud-lee.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://incheol-jung.gitbook.io/docs/q-and-a/architecture/ddd&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://incheol-jung.gitbook.io/docs/q-and-a/architecture/ddd&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1703592106378&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;DDD(Domain Driven Design) - Incheol's TECH BLOG&quot; data-og-description=&quot;이벤트 소싱과 항상 함께 알아두어야 할 개념으로 CQRS가 있으며 간단히 설명하면 커맨드와 쿼리의 책임을 분리하자는 것이다. 커맨드는 일반적인 디비 기준으로 상태를 변경하는 C,U,D와 같은 메&quot; data-og-host=&quot;incheol-jung.gitbook.io&quot; data-og-source-url=&quot;https://incheol-jung.gitbook.io/docs/q-and-a/architecture/ddd&quot; data-og-url=&quot;https://incheol-jung.gitbook.io/docs/q-and-a/architecture/ddd&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b2ygP4/hyUTDIcA0y/N8AzlhiJg7cspJCOkkOvJK/img.png?width=2088&amp;amp;height=1161&amp;amp;face=0_0_2088_1161,https://scrap.kakaocdn.net/dn/f18l7/hyUTxusz15/O0qNa2vUK5rlHhJws2xKK0/img.png?width=1230&amp;amp;height=692&amp;amp;face=0_0_1230_692,https://scrap.kakaocdn.net/dn/nd7rB/hyUTDuEO0l/xjAvCgsYKgFg2yYBVOPgQK/img.jpg?width=638&amp;amp;height=479&amp;amp;face=0_0_638_479&quot;&gt;&lt;a href=&quot;https://incheol-jung.gitbook.io/docs/q-and-a/architecture/ddd&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://incheol-jung.gitbook.io/docs/q-and-a/architecture/ddd&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b2ygP4/hyUTDIcA0y/N8AzlhiJg7cspJCOkkOvJK/img.png?width=2088&amp;amp;height=1161&amp;amp;face=0_0_2088_1161,https://scrap.kakaocdn.net/dn/f18l7/hyUTxusz15/O0qNa2vUK5rlHhJws2xKK0/img.png?width=1230&amp;amp;height=692&amp;amp;face=0_0_1230_692,https://scrap.kakaocdn.net/dn/nd7rB/hyUTDuEO0l/xjAvCgsYKgFg2yYBVOPgQK/img.jpg?width=638&amp;amp;height=479&amp;amp;face=0_0_638_479');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;DDD(Domain Driven Design) - Incheol's TECH BLOG&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;이벤트 소싱과 항상 함께 알아두어야 할 개념으로 CQRS가 있으며 간단히 설명하면 커맨드와 쿼리의 책임을 분리하자는 것이다. 커맨드는 일반적인 디비 기준으로 상태를 변경하는 C,U,D와 같은 메&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;incheol-jung.gitbook.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://youwjune.tistory.com/38&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youwjune.tistory.com/38&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1703592134523&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;DDD 설계 vs SQL 중심 설계&quot; data-og-description=&quot;1. DDD란? DDD(Domain Driven Design : 도메인 주도 설계)란? 도메인 패턴을 중심에 놓고 설계하는 패턴이다. 즉, 도메인 간의 상호작용이 설계의 중심이 된다. 도메인이란, 소프트웨어로 해결하고자 하는 &quot; data-og-host=&quot;youwjune.tistory.com&quot; data-og-source-url=&quot;https://youwjune.tistory.com/38&quot; data-og-url=&quot;https://youwjune.tistory.com/38&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/3UiKH/hyUTyGUUub/gKEL4xvpvHW2RVK6yJawe0/img.png?width=800&amp;amp;height=819&amp;amp;face=0_0_800_819,https://scrap.kakaocdn.net/dn/44xNh/hyUTLztbiC/2p8KNAOMUxnXVGsT1ZJ9ok/img.png?width=800&amp;amp;height=819&amp;amp;face=0_0_800_819,https://scrap.kakaocdn.net/dn/ZKftf/hyUTICKxBv/4GEzl6U0vszNf9RgcTpb9k/img.png?width=996&amp;amp;height=1020&amp;amp;face=0_0_996_1020&quot;&gt;&lt;a href=&quot;https://youwjune.tistory.com/38&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://youwjune.tistory.com/38&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/3UiKH/hyUTyGUUub/gKEL4xvpvHW2RVK6yJawe0/img.png?width=800&amp;amp;height=819&amp;amp;face=0_0_800_819,https://scrap.kakaocdn.net/dn/44xNh/hyUTLztbiC/2p8KNAOMUxnXVGsT1ZJ9ok/img.png?width=800&amp;amp;height=819&amp;amp;face=0_0_800_819,https://scrap.kakaocdn.net/dn/ZKftf/hyUTICKxBv/4GEzl6U0vszNf9RgcTpb9k/img.png?width=996&amp;amp;height=1020&amp;amp;face=0_0_996_1020');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;DDD 설계 vs SQL 중심 설계&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;1. DDD란? DDD(Domain Driven Design : 도메인 주도 설계)란? 도메인 패턴을 중심에 놓고 설계하는 패턴이다. 즉, 도메인 간의 상호작용이 설계의 중심이 된다. 도메인이란, 소프트웨어로 해결하고자 하는&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;youwjune.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@cv_/DDD-vs-SQL-%EC%A4%91%EC%8B%AC-%EC%84%A4%EA%B3%84-%EC%B0%A8%EC%9D%B4&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://velog.io/@cv_/DDD-vs-SQL-%EC%A4%91%EC%8B%AC-%EC%84%A4%EA%B3%84-%EC%B0%A8%EC%9D%B4&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1703601851559&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;DDD vs SQL 중심 설계 차이&quot; data-og-description=&quot;DDD(Domain-Driven Design)와 SQL-DD (Structured Query Language-Driven Design)는 소프트웨어를 개발하는 여러 방법론중 일부이다. 두 방식의 차이는?&quot; data-og-host=&quot;velog.io&quot; data-og-source-url=&quot;https://velog.io/@cv_/DDD-vs-SQL-%EC%A4%91%EC%8B%AC-%EC%84%A4%EA%B3%84-%EC%B0%A8%EC%9D%B4&quot; data-og-url=&quot;https://velog.io/@cv_/DDD-vs-SQL-중심-설계-차이&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bkCM94/hyUTwWFmzc/YnmYCz6pnJ5qkfB61tKeYK/img.png?width=950&amp;amp;height=500&amp;amp;face=0_0_950_500&quot;&gt;&lt;a href=&quot;https://velog.io/@cv_/DDD-vs-SQL-%EC%A4%91%EC%8B%AC-%EC%84%A4%EA%B3%84-%EC%B0%A8%EC%9D%B4&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://velog.io/@cv_/DDD-vs-SQL-%EC%A4%91%EC%8B%AC-%EC%84%A4%EA%B3%84-%EC%B0%A8%EC%9D%B4&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bkCM94/hyUTwWFmzc/YnmYCz6pnJ5qkfB61tKeYK/img.png?width=950&amp;amp;height=500&amp;amp;face=0_0_950_500');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;DDD vs SQL 중심 설계 차이&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;DDD(Domain-Driven Design)와 SQL-DD (Structured Query Language-Driven Design)는 소프트웨어를 개발하는 여러 방법론중 일부이다. 두 방식의 차이는?&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;velog.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://gmlwjd9405.github.io/2019/02/01/orm.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://gmlwjd9405.github.io/2019/02/01/orm.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1703651564482&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;[DB] ORM이란 - Heee's Development Blog&quot; data-og-description=&quot;Step by step goes a long way.&quot; data-og-host=&quot;gmlwjd9405.github.io&quot; data-og-source-url=&quot;https://gmlwjd9405.github.io/2019/02/01/orm.html&quot; data-og-url=&quot;http://gmlwjd9405.github.io/2019/02/01/orm.html&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/59lVK/hyUTv4HjLy/EmO5b0JImQT1F57J4fphTk/img.png?width=1997&amp;amp;height=1120&amp;amp;face=0_0_1997_1120,https://scrap.kakaocdn.net/dn/YMSeL/hyUTK8CTAb/bUTGdo2CfxiDrfMaVNkZbK/img.png?width=2193&amp;amp;height=539&amp;amp;face=0_0_2193_539,https://scrap.kakaocdn.net/dn/ZU4Jt/hyUTytyRhq/AAzfsudqVXgmLWhKXEI7ek/img.png?width=2200&amp;amp;height=322&amp;amp;face=0_0_2200_322&quot;&gt;&lt;a href=&quot;https://gmlwjd9405.github.io/2019/02/01/orm.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://gmlwjd9405.github.io/2019/02/01/orm.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/59lVK/hyUTv4HjLy/EmO5b0JImQT1F57J4fphTk/img.png?width=1997&amp;amp;height=1120&amp;amp;face=0_0_1997_1120,https://scrap.kakaocdn.net/dn/YMSeL/hyUTK8CTAb/bUTGdo2CfxiDrfMaVNkZbK/img.png?width=2193&amp;amp;height=539&amp;amp;face=0_0_2193_539,https://scrap.kakaocdn.net/dn/ZU4Jt/hyUTytyRhq/AAzfsudqVXgmLWhKXEI7ek/img.png?width=2200&amp;amp;height=322&amp;amp;face=0_0_2200_322');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[DB] ORM이란 - Heee's Development Blog&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Step by step goes a long way.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;gmlwjd9405.github.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jongsky.tistory.com/15&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://jongsky.tistory.com/15&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1703653039932&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;ORM  vs SQL Mapper&quot; data-og-description=&quot;1. 글을 작성하게 된 이유 Rest API를 만들면서 생겨난 이슈사항이다. FastAPI를 이용해 request가 왔을 때 response를 해주는 Rest API를 만들고 있었다. response를 위해서는 기존에 만들어진 db(mysql)에서 데&quot; data-og-host=&quot;jongsky.tistory.com&quot; data-og-source-url=&quot;https://jongsky.tistory.com/15&quot; data-og-url=&quot;https://jongsky.tistory.com/15&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bS4gwo/hyUTIpr6AV/yRLI2IXarQvhLqzDrRJU2K/img.png?width=800&amp;amp;height=353&amp;amp;face=0_0_800_353,https://scrap.kakaocdn.net/dn/Cdkle/hyUTIiHjvY/DKtSXBWsCTXr9xdHNjB8x1/img.png?width=800&amp;amp;height=353&amp;amp;face=0_0_800_353,https://scrap.kakaocdn.net/dn/gqPdU/hyUTFlWv1B/0flNWA4mOCptqJ2dayDx90/img.png?width=1024&amp;amp;height=452&amp;amp;face=0_0_1024_452&quot;&gt;&lt;a href=&quot;https://jongsky.tistory.com/15&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jongsky.tistory.com/15&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bS4gwo/hyUTIpr6AV/yRLI2IXarQvhLqzDrRJU2K/img.png?width=800&amp;amp;height=353&amp;amp;face=0_0_800_353,https://scrap.kakaocdn.net/dn/Cdkle/hyUTIiHjvY/DKtSXBWsCTXr9xdHNjB8x1/img.png?width=800&amp;amp;height=353&amp;amp;face=0_0_800_353,https://scrap.kakaocdn.net/dn/gqPdU/hyUTFlWv1B/0flNWA4mOCptqJ2dayDx90/img.png?width=1024&amp;amp;height=452&amp;amp;face=0_0_1024_452');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;ORM vs SQL Mapper&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;1. 글을 작성하게 된 이유 Rest API를 만들면서 생겨난 이슈사항이다. FastAPI를 이용해 request가 왔을 때 response를 해주는 Rest API를 만들고 있었다. response를 위해서는 기존에 만들어진 db(mysql)에서 데&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;jongsky.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>CS 지식 | 기초 용어,개념</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/155</guid>
      <comments>https://co-no.tistory.com/entry/%EA%B0%9C%EB%85%90-DDD-%EC%84%A4%EA%B3%84%EC%99%80-SQL-%EC%A4%91%EC%8B%AC-%EC%84%A4%EA%B3%84-feat-ORM%EA%B3%BC-SQL-Mapper#entry155comment</comments>
      <pubDate>Thu, 28 Dec 2023 00:00:25 +0900</pubDate>
    </item>
    <item>
      <title>[MSSQL] 데이터베이스명, 논리적 파일명, 물리적 파일명(.mdf, .ldf)을 쿼리로 변경하기</title>
      <link>https://co-no.tistory.com/entry/MSSQL-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4%EB%AA%85-%EB%85%BC%EB%A6%AC%EC%A0%81-%ED%8C%8C%EC%9D%BC%EB%AA%85-%EB%AC%BC%EB%A6%AC%EC%A0%81-%ED%8C%8C%EC%9D%BC%EB%AA%85mdf-ldf-%EB%B3%80%EA%B2%BD</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;417&quot; data-origin-height=&quot;488&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/APJR9/btsCDeUUfUB/dTsMpABoTLlUmuK35gePB1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/APJR9/btsCDeUUfUB/dTsMpABoTLlUmuK35gePB1/img.png&quot; data-alt=&quot;SSMS를 통한 데이터베이스 이름 변경&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/APJR9/btsCDeUUfUB/dTsMpABoTLlUmuK35gePB1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAPJR9%2FbtsCDeUUfUB%2FdTsMpABoTLlUmuK35gePB1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;417&quot; height=&quot;488&quot; data-origin-width=&quot;417&quot; data-origin-height=&quot;488&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;SSMS를 통한 데이터베이스 이름 변경&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;0. 현재 변경하려는 데이터베이스를 &lt;span style=&quot;color: #ee2323;&quot;&gt;반드시&lt;/span&gt; single_user 모드로 변경하기&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1703634755258&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;USE [master]

-- DB 단일 사용자 모드(Single User mode)로 변경
-- 'WITH ROLLBACK IMMEDIATE' : 이 ALTER문이 발생하는 도중 생기는 다른 트랜잭션들은 모두 즉시 롤백하라는 옵션
ALTER DATABASE [데이터베이스명]
SET SINGLE_USER
WITH ROLLBACK IMMEDIATE

-- 작업 완료 후 DB를 다시 원상태(Multi User mode)로 변경
ALTER DATABASE [데이터베이스명]
SET MULTI_USER&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;1. 데이터베이스 이름 변경&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1703635143311&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- 만약 현재 변경하려는 데이터베이스가 특정 SQL User에서 default database로 설정되어 있다면,
-- 아래 쿼리문 수행하여, default database 명 먼저 변경하기.
-- 그렇지 않으면, 4064 에러(Cannot open u ser default database) 뜸
USE [master]
ALTER LOGIN [SQL Login Name] WITH DEFAULT_DATABASE=[변경하려는 데이터베이스 이름]


-- 데이터베이스 이름 변경
ALTER DATABASE [현재 데이터베이스 이름]
MODIFY NAME = [변경되는 데이터베이스 이름]

-- SP로도 가능하다.
EXEC sp_renamedb '현재 데이터베이스 이름', '변경되는 데이터베이스 이름'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;논리적 파일명 또는 물리적 데이터 파일명을 변경하기 전에&lt;b&gt; 다음 쿼리를 수행하여, 현재 설정되어 있는 논리적 파일명 및 물리적 데이터 파일명을 어딘가에 &lt;span style=&quot;color: #ee2323;&quot;&gt;반드시&lt;/span&gt; 적어두자!&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1703636008817&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- 현재 데이터베이스의 Logical File Name 확인 방법
USE [확인하려는 데이터베이스명]
SELECT FILE_ID
    , [Logical File Name] = name
    , [Physical File Name] = physical_name
FROM sys.database_files

-- 위 결과 복사해두기.&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;2. 물리적 데이터 파일명(.mdf 또는 .ldf) 변경&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2.1. Backup 및 Restore(복원)을 이용한 방법&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방법은 이미 백업파일이 존재하고, 해당 파일로 Restore를 하는 과정에서 변경하고 싶을 때 사용하면 좋은 방법이다.&lt;/p&gt;
&lt;pre id=&quot;code_1703637349790&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- 해당 백업파일의 Logical Name 확인
RESTORE FILELISTONLY 
FROM DISK=N'백업파일 절대경로'

-- 해당 백업파일로 복원하면서 저장될 physical 파일 이름을 변경하는 방법
RESTORE DATABASE [복원하려는 데이터베이스명]
FROM DISK = N'백업파일 절대경로'
WITH FILE = 1
    , STATS = 10
    , RECOVERY
    , REPLACE
    , MOVE N'MDF Logical Name' TO N'바뀔 Physical .mdf 파일 디렉토리'
    , MOVE N'LDF Logical Name' TO N'바뀔 Physical .ldf 파일 디렉토리'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2.2. 데이터베이스 Detach/Attach 를 이용한 방법&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터베이스 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;Detach(분리)&lt;/b&gt;&lt;/span&gt;란, 데이터 파일을 새로운 디스크로 옮기는 등의 작업이 필요할 경우, &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;해당 DB의 Physical 파일은 그대로 보존하면서, 해당 DB에 대한 유저 Access는 차단하는 방법&lt;/b&gt;&lt;/span&gt;이다. 즉, 해당 DB를 SQL 인스턴스에서 떼어내는 방법이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터베이스 Detach를 수행할 경우, database file information, status information 등의 sys.databases에서 볼 수 있는 모든 metadata가 삭제되므로, 이 점을 주의해야 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1703639215122&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- 해당 DB 분리(Detach) 수행
USE [master]
EXEC SP_DETACH_DB '데이트베이스명', 'TRUE'

-- 해당 데이터베이스의 파일명 또는 디렉토리를 OS 내에서 변경한다.

-- 해당 DB 다시 연결(Attach) 수행
USE [master]
EXEC SP_ATTACH_DB '데이터베이스명', '변경된 .mdf 파일 디렉토리', '변경된 .ldf 파일 디렉토리'

-- 해당 DB Attach 할 때 .mdf 파일만 연결하기.
EXEC SP_ATTACH_SINGLE_FILE_DB '데이터베이스명', '변경된 .mdf 파일 디렉토리'&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;3. 논리적 파일명 변경&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1703636147452&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;USE [변경하려는 데이터베이스 이름]

-- 데이터 파일과 로그 파일이 각각 다르게 설정되어 있으므로, 쿼리를 각각 수행해줘야 한다.
-- .mdf에 대한 logical name 변경
ALTER DATABASE [변경하려는 데이터베이스 이름]
MODIFY FILE (
    NAME = '기존 Logical File Name'
    , NEWNAME = '바뀔 Logical File Name'
)

-- .ldf에 대한 logical name 변경
ALTER DATABASE [변경하려는 데이터베이스 이름]
MODIFY FILE (
    NAME = '기존 Logical File Name'
    , NEWNAME = '바뀔 Logical File Name'
)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/sql/relational-databases/databases/rename-a-database?view=sql-server-ver16&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://learn.microsoft.com/ko-kr/sql/relational-databases/databases/rename-a-database?view=sql-server-ver16&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1703634290485&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;데이터베이스 이름 바꾸기 - SQL Server&quot; data-og-description=&quot;데이터베이스 이름 바꾸기&quot; data-og-host=&quot;learn.microsoft.com&quot; data-og-source-url=&quot;https://learn.microsoft.com/ko-kr/sql/relational-databases/databases/rename-a-database?view=sql-server-ver16&quot; data-og-url=&quot;https://learn.microsoft.com/ko-kr/sql/relational-databases/databases/rename-a-database?view=sql-server-ver16&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/OGoFn/hyUTC3IYVR/24DcYJ32ypBlvhiY9VfgW0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/sql/relational-databases/databases/rename-a-database?view=sql-server-ver16&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://learn.microsoft.com/ko-kr/sql/relational-databases/databases/rename-a-database?view=sql-server-ver16&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/OGoFn/hyUTC3IYVR/24DcYJ32ypBlvhiY9VfgW0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;데이터베이스 이름 바꾸기 - SQL Server&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;데이터베이스 이름 바꾸기&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;learn.microsoft.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://dbrang.tistory.com/106&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://dbrang.tistory.com/106&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1703639441897&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[2k] 논리적 파일명 및 물리적 파일명 바꾸기&quot; data-og-description=&quot;/********************************************************************************************** -- Title : [2k] 논리적 파일명 및 물리적 파일명 바꾸기 -- Reference : dBRang.com -- Key word : alter database, restore database, sp_detach_db ***&quot; data-og-host=&quot;dbrang.tistory.com&quot; data-og-source-url=&quot;https://dbrang.tistory.com/106&quot; data-og-url=&quot;https://dbrang.tistory.com/106&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/pEIFP/hyUTH44btn/VGj6TeTaK5JsJVdFvE9X1k/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/eFrscv/hyUTGSCVaV/WcYBeUYWjhBXWuwpSUbre0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://dbrang.tistory.com/106&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://dbrang.tistory.com/106&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/pEIFP/hyUTH44btn/VGj6TeTaK5JsJVdFvE9X1k/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/eFrscv/hyUTGSCVaV/WcYBeUYWjhBXWuwpSUbre0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[2k] 논리적 파일명 및 물리적 파일명 바꾸기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;/********************************************************************************************** -- Title : [2k] 논리적 파일명 및 물리적 파일명 바꾸기 -- Reference : dBRang.com -- Key word : alter database, restore database, sp_detach_db ***&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;dbrang.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DB/SQL Server (MSSQL)</category>
      <category>MSSQL Logical name 변경</category>
      <category>MSSQL 데이터베이스 ldf 파일명 변경</category>
      <category>MSSQL 데이터베이스 mdf 파일명 변경</category>
      <category>MSSQL 데이터베이스 이름 변경</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/156</guid>
      <comments>https://co-no.tistory.com/entry/MSSQL-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4%EB%AA%85-%EB%85%BC%EB%A6%AC%EC%A0%81-%ED%8C%8C%EC%9D%BC%EB%AA%85-%EB%AC%BC%EB%A6%AC%EC%A0%81-%ED%8C%8C%EC%9D%BC%EB%AA%85mdf-ldf-%EB%B3%80%EA%B2%BD#entry156comment</comments>
      <pubDate>Wed, 27 Dec 2023 10:07:46 +0900</pubDate>
    </item>
    <item>
      <title>[개념] MSA, 컨테이너의 등장과 Agile, DevOps 문화는 무엇인가</title>
      <link>https://co-no.tistory.com/entry/%EA%B0%9C%EB%85%90-MSA-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88%EC%9D%98-%EB%93%B1%EC%9E%A5%EA%B3%BC-Agile-DevOps-%EB%AC%B8%ED%99%94%EB%8A%94-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;제조업&lt;/b&gt;에서 DBA, 미들웨어 엔지니어로 일하면서 가장 크게 느낀 부분은, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;한 번 설계하고 배포한 시스템은 그 시스템을 전부 뒤엎지 않는 이상, 변경을 하기가 굉장히 까다롭다는 것&lt;/b&gt;&lt;/span&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 필자가 일하고 있는 회사가 제조업이기 때문이고, 제조업 특성 상 &lt;u&gt;생산 가동 시간이 매출에 가장 큰 영향&lt;/u&gt;을 미치며, 이는 곧 &lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;IT 조직의 '변화'에 대한 두려움으로 경직을 불러옴으로써&lt;/b&gt; &lt;b&gt;야기된 결과&lt;/b&gt;&lt;/span&gt;라고 생각한다. &lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;이러한 문제가 비단 제조업에서만 일어날 것 같지는 않다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각설하고, 더 이상의 레거시 시스템을 찍어내는 행동을 반복하지 않기 위해, 나부터라도 조금씩 최신 IT 트렌드를 공부하고 이러한 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;기술들을 사내에 안정적으로 도입 및 적용&lt;/b&gt;&lt;/span&gt;시키며, 기존의 변화가 어려운 낡은 시스템에서 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;유연한 변화가 가능한 시스템으로 탈바꿈하는 것을 목표로&lt;/b&gt;&lt;/span&gt; 해보고자 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러기 위해서는, 이제는 트렌드라고 부르기도 뭐한, &lt;b&gt;IT의 기본적인 아키텍처 또는 문화&lt;/b&gt;로 자리 잡은 &lt;b&gt;MSA&lt;/b&gt;, &lt;b&gt;컨테이너&lt;/b&gt;, &lt;b&gt;Agile&lt;/b&gt;, &lt;b&gt;DevOps&lt;/b&gt; 등의 개념부터 알아볼 필요가 있다. 이번 포스팅에서는 이러한 것들의 개념을 정리하고자 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MSA(Micro Service Architecture)를 논하기 전에, 우리는 &lt;u&gt;지난 수십년 간 IT 시스템의 표준이었던&lt;/u&gt;&lt;b&gt; 모놀리식 아키텍처&lt;/b&gt;(Monolithic Architecture)에 대해 알아볼 필요가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;모놀리식 아키텍처(Monolithic Architecture)란?&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: MSA와 반대되는 개념으로, 전통의 아키텍처를 지칭하는 의미로 생겨난 단어이다. 통상적으로, &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;단일 코드 베이스의 애플리케이션 또는 그러한 애플리케이션이 동작되는 시스템&lt;/b&gt;&lt;/span&gt;을 말하며, 이 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;애플리케이션 하나는 단일 데이터베이스에 연결&lt;/b&gt;&lt;/span&gt;되는 구조이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;714&quot; data-origin-height=&quot;363&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FfYtw/btsBQqo9C2b/hNHAEGniTmIzh8J52fCHG1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FfYtw/btsBQqo9C2b/hNHAEGniTmIzh8J52fCHG1/img.png&quot; data-alt=&quot;모놀리식 아키텍처의 다이어그램&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FfYtw/btsBQqo9C2b/hNHAEGniTmIzh8J52fCHG1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFfYtw%2FbtsBQqo9C2b%2FhNHAEGniTmIzh8J52fCHG1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;714&quot; height=&quot;363&quot; data-origin-width=&quot;714&quot; data-origin-height=&quot;363&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;모놀리식 아키텍처의 다이어그램&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;모놀리식 아키텍처의 장점&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;단순성&lt;/b&gt; &lt;/span&gt;: 모든 코드가 단일 코드 베이스에 있으므로, 변경 사항이 발생할 경우, &lt;b&gt;적용할 모든 코드가 한 곳에(한 프로젝트 내에) 존재&lt;/b&gt;한다는 의미이다. 또한 개발환경 즉, 로컬에서 실행해야 할 경우, &lt;b&gt;단일 애플리케이션만 실행하면 되는 단순함&lt;/b&gt;이 있다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;간편한 배포&lt;/b&gt;&lt;/span&gt; : &lt;b&gt;단일 프로젝트로 배포하면 되므로 간편&lt;/b&gt;하다(?). &amp;rarr; (&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;Downtime이 자유로운 도메인이라면&lt;/b&gt;&lt;/span&gt;, 간편하다.)&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;보편성&lt;/b&gt;&lt;/span&gt; : &lt;b&gt;대부분의 개발자&lt;/b&gt;가 모놀리식 아키텍처에서 &lt;b&gt;작업한 경험&lt;/b&gt;이 있어, 프로젝트를 쉽게 시작할 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;인프라 구성 용이&lt;/b&gt;&lt;/span&gt; : 하나의 프로젝트, 즉, 하나의 애플리케이션 및 DB만 배포하면 되므로, &lt;b&gt;인프라 구성이 쉽고 관리 point가 적다. (&lt;span style=&quot;color: #ee2323;&quot;&gt;초기에만 그렇다고 본다.&lt;/span&gt;)&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;모놀리식 아키텍처의 단점&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;유지 보수의 어려움&lt;/b&gt;&lt;/span&gt; : 시간이 지남에 따라 분명 애플리케이션의 규모가 커질텐데, 이에 따른 어려움이 생길 수밖에 없다. &lt;u&gt;단일 프로젝트로 개발하면서 필요한 모듈들이 굉장히 많을텐데&lt;/u&gt;, &lt;b&gt;하나의 기능을 변경하고자 하면, 이를 참조하거나 영향을 받는 모든 모듈들도 수정해야 하기 때문&lt;/b&gt;이다. 또한 가장 큰 문제로는, 작은 부분을 수정하고 반영하는 데에 있어서도,&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt; 전체 애플리케이션이 한 번은 종료되어야 한다는 점&lt;/b&gt;&lt;/span&gt;이다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;유연하지 않은 확장성(Scale 측면)&lt;/b&gt;&lt;/span&gt; : 애플리케이션의 특정 부분에 대한 요청을 받으면, 이 부분만을 확장할 수는 없고, &lt;b&gt;전체 애플리케이션을 확장해야&lt;/b&gt; 한다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;대규모 팀 작업의 어려움&lt;/b&gt;&lt;/span&gt; : 모든 팀이 동일한 코드, 동일한 프로젝트에서 작업하기 때문에, &lt;b&gt;코드 병합에 대한 충돌 가능성&lt;/b&gt;이 높고, 기능 변경 시 &lt;b&gt;다른 팀의 작업에 영향&lt;/b&gt;을 줄 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;기술 사용 제한&lt;/b&gt;&lt;/span&gt; : &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;모듈 간의 의존성이 매우 높아&lt;/b&gt;&lt;/span&gt;, 다른 기술 스택으로 변경하는 것이 매우 어렵다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;MSA(Micro Service Architecture)란?&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;애플리케이션을 작은 서비스로 분할하고, 각 서비스가 서로 독립적(느슨한 결합)&lt;/b&gt;&lt;/span&gt;이므로 기술 및 의존성에 구애 받을 확률이 낮다. 또한, &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;각 서비스 별로 고유한 데이터베이스를 소유&lt;/b&gt;&lt;/span&gt;할 수 있으며, 그로 인해 많은 이점도 제공하지만, 여러 문제와 복잡성 또한 수반하게 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;740&quot; data-origin-height=&quot;664&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mvobt/btsBZElb7oX/fxqPnZTXK1gbaDLX3dVX60/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mvobt/btsBZElb7oX/fxqPnZTXK1gbaDLX3dVX60/img.png&quot; data-alt=&quot;MSA 아키텍처의 다이어그램&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mvobt/btsBZElb7oX/fxqPnZTXK1gbaDLX3dVX60/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fmvobt%2FbtsBZElb7oX%2FfxqPnZTXK1gbaDLX3dVX60%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;595&quot; height=&quot;534&quot; data-origin-width=&quot;740&quot; data-origin-height=&quot;664&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;MSA 아키텍처의 다이어그램&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;MSA의 장점&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;유연한 확장성(Scale 측면)&lt;/b&gt;&lt;/span&gt; : 각각의 마이크로 서비스는 서로 독립적이므로, &lt;b&gt;매우 유연한 확장이 가능&lt;/b&gt;하다. 또한 이는 애플리케이션의 &lt;b&gt;고가용성이 필요할 때 매우 유용&lt;/b&gt;하게 된다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;독립적인 배포&lt;/b&gt;&lt;/span&gt; : 마이크로 서비스는 서로 느슨하게 결합되어 있으므로, &lt;b&gt;하나의 마이크로 서비스만 배포할 수 있다&lt;/b&gt;. 수정 사항이 생겼을 때, &lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;전체 애플리케이션의 작동을 멈출 필요가 없게 되는 것&lt;/b&gt;&lt;/span&gt;이다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;SPOF 제거&lt;/b&gt;&lt;/span&gt; : 애플리케이션을 &lt;b&gt;여러 소규모 서비스로 분할&lt;/b&gt;하여, 전체에 영향을 미치는 단일 실패 지점을 제거할 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;서로 다른 DB 소유 가능&lt;/b&gt;&lt;/span&gt; : 각 마이크로 서비스의 특징에 따라, RDBMS가 적합할 수도 있고, NoSQL이 적합할 수도 있다. 이러한 &lt;b&gt;각 서비스에 적합한 DB와 연결&lt;/b&gt;하여 서비스의 유연한 변화 및 확장을 가져갈 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;다양한 기술 스택 사용 가능&lt;/b&gt; &lt;/span&gt;: 하나의 프로젝트가 아니기 때문에, &lt;b&gt;서로 다른 언어를 사용&lt;/b&gt;하여 개발할 수 있게 된다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;민첩성&lt;/b&gt; &lt;/span&gt;: 전체 애플리케이션에 큰 영향을 주지 않고, 새로운 것을 추가할 수 있어, &lt;b&gt;새 버전을 배포하는 것이 매우 쉽다.&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;MSA의 단점&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;개발 환경의 뒷받침&lt;/b&gt;&lt;/span&gt; : 여러 개의 마이크로 서비스 중 하나에 새로운 기능을 구현해야 할 때, 다른 서비스에 접근할 수 있도록 &lt;b&gt;개발환경(로컬)에서 많은 애플리케이션을 실행할 수 있는 환경&lt;/b&gt;이 갖춰져야 한다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;디버깅의 어려움&lt;/b&gt;&lt;/span&gt; : 디버깅 및 테스트 시, &lt;b&gt;둘 이상의 마이크로 서비스를 실행해야 할 수 있어&lt;/b&gt;, 이 부분이 어려울 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;개발의 어려움&lt;/b&gt;&lt;/span&gt; : 마이크로 서비스 간의 통신에서 &lt;b&gt;동기/비동기 방식의 통신&lt;/b&gt;을 고려하고, 다양한 Workflow 및 시나리오에서의 &lt;b&gt;오류 처리&lt;/b&gt;, &lt;b&gt;중앙화된 모니터링&lt;/b&gt; 체계의 필요성, &lt;b&gt;오류 식별의 어려움&lt;/b&gt; 등이 있을 수 있어, 개발하는 동안에 &lt;b&gt;복잡성이 증가&lt;/b&gt;한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기까지 애플리케이션 개발 및 유지 보수에 대한 측면, 즉, 개발자의 입장에서 모놀리식 아키텍처와 MSA의 아키텍처를 이해했다면, 이제 &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;인프라 엔지니어의 입장&lt;/b&gt;&lt;/span&gt;에서 생각해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt;&amp;ldquo;MSA, 좋다 이거야. 근데 그렇게 잘게 잘게 쪼개 놓은 서비스들을 올릴 서버는 다 어떻게 만들고 관리하라고?&amp;rdquo;&lt;/b&gt;&lt;/i&gt; 라는 문제를 인프라 엔지니어가 해결해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소규모의 마이크로 서비스들을 하나의 물리적 서버에 모두 올리자니, 이건 MSA의 최대 장점인 유연한 확장성을 없애버리는 것이고, 그렇다고 각 서비스마다 VM을 만들자니, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;불필요한 OS 관리 포인트(취약성 패치 등..)와 OS가 차지하는 리소스와 오버헤드가 과도하게 증가&lt;/b&gt;&lt;/span&gt;하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 문제의 해결책으로, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;한 물리적 서버에 대해서(하나의 OS 안에서) 각 서비스별로 독립된 공간을 만들어보자&lt;/b&gt;&lt;/span&gt;는 아이디어가 나오고, 이는 곧 &lt;b&gt;컨테이너의 등장&lt;/b&gt;이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(물론, 컨테이너의 등장 배경은, 정확히 이러한 문제보다는 애플리케이션 개발과 운영 간 간극을 최소한으로 좁히고, 이를 이미지로 관리하기 위함이라는 게 더 옳은 듯 하다.)&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;컨테이너(Container)란?&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;b&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;어떤 환경에서나 실행하기 위해 필요한 모든 요소를 포함하는 소프트웨어 패키지&lt;/span&gt;&lt;/b&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OS를 가상화하여 프라이빗 데이터 센터에서 퍼블릭 클라우드 또는 개발자의 개인 노트북에 이르기까지 어디서나 실행이 가능하다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;832&quot; data-origin-height=&quot;377&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b7VJcb/btsBXGRRV1p/aunGgqWpNuVLjWN8fEMZa0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b7VJcb/btsBXGRRV1p/aunGgqWpNuVLjWN8fEMZa0/img.png&quot; data-alt=&quot;왼쪽: Virtual Machine / 오른쪽 : Container (Docker 예시)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b7VJcb/btsBXGRRV1p/aunGgqWpNuVLjWN8fEMZa0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb7VJcb%2FbtsBXGRRV1p%2FaunGgqWpNuVLjWN8fEMZa0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;583&quot; height=&quot;264&quot; data-origin-width=&quot;832&quot; data-origin-height=&quot;377&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;왼쪽: Virtual Machine / 오른쪽 : Container (Docker 예시)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;컨테이너의 장점&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;책임 분리&lt;/b&gt;&lt;/span&gt; : 컨테이너화를 통해 개발자와 운영팀의 책임을 분리함으로써, &lt;b&gt;각자가 잘하는 것에 더 집중&lt;/b&gt;할 수 있게 된다. &lt;b&gt;개발자&lt;/b&gt;는 컨테이너에 함께 &lt;b&gt;빌드할 애플리케이션의 로직과 종속 관계&lt;/b&gt;에 집중하고, &lt;br /&gt;&lt;b&gt;운영팀&lt;/b&gt;은 특정 소프트웨어 버전 및 구성과 같은 애플리케이션의 세부 요소 대신 &lt;b&gt;배포 및 관리&lt;/b&gt;에 집중할 수 있게 된다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;Workload 이동성&lt;/b&gt;&lt;/span&gt; : 컨테이너는 Linux, Windows, Mac 등의 &lt;b&gt;OS를 가지리 않고&lt;/b&gt;, VM, 물리적 서버, 개발자 컴퓨터, 데이터 센터, 온프레미스 환경, 퍼블릭 클라우드 등&lt;b&gt; 사실상 어느 환경에서나 구동&lt;/b&gt;되므로, 개발 및 배포가 매우 쉬워지게 된다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;애플리케이션 격리&lt;/b&gt;&lt;/span&gt; : 컨테이너는 OS 수준에서 &lt;b&gt;CPU, 메모리, 스토리지, 네트워크 리소스를 가상화&lt;/b&gt;하므로, 개발자에게 다른 애플리케이션으로부터 논리적으로 격리된 OS 환경을 제공한다. 즉, 다&lt;b&gt;른 컨테이너의 과부하로 인해 내 컨테이너가 죽는 경우를 보지 않아도 된다.&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;컨테이너의 단점&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;모든 컨테이너는 동일한 OS에서 실행되어야&lt;/b&gt;&lt;/span&gt; 하며, OS 또는 버전을 조합해서 사용할 수 없는 게 관리 Point 면에서는 장점이 될 수 있지만, &lt;b&gt;거대한 시스템에 대해 다양한 환경으로 운영할 수 없다&lt;/b&gt;는 게 단점으로 될 수 있겠다.&lt;/li&gt;
&lt;li&gt;컨테이너가 올라가는 &lt;b&gt;OS가 모든 컨테이너에 대해 공유&lt;/b&gt;되므로, &lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;VM보다 보안이 취약해질 수 있다.&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;MSA 아키텍처가 적용되지 않은 컨테이너&lt;/b&gt;는 이미지로 만들어 찍어낼 수 있다는(?) 장점 외에, &lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;비용 대비 VM과 견주어 우위에 있는 장점이 없어 보인다.&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MSA와 컨테이너의 공통되는 키워드는 결국 &amp;lsquo;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;경량화&lt;/b&gt;&lt;/span&gt;&amp;rsquo;이다. 애플리케이션 아키텍처도, 인프라 아키텍처도 결국&lt;b&gt; '커다란 문제를 해결하기 위해 작은 단위로 쪼개야 한다'&lt;/b&gt;는 IT의 보편적인 진리가 한번 더 통한 셈이다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면, 개발과 운영 업무를 하는 &lt;b&gt;문화에도 &amp;lsquo;경량화&amp;rsquo;란 게 있을까?&lt;/b&gt; 우리는 이를 &amp;lsquo;Agile&amp;rsquo; 방법론과 &amp;rsquo;DevOps&amp;rsquo; 문화라는 키워드로 살펴보기로 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;Agile 방법론이란?&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &amp;lsquo;Agile&amp;rsquo;이란, &lt;b&gt;&amp;lsquo;기민한, 민첩한&amp;rsquo;&lt;/b&gt; 이라는 뜻으로, &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;일정한 주기를 가지고 빠르게 제품을 출시하여 고객의 요구사항, 변화된 환경에 맞게 요구를 더하고 수정해 나가는 탄력적인 방법론&lt;/b&gt;&lt;/span&gt;을 말한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;840&quot; data-origin-height=&quot;472&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkggk1/btsBY27F2nR/sOIKiFn2qdoC0CdZxnp1kK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkggk1/btsBY27F2nR/sOIKiFn2qdoC0CdZxnp1kK/img.png&quot; data-alt=&quot;짧은 단위의 스프린트가 모여 스크럼 형태로 일하는 Agile 방법론&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkggk1/btsBY27F2nR/sOIKiFn2qdoC0CdZxnp1kK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbkggk1%2FbtsBY27F2nR%2FsOIKiFn2qdoC0CdZxnp1kK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;566&quot; height=&quot;318&quot; data-origin-width=&quot;840&quot; data-origin-height=&quot;472&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;짧은 단위의 스프린트가 모여 스크럼 형태로 일하는 Agile 방법론&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘날 많은 기업에서는 위 그림과 같은 &lt;b&gt;*스크럼 형태&lt;/b&gt;로 애자일 프로세스를 주로 활용하는데, 특징적인 것은 변화에 수동적으로 대처하기보다 &lt;b&gt;변화를 하나의 고정값으로 전제&lt;/b&gt;하여, &lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;1~4주라는 짧은 단위&lt;/span&gt;&lt;/b&gt;의&lt;b&gt; &lt;span style=&quot;color: #006dd7;&quot;&gt;스프린트 단위&lt;/span&gt;&lt;/b&gt;로 디자인,개발,테스트를 진행한다는 것이다. (&amp;rArr;경량화한 프로세스의 지속적인 반복)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;*스크럼&lt;/b&gt; : 비즈니스 요구를 충족시키는 데에 초점을 맞추기 위해, &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;작은 목표를 짧은 주기로 점진적이며 경험적으로 제품을 지속적으로 개발 및 전달하는 관리 프레임워크&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Agile 방법론의 등장배경&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IT 엔지니어라면, Agile하면 &lt;b&gt;Waterfall(폭포수) 방법론&lt;/b&gt;이 당연하게 떠오를 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Waterfall 방법론은 아래 그림과 같은 요구사항 정의 및 &lt;b&gt;서비스 설계 &amp;rarr; 디자인 &amp;rarr; 개발 &amp;rarr; 테스트 &amp;rarr; 배포&lt;/b&gt; 과정이 순차적으로 진행되며, &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;이전 단계가 완료된 후에야 그 다음 단계로 나아가게 된다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;817&quot; data-origin-height=&quot;433&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XYHnQ/btsBXJHQlmG/vKrZO9WV8OOuYZXnkP8up0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XYHnQ/btsBXJHQlmG/vKrZO9WV8OOuYZXnkP8up0/img.png&quot; data-alt=&quot;하나의 IT Product가 출시되기까지 심사숙고(?)하는 Waterfall 방법론&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XYHnQ/btsBXJHQlmG/vKrZO9WV8OOuYZXnkP8up0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXYHnQ%2FbtsBXJHQlmG%2FvKrZO9WV8OOuYZXnkP8up0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;553&quot; height=&quot;293&quot; data-origin-width=&quot;817&quot; data-origin-height=&quot;433&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;하나의 IT Product가 출시되기까지 심사숙고(?)하는 Waterfall 방법론&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방법의 장점으로는, 단계별로 업무를 분담하므로 &lt;b&gt;맡은 바가 명확&lt;/b&gt;하고, 계획 단계의 문서화로 &lt;b&gt;단계마다 소요되는 시간이나 현재 상황을 추적&lt;/b&gt;하고 &lt;b&gt;병목을 파악하기도 쉽다&lt;/b&gt;는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;위에서 물이 떨어질 때까지 마냥 기다리고 있어야&lt;/b&gt;&lt;/span&gt; 하니 &lt;b&gt;서비스 런칭까지의 속도가 매우 느리며&lt;/b&gt;, 떨어진 요구사항대로 기능을 만들었으나 느린 속도에 의해 수 개월이 지난 시점에 해당 서비스가 배포되고 나면, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;시장 상황은 이미 변해버려&lt;/b&gt;&lt;/span&gt; 더 이상 고객이 그 기능을 필요로 하지 않은 경우도 발생할 수 있다는 치명적인 단점을 가지고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;고객의 요구사항을 더 기민하게 대응하고 실현시키기 위한 방법론&lt;/b&gt;&lt;/span&gt;으로 Agile 방법론이 등장하게 되었다고 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Agile 소프트웨어 개발 방법론에서는 다음과 같은 &lt;b&gt;가치&lt;/b&gt;를 더 중요시 한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;과정에 대한 &lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;공정&lt;/b&gt;&lt;/span&gt;과 과정에 사용되는 &lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;도구&lt;/b&gt;&lt;/span&gt; 자체 &lt;b&gt;&amp;lt;&lt;/b&gt; &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;개인과의 상호작용, 커뮤니케이션&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;포괄적인 문서&lt;/b&gt;&lt;/span&gt; &amp;lt; &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;작동하는 소프트웨어&lt;/b&gt;&lt;/span&gt; 자체&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;계약 협상&lt;/b&gt;&lt;/span&gt;을 통한 이득 &amp;lt; &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;고객과의 협력&lt;/b&gt;&lt;/span&gt;을 통한 프로젝트 성공을 통한 이득&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;계획은 일단 따르는 것&lt;/b&gt;&lt;/span&gt; &amp;lt; 계획과 다르더라도 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;변화에 기민하고 유연하게 대응하는 것&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;DevOps란?&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;기존 개발팀과 운영팀 간의 Silo(사일로) 현상을 제거하는 소프트웨어 제공 접근 방식 또는 그러한 문화&lt;/b&gt;&lt;/span&gt;를 말한다. 이는 새로운 Tool과 문화를 통해 코드 배포 또는 인프라 프로비저닝과 같이 &lt;b&gt;수동적이고 느리던 기존 프로세스에 대해 자동화&lt;/b&gt;하는 것을 목표로 한다. 이러한 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;자동화를 통해 애플리케이션 및 서비스를 신속하게 제공할 수 있는 조직의 능력 향상&lt;/b&gt;&lt;/span&gt;이라는 방향성을 가지는 문화라고 볼 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;697&quot; data-origin-height=&quot;247&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/boxWqw/btsBRRUEaZm/DuCGvkXS57675cz2TPdor1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/boxWqw/btsBRRUEaZm/DuCGvkXS57675cz2TPdor1/img.png&quot; data-alt=&quot;선순환(?) 고리를 통한 IT Product의 지속적인 개선을 지향하는 DevOps&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/boxWqw/btsBRRUEaZm/DuCGvkXS57675cz2TPdor1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FboxWqw%2FbtsBRRUEaZm%2FDuCGvkXS57675cz2TPdor1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;556&quot; height=&quot;197&quot; data-origin-width=&quot;697&quot; data-origin-height=&quot;247&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;선순환(?) 고리를 통한 IT Product의 지속적인 개선을 지향하는 DevOps&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;DevOps 등장 배경&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나의 IT Product를 출시하기 위해서는, &lt;b&gt;프로젝트를 개발하고, 빌드하고, 테스트하고, 배포하고, 운영&lt;/b&gt;하는 등의 업무가 필요한데, 보통 지금까지의 회사들은 이를 &lt;u&gt;개발팀과 운영팀으로 나누어 수행해왔다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시스템 간 연결이 점점 더 복잡해지고, 그에 따른 필요한 기술과 고객의 요구사항이 지속적으로 변화해 감에 따라, 한 IT Product를 출시하고 운영하는 데에 있어서 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;같은 방향을 바라봐야할 IT팀 내에서도, 개발팀과 운영팀 간의 소통은 매우 어려워져 갔다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;사일로 현상을 타파&lt;/b&gt;&lt;/span&gt;하고, 개발팀과 운영팀 간의 협력과 통합을 강조하며, &amp;ldquo;&lt;i&gt;&lt;b&gt;개발팀처럼 생각하는 운영팀, 운영팀처럼 생각하는 개발팀&amp;rdquo;&lt;/b&gt;&lt;/i&gt;이라는 슬로건을 통해, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;개발과 운영이 하나의 파이프라인으로 통합&lt;/b&gt;&lt;/span&gt;되어, IT Product의 품질 향상과 고객 요구사항을 더 기민하게 만족시키자는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;번외 - Agile과 DevOps의 구분?&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필자는 DevOps라는 문화 자체가 Agile 방법론을 IT 실무적으로 좀 더 효율적으로 수행하기 위한 구체적인 방법론 또는 문화라고 생각하기에 둘의 차이점에 대해 굳이 알고 싶지는 않지만,&lt;b&gt; &lt;br /&gt;Agile&lt;/b&gt;은 &lt;b&gt;고객과의 상호 작용&lt;/b&gt;에, &lt;br /&gt;&lt;b&gt;DevOps&lt;/b&gt;는 개&lt;b&gt;발팀과 운영팀 간의 긴밀한 협력 관계 구축&lt;/b&gt;에 집중한다는 포인트로 접근하면 좋을 듯 하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 이 두 용어가 추구하는 공통적인 가치는, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;공유/개방성/자율성&lt;/b&gt;&lt;/span&gt; 및 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;소통&lt;/b&gt;&lt;/span&gt;과 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;협력&lt;/b&gt;&lt;/span&gt;을 매우 중요시하며, &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;경량화&lt;/b&gt; &lt;/span&gt;및 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;MVP 모델&lt;/b&gt;&lt;/span&gt;을 지향하고, 절차와 프로세스보다는 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;Fast Fail&lt;/b&gt;&lt;/span&gt; 및 이에 대한 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;피드백&lt;/b&gt;&lt;/span&gt;에 대한 반복을 통한&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt; &lt;br /&gt;지속적인 개선과 변화&lt;/b&gt;&lt;/span&gt;를 장려한다는 것에 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://yozm.wishket.com/magazine/detail/1813/&quot;&gt;https://yozm.wishket.com/magazine/detail/1813/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1702481307890&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;모놀리식 vs 마이크로서비스, 어떤 아키텍처를 선택할까? | 요즘IT&quot; data-og-description=&quot;모놀리식 애플리케이션은 소프트웨어 개발을 위한 기본 접근 방식이다. 그렇다면 마이크로서비스가 대세가 된 현재 모놀리식 접근 방식을 버려야 할까? 만약 모놀리식 애플리케이션에서 마이&quot; data-og-host=&quot;yozm.wishket.com&quot; data-og-source-url=&quot;https://yozm.wishket.com/magazine/detail/1813/&quot; data-og-url=&quot;https://yozm.wishket.com/magazine/detail/1813/yozm.wishket.com/magazine/detail/1813/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b8GNxT/hyULV988iW/wO7lJiKIFVbVJSNbVO0tgK/img.png?width=1200&amp;amp;height=700&amp;amp;face=0_0_1200_700,https://scrap.kakaocdn.net/dn/b0D4Ld/hyULYsfORB/EOKzmQM7Q24uc2R1kxCkh0/img.png?width=1200&amp;amp;height=700&amp;amp;face=0_0_1200_700&quot;&gt;&lt;a href=&quot;https://yozm.wishket.com/magazine/detail/1813/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://yozm.wishket.com/magazine/detail/1813/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b8GNxT/hyULV988iW/wO7lJiKIFVbVJSNbVO0tgK/img.png?width=1200&amp;amp;height=700&amp;amp;face=0_0_1200_700,https://scrap.kakaocdn.net/dn/b0D4Ld/hyULYsfORB/EOKzmQM7Q24uc2R1kxCkh0/img.png?width=1200&amp;amp;height=700&amp;amp;face=0_0_1200_700');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;모놀리식 vs 마이크로서비스, 어떤 아키텍처를 선택할까? | 요즘IT&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;모놀리식 애플리케이션은 소프트웨어 개발을 위한 기본 접근 방식이다. 그렇다면 마이크로서비스가 대세가 된 현재 모놀리식 접근 방식을 버려야 할까? 만약 모놀리식 애플리케이션에서 마이&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;yozm.wishket.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;http://www.itdaily.kr/news/articleView.html?idxno=208378&quot;&gt;http://www.itdaily.kr/news/articleView.html?idxno=208378&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1702481305851&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[전문가 강좌] MSA와 애자일(Agile) - 아이티데일리&quot; data-og-description=&quot;[아이티데일리] 1960년대 최초의 단지형 아파트인 마포아파트는 6층이었다. 시간이 지나면서 건축공법, 재료, 도구들이 발전하여 이제는 100층이 넘는 초고층의 빌딩을 지으면서도 에너지와 관리 &quot; data-og-host=&quot;www.itdaily.kr&quot; data-og-source-url=&quot;http://www.itdaily.kr/news/articleView.html?idxno=208378&quot; data-og-url=&quot;http://www.itdaily.kr/news/articleView.html?idxno=208378&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/Dtjxa/hyUL6qjJ6t/MioDGvQoOpv8tLkv8BrYW0/img.png?width=200&amp;amp;height=257&amp;amp;face=36_84_151_210,https://scrap.kakaocdn.net/dn/Xiltf/hyULRNsda9/urnN7ONSKGBe9dpJ1uWWB1/img.jpg?width=600&amp;amp;height=514&amp;amp;face=0_0_600_514,https://scrap.kakaocdn.net/dn/dFbXAI/hyUL6w4K2t/kOa6wqWSydUbNw0MLIK8bK/img.png?width=504&amp;amp;height=355&amp;amp;face=0_0_504_355&quot;&gt;&lt;a href=&quot;http://www.itdaily.kr/news/articleView.html?idxno=208378&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;http://www.itdaily.kr/news/articleView.html?idxno=208378&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/Dtjxa/hyUL6qjJ6t/MioDGvQoOpv8tLkv8BrYW0/img.png?width=200&amp;amp;height=257&amp;amp;face=36_84_151_210,https://scrap.kakaocdn.net/dn/Xiltf/hyULRNsda9/urnN7ONSKGBe9dpJ1uWWB1/img.jpg?width=600&amp;amp;height=514&amp;amp;face=0_0_600_514,https://scrap.kakaocdn.net/dn/dFbXAI/hyUL6w4K2t/kOa6wqWSydUbNw0MLIK8bK/img.png?width=504&amp;amp;height=355&amp;amp;face=0_0_504_355');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[전문가 강좌] MSA와 애자일(Agile) - 아이티데일리&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;[아이티데일리] 1960년대 최초의 단지형 아파트인 마포아파트는 6층이었다. 시간이 지나면서 건축공법, 재료, 도구들이 발전하여 이제는 100층이 넘는 초고층의 빌딩을 지으면서도 에너지와 관리&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.itdaily.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://cloud.google.com/learn/what-are-containers?hl=ko&quot;&gt;https://cloud.google.com/learn/what-are-containers?hl=ko&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1702481312129&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;컨테이너란? &amp;nbsp;|&amp;nbsp; Google Cloud&quot; data-og-description=&quot;컨테이너는 어떤 환경에서나 실행하기 위해 필요한 모든 요소를 포함하는 경량 소프트웨어 패키지입니다.&quot; data-og-host=&quot;cloud.google.com&quot; data-og-source-url=&quot;https://cloud.google.com/learn/what-are-containers?hl=ko&quot; data-og-url=&quot;https://cloud.google.com/learn/what-are-containers?hl=ko&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b76Y9Y/hyUL465wLY/588yksGPqWYw4t93Kphvak/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://cloud.google.com/learn/what-are-containers?hl=ko&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://cloud.google.com/learn/what-are-containers?hl=ko&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b76Y9Y/hyUL465wLY/588yksGPqWYw4t93Kphvak/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;컨테이너란? &amp;nbsp;|&amp;nbsp; Google Cloud&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;컨테이너는 어떤 환경에서나 실행하기 위해 필요한 모든 요소를 포함하는 경량 소프트웨어 패키지입니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;cloud.google.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.vmware.com/kr/topics/glossary/content/vms-vs-containers.html?resource=cat-1065884937#cat-1065884937&quot;&gt;https://www.vmware.com/kr/topics/glossary/content/vms-vs-containers.html?resource=cat-1065884937#cat-1065884937&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1702481313787&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;Website&quot; data-og-title=&quot;Why use containers vs. VMs? | VMware Glossary&quot; data-og-description=&quot;Virtual Machines (VMs) and containers are complimentary and similar &amp;ndash; both improve IT efficiency, application portability, and enhance DevOps.&quot; data-og-host=&quot;www.vmware.com&quot; data-og-source-url=&quot;https://www.vmware.com/kr/topics/glossary/content/vms-vs-containers.html?resource=cat-1065884937#cat-1065884937&quot; data-og-url=&quot;https://www.vmware.com/topics/glossary/content/vms-vs-containers&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/oA1JW/hyULVWBvQa/zHgMuTcZE0CHb2MhvKx3n1/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400,https://scrap.kakaocdn.net/dn/ZfLY1/hyUL5rnfvj/u0Ot4AW07kJwwocRmhatfk/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400&quot;&gt;&lt;a href=&quot;https://www.vmware.com/kr/topics/glossary/content/vms-vs-containers.html?resource=cat-1065884937#cat-1065884937&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.vmware.com/kr/topics/glossary/content/vms-vs-containers.html?resource=cat-1065884937#cat-1065884937&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/oA1JW/hyULVWBvQa/zHgMuTcZE0CHb2MhvKx3n1/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400,https://scrap.kakaocdn.net/dn/ZfLY1/hyUL5rnfvj/u0Ot4AW07kJwwocRmhatfk/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Why use containers vs. VMs? | VMware Glossary&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Virtual Machines (VMs) and containers are complimentary and similar &amp;ndash; both improve IT efficiency, application portability, and enhance DevOps.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.vmware.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.codestates.com/blog/content/애자일방법론-워터폴방법론&quot;&gt;https://www.codestates.com/blog/content/애자일방법론-워터폴방법론&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1702481310838&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;애자일과 워터폴 방법론 비교 | 정의, 차이, 장단점, 적합한 조직 - 코드스테이츠 공식 블로그&quot; data-og-description=&quot;애자일 방법론의 출발은 소프트웨어 개발 방식이었지만 이제는 제품 개발을 넘어 하나의 일하는 방식, 워크플로우로 자리 잡았습니다. 대표적인 프로덕트 개발 방법론인 애자일 방법론을 소개&quot; data-og-host=&quot;www.codestates.com&quot; data-og-source-url=&quot;https://www.codestates.com/blog/content/애자일방법론-워터폴방법론&quot; data-og-url=&quot;https://www.codestates.com/blog/content/애자일방법론-워터폴방법론&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/7EXWE/hyUL0XTAum/Krfq7WIJ9kJ7RCO6nQb0pk/img.jpg?width=1546&amp;amp;height=1000&amp;amp;face=0_0_1546_1000,https://scrap.kakaocdn.net/dn/kY8qb/hyUL5Ze6SV/TKnYsdUec37kLWZIoOaGT1/img.jpg?width=1546&amp;amp;height=1000&amp;amp;face=0_0_1546_1000&quot;&gt;&lt;a href=&quot;https://www.codestates.com/blog/content/애자일방법론-워터폴방법론&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.codestates.com/blog/content/애자일방법론-워터폴방법론&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/7EXWE/hyUL0XTAum/Krfq7WIJ9kJ7RCO6nQb0pk/img.jpg?width=1546&amp;amp;height=1000&amp;amp;face=0_0_1546_1000,https://scrap.kakaocdn.net/dn/kY8qb/hyUL5Ze6SV/TKnYsdUec37kLWZIoOaGT1/img.jpg?width=1546&amp;amp;height=1000&amp;amp;face=0_0_1546_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;애자일과 워터폴 방법론 비교 | 정의, 차이, 장단점, 적합한 조직 - 코드스테이츠 공식 블로그&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;애자일 방법론의 출발은 소프트웨어 개발 방식이었지만 이제는 제품 개발을 넘어 하나의 일하는 방식, 워크플로우로 자리 잡았습니다. 대표적인 프로덕트 개발 방법론인 애자일 방법론을 소개&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.codestates.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://engineering-skcc.github.io/devops/DevOps1-애자일과데브옵스/&quot;&gt;https://engineering-skcc.github.io/devops/DevOps1-애자일과데브옵스/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1702481311653&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;데브옵스 알아가기(1) : 애자일과 데브옵스&quot; data-og-description=&quot;애자일과 데브옵스의 차이는 무엇일까요?&quot; data-og-host=&quot;engineering-skcc.github.io&quot; data-og-source-url=&quot;https://engineering-skcc.github.io/devops/DevOps1-애자일과데브옵스/&quot; data-og-url=&quot;https://engineering-skcc.github.io/devops/DevOps1-%EC%95%A0%EC%9E%90%EC%9D%BC%EA%B3%BC%EB%8D%B0%EB%B8%8C%EC%98%B5%EC%8A%A4/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bhTCiS/hyUL6cNTdp/kpCAEY3SJSvnrlcirK50pk/img.png?width=1756&amp;amp;height=746&amp;amp;face=0_0_1756_746,https://scrap.kakaocdn.net/dn/scMy2/hyUL0Q9bFI/7pkyQ67D9McJMuvzVrrc50/img.png?width=1310&amp;amp;height=448&amp;amp;face=0_0_1310_448,https://scrap.kakaocdn.net/dn/nnXyH/hyUL7iwGFx/c1nynac9GdHNum7GsDSzxk/img.png?width=1326&amp;amp;height=406&amp;amp;face=0_0_1326_406&quot;&gt;&lt;a href=&quot;https://engineering-skcc.github.io/devops/DevOps1-애자일과데브옵스/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://engineering-skcc.github.io/devops/DevOps1-애자일과데브옵스/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bhTCiS/hyUL6cNTdp/kpCAEY3SJSvnrlcirK50pk/img.png?width=1756&amp;amp;height=746&amp;amp;face=0_0_1756_746,https://scrap.kakaocdn.net/dn/scMy2/hyUL0Q9bFI/7pkyQ67D9McJMuvzVrrc50/img.png?width=1310&amp;amp;height=448&amp;amp;face=0_0_1310_448,https://scrap.kakaocdn.net/dn/nnXyH/hyUL7iwGFx/c1nynac9GdHNum7GsDSzxk/img.png?width=1326&amp;amp;height=406&amp;amp;face=0_0_1326_406');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;데브옵스 알아가기(1) : 애자일과 데브옵스&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;애자일과 데브옵스의 차이는 무엇일까요?&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;engineering-skcc.github.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>CS 지식 | 기초 용어,개념</category>
      <category>agile 방법론</category>
      <category>DevOps 문화</category>
      <category>IT Silo</category>
      <category>MSA 아키텍처</category>
      <category>모놀리식 아키텍처</category>
      <category>폭포수 방법론</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/154</guid>
      <comments>https://co-no.tistory.com/entry/%EA%B0%9C%EB%85%90-MSA-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88%EC%9D%98-%EB%93%B1%EC%9E%A5%EA%B3%BC-Agile-DevOps-%EB%AC%B8%ED%99%94%EB%8A%94-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80#entry154comment</comments>
      <pubDate>Thu, 14 Dec 2023 09:00:26 +0900</pubDate>
    </item>
    <item>
      <title>[httpd] Apache httpd의 로그 삭제 스크립트 및 crontab 등록하여 로그 파일 삭제 자동화하기</title>
      <link>https://co-no.tistory.com/entry/Apache-%EC%95%84%ED%8C%8C%EC%B9%98-httpd%EC%9D%98-%EB%A1%9C%EA%B7%B8-%EC%82%AD%EC%A0%9C-%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%B0%8F-crontab-%EB%93%B1%EB%A1%9D%ED%95%98%EC%97%AC-%EB%A1%9C%EA%B7%B8-%ED%8C%8C%EC%9D%BC-%EC%82%AD%EC%A0%9C-%EC%9E%90%EB%8F%99%ED%99%94%ED%95%98%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;apache httpd를 apachctl -k start 명령어로 실행하면, 다음과 같이 rotatelogs 플래그가 붙어서 실행되는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1380&quot; data-origin-height=&quot;93&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QXDXY/btsALWA18mA/d7pK3rUfkA5rQcrjdRFpPk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QXDXY/btsALWA18mA/d7pK3rUfkA5rQcrjdRFpPk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QXDXY/btsALWA18mA/d7pK3rUfkA5rQcrjdRFpPk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQXDXY%2FbtsALWA18mA%2Fd7pK3rUfkA5rQcrjdRFpPk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2046&quot; height=&quot;138&quot; data-origin-width=&quot;1380&quot; data-origin-height=&quot;93&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;rotatelogs는 apache httpd 패키지에 포함되어 있는 logrotate 바이너리인데, 문제는 이 녀석이 자동으로 삭제는 지원을 안 하는 듯 하다. (&lt;i&gt;&lt;s&gt;아니 이걸 왜 안함? ㅡㅡ&lt;/s&gt;&lt;/i&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 간혹 아파치 웹서버 로그 파일들 때문에 스토리지가 Full 나버려서 장애가 발생하는 경우가 있으니, 아파치 웹서버를 사용하는 환경에서는 반드시 아래 스크립트를 작성하고 crontab을 등록하여 로그가 쌓여 스토리지가 Full 나버리는 상황을 예방해보자.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;30일 이상 지난 로그 파일 삭제하는 스크립트 작성 - '&lt;span style=&quot;color: #409d00;&quot;&gt;Delete_Log.sh&lt;/span&gt;'&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1700635533404&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#!/bin/sh

# 필자의 경우, httpd 로그 파일이 저장되는 경로가 /etc/apache/logs 라고 가정하였다.
# 필자의 경우, 로그 파일명이 '애플리케이션명_log.날짜' 와 같은 형태임을 유의하자.
# 최근 수정 날짜가 30일 이상인 파일들을 find 하고 해당 파일들에 rm 명령어를 수행한다.
/usr/bin/find /etc/apache/logs/ -name '*log.*' -mtime +30 | xargs -r rm&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;xargs &lt;b&gt;-r&lt;/b&gt; : 표준 입력이 empty일 경우, 뒤에 오는 command를 수행하지 않도록 하는 옵션&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;작성한 스크립트 파일의 파일 권한을 실행할 수 있도록 수정 (예시는 root 계정만 수행할 수 있도록 설정)&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1700635640360&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;chmod 744 Delete_Log.sh&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;작성한 스크립트 파일을 crontab에 등록&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;crontab에 등록함으로써, OS 상에서 지정한 스케줄에 맞춰 자동으로 해당 스크립트가 수행되도록 설정한다.&lt;/p&gt;
&lt;pre id=&quot;code_1700635827019&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# crontab 등록 명령어
crontab -e

# 위 명령어 수행 결과로 나타나는 editor에서 다음 내용을 기입후 저장(:wq)
# '0 0 * * *'은 매일 00시 00분에 해당 명령을 수행한다는 의미
0 0 * * * {Delete_Log.sh 파일 위치}/Delete_Log.sh

# 위 editor를 빠져나온 후에 아래 명령어 수행하여 등록된 crontab 리스트 조회
crontab -l&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Middleware/웹서버</category>
      <category>Apache roglotate 파일 삭제</category>
      <category>Apache 로그 자동 삭제</category>
      <category>httpd 로그 자동 삭제</category>
      <category>httpd 로그 정기 삭제</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/153</guid>
      <comments>https://co-no.tistory.com/entry/Apache-%EC%95%84%ED%8C%8C%EC%B9%98-httpd%EC%9D%98-%EB%A1%9C%EA%B7%B8-%EC%82%AD%EC%A0%9C-%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%B0%8F-crontab-%EB%93%B1%EB%A1%9D%ED%95%98%EC%97%AC-%EB%A1%9C%EA%B7%B8-%ED%8C%8C%EC%9D%BC-%EC%82%AD%EC%A0%9C-%EC%9E%90%EB%8F%99%ED%99%94%ED%95%98%EA%B8%B0#entry153comment</comments>
      <pubDate>Wed, 22 Nov 2023 15:56:59 +0900</pubDate>
    </item>
    <item>
      <title>[Nginx] http &amp;rarr; https 리다이렉션 및 SSL 인증서 적용 (Nginx ver.1.20.1 기준)</title>
      <link>https://co-no.tistory.com/entry/Nginx-http-%E2%86%92-https-%EB%A6%AC%EB%8B%A4%EC%9D%B4%EB%A0%89%EC%85%98-%EB%B0%8F-SSL-%EC%9D%B8%EC%A6%9D%EC%84%9C-%EC%A0%81%EC%9A%A9-Nginx-ver1201-%EA%B8%B0%EC%A4%80</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CSR을 만들고 SSL 인증서 파일을 발급 받는 과정&lt;/b&gt;은 무사히 마쳤다고 생각하고 &lt;b&gt;생략&lt;/b&gt;하기로 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필자는 기관에 요청하여 받은 인증서 파일이 &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;base64 방식&lt;/b&gt;&lt;/span&gt;으로 인코딩된 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;.p7b&lt;/b&gt;&lt;/span&gt; 파일과 &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;DER&lt;/b&gt;&lt;/span&gt; 방식으로 인코딩된 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;.cer&lt;/b&gt;&lt;/span&gt; 파일로 2개였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;둘 중에 하나로 원하는 걸 사용하면 되고, 두 인증서 포맷은 다음과 같은 특징이 있으므로, 참고하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, 다양한 인증서 관련 파일 포맷에 대한 설명이 아래 링크에 있으니, 확인하면 되겠다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;.p7b&lt;/b&gt;&lt;/span&gt; 확장자
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;PKCS#7&lt;/b&gt; 포맷&lt;/li&gt;
&lt;li&gt;[&lt;b&gt;&amp;lsquo;서버 인증서&amp;rsquo;&lt;/b&gt; + &lt;b&gt;&amp;lsquo;Root 인증서&amp;rsquo;&lt;/b&gt; + &lt;b&gt;&amp;lsquo;Chain 인증서&amp;rsquo;&lt;/b&gt;] 를 모두 담을 수 있어, SSL 인증서 적용 또는 이전 시에 상당히 유용하고 편리&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Windows&lt;/b&gt; 에서는 자동 인식, &lt;b&gt;일부 서버에서는 p7b 포맷으로만&lt;/b&gt; 인증서 설정이 되는 경우도 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;인증서 내 private key 는 포함 X&lt;/b&gt;. key 파일에 대한 설정(nginx 에서는 &lt;b&gt;&amp;lsquo;ssl_certificate_key&amp;rsquo;&lt;/b&gt; 구문)은 별도의 키 파일로 잡아주어야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;.cer&lt;/b&gt;&lt;/span&gt; 확장자
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Windows&lt;/b&gt; 에서는 기본 인식되는 확장자&lt;/li&gt;
&lt;li&gt;대부분 &lt;b&gt;PEM&lt;/b&gt; 포맷이나, &lt;b&gt;Binary&lt;/b&gt; 포맷일 때도 있음&lt;/li&gt;
&lt;li&gt;주로 Windows 기반에서 인증서 파일임을 구분하기 위해서 사용되는 확장자&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;.crt&lt;/b&gt; &lt;/span&gt;확장자와 거의 동일한 의미&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.sslcert.co.kr/guides/kb/54&quot;&gt;SSL 인증서 파일 포맷 종류 - crt, cer, csr, pem, der, pfx, p12, p7b, jks, key - SecureSign&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1698876447838&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;SSL 인증서 파일 포맷 종류 - crt, cer, csr, pem, der, pfx, p12, p7b, jks, key - SecureSign&quot; data-og-description=&quot;SSL 인증서 파일 포맷 종류 - crt, cer, csr, pem, der, pfx, p12, p7b, jks, key - SecureSign&quot; data-og-host=&quot;www.sslcert.co.kr&quot; data-og-source-url=&quot;https://www.sslcert.co.kr/guides/kb/54&quot; data-og-url=&quot;https://www.sslcert.co.kr/guides/kb/54&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/4b2kT/hyUnOcQhMe/QRJNrohdA0sS3hRVcP2Shk/img.png?width=300&amp;amp;height=300&amp;amp;face=0_0_300_300,https://scrap.kakaocdn.net/dn/NN39m/hyUnKO3FKq/fLudvtcqtWSrn1yFPLVfv0/img.png?width=300&amp;amp;height=300&amp;amp;face=0_0_300_300&quot;&gt;&lt;a href=&quot;https://www.sslcert.co.kr/guides/kb/54&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.sslcert.co.kr/guides/kb/54&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/4b2kT/hyUnOcQhMe/QRJNrohdA0sS3hRVcP2Shk/img.png?width=300&amp;amp;height=300&amp;amp;face=0_0_300_300,https://scrap.kakaocdn.net/dn/NN39m/hyUnKO3FKq/fLudvtcqtWSrn1yFPLVfv0/img.png?width=300&amp;amp;height=300&amp;amp;face=0_0_300_300');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;SSL 인증서 파일 포맷 종류 - crt, cer, csr, pem, der, pfx, p12, p7b, jks, key - SecureSign&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;SSL 인증서 파일 포맷 종류 - crt, cer, csr, pem, der, pfx, p12, p7b, jks, key - SecureSign&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.sslcert.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;인증서 파일 확장자를 .p7b &amp;rarr; .pem 변환&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대부분의 글들이 .&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;pem&lt;/b&gt;&lt;/span&gt; 확장자 기준으로 설명하므로, 나도 혼란을 방지하기 위해 &lt;b&gt;.p7b &amp;rarr; .pem 변환&lt;/b&gt; 먼저 수행하겠다. &lt;b&gt;.p7b&lt;/b&gt; 확장자와 &lt;b&gt;.pem&lt;/b&gt; 확장자는 변환 시 100% 호환된다고 생각해도 무방할 듯 하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 명령어를 수행하여 확장자를 &lt;b&gt;.pem&lt;/b&gt; 으로 변환하자!&lt;/p&gt;
&lt;pre class=&quot;shell&quot; data-ke-language=&quot;shell&quot;&gt;&lt;code&gt;openssl pkcs7 -in [발급받은 .p7b 인증서] -out [.pem으로 만들 파일 이름.pem] -print_certs -text

# ex) openssl pkcs7 -in Issued_Cert.p7b -out Integrated_Cert.pem -print_certs -text&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;SSL 인증서(.pem 확장자 기준) 적용하기&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 변환된 .pem 파일과 CSR 발급 시 사용한 key 파일을 SSL 인증 옵션 구문에 함께 넣어주면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필자는 특정 사이트에 대한 server 옵션들을 모아둔 파일인 &lt;b&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;sites-available/{사이트명}&lt;/span&gt; 파일&lt;/b&gt;에 아래 구문을 넣었다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;server {
    listen      443 ssl;
    server_name Example.co.kr;

    ssl_certificate             [변환한 Cert 파일명.pem 파일 경로];
    ssl_certificate_key         [decrypted 키 파일명.key 파일 경로];

    ssl_session_timeout         5m;
		
    # SSL 취약성 제거 위한 설정
    ssl_protocols               SSLv3 TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers   on;
    ssl_ciphers                 HIGH:!aNULL:!MD5;

    location / {
        include proxy_params;
        # 동일 host 내의 gunicorn 서버로 request 전달하기 위함
        proxy_pass &amp;lt;http://unix&amp;gt;:{gunicorn의 unix .sock 파일 경로};
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 구문을 추가한 nginx site 설정 파일명을 &amp;lsquo;test_ssl&amp;rsquo; 이라고 가정하면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 명령어를 수행하여 &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;sites-available/test_ssl&lt;/b&gt;&lt;/span&gt; 사이트 설정 파일을 &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;sties-enabled/PRD&lt;/b&gt;&lt;/span&gt; 파일로 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;심볼릭 링크&lt;/b&gt;&lt;/span&gt;를 걸고, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;nginx 를 재기동&lt;/b&gt;&lt;/span&gt;하여 사이트 설정을 load하여 테스트 해보자.&lt;/p&gt;
&lt;pre class=&quot;shell&quot; data-ke-language=&quot;shell&quot;&gt;&lt;code&gt;# test_ssl -&amp;gt; PRD 심볼릭 링크
ln -s /etc/nginx/sites-available/test_ssl /etc/nginx/sites-enabled/PRD

# nginx 관련 파일 syntax 검사
nginx -t

# nginx 새로운 설정 적용 방법1 - 설정파일만 reload
nginx -s reload

# nginx 새로운 설정 적용 방법2 - nginx 재기동
systemctl restart nginx&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;http://{Domain Name}:443/&lt;/b&gt;&lt;/span&gt; 으로 접속했을 때, 이상 없이 해당 웹 사이트 접속이 된다면, SSL 인증서 설정이 문제 없이 적용 된 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 뭔가 문제가 생겼다면, &amp;lsquo;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;PRD&lt;/b&gt;&lt;/span&gt;&amp;rsquo; 심볼릭 링크를 제거하고, 기존의 site 설정 파일인 &lt;b&gt;&amp;lsquo;&lt;span style=&quot;color: #409d00;&quot;&gt;test_old&lt;/span&gt;&amp;rsquo;&lt;/b&gt; 파일로 다시 심볼릭 링크를 걸고, nginx 설정 파일을 리로드하여 롤백하면 된다.&lt;/p&gt;
&lt;pre class=&quot;shell&quot; data-ke-language=&quot;shell&quot;&gt;&lt;code&gt;# 새롭게 적용한 site 설정 파일인 'PRD' 심볼릭 링크 제거
rm /etc/sites-enabled/PRD

# 기존에 사용하던 site 설정 파일인 'test_old' 심볼릭 링크 걸기
ln -s /etc/sites-available/test_old /etc/sites-enabled/PRD

# nginx 설정 파일 리로드
nginx -s reload&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;http &amp;rarr; https 리다이렉션 설정하기&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SSL을 적용하였으니, 기존의 사이트 설정에 있는 &lt;b&gt;LISTEN 80 블록&lt;/b&gt;은 아래와 같이 변경해주어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필자의 경우, 아래와 같이 &lt;b&gt;servername {ip}&lt;/b&gt; 인 블럭과 &lt;b&gt;servername {domain name}&lt;/b&gt; 인 블럭 두 개를 설정하여,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;IP와 80 포트&lt;/b&gt;로 접속하는 경우, &lt;b&gt;domain name과 80포트&lt;/b&gt;로 접속하는 경우 모두를 &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;https://{domain-name}&lt;/b&gt;&lt;/span&gt; 으로 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;리다이렉션&lt;/b&gt;&lt;/span&gt; 하도록 설정하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로, &lt;b&gt;[::]&lt;/b&gt; 은,&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;shell&quot; data-ke-language=&quot;shell&quot;&gt;&lt;code&gt;# {IP}:80, {domain name}:80, www.{domain name}:80 으로 접속하는 경우 리다이렉션 설정
server {
    listen 80;

    server_name Example.co.kr www.Example.co.kr 10.123.123.123;

    return 301 https://Example.co.kr$request_uri;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 설정을 한 후, 다시 심볼릭 링크 및 nginx 설정 reload를 한 후에, &lt;b&gt;http://{IP}&lt;/b&gt;, &lt;b&gt;&lt;a href=&quot;http://Example.co.kr&quot;&gt;http://Example.co.kr&lt;/a&gt;&lt;/b&gt; 로 접속해서 &lt;b&gt;&lt;a href=&quot;https://Example.co.kr&quot;&gt;https://Example.co.kr&lt;/a&gt;&lt;/b&gt; 로 리다이렉션이 잘 되는 지 확인해보면 된다!&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://velog.io/@coastby/Nginx-SSL-%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://velog.io/@coastby/Nginx-SSL-%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0&lt;/a&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1698876735972&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[Nginx] SSL 적용하기&quot; data-og-description=&quot;SSL(Secure Socket Layer) 또는 TLS(Transport Layer Security)은 전송계층 상에서 클라이언트, 서버에 대한 인증 및 데이터 암호화를 수행한다. 클라이언트와 서버 양단 간 응용계층 및 TCP 전송계층 사이에서 &quot; data-og-host=&quot;velog.io&quot; data-og-source-url=&quot;https://velog.io/@coastby/Nginx-SSL-%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0&quot; data-og-url=&quot;https://velog.io/@coastby/Nginx-SSL-적용하기&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bQ1OHK/hyUnJCBTMc/k4mJPu2xlfRgn4ilt4Nko1/img.png?width=950&amp;amp;height=500&amp;amp;face=0_0_950_500,https://scrap.kakaocdn.net/dn/byoYsZ/hyUnRm55r5/evCAgueP1UKPR9oZsRyCf0/img.png?width=1200&amp;amp;height=1200&amp;amp;face=0_0_1200_1200,https://scrap.kakaocdn.net/dn/ZQeCG/hyUnKuKWTk/FDEdFcxk8baHdIFkmDJwt1/img.png?width=2000&amp;amp;height=629&amp;amp;face=0_0_2000_629&quot;&gt;&lt;a href=&quot;https://velog.io/@coastby/Nginx-SSL-%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://velog.io/@coastby/Nginx-SSL-%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bQ1OHK/hyUnJCBTMc/k4mJPu2xlfRgn4ilt4Nko1/img.png?width=950&amp;amp;height=500&amp;amp;face=0_0_950_500,https://scrap.kakaocdn.net/dn/byoYsZ/hyUnRm55r5/evCAgueP1UKPR9oZsRyCf0/img.png?width=1200&amp;amp;height=1200&amp;amp;face=0_0_1200_1200,https://scrap.kakaocdn.net/dn/ZQeCG/hyUnKuKWTk/FDEdFcxk8baHdIFkmDJwt1/img.png?width=2000&amp;amp;height=629&amp;amp;face=0_0_2000_629');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[Nginx] SSL 적용하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;SSL(Secure Socket Layer) 또는 TLS(Transport Layer Security)은 전송계층 상에서 클라이언트, 서버에 대한 인증 및 데이터 암호화를 수행한다. 클라이언트와 서버 양단 간 응용계층 및 TCP 전송계층 사이에서&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;velog.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.comodossl.co.kr/Certificate/ssl-installation-guides/Nginx.aspx&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.comodossl.co.kr/Certificate/ssl-installation-guides/Nginx.aspx&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1698876739615&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Nginx : 인증서 적용 - HanbiroSSL&quot; data-og-description=&quot;SSL 보안 서버 인증 가장 합리적인 가격의 Sectigo SSL 인증을 통해 귀사의 웹서버에 접속하는 회원들의 개인 정보를 안전하게 보호해 주시기 바랍니다. --&amp;gt; 본 가이드는 인증서 파일 설정시 참고 예&quot; data-og-host=&quot;www.comodossl.co.kr&quot; data-og-source-url=&quot;https://www.comodossl.co.kr/Certificate/ssl-installation-guides/Nginx.aspx&quot; data-og-url=&quot;https://www.comodossl.co.kr/Certificate/ssl-installation-guides/Nginx.aspx&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/k9NKk/hyUnXgy2pm/YBdGd90P8e25IHC53ETJX1/img.png?width=661&amp;amp;height=338&amp;amp;face=0_0_661_338&quot;&gt;&lt;a href=&quot;https://www.comodossl.co.kr/Certificate/ssl-installation-guides/Nginx.aspx&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.comodossl.co.kr/Certificate/ssl-installation-guides/Nginx.aspx&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/k9NKk/hyUnXgy2pm/YBdGd90P8e25IHC53ETJX1/img.png?width=661&amp;amp;height=338&amp;amp;face=0_0_661_338');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Nginx : 인증서 적용 - HanbiroSSL&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;SSL 보안 서버 인증 가장 합리적인 가격의 Sectigo SSL 인증을 통해 귀사의 웹서버에 접속하는 회원들의 개인 정보를 안전하게 보호해 주시기 바랍니다. --&amp;gt; 본 가이드는 인증서 파일 설정시 참고 예&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.comodossl.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Middleware/웹서버</category>
      <category>nginx 80 443 redirection</category>
      <category>nginx http https redirection</category>
      <category>nginx https</category>
      <category>p7b to pem</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/152</guid>
      <comments>https://co-no.tistory.com/entry/Nginx-http-%E2%86%92-https-%EB%A6%AC%EB%8B%A4%EC%9D%B4%EB%A0%89%EC%85%98-%EB%B0%8F-SSL-%EC%9D%B8%EC%A6%9D%EC%84%9C-%EC%A0%81%EC%9A%A9-Nginx-ver1201-%EA%B8%B0%EC%A4%80#entry152comment</comments>
      <pubDate>Fri, 3 Nov 2023 08:13:36 +0900</pubDate>
    </item>
    <item>
      <title>[Gunicorn] logrotate, crond를 활용한 nginx와 gunicorn의 log 파일 관리하기</title>
      <link>https://co-no.tistory.com/entry/gunicorn-logrotate-crond%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%9C-nginx%EC%99%80-gunicorn%EC%9D%98-log-%ED%8C%8C%EC%9D%BC-%EA%B4%80%EB%A6%AC%ED%95%98%EA%B8%B0</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;logrotate 란?&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Linux 환경에서 로그의 관리를 도와주는 CUI 기반의 도구이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자가 정한 &lt;b&gt;주기마다 쌓인 로그를 아카이빙&lt;/b&gt;, &lt;b&gt;아카이빙된 파일의 갯수를 일정 갯수로 제한&lt;/b&gt;하는 등의 로그 관리를 하여, &lt;u&gt;스토리지 용량이 부족해지는 등의 문제를 방지&lt;/u&gt;할 수 있도록 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;logrotate 자체는 daemon이 아닌, 로그의 관리를 도와주는 단순 실행파일이므로, 주기적으로 알아서 작업할 수 있는 능력이 없다. 따라서, 반드시 Linux 내의 &amp;lsquo;&lt;b&gt;crond&lt;/b&gt;&amp;rsquo; 와 같은 스케줄러 설정이 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt; /etc/logrotate.d&lt;/b&gt; &lt;/span&gt;디렉토리에 각 로그파일마다의 logrotate 설정에 대한 파일들이 있는데, 여기에 &amp;lsquo;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;nginx&lt;/b&gt;&lt;/span&gt;&amp;rsquo;, &amp;lsquo;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;{Gunicorn으로 구동할 APP 이름}&lt;/b&gt;&lt;/span&gt;&amp;rsquo; 으로 파일명을 하여 Nginx 및 Gunicorn 에 대한 logrotate 설정을 할 것이다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;Nginx logrotate 설정&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# /etc/logrotate.d/nginx 파일

/etc/nginx/log/*.log {
    daily
    dateext
    dateyesterday
    rotate 60
    missingok
    compress
    delaycompress
    notifempty
    create 0640 nginx nginx
    sharedscripts
    postrotate
            if [ -f /run/nginx.pid ]; then
                kill -USR1 `cat /run/nginx.pid`
            fi
    endscript
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 logrotate 설정 파일의 해석은 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;맨 위 &lt;b&gt;/etc/nginx/log/*.log&lt;/b&gt; : &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;/etc/nginx/log 디렉토리&lt;/b&gt;&lt;/span&gt;에 있는 &lt;span style=&quot;color: #006dd7;&quot;&gt;*&lt;b&gt;.log 파일&lt;/b&gt;&lt;/span&gt;에 대해 다음 logrotate 옵션을 지정한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;daily&lt;/b&gt; : 매일 logrotate를 수행하여, 일별로 새로운 로그 파일이 생성되도록 한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;dateext&lt;/b&gt; : 로그 파일명에 &amp;lsquo;20231028&amp;rsquo; 과 같은 날짜 형식을 추가하여 로그파일이 생성되도록 한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;dateyesterday&lt;/b&gt; : dateext로 붙는 날짜 형식에 하루 전날 기준으로 생성하도록 한다. &lt;br /&gt;&amp;rArr; &lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;이 옵션을 사용하지 않으면&lt;/b&gt;&lt;/span&gt;, logrotate를 수행한 해당 시점 기준으로 파일명에 날짜가 새겨져서 &lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;헷갈리게 된다.&lt;/b&gt;&lt;/span&gt; 예를 들면 &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;2023.10.28.&lt;/b&gt;&lt;/span&gt; 에 logrotate를 하게 되면 결과로 생성된 로그 파일(ex) &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;error.log-20231028&lt;/b&gt;&lt;/span&gt;)에는 &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;2023.10.27. 의 로그들만 있는데&lt;/b&gt;&lt;/span&gt;, 이를 방지하고자 이 옵션을 사용하면, 2023.10.28에 logrotate를 한 결과 로그 파일명이 &amp;lsquo;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;error.log-20231027&lt;/b&gt;&lt;/span&gt;&amp;rsquo;로 되는 것이다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;rotate [숫자]&lt;/b&gt; : 해당 개수만큼만 로그 파일을 보관한다. 이 수를 초과하면, 오래된 로그부터 삭제된다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;missingok&lt;/b&gt; : 로그 파일이 없는 경우에도 경고 없이 진행한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;compress&lt;/b&gt; : 로그 파일을 압축하여 저장한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;delaycompress&lt;/b&gt; : 다음 logrotate 가 진행되기 전까지 압축을 지연시킨다. &amp;rArr; 2023.10.28. 에 logrotate 가 수행된다면, 이때 결과 파일로 생기는 로그 파일은 압축을 하지 않고(다음날인 2023.10.29.에 해당 파일이 압축된다.), 2023.10.27. 에 logrotate 수행한 파일을 압축하게 된다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;notifempty&lt;/b&gt; : 로그 파일이 비어 있으면 로테이션하지 않도록 한다. 즉, 해당 날짜에 대한 새로운 로그가 생기지 않았다면, 로그 파일명 기준으로 해당 날짜에 대한 로그가 누락된 것처럼 보일 수도 있겠다&amp;hellip;!&lt;/li&gt;
&lt;li&gt;&lt;b&gt;create 0640 nginx nginx&lt;/b&gt; : logrotate 결과 생기는 파일에 대한 권한을 설정하는 것으로, 이 예시에서는 해당 로그 파일에 대해 0640 permission 으로 &amp;lsquo;nginx&amp;rsquo; 유저, &amp;lsquo;nginx&amp;rsquo; 그룹에 소유권을 부여한다는 의미이다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;sharedscripts&lt;/b&gt; : 여러 로그 파일이 있는 경우, 한 번만 logrotate 를 수행하도록 하여, 이 옵션으로 지정된 logrotate 중복 수행을 방지하고, 실행시간 및 리소스 사용을 줄인다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;postrotate&lt;/b&gt; : logrotate 수행 이후에 수행할 작업을 정의하는 구문으로, 위 예시에서는 nginx에 USR1 시그널을 보내어 log 파일을 re-open 함으로써, &lt;b&gt;logrotate 수행 결과 생성된 로그 파일&lt;/b&gt;에 &lt;b&gt;현재 구동중인 nginx의 로그가 계속하여 쌓이는 것을 방지&lt;/b&gt;한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;endscript&lt;/b&gt; : &amp;lsquo;&lt;span style=&quot;background-color: #dddddd; color: #ef6f53;&quot;&gt;&lt;b&gt;prerotate&lt;/b&gt;&lt;/span&gt;&amp;rsquo; &amp;lsquo;&lt;span style=&quot;background-color: #dddddd; color: #ef6f53;&quot;&gt;&lt;b&gt;postrotate&lt;/b&gt;&lt;/span&gt;&amp;rsquo; 와 같은 옵션 블록을 사용할 때, 이 &lt;b&gt;블록에 속한 명령어나 스크립트의 실행 범위의 끝을 나타내는&lt;/b&gt; 키워드에 해당한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;Gunicorn logrotate 설정&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# /etc/logrotate.d/{Gunicorn으로 구동할 APP 이름} 파일

/apps/venvs/qa_portal/logs/*.log {
    daily
    dateext
    dateyesterday
    rotate 60
    missingok
    compress
    delaycompress
    notifempty
    create 0640 gunicorn gunicorn
    sharedscripts
    postrotate
            if [ -f /apps/venvs/qa_portal/qa_portal.pid ]; then
                kill -USR1 `cat /apps/venvs/qa_portal/qa_portal.pid`
            fi
    endscript
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;crond 란?&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;Cron(주기적인 job 스케줄 실행을 위한 S/W 유틸리티)&lt;/b&gt;&lt;/span&gt;의 &lt;b&gt;daemon 프로세스&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;crond 는 기본적으로 아래와 같은 구조로 &lt;b&gt;crontab&lt;/b&gt; 과 &lt;b&gt;cron.d&lt;/b&gt; 의 수행해야 할 작업 내역을 불러와서 일정 주기마다 해당 작업을 수행한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;541&quot; data-origin-height=&quot;366&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bpiHcO/btszCueXIgC/cfvFkhrzT12kdvwvPhVhF0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bpiHcO/btszCueXIgC/cfvFkhrzT12kdvwvPhVhF0/img.png&quot; data-alt=&quot;출처 :&amp;amp;amp;nbsp; https://blog.o3g.org/server/logrotate를-활용하여-로그-관리하기/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bpiHcO/btszCueXIgC/cfvFkhrzT12kdvwvPhVhF0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbpiHcO%2FbtszCueXIgC%2FcfvFkhrzT12kdvwvPhVhF0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;541&quot; height=&quot;366&quot; data-origin-width=&quot;541&quot; data-origin-height=&quot;366&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 :&amp;amp;nbsp; https://blog.o3g.org/server/logrotate를-활용하여-로그-관리하기/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필자는 간편하게 &lt;span style=&quot;background-color: #dddddd; color: #ef6f53;&quot;&gt;&lt;b&gt;crontab&lt;/b&gt;&lt;/span&gt;을 활용하여 스케줄 job을 등록하고자 한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;crontab&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;crontab은 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;cron의 실행주기 및 실행시간이 지정된 작업의 모음&lt;/b&gt;&lt;/span&gt;으로 아래와 같은 명령어 형식을 통해 스케줄 job을 등록할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;* * * * * [실행 명령어 또는 쉘 스크립트]

# 첫번째   '*' : 0~59 의 숫자를 입력하여, **몇 분**에 해당 명령을 수행할 지 결정
# 두번째   '*' : 0~23 의 숫자를 입력하여, **몇 시**에 해당 명령을 수행할 지 결정
# 세번째   '*' : 1~31 의 숫자를 입력하여, 매달 **며칠**에 해당 명령을 수행할 지 결정
# 네번째   '*' : 1~12 의 숫자를 입력하여, **몇 월**에 해당 명령을 수행할 지 결정
# 다섯번째 '*' : 0~7 의 숫자 또는 [sun | mon | tue | web | thu | fri | sat] 중 하나 입력
# **무슨 요일**에 해당 명령을 수행할 지 결정 / 일:0,7 / 월:1 / 토:6&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 명령어를 통해 &lt;b&gt;nginx의 logrotate&lt;/b&gt;와 &lt;b&gt;gunicorn의 logrotate&lt;/b&gt;를 &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;매일&lt;/b&gt;&lt;/span&gt; 하루의 시작인&lt;span style=&quot;color: #409d00;&quot;&gt; &lt;b&gt;00시 00분&lt;/b&gt;&lt;/span&gt;에 수행하도록 해보자.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# crontab 스케줄 등록 (crontab -e)
# vi editor처럼 나타나는데 거기에 등록하려는 crontab 형식의 스케줄을 입력하고 :wq로 저장하면 된다.
crontab -e 

# crontab -e 로 나오는 텍스트 에디터에서 다음을 입력하고 ':wq' 입력하여 저장 및 종료
# nginx의 logrotate를 crontab에 매일 오전 00:00 으로 등록
0 0 * * * /usr/sbin/logrotate -f /etc/logrotate.d/nginx

# Gunicorn으로 구동하는 App의 logrotate를 crontab에 매일 오전 00:00 으로 등록
0 0 * * * /usr/sbin/logrotate -f /etc/logrotate.d/{Gunicorn으로 구동하는 App의 logrotate 설정 파일명}

# 현재 crontab으로 걸려 있는 모든 스케줄 job 조회
crontab -l&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://sangchul.kr/entry/Nginx-%EB%A1%9C%EA%B7%B8-%ED%8C%8C%EC%9D%BC%EC%9D%98-%EB%A1%9C%ED%85%8C%EC%9D%B4%EC%85%98-%EC%84%A4%EC%A0%95nginx-logrotate&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://sangchul.kr/entry/Nginx-%EB%A1%9C%EA%B7%B8-%ED%8C%8C%EC%9D%BC%EC%9D%98-%EB%A1%9C%ED%85%8C%EC%9D%B4%EC%85%98-%EC%84%A4%EC%A0%95nginx-logrotate&lt;/a&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1698876058311&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Nginx 로그 파일의 로테이션 설정하는 방법(nginx logrotate)&quot; data-og-description=&quot;Nginx 로그 파일의 로테이션 설정하는 방법(nginx logrotate) Nginx 로그 파일을 주기적으로 로테이션(순환)하여 로그 파일 크기를 관리하고 오래된 로그를 보관하려면 logrotate를 사용할 수 있습니다. Ngi&quot; data-og-host=&quot;sangchul.kr&quot; data-og-source-url=&quot;https://sangchul.kr/entry/Nginx-%EB%A1%9C%EA%B7%B8-%ED%8C%8C%EC%9D%BC%EC%9D%98-%EB%A1%9C%ED%85%8C%EC%9D%B4%EC%85%98-%EC%84%A4%EC%A0%95nginx-logrotate&quot; data-og-url=&quot;https://sangchul.kr/entry/Nginx-%EB%A1%9C%EA%B7%B8-%ED%8C%8C%EC%9D%BC%EC%9D%98-%EB%A1%9C%ED%85%8C%EC%9D%B4%EC%85%98-%EC%84%A4%EC%A0%95nginx-logrotate&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/iJC1f/hyUnVwf6YE/N8kzyirpBUzjYxcp1fz48k/img.jpg?width=300&amp;amp;height=255&amp;amp;face=0_0_300_255,https://scrap.kakaocdn.net/dn/v8arP/hyUnWIF0MA/T81y6kSOETJH0xUHzLUKuK/img.jpg?width=300&amp;amp;height=255&amp;amp;face=0_0_300_255&quot;&gt;&lt;a href=&quot;https://sangchul.kr/entry/Nginx-%EB%A1%9C%EA%B7%B8-%ED%8C%8C%EC%9D%BC%EC%9D%98-%EB%A1%9C%ED%85%8C%EC%9D%B4%EC%85%98-%EC%84%A4%EC%A0%95nginx-logrotate&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://sangchul.kr/entry/Nginx-%EB%A1%9C%EA%B7%B8-%ED%8C%8C%EC%9D%BC%EC%9D%98-%EB%A1%9C%ED%85%8C%EC%9D%B4%EC%85%98-%EC%84%A4%EC%A0%95nginx-logrotate&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/iJC1f/hyUnVwf6YE/N8kzyirpBUzjYxcp1fz48k/img.jpg?width=300&amp;amp;height=255&amp;amp;face=0_0_300_255,https://scrap.kakaocdn.net/dn/v8arP/hyUnWIF0MA/T81y6kSOETJH0xUHzLUKuK/img.jpg?width=300&amp;amp;height=255&amp;amp;face=0_0_300_255');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Nginx 로그 파일의 로테이션 설정하는 방법(nginx logrotate)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Nginx 로그 파일의 로테이션 설정하는 방법(nginx logrotate) Nginx 로그 파일을 주기적으로 로테이션(순환)하여 로그 파일 크기를 관리하고 오래된 로그를 보관하려면 logrotate를 사용할 수 있습니다. Ngi&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;sangchul.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://m.blog.naver.com/hello_world_study/221501251102&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://m.blog.naver.com/hello_world_study/221501251102&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1698876064713&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;gunicorn, flask 그리고 log 설정하기 with logrotate&quot; data-og-description=&quot;#gunicorn 은 tomcat 과 같은 웹서버입니다. 보통 tomcat 은 자바와 연결되어 동작하고, gunicorn 의 경우 ...&quot; data-og-host=&quot;blog.naver.com&quot; data-og-source-url=&quot;https://m.blog.naver.com/hello_world_study/221501251102&quot; data-og-url=&quot;https://blog.naver.com/hello_world_study/221501251102&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/byPVLo/hyUnViLgN8/91SKYR7nN9gTDyBKE5Xktk/img.png?width=270&amp;amp;height=270&amp;amp;face=0_0_270_270&quot;&gt;&lt;a href=&quot;https://m.blog.naver.com/hello_world_study/221501251102&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://m.blog.naver.com/hello_world_study/221501251102&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/byPVLo/hyUnViLgN8/91SKYR7nN9gTDyBKE5Xktk/img.png?width=270&amp;amp;height=270&amp;amp;face=0_0_270_270');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;gunicorn, flask 그리고 log 설정하기 with logrotate&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;#gunicorn 은 tomcat 과 같은 웹서버입니다. 보통 tomcat 은 자바와 연결되어 동작하고, gunicorn 의 경우 ...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;blog.naver.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://blog.o3g.org/server/logrotate%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%98%EC%97%AC-%EB%A1%9C%EA%B7%B8-%EA%B4%80%EB%A6%AC%ED%95%98%EA%B8%B0/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://blog.o3g.org/server/logrotate%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%98%EC%97%AC-%EB%A1%9C%EA%B7%B8-%EA%B4%80%EB%A6%AC%ED%95%98%EA%B8%B0/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1698876069213&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;logrotate를 활용하여 로그 관리하기 : 오픈 인프라 엔지니어 그룹&quot; data-og-description=&quot;1. 서론 데이터베이스 시스템이나 어플리케이션 서버, 웹 서버를 운용하다 보면 어느순간 쌓여 있는 로그들을 확인할수 있다. 이렇게 쌓인 로그들은 운영중인 시스템에 장애가 발생했을때 원인&quot; data-og-host=&quot;blog.o3g.org&quot; data-og-source-url=&quot;https://blog.o3g.org/server/logrotate%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%98%EC%97%AC-%EB%A1%9C%EA%B7%B8-%EA%B4%80%EB%A6%AC%ED%95%98%EA%B8%B0/&quot; data-og-url=&quot;https://blog.o3g.org/server/logrotate%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%98%EC%97%AC-%EB%A1%9C%EA%B7%B8-%EA%B4%80%EB%A6%AC%ED%95%98%EA%B8%B0/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/COTbZ/hyUnSGjpYi/6evo9ZmCprODHjA5wEyKj0/img.png?width=300&amp;amp;height=251&amp;amp;face=0_0_300_251,https://scrap.kakaocdn.net/dn/xKFPs/hyUnWaSRBu/dC8VhA7Yi1FRyHxUn6cpik/img.png?width=300&amp;amp;height=198&amp;amp;face=0_0_300_198&quot;&gt;&lt;a href=&quot;https://blog.o3g.org/server/logrotate%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%98%EC%97%AC-%EB%A1%9C%EA%B7%B8-%EA%B4%80%EB%A6%AC%ED%95%98%EA%B8%B0/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://blog.o3g.org/server/logrotate%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%98%EC%97%AC-%EB%A1%9C%EA%B7%B8-%EA%B4%80%EB%A6%AC%ED%95%98%EA%B8%B0/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/COTbZ/hyUnSGjpYi/6evo9ZmCprODHjA5wEyKj0/img.png?width=300&amp;amp;height=251&amp;amp;face=0_0_300_251,https://scrap.kakaocdn.net/dn/xKFPs/hyUnWaSRBu/dC8VhA7Yi1FRyHxUn6cpik/img.png?width=300&amp;amp;height=198&amp;amp;face=0_0_300_198');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;logrotate를 활용하여 로그 관리하기 : 오픈 인프라 엔지니어 그룹&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;1. 서론 데이터베이스 시스템이나 어플리케이션 서버, 웹 서버를 운용하다 보면 어느순간 쌓여 있는 로그들을 확인할수 있다. 이렇게 쌓인 로그들은 운영중인 시스템에 장애가 발생했을때 원인&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;blog.o3g.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Middleware/WSGI</category>
      <category>gunicorn logrotate</category>
      <category>logrotate crond</category>
      <category>logrotate crontab</category>
      <category>logrotate 하루전</category>
      <category>nginx logrotate</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/151</guid>
      <comments>https://co-no.tistory.com/entry/gunicorn-logrotate-crond%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%9C-nginx%EC%99%80-gunicorn%EC%9D%98-log-%ED%8C%8C%EC%9D%BC-%EA%B4%80%EB%A6%AC%ED%95%98%EA%B8%B0#entry151comment</comments>
      <pubDate>Thu, 2 Nov 2023 07:02:22 +0900</pubDate>
    </item>
    <item>
      <title>[Gunicorn] gunicorn - nginx 연동</title>
      <link>https://co-no.tistory.com/entry/gunicorn-gunicorn-nginx-%EC%97%B0%EB%8F%99</link>
      <description>&lt;script src=&quot;//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.2/highlight.min.js&quot;&gt;&lt;/script&gt;
&lt;script&gt;hljs.initHighlightingOnLoad();&lt;/script&gt;
&lt;article id=&quot;719af18f-a678-4974-9df1-b1059b84070f&quot; class=&quot;page sans Notion&quot;&gt;&lt;header&gt;
&lt;p class=&quot;page-description&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/header&gt;
&lt;div class=&quot;page-body Tistory&quot;&gt;
&lt;h2 id=&quot;f43a359e-868a-458e-b362-e9ae979cdabb&quot; class=&quot;&quot; data-ke-size=&quot;size26&quot;&gt;1. nginx 디렉토리 권한 수정&lt;/h2&gt;
&lt;p id=&quot;d6553565-bf16-4130-ab6e-3c3db8e707fe&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;RHEL9 에서 dnf로 nginx를 설치하면 nginx 디렉토리들에 대한 권한이 default로 root로 들어가 있을 것이다. 이는 보안상 취약하므로, 아래 명령어를 수행하여 &amp;lsquo;nginx&amp;rsquo; 유저 및 그룹으로 변경해 주도록 하자.&lt;/p&gt;
&lt;pre id=&quot;5eedb9eb-a7a1-4d34-bd55-e3b489582717&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# /etc/nginx/ 디렉토리 권한을 nginx:nginx로 변경 
chown -R nginx:nginx /etc/nginx/&lt;/code&gt;&lt;/pre&gt;
&lt;p id=&quot;1098a59f-56ca-4cb2-8680-96f75c229890&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;d293039a-71cb-45c5-85a5-220851b1fb22&quot; class=&quot;&quot; data-ke-size=&quot;size26&quot;&gt;2. SELinux 설정 변경&lt;/h2&gt;
&lt;p id=&quot;4e32e715-b1b7-4c23-890b-e05f16196c32&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;SELinux는 최신 RHEL 및 CentOS 에서 기본적으로 활성화되어 있는 Linux 시스템용 보안 아키텍처이다. SELinux 모듈이 켜져 있으면, 파일 접근 권한, Upstream 위치로의 Proxy 및 소켓을 통한 다른 프로세스와 통신하는 것 등에 제한이 따르기 때문에, nginx 도 구동부터 막히게 된다.&lt;/p&gt;
&lt;p id=&quot;a4723a5d-da92-4800-a187-c01bd27fa6d8&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;따라서 아래 명령어 및 파일 수정으로 SELinux를 enforcing &amp;rarr; permissive 로 변경해보자!&lt;/p&gt;
&lt;pre id=&quot;b805b44c-cfd1-4d71-bd59-c61257d90015&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# 현재 SELinux 상태 확인 명령어 
sestatus&lt;/code&gt;&lt;/pre&gt;
&lt;figure id=&quot;59eeac77-4f30-486f-9445-9972651e145f&quot; class=&quot;image&quot; style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/rTqh1/btszvJD8jMb/Ej9Y8XjoTEE4W9auKmoBhk/img.png&quot;&gt;&lt;img style=&quot;width: 576px;&quot; src=&quot;https://blog.kakaocdn.net/dn/rTqh1/btszvJD8jMb/Ej9Y8XjoTEE4W9auKmoBhk/img.png&quot; /&gt;&lt;/a&gt;&lt;/figure&gt;
&lt;p id=&quot;3d3b1b92-f9e9-44d3-9199-ce0d22e34217&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;서버를 처음 셋업하고 SELinux에 대한 설정을 건드리지 않았다면, 위와 같이 &lt;b&gt;Current mode&lt;/b&gt;가 &lt;code&gt;&lt;b&gt;enforcing&lt;/b&gt;&lt;/code&gt; 일 것이다. 이 상태면, &lt;code&gt;&lt;b&gt;systemctl start nginx&lt;/b&gt;&lt;/code&gt; 가 되지 않는다.&lt;/p&gt;
&lt;pre id=&quot;841f1098-def1-4033-baa9-25c8d52b5ecb&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# 현재 SELinux 를 enforcing -&amp;gt; permissive 로 변경 
setenforce 0  

# SELinux 상태 다시 확인 
sestatus&lt;/code&gt;&lt;/pre&gt;
&lt;figure id=&quot;c0c518ff-20a2-46ab-a445-16c76cfdd4ad&quot; class=&quot;image&quot; style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/sHJCm/btszuKKhGPA/6g7JPKWu2ONipYqi3gCj3k/img.png&quot;&gt;&lt;img style=&quot;width: 592px;&quot; src=&quot;https://blog.kakaocdn.net/dn/sHJCm/btszuKKhGPA/6g7JPKWu2ONipYqi3gCj3k/img.png&quot; /&gt;&lt;/a&gt;&lt;/figure&gt;
&lt;p id=&quot;6888c328-074d-4f4f-933c-9f2bbc79a1f5&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;이제 nginx 는 구동시킬 수 있을 것이다.&lt;/p&gt;
&lt;p class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;문제는 이 &lt;b&gt;서버가 재부팅되면, 다시 SELinux의 config 파일을 읽어와서&lt;/b&gt;&lt;/p&gt;
&lt;p id=&quot;7a87a8c4-3c1f-4048-b526-18c012390e48&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;&lt;b&gt;enforcing&lt;/b&gt;&lt;/code&gt; 모드로 될 것이므로, 아예 config 파일에서도 &lt;code&gt;&lt;b&gt;permissive&lt;/b&gt;&lt;/code&gt;로 설정을 바꿔보자!&lt;/p&gt;
&lt;pre id=&quot;a5c9a60b-fa43-4dfc-9592-9a9e97533763&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# RHEL9 기준, vim /etc/selinux/config  
# /etc/selinux/config 파일 
# 아래와 같이 'SELINUX' 값을 'permissive'로 변경 

SELINUX=permissive&lt;/code&gt;&lt;/pre&gt;
&lt;figure id=&quot;7de1b0f8-b467-4bde-86dc-63b27505f7e5&quot; class=&quot;image&quot; style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/bJl1Uu/btszwbN7YT1/ofy9J9r4KMgPwdRtT2PH81/img.png&quot;&gt;&lt;img style=&quot;width: 585px;&quot; src=&quot;https://blog.kakaocdn.net/dn/bJl1Uu/btszwbN7YT1/ofy9J9r4KMgPwdRtT2PH81/img.png&quot; /&gt;&lt;/a&gt;&lt;/figure&gt;
&lt;p id=&quot;1f7700d2-5a34-4c5d-8dea-70066cc2e201&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;SELinux 의 config 파일을 permissive로 변경 후에 다시 sestatus 명령어를 수행해보면, 위 그림과 같이 Mode from config file 의 값이 permissive로 변경된 것을 확인할 수 있다!&lt;/p&gt;
&lt;p id=&quot;a976f419-a723-484f-9935-ce5ce1e22b1f&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;8e4a1a5d-72fa-42a5-ad81-2e32ae54020b&quot; class=&quot;&quot; data-ke-size=&quot;size26&quot;&gt;3. nginx 기본 설정 파일 수정 - nginx.conf&lt;/h2&gt;
&lt;pre id=&quot;d91f15fe-7b80-4e0c-90b4-3d47566e1fe8&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# nginx 설치 경로로 이동 
cd /etc/nginx  

# nginx.conf 파일 수정 전 원본 복사 
cp nginx.conf nginx.conf_ori  

# nginx.conf 파일을 수정 
vim nginx.conf&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;6c734dc7-8337-4461-81e6-0daaf32fd910&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# nginx.conf  

# worker 프로세스를 실행할 사용자 설정 
# 이 user에 따라 권한이 달라질 수 있다. 
user nginx; 

# 실행할 worker 프로세스 설정 
# 서버에 장착되어 있는 코어 수만큼 할당하는 것이 보통. 
worker_processes auto;  

# 오류 로그를 남길 파일 경로 지정 
# 여기에서는 /etc/nginx/log 디렉토리를 만들었다고 가정 
error_log /etc/nginx/log/error.log warn;  

# nginx 마스터 프로세스 ID를 저장할 파일 경로 지정 
pid /run/nginx.pid;   

# 접속 처리에 관한 설정 
events { 	
    # 워커 프로세스 한 개당 동시 접속 수 지정 (512 or 1024 추천) 	
    worker_connections 1024; 
}  

# 웹, 프록시 관련 서버 설정 
http {  	
    # 액세스 로그 형식 지정 	
    log_format main '$remote_addr - $remote_user [$time_local] &quot;$request&quot; ' 									'$status $body_bytes_sent &quot;$http_referer&quot; ' 									
    '&quot;$http_user_agent&quot; &quot;$http_x_forwarded_for&quot;';  	
    
    # 액세스 로그를 남길 파일 경로 지정 		
    access_log /etc/nginx/log/access.log main; 	 	
    
    # sendfile api 를 사용할 지 말 지 결정 	
    sendfile        on; 	
    
    # on - 데이터를 클라이언트로 전송할 때 데이터를 버퍼링하여 전송 지연을 최소화. 	
    tcp_nopush      on; 	
    
    # on - 작은 패킷을 빠르게 전송하여 지연 시간을 최소화.   
    tcp_nodelay   on; 	
    
    # 접속 시 커넥션을 몇 초동안 유지할 지에 대한 설정   
    keepalive_timeout 65; 	
    
    # nginx가 MIME 타입을 해시 테이블에 저장하는 데 사용하는 메모리의 최대 크기 (default 4096) 	
    type_hash_max_size 4096;  	  	
    
    # mime.types 파일을 읽어온다. 	
    include /etc/nginx/mime.types; 	
    
    # MIME 타입 설정 	
    default_type application/octet-stream;  	
    
    # 보안을 위해 nginx 버전을 숨기도록 지정 	
    server_tokens off;  	
    
    # /etc/nginx/conf.d 디렉토리에 하위의 모든 .conf 파일을 읽어오도록 설정 	
    include /etc/nginx/conf.d/*.conf;  	
    
    # RHEL9 의 dnf 배포판에는 없어 별도로 디렉토리 생성 및 conf 구문 추가 	
    # /etc/nginx/sites-enabled 디렉토리 하위의 모든 사이트 설정을 불러오도록 지정 	
    include /etc/nginx/sites-enabled/*; 
}&lt;/code&gt;&lt;/pre&gt;
&lt;p id=&quot;a530f1ea-6fe5-4973-aac9-f447e20d7e17&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;8a48ccce-c12f-4384-b80b-3baef178c127&quot; class=&quot;&quot; data-ke-size=&quot;size26&quot;&gt;4. nginx-gunicorn 연동을 위한 config 파일 작성&lt;/h2&gt;
&lt;p id=&quot;f90a82a1-b3a6-488d-9d6e-71ff1b553f24&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;필자는 RHEL9에서 dnf로 설치한 nginx에 &lt;b&gt;sites-available&lt;/b&gt; 디렉토리가 따로 없었다. 그래서 별도로 생성해주었고, 해당 디렉토리는 실제 conf파일이 반영 되는 곳이 아닌, 미리 conf파일을 작성하여 저장하는 용도로 사용된다.&lt;/p&gt;
&lt;pre id=&quot;e2ef6a35-d120-4888-928e-f2611c3b771c&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# /etc/nginx/sites-available 디렉토리 하위에 [gunicorn에 배포할 프로젝트 이름] 으로 설정 파일을 만들 것이다. 
# 예시 : /etc/nginx/sites-available/test_project  

server { 	
    listen 80; 	
    server_name [IP address | Domain name];  	
    
    location / { 		
        include proxy_params; 		
        proxy_pass http://unix:/apps/venvs/{프로젝트의 가상환경명}/run/{프로젝트명}.sock; 	
    } 
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul id=&quot;f6bd010c-74e6-4f0b-bc1a-8cc03f3d6402&quot; class=&quot;bulleted-list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot;&gt;&lt;code&gt;&lt;b&gt;location / &lt;/b&gt;&lt;/code&gt;: 모든 요청을 구문에 맞게 리다이렉션 하라는 의미&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id=&quot;77173f2c-6c1b-4f10-87e5-8ca4865e59eb&quot; class=&quot;bulleted-list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot;&gt;&lt;code&gt;&lt;b&gt;http://unix:/~.sock&lt;/b&gt;&lt;/code&gt; : 해당 요 청을 Gunicorn의 Unix Domain Socket으로 보내라는 의미&lt;/li&gt;
&lt;/ul&gt;
&lt;p id=&quot;5fcd362c-6852-4bd1-a1ad-4621b512302a&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;0dc18e33-4f84-417c-b087-2e33f8aad5d2&quot; class=&quot;&quot; data-ke-size=&quot;size26&quot;&gt;5. proxy_params 파일 작성&lt;/h2&gt;
&lt;p id=&quot;9910d825-f88d-4f7c-8dbc-2091fdc704f2&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;위 test_proejct에 대한 config 파일에 include proxy_params 구문이 있는데, 우리는 해당 파일을 아직 작성하지 않았다. proxy_params 파일은 해당 사이트에 대한 별도의 프록시 파라미터 설정을 해주는 파일이다. 다음과 같이 작성해보도록 하자.&lt;/p&gt;
&lt;pre id=&quot;043fd0f3-9dcc-49f6-8ad5-63c435a454f9&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# vim /etc/nginx/proxy_params  
# proxy_params 파일  

# Request를 넘겨 받을 때 아래 Proxy Header 정보를 지정 
proxy_set_header X-Real-IP $remote_addr; 
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme; 
proxy_set_header X-NginX-Proxy true;  

# 서버(웹사이트)에 업로드 가능한 파일 최대 용량 
# default : 1M 
client_max_body_size 128M;  #

클라이언트 Buffer 사이즈 (body 들어오는 사이즈) 
# default : 32bit=8k, 64bit=16k 
client_body_buffer_size 1M;  

# 백엔드 서버로부터 해당 response를 버퍼링할 지 여부 정의 
# on : 버퍼가 제공하는 메모리 공간을 이용하여 응답 데이터를 메모리에 저장 
# off : 응답을 직접 클라이언트에게 전달 
proxy_buffering on;  

# 백엔드 서버로부터 response 데이터를 읽는 데 사용할 버퍼의 수와 크기 설정 
proxy_buffers 256 16k;  

# 백엔드 서버 response의 첫 부분을 읽기 위한 버퍼 크기 지정 
proxy_buffer_size 128k;  

# 여기서 지정한 값을 버퍼가 초과하면, 데이터를 클라이언트로 보내고 버퍼를 비움 
proxy_busy_buffers_size 256k;  

# 한 번에 사용할 수 있는 임시 파일 용량 
proxy_temp_file_write_size 256k;  

# 최대 사용할 수 있는 임시 파일 용량 
proxy_max_temp_file_size 1024M;  

# 백엔드 서버 접속 제한 시간(sec 단위)을 정의 
proxy_connect_timeout 3600;  

# 백엔드 서버로부터 데이터를 읽을 때의 제한 시간 
proxy_send_timeout 3600; 

# 백엔드 서버로 데이터를 전송할 때의 제한 시간 
proxy_read_timeout 3600;  

# 백엔드 서버가 보내오는 모든 에러 페이지를 nginx가 직접 클라이언트에게 회신 
proxy_intercept_errors on;&lt;/code&gt;&lt;/pre&gt;
&lt;p id=&quot;3e1f87bf-f3f0-4cc2-a005-12d80668e0a0&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;fe84e7a5-2106-4bd7-8fa1-14be710482bc&quot; class=&quot;&quot; data-ke-size=&quot;size26&quot;&gt;6. sites-enabled에 링크 생성을 통한 프로젝트 config 파일 적용&lt;/h2&gt;
&lt;p id=&quot;13164539-6614-4284-abee-1d3887b577d3&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;sites-available 에서 작성한 프로젝트에 대한 config파일을 sites-enabled 디렉토리 하위에 &lt;b&gt;심볼릭 링크&lt;/b&gt;로 만들어 해당 config가 적용되도록 한다. nginx는 이러한 방식을 통해, 현재 서버에 적용되고 있는 config 파일을 직접 수정하지 않고, 별도의 파일로 작성 후에 바로 적용할 수 있도록 구현되어 있다.&lt;/p&gt;
&lt;pre id=&quot;8a0bef9f-893a-4b59-8467-10360375d2e3&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# 실제 nginx에서 가져오는 설정 파일인 sites-enabled 하위 파일을 심볼릭 링크로 생성 
ln -s /etc/nginx/sites-available/test_project /etc/nginx/sites-enabled/test_project  

# 생성된 심볼릭 링크에 대한 소유권을 'nginx' 로 변경 
chown -h nginx:nginx /etc/nginx/sites-enabled/test_project&lt;/code&gt;&lt;/pre&gt;
&lt;p id=&quot;d50e63df-a3b5-4f3d-b419-81ea0fdaba9c&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;31b8d615-7b78-470a-af91-3a4a5cfff3ed&quot; class=&quot;&quot; data-ke-size=&quot;size23&quot;&gt;7, gunicorn 전용 계정 생성 및 권한 부여&lt;/h3&gt;
&lt;p id=&quot;fa6cfe1f-45e2-46e8-9f38-0be966d188b5&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;python과 관련된 디렉토리인 /apps와 그 하위 디렉토리들에 대한 권한을 모두 &amp;lsquo;&lt;b&gt;gunicorn&lt;/b&gt;&amp;rsquo;이라는 계정으로 소유권을 이전할 것이다. 일단 OS 계정부터 만들어야 하니, 다음 명령어를 수행하여 계정을 만들자.&lt;/p&gt;
&lt;pre id=&quot;6f2f1a43-0498-4b75-9260-8e6536d5b469&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# 아래 명령어는 모두 root 또는 root 계정과 동등한 권한으로 수행 
# 'gunicorn' Linux 계정 생성 
useradd gunicorn 

# 'gunicorn' Password 설정 
passwd gunicorn  

# python과 관련된 디렉토리인 /apps 및 그 하위 디렉토리의 소유권을 모두 gunicorn으로 변경 
chown -R gunicorn:gunicorn /apps  

# 'gunicorn' 홈 디렉토리 설정 
usermod -d /apps gunicorn  

# 'gunicorn'이 구동되면서 생성될 소켓 파일이 위치할 디렉토리 생성 
# 'gunicorn' 으로 계정 전환하여 생성하기 
mkdir /apps/venvs/test_project/run&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;084ac29a-5dd1-454c-a1a3-d91654d65dc9&quot; class=&quot;&quot; data-ke-size=&quot;size26&quot;&gt;8. gunicorn의 socket 파일에 대한 보안 컨텍스트 변경&lt;/h2&gt;
&lt;p id=&quot;9acad2be-491a-4380-99ad-ad5be38b17f0&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;nginx &amp;harr; gunicorn 간 통신을 TCP가 아닌 Unix Domain Socket을 이용하여 셋업하고자 한다.&lt;/p&gt;
&lt;p id=&quot;7b563f2e-e452-41d7-badc-c45bef21c1b7&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;필자의 경우 nginx 와 gunicorn을 같은 서버에 둔다고 가정하여, &lt;b&gt;불필요한 네트워크 오버헤드를 없애기 위해&lt;/b&gt; 로컬 환경 안에서의 UDS(Unix Domain Socket)을 통한 통신으로 설정하는 것이다.&lt;/p&gt;
&lt;p id=&quot;314adbed-fe33-4ff1-bcd9-9f4113b94638&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;우선 /run/test_project.sock 파일이 생성되려면, gunicorn을 UDS 방식으로 한번 구동시켜줘야 한다.&lt;/p&gt;
&lt;p id=&quot;4a509f2d-162e-4552-815d-8c4215b5a572&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;gunicorn이 이미 실행되어 있다면 종료시키고, 다음 명령어로 gunicorn을 다시 구동시키자.&lt;/p&gt;
&lt;pre id=&quot;1e5d1ebe-6a9e-4836-ab51-9592dffebd0b&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# python 프로젝트에 대한 venv 활성화 및 프로젝트의 홈 디렉토리에서 수행 
# &quot;pybo:create_app()&quot; 구문은 배포하는 애플리케이션에 맞춰 지정해야 한다. 
gunicorn --bind unix:/apps/venvs/test_project/run/test_project.sock &quot;pybo:create_app()&quot; &amp;amp;  

# /run/test_project.sock 파일 생성 확인 후, gunicorn 종료 
kill -9 [gunicorn PID]&lt;/code&gt;&lt;/pre&gt;
&lt;p id=&quot;bce4d4f3-5cfe-4065-bcb9-6c4d59f2eb93&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;gunicorn의 UDS 소켓 파일의 보안 컨텍스트를 변경하지 않으면, nginx 의 포트(IP:80)를 통한 접속 시,&lt;/p&gt;
&lt;mark class=&quot;highlight-red&quot;&gt;&lt;b&gt;502 Bad Gateway &lt;/b&gt;&lt;/mark&gt;
&lt;p class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;에러와 nginx의 에러 로그에서는&lt;/p&gt;
&lt;mark class=&quot;highlight-red&quot;&gt;&lt;b&gt;Connection refuesed&lt;/b&gt;&lt;/mark&gt;
&lt;p id=&quot;70afcfb9-8ed1-4be4-b669-51cda33032a6&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;에러를 마주할 것이다.&lt;/p&gt;
&lt;p class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;정석이라면 /apps/venvs/test_project/run/test_project.sock 파일의 보안 컨텍스트를 변경해줘야 하지만,&lt;/p&gt;
&lt;mark class=&quot;highlight-blue&quot;&gt;&lt;b&gt;그냥 더 쉽게 &amp;lsquo;nginx&amp;rsquo; 계정이 &amp;lsquo;gunicorn&amp;rsquo; 그룹에 들어가도록 하자.&lt;/b&gt;&lt;/mark&gt;
&lt;pre id=&quot;15e71b00-a519-4c1c-bec3-cc1876c81641&quot; class=&quot;code Shell&quot;&gt;&lt;code&gt;usermod -G nginx gunicorn&lt;/code&gt;&lt;/pre&gt;
&lt;p id=&quot;e7b4557d-7f9f-47f5-9fcc-56b9a9f69d74&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;rarr; 이렇게 하면, nginx가 'gunicorn' 계정과 동일한 그룹으로 구동되어, gunicorn에 의해 생성되는 sock 파일을 접근할 수 있게 된다.&lt;/p&gt;
&lt;p id=&quot;f9757fcb-0204-46ce-9abb-3ea70bc603fb&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;78658e35-0843-43b1-a139-61de3acb0771&quot; class=&quot;&quot; data-ke-size=&quot;size26&quot;&gt;2. 작성한 nginx의 모든 config 파일 syntax 검사&lt;/h2&gt;
&lt;pre id=&quot;9d0fd635-0329-4bf4-9930-b1c9576811eb&quot; class=&quot;code Shell&quot;&gt;&lt;code&gt;nginx -t&lt;/code&gt;&lt;/pre&gt;
&lt;figure id=&quot;befa40a5-8a03-4a08-b5aa-27b7e5cf1a87&quot; class=&quot;image&quot; style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/WVyX3/btszvfwLGTh/yFGm8dnkK1xEs5yHalsRhk/img.png&quot;&gt;&lt;img style=&quot;width: 800px;&quot; src=&quot;https://blog.kakaocdn.net/dn/WVyX3/btszvfwLGTh/yFGm8dnkK1xEs5yHalsRhk/img.png&quot; /&gt;&lt;/a&gt;&lt;/figure&gt;
&lt;p id=&quot;01652d6b-ecc1-45ad-9f91-6176721d814d&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;위와 같이 &lt;code&gt;&lt;b&gt;syntax is ok&lt;/b&gt;&lt;/code&gt; 및 &lt;code&gt;&lt;b&gt;test is successful&lt;/b&gt;&lt;/code&gt; 이라는 문구가 나타났다면, nginx config 파일의 syntax error는 없다고 볼 수 있다.&lt;/p&gt;
&lt;p id=&quot;2dc583ed-0ea4-4e36-9fd0-5d3b29fd6748&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;6f7f9305-1a86-4ef5-ad1c-43942122c809&quot; class=&quot;&quot; data-ke-size=&quot;size26&quot;&gt;10. nginx 구동&lt;/h2&gt;
&lt;p id=&quot;8100d54c-46f4-4bfc-8236-cb03dc8b6f20&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;config 파일에 이상이 없으니, 이제 nginx 를 구동하여 WSGI서버와 연동이 잘 되었는지 확인해보자!&lt;/p&gt;
&lt;pre id=&quot;0cb8f20f-8754-496d-b4fc-f8212adf39cc&quot; class=&quot;code Shell&quot;&gt;&lt;code&gt;systemctl start nginx&lt;/code&gt;&lt;/pre&gt;
&lt;p id=&quot;e64ef46f-7024-4122-9342-ff638ebbfeac&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;cc832f95-17bf-4e4d-91fc-e538e44ac0dd&quot; class=&quot;&quot; data-ke-size=&quot;size26&quot;&gt;11. {IP}:80 를 통한 접속으로 test_project Web App 접속 여부 확인&lt;/h2&gt;
&lt;p id=&quot;f707ee36-4fa2-4652-b90f-f3c4a53f83a4&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;nginx 및 gunicorn이 10.123.123.123 서버에서 구동된다면, http://10.123.123.123:80/ 로 접속하여 gunicorn으로 구동하는 애플리케이션의 인덱스 페이지가 나타나는 지 확인하면 된다.&lt;/p&gt;
&lt;p id=&quot;9643a9ec-862b-4bc4-914a-c9bcfa2f3fde&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;09315fa0-2498-4dd7-bc9d-07e100f1ae40&quot; class=&quot;&quot; data-ke-size=&quot;size26&quot;&gt;12. gunicorn service 등록&lt;/h2&gt;
&lt;p id=&quot;aa1b50c1-f0ce-4728-b06b-0d541f36f132&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;systemctl 명령어로 gunicorn을 쉽게 올리고 내릴 수 있도록, service 파일로 작성해보자.&lt;/p&gt;
&lt;p id=&quot;e2faa1c4-e2aa-42f3-a137-178b721a07e5&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p id=&quot;f4bad42e-f2b5-4921-b460-a09ce4d91e04&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;서비스 파일에 사용될 환경변수가 선언된 파일이다. 이는 해당 프로젝트의 venv 디렉토리에 위치시키도록 하자.&lt;/p&gt;
&lt;pre id=&quot;ed046894-f297-4d99-8fe8-dc27bb921f5d&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# /apps/venvs/test_project/test_project.env 파일 
FLASK_APP=pybo 
FLASK_DEBUG=false    # 운영 환경이므로 디버깅 모드는 false로 한다. 
APP_CONFIG_FILE=/apps/projects/test_project/config/production.py&lt;/code&gt;&lt;/pre&gt;
&lt;p id=&quot;255f6824-76f9-4795-89b6-df7ab6c34670&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p id=&quot;329cdf70-4828-4379-9fb1-6abdff42ab0a&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;이제 서비스 파일을 작성해보자. python의 경우 venv를 프로젝트 단위로 구성하였으므로, 서비스 파일 또한 gunicorn으로 구동시킬 프로젝트 단위로 생성해야 함을 주의하자!&lt;/p&gt;
&lt;pre id=&quot;bcd8469f-6178-47e8-8d08-9490349c8620&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# gunicorn으로 구동 시킬 프로젝트에 대한 서비스 생성 (root 계정 또는 그와 동등한 계정으로 수행) 
# 위 예시와 맞추기 위해 service 명을 'test_project'로 지정 
vim /usr/lib/systemd/system/test_project.service  

# test_project.service 파일 
[Unit] 
Description=gunicorn daemon 
After=network.target  

[Service] 
User=gunicorn 
Group=gunicorn 
WorkingDirectory=/apps/projects/test_project 
EnvironmentFile=/apps/venvs/test_project/test_project.env 
ExecStart=/apps/venvs/test_project.sh 
ExecStart= 
ExecStart=/apps/venvs/test_project/bin/gunicorn \         
    --workers 2 \         
    --bind unix:/apps/venvs/test_project/run/test_project.sock \         
    --access-logfile /apps/venvs/test_project/logs/access.log \         
    --error-logfile /apps/venvs/test_project/logs/error.log \         
    &quot;pybo:create_app()&quot;  
    
[Install] 
WantedBy=multi-user.target&lt;/code&gt;&lt;/pre&gt;
&lt;p id=&quot;be17cf16-078d-414e-b308-c8e43e838da2&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;65348ca5-6cf3-4694-87d7-d85ec7f1ff90&quot; class=&quot;&quot; data-ke-size=&quot;size26&quot;&gt;참고&lt;/h2&gt;
&lt;figure id=&quot;89a622ad-dfde-4ea4-a351-120f155ee6bd&quot;&gt;&lt;a class=&quot;bookmark source&quot; href=&quot;https://wikidocs.net/81078&quot;&gt;
&lt;div class=&quot;bookmark-info&quot;&gt;
&lt;div class=&quot;bookmark-text&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;/span&gt;&lt;a style=&quot;letter-spacing: 0px;&quot; href=&quot;https://wikidocs.net/81078&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://wikidocs.net/81078&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/article&gt;
&lt;figure id=&quot;og_1698756827243&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;4-11 웹 서버, Nginx 사용해서 파이보에 접속하기&quot; data-og-description=&quot;여기서는 웹 서버 Nginx를 설치하고 사용해 보자. Nginx는 높은 성능을 목적으로 개발한 웹 서버로 파이썬 웹 프레임워크인 장고나 플라스크에서 많이 사용한다. Nginx를 &amp;hellip;&quot; data-og-host=&quot;wikidocs.net&quot; data-og-source-url=&quot;https://wikidocs.net/81078&quot; data-og-url=&quot;https://wikidocs.net/81078&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bAR5E4/hyUnN5zE5Q/oGXWjgfe3REI3Gtk98Xnd0/img.jpg?width=94&amp;amp;height=128&amp;amp;face=0_0_94_128,https://scrap.kakaocdn.net/dn/bXpfXC/hyUnW9glii/exjTDt8Z5qYpzwkeARul51/img.png?width=1006&amp;amp;height=496&amp;amp;face=0_0_1006_496&quot;&gt;&lt;a href=&quot;https://wikidocs.net/81078&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://wikidocs.net/81078&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bAR5E4/hyUnN5zE5Q/oGXWjgfe3REI3Gtk98Xnd0/img.jpg?width=94&amp;amp;height=128&amp;amp;face=0_0_94_128,https://scrap.kakaocdn.net/dn/bXpfXC/hyUnW9glii/exjTDt8Z5qYpzwkeARul51/img.png?width=1006&amp;amp;height=496&amp;amp;face=0_0_1006_496');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;4-11 웹 서버, Nginx 사용해서 파이보에 접속하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;여기서는 웹 서버 Nginx를 설치하고 사용해 보자. Nginx는 높은 성능을 목적으로 개발한 웹 서버로 파이썬 웹 프레임워크인 장고나 플라스크에서 많이 사용한다. Nginx를 &amp;hellip;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;wikidocs.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@odh0112/Django-Nginx-Gunicorn-%EC%97%B0%EB%8F%99-2-fb00a9kg&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://velog.io/@odh0112/Django-Nginx-Gunicorn-%EC%97%B0%EB%8F%99-2-fb00a9kg&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1698756852008&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[Django] - Nginx + Gunicorn 연동 (2)&quot; data-og-description=&quot;1. Nginx란 이전에 gunicorn을 이용해 서버 가동을 했다면 이제는 웹서버인 Nginx와 연동해 서비스를 꾸려나가볼 것입니다. 우선 Nginx는 트래픽이 많은 웹사이트의 서버(WAS)를 도와주는 고성능 경량 웹&quot; data-og-host=&quot;velog.io&quot; data-og-source-url=&quot;https://velog.io/@odh0112/Django-Nginx-Gunicorn-%EC%97%B0%EB%8F%99-2-fb00a9kg&quot; data-og-url=&quot;https://velog.io/@odh0112/Django-Nginx-Gunicorn-연동-2-fb00a9kg&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/iGUor/hyUlqRsIx5/VxJ25HE97PVuxPaYBzLlc0/img.png?width=950&amp;amp;height=500&amp;amp;face=0_0_950_500,https://scrap.kakaocdn.net/dn/wMoQI/hyUnWnSPGW/18Es6RQI3AEbK3iczaIdQK/img.jpg?width=1334&amp;amp;height=1334&amp;amp;face=537_560_793_839&quot;&gt;&lt;a href=&quot;https://velog.io/@odh0112/Django-Nginx-Gunicorn-%EC%97%B0%EB%8F%99-2-fb00a9kg&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://velog.io/@odh0112/Django-Nginx-Gunicorn-%EC%97%B0%EB%8F%99-2-fb00a9kg&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/iGUor/hyUlqRsIx5/VxJ25HE97PVuxPaYBzLlc0/img.png?width=950&amp;amp;height=500&amp;amp;face=0_0_950_500,https://scrap.kakaocdn.net/dn/wMoQI/hyUnWnSPGW/18Es6RQI3AEbK3iczaIdQK/img.jpg?width=1334&amp;amp;height=1334&amp;amp;face=537_560_793_839');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[Django] - Nginx + Gunicorn 연동 (2)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;1. Nginx란 이전에 gunicorn을 이용해 서버 가동을 했다면 이제는 웹서버인 Nginx와 연동해 서비스를 꾸려나가볼 것입니다. 우선 Nginx는 트래픽이 많은 웹사이트의 서버(WAS)를 도와주는 고성능 경량 웹&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;velog.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://kscory.com/dev/nginx/setting&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://kscory.com/dev/nginx/setting&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Uploaded by&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a style=&quot;color: #0070d1;&quot; href=&quot;https://github.com/jmjeon94/N2T&quot;&gt;N2T&lt;/a&gt;&lt;/p&gt;</description>
      <category>Middleware/WSGI</category>
      <category>gunicorn</category>
      <category>nginx</category>
      <category>nginx gunicorn 연동</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/150</guid>
      <comments>https://co-no.tistory.com/entry/gunicorn-gunicorn-nginx-%EC%97%B0%EB%8F%99#entry150comment</comments>
      <pubDate>Tue, 31 Oct 2023 21:43:35 +0900</pubDate>
    </item>
    <item>
      <title>[Gunicorn] RHEL9, Python 3.11 환경에서 Gunicorn(구니콘) 설치</title>
      <link>https://co-no.tistory.com/entry/Gunicorn-RHEL9-Python-311-%ED%99%98%EA%B2%BD%EC%97%90%EC%84%9C-Gunicorn%EA%B5%AC%EB%8B%88%EC%BD%98-%EC%84%A4%EC%B9%98</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;사전 요구 사항&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Python, pip 설치 - &lt;a title=&quot;[Python] RHEL9에서 Python 3.11 설치, 가상환경(venv) 구성&quot; href=&quot;https://co-no.tistory.com/entry/Python-RHEL9%EC%97%90%EC%84%9C-Python-311-%EC%84%A4%EC%B9%98-%EA%B0%80%EC%83%81%ED%99%98%EA%B2%BDvenv-%EA%B5%AC%EC%84%B1&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://co-no.tistory.com/entry/Python-RHEL9%EC%97%90%EC%84%9C-Python-311-%EC%84%A4%EC%B9%98-%EA%B0%80%EC%83%81%ED%99%98%EA%B2%BDvenv-%EA%B5%AC%EC%84%B1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;내 환경의 경우, Python 3.11로 개발하였기 때문에 아래 문서 모두 Python 3.11, pip 3.11을 기준으로 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;0. 프로젝트에 대한 가상환경 활성화&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;gunicorn은 pip로 설치하는 Python 패키지이므로, gunicorn에서 띄우려는 애플리케이션(프로젝트)에 대한 가상환경을 구성한 후에 해당 가상환경을 활성화하도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글의 예시에서는 배포하려는 애플리케이션의 이름을 &amp;lsquo;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;test_project&lt;/b&gt;&lt;/span&gt;&amp;rsquo;로 한다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Python venv(가상환경) 활성화&lt;/b&gt;&lt;/h4&gt;
&lt;pre class=&quot;applescript&quot;&gt;&lt;code&gt;# 'test_project'의 venv를 /apps/venvs/test_project 디렉토리에 이미 구성하였다고 가정한다.
source /apps/venvs/test_project/bin/activate
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;pip 최신화&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 pip 자체의 업데이트를 위해 다음 명령을 수행하자.&lt;/p&gt;
&lt;pre class=&quot;ada&quot;&gt;&lt;code&gt;# 가상환경 안에서는 'pip3.11' 로 사용하지 않고, 'pip'로 사용해도 된다. 
pip install --upgrade pip
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;venv 내의 pip 필요 패키지 설치&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;pip 업그레이드도 되었으니, 이제 배포하려는 프로젝트에서 사용하는 패키지들을 서버 내 가상환경에 설치해주어야 한다.&lt;/p&gt;
&lt;pre class=&quot;vala&quot;&gt;&lt;code&gt;# 가상환경 활성화 된 상태로 진행
# 개발자가 requirements.txt 를 줬다고 가정
pip install -r requirements.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;가상환경에 flask와 관련 패키지 설치&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre class=&quot;cmake&quot;&gt;&lt;code&gt;pip install flask
pip install flask-migrate
pip install flask-wtf
&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;1. gunicorn pip로 설치&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;autoit&quot;&gt;&lt;code&gt;# 'test_proejct' 가상환경이 activate 되어 있는 상태에서 수행
pip install gunicron
&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;2. gunicorn 설치 및 동작 확인&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2.1. gunicorn이 OS 상에서 어느 경로에 설치되어 있는지 확인&lt;/b&gt;&lt;/h4&gt;
&lt;pre class=&quot;dart&quot;&gt;&lt;code&gt;pip show gunicorn
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;789&quot; data-origin-height=&quot;262&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxfA09/btszlZFKoaL/0jdTHW2qaehdg3LEnSO9ck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxfA09/btszlZFKoaL/0jdTHW2qaehdg3LEnSO9ck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxfA09/btszlZFKoaL/0jdTHW2qaehdg3LEnSO9ck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxfA09%2FbtszlZFKoaL%2F0jdTHW2qaehdg3LEnSO9ck%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;789&quot; height=&quot;262&quot; data-origin-width=&quot;789&quot; data-origin-height=&quot;262&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; 가상환경(venv)로 지정한 디렉토리 안에 gunicorn 또한 설치된 것을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2.2. gunicorn 정상 실행 확인&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;gunicorn 설치 경로로 이동&lt;/p&gt;
&lt;pre class=&quot;awk&quot;&gt;&lt;code&gt;cd /apps/venvs/test_project/lib64/python3.11/site-packages
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;gunicorn 실행&lt;/p&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;gunicorn --bind 0.0.0.0:8000 [Flask 프로젝트명].wsgi &amp;amp;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;i&gt;&lt;span style=&quot;color: #ef6f53;&quot;&gt;--&lt;b&gt;bind 0.0.0.0:8000&lt;/b&gt;&amp;nbsp;&lt;/span&gt;&lt;/i&gt;:&lt;/span&gt; 모든 IP의 접속에 대해 허용하고, &lt;b&gt;8000&lt;/b&gt;번 Port로&lt;b&gt; gunicorn을 서비스&lt;/b&gt;한다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ef6f53; background-color: #dddddd;&quot;&gt;&lt;i&gt;&lt;b&gt;gunicorn&lt;/b&gt; &lt;/i&gt;&lt;/span&gt;앞에&lt;span style=&quot;color: #ef6f53;&quot;&gt; &lt;i&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt;nohup&lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;을 붙이면, gunicorn을 실행시킨 SSH 세션이 끊어져도 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;gunicorn 서버(서비스)는 계속 On 상태&lt;/b&gt;&lt;/span&gt;가 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2.3. 샘플 app을 gunicorn으로 구동&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트 코드의 github 링크를 첨부하니, 이걸 사용해서 배포했을 때 정상적으로 페이지가 나타난다면, 일단 gunicorn 구동에는 문제가 없다고 보면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/jjh2x/Flask_Sample_App&quot;&gt;https://github.com/jjh2x/Flask_Sample_App&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자 그럼 서버 환경에서 &lt;b&gt;github의 위 샘플 코드를 받아와 보자.&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;shell&quot; data-ke-language=&quot;shell&quot;&gt;&lt;code&gt;# python 프로젝트 코드가 저장되는 디렉토리로 이동
cd /apps/projects

# Sample Flask Web App 프로젝트를 위의 예시와 맞추기 위해,
# 'test_project' 라는 이름으로 clone
git clone &amp;lt;https://github.com/jjh2x/Flask_Sample_App.git&amp;gt; test_project&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클론이 완료되면 다음 명령어를 통해 아래 그림과 같은 결과를 확인할 수 있을 것이다.&lt;/p&gt;
&lt;pre class=&quot;vim&quot;&gt;&lt;code&gt;ls
ls -al test_project/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;774&quot; data-origin-height=&quot;341&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bm3Hj6/btszkRavRJj/p5Yr4kCYUdmS198kyT4a8k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bm3Hj6/btszkRavRJj/p5Yr4kCYUdmS198kyT4a8k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bm3Hj6/btszkRavRJj/p5Yr4kCYUdmS198kyT4a8k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbm3Hj6%2FbtszkRavRJj%2Fp5Yr4kCYUdmS198kyT4a8k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;774&quot; height=&quot;341&quot; data-origin-width=&quot;774&quot; data-origin-height=&quot;341&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;gunicorn으로 샘플 앱 구동&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;github에서 받아 온 sample app은 &amp;lsquo;pybo&amp;rsquo;라는 이름으로 애플리케이션 팩토리가 정의되어 있다. (=&lt;b&gt;init&lt;/b&gt;.py) 또한 해당 애플리케이션 팩토리 안에 &amp;lsquo;create_app()&amp;rsquo; 이라는 함수가 정의되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 아래와 같이 gunicorn으로 해당 app을 구동하면 된다.&lt;/p&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;gunicorn --bind 0:8000 &quot;pybo:create_app()&quot; &amp;amp;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;혹시 아래와 같은 페이지와 함께 sample app에 대한 접속이 되지 않는다면, 서버의 내부 방화벽에서 막고 있는 건 아닌지 확인이 필요하다. 필자는 &lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;테스트를 위해 내부 방화벽을 우선 다 내리고&lt;/b&gt;&lt;/span&gt; 진행하였다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;764&quot; data-origin-height=&quot;473&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dj9WLy/btszk2JIH5M/ZuBhyUykuJz8sUMJFtqGHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dj9WLy/btszk2JIH5M/ZuBhyUykuJz8sUMJFtqGHk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dj9WLy/btszk2JIH5M/ZuBhyUykuJz8sUMJFtqGHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdj9WLy%2Fbtszk2JIH5M%2FZuBhyUykuJz8sUMJFtqGHk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;764&quot; height=&quot;473&quot; data-origin-width=&quot;764&quot; data-origin-height=&quot;473&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;3. gunicorn의 로깅&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 log가 쌓일 디렉토리를 만들기 위해 아래 명령어를 수행하자.&lt;/p&gt;
&lt;pre class=&quot;awk&quot;&gt;&lt;code&gt;mkdir /apps/venvs/test_project/logs
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 gunicorn 구동 시, &lt;span style=&quot;color: #ef6f53; background-color: #dddddd;&quot;&gt;&lt;i&gt;&lt;b&gt;--access-logfile&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;, &lt;span style=&quot;color: #ef6f53; background-color: #dddddd;&quot;&gt;&lt;i&gt;&lt;b&gt;--error-logfile&lt;/b&gt;&lt;/i&gt;&lt;/span&gt; 플래그를 추가하여 다음과 같이 수행하면 된다.&lt;/p&gt;
&lt;pre class=&quot;awk&quot;&gt;&lt;code&gt;gunicorn --bind 0:8000 --access-logfile /apps/venvs/test_project/logs/access.log --error-logfile /apps/venvs/test_project/logs/error.log
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;후.. gunicorn 하나 켜고 끄기 명령어가 너무 빡센 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 포스팅에서 nginx와 gunicorn 연동 과정에서 gunicorn 서비스 파일도 만들 것이니, 일단은 임시로 위의 명령어를 사용하도록 하자&amp;hellip;!&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://wikidocs.net/81077&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://wikidocs.net/81077&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1698476460224&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;4-10 WSGI 서버 Gunicorn 사용하기&quot; data-og-description=&quot;이제 파이보에서 사용할 WSGI 서버인 Gunicorn을 설치하고 사용해 보자. &amp;gt; Gunicorn은 구니콘이라고 읽는다. [TOC] ## Gunicorn 설치하고 사용해 &amp;hellip;&quot; data-og-host=&quot;wikidocs.net&quot; data-og-source-url=&quot;https://wikidocs.net/81077&quot; data-og-url=&quot;https://wikidocs.net/81077&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/chpBpH/hyUlqJYPz3/wUoHXK3JkKCnV2SVvXdaC1/img.jpg?width=94&amp;amp;height=128&amp;amp;face=0_0_94_128&quot;&gt;&lt;a href=&quot;https://wikidocs.net/81077&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://wikidocs.net/81077&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/chpBpH/hyUlqJYPz3/wUoHXK3JkKCnV2SVvXdaC1/img.jpg?width=94&amp;amp;height=128&amp;amp;face=0_0_94_128');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;4-10 WSGI 서버 Gunicorn 사용하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;이제 파이보에서 사용할 WSGI 서버인 Gunicorn을 설치하고 사용해 보자. &amp;gt; Gunicorn은 구니콘이라고 읽는다. [TOC] ## Gunicorn 설치하고 사용해 &amp;hellip;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;wikidocs.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@yejin20/TILGunicorn-%EC%82%AC%EC%9A%A9-%EB%AA%85%EB%A0%B9%EC%96%B4&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://velog.io/@yejin20/TILGunicorn-%EC%82%AC%EC%9A%A9-%EB%AA%85%EB%A0%B9%EC%96%B4&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1698476470099&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[TIL]Gunicorn 사용하기&quot; data-og-description=&quot;Gunicorn은 Green Unicorn이라는 뜻으로 Python WSGI HTTP 서버다.웹서버와 WAS 사이를 연결하는 인터페이스로 파이썬에서는 wsgi를 사용하고 있다.이렇게 서버를 실행하면 EC2를 종료해도 서버가 계속 켜져&quot; data-og-host=&quot;velog.io&quot; data-og-source-url=&quot;https://velog.io/@yejin20/TILGunicorn-%EC%82%AC%EC%9A%A9-%EB%AA%85%EB%A0%B9%EC%96%B4&quot; data-og-url=&quot;https://velog.io/@yejin20/TILGunicorn-사용-명령어&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cCHpDs/hyUkl93JsS/1Goewbl6tvDR0YE1qK66M1/img.jpg?width=768&amp;amp;height=197&amp;amp;face=0_0_768_197,https://scrap.kakaocdn.net/dn/o1LIo/hyUlvxKhPE/Bt2ZwXKh1hIE26x6HwYCck/img.jpg?width=768&amp;amp;height=197&amp;amp;face=0_0_768_197,https://scrap.kakaocdn.net/dn/uzftY/hyUlvYOk0w/YIZV5YiAU7CFQx2s3gITz1/img.png?width=2626&amp;amp;height=1518&amp;amp;face=0_0_2626_1518&quot;&gt;&lt;a href=&quot;https://velog.io/@yejin20/TILGunicorn-%EC%82%AC%EC%9A%A9-%EB%AA%85%EB%A0%B9%EC%96%B4&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://velog.io/@yejin20/TILGunicorn-%EC%82%AC%EC%9A%A9-%EB%AA%85%EB%A0%B9%EC%96%B4&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cCHpDs/hyUkl93JsS/1Goewbl6tvDR0YE1qK66M1/img.jpg?width=768&amp;amp;height=197&amp;amp;face=0_0_768_197,https://scrap.kakaocdn.net/dn/o1LIo/hyUlvxKhPE/Bt2ZwXKh1hIE26x6HwYCck/img.jpg?width=768&amp;amp;height=197&amp;amp;face=0_0_768_197,https://scrap.kakaocdn.net/dn/uzftY/hyUlvYOk0w/YIZV5YiAU7CFQx2s3gITz1/img.png?width=2626&amp;amp;height=1518&amp;amp;face=0_0_2626_1518');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[TIL]Gunicorn 사용하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Gunicorn은 Green Unicorn이라는 뜻으로 Python WSGI HTTP 서버다.웹서버와 WAS 사이를 연결하는 인터페이스로 파이썬에서는 wsgi를 사용하고 있다.이렇게 서버를 실행하면 EC2를 종료해도 서버가 계속 켜져&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;velog.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Middleware/WSGI</category>
      <category>Flask Gunicorn</category>
      <category>gunicorn logging</category>
      <category>gunicorn logging flag</category>
      <category>Python Gunicorn 설치</category>
      <category>Python 샘플 애플리케이션</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/148</guid>
      <comments>https://co-no.tistory.com/entry/Gunicorn-RHEL9-Python-311-%ED%99%98%EA%B2%BD%EC%97%90%EC%84%9C-Gunicorn%EA%B5%AC%EB%8B%88%EC%BD%98-%EC%84%A4%EC%B9%98#entry148comment</comments>
      <pubDate>Sun, 29 Oct 2023 12:00:48 +0900</pubDate>
    </item>
    <item>
      <title>[Python] RHEL9에서 Python 3.11 설치, 가상환경(venv) 구성</title>
      <link>https://co-no.tistory.com/entry/Python-RHEL9%EC%97%90%EC%84%9C-Python-311-%EC%84%A4%EC%B9%98-%EA%B0%80%EC%83%81%ED%99%98%EA%B2%BDvenv-%EA%B5%AC%EC%84%B1</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;900&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GuBFx/btszhpsM4IT/7qPFrYkp92VdWyVO5qUPwK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GuBFx/btszhpsM4IT/7qPFrYkp92VdWyVO5qUPwK/img.png&quot; data-alt=&quot;출처 :&amp;amp;nbsp;https://discover.hubpages.com/technology/Installing-Python-on-Red-hat-enterprise-Linux-RHEL-6-and-RHEL-7&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GuBFx/btszhpsM4IT/7qPFrYkp92VdWyVO5qUPwK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGuBFx%2FbtszhpsM4IT%2F7qPFrYkp92VdWyVO5qUPwK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;517&quot; height=&quot;388&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;900&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 :&amp;nbsp;https://discover.hubpages.com/technology/Installing-Python-on-Red-hat-enterprise-Linux-RHEL-6-and-RHEL-7&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;0. dnf(yum) update&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최신 패키지를 사용하도록 dnf 업데이트를 수행하자.&lt;/p&gt;
&lt;pre class=&quot;shell&quot; data-ke-language=&quot;shell&quot;&gt;&lt;code&gt;dnf update&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;1. Python 3.11 dnf로 설치&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;shell&quot; data-ke-language=&quot;shell&quot;&gt;&lt;code&gt;dnf install python3.11&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; &lt;b&gt;dnf install python3&lt;/b&gt; 는 python 3.9 가 설치되므로, 유의하자!&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;2. Python 3.11 설치 확인&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;shell&quot; data-ke-language=&quot;shell&quot;&gt;&lt;code&gt;python3.11 --version&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; python 3.9 버전과 구분하기 위해, python3.11 을 구동하는 명령어는 default로 python3.11 로 설정되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 명령어 수행 시, 특정 버전이 나타난다면 설치는 잘 된 것이다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;pip를 설치하기에 앞서, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;Python은 Dependency 부분에서 꽤나 골치 아픈 언어이다. 사람들이 많이 사용하는 만큼, 업데이트 주기도 빠르다. 그리고 그 업데이트에 따라 변동사항이 꽤나 큰 경우도 많다.&lt;/b&gt;&lt;/span&gt; 따라서 Python을 개발 또는 운영 환경에 배포할 때에는 웬만하면, 아니 반드시.. &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;가상환경을 구성해서 각 프로젝트별로 애플리케이션 구동 환경을 구분지어야 한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가상환경의 필요성에 대한 글은 다음 글이 잘 설명해주는 것 같아 링크를 첨부한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://heytech.tistory.com/316&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://heytech.tistory.com/316&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;3. Python 가상환경 구성&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3.1. Python 애플리케이션이 배포될 폴더 생성&lt;/b&gt;&lt;/h4&gt;
&lt;pre class=&quot;shell&quot; data-ke-language=&quot;shell&quot;&gt;&lt;code&gt;# /(root) 하위에 'apps' 라고 생성하기로 한다.
mkdir /apps&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3.2. Python 가상환경(venv) 폴더 생성&lt;/b&gt;&lt;/h4&gt;
&lt;pre class=&quot;shell&quot; data-ke-language=&quot;shell&quot;&gt;&lt;code&gt;# /apps 하위에 웹 애플리케이션이 올라갈 'projects' 폴더 생성
mkdir /apps/projects

# /apps 하위에 Python 가상환경을 구분시킬 'venvs' 폴더 생성
# 'venvs' 폴더 하위에 각 프로젝트명 또는 애플리케이션 이름별로 가상환경 폴더를 구성한다.
mkdir /apps/venvs&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3.3. &amp;lsquo;venvs&amp;rsquo; 폴더 하위에 프로젝트에 대한 가상환경 구성&lt;/b&gt;&lt;/h4&gt;
&lt;pre class=&quot;shell&quot; data-ke-language=&quot;shell&quot;&gt;&lt;code&gt;# 이 글에서는 'test_project'라는 프로젝트를 예시로 사용하기로 한다.

# /apps/venvs 디렉토리로 이동
cd /apps/venvs

# RHEL9의 경우, venv 모듈이 별도 설치 없이 python3.11 만 설치해도 존재한다.
# 'venvs' 디렉토리 하위에 'test_project'라는 프로젝트의 가상환경 구성
python3.11 -m venv 'test_project'&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3.4. &amp;lsquo;test_project&amp;rsquo;의 가상환경 진입&lt;/b&gt;&lt;/h4&gt;
&lt;pre class=&quot;shell&quot; data-ke-language=&quot;shell&quot;&gt;&lt;code&gt;# 'test_project' 프로젝트의 가상환경 디렉토리로 이동
cd /apps/venvs/test_project&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기에서&lt;span style=&quot;background-color: #c0d1e7;&quot;&gt; &lt;b&gt;ls -al&lt;/b&gt; &lt;/span&gt;또는&lt;span style=&quot;background-color: #c0d1e7;&quot;&gt; &lt;b&gt;ll&lt;/b&gt; &lt;/span&gt;을 입력하면, python으로 가상환경을 구성했을 때 어떠한 디렉토리들이 생성되는지 다음과 같이 확인할 수 있다!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;647&quot; data-origin-height=&quot;170&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHs8Bn/btszhs3Z8WP/sn0Zm8resGwfobwqUUgnYk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHs8Bn/btszhs3Z8WP/sn0Zm8resGwfobwqUUgnYk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHs8Bn/btszhs3Z8WP/sn0Zm8resGwfobwqUUgnYk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHs8Bn%2Fbtszhs3Z8WP%2Fsn0Zm8resGwfobwqUUgnYk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;647&quot; height=&quot;170&quot; data-origin-width=&quot;647&quot; data-origin-height=&quot;170&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 다음 명령어를 통해 실제 &lt;b&gt;&amp;lsquo;&lt;span style=&quot;color: #409d00;&quot;&gt;test_project&lt;/span&gt;&amp;rsquo;의 가상환경을 작동&lt;/b&gt;시켜보자.&lt;/p&gt;
&lt;pre class=&quot;shell&quot; data-ke-language=&quot;shell&quot;&gt;&lt;code&gt;# 'test_project'의 가상환경 작동
source /apps/venvs/test_project/bin/activate&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가상환경이 활성화되면, 다음과 같이 Shell 앞에 &lt;b&gt;(venv 이름)&lt;/b&gt; 이 생긴다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;841&quot; data-origin-height=&quot;51&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/buu7Fx/btszjFhsisi/pgS9eodDzeOjyk07lAU3B0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/buu7Fx/btszjFhsisi/pgS9eodDzeOjyk07lAU3B0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/buu7Fx/btszjFhsisi/pgS9eodDzeOjyk07lAU3B0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbuu7Fx%2FbtszjFhsisi%2FpgS9eodDzeOjyk07lAU3B0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;841&quot; height=&quot;51&quot; data-origin-width=&quot;841&quot; data-origin-height=&quot;51&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가상환경에서 벗어나고 싶다면, 가상환경의 shell에서&lt;span style=&quot;background-color: #c0d1e7;&quot;&gt; &lt;b&gt;deactivate&lt;/b&gt; &lt;/span&gt;를 아무데에서나 입력하면 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;613&quot; data-origin-height=&quot;48&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ac9Fa/btszlkQZm70/0FbrHg7fAlEvQHIedFxuc1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ac9Fa/btszlkQZm70/0FbrHg7fAlEvQHIedFxuc1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ac9Fa/btszlkQZm70/0FbrHg7fAlEvQHIedFxuc1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAc9Fa%2FbtszlkQZm70%2F0FbrHg7fAlEvQHIedFxuc1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;613&quot; height=&quot;48&quot; data-origin-width=&quot;613&quot; data-origin-height=&quot;48&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/installing_and_using_dynamic_programming_languages/assembly_installing-and-using-python_installing-and-using-dynamic-programming-languages&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/installing_and_using_dynamic_programming_languages/assembly_installing-and-using-python_installing-and-using-dynamic-programming-languages&lt;/a&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>Python</category>
      <category>Linux Python 3.11</category>
      <category>Linux Python 3.9</category>
      <category>Linux Python 설치</category>
      <category>RHEL9 Python</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/147</guid>
      <comments>https://co-no.tistory.com/entry/Python-RHEL9%EC%97%90%EC%84%9C-Python-311-%EC%84%A4%EC%B9%98-%EA%B0%80%EC%83%81%ED%99%98%EA%B2%BDvenv-%EA%B5%AC%EC%84%B1#entry147comment</comments>
      <pubDate>Sat, 28 Oct 2023 15:39:57 +0900</pubDate>
    </item>
    <item>
      <title>[MSSQL] SQL Server Linked Server(연결된 서버) 추가와 로그인 매핑정보 / 삭제</title>
      <link>https://co-no.tistory.com/entry/MSSQL-SQL-Server-Linked-Server%EC%97%B0%EA%B2%B0%EB%90%9C-%EC%84%9C%EB%B2%84-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;SQL Server (MSSQL)의 Linked Server(연결된 서버)란?&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: 데이터베이스 엔진에서 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;다른 SQL Server 인스턴스&lt;/b&gt;&lt;/span&gt; 또는 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;Oracle과 같은 이기종 데이터베이스&lt;/b&gt;&lt;/span&gt; 제품의 테이블을 포함하는 Transact-SQL 문을 실행할 수 있도록 설정하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Linked Server 를 Configuration 하는 데에 있어, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;서버의 기능 및 필수 Parameter는 MS 공식 문서에서 제공하는 일반적인 예시와는 크게 다를 수 있다고 공식 문서에서도 명시되어 있으니&lt;/b&gt;&lt;/span&gt;, &lt;b&gt;다양한 케이스에 따라 많은 학습이 필요할 것&lt;/b&gt;으로 보인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필자의 경우에는, SSMS GUI로는 원인 파악이 제대로 되지 않는(?) 다양한 에러(대부분 복잡한 권한 문제가 아닐까 싶다&amp;hellip;)가 나는 것 같아, 아래와 같이 쿼리로 확실하게 수행하는 법을 기록해 두고자 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;0. &lt;span style=&quot;color: #8a3db6;&quot;&gt;현재 시스템&lt;/span&gt;의 Linked Server &lt;span style=&quot;color: #8a3db6;&quot;&gt;확인&lt;/span&gt; 쿼리&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;sql&quot; data-ke-language=&quot;sql&quot;&gt;&lt;code&gt;/* 현재 시스템에 세팅되어 있는 Linked-Server 확인 쿼리 */
SELECT * 
FROM master.dbo.sysservers
WHERE srvname = '[연결된 서버별칭]'

/* 현재 시스템에 세팅되어 있는 Linked-Server의 로그인 매핑 정보 확인 쿼리 */
SELECT *
FROM master.sys.linked_logins
WHERE remote_name = '[Remote DB 로그인 계정]'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1. &lt;span style=&quot;color: #8a3db6;&quot;&gt;Linked Server&lt;/span&gt; 추가&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;sql&quot; data-ke-language=&quot;sql&quot;&gt;&lt;code&gt;EXEC sp_addlinkedserver
	@server = N'[연결된 서버 별칭]'
	, @srvproduct = N'[OLE DB Source DB의 제품 이름]'
	, @provider = N'[OLE DB Provider의 PROGID(프로그래밍 식별자)]'
	, @datasrc = N'{IP},{PORT}'          -- PORT 생략 시 OLE DB의 Default 포트로 연결

/* 예시 */
EXEC sp_addlinkedserver
	@server = N'REMOTE_DB_TEST'
	, @srvproduct = N''                    -- 공식문서에 기본값이 Null이라고 되어 있지만, 이렇게 빈 문자열로 명시해주어야 에러 없이 생성이 된다.
	, @provider = N'SQLOLEDB'
	, @datasrc = N'10.123.123.123,55555'&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2. 생성된 Linked Server에 대한 &lt;span style=&quot;color: #8a3db6;&quot;&gt;로그인 계정 매핑 정보&lt;/span&gt; 추가&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로그인 계정 매핑 정보를 반드시 추가할 필요는 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 추가하지 않는다면, &amp;lsquo;&lt;b&gt;NT AUTHORITY\ANONYMOUS LOGON&lt;/b&gt;&amp;rsquo; 계정으로 연결을 시도하는데, 일반적으로 접근 권한이 제한되어 있다. 따라서 연결이 안될 것이다. 보안상 연결이 안 되는 것이 맞다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필자의 경우, SSMS의 GUI로 설정하는 건 parameter가 내가 의도하는 대로 설정이 되지 않는지, 아래와 같은 에러가 뜨면서 연결 테스트 진행이 되지 않아, &lt;b&gt;SP(Stored Procedure)로 수행&lt;/b&gt;하였다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;774&quot; data-origin-height=&quot;607&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VvnFM/btsyQTtdrdd/4bWklEURgPWvjGbrKPhSQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VvnFM/btsyQTtdrdd/4bWklEURgPWvjGbrKPhSQ1/img.png&quot; data-alt=&quot;Access to the remote server is denied because no login-mapping exists 에러&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VvnFM/btsyQTtdrdd/4bWklEURgPWvjGbrKPhSQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVvnFM%2FbtsyQTtdrdd%2F4bWklEURgPWvjGbrKPhSQ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;774&quot; height=&quot;607&quot; data-origin-width=&quot;774&quot; data-origin-height=&quot;607&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Access to the remote server is denied because no login-mapping exists 에러&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 아래와 같이 Linked-Server에 대한 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;로그인 계정 매핑 정보&lt;/b&gt;&lt;/span&gt;도 별도로 추가해 주어야 한다.&lt;/p&gt;
&lt;pre class=&quot;aspectj&quot;&gt;&lt;code&gt;EXEC sp_addlinkedsrvlogin
	@rmtsrvname = N'[연결된 서버 별칭]'
	, @useself = N'FALSE'              -- 로컬 로그인 계정으로 원격 로그인 계정에 그대로 사용할지 말지 정하는 옵션
	, @locallogin = N'[Local DB의 올바른 권한을 가진 계정]'
	, @rmtuser = N'[Remote DB의 올바른 권한을 가진 계정]'
	, @rmtpassword = N'[Remote DB 계정의 Password]'

/* 예시 */
EXEC sp_addlinkedsrvlogin
	@rmtsrvname = N'REMOTE_DB_TEST'
	, @useself = N'FALSE'
	, @locallogin = N'LOCALDBADM'
	, @rmtuser = N'REMOTEDBADM'
	, @rmtpassword = N'My_Password123~!'
&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;useself&lt;/b&gt;&lt;/span&gt; 의 값을 &lt;i&gt;&lt;b&gt;TRUE&lt;/b&gt;&lt;/i&gt;로 할 경우, 현재 로컬 서버의 로그인 계정으로 로그인을 하게 되는데, &lt;br /&gt;만약 원격 DB 서버에 동일한 이름의 계정이 없거나 필요한 권한을 가지고 있지 않으면, 로그인이 되지 않아 Linked-Server를 사용할 수 없으니, 이 점 유의하자!&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3. 생성된 Linked Server 연결 테스트&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;834&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5izH0/btsyQpTrNo9/2oiooDtgc1NcCgW1ixGwu1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5izH0/btsyQpTrNo9/2oiooDtgc1NcCgW1ixGwu1/img.png&quot; data-alt=&quot;SSMS의 DB 인스턴스 - [서버 개체] - [연결된 서버] - 해당 연결된 서버 마우스 우클릭 - '연결 테스트'&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5izH0/btsyQpTrNo9/2oiooDtgc1NcCgW1ixGwu1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5izH0%2FbtsyQpTrNo9%2F2oiooDtgc1NcCgW1ixGwu1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;378&quot; height=&quot;834&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;834&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;SSMS의 DB 인스턴스 - [서버 개체] - [연결된 서버] - 해당 연결된 서버 마우스 우클릭 - '연결 테스트'&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;유의할 점&lt;/b&gt; : Linked-Server를 만든 계정은 System Admin 권한을 가졌을 것이고, 이는 로그인 계정 매핑에 사용된 계정과는 다를 가능성이 높다. (SA 권한을 거기에 박는건 보안상 너무 위험하니까&amp;hellip;) 따라서, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;위와 같은 SSMS GUI 상의 [연결 테스트]는 로그인 계정으로 들어간 계정으로 다시 DB에 로그인하여 테스트 해야 한다. 이는 Linked-Server를 이용하는 프로시저와 Agent Job을 테스트 할 때에도 마찬가지이다.&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Linked-Server 삭제 방법&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Linked-Server 삭제를 할 때에는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;로그인 매핑 정보를 먼저 삭제한 후&lt;/b&gt;&lt;/span&gt;, Linked-Server 개체를 삭제해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SP로 수행하려면 &lt;b&gt;다음 쿼리를 순서대로 수행&lt;/b&gt;하면 된다.&lt;/p&gt;
&lt;pre class=&quot;sql&quot; data-ke-language=&quot;sql&quot;&gt;&lt;code&gt;/* Linked-Server 로그인 매핑 정보 삭제 SP */
EXEC sp_droplinkedsrvlogin
    @rmtsrvname = N'[연결된 서버 별칭]'
    , @locallogin = N'[로그인 매핑 정보의 Local 로그인 계정]'

/* Linked-Server 개체 삭제 SP */
EXEC sp_dropserver
	@server = N'[연결된 서버 별칭]'

/* 예시 */
EXEC sp_drolinkedsrvlogin
	@rmtsrvname = N'REMOTE_DB_TEST'
	, @locallogin = N'LOCALDBADM'

EXEC sp_dropserver
	@server = N'REMOTE_DB_TEST'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/sql/relational-databases/system-stored-procedures/sp-addlinkedserver-transact-sql?view=sql-server-ver16&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://learn.microsoft.com/ko-kr/sql/relational-databases/system-stored-procedures/sp-addlinkedserver-transact-sql?view=sql-server-ver16&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1697781319169&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;sp_addlinkedserver(Transact-SQL) - SQL Server&quot; data-og-description=&quot;sp_addlinkedserver(Transact-SQL)&quot; data-og-host=&quot;learn.microsoft.com&quot; data-og-source-url=&quot;https://learn.microsoft.com/ko-kr/sql/relational-databases/system-stored-procedures/sp-addlinkedserver-transact-sql?view=sql-server-ver16&quot; data-og-url=&quot;https://learn.microsoft.com/ko-kr/sql/relational-databases/system-stored-procedures/sp-addlinkedserver-transact-sql?view=sql-server-ver16&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/0TiFe/hyUgLNObP4/WIuwkdigUyYSzsYZT1KG7k/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/sql/relational-databases/system-stored-procedures/sp-addlinkedserver-transact-sql?view=sql-server-ver16&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://learn.microsoft.com/ko-kr/sql/relational-databases/system-stored-procedures/sp-addlinkedserver-transact-sql?view=sql-server-ver16&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/0TiFe/hyUgLNObP4/WIuwkdigUyYSzsYZT1KG7k/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;sp_addlinkedserver(Transact-SQL) - SQL Server&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;sp_addlinkedserver(Transact-SQL)&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;learn.microsoft.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/sql/relational-databases/system-stored-procedures/sp-addlinkedsrvlogin-transact-sql?view=sql-server-ver16&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://learn.microsoft.com/ko-kr/sql/relational-databases/system-stored-procedures/sp-addlinkedsrvlogin-transact-sql?view=sql-server-ver16&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1697781325417&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;sp_addlinkedsrvlogin(Transact-SQL) - SQL Server&quot; data-og-description=&quot;sp_addlinkedsrvlogin(Transact-SQL)&quot; data-og-host=&quot;learn.microsoft.com&quot; data-og-source-url=&quot;https://learn.microsoft.com/ko-kr/sql/relational-databases/system-stored-procedures/sp-addlinkedsrvlogin-transact-sql?view=sql-server-ver16&quot; data-og-url=&quot;https://learn.microsoft.com/ko-kr/sql/relational-databases/system-stored-procedures/sp-addlinkedsrvlogin-transact-sql?view=sql-server-ver16&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cJdZQr/hyUgJbnULv/KyAfhteZaJfZG5UWnZRY30/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/sql/relational-databases/system-stored-procedures/sp-addlinkedsrvlogin-transact-sql?view=sql-server-ver16&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://learn.microsoft.com/ko-kr/sql/relational-databases/system-stored-procedures/sp-addlinkedsrvlogin-transact-sql?view=sql-server-ver16&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cJdZQr/hyUgJbnULv/KyAfhteZaJfZG5UWnZRY30/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;sp_addlinkedsrvlogin(Transact-SQL) - SQL Server&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;sp_addlinkedsrvlogin(Transact-SQL)&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;learn.microsoft.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://blog.naver.com/diceworld/220311810558&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://blog.naver.com/diceworld/220311810558&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1697781333315&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;MSSQL 연결된서버 사용하기 (linked server)&quot; data-og-description=&quot;&amp;nbsp; &amp;nbsp; &amp;nbsp;- MSSQL 연결된 서버란? &amp;nbsp; &amp;nbsp; &amp;nbsp;MSSQL 은 연결된서버 기능을 ...&quot; data-og-host=&quot;blog.naver.com&quot; data-og-source-url=&quot;https://blog.naver.com/diceworld/220311810558&quot; data-og-url=&quot;https://blog.naver.com/diceworld/220311810558&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cSIPGf/hyUgUqpR43/UjxXp1UKeAIR4v4tL2Uah0/img.jpg?width=740&amp;amp;height=150&amp;amp;face=0_0_740_150&quot;&gt;&lt;a href=&quot;https://blog.naver.com/diceworld/220311810558&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://blog.naver.com/diceworld/220311810558&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cSIPGf/hyUgUqpR43/UjxXp1UKeAIR4v4tL2Uah0/img.jpg?width=740&amp;amp;height=150&amp;amp;face=0_0_740_150');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;MSSQL 연결된서버 사용하기 (linked server)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;- MSSQL 연결된 서버란? &amp;nbsp; &amp;nbsp; &amp;nbsp;MSSQL 은 연결된서버 기능을 ...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;blog.naver.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DB/SQL Server (MSSQL)</category>
      <category>MSSQL Linked Server</category>
      <category>MSSQL Linked Server Account</category>
      <category>MSSQL Linked Server Query</category>
      <category>MSSQL Linked Server 에러</category>
      <category>MSSQL Linked Server 쿼리</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/146</guid>
      <comments>https://co-no.tistory.com/entry/MSSQL-SQL-Server-Linked-Server%EC%97%B0%EA%B2%B0%EB%90%9C-%EC%84%9C%EB%B2%84-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0#entry146comment</comments>
      <pubDate>Fri, 20 Oct 2023 14:59:51 +0900</pubDate>
    </item>
    <item>
      <title>[보안] SSH Protocol의 암호화, Hashing 알고리즘 (feat. Linux OpenSSH)</title>
      <link>https://co-no.tistory.com/entry/%ED%86%B5%EC%8B%A0-SSH-Protocol%EC%9D%98-%EC%95%94%ED%98%B8%ED%99%94-Hashing-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-feat-Linux-OpenSSH</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;OpenSSH 기준으로, SSH의 &lt;b&gt;암호화&lt;/b&gt; 또는 &lt;b&gt;Hashing&lt;/b&gt;과 관련된 알고리즘의 분류를 다음과 같이 4가지 정도로 할 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Key Exchange&lt;/b&gt; Algorithms&lt;/li&gt;
&lt;li&gt;&lt;b&gt;MAC&lt;/b&gt; Algorithms&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Ciphers&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;HostKey&lt;/b&gt; Algorihtms&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SSH 프로토콜에서 통신을 할 때에는 SSH Client와 SSH Server 간에 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;위 알고리즘에 대해 서로 일치하는 게 반드시 1개는 필요&lt;/b&gt;&lt;/span&gt;하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;/etc/ssh/ssh_config&lt;/b&gt; 에는 해당 host가 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;SSH Client로 동작할 때&lt;/b&gt;&lt;/span&gt;에 지원하는 알고리즘 리스트가 나와 있다. 즉, 해당 configuration을 통해 weak algorithms을 인위적으로 제외시킬 수 있다는 것이다. 만약 KexAlgorithms, MACs, Ciphers, HostKeyAlgorithms 와 같은 구문이 없다면, 해당 OpenSSH 버전에서 Default로 지원하는 알고리즘 set을 사용하고 있는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;/etc/ssh/sshd_config&lt;/b&gt; 는 해당 host가 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;SSH Server로 동작할 때&lt;/b&gt;&lt;/span&gt;에 지원하는 알고리즘 리스트가 나와 있다. 해당 configuration을 통해 weak algorihtms 을 인위적으로 제외시킬 수 있다는 것이다. &lt;u&gt;사실상 SSH Server 쪽의 weak algorithms 들을 제외하여 원천적으로 차단하는 것이 보안 적용에 효과적&lt;/u&gt;이므로, 원격 제어 자주 당하거나(?) SFTP 서버 등으로 활용되는 Host의 경우, 반드시 sshd_config 를 철저하게 설정해 주어야 한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Key Exchange Algorihtms&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: SSH 프로토콜에서 Client와 Server 간에 Public Key(공개키)를 주고 받는데, 이 공개키를 기반으로 암호화 및 복호화에 사용되는 대칭키를 생성하게 된다. 이러한 SSH 프로토콜 상&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt; Client와 Server간에 Public Key를 주고 받는 과정 자체가 보호되어야 하기 때문에, 이 교환 과정에서 사용되는 알고리즘&lt;/b&gt;&lt;/span&gt;을 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;OpenSSH&lt;/b&gt; - 현재 Host가 &lt;b&gt;SSH Server&lt;/b&gt;로 동작할 때 지원하는 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;Key Exchange Algorithms&lt;/b&gt;&lt;/span&gt; 확인 방법&lt;/p&gt;
&lt;pre class=&quot;gradle&quot;&gt;&lt;code&gt;sshd -T | grep -oP '(?&amp;lt;=^kexalgorithms\\s)\\S+'
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;MAC Algorithms&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: SSH 프로토콜에서 Client와 Server 간에 데이터를 주고 받을 때, &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;해당 데이터가 올바른 Client 또는 올바른 Server로부터 온 게 맞는지 확인하기 위한 Hashing 알고리즘&lt;/b&gt;&lt;/span&gt;이다. 즉, &lt;b&gt;데이터의 무결성을 보장&lt;/b&gt;하기 위한 알고리즘이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;OpenSSH&lt;/b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;- 현재 Host가&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;SSH Server&lt;/b&gt;로 동작할 때 지원하는&amp;nbsp;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;MAC Algorithms&lt;/b&gt;&lt;/span&gt; 확인 방법&lt;/p&gt;
&lt;pre class=&quot;gradle&quot;&gt;&lt;code&gt;sshd -T | grep -oP '(?&amp;lt;=^macs\\s)\\S+'
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Ciphers&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: SSH 프로토콜에서 Client와 Server 간에 주고 받는 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;데이터의 실질적인 내용을 암호화하는 알고리즘Set&lt;/b&gt;&lt;/span&gt;이다. SSH Server에서 설정되어 있는 순서에 따라, Cipher Suite 채택에 대한 Preference가 결정된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Client로부터 받은 Cipher Suite 중에서 Server가 지원하는 Cipher Suite와 일치하는 것을 확인하고, 그 중 Server에서 가장 앞에 설정된 Cipher Suite가 Client 및 Server 간에 주고 받는 데이터에 대한 암호화 알고리즘set으로 채택된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;OpenSSH&lt;/b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;- 현재 Host가&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;SSH Server&lt;/b&gt;로 동작할 때 지원하는&amp;nbsp;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;Cipher Algorithms&lt;/b&gt;&lt;/span&gt; 확인 방법&lt;/p&gt;
&lt;pre class=&quot;gradle&quot;&gt;&lt;code&gt;sshd -T | grep -oP '(?&amp;lt;=^ciphers\\s)\\S+'
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;HostKey Algorithms&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: SSH 프로토콜에서 Client 및 Server의&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt; Host Key를 생성하고 검증하는 데 사용되는 암호화 알고리즘&lt;/b&gt;&lt;/span&gt;이다. 여기서 Host Key란, 해당 SSH Client에 대한 Server를 인증할 때 사용되는 Key이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;OpenSSH&lt;/b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;- 현재 Host가&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;SSH Server&lt;/b&gt;로 동작할 때 지원하는&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt; HostKey Algorithms&lt;/b&gt; &lt;/span&gt;확인 방법&lt;/p&gt;
&lt;pre class=&quot;gradle&quot;&gt;&lt;code&gt;sshd -T | grep -oP '(?&amp;lt;=^hostkeyalgorithms\\s)\\S+'
&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Security</category>
      <category>/etc/ssh/sshd_config</category>
      <category>/etc/ssh/ssh_config</category>
      <category>SSH Ciphers</category>
      <category>SSH Encryption Algorithms</category>
      <category>SSH Hashing Algorithms</category>
      <category>SSH HostKey</category>
      <category>SSH KEX</category>
      <category>SSH MAC</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/145</guid>
      <comments>https://co-no.tistory.com/entry/%ED%86%B5%EC%8B%A0-SSH-Protocol%EC%9D%98-%EC%95%94%ED%98%B8%ED%99%94-Hashing-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-feat-Linux-OpenSSH#entry145comment</comments>
      <pubDate>Mon, 18 Sep 2023 12:00:12 +0900</pubDate>
    </item>
    <item>
      <title>[Protocol] SSH의 개념, 통신 과정(feat. OpenSSH)</title>
      <link>https://co-no.tistory.com/entry/%ED%86%B5%EC%8B%A0-SSH%EC%9D%98-%EA%B0%9C%EB%85%90-%ED%86%B5%EC%8B%A0-%EA%B3%BC%EC%A0%95feat-OpenSSH</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;SSH(시큐어 셸, SecureSHell) 란?&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: 네트워크 상의 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;다른 컴퓨터에 로그인&lt;/b&gt;&lt;/span&gt;하거나 &lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;원격 시스템에서 명령을 실행&lt;/span&gt;&lt;/b&gt;하고 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;다른 시스템으로 파일을 복사&lt;/b&gt;&lt;/span&gt;할 수 있도록 해 주는 &lt;b&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;응용 프로그램&lt;/span&gt; 또는 그 &lt;span style=&quot;color: #8a3db6;&quot;&gt;프로토콜&lt;/span&gt;&lt;/b&gt;을 가리킨다.&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: right;&quot; data-ke-size=&quot;size16&quot;&gt;- 위키백과 -&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Default로 &lt;b&gt;22번 포트&lt;/b&gt;를 사용&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Sender - Receiver 간 주고 받는 데이터 자체가 암호화&lt;/b&gt;되어, 해당 패킷이 스니핑 되더라도 복호화할 수 있는 Key를 획득하지 못하면 해당 정보를 알 수 없게끔 설계되어 있다.&lt;/li&gt;
&lt;li&gt;SSH &lt;b&gt;Client&lt;/b&gt; : SSH 프로토콜을 이용하여 원격 시스템(SSH Server)에 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;접속 및 명령을 내리도록 하는 주체 &lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;SSH &lt;b&gt;Server&lt;/b&gt; : SSH Client로부터 SSH 프로토콜을 통해 &lt;b&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;받은 명령을 수행하는 주체(?)&lt;/span&gt;.&lt;/b&gt; 쉽게 말해, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;원격지 &lt;/b&gt;&lt;/span&gt;서버 또는 컴퓨터.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;등장 배경&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 원격 시스템에서의 명령을 실행하고 다른 시스템으로 파일을 복사할 수 있도록 해주는 동일한 기능을 가진 응용 프로그램은 기존에도 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;rsh, rlogin, telnet, ftp&lt;/b&gt; 등이 그것들인데, 이러한 응용 프로그램 또는 프로토콜들은 세션을 맺는 과정 또는 데이터를 통신하는 과정 등에서 암호화가 되어 있지 않아, *&lt;b&gt;스니핑(Sniffing) 공격&lt;/b&gt;에 늘 노출되어 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;✳ &lt;b&gt;스니핑(Sniffing)&lt;/b&gt; : 사전적 의미로는 &amp;lsquo;&lt;b&gt;코를 킁킁거리다&lt;/b&gt;&amp;rsquo;, &amp;lsquo;&lt;b&gt;냄새를 맡다&lt;/b&gt;&amp;rsquo;로, IT 용어에서는 송신자(Sender)와 수신자(Receiver) 간 &lt;b&gt;교환되는 패킷 정보를 네트워크 상에서 도청&lt;/b&gt;하는 행위를 말한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;SSH 통신 과정&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. Session Authentication&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SSH Client와 Server 간 세션이 맺어지려면, &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;Client와 Server 가 서로가 올바른 노드인지 인증하는 절차&lt;/b&gt;&lt;/span&gt;가 필요하다. SSH 프로토콜에서는 이를 &lt;b&gt;Public Key(공개키)&lt;/b&gt;와 &lt;b&gt;Private Key(개인키)&lt;/b&gt;로 이루어지는&lt;span style=&quot;color: #006dd7;&quot;&gt; &lt;b&gt;비대칭키 암호화 방식&lt;/b&gt;&lt;/span&gt;을 이용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세션이 맺어지기 전부터 이러한 인증 과정을 거치는 이유는, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;SSH Client 가 최초에 요청한 SSH Connection Request를 Attacker가 가로채어 SSH Server인 척 하지 못하게 하려는 이유&lt;/b&gt;&lt;/span&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Linux 에서는 대부분 OpenSSH 라는 프로그램을 통해 SSH 프로토콜을 이용하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SSH 프로토콜은 기본적으로 &lt;b&gt;Client의 Public Key, Private Key / Server의 Public Key, Private Key 가 갖추어져 있어야만&lt;/b&gt; 통신이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 SSH 프로토콜의 세션 인증 과정이 어떻게 진행되는 지 다음 그림을 통해 살펴보자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1948&quot; data-origin-height=&quot;1106&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Dctvw/btsueMyISPp/UB3JImTB4IDHwssAxwhvzk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Dctvw/btsueMyISPp/UB3JImTB4IDHwssAxwhvzk/img.png&quot; data-alt=&quot;SSH 프로토콜에서 SSH Client와 SSH Server 간 세션을 맺는 인증 과정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Dctvw/btsueMyISPp/UB3JImTB4IDHwssAxwhvzk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDctvw%2FbtsueMyISPp%2FUB3JImTB4IDHwssAxwhvzk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1948&quot; height=&quot;1106&quot; data-origin-width=&quot;1948&quot; data-origin-height=&quot;1106&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;SSH 프로토콜에서 SSH Client와 SSH Server 간 세션을 맺는 인증 과정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;✳ &lt;b&gt;KEX :&lt;/b&gt; SSH에서 &lt;b&gt;Key Exchange Algorithm&lt;/b&gt; 을 가리키는 말로, SSH Client와 Server가 서로의 Public Key를 공유할 때, Attacker가 해당 Public Key를 가로채어 SSH Client인 척 또는 SSH Server인 척 하지 못하도록 방지하는 알고리즘이다. 여기서 알아두어야 할 점은, 이 KEX 알고리즘은 암호화 알고리즘이 아니며, &lt;b&gt;서로 간 안전하게 Public Key를 공유할 수 있도록 해주는 알고리즘&lt;/b&gt;이라는 점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;✳ &lt;b&gt;해시 함수(Hashing) :&lt;/b&gt; 임의의 길이의 데이터를 고정된 길이의 데이터로 매핑하는 함수.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해시 함수에 의해 만들어진 출력값을 가지고 역으로 입력값을 찾는 것이 계산적으로 불가능하기 때문에, 암호화-복호화의 용도로 보기에는 어렵다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SSH 프로토콜에서는, SSH Connection 이 성공적으로 이루어지기 전에, 즉 &lt;b&gt;위 과정 중간에 Attacker가 잠입하여 교환되는 모든 정보를 조작할 수도&lt;/b&gt; 있으므로, 이를 방지하기 위해 **Sender 가 보낸 메시지가 변조되지 않았는지 확인(데이터의 무결성 보증)**하는 절차가 존재한다. 이 때 사용하는 알고리즘이 &lt;b&gt;MAC(Message Authentication Code)&lt;/b&gt; Algorithms 이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. User Authentication&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 세션 인증 과정을 거쳐 SSH Client와 SSH Server 간에 Connection이 열리게 되면, 이제 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;접속을 시도하는 User가 접속 권한이 있는 사람인지 확인하는 절차&lt;/b&gt;&lt;/span&gt;가 필요하다. 즉, 위 세션 과정에서 정상적인 과정을 거쳐 정상적으로 SSH Conneciton이 생성되었다 하더라도, &lt;u&gt;&lt;b&gt;SSH Client를 사용하는 유저 자체가 Attacker였다면, 말짱 도루묵이 된다.&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SSH 프로토콜에서 유저에 대한 Authentication을 하는 방법은 크게 2가지가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2.1. Password 인증&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사용자가 입력한 비밀번호를 Session Authentication 과정에서 생성한 Session Key로 암호화하여 SSH Server에게 보내고, 이를 SSH Server가 검증하면 끝나는 방식&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;보안상 권장하지 않는 방식&lt;/b&gt;&lt;/span&gt;이다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Attacker가 Brute-Force 공격으로 Password를 알아낼 수 있다.&lt;/li&gt;
&lt;li&gt;사용자가 PW를 까먹어버리면 큰일이다!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2.2. Key-Pair 인증&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;SSH Client에서 Public Key, Private Key를 생성&lt;/b&gt;&lt;/span&gt;하고, 이를&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt; SSH Server에 접속할 때 Public Key를 제출&lt;/b&gt;&lt;/span&gt;하여 인증되는 방식&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Password 방식보다 높은 수준의 보안&lt;/b&gt;이다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;SSH Server에 기존에 등록되어 있는 user 및 host가 아니라면, 일단 Attakcer의 host라고 의심하고 보는 것이다.&lt;/li&gt;
&lt;li&gt;Key-Pair 인증 방식을 적용하려면, 최초에 SSH Client가 &lt;b&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;ssh-copy-id&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/b&gt; 명령어를 사용하여 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;SSH Server에 Public Key 파일을 보내주어야&lt;/b&gt;&lt;/span&gt; 한다. 이때 &lt;b&gt;SSH Server에 대한 PW를 입력&lt;/b&gt;하여, SSH Server에 Public Key 파일을 넣을 수 있도록 한다.&lt;/li&gt;
&lt;li&gt;SSH Server에서 접속을 허용하는 Client의 Public Key가 &lt;b&gt;authorized_keys&lt;/b&gt; 파일에 한번 등록되었다면, SSH Client는 추후 접속에서 해당 Key 파일에 대한 Passphrase를 입력하기만 하면 SSH 접속이 가능해진다. (&lt;b&gt;Passphrase&lt;/b&gt;는 SSH Client에서 &lt;b&gt;ssh-keygen&lt;/b&gt; 명령어를 이용하여 키 파일을 생성할 때 입력할 수도 있고, 입력하지 않으면 Passphrase는 존재하지 않게 된다.)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2003&quot; data-origin-height=&quot;1106&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c1B3Yb/btst6PDlV3L/3uG716nfWtOVWNpuhlH2J1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c1B3Yb/btst6PDlV3L/3uG716nfWtOVWNpuhlH2J1/img.png&quot; data-alt=&quot;SSH Protocol의 User Athentication - Key-Pair 인증 방식&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c1B3Yb/btst6PDlV3L/3uG716nfWtOVWNpuhlH2J1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc1B3Yb%2Fbtst6PDlV3L%2F3uG716nfWtOVWNpuhlH2J1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2003&quot; height=&quot;1106&quot; data-origin-width=&quot;2003&quot; data-origin-height=&quot;1106&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;SSH Protocol의 User Athentication - Key-Pair 인증 방식&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://veneas.tistory.com/entry/Linux-%EB%A6%AC%EB%88%85%EC%8A%A4-ssh-%EB%8F%99%EC%9E%91-%EB%B0%A9%EC%8B%9D-%EC%84%A4%EC%B9%98-%EB%B0%8F-%EC%82%AC%EC%9A%A9%EB%B2%95&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://veneas.tistory.com/entry/Linux-%EB%A6%AC%EB%88%85%EC%8A%A4-ssh-%EB%8F%99%EC%9E%91-%EB%B0%A9%EC%8B%9D-%EC%84%A4%EC%B9%98-%EB%B0%8F-%EC%82%AC%EC%9A%A9%EB%B2%95&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1694961826672&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[Linux] 리눅스 ssh 동작 방식, 설치 및 사용법&quot; data-og-description=&quot;목차 1. SSH SSH 이란 Secure Shell Protocol의 약자로, FTP / Telnet에 비해 보안에 초점을 맞춘 Protocol입니다. 네트워크 상의 다른 컴퓨터에 로그인하거나 원격 시스템에서 명령을 실행하고 다른 시스템으&quot; data-og-host=&quot;veneas.tistory.com&quot; data-og-source-url=&quot;https://veneas.tistory.com/entry/Linux-%EB%A6%AC%EB%88%85%EC%8A%A4-ssh-%EB%8F%99%EC%9E%91-%EB%B0%A9%EC%8B%9D-%EC%84%A4%EC%B9%98-%EB%B0%8F-%EC%82%AC%EC%9A%A9%EB%B2%95&quot; data-og-url=&quot;https://veneas.tistory.com/entry/Linux-%EB%A6%AC%EB%88%85%EC%8A%A4-ssh-%EB%8F%99%EC%9E%91-%EB%B0%A9%EC%8B%9D-%EC%84%A4%EC%B9%98-%EB%B0%8F-%EC%82%AC%EC%9A%A9%EB%B2%95&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bpTOyt/hyTVRn4MES/daovSxFiCxNMWWPrAkXzok/img.png?width=800&amp;amp;height=259&amp;amp;face=0_0_800_259,https://scrap.kakaocdn.net/dn/tVA5o/hyTVS8kxzI/cLUkEFI2j29JkrYuy1T8Nk/img.png?width=800&amp;amp;height=259&amp;amp;face=0_0_800_259,https://scrap.kakaocdn.net/dn/fw62e/hyTY4lKxN8/uswSd3SGA9VwBkKkBDoKu0/img.png?width=1194&amp;amp;height=519&amp;amp;face=0_0_1194_519&quot;&gt;&lt;a href=&quot;https://veneas.tistory.com/entry/Linux-%EB%A6%AC%EB%88%85%EC%8A%A4-ssh-%EB%8F%99%EC%9E%91-%EB%B0%A9%EC%8B%9D-%EC%84%A4%EC%B9%98-%EB%B0%8F-%EC%82%AC%EC%9A%A9%EB%B2%95&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://veneas.tistory.com/entry/Linux-%EB%A6%AC%EB%88%85%EC%8A%A4-ssh-%EB%8F%99%EC%9E%91-%EB%B0%A9%EC%8B%9D-%EC%84%A4%EC%B9%98-%EB%B0%8F-%EC%82%AC%EC%9A%A9%EB%B2%95&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bpTOyt/hyTVRn4MES/daovSxFiCxNMWWPrAkXzok/img.png?width=800&amp;amp;height=259&amp;amp;face=0_0_800_259,https://scrap.kakaocdn.net/dn/tVA5o/hyTVS8kxzI/cLUkEFI2j29JkrYuy1T8Nk/img.png?width=800&amp;amp;height=259&amp;amp;face=0_0_800_259,https://scrap.kakaocdn.net/dn/fw62e/hyTY4lKxN8/uswSd3SGA9VwBkKkBDoKu0/img.png?width=1194&amp;amp;height=519&amp;amp;face=0_0_1194_519');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[Linux] 리눅스 ssh 동작 방식, 설치 및 사용법&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;목차 1. SSH SSH 이란 Secure Shell Protocol의 약자로, FTP / Telnet에 비해 보안에 초점을 맞춘 Protocol입니다. 네트워크 상의 다른 컴퓨터에 로그인하거나 원격 시스템에서 명령을 실행하고 다른 시스템으&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;veneas.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://gwonbookcase.tistory.com/56&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://gwonbookcase.tistory.com/56&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1694961831922&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;SSH 공개키 인증 과정&quot; data-og-description=&quot;1. 공개키 암호화란? 공개 키 암호 방식은 암호 방식의 한 종류로 사전에 비밀 키를 나눠가지지 않은 사용자들이 안전하게 통신할 수 있도록 한다. 공개 키 암호 방식에서는 공개 키와 비밀 키가 &quot; data-og-host=&quot;gwonbookcase.tistory.com&quot; data-og-source-url=&quot;https://gwonbookcase.tistory.com/56&quot; data-og-url=&quot;https://gwonbookcase.tistory.com/56&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/hDa3k/hyTVZTT5YQ/hWwSkkjb7hJj4nnhFcLs31/img.png?width=800&amp;amp;height=583&amp;amp;face=0_0_800_583,https://scrap.kakaocdn.net/dn/coOF2Q/hyTVOERoHM/VkodhNnRl7CCwGCKYE2nt0/img.png?width=800&amp;amp;height=583&amp;amp;face=0_0_800_583,https://scrap.kakaocdn.net/dn/bXukhh/hyTVRuOFwf/ukrdyOrX9iKW7M8IRoBl1K/img.jpg?width=2000&amp;amp;height=2000&amp;amp;face=0_0_2000_2000&quot;&gt;&lt;a href=&quot;https://gwonbookcase.tistory.com/56&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://gwonbookcase.tistory.com/56&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/hDa3k/hyTVZTT5YQ/hWwSkkjb7hJj4nnhFcLs31/img.png?width=800&amp;amp;height=583&amp;amp;face=0_0_800_583,https://scrap.kakaocdn.net/dn/coOF2Q/hyTVOERoHM/VkodhNnRl7CCwGCKYE2nt0/img.png?width=800&amp;amp;height=583&amp;amp;face=0_0_800_583,https://scrap.kakaocdn.net/dn/bXukhh/hyTVRuOFwf/ukrdyOrX9iKW7M8IRoBl1K/img.jpg?width=2000&amp;amp;height=2000&amp;amp;face=0_0_2000_2000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;SSH 공개키 인증 과정&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;1. 공개키 암호화란? 공개 키 암호 방식은 암호 방식의 한 종류로 사전에 비밀 키를 나눠가지지 않은 사용자들이 안전하게 통신할 수 있도록 한다. 공개 키 암호 방식에서는 공개 키와 비밀 키가&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;gwonbookcase.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://swalloow.github.io/ssh-tunneling/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://swalloow.github.io/ssh-tunneling/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1694961839717&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;SSH 프로토콜과 Tunneling 이해하기&quot; data-og-description=&quot;지금까지 아무 생각없이 SSH를 사용하다가 한번 정리해보았습니다. SSH Protocol SSH는 Secure Shell의 약자입니다. SSH는 한마디로 정의하면, 네트워크 상의 다른 컴퓨터에 로그인하거나 원격 시스템에&quot; data-og-host=&quot;swalloow.github.io&quot; data-og-source-url=&quot;https://swalloow.github.io/ssh-tunneling/&quot; data-og-url=&quot;https://swalloow.github.io/ssh-tunneling/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/A0oin/hyTY29iEpv/MGxAwYeNjCmvF1zKmsg0aK/img.jpg?width=1080&amp;amp;height=720&amp;amp;face=0_0_1080_720,https://scrap.kakaocdn.net/dn/BC1m4/hyTV2b1MRY/nNaQhNTJCngAJQqjM9IviK/img.jpg?width=1080&amp;amp;height=720&amp;amp;face=0_0_1080_720&quot;&gt;&lt;a href=&quot;https://swalloow.github.io/ssh-tunneling/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://swalloow.github.io/ssh-tunneling/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/A0oin/hyTY29iEpv/MGxAwYeNjCmvF1zKmsg0aK/img.jpg?width=1080&amp;amp;height=720&amp;amp;face=0_0_1080_720,https://scrap.kakaocdn.net/dn/BC1m4/hyTV2b1MRY/nNaQhNTJCngAJQqjM9IviK/img.jpg?width=1080&amp;amp;height=720&amp;amp;face=0_0_1080_720');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;SSH 프로토콜과 Tunneling 이해하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;지금까지 아무 생각없이 SSH를 사용하다가 한번 정리해보았습니다. SSH Protocol SSH는 Secure Shell의 약자입니다. SSH는 한마디로 정의하면, 네트워크 상의 다른 컴퓨터에 로그인하거나 원격 시스템에&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;swalloow.github.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://seunghyunson.tistory.com/4&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://seunghyunson.tistory.com/4&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1694961843067&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;SSH란 무엇일까?&quot; data-og-description=&quot;SSH란 무엇일까? SSH를 왜 사용할까? SSH의 장단점은? GitHub 계정 연동까지! 다들 한 번쯤 SSH라는 단어를 들어보거나 본 적이 있을 것입니다. GitHub에서 repository를 clone 받을 때도 등장하고, 배포용으&quot; data-og-host=&quot;seunghyunson.tistory.com&quot; data-og-source-url=&quot;https://seunghyunson.tistory.com/4&quot; data-og-url=&quot;https://seunghyunson.tistory.com/4&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bZUXK6/hyTY3NUy8q/X8hGWS6vgrrkCm77lj4okK/img.png?width=334&amp;amp;height=334&amp;amp;face=0_0_334_334,https://scrap.kakaocdn.net/dn/dqsJFY/hyTY64WquK/wBx6pSNdU1FCeEhkVKkLl1/img.png?width=334&amp;amp;height=334&amp;amp;face=0_0_334_334,https://scrap.kakaocdn.net/dn/xdlGw/hyTVRn4MSi/dEFmVmL2zPhUCl7ST6WXPK/img.png?width=1162&amp;amp;height=842&amp;amp;face=0_0_1162_842&quot;&gt;&lt;a href=&quot;https://seunghyunson.tistory.com/4&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://seunghyunson.tistory.com/4&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bZUXK6/hyTY3NUy8q/X8hGWS6vgrrkCm77lj4okK/img.png?width=334&amp;amp;height=334&amp;amp;face=0_0_334_334,https://scrap.kakaocdn.net/dn/dqsJFY/hyTY64WquK/wBx6pSNdU1FCeEhkVKkLl1/img.png?width=334&amp;amp;height=334&amp;amp;face=0_0_334_334,https://scrap.kakaocdn.net/dn/xdlGw/hyTVRn4MSi/dEFmVmL2zPhUCl7ST6WXPK/img.png?width=1162&amp;amp;height=842&amp;amp;face=0_0_1162_842');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;SSH란 무엇일까?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;SSH란 무엇일까? SSH를 왜 사용할까? SSH의 장단점은? GitHub 계정 연동까지! 다들 한 번쯤 SSH라는 단어를 들어보거나 본 적이 있을 것입니다. GitHub에서 repository를 clone 받을 때도 등장하고, 배포용으&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;seunghyunson.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>CS 지식 | 기초 용어,개념</category>
      <category>Kex</category>
      <category>Linux OpenSSH 통신과정</category>
      <category>linux ssh</category>
      <category>MACs Algoirhtms</category>
      <category>SSH 개념</category>
      <category>SSH 통신 과정</category>
      <category>SSH 통신 흐름</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/144</guid>
      <comments>https://co-no.tistory.com/entry/%ED%86%B5%EC%8B%A0-SSH%EC%9D%98-%EA%B0%9C%EB%85%90-%ED%86%B5%EC%8B%A0-%EA%B3%BC%EC%A0%95feat-OpenSSH#entry144comment</comments>
      <pubDate>Sun, 17 Sep 2023 23:35:18 +0900</pubDate>
    </item>
    <item>
      <title>[MSSQL] SQL Server의 메모리 관련 문제를 진단하는 1차적인 방법</title>
      <link>https://co-no.tistory.com/entry/MSSQL-SQL-Server%EC%9D%98-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EA%B4%80%EB%A0%A8-%EB%AC%B8%EC%A0%9C%EB%A5%BC-%EC%A7%84%EB%8B%A8%ED%95%98%EB%8A%94-1%EC%B0%A8%EC%A0%81%EC%9D%B8-%EB%B0%A9%EB%B2%95</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;476&quot; data-origin-height=&quot;280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cbOQtz/btsrTo0fqt9/QZKtGyINsHXrcGZGpjzQv1/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cbOQtz/btsrTo0fqt9/QZKtGyINsHXrcGZGpjzQv1/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cbOQtz/btsrTo0fqt9/QZKtGyINsHXrcGZGpjzQv1/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcbOQtz%2FbtsrTo0fqt9%2FQZKtGyINsHXrcGZGpjzQv1%2Fimg.webp&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;476&quot; height=&quot;280&quot; data-origin-width=&quot;476&quot; data-origin-height=&quot;280&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시작하기에 앞서, 이 포스팅 하나만으로 SQL Server의 &lt;b&gt;Memory Pressure (메모리 압박)&lt;/b&gt;을 진단하는 것은 섣부른 판단일 수 있다. 정확한 Memory Pressure를 진단하고 그것을 개선하는 프로세스는 상당히 디테일하게 진행이 되어야 하므로,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;굉장히 긴 튜닝의 여정이 될 수 있다는 점을 미리 알아두자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 &lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;Memory Alert&lt;/b&gt; &lt;/span&gt;이 떴다든가, &lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;유저가 쿼리 결과가 너무 늦는다거나&lt;/b&gt;&lt;/span&gt;와 같은 얘기를 들었을 때,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 SQL Server 상에서 Memory Pressure가 일어났을 것이라는 짐작해볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음은 가장 먼저 시도해 볼 간단한 쿼리 3가지를 소개한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;1. sys.dm_os_sys_memory&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: OS level 에서의 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;설정된(?) 메모리 관련 정보&lt;/b&gt;&lt;/span&gt;를 반환하는 테이블&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SQL Server는 기본적으로, OS level에 있는 external memory 조건과 하드웨어 기반의 물리적인 제한(물리적인 메모리 양 등)에 맞춰 제한되고 반응한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 가장 첫 번째로, &lt;b&gt;OS level 에서의 메모리 사용량&lt;/b&gt;이 어떻게 되는 지를 우선 체크해봐야 할 것이다.&lt;/p&gt;
&lt;pre class=&quot;sql&quot; data-ke-language=&quot;sql&quot;&gt;&lt;code&gt;SELECT [Total Physical Memory in MB] = total_physical_memory_kb/1024
	, [Physical Memory Available in MB] = available_physical_memory_kb/1024
	, system_memory_state_desc
FROM sys.dm_os_sys_memory&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;total_physical_memory&lt;/b&gt; : OS가 사용할 수 있는 물리적인 메모리 전체 총량&lt;/li&gt;
&lt;li&gt;&lt;b&gt;available_physical_memory&lt;/b&gt; : total_physical_memory 에서 가용 가능한 남은 용량&lt;/li&gt;
&lt;li&gt;&lt;b&gt;system_memory_state_desc&lt;/b&gt; : system_high_memory_signal_state 와 system_low_memory_signal_state 의 값에 따라 &lt;b&gt;문구&lt;/b&gt;가 정해지는 column
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;Available physical memory is high&lt;/b&gt;&lt;/span&gt;&lt;b&gt;)&lt;/b&gt; system_high_memory_signal_state = 1 / system_low_memory_signal_state = 0 &lt;b&gt;&amp;rArr; 가용가능한 Physical Memory 양이 충분하다.&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;Available physical memory is low&lt;/b&gt;&lt;/span&gt;&lt;b&gt;)&lt;/b&gt; system_high_memory_signal_state = 0 / system_low_memory_signal_state = 1 &lt;b&gt;&amp;rArr; 가용가능한 Physical Memory 양이 &lt;span style=&quot;color: #ee2323;&quot;&gt;부족&lt;/span&gt;하다.&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;Physical memory usage is steady&lt;/span&gt;)&lt;/b&gt; system_high_memory_signal_state = 0 / system_low_memory_signal_state = 0 &lt;b&gt;&amp;rArr; 가용가능한 Physical Memory 가 충분하지도, 부족하지도 않게 적절하다.&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;Physical memory state is transitioning&lt;/b&gt;&lt;/span&gt;) system_high_memory_signal_state = 0 / system_low_memory_signal_state = 0 &lt;b&gt;&amp;rArr; 가용가능한 Physical Memory 가 &lt;span style=&quot;color: #ee2323;&quot;&gt;급격하게 변화&lt;/span&gt;하는 순간에 이 쿼리가 수행되었다면 나올 수 있는 값이다.&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;위 값에서 실제 메모리 문제로 인식되는 것은 &lt;b&gt;&amp;lsquo;&lt;span style=&quot;color: #ee2323;&quot;&gt;Available physical memory is low&lt;/span&gt;&amp;rsquo;&lt;/b&gt; 라고 보면 될 것이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;2. sys.dm_os_process_memory&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: OS level 에서 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;프로세스에 할당된 메모리&lt;/b&gt;&lt;/span&gt;를 확인할 수 있는 테이블&lt;/p&gt;
&lt;pre class=&quot;sql&quot; data-ke-language=&quot;sql&quot;&gt;&lt;code&gt;SELECT [Physical Memory Used in MB] = physical_memory_in_use_kb/1024
	, [Physical Memory Low] = process_physical_memory_low
	, [Virtual Memory Low] = process_virtual_memory_low 
FROM sys.dm_os_process_memory&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;physical_memory_in_use_kb&lt;/b&gt; : OS에 보고된, &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;프로세스에서 실제 사용하는 메모리 분량&lt;/b&gt;&lt;/span&gt;을 KB 단위로 나타낸 값&lt;/li&gt;
&lt;li&gt;&lt;b&gt;process_physical_memory_low&lt;/b&gt; : 0 또는 1의 값으로, process 에서 사용 가능한 physical memory양이 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;부족할 때 1&lt;/b&gt;&lt;/span&gt;로 반응하는 값이다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;process_virtual_memory_low&lt;/b&gt; : 0 또는 1의 값으로, process 에서 사용 가능한 virtual memory (Physical memory 가 아닌 영역, 페이지 파일 등) 의 양이 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;부족할 때 1&lt;/b&gt;&lt;/span&gt;로 반응하는 값이다.
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;process_physical_memory_low&lt;/b&gt; 값과 &lt;b&gt;process_virtual_memory_low&lt;/b&gt; 값 중 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;둘 중 하나라도 1&lt;/b&gt;&lt;/span&gt;이 나온다면, &lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;Memory Pressure의 원인을 면밀히 조사해 볼 필요&lt;/b&gt;&lt;/span&gt;가 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;3. sys.dm_os_sys_info&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: Computer(노드)에 대한 다양한 metric과 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;현재 가용 가능하거나 SQL Server에 의해 소비되고 있는 리소스에 대한 정보&lt;/b&gt;&lt;/span&gt;를 반환하는 테이블&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;SQL Server 2008 버전에서 사용)&lt;/h3&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;SELECT [Physical Memory in MB] = physical_memory_in_bytes/1024/1024
	, [Virtual Memory in MB] = virtual_memory_in_bytes/1024/1024
	, [SQL Server Committed Memory in MB] = bpool_committed/1024
	, [SQL Server Target Committed Memory in MB] = bpool_commit_target/1024 
FROM sys.dm_os_sys_info
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;SQL Server 2012 이상 버전에서 사용)&lt;/h3&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;SELECT [Physical Memory in MB] = physical_memory_kb/1024
	, [Virtual Memory in MB] = virtual_memory_kb/1024
	, [SQL Server Committed Memory in MB] = committed_kb/1024
	, [SQL Server Target Committed Memory in MB] = committed_target_kb/1024 
FROM sys.dm_os_sys_info
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;physical_memory_kb&lt;/b&gt; | &lt;b&gt;physical_memory_in_bytes&lt;/b&gt; : 해당 machine의 physical memory 총량&lt;/li&gt;
&lt;li&gt;&lt;b&gt;virtual_memory_kb&lt;/b&gt; | &lt;b&gt;virtual_memory_in_bytes&lt;/b&gt; : 해당 machine의 virtual memory 총량&lt;/li&gt;
&lt;li&gt;&lt;b&gt;committed_kb&lt;/b&gt; | &lt;b&gt;bpool_committed&lt;/b&gt; : SQL Server memory manger에 의해 커밋된(committed) 메모리 양&lt;/li&gt;
&lt;li&gt;&lt;b&gt;committed_target_kb&lt;/b&gt; | &lt;b&gt;bpool_commit_target&lt;/b&gt; : SQL Server memory manager에 의해 소비될 수 있는 메모리 총량으로, 예상치를 의미한다. 이 값에 따라 SQL Server memory manager가 committed 메모리 양을 늘릴지 또는 축소할 지를 결정한다.
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;committed_target_kb &amp;gt; committed_kb&lt;/b&gt; &lt;br /&gt;&lt;/span&gt;&amp;rArr; SQL Server Memory Manager가 추가적인 메모리를 더 잡으려고 할 것이다. Memory Pressure 가 없이 아직 여유 있는 상태라고 봐도 무방하다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;committed_target_kb &amp;le; committed_kb&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&amp;rArr; SQL Server Memory Manager가 현재 커밋된 메모리를 줄일려고 할 것이므로, 현재 가용가능한 Memory 양을 봐야 한다. 만약 &lt;b&gt;(committed_kb - committed_target_kb)&lt;/b&gt; 값이 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;가용 가능한 Memory 양보다 크다면&lt;/b&gt;, &lt;b&gt;Memory Pressure 가 일어나고 있다&lt;/b&gt;&lt;/span&gt;고 볼 수 있을 것이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만일 위 3개의 쿼리 수행 결과, 좋지 않은 징후를 발견했다면, 현재 서버가 Memory Pressure에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;있다고 보고 면밀히 조사하는 것이 좋을 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DB/SQL Server (MSSQL)</category>
      <category>SQL Server Memory Pressure</category>
      <category>SQL Server 메모리 부족</category>
      <category>SQL Server 메모리 사용량</category>
      <category>SQL Server 메모리 압박</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/143</guid>
      <comments>https://co-no.tistory.com/entry/MSSQL-SQL-Server%EC%9D%98-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EA%B4%80%EB%A0%A8-%EB%AC%B8%EC%A0%9C%EB%A5%BC-%EC%A7%84%EB%8B%A8%ED%95%98%EB%8A%94-1%EC%B0%A8%EC%A0%81%EC%9D%B8-%EB%B0%A9%EB%B2%95#entry143comment</comments>
      <pubDate>Mon, 21 Aug 2023 17:00:42 +0900</pubDate>
    </item>
    <item>
      <title>[Prometheus] node_exporter와 Windows_exporter 에 적용시키는 샘플 rules.yml</title>
      <link>https://co-no.tistory.com/entry/Prometheus-nodeexporter%EC%99%80-Windowsexporter-%EC%97%90-%EC%A0%81%EC%9A%A9%EC%8B%9C%ED%82%A4%EB%8A%94-%EC%83%98%ED%94%8C-rulesyml</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;프로메테우스로 전사의 서버를 커버하려면, Linux 와 Windows Server 에 따라서 exporter 가 다르므로, 서로 다르게 rule을 적용시켜줘야 할 필요가 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 샘플은 &lt;b&gt;CPU usage&lt;/b&gt;, &lt;b&gt;Memory Usage&lt;/b&gt;, &lt;b&gt;Disk Space&lt;/b&gt; 를 기준으로 alert을 받기 위한 rules.yml 이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 rules.yml 의 파일명은 자유롭게 설정 가능하다!&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;Linux&lt;/span&gt;)&lt;/b&gt; &lt;b&gt;node_exporter&lt;/b&gt; 를 통해 metric을 수집하므로, 아래의 &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;node_exporter_rules.yml&lt;/b&gt;&lt;/span&gt; 을 적용 받는다.&lt;/p&gt;
&lt;pre id=&quot;code_1680246515742&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 'node_exporter_rules.yml'

groups:
  - name: custom_rules
    rules:
      - record: node_CPU_Usage_percent
        expr: 100 - (avg by (instance) (irate(node_cpu_seconds_total{mode=&quot;idle&quot;}[5m]) * 100))

      - record: node_Memory_Usage_percent
        expr: 100 - ((node_memory_MemAvailable_bytes * 100) / node_memory_MemTotal_bytes)

      - record: node_Filesystem_Free_percent
        expr: 100 * node_filesystem_free_bytes{mountpoint=&quot;/&quot;} / node_filesystem_size_bytes{mountpoint=&quot;/&quot;}

  - name: alert_rules
    rules:
      - alert: InstanceDown
        expr: up == 0
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: &quot;Instance [{{ $labels.instance }}] down&quot;
          description: &quot;[{{ $labels.instance }}] of job [{{ $labels.job }}] has been down for more than 1 minute.&quot;
     
      - alert: High_CPU_Usage_80
        expr: node_CPU_Usage_percent &amp;gt;= 80
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: &quot;Instance [{{ $labels.instance }}] CPU Usage High - 80%&quot;
          description: &quot;[{{ $labels.instance }}] has ben exceeded 80% of CPU usage in the last 5 minutes.&quot;
      
      - alert: High_CPU_Usage_90
        expr: node_CPU_Usage_percent &amp;gt;= 90
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: &quot;Instance [{{ $labels.instance }}] CPU Usage High - 90%&quot;
          description: &quot;[{{ $labels.instance }}] has ben exceeded 90% of CPU usage in the last 5 minutes.&quot;

      - alert: High_Memory_Usage_80
        expr: node_Memory_Usage_percent &amp;gt;=80
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: &quot;Instance [{{ $labels.instance }}] Memory usage High - 80%&quot;
          description: &quot;[{{ $labels.instance }}] of job [{{ $labels.job }}] has been exceeded {{ $value }}% or more of Memory usage.&quot;
       
      - alert: High_Memory_Usage_90
        expr: node_Memory_Usage_percent &amp;gt;= 90
        for: 3m
        labels:
          severity: critical
        annotations:
          summary: &quot;Instance [{{ $labels.instance }}] Memory usage High - 90%&quot;
          description: &quot;[{{ $labels.instance }}] of job [{{ $labels.job }}] has been exceeded {{ $value }}% or more of Memory usage.&quot;
         
      - alert: DiskSpace_Free_10
        expr: node_Filesystem_Free_percent &amp;lt;= 10
        labels:
          severity: critical
        annotations:
          summary: &quot;Instance [{{ $labels.instance }}] has 10% or less Free disk space&quot;
          description: &quot;[{{ $labels.instance }}] has only {{ $value }}% or less free.&quot;
      
      - alert: DiskSpace_Free_20
        expr: node_Filesytem_Free_percent &amp;lt;= 20
        labels:
          severity: warning
        annotations:
          summary: &quot;Instance [{{ $labels.instance }}] has 20% or less Free disk space&quot;
          description: &quot;[{{ $labels.instance }}] has only {{ $value }}% or less free.&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;Windows Server&lt;/span&gt;)&lt;/b&gt; &lt;b&gt;windows_exporter&lt;/b&gt; 를 통해 metric을 수집하므로, 아래의&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt; windows_exporter_rules.yml&lt;/b&gt;&lt;/span&gt; 을 적용 받는다.&lt;/p&gt;
&lt;pre id=&quot;code_1680246552988&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 'windows_exporter_rules.yml'

groups:
  - name: custom_record
    rules:
      - record: Windows_Server_CPU_Usage
        expr: 100 - (avg by (instance) (rate(windows_cpu_time_total{mode=&quot;idle&quot;}[2m])) * 100)

      - record: Windows_Server_Memory_Usage
        expr: 100 - ((windows_os_physical_memory_free_bytes / windows_cs_physical_memory_bytes) * 100)

      - record: Windows_Server_DiskSpace_Usage
        expr: 100 - (windows_logical_disk_free_bytes{volume!~&quot;HarddiskVolume.+&quot;} / windows_logical_disk_size_bytes{volume!~&quot;HarddiskVolume.+&quot;})*100


  - name: alert_rules
    rules:
      - alert: InstanceDown
        expr: up == 0
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: &quot;Instance [{{ $labels.instance }}] down&quot;
          description: &quot;[{{ $labels.instance }}] of job [{{ $labels.job }}] has been down for more than 1 minute.&quot;
      
      - alert: Windows_Server_CPU_Usage_90
        expr: Windows_Server_CPU_Usage &amp;gt;= 90
        for: 3m
        labels:
          severity: critical
        annotations:
          summary: &quot;Instance [{{ $labels.instance }}] CPU Usage High - 90%&quot;
          description: &quot;[{{ $labels.instance }}] has ben exceeded 90% of CPU usage in the last 3 minutes.&quot;
      
      - alert: Windows_Server_CPU_Usage_80
        expr: Windows_Server_CPU_Usage &amp;gt;= 80
        for: 3m
        labels:
          severity: warning
        annotations:
          summary: &quot;Instance [{{ $labels.instance }}] CPU Usage High - 80%&quot;
          description: &quot;[{{ $labels.instance }}] has ben exceeded 80% of CPU usage in the last 3 minutes.&quot;
       
      - alert: Windows_Server_Memory_Usage_90
        expr: Windows_Server_Memory_Usage &amp;gt;= 90
        for: 3m
        labels:
          severity: critical
        annotations:
          summary: &quot;Instance [{{ $labels.instance }}] Memory Usage High - 90%&quot;
          description: &quot;[{{ $labels.instance }}] has ben exceeded 90% of Memory usage in the last 3 minutes.&quot;
      
      - alert: Windows_Server_Memory_Usage_80
        expr: Windows_Server_Memory_Usage &amp;gt;= 80 unless on(instance) {instance=&quot;예외 적용시킬 호스트의 IP:Port&quot;}
        for: 3m
        labels:
          severity: warning
        annotations:
          summary: &quot;Instance [{{ $labels.instance }}] Memory Usage High - 80%&quot;
          description: &quot;[{{ $labels.instance }}] has ben exceeded 80% of Memory usage in the last 3 minutes.&quot;

      
      - alert: Windows_Server_DiskSpace_Usage_90
        expr: Windows_Server_DiskSpace_Usage &amp;gt;= 90
        labels:
          severity: critical
        annotations:
          summary: &quot;Instance [{{ $labels.instance }}] has 10% or less Free disk space&quot;
          description: &quot;Disk usage is more than 90%\n LABELS = {{ $labels }}\n VALUE = {{ $value }}&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 샘플의 '&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;Windows_Server_Memory_Usage_80&lt;/b&gt;&lt;/span&gt;' 이라는 이름의 alert을 보면, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;expr&lt;/b&gt;&lt;/span&gt; 에 &lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;unless on 구문&lt;/b&gt;&lt;/span&gt;도 사용 가능한 것을 확인할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;unless on(&lt;span style=&quot;color: #409d00;&quot;&gt;[앞 promquery 결과 값의 label]&lt;/span&gt;) {&lt;span style=&quot;color: #409d00;&quot;&gt;labelname&lt;/span&gt;=&quot;&lt;span style=&quot;color: #409d00;&quot;&gt;원하는 조건&lt;/span&gt;&quot;}&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 사용하여, unless 기준 앞 구절의 결과로 나온 값에서 원하는 label 을 기준으로 하여 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;해당 label의 특정 값을 가지면, 이 alert을 적용시키지 않도록 하는 구문&lt;/b&gt;&lt;/span&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 lable set &lt;span style=&quot;color: #333333; background-color: #c1bef9;&quot;&gt;(&lt;b&gt;{~}&lt;/b&gt;&lt;/span&gt;) 구문에서 &lt;span style=&quot;background-color: #c1bef9;&quot;&gt;&lt;b&gt;=~&lt;/b&gt;&lt;/span&gt; Operator로 정규식 형태로 표현도 가능하다. 예시는 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;unless on(instance) {instance&lt;span style=&quot;background-color: #9feec3;&quot;&gt;=~&lt;/span&gt;&quot;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;(&lt;/span&gt;A_HOSTNAME&lt;span style=&quot;background-color: #9feec3;&quot;&gt;)|(&lt;/span&gt;B_HOSTNAME&lt;span style=&quot;background-color: #9feec3;&quot;&gt;)&lt;/span&gt;&quot;}&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;rules.yml 파일 내의 내용이 syntax에 어긋나지 않는 지 확인하기&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1695259495355&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;bin/promtool check rules rules/node_exporter_rules.yml&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Promquery를 사용하면서 유용한 rules.yml 에 대한 문법들을 알게 되면 여기에 추가적으로 기록할 예정이다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1680245892833&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Alerting rules | Prometheus&quot; data-og-description=&quot;An open-source monitoring system with a dimensional data model, flexible query language, efficient time series database and modern alerting approach.&quot; data-og-host=&quot;prometheus.io&quot; data-og-source-url=&quot;https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/&quot; data-og-url=&quot;https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/OZ9JZ/hyR6SaNQG9/MU9gSdi8TI0SXI1nGFlGY0/img.png?width=192&amp;amp;height=192&amp;amp;face=0_0_192_192&quot;&gt;&lt;a href=&quot;https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/OZ9JZ/hyR6SaNQG9/MU9gSdi8TI0SXI1nGFlGY0/img.png?width=192&amp;amp;height=192&amp;amp;face=0_0_192_192');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Alerting rules | Prometheus&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;An open-source monitoring system with a dimensional data model, flexible query language, efficient time series database and modern alerting approach.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;prometheus.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://awesome-prometheus-alerts.grep.to/rules.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://awesome-prometheus-alerts.grep.to/rules.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1680245929911&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Awesome Prometheus alerts&quot; data-og-description=&quot;Collection of alerting rules&quot; data-og-host=&quot;awesome-prometheus-alerts.grep.to&quot; data-og-source-url=&quot;https://awesome-prometheus-alerts.grep.to/rules.html&quot; data-og-url=&quot;http://awesome-prometheus-alerts.grep.to/rules.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://awesome-prometheus-alerts.grep.to/rules.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://awesome-prometheus-alerts.grep.to/rules.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Awesome Prometheus alerts&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Collection of alerting rules&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;awesome-prometheus-alerts.grep.to&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://stackoverflow.com/questions/69435005/use-conditional-operator-in-prometheus-alert-rules-to-set-severity&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://stackoverflow.com/questions/69435005/use-conditional-operator-in-prometheus-alert-rules-to-set-severity&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Observability</category>
      <category>Prometheus node exporter rules sample</category>
      <category>Prometheus rules exception</category>
      <category>Prometheus rules sample</category>
      <category>Prometheus windows exporter rules sample</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/139</guid>
      <comments>https://co-no.tistory.com/entry/Prometheus-nodeexporter%EC%99%80-Windowsexporter-%EC%97%90-%EC%A0%81%EC%9A%A9%EC%8B%9C%ED%82%A4%EB%8A%94-%EC%83%98%ED%94%8C-rulesyml#entry139comment</comments>
      <pubDate>Fri, 31 Mar 2023 16:18:53 +0900</pubDate>
    </item>
    <item>
      <title>[MSSQL] SQL Server 호스트의 Disk Space Alert 설정하기 / Powershell 방식 VS MSSQL 쿼리 방식</title>
      <link>https://co-no.tistory.com/entry/MSSQL-SQL-Server-%ED%98%B8%EC%8A%A4%ED%8A%B8%EC%9D%98-Disk-Space-Alert-%EC%84%A4%EC%A0%95%ED%95%98%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;DBA로서, 데이터베이스가 저장되는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;Disk의 Space를 관리하는 일은 대단히 중요&lt;/b&gt;&lt;/span&gt;하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 파일이 저장될 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;Disk의 용량이 부족하다면, 당연하게도 데이터가 계속적으로 증가하는 서비스는 멈추게 된다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;따라서 DBA는 데이터베이스가 저장되는 Disk의 Space를 수시로 확인하여 용량이 부족할 경우, 스토리지 담당자와 컨택하여 최대한 빠르게 스토리지 공간을 늘리는 것이 중요하다. 그러기 위해서는 Disk Space를 수시로 체크하고 DBA와 스토리지 담당자에게 Alert을 보내는 시스템을 구축해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이번 포스팅에서 그&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt; Alert 시스템 구축&lt;/b&gt;&lt;/span&gt;에 대해 간단히 알아보자!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 포스팅에서는 크게 2가지 방법을 소개한다. 첫번째는 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;Powershell 스크립트&lt;/b&gt;&lt;/span&gt; 방법, 두번째는 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;MSSQL 쿼리&lt;/b&gt;&lt;/span&gt;를 활용한 방법에 대해 알아볼 것이다. 또한 alert 시스템은 실제 Production 환경에서 5분 단위로 job이 돌게끔 지정하기도 하는데, 이렇게 자주 도는 만큼&amp;nbsp; 서버의 리소스를 많이 차지하면 안되므로, 어떤게 더 리소스 효율적인지도 알아보자!&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. &lt;span style=&quot;color: #006dd7;&quot;&gt;Powershell&lt;/span&gt; &lt;span style=&quot;color: #006dd7;&quot;&gt;스크립트&lt;/span&gt; 방식&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1680161255270&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# SQL Server가 설치되어 있는 hostname을 'hostname' 변수에 담기
$hostname=Get-WMIObject Win32_ComputerSystem | Select-Object -ExpandProperty name

# 임계치 설정 (GB)
# powershell의 hashtable 자료형으로 선언. Disk의 Drive Letter와 Threshold 값을 매칭시킨다.
$thresholdList = @{
    # Threshold 값은 각 드라이브 Total Size의 10% 정도로 잡았다.
    C = 20
    D = 50
    K = 15
    L = 10
    M = 0.05
    T = 2.5
    S = 1
}

# 이메일 정보 설정
$smtpServer = &quot;SMTP Server IP&quot;
$smtpPort = [SMTP Server Port]
$username = &quot;SMTP Server Authentication Username&quot;
$password = &quot;SMTP Server Authentication Password&quot;
$from = &quot;Alert 메일의 보내는 이를 지정&quot;
$to = &quot;Alert 메일이 가는 대상을 지정, 여러 명 가능&quot;
$subject = &quot;$hostname : DISK Space Alert&quot;	# $hostname 변수를 사용하여 Alert의 대상이 되는 호스트네임을 메일 제목에 확인하기 쉽게 넣기
$body = &quot;&quot;	# 메일의 내용에 해당하는 부분으로, 아래 foreach 구문 위해 빈 str으로 지정

# 드라이브 목록 설정
$drives = Get-PSDrive -PSProvider FileSystem | Where-Object { $_.Free -ne $null -and $_.Root -notlike '*swdist*' }

# 각 드라이브별 공간 확인
foreach ($drive in $drives) {
    $driveLetter = $drive.Root	# C 드라이브를 예로 들면, 'C:\' 가 'driveLetter' 변수에 담기게 됨.
    $pdriveLetter = $driveLetter[0]	# 'C:\'에서 첫번째 문자인 'C'만 추출.

    $freeSpace = [math]::Round($drive.Free / 1GB, 2)	# GB 단위로 체크할 것이므로, '1GB' 로 나눈다.
    $totalSpace = [math]::Round(($drive.Used + $drive.Free) / 1GB, 2)
    $percentFree = [math]::Round(($freeSpace / $totalSpace) * 100, 2)


    # 각 드라이브별로 threshold 값 체크하여 body 메시지 작성해주기.
    # 드라이브의 남은 용량이 threshold 값보다 작을 경우, body에 메시지를 추가한다.
    if ($freeSpace -lt $thresholdList[&quot;$pdriveLetter&quot;]) {
        $body = $body + &quot;`n`n&quot; + &quot;'$hostname' : Drive $driveLetter is running low on disk space (Free: $freeSpace GB, Total: $totalSpace GB, Free %: $percentFree %)&quot;
    }
    # 명목상 powershell 상에서 else문을 타는지 확인하기 위함.
    else {
        Write-Host &quot;'$hostname' : Drive $driveLetter is available.&quot;
    }
}

# 'body' 변수가 빈 문자열이 아니라면 이메일 발송
if ($body -ne &quot;&quot;) {
    Send-MailMessage -SmtpServer $smtpServer -Port $smtpPort -From $from -To $to -Subject $subject -Body $body    
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2. &lt;span style=&quot;color: #006dd7;&quot;&gt;MSSQL 쿼리&lt;/span&gt; 방식&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;MSSQL 쿼리 방식은 &lt;b&gt;[msdb]&lt;/b&gt; 를 활용한다. 참고로 SQL Server에서 [msdb] 란, SQL Server 엔진을 설치하면 기본으로 생성되는 시스템 데이터베이스로, SQL Server Agent의 Alerts 및 Jobs 를 예약하고, SSMS, Service Broker 및 Database Mail과 같은 기타 기능에 사용되는 데이터베이스이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MSSQL 쿼리 방식의 디스크 여유 공간을 확인하는 로직은 Powershell과 비슷하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[현재 드라이브들의 &lt;span style=&quot;color: #006dd7;&quot;&gt;남은 용량을 테이블에 기록&lt;/span&gt;한다.]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;gt; &lt;b&gt;[각 드라이브별 &lt;span style=&quot;color: #006dd7;&quot;&gt;Threshold를 기록해놓은 테이블을 참조&lt;/span&gt;한다.]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;gt; &lt;b&gt;[지정해놓은 Threshold보다 드라이브의 남은 용량이 작다면,&lt;span style=&quot;color: #006dd7;&quot;&gt; 메일의 내용 부분에 해당하는 변수에 담는다.]&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;gt; [&lt;b&gt;최종적으로 메일의 내용 부분에 해당하는 변수를 파라미터로, &lt;span style=&quot;color: #006dd7;&quot;&gt;메일을 전송&lt;/span&gt;한다.]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 과정을 수행하기 위해서는 &lt;u&gt;&lt;b&gt;먼저 [msdb]에 테이블을 생성해야 한다.&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2-1. Disk Space의 Threshold 정보를 지정하여 넣을 &lt;span style=&quot;color: #006dd7;&quot;&gt;테이블 생성&lt;/span&gt; - '&lt;span style=&quot;color: #409d00;&quot;&gt;driveThreshold&lt;/span&gt;'&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1680163023092&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* Disk Space Threshold 테이블 생성 */

USE [msdb]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[driveThreshold](
	[drive_letter] [varchar](1) NOT NULL,
	[total_size_MB] [int] NULL,
	[threshold_size_MB] [int] NULL,
	[is_check] [int] NULL,	-- is_check는 해당 드라이브에 대하여 alert 을 적용할 지 말지 선택할 때 사용한다.
PRIMARY KEY CLUSTERED 
(
	[drive_letter] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[driveThreshold] ADD  DEFAULT ((1)) FOR [is_check]
GO&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2-2. 드라이브별 Threshold 값 지정하여 '&lt;span style=&quot;color: #409d00;&quot;&gt;diskThreshold&lt;/span&gt;' 테이블에 &lt;span style=&quot;color: #006dd7;&quot;&gt;넣기&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;우선, OS의 각 드라이브별 총 사이즈를 확인하기 위해 다음 쿼리 '&lt;b&gt;xp_cmdshell&lt;/b&gt;' 을 이용할 건데, 이는 sp_configure를 통해 xp_cmdshell 이 수행되도록 전역 설정 변경이 필요하다. 아래 쿼리를 수행하여 xp_cmdshell 을 enable 설정하자. 보안상 계속 enable 해두는 것은 위험하므로, &lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;이 2-2. 마무리 단계에 xp_cmdshell 을 다시 disable 할 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1691371535067&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;EXECUTE sp_configure 'show advanced options', 1
GO
RECONFIGURE 	-- reconfigure 명령어는 'ALTER SETTINGS' 서버 수준 권한 또는  sysadmin 및 serveradmin 고정 서버 역할이 필요하다.
GO

EXECUTE sp_configure 'xp_cmdshell', 1;
GO
RECONFIGURE
GO

EXECUTE sp_configure 'show advanced options', 0
GO
RECONFIGURE
GO&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OS에 mount 되어 있는 drive 의 총 사이즈 (=Capacity), 사용 가능 공간 (=Free Space) 로 &lt;b&gt;임시테이블 생성&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1691373154234&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;DECLARE @svrName VARCHAR(255)
DECLARE @sql VARCHAR(400)

SET @svrName = @@SERVERNAME
SET @sql = 'powershell.exe -c &quot;Get-WmiObject -ComputerName ' + QUOTENAME(@svrName,'''') + ' -Class Win32_Volume -Filter ''DriveType = 3'' | select name,capacity,freespace | foreach{$_.name+''|''+$_.capacity/1048576+''%''+$_.freespace/1048576+''*''}&quot;'

--creating a temporary table
CREATE TABLE #output
(line varchar(255))

--inserting disk name, total space and free space value in to temporary table
INSERT INTO #output
EXEC xp_cmdshell @sql

GO&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1680163324726&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* diskThreshold 테이블에 각 드라이브별 Threshold 값 지정  */

-- 위 #output 임시 테이블 통해 드라이브별 총 사이즈를 'driveThreshold' 테이블에 삽입
INSERT INTO [msdb].[dbo].[driveThreshold] ([drive_letter], [total_size_MB])
--script to retrieve the values in MB from PS Script output
	SELECT RTRIM(LTRIM(SUBSTRING(line,1,CHARINDEX('|',line) -3)))		AS [drive_name]
	   , ROUND(CAST(RTRIM(LTRIM(SUBSTRING(line,CHARINDEX('|',line)+1,
	   (CHARINDEX('%',line) -1)-CHARINDEX('|',line)) )) AS Float),0)	AS [Capacity (MB)]
	FROM #output
	WHERE line like '[A-Z][:]%'
	ORDER BY [drive_name]

-- driveThreshold 테이블 데이터 Insert 잘 되었는지 확인
SELECT * FROM [msdb].[dbo].[driveThreshold]

-- Threshold 값 일괄적으로 각 드라이브의 Total Size * 0.1 (10%) 로 변경하기
UPDATE [msdb].[dbo].[driveThreshold]
SET [threshold_size_MB] = [total_size_MB] * 0.1

--'driveThreshold' 테이블 값 삽입하기 위해 만들었던 임시테이블 삭제
DROP TABLE #output

GO&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;xp_cmdshell&lt;/b&gt;&lt;/span&gt; &lt;b&gt;disable&lt;/b&gt; 설정&lt;/p&gt;
&lt;pre id=&quot;code_1691374050926&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;EXECUTE sp_configure 'show advanced options', 1
GO
RECONFIGURE 	-- reconfigure 명령어는 'ALTER SETTINGS' 서버 수준 권한 또는  sysadmin 및 serveradmin 고정 서버 역할이 필요하다.
GO

EXECUTE sp_configure 'xp_cmdshell', 0;
GO
RECONFIGURE
GO

EXECUTE sp_configure 'show advanced options', 0
GO
RECONFIGURE
GO&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2-3. 쿼리가 수행되는 순간의 각 드라이브 여유 공간을 기록할 &lt;span style=&quot;color: #006dd7;&quot;&gt;테이블 생성&lt;/span&gt; - '&lt;span style=&quot;color: #409d00;&quot;&gt;driveAvailable&lt;/span&gt;'&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1680163617833&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* 현재 드라이브의 남은 용량을 기록할 테이블('driveAvailable') 생성 */

USE [msdb]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[driveAvailable](
	[id] [int] IDENTITY(1,1) NOT NULL,		-- 드라이브 사이즈 기록의 순번 용도
	[drive_letter] [varchar](1) NULL,
	[drive_available_MB] [int] NULL,
	[datetime] [datetime] NULL,				-- 드라이브 사이즈를 체크한 순간의 시간 기록
PRIMARY KEY CLUSTERED 
(
	[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[driveAvailable] ADD  DEFAULT (getdate()) FOR [datetime]
GO&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2-4. SQL Server Agent의 &lt;span style=&quot;color: #006dd7;&quot;&gt;Job 으로 등록할 쿼리&lt;/span&gt; (Job step의 Type을 T-SQL로 지정)&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1680164276446&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;USE [msdb]

SET NOCOUNT ON	-- 쿼리 수행결과 중 영향받은 행 수를 나타내는 메시지 반환을 하지 않겠다.

DECLARE @subjectstr varchar(100)
	, @querystr varchar(1000)
	, @limit int, @rowcnt int

INSERT INTO msdb.dbo.driveAvailable(drive_letter, drive_available_MB) 
EXEC xp_fixeddrives

SET @rowcnt = @@rowcount

SET @subjectstr = @@servername + ': DISK Space Alert'	--메일 제목
SET @querystr ='
SELECT ''&quot;'' + @@servername +''&quot;: ''+ da.drive_letter + '' drive is '' + convert(varchar(10), convert(numeric(5,2), ((drive_available_MB/(total_size_MB * 1.0)) * 100))) + '' % remained. ('' + convert(varchar(10), drive_available_MB) + '' MB available)''
FROM msdb.dbo.driveThreshold t 
	JOIN (
	    SELECT TOP (' + CONVERT(VARCHAR(10), @rowcnt) + ') * 
	    FROM msdb.dbo.driveAvailable ORDER BY id DESC
	    ) da 
	ON t.drive_letter = da.drive_letter
WHERE is_check = 1
	AND da.drive_available_MB &amp;lt; t.threshold_size_MB
' -- 메일 내용에 해당


IF(EXISTS(
	SELECT *
	FROM msdb.dbo.driveThreshold t 
		JOIN (SELECT TOP (@rowcnt) * FROM msdb.dbo.driveAvailable ORDER BY id DESC) da ON t.drive_letter = da.drive_letter
	WHERE t.is_check = 1
		AND da.drive_available_MB &amp;lt; t.threshold_size_MB
		)
)
BEGIN
	EXEC msdb.dbo.sp_send_dbmail  
		@profile_name = 'SSMS Database Mail Profile',		-- SSMS 상의 Database Mail 에 설정되어 있는 Profile명
		@recipients = 'alert 메일 갈 메일 주소. 여러개 가능.',	-- alert 메일이 갈 대상
		@query =  @querystr,  
		@subject = @subjectstr,  
		@attach_query_result_as_file = 0
END&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;2.5. 매일 일정한 시간에 따라 변화된 Disk Space 값 조회&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1724890020994&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT [id]
	, [drive_letter]
	, [drive_available_MB]
	, [datetime]
FROM [msdb].[dbo].[driveAvailable]
WHERE [drive_letter] = 'F'
	AND [datetime] &amp;gt;= DATEADD(DAY, -100, GETDATE())	-- 최근 100일 동안의 데이터
	AND CONVERT(VARCHAR, [datetime], 8) BETWEEN '08:00:00.000' AND '08:05:00.000' -- 5분 단위로 Disk Space를 기록한다고 했을 때, 매일 8시 00분대의 데이터 조회 위함 
ORDER BY [datetime] DESC&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3. 결론&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp;Intel Xeon의 8코어(logical 16코어)&lt;/b&gt; CPU로 테스트 해본 결과, Windows의 Performance Monitor의 %Processor Time 메트릭 기준으로, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;Powershell 스크립트 기반&lt;/b&gt;&lt;/span&gt;으로 동작하는 Agent Job은 &lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;순간적으로 5%~7% 가량&lt;/b&gt;&lt;/span&gt;의 CPU 부하율을 보였고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;T-SQL 스크립트 기반&lt;/b&gt;&lt;/span&gt;으로 동작하는 Agent Job은 &lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;순간적으로 1~3% 가량&lt;/b&gt;&lt;/span&gt;의 CPU 부하율을 보였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;단순 Percentage 값으로 보면 최대 6% 차이이지만, 이러한 job을 &lt;u&gt;수많은 트랜잭션이 오고 가는 Production 서버에서 5분 단위로 수행한다면,&lt;/u&gt; 이 6%가 어마어마한 차이를 낼 수도 있을 것이라 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;따라서, SQL Server 의 데이터 파일이 차지하는 드라이브의 Disk Alert을 보내는 시스템은 가능하면 위 두 방법 중 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;T-SQL 기반으로 하는 방법을 채택하는 게 올바른 것으로 보인다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;혹여나 Disk 의 현재 용량을 측정하고 기록해두는 &lt;b&gt;테이블(&lt;span style=&quot;color: #409d00;&quot;&gt;driveAvailable&lt;/span&gt;) 자체가 차지하는 용량&lt;/b&gt;이 많지 않을까도 염려스러웠는데, 계산해보면 이렇다.&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;id - &lt;b&gt;int&lt;/b&gt; : &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;4바이트&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;drive_letter - &lt;b&gt;varchar(1)&lt;/b&gt; : &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;1바이트&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;drive_available_MB - &lt;b&gt;int&lt;/b&gt; : &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;4바이트&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;datetime - &lt;b&gt;datetime&lt;/b&gt; : &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;8바이트&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 Row 당(한 드라이브에 대한 정보) &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;총 17바이트&lt;/b&gt;&lt;/span&gt;로, 위 예시에서는 체크하는 &lt;b&gt;드라이브 개수가 6개&lt;/b&gt;, 이를 5분 단위로 한다고 했을 경우 &lt;b&gt;1시간에 12번&lt;/b&gt; job이 돌고, 이를 1년으로 환산할 경우의 driveAvailable 테이블 용량은 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(17*6) * 12 * 24 * 365 = 10,722,240 바이트 = 10.22 MB 이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;즉, 이러한 job을 Windows의 D&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;rive Letter 최대 개수인 26개로 잡고, 10년동안 돌려도 500 MB 가 안된다.&lt;/b&gt; &lt;/span&gt;그러니 &lt;b&gt;'&lt;span style=&quot;color: #409d00;&quot;&gt;driveAvailable&lt;/span&gt;' 테이블이 차지하는 용량은 신경 쓰지 않아도 된다!&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/sql/relational-databases/databases/msdb-database?view=sql-server-ver16&quot;&gt;https://learn.microsoft.com/ko-kr/sql/relational-databases/databases/msdb-database?view=sql-server-ver16&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1680162139450&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;msdb 데이터베이스 - SQL Server&quot; data-og-description=&quot;msdb 데이터베이스&quot; data-og-host=&quot;learn.microsoft.com&quot; data-og-source-url=&quot;https://learn.microsoft.com/ko-kr/sql/relational-databases/databases/msdb-database?view=sql-server-ver16&quot; data-og-url=&quot;https://learn.microsoft.com/ko-kr/sql/relational-databases/databases/msdb-database&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b2IgQa/hyR5AaUXJk/yyf9kvbCOE8Bkty1bPurfk/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400&quot;&gt;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/sql/relational-databases/databases/msdb-database?view=sql-server-ver16&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://learn.microsoft.com/ko-kr/sql/relational-databases/databases/msdb-database?view=sql-server-ver16&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b2IgQa/hyR5AaUXJk/yyf9kvbCOE8Bkty1bPurfk/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;msdb 데이터베이스 - SQL Server&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;msdb 데이터베이스&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;learn.microsoft.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/sql/t-sql/data-types/int-bigint-smallint-and-tinyint-transact-sql?view=sql-server-ver16&quot;&gt;https://learn.microsoft.com/ko-kr/sql/t-sql/data-types/int-bigint-smallint-and-tinyint-transact-sql?view=sql-server-ver16&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1680224332366&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;int, bigint, smallint 및 tinyint(Transact-SQL) - SQL Server&quot; data-og-description=&quot;Int, bigint, smallint, tinyint 데이터 형식의 Transact-SQL 참조입니다. 해당 데이터 형식은 정수 데이터를 나타내는 데 사용됩니다.&quot; data-og-host=&quot;learn.microsoft.com&quot; data-og-source-url=&quot;https://learn.microsoft.com/ko-kr/sql/t-sql/data-types/int-bigint-smallint-and-tinyint-transact-sql?view=sql-server-ver16&quot; data-og-url=&quot;https://learn.microsoft.com/ko-kr/sql/t-sql/data-types/int-bigint-smallint-and-tinyint-transact-sql&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bt1kcf/hyR6NUsg07/5XFMKdxK3YNYKnL4K7kjGK/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400&quot;&gt;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/sql/t-sql/data-types/int-bigint-smallint-and-tinyint-transact-sql?view=sql-server-ver16&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://learn.microsoft.com/ko-kr/sql/t-sql/data-types/int-bigint-smallint-and-tinyint-transact-sql?view=sql-server-ver16&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bt1kcf/hyR6NUsg07/5XFMKdxK3YNYKnL4K7kjGK/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;int, bigint, smallint 및 tinyint(Transact-SQL) - SQL Server&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Int, bigint, smallint, tinyint 데이터 형식의 Transact-SQL 참조입니다. 해당 데이터 형식은 정수 데이터를 나타내는 데 사용됩니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;learn.microsoft.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.mssqltips.com/sqlservertip/2444/script-to-get-available-and-free-disk-space-for-sql-server/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.mssqltips.com/sqlservertip/2444/script-to-get-available-and-free-disk-space-for-sql-server/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1691372768601&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Script to Get Available and Free Disk Space for SQL Server&quot; data-og-description=&quot;Often we face the situation where we need to check the total disk space and available disk space for both physical and LUN/Mount drives. The extended stored procedure XP_FixedDrives is unable to help us in this scenario, so we have to log into the machine&quot; data-og-host=&quot;www.mssqltips.com&quot; data-og-source-url=&quot;https://www.mssqltips.com/sqlservertip/2444/script-to-get-available-and-free-disk-space-for-sql-server/&quot; data-og-url=&quot;https://www.mssqltips.com/sqlservertip/2444/script-to-get-available-and-free-disk-space-for-sql-server/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/7522D/hyTzkwLGNv/i7mONEELgjKW5kwXTBPu01/img.jpg?width=552&amp;amp;height=326&amp;amp;face=0_0_552_326&quot;&gt;&lt;a href=&quot;https://www.mssqltips.com/sqlservertip/2444/script-to-get-available-and-free-disk-space-for-sql-server/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.mssqltips.com/sqlservertip/2444/script-to-get-available-and-free-disk-space-for-sql-server/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/7522D/hyTzkwLGNv/i7mONEELgjKW5kwXTBPu01/img.jpg?width=552&amp;amp;height=326&amp;amp;face=0_0_552_326');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Script to Get Available and Free Disk Space for SQL Server&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Often we face the situation where we need to check the total disk space and available disk space for both physical and LUN/Mount drives. The extended stored procedure XP_FixedDrives is unable to help us in this scenario, so we have to log into the machine&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.mssqltips.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DB/SQL Server (MSSQL)</category>
      <category>Disk Alert Powershell VS T-SQL</category>
      <category>Powershell Disk Alert</category>
      <category>SQL Server Agent Disk Alert</category>
      <category>SQL Server Disk Alert</category>
      <category>T-SQL Disk Alert</category>
      <category>Windows Server Disk Alert</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/138</guid>
      <comments>https://co-no.tistory.com/entry/MSSQL-SQL-Server-%ED%98%B8%EC%8A%A4%ED%8A%B8%EC%9D%98-Disk-Space-Alert-%EC%84%A4%EC%A0%95%ED%95%98%EA%B8%B0#entry138comment</comments>
      <pubDate>Fri, 31 Mar 2023 10:09:04 +0900</pubDate>
    </item>
    <item>
      <title>[Prometheus] Metric의 Threshold를 지정하고 AlertManager로 메일 통해 알람 받기</title>
      <link>https://co-no.tistory.com/entry/Prometheus-Metric%EC%9D%98-Threshold%EB%A5%BC-%EC%A7%80%EC%A0%95%ED%95%98%EA%B3%A0-AlertManager%EB%A1%9C-%EC%95%8C%EB%9E%8C-%EB%B0%9B%EA%B8%B0</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1. Prometheus의 &lt;span style=&quot;color: #006dd7;&quot;&gt;Alertmanager 플러그인&lt;/span&gt; 설치&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1679010952071&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# alertmanager 설치 파일 다운로드
# cd ~/Downloads
# wget https://github.com/prometheus/alertmanager/releases/download/v0.25.0/alertmanager-0.25.0.linux-amd64.tar.gz
# tar -xzvf alertmanager-0.25.0.linux-amd64.tar.gz
# rm -rf alertmanager-0.25.0.linux-amd64.tar.gz

# alertmanager 유저 추가
# useradd --no-create-home --shell /bin/false alertmanager

# alertmanager의 디렉토리를 opt 하위로 이동 및 관리 편의를 위한 logs, conf, bin, data 디렉토리 생성
# mv ~/Downloads/alertmanager-0.25.0.linux-amd64 /opt/alertmanager
# mkdir /opt/alertmanager/logs /opt/alertmanager/conf /opt/alertmanager/bin /opt/alertmanager/data
# mv /opt/alertmanager/alertmanager.yml /opt/alertmanager/conf
# mv /opt/alertmanager/alertmanager /opt/alertmanager/bin/
# mv /opt/alertmanager/amtool /opt/alertmanager/bin/

# alertmanager HOME 디렉토리 권한 부여
# chown -R alertmanager:alertmanager /opt/alertmanager&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1679031671072&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# vi /etc/sysconfig/alertmanager 로 'alertmanager' 환경변수 위한 파일 생성

# /etc/sysconfig/alertmanager 파일

ALERTMANAGER_USER=alertmanager

ALERTMANAGER_GROUP=alertmanager

ALERTMANAGER_HOME=/opt/alertmanager

LOG_DIR=/opt/alertmanager/logs

DATA_DIR=/opt/alertmanager/data

CONF_DIR=/opt/alertmanager/conf

CONF_FILE=/opt/alertmanager/conf/alertmanager.yml

# Only used on systemd systems
PID_FILE_DIR=/var/run/alertmanager&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1679011198137&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# alertmanager service 등록
# vi /usr/lib/systemd/system/alertmanager.service 로 'alertmanager.service' 파일 생성

# alertmanager.service 파일 내용

[Unit]
Description=Alertmanager
Wants=network-online.target
After=network-online.target

[Service]
EnvironmentFile=/etc/sysconfig/alertmanager
PIDFile=/var/run/alertmanager.pid

User=alertmanager
Group=alertmanager
Type=simple
Restart=always
WorkingDirectory=/opt/alertmanager
RuntimeDirectory=alertmanager
RuntimeDirectoryMode=0750
ExecStart=/opt/alertmanager/bin/alertmanager    \
    --config.file=${CONF_FILE}                  \
    --storage.path=${DATA_DIR}/                 \
    --cluster.listen-address=                   \


[Install]
WantedBy=multi-user.target&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;- alertmanager가 정상 설치 되었는지 확인하기 위해 &lt;span style=&quot;color: #006dd7;&quot;&gt;alertmanager 웹 콘솔 접속&lt;/span&gt;하기&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1679123178051&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# alertamanger.service 가동
systemctl start alertmanager.service&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;alertmanager 서버를 작동시킨 후, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;{alertamanger 를 설치한 IP}:9093&lt;/b&gt;&lt;/span&gt; &lt;u&gt;(Default Port)&lt;/u&gt; 로 접속하면, alertmanager 가 정상 설치 및 정상 가동 되었다면 아래와 같은 화면을 볼 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1151&quot; data-origin-height=&quot;728&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yoP38/btr4vjhSqcg/4t7caHiOVQCxDhG2HFygVk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yoP38/btr4vjhSqcg/4t7caHiOVQCxDhG2HFygVk/img.png&quot; data-alt=&quot;Alertmanager 웹 콘솔 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yoP38/btr4vjhSqcg/4t7caHiOVQCxDhG2HFygVk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyoP38%2Fbtr4vjhSqcg%2F4t7caHiOVQCxDhG2HFygVk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;699&quot; height=&quot;442&quot; data-origin-width=&quot;1151&quot; data-origin-height=&quot;728&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Alertmanager 웹 콘솔 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;- &lt;span style=&quot;color: #006dd7;&quot;&gt;프로메테우스의 alert 시스템&lt;/span&gt;을 설치한 'alertmanager' 로 &lt;span style=&quot;color: #006dd7;&quot;&gt;등록&lt;/span&gt;하기&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1679041121881&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# vi /opt/prometheus/conf/prometheus.yml 로 prometheus.yml 파일 수정

# /opt/prometheus/conf/prometheus.yml 파일의 'alerting:' 부분

alerting:
  alertmanagers:
    - static_configs:
        - targets: [&quot;your_alertmanager_IP:9093&quot;]&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1679041406883&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# promtool check config &amp;lt;config-files&amp;gt; 로 prometheus.yml 검증하기

# /opt/prometheus/bin/promtool check config /opt/prometheus/conf/prometheus.yml&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1679041440807&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 변경된 prometheus.yml 적용하기 위해 프로메테우스 서버 재시작 하기

# systemctl restart prometheus.service&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2. 프로메테우스의 &lt;span style=&quot;color: #006dd7;&quot;&gt;rules.yml&lt;/span&gt; 설정&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1679037775104&quot; class=&quot;shell&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 프로메테우스가 설치되어 있는 경로로 이동
# cd /opt/prometheus

# 'rules' 라는 디렉토리 생성 - rule과 관련된 yml 파일들을 따로 모아두기 위함.
# mkdir rules

# 'rules' 디렉토리가 root 계정으로 생성되었으므로, 권한 부여하기
chown -R prometheus:prometheus /opt/prometheus/&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;- rules.yml 생성 (여기서는 이름을 '&lt;span style=&quot;color: #409d00;&quot;&gt;test-rules.yml&lt;/span&gt;' 로 지정하겠다.)&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1679038464537&quot; class=&quot;shell&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# vi /opt/prometheus/rules/test-rules.yml 로 'test-rules.yml' 생성

# /opt/prometheus/rules/test-rules.yml 파일

groups:
  - name: custom_rules
    rules:
      - record: node_memory_MemFree_percent
        expr: 100 - (100 * node_memory_MemFree_bytes / node_memory_MemTotal_bytes)

      - record: node_filesystem_free_percent
        expr: 100 * node_filesystem_free_bytes{mountpoint=&quot;/&quot;} / node_filesystem_size_bytes{mountpoint=&quot;/&quot;}

  - name: alert_rules
    rules:
      - alert: InstanceDown
        expr: up == 0
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: &quot;Instance [{{ $labels.instance }}] down&quot;
          description: &quot;[{{ $labels.instance }}] of job [{{ $labels.job }}] has been down for more than 1 minute.&quot;
          
      - alert: DiskSpaceFree10Percent
        expr: node_filesystem_free_percent &amp;lt;= 10
        labels:
          severity: warning
        annotations:
          summary: &quot;Instance [{{ $labels.instance }}] has 10% or less Free disk space&quot;
          description: &quot;[{{ $labels.instance }}] has only {{ $value }}% or less free.&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;- 생성한 rule 파일을 &lt;span style=&quot;color: #006dd7;&quot;&gt;prometheus 에 인식&lt;/span&gt;시키기.&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;rule 파일의 syntax error 등이 없는 지, 다음 명령어를 통해 확인한다.&lt;/p&gt;
&lt;pre id=&quot;code_1679038631854&quot; class=&quot;shell&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 생성한 rule 파일에 prometheus로 소유권 변경
chown prometheus:prometheus /opt/prometheus/rules/test-rules.yml

# 프로메테우스 설치 경로의 'promtool' 명령어 통해 확인
# promtoll check rules { rule.yml의 경로 }
# /opt/prometheus/bin/promtool check rules /opt/prometheus/rules/test-rules.yml&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1679037775105&quot; class=&quot;shell&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# vi /opt/prometheus/conf/prometheus.yml 수행하여 아래 문구 추가

# /opt/prometheus/conf/prometheus.yml 파일

rule_files:
  - &quot;/opt/prometheus/rules/test-rules.yml&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1679039169573&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# prometheus.yml 변경사항 적용 위한 프로메테우스 재시작
# systemctl restart prometheus.service&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;- prometheus 서버에 &lt;span style=&quot;color: #006dd7;&quot;&gt;rules가 적용되었는지&lt;/span&gt; 확인하기&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;969&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bQF5kn/btr4qyT3L6f/kECmBExTizUKGPauV03ei0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bQF5kn/btr4qyT3L6f/kECmBExTizUKGPauV03ei0/img.png&quot; data-alt=&quot;{프로메테우스가 설치된 서버 IP}:9000/rules 페이지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bQF5kn/btr4qyT3L6f/kECmBExTizUKGPauV03ei0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbQF5kn%2Fbtr4qyT3L6f%2FkECmBExTizUKGPauV03ei0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;969&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;969&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;{프로메테우스가 설치된 서버 IP}:9000/rules 페이지&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3. &lt;span style=&quot;color: #006dd7;&quot;&gt;alertmanager.yml&lt;/span&gt; 설정&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;- &lt;span style=&quot;color: #006dd7;&quot;&gt;alertmanager.yml&lt;/span&gt; 파일 내용 작성&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1678752533466&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# /opt/alertmanager/conf/alertmanager.yml 파일

global: 	
  resolve_timeout: 5m

route:
  group_by: ['alertname']
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 3h
  receiver: 'Receiver Name'
   
receivers:
  - name: 'Receiver Name'
    email_configs:
      - to: 'your-email@yourdomain.com'
        from: 'Prometheus_Alert@yourdomain.com'
        smarthost: 'your_smtp_server_IP:your_smtp_port'
        auth_username: 'your_smtp_auth_username'
        auth_password: 'your_smtp_auth_password'
        require_tls: false		# 디폴트가 true인데, 테스트하려는 smtp 서버가 tls 인증을 지원하지 않는 경우, false로 지정해야 메일이 성공적으로 발송된다.

inhibit_rules:
  - source_match:
      severity: 'critical'
    target_match:
      severity: 'warning'
    equal: ['alertname', 'instance']&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;global&lt;/b&gt; : Alertmanager 전반에 적용되는 설정&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;resolve_timeout&lt;/b&gt; :&amp;nbsp; alert이 EndsAt(해당 사안 종료 시각)을 명시하지 않을 경우, 이 옵션으로 설정해놓은 시간이 지나면, alert을 Alertmanager에서 Resolve 처리하게 된다. 기본값은 5m&lt;/li&gt;
&lt;li&gt;&lt;b&gt;smtp_*&lt;/b&gt; : Alertmanager가 이메일 알림을 보낼 때 사용하는 SMTP 서버와 인증 정보를 global로도 박을 수 있다. receiver의 대상 메일 서버가 하나인 경우 주로 global로 박아서 사용하게 될 것이다.&lt;br /&gt;구체적인 내용은 '참고'의 프로메테우스 공식 문서 참고.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;slack_*&lt;/b&gt; : Alertmanager가 Slack 메시지를 보낼 때 사용하는 webhook URL과 인증 토큰을 설정. &lt;br /&gt;구체적인 내용은 '참고'의 프로메테우스 공식 문서 참고.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;pagerduty_*&lt;/b&gt; : Alertmanager가 PagerDuty 알림을 보낼 때 사용하는 인증 토큰을 설정. &lt;br /&gt;구체적인 내용은 '참고'의 프로메테우스 공식 문서 참고.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;route&lt;/b&gt; : alert 라우팅 규칙을 정의&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;receiver&lt;/b&gt; : alert을 수신하는 대상을 지정. 여러 대상 지정 가능&lt;/li&gt;
&lt;li&gt;&lt;b&gt;group_by&lt;/b&gt; : alert을 그룹화하는 기준을 설정. alert이 발생한 대상에 대한 label 등을 기준으로 그룹화 하는 설정&lt;/li&gt;
&lt;li&gt;&lt;b&gt;group_wait&lt;/b&gt; : alert 그룹에 대한 notification 을 다시 보내기 전, 얼마나 기다려야 하는지를 설정. 기본값은 30s&lt;br /&gt;만약 이 시간 내에 [group_by] 의 동일한 label을 가진 다른 alert이 발생한다면, 해당 그룹에 추가하고, 다시 또 다른 alert 오는지 대기했다가, 없을 경우에 지금까지 온 해당 그룹의 모든 alert 을 notify 한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;group_interval&lt;/b&gt; : &lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;아직 resolved 되지 않은&lt;span&gt; alert에 대해 반복 알림(notification)을 보내기 전, &lt;/span&gt;&lt;/span&gt;대기하는 시간을 설정. &lt;br /&gt;기본값은 5m&lt;/li&gt;
&lt;li&gt;&lt;b&gt;repeat_interval&lt;/b&gt; : 반복적으로 알림을 보내는 경우, 알림을 보내는 간격을 설정. 기본값은 3h&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;receivers&lt;/b&gt; : 알림(notification)을 수신하는 대상의 정보를 정의&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;email_configs&lt;/b&gt; : 이메일로 알림을 보내는 경우 사용되는 SMTP 서버 및 수신자 정보를 설정&lt;/li&gt;
&lt;li&gt;&lt;b&gt;webhook_configs&lt;/b&gt; : 웹훅을 사용하여 알림을 보내는 경우, 웹훅 End point 와 인증 정보를 설정&lt;/li&gt;
&lt;li&gt;&lt;b&gt;pagerduty_configs&lt;/b&gt; : PagerDuty 알림을 수신하는 경우, 서비스와 인증 토큰을 설정&lt;/li&gt;
&lt;li&gt;&lt;b&gt;slack_configs&lt;/b&gt; : Slack 메시지를 수신하는 경우, 웹훅 URL과 인증 토큰을 설정&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;inhibit_rules&lt;/b&gt;: source_match 에서 지정한 label에 해당하는 label을 가진 alert이 이미 있다면, target_match 에서 지정한 label에 해당하는 label을 가진 alert에 대한 notification 은 하지 않도록 지정하는 설정&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;source_match&lt;/b&gt; : 이 단락에 명시된 조건을 충족하면, inhibit_rule 을 적용하게 된다. 따라서 이 단락에 명시된 조건에 해당하는 alert만 notify 한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;target_match&lt;/b&gt; : 이 단락에 명시된 조건의 alert은 notify 되지 않는다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;equal&lt;/b&gt; : 동일한 alert을 평가하는 기준으로, 위 예시에서는 alert의 이름과 해당 alert이 발생한 instance가 동일하다면, 동일한 alert으로 보고, severity 가 warning인 alert은 무시하고, severity가 critical 인 alert만 notify 하게 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;- alertmanager.yml 파일 &lt;span style=&quot;color: #006dd7;&quot;&gt;검증&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작성한 alertmanager.yml 파일의 syntax error 등은 없는지 확인한다.&lt;/p&gt;
&lt;pre id=&quot;code_1679040936503&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# amtool check-config {alertmanager.yml의 경로}
# /opt/alertmanager/bin/amtool check-config /opt/alertmanager/conf/alertmanager.yml&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1679041527690&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# alertmanager.yml 적용시키기 위해 alertmanager 재시작하기
# systemctl restart alertmanager.service&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;- alertmanager.yml 파일 적용이 되었는지 &lt;span style=&quot;color: #006dd7;&quot;&gt;프로메테우스 콘솔 창에서 확인&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1282&quot; data-origin-height=&quot;280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDMG3J/btr4zcocdhP/wk02sbAbZik7lYKgvRaaR0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDMG3J/btr4zcocdhP/wk02sbAbZik7lYKgvRaaR0/img.png&quot; data-alt=&quot;프로메테우스 콘솔창의 [Alerts] 메뉴에서 'InstanceDown' 과 'DiskSpaceFree10Percent' 가 적용됨을 확인할 수 있다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDMG3J/btr4zcocdhP/wk02sbAbZik7lYKgvRaaR0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDMG3J%2Fbtr4zcocdhP%2Fwk02sbAbZik7lYKgvRaaR0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1282&quot; height=&quot;280&quot; data-origin-width=&quot;1282&quot; data-origin-height=&quot;280&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;프로메테우스 콘솔창의 [Alerts] 메뉴에서 'InstanceDown' 과 'DiskSpaceFree10Percent' 가 적용됨을 확인할 수 있다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://prometheus.io/docs/alerting/latest/alertmanager/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://prometheus.io/docs/alerting/latest/alertmanager/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1678751468221&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Alertmanager | Prometheus&quot; data-og-description=&quot;An open-source monitoring system with a dimensional data model, flexible query language, efficient time series database and modern alerting approach.&quot; data-og-host=&quot;prometheus.io&quot; data-og-source-url=&quot;https://prometheus.io/docs/alerting/latest/alertmanager/&quot; data-og-url=&quot;https://prometheus.io/docs/alerting/latest/alertmanager/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/Da1Gx/hyRU3DtZKf/Ixi1Nku0ChGywoL6RWjOp0/img.png?width=192&amp;amp;height=192&amp;amp;face=0_0_192_192&quot;&gt;&lt;a href=&quot;https://prometheus.io/docs/alerting/latest/alertmanager/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://prometheus.io/docs/alerting/latest/alertmanager/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/Da1Gx/hyRU3DtZKf/Ixi1Nku0ChGywoL6RWjOp0/img.png?width=192&amp;amp;height=192&amp;amp;face=0_0_192_192');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Alertmanager | Prometheus&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;An open-source monitoring system with a dimensional data model, flexible query language, efficient time series database and modern alerting approach.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;prometheus.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://godekdls.github.io/Prometheus/alerting.configuration/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://godekdls.github.io/Prometheus/alerting.configuration/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1679031805685&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Alert Configuration&quot; data-og-description=&quot;Alertmanager 설정 가이드&quot; data-og-host=&quot;godekdls.github.io&quot; data-og-source-url=&quot;https://godekdls.github.io/Prometheus/alerting.configuration/&quot; data-og-url=&quot;https://godekdls.github.io/Prometheus/alerting.configuration/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bF0kwt/hyRXzu36wH/lN3xdijhXIigoUNjJR5100/img.png?width=830&amp;amp;height=370&amp;amp;face=0_0_830_370,https://scrap.kakaocdn.net/dn/cVVqjm/hyRXtuPWDE/nOAVKrWqUuFbvkDqj2WpC1/img.png?width=830&amp;amp;height=370&amp;amp;face=0_0_830_370,https://scrap.kakaocdn.net/dn/dFx9IR/hyRXAHwx3v/FOX302FPyMQ3IEA1trfme1/img.png?width=830&amp;amp;height=370&amp;amp;face=0_0_830_370&quot;&gt;&lt;a href=&quot;https://godekdls.github.io/Prometheus/alerting.configuration/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://godekdls.github.io/Prometheus/alerting.configuration/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bF0kwt/hyRXzu36wH/lN3xdijhXIigoUNjJR5100/img.png?width=830&amp;amp;height=370&amp;amp;face=0_0_830_370,https://scrap.kakaocdn.net/dn/cVVqjm/hyRXtuPWDE/nOAVKrWqUuFbvkDqj2WpC1/img.png?width=830&amp;amp;height=370&amp;amp;face=0_0_830_370,https://scrap.kakaocdn.net/dn/dFx9IR/hyRXAHwx3v/FOX302FPyMQ3IEA1trfme1/img.png?width=830&amp;amp;height=370&amp;amp;face=0_0_830_370');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Alert Configuration&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Alertmanager 설정 가이드&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;godekdls.github.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://medium.com/techno101/how-to-send-a-mail-using-prometheus-alertmanager-7e880a3676db&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://medium.com/techno101/how-to-send-a-mail-using-prometheus-alertmanager-7e880a3676db&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1679031813352&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;How to Send a Mail Using Prometheus Alertmanager?&quot; data-og-description=&quot;How to create Alerting Rules? Install and configure Alertmanager to send mail on alert firing.&quot; data-og-host=&quot;medium.com&quot; data-og-source-url=&quot;https://medium.com/techno101/how-to-send-a-mail-using-prometheus-alertmanager-7e880a3676db&quot; data-og-url=&quot;https://medium.com/techno101/how-to-send-a-mail-using-prometheus-alertmanager-7e880a3676db&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/v6Qeo/hyRWqfrDoj/J4Q9Ofck8pXbTkAl550rh1/img.gif?width=785&amp;amp;height=442&amp;amp;face=0_0_785_442&quot;&gt;&lt;a href=&quot;https://medium.com/techno101/how-to-send-a-mail-using-prometheus-alertmanager-7e880a3676db&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://medium.com/techno101/how-to-send-a-mail-using-prometheus-alertmanager-7e880a3676db&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/v6Qeo/hyRWqfrDoj/J4Q9Ofck8pXbTkAl550rh1/img.gif?width=785&amp;amp;height=442&amp;amp;face=0_0_785_442');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;How to Send a Mail Using Prometheus Alertmanager?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;How to create Alerting Rules? Install and configure Alertmanager to send mail on alert firing.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;medium.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://awesome-prometheus-alerts.grep.to/rules.html#windows-server&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://awesome-prometheus-alerts.grep.to/rules.html#windows-server&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1680154146078&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Awesome Prometheus alerts&quot; data-og-description=&quot;Collection of alerting rules&quot; data-og-host=&quot;awesome-prometheus-alerts.grep.to&quot; data-og-source-url=&quot;https://awesome-prometheus-alerts.grep.to/rules.html#windows-server&quot; data-og-url=&quot;http://awesome-prometheus-alerts.grep.to/rules.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://awesome-prometheus-alerts.grep.to/rules.html#windows-server&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://awesome-prometheus-alerts.grep.to/rules.html#windows-server&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Awesome Prometheus alerts&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Collection of alerting rules&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;awesome-prometheus-alerts.grep.to&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;-&amp;gt; Alert rules 작성 예시 참고하기 좋은 사이트!&lt;/b&gt;&lt;/p&gt;</description>
      <category>Observability</category>
      <category>prometheus alertmanager</category>
      <category>prometheus alertmanager port</category>
      <category>prometheus alertmanager rule</category>
      <category>prometheus alertmanager 설치</category>
      <category>prometheus alertmanager 연동</category>
      <category>prometheus mail alert</category>
      <category>prometheus 메일 알림</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/134</guid>
      <comments>https://co-no.tistory.com/entry/Prometheus-Metric%EC%9D%98-Threshold%EB%A5%BC-%EC%A7%80%EC%A0%95%ED%95%98%EA%B3%A0-AlertManager%EB%A1%9C-%EC%95%8C%EB%9E%8C-%EB%B0%9B%EA%B8%B0#entry134comment</comments>
      <pubDate>Sat, 18 Mar 2023 16:55:20 +0900</pubDate>
    </item>
    <item>
      <title>[Prometheus] Node Exporter 를 CentOS 7 서버에 설치하기</title>
      <link>https://co-no.tistory.com/entry/Prometheus-Node-Exporter-%EB%A5%BC-CentOS-7-%EC%84%9C%EB%B2%84%EC%97%90-%EC%84%A4%EC%B9%98%ED%95%98%EA%B3%A0-Grafana%EB%A1%9C-node-metric-%EA%B2%B0%EA%B3%BC-%EB%AA%A8%EB%8B%88%ED%84%B0%EB%A7%81%ED%95%98%EA%B8%B0</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1. &lt;span style=&quot;color: #006dd7;&quot;&gt;Node Exporter&lt;/span&gt; 설치&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;서버 리소스 metric이 모니터링 되는 대상 서버&lt;/b&gt;&lt;/span&gt;를 이제부터 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;클라이언트&lt;/b&gt;&lt;/span&gt;라고 칭하겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;클라이언트에 Node Exporter 를 설치해야만, 프로메테우스가 Node Exporter로부터 metric을 수집해 올 수 있다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Node Exporter 설치 방법을 살펴보자!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로메테우스의 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;Node Exporter&lt;/b&gt;&lt;/span&gt;는 아래 &lt;b&gt;github&lt;/b&gt; 에서 설치할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/prometheus/node_exporter/releases/tag/v1.5.0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/prometheus/node_exporter/releases/tag/v1.5.0&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1678930125314&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;Release 1.5.0 / 2022-11-29 &amp;middot; prometheus/node_exporter&quot; data-og-description=&quot;NOTE: This changes the Go runtime &amp;quot;GOMAXPROCS&amp;quot; to 1. This is done to limit the concurrency of the exporter to 1 CPU thread at a time in order to avoid a race condition problem in the Linux kernel (...&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/prometheus/node_exporter/releases/tag/v1.5.0&quot; data-og-url=&quot;https://github.com/prometheus/node_exporter/releases/tag/v1.5.0&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bLijej/hyRWqyUucc/eq3MoNFHAowK6zf50Yu3PK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/prometheus/node_exporter/releases/tag/v1.5.0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/prometheus/node_exporter/releases/tag/v1.5.0&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bLijej/hyRWqyUucc/eq3MoNFHAowK6zf50Yu3PK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Release 1.5.0 / 2022-11-29 &amp;middot; prometheus/node_exporter&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;NOTE: This changes the Go runtime &quot;GOMAXPROCS&quot; to 1. This is done to limit the concurrency of the exporter to 1 CPU thread at a time in order to avoid a race condition problem in the Linux kernel (...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리눅스 서버에서 &lt;b&gt;명령어를 통한 설치&lt;/b&gt;는 아래와 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1678930829171&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Node_Exporter를 설치하려는 디렉토리로 이동
# 나는 나중에 어디에 설치되어 있는지 확인하기 쉽게, /usr/share/에 'node_exporter' 라는 디렉토리를 따로 만들었다.
$ cd /usr/share/node_exporter

# 설치하려는 클라이언트의 Linux 버전에 따라 설치 파일이 다르다. 유의하자.
$ wget https://github.com/prometheus/node_exporter/releases/download/v1.5.0/node_exporter-1.5.0.linux-amd64.tar.gz

# 다운로드 받은 파일 압축 해제
$ tar -xzvf ./node_exporter-1.5.0.linux-amd64.tar.gz&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2. Node Exporter 를 서버 부팅과 함께 실행하도록 &lt;span style=&quot;color: #006dd7;&quot;&gt;service 파일&lt;/span&gt; 만든 후, &lt;span style=&quot;color: #006dd7;&quot;&gt;실행&lt;/span&gt;하기&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1678931367271&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 서비스 파일 생성
# vi /usr/lib/systemd/system/node_exporter.service&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1678931658962&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# /usr/lib/systemd/system/node_exporter.service 파일

[Unit]
Descripion=Node Exporter
After=network.target

[Service]
User=root
Group=root
Type=simple
ExecStart=/usr/share/node_exporter/node_exporter

[Install]
WantedBy=multi-user.target&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1678931797619&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 작성한 서비스 파일 systemctl로 불러오기
# systemctl daemon-reload

# 부팅 시 자동실행 되도록 enable 설정하기
# systemctl enable node_exporter.service

# Node_Exporter 실행하기
# systemctl start node_exporter.service&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 과정을 거쳐 node_exporter 를 실행한 후, 브라우저에서 아래 URL로 접속하면 클라이언트의 metric이 프로메테우스가 가져올 수 있는 형태로 수집되는 것을 확인할 수 있다. 디폴트 포트가 9100 으로 설정되어 있다는 것을 알아두자!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;{&lt;span style=&quot;color: #409d00;&quot;&gt;node_exporter가 설치된 서버의 IP&lt;/span&gt;}:&lt;span style=&quot;color: #006dd7;&quot;&gt;9100&lt;/span&gt;/&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;or&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;{&lt;span style=&quot;color: #409d00;&quot;&gt;node_exporter가 설치된 서버의 IP&lt;/span&gt;}:&lt;span style=&quot;color: #006dd7;&quot;&gt;9100&lt;/span&gt;/metrics&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3. 프로메테우스 서버에 모니터링 할 &lt;span style=&quot;color: #006dd7;&quot;&gt;클라이언트(Node_exporter가 설치된 서버) 등록&lt;/span&gt;하기&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1678932383984&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 프로메테우스가 설치된 서버

# 프로메테우스로 유저 전환
# su - prometheus

# 프로메테우스 서버의 설정파일 변경
$ vi $PROMETHEUS_HOME/prometheus.yml&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1678932543347&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 'scrape_configs' 에 아래 내용 추가 또는 변경

  - job_name: &quot;프로메테우스에서 인식할 job name으로 설정&quot;
    
    static_confgis:
      - target: [&quot;{Node_Exporter가 설치된 서버 IP}:9100&quot;]&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://sanggi-jayg.tistory.com/104&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://sanggi-jayg.tistory.com/104&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1678932191535&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Prometheus + Node Exporter + Grafana 연동&quot; data-og-description=&quot;프로메테우스 설치 https://prometheus.io/ # 유저 추가 useradd -m -s /bin/bash prometheus su - prometheus # 다운로드 cd /home/prometheus wget https://github.com/prometheus/prometheus/releases/download/v2.28.0/prometheus-2.28.0.linux-amd64.tar&quot; data-og-host=&quot;sanggi-jayg.tistory.com&quot; data-og-source-url=&quot;https://sanggi-jayg.tistory.com/104&quot; data-og-url=&quot;https://sanggi-jayg.tistory.com/104&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/RCB8B/hyRWmDl1ld/BivemRkL4d4L0n67NH25R1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/6vjfB/hyRWrxQrvr/ufarJFZUml868IXMtVk6K0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://sanggi-jayg.tistory.com/104&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://sanggi-jayg.tistory.com/104&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/RCB8B/hyRWmDl1ld/BivemRkL4d4L0n67NH25R1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/6vjfB/hyRWrxQrvr/ufarJFZUml868IXMtVk6K0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Prometheus + Node Exporter + Grafana 연동&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;프로메테우스 설치 https://prometheus.io/ # 유저 추가 useradd -m -s /bin/bash prometheus su - prometheus # 다운로드 cd /home/prometheus wget https://github.com/prometheus/prometheus/releases/download/v2.28.0/prometheus-2.28.0.linux-amd64.tar&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;sanggi-jayg.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Observability</category>
      <category>프로메테우스 Exporter 등록</category>
      <category>프로메테우스 Linux Exporter</category>
      <category>프로메테우스 Node Exporter</category>
      <category>프로메테우스 Node Exporter 설치</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/137</guid>
      <comments>https://co-no.tistory.com/entry/Prometheus-Node-Exporter-%EB%A5%BC-CentOS-7-%EC%84%9C%EB%B2%84%EC%97%90-%EC%84%A4%EC%B9%98%ED%95%98%EA%B3%A0-Grafana%EB%A1%9C-node-metric-%EA%B2%B0%EA%B3%BC-%EB%AA%A8%EB%8B%88%ED%84%B0%EB%A7%81%ED%95%98%EA%B8%B0#entry137comment</comments>
      <pubDate>Thu, 16 Mar 2023 12:13:36 +0900</pubDate>
    </item>
    <item>
      <title>[Grafana] CentOS 7 에서 Grafana(Prometheus 데이터를 시각화해주는 서버) 설치하고 프로메테우스와 연동하기</title>
      <link>https://co-no.tistory.com/entry/Grafana-Prometheus%EC%9D%98-Metric-%EC%9D%84-%EC%8B%9C%EA%B0%81%ED%99%94%ED%95%98%EC%97%AC-%EB%8C%80%EC%8B%9C%EB%B3%B4%EB%93%9C%EB%A5%BC-%EB%A7%8C%EB%93%A4-%EC%88%98-%EC%9E%88%EB%8A%94-Grafana-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0</link>
      <description>&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;0. 현재 Grafana 릴리즈된 버전 확인하기&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;a href=&quot;https://grafana.com/grafana/download/9.4.3?edition=oss&quot;&gt;https://grafana.com/grafana/download/9.4.3?edition=oss&lt;/a&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1678925250553&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Download Grafana | Grafana Labs&quot; data-og-description=&quot;Overview of how to download and install different versions of Grafana on different operating systems.&quot; data-og-host=&quot;grafana.com&quot; data-og-source-url=&quot;https://grafana.com/grafana/download/9.4.3?edition=oss&quot; data-og-url=&quot;https://grafana.com/grafana/download/9.4.3?edition=oss&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/coMw76/hyRWsXFOPO/6Ovbx4Z1tPxeAbgpav0UEk/img.png?width=900&amp;amp;height=780&amp;amp;face=0_0_900_780&quot;&gt;&lt;a href=&quot;https://grafana.com/grafana/download/9.4.3?edition=oss&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://grafana.com/grafana/download/9.4.3?edition=oss&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/coMw76/hyRWsXFOPO/6Ovbx4Z1tPxeAbgpav0UEk/img.png?width=900&amp;amp;height=780&amp;amp;face=0_0_900_780');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Download Grafana | Grafana Labs&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Overview of how to download and install different versions of Grafana on different operating systems.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;grafana.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;2023.03.16 기준&lt;/b&gt;, 9.4.3 버전이 최신 버전이므로, 아래 설치 과정도 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;9.4.3 버전(OSS)&lt;/b&gt;&lt;/span&gt; 로 진행&lt;/span&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;하겠다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1. Grafana&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;설치&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1678925218278&quot; class=&quot;shell&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 그라파나 다운로드
# cd ~
# wget https://dl.grafana.com/oss/release/grafana-9.4.3-1.x86_64.rpm
# 위 다운로드 링크는 설치하려는 그라파나의 버전, OS 버전에 따라 달라진다.

# 다운로드 받은 그라파나 rpm파일을 yum으로 설치 진행
# 추후 취약성 등의 보안 패치 등을 수월하게 하기 위해 yum 으로 수행
# yum install ~/grafana-9.4.3-1.x86_64.rpm

# 'grafana' 유저 추가는 선택 사항. (yum으로 설치 시, /sbin/nologin 으로 grafana 계정 생성된다.)
# useradd -m -s /bin/bash grafana

# 'grafana' 유저로 전환 (yum으로 진행 시 X)
# su - grafana&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. yum 으로 설치 된 Grafana의 &lt;span style=&quot;color: #006dd7;&quot;&gt;각종 디렉토리 및 파일&lt;/span&gt;&amp;nbsp;확인&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Grafana &lt;span style=&quot;color: #006dd7;&quot;&gt;엔진(GRAFANA_HOME)&lt;/span&gt;&amp;nbsp;디렉토리&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1678925218279&quot; class=&quot;shell&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Grafana 엔진 디렉토리 확인하기
# ls -al /usr/share/grafana&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;/usr/share/grafana&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;┖ bin/&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;┖ conf/&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;┖ plugins-bundled/&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;┖ public/&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;┖ VERSION&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Grafana의 &lt;span style=&quot;color: #006dd7;&quot;&gt;환경변수&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1678927154128&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Grafana의 환경변수 확인하기
# vi /etc/sysconfig/grafana-server&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1678927195782&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;GRAFANA_USER=grafana

GRAFANA_GROUP=grafana

GRAFANA_HOME=/usr/share/grafana

LOG_DIR=/var/log/grafana

DATA_DIR=/var/lib/grafana

MAX_OPEN_FILES=10000

CONF_DIR=/etc/grafana

CONF_FILE=/etc/grafana/grafana.ini

RESTART_ON_UPGRADE=true

PLUGINS_DIR=/var/lib/grafana/plugins

PROVISIONING_CFG_DIR=/etc/grafana/provisioning

# Only used on systemd systems
PID_FILE_DIR=/var/run/grafana&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Grafana의 &lt;span style=&quot;color: #006dd7;&quot;&gt;서비스 파일(grafana-server.service)&lt;/span&gt;&amp;nbsp;확인&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1678927372566&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Grafana의 service 파일 확인하기
# vi /usr/lib/systemd/system/grafana-server.service&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1678927489127&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[Unit]
Description=Grafana instance
Documentation=http://docs.grafana.org
Wants=network-online.target
After=network-online.target
After=postgresql.service mariadb.service mysqld.service

[Service]
EnvironmentFile=/etc/sysconfig/grafana-server
User=grafana
Group=grafana
Type=notify
Restart=on-failure
WorkingDirectory=/usr/share/grafana
RuntimeDirectory=grafana
RuntimeDirectoryMode=0750
ExecStart=/usr/share/grafana/bin/grafana server                                     \
                            --config=${CONF_FILE}                                   \
                            --pidfile=${PID_FILE_DIR}/grafana-server.pid            \
                            --packaging=rpm                                         \
                            cfg:default.paths.logs=${LOG_DIR}                       \
                            cfg:default.paths.data=${DATA_DIR}                      \
                            cfg:default.paths.plugins=${PLUGINS_DIR}                \
                            cfg:default.paths.provisioning=${PROVISIONING_CFG_DIR}

LimitNOFILE=10000
TimeoutStopSec=20
CapabilityBoundingSet=
DeviceAllow=
LockPersonality=true
MemoryDenyWriteExecute=false
NoNewPrivileges=true
PrivateDevices=true
PrivateTmp=true
ProtectClock=true
ProtectControlGroups=true
ProtectHome=true
ProtectHostname=true
ProtectKernelLogs=true
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectProc=invisible
ProtectSystem=full
RemoveIPC=true
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
RestrictNamespaces=true
RestrictRealtime=true
RestrictSUIDSGID=true
SystemCallArchitectures=native
UMask=0027

[Install]
WantedBy=multi-user.target&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3. Grafana&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;실행&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Grafana &lt;span style=&quot;color: #006dd7;&quot;&gt;서버 실행&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1678925218280&quot; class=&quot;shell&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 그라파나 서버 실행
# systemctl start grafana-server.service

# 그라파나 서버 실행 상태 확인
# systemctl status grafana-server&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Grafana &lt;span style=&quot;color: #006dd7;&quot;&gt;웹 콘솔&lt;/span&gt; 접속&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;{그라파나가 설치된 IP}&lt;/span&gt;:&lt;span style=&quot;color: #ee2323;&quot;&gt;3000&lt;/span&gt;/&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;-&amp;gt; 기본 포트는 3000이다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;접속하면 ID와 PW를 입력하라는 창이 나타나는데, Grafana를 설치한 후, 아무것도 설정하지 않은 채 바로 웹 콘솔에 접속하였다면, 초기 ID와 PW 는 '&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;admin&lt;/b&gt;&lt;/span&gt;' / '&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;admin&lt;/b&gt;&lt;/span&gt;' 이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1918&quot; data-origin-height=&quot;968&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/k3mTC/btr32vwLgf8/v7yxuTRhK7CR7pxRlG6fJK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/k3mTC/btr32vwLgf8/v7yxuTRhK7CR7pxRlG6fJK/img.png&quot; data-alt=&quot;그라파나 웹 콘솔 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/k3mTC/btr32vwLgf8/v7yxuTRhK7CR7pxRlG6fJK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fk3mTC%2Fbtr32vwLgf8%2Fv7yxuTRhK7CR7pxRlG6fJK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1918&quot; height=&quot;968&quot; data-origin-width=&quot;1918&quot; data-origin-height=&quot;968&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;그라파나 웹 콘솔 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;위와 같은 웹 콘솔 화면이 보인다면, grafana-server 실행은 정상적으로 잘 된 것이다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;4. Grafana &lt;span style=&quot;color: #006dd7;&quot;&gt;데이터 소스&lt;/span&gt; 추가&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;설치한 그라파나가 프로메테우스 서버의 metric 들을 가져오기 위해서는, 그라파나에 프로메테우스 Datasource 를 추가해주어야 한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;추가 화면은 아래와 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1629&quot; data-origin-height=&quot;812&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/L0f8u/btr34VVOCL8/k954EdKDOsNv4okDaGQ2mk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/L0f8u/btr34VVOCL8/k954EdKDOsNv4okDaGQ2mk/img.png&quot; data-alt=&quot;그라파나 웹 콘솔 - 왼쪽 메뉴의 [Configuration] - [Data sources] - 'Add data source' 클릭&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/L0f8u/btr34VVOCL8/k954EdKDOsNv4okDaGQ2mk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FL0f8u%2Fbtr34VVOCL8%2Fk954EdKDOsNv4okDaGQ2mk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1629&quot; height=&quot;812&quot; data-origin-width=&quot;1629&quot; data-origin-height=&quot;812&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;그라파나 웹 콘솔 - 왼쪽 메뉴의 [Configuration] - [Data sources] - 'Add data source' 클릭&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'Add data source' 를 클릭하면 아래 그림처럼 추가할 수 있는 데이터소스 목록이 나오는데, 우리는 여기에서 'Prometheus'를 선택한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1405&quot; data-origin-height=&quot;710&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nQ7RG/btr34brkmsg/ce1SHYbUE8hmz0koIwaNK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nQ7RG/btr34brkmsg/ce1SHYbUE8hmz0koIwaNK1/img.png&quot; data-alt=&quot;[Add data source] - 'Prometheus' 선택&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nQ7RG/btr34brkmsg/ce1SHYbUE8hmz0koIwaNK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnQ7RG%2Fbtr34brkmsg%2Fce1SHYbUE8hmz0koIwaNK1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1405&quot; height=&quot;710&quot; data-origin-width=&quot;1405&quot; data-origin-height=&quot;710&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[Add data source] - 'Prometheus' 선택&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 아래 그림처럼 해당 데이터소스를 통해 어떤 서버를 바라볼 것인지부터 Scrape interval 등 다양한 옵션들을 지정해 줄 수 있는데, 적절히 선택 후에 'Save &amp;amp; test' 버튼을 클릭하면 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1729&quot; data-origin-height=&quot;872&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bLj4R5/btr37AwzClx/sODv6p3HASCtwzgM0kAUHK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bLj4R5/btr37AwzClx/sODv6p3HASCtwzgM0kAUHK/img.png&quot; data-alt=&quot;그라파나 data source 설정 (1)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bLj4R5/btr37AwzClx/sODv6p3HASCtwzgM0kAUHK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbLj4R5%2Fbtr37AwzClx%2FsODv6p3HASCtwzgM0kAUHK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1729&quot; height=&quot;872&quot; data-origin-width=&quot;1729&quot; data-origin-height=&quot;872&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;그라파나 data source 설정 (1)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1598&quot; data-origin-height=&quot;806&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zBKOt/btr35FrCjOd/7Wr3YxhdznW1cH2acnchC0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zBKOt/btr35FrCjOd/7Wr3YxhdznW1cH2acnchC0/img.png&quot; data-alt=&quot;그라파나 data source 설정 (2)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zBKOt/btr35FrCjOd/7Wr3YxhdznW1cH2acnchC0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzBKOt%2Fbtr35FrCjOd%2F7Wr3YxhdznW1cH2acnchC0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1598&quot; height=&quot;806&quot; data-origin-width=&quot;1598&quot; data-origin-height=&quot;806&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;그라파나 data source 설정 (2)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;5. Grafana에 Node_Exporter Metric 기반의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;유용한 대시보드 구성&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;- '&lt;span style=&quot;color: #409d00;&quot;&gt;Node Exporter Full&lt;/span&gt;'&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그라파나 공식 사이트에는 여러 사람들이 커스터마이징 해놓은 대시보드들이 공유되어 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;대시보드의 내용은 datasource를 제외하고는 모두 json 으로 설정이 유지된다. 이 말인 즉슨,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;json 설정만 export 또는 import 하게 되면&lt;/b&gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;그라파나 서버가 어디에 있든,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;쉽게 해당 대시보드의 설정 및 패널을 공유하여 재사용성을 높일 수 있다!&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이 포스팅에서는 Node_Exporter 메트릭에서 서버 모니터링을 수월하게 하도록 의미있는 정보들로 대시보드를 만들어놓은, 대표적인 대시보드인&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;'&lt;span style=&quot;color: #409d00;&quot;&gt;Node Exporter Full&lt;/span&gt;'&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;을 기준으로 살펴본다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;'&lt;span style=&quot;color: #409d00;&quot;&gt;Node Exporter Full&lt;/span&gt;' 대시보드 템플릿(?) 사이트&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://grafana.com/grafana/dashboards/1860-node-exporter-full&quot;&gt;https://grafana.com/grafana/dashboards/1860-node-exporter-full&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1678936073813&quot; style=&quot;color: #333333; text-align: start;&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Node Exporter Full | Grafana Labs&quot; data-og-description=&quot;Edit Delete Confirm Cancel&quot; data-og-host=&quot;grafana.com&quot; data-og-source-url=&quot;https://grafana.com/grafana/dashboards/1860-node-exporter-full&quot; data-og-url=&quot;https://grafana.com/grafana/dashboards/1860-node-exporter-full/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bc7hHL/hyRWtboMaj/zLleRmUVGMIiXkId46Izlk/img.jpg?width=1200&amp;amp;height=700&amp;amp;face=0_0_1200_700,https://scrap.kakaocdn.net/dn/bS3Hs8/hyRWmDocte/FLL0iEsclm3Q59CFf7p771/img.jpg?width=1200&amp;amp;height=700&amp;amp;face=0_0_1200_700&quot;&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://grafana.com/grafana/dashboards/1860-node-exporter-full&quot; data-source-url=&quot;https://grafana.com/grafana/dashboards/1860-node-exporter-full&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bc7hHL/hyRWtboMaj/zLleRmUVGMIiXkId46Izlk/img.jpg?width=1200&amp;amp;height=700&amp;amp;face=0_0_1200_700,https://scrap.kakaocdn.net/dn/bS3Hs8/hyRWmDocte/FLL0iEsclm3Q59CFf7p771/img.jpg?width=1200&amp;amp;height=700&amp;amp;face=0_0_1200_700');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; style=&quot;color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;Node Exporter Full | Grafana Labs&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; style=&quot;color: #909090;&quot; data-ke-size=&quot;size16&quot;&gt;Edit Delete Confirm Cancel&lt;/p&gt;
&lt;p class=&quot;og-host&quot; style=&quot;color: #909090;&quot; data-ke-size=&quot;size16&quot;&gt;grafana.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1520&quot; data-origin-height=&quot;728&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/q42ax/btr32ukqxF9/0e66oNyVyFOrlWEJz28DYK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/q42ax/btr32ukqxF9/0e66oNyVyFOrlWEJz28DYK/img.png&quot; data-alt=&quot;'Node Exporter Full' 대시보드 사이트&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/q42ax/btr32ukqxF9/0e66oNyVyFOrlWEJz28DYK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fq42ax%2Fbtr32ukqxF9%2F0e66oNyVyFOrlWEJz28DYK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1520&quot; height=&quot;728&quot; data-origin-width=&quot;1520&quot; data-origin-height=&quot;728&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;'Node Exporter Full' 대시보드 사이트&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;JSON 형태로도 다운 받을 수 있는데, 그라파나에 쉽게 바로 적용하기 위해 'Copy ID to clipboard' 로 이 대시보드의 ID만 복사해서 사용하자!&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;그라파나에 대시보드 ID로&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;대시보드 Import&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;하기&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그라파나 웹 콘솔에서 왼쪽 메뉴의 [Dashboards] - [+ Import] 를 클릭하자!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1504&quot; data-origin-height=&quot;813&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cOGNfi/btr37ub5QE5/UWmlNV1lknOOe63l0nn851/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cOGNfi/btr37ub5QE5/UWmlNV1lknOOe63l0nn851/img.png&quot; data-alt=&quot;그라파나 웹 콘솔 - 왼쪽의 [Dashboards] 메뉴 - [ + Import] 클릭&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cOGNfi/btr37ub5QE5/UWmlNV1lknOOe63l0nn851/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcOGNfi%2Fbtr37ub5QE5%2FUWmlNV1lknOOe63l0nn851%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1504&quot; height=&quot;813&quot; data-origin-width=&quot;1504&quot; data-origin-height=&quot;813&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;그라파나 웹 콘솔 - 왼쪽의 [Dashboards] 메뉴 - [ + Import] 클릭&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;복사한 대시보드 ID를 입력하고 'Load' 버튼을 클릭하자!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1570&quot; data-origin-height=&quot;792&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMdBax/btr38oW0AWH/mI9fl6FMmk7aekgBkBeHLK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMdBax/btr38oW0AWH/mI9fl6FMmk7aekgBkBeHLK/img.png&quot; data-alt=&quot;[Import dashboard] 창 - 복사한 대시보드 ID 입력 - 'Load' 버튼 클릭&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMdBax/btr38oW0AWH/mI9fl6FMmk7aekgBkBeHLK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMdBax%2Fbtr38oW0AWH%2FmI9fl6FMmk7aekgBkBeHLK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1570&quot; height=&quot;792&quot; data-origin-width=&quot;1570&quot; data-origin-height=&quot;792&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[Import dashboard] 창 - 복사한 대시보드 ID 입력 - 'Load' 버튼 클릭&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그럼 아래 그림처럼 이 대시보드를 어떤 이름으로, 어떤 폴더에 저장할 것이고, 어떤 데이터소스를 기반으로 할 것인지를 선택할 수 있다. 우리는 프로메테우스 서버의 데이터를 시각화하여 대시보드를 만드는 것이므로, 데이터 소스를 프로메테우스로 설정한 데이터소스로 잡아주자. 그리고 'Import' 버튼을 클릭하면 된다!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1663&quot; data-origin-height=&quot;839&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjy9gB/btr38OuAEVp/HdSaxdSeex0Ke8DOle9w5k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjy9gB/btr38OuAEVp/HdSaxdSeex0Ke8DOle9w5k/img.png&quot; data-alt=&quot;[Import dashboard] 창 - Options 작성 / 데이터소스를 프로메테우스 기반 데이터소스로 설정 - 'Import' 버튼 클릭&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjy9gB/btr38OuAEVp/HdSaxdSeex0Ke8DOle9w5k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbjy9gB%2Fbtr38OuAEVp%2FHdSaxdSeex0Ke8DOle9w5k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1663&quot; height=&quot;839&quot; data-origin-width=&quot;1663&quot; data-origin-height=&quot;839&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[Import dashboard] 창 - Options 작성 / 데이터소스를 프로메테우스 기반 데이터소스로 설정 - 'Import' 버튼 클릭&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Import 된 'Node Exporter Full' 대시보드 확인&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1511&quot; data-origin-height=&quot;762&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0aJqV/btr34MLDPzE/WVi7Cz2zH5Tgc2tiQA5R50/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0aJqV/btr34MLDPzE/WVi7Cz2zH5Tgc2tiQA5R50/img.png&quot; data-alt=&quot;Import 된 'Node Exporter Full' 대시보드&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0aJqV/btr34MLDPzE/WVi7Cz2zH5Tgc2tiQA5R50/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0aJqV%2Fbtr34MLDPzE%2FWVi7Cz2zH5Tgc2tiQA5R50%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1511&quot; height=&quot;762&quot; data-origin-width=&quot;1511&quot; data-origin-height=&quot;762&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Import 된 'Node Exporter Full' 대시보드&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;패스트캠퍼스 - '한 번에 끝내는 데이터 엔지니어링 초격차 패키지 Online' 중 Part.5 Observability - Ch 04_01. / Ch 04_02.&lt;/p&gt;</description>
      <category>Observability</category>
      <category>Grafana CentOS 7</category>
      <category>Grafana Node Exporter Full</category>
      <category>Grafana systemctl 파일</category>
      <category>Grafana yum</category>
      <category>Grafana 대시보드 템플릿</category>
      <category>grafana 설치</category>
      <category>그라파나 설치</category>
      <category>그라파나 프로메테우스 연동</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/136</guid>
      <comments>https://co-no.tistory.com/entry/Grafana-Prometheus%EC%9D%98-Metric-%EC%9D%84-%EC%8B%9C%EA%B0%81%ED%99%94%ED%95%98%EC%97%AC-%EB%8C%80%EC%8B%9C%EB%B3%B4%EB%93%9C%EB%A5%BC-%EB%A7%8C%EB%93%A4-%EC%88%98-%EC%9E%88%EB%8A%94-Grafana-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0#entry136comment</comments>
      <pubDate>Thu, 16 Mar 2023 10:21:21 +0900</pubDate>
    </item>
    <item>
      <title>[MSSQL] Lock 상황 유발해보고, Lock을 유발하는 세션 찾아서 종료시키기</title>
      <link>https://co-no.tistory.com/entry/MSSQL-Lock-%EC%83%81%ED%99%A9-%EC%9C%A0%EB%B0%9C%ED%95%B4%EB%B3%B4%EA%B3%A0-Lock%EC%9D%84-%EC%9C%A0%EB%B0%9C%ED%95%98%EB%8A%94-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%EC%B0%BE%EC%95%84%EC%84%9C-%EC%A2%85%EB%A3%8C%EC%8B%9C%ED%82%A4%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Lock 유발시키기에 앞서, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;아래 쿼리는 Lock을 인위적으로 유발하기 위해 사용하는 쿼리&lt;/b&gt;&lt;/span&gt;로, 인위적으로 트랜잭션의 수행시간을 1시간으로 지정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;현업의 운영 DB에서는 해당 쿼리를 절대 사용하면 안된다. 반드시 테스트 용도로만 사용해야 한다.&lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1. 테이블 Lock 걸리도록 하는 쿼리 수행&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1678776211561&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- 테스트 DB로 SQL Server 에서 공식적으로 제공하는 'AdventureWorks2019' 샘플 DB를 사용한다.
USE AdventureWorks2019

-- 테스트 해볼 row를 조회하는 쿼리
SELECT ProductID, Name
FROM Production.Product
WHERE ProductID=999
-- 수행 결과 : ProductID: 999 / Name: Road-750 Black, 52

BEGIN TRAN
	UPDATE Production.Product SET Name='test'
    WHERE ProductID=999
    
    WAITFOR DELAY '01:00:00' 	-- 트랜잭션은 임의로 1시간 delay
   
COMMIT TRAN&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 쿼리를 수행한 후, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;동일한 DB의 새 쿼리 창&lt;/b&gt;&lt;/span&gt;을 연 다음 아래 쿼리를 수행해보자.&lt;/p&gt;
&lt;pre id=&quot;code_1678776385952&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT ProductID, Name
FROM AdventureWorks2019.Production.Product
WHERE ProductID=999&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 결과는 아래와 같이, 당연하게도 1시간동안 트랜잭션으로 해당 테이블을 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;Lock 걸게 만들었으니, SELECT 쿼리가 수행되지 않을 것&lt;/b&gt;&lt;/span&gt;이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1298&quot; data-origin-height=&quot;626&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Bz8WQ/btr3StRXkkE/gEGwUsHtifhnkmZOt5qrkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Bz8WQ/btr3StRXkkE/gEGwUsHtifhnkmZOt5qrkk/img.png&quot; data-alt=&quot;Lock 걸린 테이블을 조회해서 쿼리가 지연되는 상황&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Bz8WQ/btr3StRXkkE/gEGwUsHtifhnkmZOt5qrkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBz8WQ%2Fbtr3StRXkkE%2FgEGwUsHtifhnkmZOt5qrkk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;877&quot; height=&quot;423&quot; data-origin-width=&quot;1298&quot; data-origin-height=&quot;626&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Lock 걸린 테이블을 조회해서 쿼리가 지연되는 상황&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2. 현재 Lock 을 유발하는 쿼리가 사용하고 있는 &lt;span style=&quot;color: #006dd7;&quot;&gt;데이터베이스의 ID&lt;/span&gt; 확인&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 데이터베이스가 Lock 걸린 상황인 것을 확인했다면, 이제 그 &lt;b&gt;데이터베이스의 개체 ID&lt;/b&gt;를 조회해보자!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;'sys.dm_tran_locks'&lt;/b&gt;&lt;/span&gt; T-SQL 을 사용하기 위해 DB_ID를 확인하는 것이다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1678776701659&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- name='Lock 걸린 데이터베이스 이름'
SELECT database_id, name FROM sys.databases
WHERE name = 'AdventureWorks2019'&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;265&quot; data-origin-height=&quot;74&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/E6lsg/btr3HoknrlZ/XpvAo5KcCnjWXBTzQxgdFK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/E6lsg/btr3HoknrlZ/XpvAo5KcCnjWXBTzQxgdFK/img.png&quot; data-alt=&quot;Lock 걸린 데이터베이스인 'AdventureWorks2019' 의 DB_ID 확인&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/E6lsg/btr3HoknrlZ/XpvAo5KcCnjWXBTzQxgdFK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FE6lsg%2Fbtr3HoknrlZ%2FXpvAo5KcCnjWXBTzQxgdFK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;265&quot; height=&quot;74&quot; data-origin-width=&quot;265&quot; data-origin-height=&quot;74&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Lock 걸린 데이터베이스인 'AdventureWorks2019' 의 DB_ID 확인&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3. &lt;span style=&quot;color: #006dd7;&quot;&gt;Lock 정보&lt;/span&gt;를 확인하기&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1678776983045&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- Lock 정보를 조회하는 쿼리
-- resource_database_id = &amp;lt;dbid&amp;gt; 값에 위에서 조회한 데이터베이스의 ID를 넣어야 함.
SELECT resource_type, resource_associated_entity_id,  
    request_status, request_mode,request_session_id,  
    resource_description   
FROM sys.dm_tran_locks  
WHERE resource_database_id = 5&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;'sp_lock'&lt;/b&gt; &lt;/span&gt;을 사용해도 되나, 이는 &lt;b&gt;&lt;u&gt;SQL Server 2016 버전 이후부터는 Deprecated 되어&lt;/u&gt;&lt;/b&gt; 더이상 권장하지 않는 방법이므로, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;'sys.dm_tran_locks'&lt;/b&gt; &lt;/span&gt;를 사용하자!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1175&quot; data-origin-height=&quot;683&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dsXTLB/btr3HQueIY1/WMrL9UD6bp386aEiDz7n71/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dsXTLB/btr3HQueIY1/WMrL9UD6bp386aEiDz7n71/img.png&quot; data-alt=&quot;sys.dm_tran_locks 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dsXTLB/btr3HQueIY1/WMrL9UD6bp386aEiDz7n71/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdsXTLB%2Fbtr3HQueIY1%2FWMrL9UD6bp386aEiDz7n71%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;743&quot; height=&quot;432&quot; data-origin-width=&quot;1175&quot; data-origin-height=&quot;683&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;sys.dm_tran_locks 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 결과를 보면,&lt;b&gt; mode가&lt;span style=&quot;color: #ee2323;&quot;&gt; IX&lt;/span&gt;로&lt;/b&gt; 배타적 잠금에 걸린 걸 확인할 수 있다. Lock 걸린 개체(테이블)의 &lt;b&gt;entity ID&lt;/b&gt;는 '&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;72057594061783040&lt;/b&gt;&lt;/span&gt;' 인 것을 확인할 수 있고, Lock 을 잡고 있는 &lt;b&gt;세션의 ID&lt;/b&gt;는 '&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;52&lt;/b&gt;&lt;/span&gt;' 인 것을 기억해두자!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 쿼리는 &lt;b&gt;entity ID 로 object ID를 알아보기 위한 쿼리&lt;/b&gt;이다. 참고로 알아두자.&lt;/p&gt;
&lt;pre id=&quot;code_1678778539843&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT object_name(object_id), *  
FROM sys.partitions  
WHERE hobt_id=72057594061783040&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1096&quot; data-origin-height=&quot;67&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vrY4f/btr3HUKcDeT/Oh7yHKTtmuVyseq0QOovCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vrY4f/btr3HUKcDeT/Oh7yHKTtmuVyseq0QOovCK/img.png&quot; data-alt=&quot;sys.partitions 쿼리 수행 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vrY4f/btr3HUKcDeT/Oh7yHKTtmuVyseq0QOovCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvrY4f%2Fbtr3HUKcDeT%2FOh7yHKTtmuVyseq0QOovCK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1096&quot; height=&quot;67&quot; data-origin-width=&quot;1096&quot; data-origin-height=&quot;67&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;sys.partitions 쿼리 수행 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;4. Lock 을 유발시키는 세션 ID를 통해 &lt;span style=&quot;color: #006dd7;&quot;&gt;해당 세션이 수행한 스크립트를 확인&lt;/span&gt;해보자&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1678778604743&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- Lock 을 유발시키는 Session_ID를 통해 해당 세션이 수행한 스크립트를 확인하는 T-SQL
-- DBCC INPUTBUFFER ('session_id')
DBCC INPUTBUFFER (52)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1530&quot; data-origin-height=&quot;122&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FYkeh/btr3Q9GfC3z/wVJmmEI4TiBmlKlFa4VzVK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FYkeh/btr3Q9GfC3z/wVJmmEI4TiBmlKlFa4VzVK/img.png&quot; data-alt=&quot;Lock 유발한 범인을 확인할 수 있다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FYkeh/btr3Q9GfC3z/wVJmmEI4TiBmlKlFa4VzVK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFYkeh%2Fbtr3Q9GfC3z%2FwVJmmEI4TiBmlKlFa4VzVK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1530&quot; height=&quot;122&quot; data-origin-width=&quot;1530&quot; data-origin-height=&quot;122&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Lock 유발한 범인을 확인할 수 있다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;5. Lock을 유발한 &lt;span style=&quot;color: #ee2323;&quot;&gt;세션 종료&lt;/span&gt;시키기&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;mass update 성격의 쿼리&lt;/b&gt;가 수행되는 &lt;u&gt;&lt;b&gt;세션을 함부로 종료했다가는 데이터의 정합성이 다 깨져버리니&lt;/b&gt;&lt;/u&gt;, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;세션을 강제 종료시킬 때에는 정말 신중해야 한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;※ 해당 세션을 종료시키게 되면, 쿼리가 중간에 수행되다 중단되는 것이기 때문에, 반드시 해당 애플리케이션 오너와 상의가 필요하다. 예를 들어, 회사에서 급여를 올리는 batch 를 돌렸는데 그 세션을 중간에 종료시켜버리면, 어떤 사람은 급여가 올라갔는데, 어떤 사람은 올라가지 않은 불상사가 발생할 수 있다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1678778842934&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- 종료를 해도 되는 세션이라면 강제로 종료시키는 방법
-- 여기서는 일부러 딜레이 시키는 쿼리를 수행하는 세션이므로 종료시켜도 된다.
-- KILL 'session_id'
KILL 52&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;6. 원래 수행하려던 쿼리 수행하여 &lt;span style=&quot;color: #006dd7;&quot;&gt;Lock 해제된 것 확인&lt;/span&gt;하기.&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1678778926008&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT ProductID, Name
FROM AdventureWorks2019.Production.Product
WHERE ProductID=999&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;555&quot; data-origin-height=&quot;690&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bArIew/btr3J3mlIMo/BD8hMicgvBbWI4u7BMUxe1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bArIew/btr3J3mlIMo/BD8hMicgvBbWI4u7BMUxe1/img.png&quot; data-alt=&quot;AdventureWorks2019 DB 의 Lock 이 해제되어 정상적으로 데이터가 조회된다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bArIew/btr3J3mlIMo/BD8hMicgvBbWI4u7BMUxe1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbArIew%2Fbtr3J3mlIMo%2FBD8hMicgvBbWI4u7BMUxe1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;276&quot; height=&quot;343&quot; data-origin-width=&quot;555&quot; data-origin-height=&quot;690&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;AdventureWorks2019 DB 의 Lock 이 해제되어 정상적으로 데이터가 조회된다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/sql/relational-databases/system-dynamic-management-views/sys-dm-tran-locks-transact-sql?view=sql-server-ver16&quot;&gt;https://learn.microsoft.com/ko-kr/sql/relational-databases/system-dynamic-management-views/sys-dm-tran-locks-transact-sql?view=sql-server-ver16&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1678775772087&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;sys.dm_tran_locks(Transact-SQL) - SQL Server&quot; data-og-description=&quot;sys.dm_tran_locks(Transact-SQL)&quot; data-og-host=&quot;learn.microsoft.com&quot; data-og-source-url=&quot;https://learn.microsoft.com/ko-kr/sql/relational-databases/system-dynamic-management-views/sys-dm-tran-locks-transact-sql?view=sql-server-ver16&quot; data-og-url=&quot;https://learn.microsoft.com/ko-kr/sql/relational-databases/system-dynamic-management-views/sys-dm-tran-locks-transact-sql&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/HjRZ0/hyRVgJ2Bss/opmV6mYcN29qTTCSAZewB1/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400&quot;&gt;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/sql/relational-databases/system-dynamic-management-views/sys-dm-tran-locks-transact-sql?view=sql-server-ver16&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://learn.microsoft.com/ko-kr/sql/relational-databases/system-dynamic-management-views/sys-dm-tran-locks-transact-sql?view=sql-server-ver16&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/HjRZ0/hyRVgJ2Bss/opmV6mYcN29qTTCSAZewB1/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;sys.dm_tran_locks(Transact-SQL) - SQL Server&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;sys.dm_tran_locks(Transact-SQL)&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;learn.microsoft.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DB/SQL Server (MSSQL)</category>
      <category>dbcc inputbuffer</category>
      <category>SQL Server 2019 Lock</category>
      <category>SQL Server Lock 유발</category>
      <category>SQL Server Lock 해제</category>
      <category>SQL Server 세션 강제 종료</category>
      <category>sys.dm_tran_locks</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/135</guid>
      <comments>https://co-no.tistory.com/entry/MSSQL-Lock-%EC%83%81%ED%99%A9-%EC%9C%A0%EB%B0%9C%ED%95%B4%EB%B3%B4%EA%B3%A0-Lock%EC%9D%84-%EC%9C%A0%EB%B0%9C%ED%95%98%EB%8A%94-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%EC%B0%BE%EC%95%84%EC%84%9C-%EC%A2%85%EB%A3%8C%EC%8B%9C%ED%82%A4%EA%B8%B0#entry135comment</comments>
      <pubDate>Tue, 14 Mar 2023 16:37:51 +0900</pubDate>
    </item>
    <item>
      <title>[Prometheus] CentOS 7 에서 프로메테우스(Prometheus) 설치 및 기본 설정, 실행</title>
      <link>https://co-no.tistory.com/entry/Observability-%ED%94%84%EB%A1%9C%EB%A9%94%ED%85%8C%EC%9A%B0%EC%8A%A4Prometheus-%EC%84%A4%EC%B9%98-%EB%B0%8F-%EA%B8%B0%EB%B3%B8-%EC%84%A4%EC%A0%95-%EC%8B%A4%ED%96%89</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1. 프로메테우스 &lt;span style=&quot;color: #006dd7;&quot;&gt;설치&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1678252059909&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 'prometheus' 유저 추가
# useradd --no-create-home --shell /sbin/nologin prometheus

# 프로메테우스 다운로드
# cd ~/Downloads
# wget https://github.com/prometheus/prometheus/releases/download/v2.42.0/prometheus-2.42.0.linux-amd64.tar.gz
# 위 다운로드 링크는 설치하려는 프로메테우스의 버전, OS 버전에 따라 달라진다.

# 다운로드 받은 프로메테우스 tar.gz 파일 압축 풀기
# tar -xzvf prometheus-2.42.0.linux-amd64.tar.gz

# prometheus 설치 경로 변경
# mv ~/Downloads/prometheus-2.42.0.linux-amd64 /opt/prometheus

# 관리 편의를 위한 디렉토리 생성
# mkdir /opt/prometheus/bin /opt/prometheus/conf /opt/prometheus/data

# prometheus HOME 디렉토리 권한 부여
# chown -R prometheus:prometheus /opt/prometheus&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2. 프로메테우스 &lt;span style=&quot;color: #006dd7;&quot;&gt;실행&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1678252901673&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 프로메테우스 설치 경로로 이동
$ cd /opt/prometheus

# 프로메테우스 서버 실행
$ ./prometheus --config.file=/opt/prometheus/conf/prometheus.yml&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1517&quot; data-origin-height=&quot;466&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/p2CRe/btr2ORlsrM6/kMEJyyslxNAXdn0Uvzjzk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/p2CRe/btr2ORlsrM6/kMEJyyslxNAXdn0Uvzjzk0/img.png&quot; data-alt=&quot;프로메테우스 실행 성공 출력 화면 - &amp;quot;Starting rule manager...&amp;quot; 를 확인하기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/p2CRe/btr2ORlsrM6/kMEJyyslxNAXdn0Uvzjzk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fp2CRe%2Fbtr2ORlsrM6%2FkMEJyyslxNAXdn0Uvzjzk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1517&quot; height=&quot;466&quot; data-origin-width=&quot;1517&quot; data-origin-height=&quot;466&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;프로메테우스 실행 성공 출력 화면 - &quot;Starting rule manager...&quot; 를 확인하기&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;- 프로메테우스 접속&lt;/b&gt; - default는 9090 포트&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;http://{프로메테우스 올라간 서버 IP 또는 DNS 호스트네임}:9090/&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;ex) http://10.0.2.15:9090/&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 url로 접속이 된다면 프로메테우스 서버가 정상적으로 구동된 것이다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3. &lt;span style=&quot;color: #006dd7;&quot;&gt;Metric 이름&lt;/span&gt;으로 검색해보기&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;http://{프로메테우스 올라간 서버 IP 또는 DNS 호스트네임}:9090/metrics&amp;nbsp;&lt;/b&gt;로 접속하면 프로메테우스 서버가 수집한 metric 들을 확인할 수 있다. 이러한 metric 들은 프로메테우스의 GUI 콘솔 상에서도 다음과 같이 검색이 가능하다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1256&quot; data-origin-height=&quot;723&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/caxQ0y/btr2Iwh8GuK/pKY9f6dHrpfc638TPKEMwK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/caxQ0y/btr2Iwh8GuK/pKY9f6dHrpfc638TPKEMwK/img.png&quot; data-alt=&quot;/metrics 에서 확인해본 'go_memstats_alloc_bytes' 메트릭&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/caxQ0y/btr2Iwh8GuK/pKY9f6dHrpfc638TPKEMwK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcaxQ0y%2Fbtr2Iwh8GuK%2FpKY9f6dHrpfc638TPKEMwK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;786&quot; height=&quot;452&quot; data-origin-width=&quot;1256&quot; data-origin-height=&quot;723&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;/metrics 에서 확인해본 'go_memstats_alloc_bytes' 메트릭&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1489&quot; data-origin-height=&quot;540&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SSHR9/btr2C8XcFY3/wYZ6MoikHUvJ2qnkKTPYv0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SSHR9/btr2C8XcFY3/wYZ6MoikHUvJ2qnkKTPYv0/img.png&quot; data-alt=&quot;프로메테우스 콘솔 페이지에서 metric 이름으로 검색한 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SSHR9/btr2C8XcFY3/wYZ6MoikHUvJ2qnkKTPYv0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSSHR9%2Fbtr2C8XcFY3%2FwYZ6MoikHUvJ2qnkKTPYv0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;965&quot; height=&quot;350&quot; data-origin-width=&quot;1489&quot; data-origin-height=&quot;540&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;프로메테우스 콘솔 페이지에서 metric 이름으로 검색한 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;4. &lt;span style=&quot;color: #006dd7;&quot;&gt;prometheus.yml&lt;/span&gt; (프로메테우스 configuration 파일) 의 &lt;span style=&quot;color: #006dd7;&quot;&gt;Default&lt;/span&gt; 설정 살펴보기&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1678254835584&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# prometheus.yml 파일

# my global config
global:
  scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
  evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
  # scrape_timeout is set to the global default (10s).
 
# Alertmanager configuration
alerting:
  alertmanagers:
    - static_configs:
        - targets:
          # - alertmanager:9093

# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
  # - &quot;first_rules.yml&quot;
  # - &quot;second_rules.yml&quot;

 # A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
  # The job name is added as a label `job=&amp;lt;job_name&amp;gt;` to any timeseries scraped from this config.
    - job_name: &quot;prometheus&quot;
    
      # metrics_paht defaults to '/metrics'
      # scheme defaults to 'http'.
      
        static_configs:
          - targets: [&quot;localhost:9090&quot;]&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;5. systemctl에 &lt;span style=&quot;color: #006dd7;&quot;&gt;service 등록&lt;/span&gt;하기&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;- service 파일 생성&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1678260009918&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# vi /usr/lib/systemd/system/prometheus.service&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1678259226699&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# /usr/lib/systemd/system/prometheus.service 파일

[Unit]
Description=Prometheus Server
Documentation=https://prometheus.io/docs/introduction/overview/
Wants=network-online.target
After=network-online.target

[Service]
EnvironmentFile=/etc/sysconfig/prometheus
PIDFile=/var/run/prometheus.pid

User=prometheus
Group=prometheus
Restart=on-failure

WorkingDirectory=/opt/prometheus
RuntimeDirectory=prometheus
RuntimeDirectoryMode=0750

ExecStart=/opt/prometheus/bin/prometheus                                \
  --config.file=${CONF_FILE}                                            \
  --storage.tsdb.path=${DATA_DIR}										\
  --web.console.templates=${PROMETHEUS_HOME}/consoles                   \
  --web.console.libraries=${PROMETHEUS_HOME}/cconsole_libraries         \
  --web.enable-admin-api
  --storage.tsdb.retention.time=30d    # prometheus에서 수집한 데이터 보관 주기를 30일로 지정

[Install]
WantedBy=multi-user.target&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;- service 파일 작성시 깔끔하게 작성하기 위한, /etc/sysconfig/prometheus 작성&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1679037349429&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# vi /etc/sysconfig/prometheus 로 파일 생성

# /etc/sysconfig/prometheus 파일

PROMETHEUS_USER=prometheus

PROMETHEUS_GROUP=prometheus

PROMETHEUS_HOME=/opt/prometheus

LOG_DIR=/opt/prometheus/logs

DATA_DIR=/opt/prometheus/data

CONF_DIR=/opt/prometheus/conf

CONF_FILE=/opt/prometheus/conf/prometheus.yml

# Only used on systemd systems
PID_FILE_DIR=/var/run/prometheus&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;- 새로 작성한 .service 파일을 systemctl 에 인식시키기&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1678260065510&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# systemctl daemon-reload&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;- 프로메테우스를 systemctl 로 구동하기&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1678260222486&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# systemctl start prometheus&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;- 부팅시 자동으로 서비스 시작하도록 하기&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1678260110606&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# systemctl enable prometheus.service&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://sanggi-jayg.tistory.com/91&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://sanggi-jayg.tistory.com/91&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1678251717367&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[CentOS 7] Prometheus + Grafana 설치&quot; data-og-description=&quot;CentOS 7 에 Prometheus + Grafana 설치 메뉴얼 프로메테우스 설치 https://prometheus.io/ # 유저 추가 useradd -m -s /bin/bash prometheus su - prometheus # 다운로드 cd /home/prometheus wget https://github.com/prometheus/prometheus/releases&quot; data-og-host=&quot;sanggi-jayg.tistory.com&quot; data-og-source-url=&quot;https://sanggi-jayg.tistory.com/91&quot; data-og-url=&quot;https://sanggi-jayg.tistory.com/91&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cbRZ2a/hyRRDegAVy/VyGgwo9LDil7JwnRjI75B0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/eGqq1/hyRRGhKi3P/pflY5fl8Olt71rtWFPUpJ0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://sanggi-jayg.tistory.com/91&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://sanggi-jayg.tistory.com/91&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cbRZ2a/hyRRDegAVy/VyGgwo9LDil7JwnRjI75B0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/eGqq1/hyRRGhKi3P/pflY5fl8Olt71rtWFPUpJ0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[CentOS 7] Prometheus + Grafana 설치&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;CentOS 7 에 Prometheus + Grafana 설치 메뉴얼 프로메테우스 설치 https://prometheus.io/ # 유저 추가 useradd -m -s /bin/bash prometheus su - prometheus # 다운로드 cd /home/prometheus wget https://github.com/prometheus/prometheus/releases&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;sanggi-jayg.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;패스트캠퍼스 - '한 번에 끝내는 데이터 엔지니어링 초격차 패키지 Online' 중 Part.5 Observability - Ch 02_02.&lt;/p&gt;</description>
      <category>Observability</category>
      <category>prometheus install</category>
      <category>prometheus.yml 디폴트</category>
      <category>프로메테우스 설정 파일</category>
      <category>프로메테우스 설치</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/133</guid>
      <comments>https://co-no.tistory.com/entry/Observability-%ED%94%84%EB%A1%9C%EB%A9%94%ED%85%8C%EC%9A%B0%EC%8A%A4Prometheus-%EC%84%A4%EC%B9%98-%EB%B0%8F-%EA%B8%B0%EB%B3%B8-%EC%84%A4%EC%A0%95-%EC%8B%A4%ED%96%89#entry133comment</comments>
      <pubDate>Tue, 14 Mar 2023 08:44:45 +0900</pubDate>
    </item>
    <item>
      <title>[Linux][CentOS 7] vi, vim 테마(colorscheme) 설정 - onehalf</title>
      <link>https://co-no.tistory.com/entry/LinuxCentOS-7-vi-vim-%ED%85%8C%EB%A7%88-%EC%84%A4%EC%A0%95</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;0. &lt;span style=&quot;color: #006dd7;&quot;&gt;vi -&amp;gt; vim&lt;/span&gt; 으로 설정하기&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;* vim&lt;/b&gt; : &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;vi 에디터보다 쉬운&lt;/b&gt;&lt;/span&gt; 텍스트 에디터이며, &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;vi에서 확장된 기능&lt;/b&gt;&lt;/span&gt;들을 가지고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;vim 설치 - yum 으로 진행&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1678235078858&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# yum -y install vim&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;alias 설정&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;- 전역으로 설정하기 (모든 user들에 적용됨)&lt;/p&gt;
&lt;pre id=&quot;code_1678235644953&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# vi /etc/bashrc&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 해당 계정에만 설정하기&lt;/p&gt;
&lt;pre id=&quot;code_1678235768827&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ cd ~
$ vi .bashrc	('.bashrc' 라는 파일을 User의 홈 디렉토리에 생성하여 내용 설정)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;- alias 구문 추가&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 구문을 /etc/bashrc 파일 또는 ~/.bashrc 파일 가장 아래에 추가한다.&lt;/p&gt;
&lt;pre id=&quot;code_1678236200946&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;alias vi='/usr/bin/vim'&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;647&quot; data-origin-height=&quot;154&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cqeqXk/btr2D7Qk9jK/oRTHTtO2rFcvHxWB6ZqKl0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cqeqXk/btr2D7Qk9jK/oRTHTtO2rFcvHxWB6ZqKl0/img.png&quot; data-alt=&quot;/etc/bashrc 파일의 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cqeqXk/btr2D7Qk9jK/oRTHTtO2rFcvHxWB6ZqKl0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcqeqXk%2Fbtr2D7Qk9jK%2FoRTHTtO2rFcvHxWB6ZqKl0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;530&quot; height=&quot;126&quot; data-origin-width=&quot;647&quot; data-origin-height=&quot;154&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;/etc/bashrc 파일의 예시&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;- 변경된 설정 내용 적용&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1678236577774&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# source /etc/bashrc

또는

$ source ~/.bashrc&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 과정을 모두 진행하면, vi 명령어가 vim 으로 자동 적용되는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1. onehalf 테마 &lt;span style=&quot;color: #006dd7;&quot;&gt;다운로드&lt;/span&gt; 하기&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/sonph/onehalf/tree/master/vim/colors&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/sonph/onehalf/tree/master/vim/colors&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1678237174175&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - sonph/onehalf: Clean, vibrant and pleasing color schemes for Vim, Sublime Text, iTerm, gnome-terminal and more.&quot; data-og-description=&quot;Clean, vibrant and pleasing color schemes for Vim, Sublime Text, iTerm, gnome-terminal and more. - GitHub - sonph/onehalf: Clean, vibrant and pleasing color schemes for Vim, Sublime Text, iTerm, gn...&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/sonph/onehalf/tree/master/vim/colors&quot; data-og-url=&quot;https://github.com/sonph/onehalf&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/obTKb/hyRRMINKhM/IRpwry9KaS9TOAnS6hY6uk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/sonph/onehalf/tree/master/vim/colors&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/sonph/onehalf/tree/master/vim/colors&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/obTKb/hyRRMINKhM/IRpwry9KaS9TOAnS6hY6uk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - sonph/onehalf: Clean, vibrant and pleasing color schemes for Vim, Sublime Text, iTerm, gnome-terminal and more.&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Clean, vibrant and pleasing color schemes for Vim, Sublime Text, iTerm, gnome-terminal and more. - GitHub - sonph/onehalf: Clean, vibrant and pleasing color schemes for Vim, Sublime Text, iTerm, gn...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 링크로 들어가면, vim에 대한 onehalf 컬러 스키마를 다운 받을 수 있다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 나는 어두운 게 좋아서 'onehalfdark.vim' 으로 설치했다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2. onehalf &lt;span style=&quot;color: #006dd7;&quot;&gt;테마 파일 위치&lt;/span&gt;해놓기&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 전역으로 설정&lt;/p&gt;
&lt;pre id=&quot;code_1678238470736&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# cp ${테마 설치한 경로}/onehalfdark.vim /usr/share/vim/vimfiles/colors/	# /usr/share/vim/vimfiles/colors 에 컬러스키마 파일들이 모여 있음.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 해당 유저만 설정&lt;/p&gt;
&lt;pre id=&quot;code_1678237477678&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ mkdir -p ~/.vim/colors/		# 홈 디렉토리에 .vim 와 colors 디렉토리 만들기

$ cp ${테마 설치한 경로}/onehalfdark.vim ~/.vim/colors/	# 홈 디렉토리의 .vim/colors 하위에 테마 파일 복사하기&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3. &lt;span style=&quot;color: #006dd7;&quot;&gt;vimrc 파일&lt;/span&gt;에 &lt;span style=&quot;color: #ef6f53;&quot;&gt;'colorscheme' 구문&lt;/span&gt; 추가하여 테마(vim 파일) 지정해주기&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 전역으로 설정&lt;/p&gt;
&lt;pre id=&quot;code_1678238424901&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# vi /etc/vimrc		# /etc/vimrc 파일 열어서 수정하기&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;/etc/vimrc 파일 가장 하단에 아래 구문 추가&lt;/p&gt;
&lt;pre id=&quot;code_1678238454490&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;colorscheme onehalfdark&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 해당 유저만 설정&lt;/p&gt;
&lt;pre id=&quot;code_1678238140288&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ vi ~/.vimrc	# 홈 디렉토리의 .vimrc 파일 열어서 수정하기&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.vimrc 파일 가장 하단에 아래 구문 추가&lt;/p&gt;
&lt;pre id=&quot;code_1678237768638&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;colorscheme onehalfdark&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1125&quot; data-origin-height=&quot;737&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7R0aD/btr2FiD5oSp/mmzXI6PbVQPAyp4vKmkWHK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7R0aD/btr2FiD5oSp/mmzXI6PbVQPAyp4vKmkWHK/img.png&quot; data-alt=&quot;~/.vimrc 파일 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7R0aD/btr2FiD5oSp/mmzXI6PbVQPAyp4vKmkWHK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7R0aD%2Fbtr2FiD5oSp%2FmmzXI6PbVQPAyp4vKmkWHK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;613&quot; height=&quot;402&quot; data-origin-width=&quot;1125&quot; data-origin-height=&quot;737&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;~/.vimrc 파일 예시&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 과정까지 완료하면, 이제 vi 에디터를 열 때, 예쁘게 테마가 설정된 걸 확인할 수 있다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;혹시나 적용이 되지 않는 경우에는, &lt;b&gt;테마 파일의 파일 권한&lt;/b&gt;이 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;644(rw-r--r--)&lt;/b&gt; &lt;/span&gt;인지 확인해보자!&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://shary1012.tistory.com/231&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://shary1012.tistory.com/231&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1678234733708&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[linux] vimrc 설정 (vim install 부터 colorscheme 다운로드 받아서 적용하기)&quot; data-og-description=&quot;1. 설치 및 기본 적용 vimrc를 적용하기 위해서는 'xxx.vim' 파일을 특정 폴더(/usr/share/vim/vim00)에 넣고 colorscheme를 적용하면 되는데, 리눅스를 처음 설치했을 때에는 '/usr/share/vim' 디렉토리가 생성되어&quot; data-og-host=&quot;shary1012.tistory.com&quot; data-og-source-url=&quot;https://shary1012.tistory.com/231&quot; data-og-url=&quot;https://shary1012.tistory.com/231&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/3BEA2/hyRRCsFfbk/1WJ2B5Eat8HlCa9roixwBk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/cDmrqW/hyRRMPw8Ee/Cqx8JCL5RgiwxGmt0QMZq1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/cIx34d/hyRRCe7HjN/RJKnadktdY08npsUif7B1K/img.jpg?width=720&amp;amp;height=961&amp;amp;face=0_0_720_961&quot;&gt;&lt;a href=&quot;https://shary1012.tistory.com/231&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://shary1012.tistory.com/231&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/3BEA2/hyRRCsFfbk/1WJ2B5Eat8HlCa9roixwBk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/cDmrqW/hyRRMPw8Ee/Cqx8JCL5RgiwxGmt0QMZq1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/cIx34d/hyRRCe7HjN/RJKnadktdY08npsUif7B1K/img.jpg?width=720&amp;amp;height=961&amp;amp;face=0_0_720_961');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[linux] vimrc 설정 (vim install 부터 colorscheme 다운로드 받아서 적용하기)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;1. 설치 및 기본 적용 vimrc를 적용하기 위해서는 'xxx.vim' 파일을 특정 폴더(/usr/share/vim/vim00)에 넣고 colorscheme를 적용하면 되는데, 리눅스를 처음 설치했을 때에는 '/usr/share/vim' 디렉토리가 생성되어&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;shary1012.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>OS/Linux</category>
      <category>vim 색깔</category>
      <category>vim 설정</category>
      <category>vim 설치</category>
      <category>vim 테마 설정</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/132</guid>
      <comments>https://co-no.tistory.com/entry/LinuxCentOS-7-vi-vim-%ED%85%8C%EB%A7%88-%EC%84%A4%EC%A0%95#entry132comment</comments>
      <pubDate>Wed, 8 Mar 2023 11:47:33 +0900</pubDate>
    </item>
    <item>
      <title>[Linux] CentOS 7 에서 User 생성(useradd)과 User 홈 디렉토리 설정</title>
      <link>https://co-no.tistory.com/entry/Linux-CentOS7-%EC%97%90%EC%84%9C-User-%EC%83%9D%EC%84%B1useradd%EA%B3%BC-User-%ED%99%88-%EB%94%94%EB%A0%89%ED%86%A0%EB%A6%AC-%EC%84%A4%EC%A0%95</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;우선 아래 command 들은 모두 root 권한과 동일한 유저로 진행했음을 먼저 일러둔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;User &lt;span style=&quot;color: #006dd7;&quot;&gt;생성&lt;/span&gt; 명령어&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1677561588289&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ useradd [OPTIONS] USERNAME&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;주요 옵션)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;-p&lt;/b&gt; : 사용자의 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;암호(Password)&lt;/b&gt;&lt;/span&gt; 추가&lt;/li&gt;
&lt;li&gt;&lt;b&gt;-d&lt;/b&gt; : &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;홈 디렉토리&lt;/b&gt;&lt;/span&gt; 지정&lt;br /&gt;* 최종 디렉토리만 생성하므로, 중간 경로가 존재하지 않는 경우 미리 생성해두어야 한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;-g&lt;/b&gt; : &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;기본&lt;/b&gt;&lt;b&gt;그룹&lt;/b&gt;&lt;/span&gt;을 지정할 때 사용&lt;br /&gt;* 지정할 그룹이 미리 생성되어 있어야 함.&lt;br /&gt;* 이 옵션을 넣지 않을 경우, default로 &lt;u&gt;USERNAME 과 동일한 그룹에 포함됨. (Redhat 계열)&lt;/u&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;-G&lt;/b&gt; : 기본 그룹 외의 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;추가로 그룹에 속하게&lt;/b&gt;&lt;/span&gt; 할 경우 (--groups)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;-c&lt;/b&gt; : 사용자에 대한 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;설명(Caption)&lt;/b&gt;&lt;/span&gt;을 설정&lt;/li&gt;
&lt;li&gt;&lt;b&gt;-s&lt;/b&gt; : 사용자가 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;사용할 쉘(Shell)&lt;/b&gt;&lt;/span&gt;을 지정할 때 사용&lt;/li&gt;
&lt;li&gt;&lt;b&gt;-D&lt;/b&gt; :&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt; /etc/default/useradd&lt;/b&gt;&lt;/span&gt; 에 설정된 유저 추가와 관련된 기본 사항들을 보여줌&lt;/li&gt;
&lt;li&gt;&lt;b&gt;-m&lt;/b&gt; : 사용자를 생성할 때, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;홈 디렉토리를 생성&lt;/b&gt;&lt;/span&gt;해주는 옵션&lt;br /&gt;* &lt;u&gt;Redhat 계열에서는 이 옵션을 사용하지 않아도 홈 디렉토리가 USERNAME에 맞춰 알아서 생성됨&lt;/u&gt;&lt;br /&gt;* 보통 -k 옵션과 함께 사용하여 사용자 생성시 기본적으로 부여되는 목록이 들어있는 skeldir 을 지정할 때 사용&lt;/li&gt;
&lt;li&gt;&lt;b&gt;-k&lt;/b&gt; : 사용자 생성 시 제공되는 환경 파일들은 기본적으로 &lt;b&gt;/etc/skel 로 지정되는데, 이외의 디렉토리를 지정할 때&lt;/b&gt; 사용&lt;/li&gt;
&lt;li&gt;&lt;b&gt;-f&lt;/b&gt; : 사용자의 &lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;패스워드 만기일&lt;/span&gt;을 날짜수로&lt;/b&gt; 지정할 때 사용&lt;/li&gt;
&lt;li&gt;&lt;b&gt;-e&lt;/b&gt; : 계정의 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;만기일(Expiration)&lt;/b&gt;&lt;/span&gt;을&lt;b&gt; YYYY-MM-DD 형식&lt;/b&gt;으로 지정하여 사용&lt;/li&gt;
&lt;li&gt;&lt;b&gt;-u&lt;/b&gt; : 사용자 추가 시,&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt; UID 값&lt;/b&gt;&lt;/span&gt; 지정&lt;/li&gt;
&lt;li&gt;&lt;b&gt;-r&lt;/b&gt; : &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;시스템 계정 추가 시&lt;/b&gt;&lt;/span&gt; 사용. &lt;b&gt;/etc/login.defs&lt;/b&gt; 파일에서 정의된 &lt;b&gt;UID_MIN&lt;/b&gt; 값보다 작은 UID 값을, &lt;b&gt;GID_MIN&lt;/b&gt; 값보다 작은 GID를 자동으로 선택하여 추가하게 됨.&lt;b&gt; '-u UID' 및 '-g GID'&lt;/b&gt; 와 같이 직접 UID나 GID를 추가옵션을 사용한다면 -r 옵션은 사용되지 않음.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;-h&lt;/b&gt; : &lt;b&gt;--help&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;User &lt;span style=&quot;color: #006dd7;&quot;&gt;암호(Password)&lt;/span&gt; 설정&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1677563288198&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ passwd USERNAME&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;User 생성 &lt;span style=&quot;color: #409d00;&quot;&gt;예시&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. &lt;b&gt;'testuser1'&lt;/b&gt; 라는 사용자를 생성하면서 &lt;b&gt;홈 디렉토리&lt;/b&gt;의 경로 및 &lt;b&gt;그룹을 지정&lt;/b&gt;하는 명령어&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 홈 디렉토리 : &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;/home/tester/testuser1&lt;/b&gt;&lt;/span&gt; / 그룹 : &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;tester&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 위 디렉토리와 그룹은 모두 미리 생성되어 있는 걸로 가정&lt;/p&gt;
&lt;pre id=&quot;code_1677562059809&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ useradd testuser1 -d /home/tester/testuser1 -g tester&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. &lt;b&gt;'testuser2'&lt;/b&gt; 라는 사용자를 생성하면서 &lt;b&gt;여러 그룹으로 할당&lt;/b&gt;시키는 명령어&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 기본 그룹 : '&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;tester&lt;/b&gt;&lt;/span&gt;' / 보조 그룹 : '&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;wheel&lt;/b&gt;&lt;/span&gt;', '&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;developers&lt;/b&gt;&lt;/span&gt;'&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 위 그룹들은 모두 미리 생성되어 있는 걸로 가정&lt;/p&gt;
&lt;pre id=&quot;code_1677562680195&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ useradd -g tester -G wheel,developers testuser2&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;현재 사용자 추가시, &lt;span style=&quot;color: #006dd7;&quot;&gt;default로 지정되는 옵션&lt;/span&gt; 확인하기&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1677562787551&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ useradd -D&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1677562841619&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 내 로컬 환경에서 useradd -D 결과
# 이 설정들은 /etc/default/useradd 에서 확인 및 변경 가능
GROUP=100
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/bash
SKEL=/etc/skel
CREATE_MAIL_SPOOL=yes&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jjeongil.tistory.com/1449&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://jjeongil.tistory.com/1449&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1677560287508&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Linux : User 생성 방법, 예제, 명령어(useradd Command)&quot; data-og-description=&quot;리눅스는 다중 사용자 시스템으로, 둘 이상의 사용자가 동시에 동일한 시스템과 상호 작용할 수 있습니다. 시스템 관리자는 사용자를 생성 및 제거하고 다른 그룹에 할당하여 시스템의 사용자 &quot; data-og-host=&quot;jjeongil.tistory.com&quot; data-og-source-url=&quot;https://jjeongil.tistory.com/1449&quot; data-og-url=&quot;https://jjeongil.tistory.com/1449&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/k32B5/hyRMy4Hxvj/Xw7ofsseuPyskNhkVHYQF0/img.png?width=200&amp;amp;height=200&amp;amp;face=0_0_200_200,https://scrap.kakaocdn.net/dn/uQlTZ/hyRMljYK6l/zwNQIGrW89zjcVn8tBnJc0/img.png?width=200&amp;amp;height=200&amp;amp;face=0_0_200_200,https://scrap.kakaocdn.net/dn/ndLon/hyRMzJjYqh/jgdxT5CffToup5BooRztL0/img.png?width=200&amp;amp;height=200&amp;amp;face=0_0_200_200&quot;&gt;&lt;a href=&quot;https://jjeongil.tistory.com/1449&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jjeongil.tistory.com/1449&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/k32B5/hyRMy4Hxvj/Xw7ofsseuPyskNhkVHYQF0/img.png?width=200&amp;amp;height=200&amp;amp;face=0_0_200_200,https://scrap.kakaocdn.net/dn/uQlTZ/hyRMljYK6l/zwNQIGrW89zjcVn8tBnJc0/img.png?width=200&amp;amp;height=200&amp;amp;face=0_0_200_200,https://scrap.kakaocdn.net/dn/ndLon/hyRMzJjYqh/jgdxT5CffToup5BooRztL0/img.png?width=200&amp;amp;height=200&amp;amp;face=0_0_200_200');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Linux : User 생성 방법, 예제, 명령어(useradd Command)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;리눅스는 다중 사용자 시스템으로, 둘 이상의 사용자가 동시에 동일한 시스템과 상호 작용할 수 있습니다. 시스템 관리자는 사용자를 생성 및 제거하고 다른 그룹에 할당하여 시스템의 사용자&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;jjeongil.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://starrykss.tistory.com/1631&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://starrykss.tistory.com/1631&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1677560362261&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[리눅스 명령어] useradd / useradd -D&quot; data-og-description=&quot;useradd / useradd -D useradd 사용자의 ID를 생성하는 명령 사용법 useradd [option] [사용자 계정 이름] 주요 옵션 옵션 설명 -p 사용자의 암호(Password)를 추가할 때 사용 -d - 홈 디렉터리(Directory)를 지정할 때 &quot; data-og-host=&quot;starrykss.tistory.com&quot; data-og-source-url=&quot;https://starrykss.tistory.com/1631&quot; data-og-url=&quot;https://starrykss.tistory.com/1631&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/K09Xc/hyRMjT2x43/UsTXxkDOkouQe2xZPNxLUk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/cgJk4V/hyRMyczsrR/xHxtoMKtyzOKf6AzgalJA1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://starrykss.tistory.com/1631&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://starrykss.tistory.com/1631&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/K09Xc/hyRMjT2x43/UsTXxkDOkouQe2xZPNxLUk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/cgJk4V/hyRMyczsrR/xHxtoMKtyzOKf6AzgalJA1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[리눅스 명령어] useradd / useradd -D&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;useradd / useradd -D useradd 사용자의 ID를 생성하는 명령 사용법 useradd [option] [사용자 계정 이름] 주요 옵션 옵션 설명 -p 사용자의 암호(Password)를 추가할 때 사용 -d - 홈 디렉터리(Directory)를 지정할 때&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;starrykss.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>OS/Linux</category>
      <category>linux user</category>
      <category>linux useradd</category>
      <category>Linux 유저 홈 디렉토리</category>
      <category>Redhat useradd -D</category>
      <category>리눅스 유저 생성</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/129</guid>
      <comments>https://co-no.tistory.com/entry/Linux-CentOS7-%EC%97%90%EC%84%9C-User-%EC%83%9D%EC%84%B1useradd%EA%B3%BC-User-%ED%99%88-%EB%94%94%EB%A0%89%ED%86%A0%EB%A6%AC-%EC%84%A4%EC%A0%95#entry129comment</comments>
      <pubDate>Tue, 28 Feb 2023 14:46:38 +0900</pubDate>
    </item>
    <item>
      <title>[MongoDB] CentOS 7 에 MongoDB 설치 및 샤드 클러스터 구성하기</title>
      <link>https://co-no.tistory.com/entry/MongoDB-CentOS-7-%EC%97%90-MongoDB-%EC%84%A4%EC%B9%98-%EB%B0%8F-%EC%83%A4%EB%93%9C-%ED%81%B4%EB%9F%AC%EC%8A%A4%ED%84%B0-%EA%B5%AC%EC%84%B1%ED%95%98%EA%B8%B0</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;0. 서버 구성&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1813&quot; data-origin-height=&quot;1058&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OAhSp/btr1fORrHzU/GG6B2ocO0OtYPENIupFykk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OAhSp/btr1fORrHzU/GG6B2ocO0OtYPENIupFykk/img.png&quot; data-alt=&quot;이 포스팅에서의 MongoDB 구조&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OAhSp/btr1fORrHzU/GG6B2ocO0OtYPENIupFykk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOAhSp%2Fbtr1fORrHzU%2FGG6B2ocO0OtYPENIupFykk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;705&quot; height=&quot;411&quot; data-origin-width=&quot;1813&quot; data-origin-height=&quot;1058&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이 포스팅에서의 MongoDB 구조&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보다시피,&lt;u&gt; Config 서버, Router 서버, 샤딩 서버가 모두 한 물리적 서버(VM Machine)에 존재&lt;/u&gt;하기 때문에, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;사실상 HA(High Availability) 기능은 없다고 봐야&lt;/b&gt;&lt;/span&gt; 한다. &lt;u&gt;J_Mongo 1번서버가 Down되면 MongoDB 시스템 전체가 Down&lt;/u&gt; 되기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정석적으로 하려면 최소 &lt;b&gt;Config 서버 3대&lt;/b&gt;(Primary-Secondary-Secondary 또는 Arbiter) / &lt;b&gt;Router 서버 2대&lt;/b&gt;(1대는 스페어이자, request 자체의 분산 목적) / &lt;b&gt;Sharding 서버 2대&lt;/b&gt;(데이터 분산 목적)&lt;b&gt;*3&lt;/b&gt; (Priamry-Secondary-Secondary 또는 Arbiter 구성의 Replica Set) 으로 &lt;b&gt;총 11대&lt;/b&gt;가 필요하다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 데이터의 변경이 잦아 샤드 클러스터를 추가한다고 하면, 필요한 서버의 대수가 기하급수적으로 증가하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 포스팅에서는 샤딩이 어떻게 되는지, 레플리카셋에서 쿼리 분산이나 Fail-Over가 어떻게 진행되는지 '살펴보기' 위한 목적이므로, 3대의 서버(VM Machine)으로만 진행하기로 하자...!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1. MongoDB 설치&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서는 MongoDB 5.0 버전을 기준으로 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 아래와 같이 /etc/yum.repos.d/ 아래에 'mongodb-org-5.0.repo' 라고 이름 지어(이름은 사실 자유) yum 레포를 설정해준다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1677508035011&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[mongodb-org-5.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/5.0/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-5.0.asc&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 다음 명령어로 mongodb 를 설치한다.&lt;/p&gt;
&lt;pre id=&quot;code_1677508101100&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# yum install -y mongodb-org&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2. MongoDB의 &lt;span style=&quot;color: #006dd7;&quot;&gt;DATA&lt;/span&gt;, &lt;span style=&quot;color: #006dd7;&quot;&gt;config&lt;/span&gt;, &lt;span style=&quot;color: #006dd7;&quot;&gt;log&lt;/span&gt; 디렉토리 생성&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디렉토리 역시 관리하기 편한대로 구성하면 되나, 기본적으로 data가 들어가는 디렉토리, mongodb 를 실행할 때 불러올 conf 파일이 있는 디렉토리, 로그가 쌓이는 디렉토리는 따로 분리하는 것이 관리하기에 편할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내 디렉토리 구조는 아래와 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;837&quot; data-origin-height=&quot;236&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/chaLWw/btr0NNtvtzW/iKqNLnvpRCR4fdHuMHIZE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/chaLWw/btr0NNtvtzW/iKqNLnvpRCR4fdHuMHIZE0/img.png&quot; data-alt=&quot;내가 설치한 mongodb 디렉토리 구조&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/chaLWw/btr0NNtvtzW/iKqNLnvpRCR4fdHuMHIZE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FchaLWw%2Fbtr0NNtvtzW%2FiKqNLnvpRCR4fdHuMHIZE0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;528&quot; height=&quot;149&quot; data-origin-width=&quot;837&quot; data-origin-height=&quot;236&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;내가 설치한 mongodb 디렉토리 구조&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1677508675999&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 1번 서버 - Config 서버, Router 서버, 샤드 서버(Primary) 3개로 구성 예정
mkdir /home/mongodb/config
mkdir /home/mongodb/DATA
mkdir /home/mongodb/DATA/conf
mkdir /home/mongodb/DATA/rs1
mkdir /home/mongodb/DATA/rs2
mkdir /home/mongodb/DATA/rs3
mkdir /home/mongodb/log


# 2번 서버 - 샤드 서버(Secondary) 3개로 구성 예정
mkdir /home/mongodb/config
mkdir /home/mongodb/DATA
mkdir /home/mongodb/DATA/rs1
mkdir /home/mongodb/DATA/rs2
mkdir /home/mongodb/DATA/rs3
mkdir /home/mongodb/log


# 3번 서버 - 샤드 서버(Secondary) 3개로 구성 예정
mkdir /home/mongodb/config
mkdir /home/mongodb/DATA
mkdir /home/mongodb/DATA/rs1
mkdir /home/mongodb/DATA/rs2
mkdir /home/mongodb/DATA/rs3
mkdir /home/mongodb/log&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3. Authorization 을 위한&lt;span style=&quot;color: #f89009;&quot;&gt; Key 파일&lt;/span&gt; 생성&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1677508827996&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 1번 서버에서 openssl로 생성하여 scp로 2번서버, 3번서버로 복사하기.
openssl rand -base64 755 &amp;gt; /home/mongodb/config/mongodb-keyfile

# 파일 권한 변경
chmod 600 /home/mongodb/config/mongodb-keyfile

# 2번, 3번 서버로 복사
scp /home/mongodb/config/mongodb-keyfile mongo@{2번서버 IP}:/home/mongodb/config/mongodb-keyfile
scp /home/mongodb/config/mongodb-keyfile mongo@{3번서버 IP}:/home/mongodb/config/mongodb-keyfile&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;4. Mongo 인스턴스를 실행할 때 불러올&lt;span style=&quot;color: #006dd7;&quot;&gt; conf 파일&lt;/span&gt; 생성&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4-1. Config 서버&amp;nbsp;&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1677544164002&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# vim /home/mongodb/config/mongod_config.conf&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1677544308073&quot; class=&quot;php&quot; data-ke-language=&quot;php&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# mongod_config.conf

# for documentation of all options, see:
#    http://docs.mongodb.org/manual/reference/configuration-options/

# 로깅 데이터 설정
systemLog:
    destination: file
    logAppend: true
    path: /home/mongodb/log/mongod_config.log

# 데이터 저장 설정
storage:
    dbPath: /home/mongodb/DATA/conf
    journal:
        enabled: true
    engine: &quot;wiredTiger&quot;

# 몽고DB 인스턴스의 프로세스 설정
processManagement:
    fork: true	# fork and run in background
    pidFilePath: /home/mongodb/log/mongod_config.pid	# location of pidfile

# 네트워크 인터페이스 설정
net:
    port: 20000
    bindIp: 0.0.0.0 	 # MongoDB 인스턴스가 실행되는 서버에서 모든 IP 주소에서 들어오는 클라이언트 연결을 수신하도록 설정하는 것
    
# 레플리케이션 설정
# Config 서버는 Config 서버끼리 같은 Replica Set 이름으로 지정
replication:
    replSetName: &quot;configRepl&quot;

# 샤딩 설정
# 샤딩 클러스터에서 이 인스턴스가 어떠한 역할을 할지 알려주는 것
sharding:
    clusterRole: configsvr
    
# Security 설정
# 이 구문은 mongodb 셋업이 끝난 후, Primary 노드에서 유저 생성을 한 이후에 넣을 것.
security:
    keyFile: /home/mongodb/config/mongodb-keyfile
    authorization: &quot;enabeld&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4-2. Shard 서버&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1677544827664&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# vim /home/mongodb/config/mongod_shard_rs1.conf

# vim /home/mongodb/config/mongod_shard_rs2.conf

# vim /home/mongodb/config/mongod_shard_rs3.conf&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1677544976867&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# mongod_shard_rs1.conf

# for documentation of all options, see:
#    http://docs.mongodb.org/manual/reference/configuration-options/

# 로깅 데이터 설정
systemLog:
    destination: file
    logAppend: true
    path: /home/mongodb/log/mongod_shard_rs1.log	# [rs1 | rs2 | rs3].log

# 데이터 저장 설정
storage:
    dbPath: /home/mongodb/DATA/rs1	# # [rs1 | rs2 | rs3]
    journal:
        enabled: true
    engine: &quot;wiredTiger&quot;

# 몽고DB 인스턴스의 프로세스 설정
processManagement:
    fork: true	# fork and run in background
    pidFilePath: /home/mongodb/log/mongod_shard_rs1.pid	# location of pidfile / [rs1 | rs2 | rs3].pid

# 네트워크 인터페이스 설정
net:
    port: 30001	# 동일한 레플리카셋으로 넣는다면 포트도 동일하게 설정 [30001 | 30002 | 30003]
    bindIp: 0.0.0.0 	 # MongoDB 인스턴스가 실행되는 서버에서 모든 IP 주소에서 들어오는 클라이언트 연결을 수신하도록 설정하는 것
    
# 레플리케이션 설정
# Sharding 서버는 Port 넘버 기준으로 같은 노드끼리 같은 Replica Set 이름으로 지정
# Secondary 노드에서도 동일하게 설정한 후, Primary 노드에서 rs.initiate()로 Secondary 노드를 추가하면 자동으로 Secondary 노드에 데이터 동기화 됨.
replication:
    replSetName: &quot;rs1&quot;	# [rs1 | rs2 | rs3]

# 샤딩 설정
# 샤딩 클러스터에서 이 인스턴스가 어떠한 역할을 할지 알려주는 것
sharding:
    clusterRole: shardsvr
    
# Security 설정
# 이 구문은 mongodb 셋업이 끝난 후, Primary 노드에서 유저 생성을 한 이후에 넣을 것.
security:
    keyFile: /home/mongodb/config/mongodb-keyfile
    authorization: &quot;enabeld&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4-3. Router 서버&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1677545371997&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# vim /home/mongodb/config/mongos_config.conf&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1677545401387&quot; class=&quot;php&quot; data-ke-language=&quot;php&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# mongos_config.conf

# for documentation of all options, see:
#    http://docs.mongodb.org/manual/reference/configuration-options/

# 로깅 데이터 설정
systemLog:
    destination: file
    logAppend: true
    path: /home/mongodb/log/mongos.log

# 몽고DB 인스턴스의 프로세스 설정
processManagement:
    fork: true	# fork and run in background
    pidFilePath: /home/mongodb/log/mongos.pid	# location of pidfile

# 네트워크 인터페이스 설정
net:
    port: 20001	
    bindIp: 0.0.0.0 	 # MongoDB 인스턴스가 실행되는 서버에서 모든 IP 주소에서 들어오는 클라이언트 연결을 수신하도록 설정하는 것
    
    
# 샤딩 설정
# Router 서버에서는 샤드 클러스터의 config 서버를 바라보도록 설정해야 한다.
sharding:
    configDB: configRepl/10.0.2.16:20000
    
    
# Security 설정
# 이 구문은 mongodb 셋업이 끝난 후, Primary 노드에서 유저 생성을 한 이후에 넣을 것.
security:
    keyFile: /home/mongodb/config/mongodb-keyfile&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;5. Mongo 인스턴스 실행 및 초기 설정&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;5-1. Config 서버&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;5-1-a. Config 서버 인스턴스 실행&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1677545977022&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ mongod --config /home/mongodb/config/mongod_config.conf&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;5-1-b. Config 서버 Replica Set 설정&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1677546117709&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# config 서버 접속
$ mongo 10.0.2.16:20000

# config 서버 shell에서
&amp;gt; rs.initiate({
    _id: &quot;configRepl&quot;,
    members: [
        { _id: 0, host: &quot;10.0.2.16:20000&quot; }
    ]
})&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;5-1-c. Config 서버 계정 생성&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1677546518617&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;gt; use admin
&amp;gt; db.createUser({user: &quot;root&quot;, pwd: &quot;블라블라~&quot;, roles: [&quot;root&quot;]})
# 서버의 모든 administration 작업을 위한 root 권한의 계정 생성

&amp;gt; use testdb
&amp;gt; db.createUser({user: &quot;testuser&quot;, pwd: &quot;블라블라~&quot;, roles: [{role: &quot;readWrite&quot;, db: &quot;testdb&quot;}]})
# 'testdb' 라는 데이터베이스만 사용할 수 있도록 하는 테스트 계정 생성&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;5-2. Shard 서버&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;5-2-a. Shard 서버 인스턴스 실행&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1677546767401&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ mongod --config /home/mongodb/config/mongod_shard_rs1.conf
$ mongod --config /home/mongodb/config/mongod_shard_rs2.conf
$ mongod --config /home/mongodb/config/mongod_shard_rs3.conf&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;5-2-b. Shard 서버 Replica Set 설정&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1677546860611&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# shard 서버 접속
$ mongo 10.0.2.16:30001 ~ 30003

# shard 서버 shell에서
&amp;gt; rs.initiate({
    _id: &quot;rs1&quot;,
    members: [
        { _id: 0, host: &quot;10.0.2.16:30001&quot; }
        { _id: 1, host: &quot;10.0.2.17:30001&quot; }
        { _id: 2, host: &quot;10.0.2.18:30001&quot; }
    ]
})
&amp;gt; rs.status()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;5-2-c. Shard 서버 계정 생성&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1677547100555&quot; class=&quot;reasonml&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;gt; use admin
&amp;gt; db.createUser({user: &quot;root&quot;, pwd: &quot;블라블라~&quot;, roles: [&quot;root&quot;]})
# 서버의 모든 administration 작업을 위한 root 권한의 계정 생성

&amp;gt; use testdb
&amp;gt; db.createUser({user: &quot;testuser&quot;, pwd: &quot;블라블라~&quot;, roles: [{role: &quot;readWrite&quot;, db: &quot;testdb&quot;}]})
# 'testdb' 라는 데이터베이스만 사용할 수 있도록 하는 테스트 계정 생성&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;5-3. Router 서버&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;5-3-a. Router 서버 인스턴스 실행&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1677547168170&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ mongos --config /home/mongodb/config/mongos_config.conf&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;5-3-b. Router 서버 Shard Set 설정&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1677547227621&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# mongos 서버 접속
$ mongo 10.0.2.16:20001

# Router 서버 shell에서
&amp;gt; sh.addShard(&quot;rs1/10.0.2.16:30001&quot;)
&amp;gt; sh.addShard(&quot;rs2/10.0.2.16:30002&quot;)
&amp;gt; sh.addShard(&quot;rs3/10.0.2.16:30003&quot;)
&amp;gt; sh.status()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;5-3-c. Router 서버 계정 생성&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1677547470721&quot; class=&quot;reasonml&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;gt; use admin
&amp;gt; db.createUser({user: &quot;root&quot;, pwd: &quot;블라블라~&quot;, roles: [&quot;root&quot;]})
# 서버의 모든 administration 작업을 위한 root 권한의 계정 생성

&amp;gt; use testdb
&amp;gt; db.createUser({user: &quot;testuser&quot;, pwd: &quot;블라블라~&quot;, roles: [{role: &quot;readWrite&quot;, db: &quot;testdb&quot;}]})
# 'testdb' 라는 데이터베이스만 사용할 수 있도록 하는 테스트 계정 생성&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;6. 샤딩 테스트&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터가 분산되어 잘 저장되는지 확인해보자!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;6.1. 테스트 DB 생성 및 샤딩 선언, 데이터 생성&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1677547794290&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Router 서버 접속
$ mongo 10.0.2.16:20001

# 데이터베이스 생성 및 collection 인덱스 생성
&amp;gt; use testdb
&amp;gt; db.test.createIndex({&quot;index&quot;: 1})

# shard를 할 것이라고 배포
&amp;gt; sh.enableSharding(&quot;testdb&quot;)
&amp;gt; sh.shardCollection(&quot;testdb.test&quot;, {index: &quot;hashed&quot;})

# 테스트용 데이터 1000개 document 생성
&amp;gt; for (var n=1; n&amp;lt;=1000; n++) {
    db.test.insert({index: n, value: &quot;test&quot;})
}

# 'test' 컬렉션의 document 수 확인
&amp;gt; db.test.count()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;791&quot; data-origin-height=&quot;165&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/N3QhA/btr0RKi8Lh6/ylidvZnqfH8IT0QzxKIo91/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/N3QhA/btr0RKi8Lh6/ylidvZnqfH8IT0QzxKIo91/img.png&quot; data-alt=&quot;Router 서버에서의 db.test.count() 결과 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/N3QhA/btr0RKi8Lh6/ylidvZnqfH8IT0QzxKIo91/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FN3QhA%2Fbtr0RKi8Lh6%2FylidvZnqfH8IT0QzxKIo91%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;522&quot; height=&quot;109&quot; data-origin-width=&quot;791&quot; data-origin-height=&quot;165&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Router 서버에서의 db.test.count() 결과 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;6.2. 각 샤드 서버(rs1, rs2, rs3) 에 데이터가 골고루 분산되어 저장되었는지 확인&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1677548169852&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 샤드 노드 1번 접속 및 document 개수 확인
$ mongod 10.0.2.16:30001

&amp;gt; use testdb
&amp;gt; db.getCollecion(&quot;test&quot;).find({}).count()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;920&quot; data-origin-height=&quot;75&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HSWpT/btr0NIMGUQ9/yXwgfbh2Gm4kIYJf7SIjLK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HSWpT/btr0NIMGUQ9/yXwgfbh2Gm4kIYJf7SIjLK/img.png&quot; data-alt=&quot;샤드 1번 노드에서의 db.getCollection(&amp;quot;test&amp;quot;).find({}).count() 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HSWpT/btr0NIMGUQ9/yXwgfbh2Gm4kIYJf7SIjLK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHSWpT%2Fbtr0NIMGUQ9%2FyXwgfbh2Gm4kIYJf7SIjLK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;553&quot; height=&quot;45&quot; data-origin-width=&quot;920&quot; data-origin-height=&quot;75&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;샤드 1번 노드에서의 db.getCollection(&quot;test&quot;).find({}).count() 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1677552764819&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 샤드 노드 2번 접속 및 document 개수 확인
$ mongod 10.0.2.16:30002

&amp;gt; use testdb
&amp;gt; db.getCollecion(&quot;test&quot;).find({}).count()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1178&quot; data-origin-height=&quot;102&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwTam0/btr0KF3KSIv/rItCrjKub07ZX77lSCAKn0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwTam0/btr0KF3KSIv/rItCrjKub07ZX77lSCAKn0/img.png&quot; data-alt=&quot;샤드 2번 노드에서의 db.getCollection(&amp;quot;test&amp;quot;).find({}).count() 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwTam0/btr0KF3KSIv/rItCrjKub07ZX77lSCAKn0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwTam0%2Fbtr0KF3KSIv%2FrItCrjKub07ZX77lSCAKn0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;569&quot; height=&quot;49&quot; data-origin-width=&quot;1178&quot; data-origin-height=&quot;102&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;샤드 2번 노드에서의 db.getCollection(&quot;test&quot;).find({}).count() 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1677552796120&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 샤드 노드 3번 접속 및 document 개수 확인
$ mongod 10.0.2.16:30003

&amp;gt; use testdb
&amp;gt; db.getCollecion(&quot;test&quot;).find({}).count()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1174&quot; data-origin-height=&quot;101&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/co085n/btr1ddc2yZj/QuJkk67Hl8bhkJKdPk5wB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/co085n/btr1ddc2yZj/QuJkk67Hl8bhkJKdPk5wB0/img.png&quot; data-alt=&quot;샤드 3번 노드에서의 db.getCollection(&amp;quot;test&amp;quot;).find({}).count() 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/co085n/btr1ddc2yZj/QuJkk67Hl8bhkJKdPk5wB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fco085n%2Fbtr1ddc2yZj%2FQuJkk67Hl8bhkJKdPk5wB0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;570&quot; height=&quot;49&quot; data-origin-width=&quot;1174&quot; data-origin-height=&quot;101&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;샤드 3번 노드에서의 db.getCollection(&quot;test&quot;).find({}).count() 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;310 + 346 + 344 = 1000 으로, 정상적으로 document 들이 분산되어 저장되 것을 확인할 수 있다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 이 포스트의 구성에서는, 샤딩할 경우 데이터가 어떻게 분산되는지만 확인할 것이었기에 한 개의 VM Machine 에 3개의 샤드 서버 인스턴스를 모두 몰아 넣었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 샤딩 환경에서는 각 샤드 서버가 서로 다른 각각의 물리적 서버에 있을 것이므로, 방화벽 등의 설정을 통하여 기본 통신이 원활하게 되는지 반드시 확인하는 작업이 필요하다!&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer-ljo.tistory.com/36&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://developer-ljo.tistory.com/36&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1677466694698&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;centos mongodb 설치 및 샤딩&quot; data-og-description=&quot;0. 서버 구성 - 서버2대 - 서버 1 : mongos,config,shard1~3 - 서버 2 : shard1~3 1. mongodb 설치 # mongodb repository 등록 vi /etc/yum.repos.d/mongodb-org-3.4.repo [mongodb-org-3.4] name=MongoDB Repository baseurl=https://repo.mongodb.org/yum/re&quot; data-og-host=&quot;developer-ljo.tistory.com&quot; data-og-source-url=&quot;https://developer-ljo.tistory.com/36&quot; data-og-url=&quot;https://developer-ljo.tistory.com/36&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bC7DKV/hyRKKEFCtD/s3LJakolRON1kiLErmJoW1/img.jpg?width=506&amp;amp;height=428&amp;amp;face=0_0_506_428,https://scrap.kakaocdn.net/dn/8Y2r3/hyRMtnL4jJ/YjHdsZ627PRiEiBM0BY8qK/img.jpg?width=506&amp;amp;height=428&amp;amp;face=0_0_506_428,https://scrap.kakaocdn.net/dn/P1GEO/hyRMybyjfF/rZGTYnwpadUBwJkrqNiFj0/img.jpg?width=506&amp;amp;height=428&amp;amp;face=0_0_506_428&quot;&gt;&lt;a href=&quot;https://developer-ljo.tistory.com/36&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer-ljo.tistory.com/36&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bC7DKV/hyRKKEFCtD/s3LJakolRON1kiLErmJoW1/img.jpg?width=506&amp;amp;height=428&amp;amp;face=0_0_506_428,https://scrap.kakaocdn.net/dn/8Y2r3/hyRMtnL4jJ/YjHdsZ627PRiEiBM0BY8qK/img.jpg?width=506&amp;amp;height=428&amp;amp;face=0_0_506_428,https://scrap.kakaocdn.net/dn/P1GEO/hyRMybyjfF/rZGTYnwpadUBwJkrqNiFj0/img.jpg?width=506&amp;amp;height=428&amp;amp;face=0_0_506_428');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;centos mongodb 설치 및 샤딩&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;0. 서버 구성 - 서버2대 - 서버 1 : mongos,config,shard1~3 - 서버 2 : shard1~3 1. mongodb 설치 # mongodb repository 등록 vi /etc/yum.repos.d/mongodb-org-3.4.repo [mongodb-org-3.4] name=MongoDB Repository baseurl=https://repo.mongodb.org/yum/re&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer-ljo.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://urame.tistory.com/entry/%EB%AA%BD%EA%B3%A0%EB%94%94%EB%B9%84mongodb-%EC%83%A4%EB%93%9Cshard-%EC%84%A4%EC%A0%95&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://urame.tistory.com/entry/%EB%AA%BD%EA%B3%A0%EB%94%94%EB%B9%84mongodb-%EC%83%A4%EB%93%9Cshard-%EC%84%A4%EC%A0%95&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1677548292314&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;몽고디비(mongodb) 샤드(shard) 설정&quot; data-og-description=&quot;금일은 몽고디비 샤드에 대해 알아보겠다. 금일 몽고디비 구성도는 아래와 같다. 2번정도 쭉 따라서 확인차 만들어 보았다. 큰 문제 없이 구성이 된다. 단, 위 그림에서 회색으로 표현된 부분은 &quot; data-og-host=&quot;urame.tistory.com&quot; data-og-source-url=&quot;https://urame.tistory.com/entry/%EB%AA%BD%EA%B3%A0%EB%94%94%EB%B9%84mongodb-%EC%83%A4%EB%93%9Cshard-%EC%84%A4%EC%A0%95&quot; data-og-url=&quot;https://urame.tistory.com/entry/%EB%AA%BD%EA%B3%A0%EB%94%94%EB%B9%84mongodb-%EC%83%A4%EB%93%9Cshard-%EC%84%A4%EC%A0%95&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/Ap4et/hyRMsXq8Mz/VAEUSj4klSTzpofplTLhGk/img.png?width=800&amp;amp;height=620&amp;amp;face=0_0_800_620,https://scrap.kakaocdn.net/dn/Xh8uj/hyRMxRZ1rr/NVTlmFCS4UxmsmN0oiGB41/img.png?width=800&amp;amp;height=620&amp;amp;face=0_0_800_620,https://scrap.kakaocdn.net/dn/jPwb2/hyRMqFjc2O/PWV93FjOvlBVUCRXM7DDp1/img.png?width=865&amp;amp;height=718&amp;amp;face=0_0_865_718&quot;&gt;&lt;a href=&quot;https://urame.tistory.com/entry/%EB%AA%BD%EA%B3%A0%EB%94%94%EB%B9%84mongodb-%EC%83%A4%EB%93%9Cshard-%EC%84%A4%EC%A0%95&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://urame.tistory.com/entry/%EB%AA%BD%EA%B3%A0%EB%94%94%EB%B9%84mongodb-%EC%83%A4%EB%93%9Cshard-%EC%84%A4%EC%A0%95&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/Ap4et/hyRMsXq8Mz/VAEUSj4klSTzpofplTLhGk/img.png?width=800&amp;amp;height=620&amp;amp;face=0_0_800_620,https://scrap.kakaocdn.net/dn/Xh8uj/hyRMxRZ1rr/NVTlmFCS4UxmsmN0oiGB41/img.png?width=800&amp;amp;height=620&amp;amp;face=0_0_800_620,https://scrap.kakaocdn.net/dn/jPwb2/hyRMqFjc2O/PWV93FjOvlBVUCRXM7DDp1/img.png?width=865&amp;amp;height=718&amp;amp;face=0_0_865_718');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;몽고디비(mongodb) 샤드(shard) 설정&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;금일은 몽고디비 샤드에 대해 알아보겠다. 금일 몽고디비 구성도는 아래와 같다. 2번정도 쭉 따라서 확인차 만들어 보았다. 큰 문제 없이 구성이 된다. 단, 위 그림에서 회색으로 표현된 부분은&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;urame.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DB/MongoDB</category>
      <category>MongoDB Sharding</category>
      <category>MongoDB 레플리카셋</category>
      <category>MongoDB 샤드 클러스터</category>
      <category>MongoDB 샤드 클러스터 설정</category>
      <category>MongoDB 샤드 클러스터 테스트</category>
      <category>MongoDB 샤딩 실습</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/128</guid>
      <comments>https://co-no.tistory.com/entry/MongoDB-CentOS-7-%EC%97%90-MongoDB-%EC%84%A4%EC%B9%98-%EB%B0%8F-%EC%83%A4%EB%93%9C-%ED%81%B4%EB%9F%AC%EC%8A%A4%ED%84%B0-%EA%B5%AC%EC%84%B1%ED%95%98%EA%B8%B0#entry128comment</comments>
      <pubDate>Mon, 27 Feb 2023 11:58:21 +0900</pubDate>
    </item>
    <item>
      <title>[네트워크] Linux 환경에서 네트워크 관련 트러블슈팅을 위한 기본 command 가이드</title>
      <link>https://co-no.tistory.com/entry/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-Linux-%ED%99%98%EA%B2%BD%EC%97%90%EC%84%9C-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EA%B4%80%EB%A0%A8-%ED%8A%B8%EB%9F%AC%EB%B8%94%EC%8A%88%ED%8C%85%EC%9D%84-%EC%9C%84%ED%95%9C-%EA%B8%B0%EB%B3%B8-command-%EA%B0%80%EC%9D%B4%EB%93%9C</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. ping&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: 대상 호스트(hostname or IP주소)로 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;ICMP(Internet Control Message Protocol)을 보내는 명령어&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 서비스가 안된다는 말을 들었을 때, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;가장 먼저 해봐야 하는 command&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 해당 소프트웨어가 문제인지, 소프트웨어가 올라가 있는 &lt;u&gt;호스트(서버) 자체의 문제인지 판단하기 위함&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 대상 호스트 자체가 살아 있다면 ping은 나가므로, &lt;u&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;ping이 나간다고 해서 해당 소프트웨어가 정상이라고 판단하지 말 것&lt;/b&gt;&lt;/span&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1675131328630&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ ping [hostname]
또는
$ ping [IP address]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;593&quot; data-origin-height=&quot;171&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMjyh3/btrXChKJjJt/I5ZGKkG8wMScEtgh8sqpS0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMjyh3/btrXChKJjJt/I5ZGKkG8wMScEtgh8sqpS0/img.png&quot; data-alt=&quot;ping 정상 결과 출력 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMjyh3/btrXChKJjJt/I5ZGKkG8wMScEtgh8sqpS0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMjyh3%2FbtrXChKJjJt%2FI5ZGKkG8wMScEtgh8sqpS0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;593&quot; height=&quot;171&quot; data-origin-width=&quot;593&quot; data-origin-height=&quot;171&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ping 정상 결과 출력 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;162&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/B7SZM/btrXDhKfpi0/Uki8eH6lh2Qx2NpbjoUYPK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/B7SZM/btrXDhKfpi0/Uki8eH6lh2Qx2NpbjoUYPK/img.png&quot; data-alt=&quot;ping 비정상 결과 출력 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/B7SZM/btrXDhKfpi0/Uki8eH6lh2Qx2NpbjoUYPK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FB7SZM%2FbtrXDhKfpi0%2FUki8eH6lh2Qx2NpbjoUYPK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;603&quot; height=&quot;162&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;162&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ping 비정상 결과 출력 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. netstat&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: Network Statistics로, &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;TCP/IP Connection 네트워크의 통계 정보를 제공&lt;/b&gt;&lt;/span&gt;해주는 명령어&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;열려있는 포트 및 동작하고 있는 소프트웨어 정보를 함께 확인&lt;/b&gt;&lt;/span&gt;할 때 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;옵션)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- a&lt;/b&gt; : 모든 네트워크 상태 출력 [-all]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- i&lt;/b&gt; : 인터페이스별 통계값 출력 [--interface]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- n&lt;/b&gt; : IP address 및 Port 표시 ( netstat는 역dns 질의를 통해 각 IP에 매칭되는 Hostname을 얻으려 하는데, 이때 출력에 지연이 생기게 된다. 굳이 Hostname이 필요 없다면 해당 옵션을 사용하길 권장한다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- p&lt;/b&gt; : PID(프로세스 ID)와 사용중인 프로그램명 출력 [--program]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- r&lt;/b&gt; : 라우팅 테이블 출력 [--route]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- t&lt;/b&gt; : TCP 프로토콜만 출력 [--tcp]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- u&lt;/b&gt; : UDP 프로토콜만 출력 [--udp]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- l(엘)&lt;/b&gt; : 대기중인 네트워크 [--listening]&lt;/p&gt;
&lt;pre id=&quot;code_1675132854095&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ netstat -tnlp
(-&amp;gt; TCP 프로토콜만 출력, IP주소 및 포트 형식으로 표시, LISTEN 중인 녀석들만 출력, PID까지 표시)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;877&quot; data-origin-height=&quot;301&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cD1bIy/btrXCYYj8zA/e3NX1DeelPk26ccMSk023K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cD1bIy/btrXCYYj8zA/e3NX1DeelPk26ccMSk023K/img.png&quot; data-alt=&quot;netstat -tnlp 결과 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cD1bIy/btrXCYYj8zA/e3NX1DeelPk26ccMSk023K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcD1bIy%2FbtrXCYYj8zA%2Fe3NX1DeelPk26ccMSk023K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;787&quot; height=&quot;270&quot; data-origin-width=&quot;877&quot; data-origin-height=&quot;301&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;netstat -tnlp 결과 예시&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;결과 설명)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;Proto :&lt;/b&gt; 프로토콜 종류. TCP, UDP RAW 등&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Recv-Q :&lt;/b&gt; 해당 프로세스가 현재 받는 Byte 수 표기&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Send-Q :&lt;/b&gt; 해당 프로세스가 현재 보내는 Byte 수 표기&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Local Address :&lt;/b&gt; 출발지 주소 및 포트&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Foreign Address :&lt;/b&gt; 목적지 주소 및 포트&lt;/li&gt;
&lt;li&gt;&lt;b&gt;State :&lt;/b&gt; 포트의 상태&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. traceroute&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;지정된 Host까지 패킷이 전달되는 경로&lt;/b&gt;&lt;/span&gt;를 표시. IP 패킷의 TTL(Time-To-Live) 필드를 활용하여 &lt;b&gt;Destination 까지의 Traffic Path 를 알아내는데&lt;/b&gt;, 해당 방법을 정리하면 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;① TTL 1 부터 한 패킷씩 전송을 시작한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;② 패킷이 전송 중에 만료될 것이므로, Upstream Router는 ICMP Time-To-Live Exceeded 패킷을 보내면서 hop 을 식별한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;③ 위 과정을 반복하며, 다음 hop을 식별한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;④ 위와 같이 패킷 전송을 반복하여, 최종 Destination 까지 도달하는 과정 중의 라우터 리스트를 알아낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 특정 호스트에 대한 ping이 날라가지 않는 경우, traceroute를 통해 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;해당 호스트 자체에 문제가 있는지, 호스트에 도달하기까지의 경로 상에 있는 네트워크 인터페이스에 문제가 있는지 알아보는 데&lt;/b&gt;&lt;/span&gt;에 사용&lt;/p&gt;
&lt;pre id=&quot;code_1675137706628&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ traceroute [Hostname]
or
$ traceroute [IP Address]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;792&quot; data-origin-height=&quot;435&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMrmbN/btrXCIuSaV3/nrOjpqVBQ4XB4iVdDvFa10/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMrmbN/btrXCIuSaV3/nrOjpqVBQ4XB4iVdDvFa10/img.png&quot; data-alt=&quot;traceroute 출력 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMrmbN/btrXCIuSaV3/nrOjpqVBQ4XB4iVdDvFa10/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMrmbN%2FbtrXCIuSaV3%2FnrOjpqVBQ4XB4iVdDvFa10%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;475&quot; height=&quot;261&quot; data-origin-width=&quot;792&quot; data-origin-height=&quot;435&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;traceroute 출력 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;4. route&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;Host의 Routing Table을 확인 및 설정&lt;/b&gt;&lt;/span&gt;하는 유틸리티.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;* Routing Table&lt;/b&gt; : &lt;span&gt;&lt;span&gt;&amp;nbsp;Router 가 &lt;/span&gt;&lt;/span&gt;특정 서브넷에서 다른 서브넷으로 패킷을 보낼 때 네트워크 노선(?)을 변환시키는데, 이때 활용하는 정보를 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 네트워크 단의 문제를 확인할 때에는 &lt;b&gt;'route -n'&lt;/b&gt; 을 사용하여 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;IP별로 패킷이 어떤 라우터로 거쳐가는지 확인&lt;/b&gt;&lt;/span&gt;할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1675150563688&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ route -n&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;715&quot; data-origin-height=&quot;121&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uk9dk/btrXIyYTT7d/RV6rcl9zHwDam8X9XRUQtK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uk9dk/btrXIyYTT7d/RV6rcl9zHwDam8X9XRUQtK/img.png&quot; data-alt=&quot;route -n 결과 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uk9dk/btrXIyYTT7d/RV6rcl9zHwDam8X9XRUQtK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fuk9dk%2FbtrXIyYTT7d%2FRV6rcl9zHwDam8X9XRUQtK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;715&quot; height=&quot;121&quot; data-origin-width=&quot;715&quot; data-origin-height=&quot;121&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;route -n 결과 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;결과 설명)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같은 규칙을 따라 라우팅 테이블을 해석한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;① 컴퓨터는 위의 첫번째 행부터 다음 행으로 차례대로 한 행씩 읽어가며 처리할 패킷을 보낼 수 있는지 확인하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;② default(0.0.0.0) 라는 것은 이 Host의 기본 게이트웨이 설정을 의미하며, 이 행의 Gateway 값이 기본 게이트웨이의 IP 주소를 나타낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;③ 보낼 데이터의 목적지 IP 주소와 Genmask 값과의 AND 연산을 하여 그 결과가 해당 행의 Destination 항목과 동일할 경우, 해당 행의 Iface에 있는 인터페이스로 해당 패킷을 전송한다. 해당 행의 Destination 항목과 다르다면 다음 행으로 이동한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;④ Iface 의 값이 'lo'로 되어 있는 것은, 이 Host의 루프백 데이터를 처리하기 위한 설정이다. 즉, 자기 자신에게 데이터를 보낼 때 처리를 담당하는 인터페이스를 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;필드 설명)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;Destination&lt;/b&gt; : 목적지 네트워크 주소&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Gateway&lt;/b&gt; : 목적지로 가기 위한 게이트웨이 주소&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Genmask&lt;/b&gt; : 목적지 네트워크의 넷마스크 주소 (패킷의 목적지 IP 주소와 Genmask 값을 'AND 연산'한 결과가 해당 패킷이 이동할 다음 목적지 IP 주소가 된다.)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Flags&lt;/b&gt; : 해당 경로에 대한 정보를 알려주는 기호&lt;br /&gt;&amp;nbsp;&lt;b&gt;- U&lt;/b&gt; : 해당 경로 유효&lt;br /&gt;&amp;nbsp;&lt;b&gt;- H&lt;/b&gt; : 해당 경로가 호스트를 향하고 있음. (Destination의 IP가 Host임을 나타냄.) 즉, 라우터를 거치지 않아도 됨.&lt;br /&gt;&lt;b&gt;&amp;nbsp;- G&lt;/b&gt; : 해당 경로가 게이트웨이를 향하고 있음. 즉, 해당 Destination 으로 가려면, 라우터를 통과해야한다는 의미.&lt;br /&gt;&lt;b&gt;&amp;nbsp;- I&lt;/b&gt; : 해당 경로 무효&lt;/li&gt;
&lt;li&gt;Metric : 다음 라우터까지의 거리&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Ref&lt;/b&gt; : 경로를 참조한 횟수&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Use&lt;/b&gt; : 경로를 탐색한 횟수&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Iface&lt;/b&gt; : 패킷이 오가는 데 사용하게 될 네트워크 인터페이스&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;5. ss (Socket Statistics)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: 리눅스 시스템의 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;소켓 상태를 조회할 수 있는 유틸리티.&lt;/b&gt;&lt;/span&gt; netstat와 비슷한 역할을 수행하나, &lt;u&gt;최근 리눅스 배포판에서는 netstat보다는 ss 사용을 권장&lt;/u&gt;하고 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;옵션)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- a&lt;/b&gt; : 모든 소켓을 표시 [--all]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- l&lt;/b&gt; : 접속 대기 상태 소켓만 표시 [--listening]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- n&lt;/b&gt; : 호스트 DNS명이 아닌 IP Address 형태로 표시 [--numeric]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- t : TCP 소켓만 표시 [--tcp]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- u&lt;/b&gt; : UDP 소켓만 표시 [--udp]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- x&lt;/b&gt; : UNIX 도메인 소켓을 표시 [--unix]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- p&lt;/b&gt; : 포로세스명을 표시 [--process]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- s&lt;/b&gt; : 각 프로토콜의 통계 정보를 표시 [--summary]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1676338591318&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ ss&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;902&quot; data-origin-height=&quot;77&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bY64k4/btrZchPxUXM/Th01x9Xohrt2bzhERgEaPK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bY64k4/btrZchPxUXM/Th01x9Xohrt2bzhERgEaPK/img.png&quot; data-alt=&quot;ss 결과 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bY64k4/btrZchPxUXM/Th01x9Xohrt2bzhERgEaPK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbY64k4%2FbtrZchPxUXM%2FTh01x9Xohrt2bzhERgEaPK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;902&quot; height=&quot;77&quot; data-origin-width=&quot;902&quot; data-origin-height=&quot;77&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ss 결과 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;결과 설명)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;Netid :&lt;/b&gt; 프로토콜명.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;State :&lt;/b&gt; 소켓 상태&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Recv-Q : &lt;/b&gt;수신 실패 데이터 바이트 수&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Send-Q :&lt;/b&gt; 송신 실패 데이터 바이트 수&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Local Address:Port :&lt;/b&gt;&amp;nbsp; 소켓에 연결된 경로명 또는 로컬 호스트명(IP 주소)와 포트 번호&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Peer Address:Port :&lt;/b&gt; 원격 호스트 호스트명(IP 주소)와 포트 번호&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jaemunbro.medium.com/linux-network-%EB%AC%B8%EC%A0%9C%ED%95%B4%EA%B2%B0-%EA%B0%80%EC%9D%B4%EB%93%9C-for-beginners-b167d5175ef8&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://jaemunbro.medium.com/linux-network-%EB%AC%B8%EC%A0%9C%ED%95%B4%EA%B2%B0-%EA%B0%80%EC%9D%B4%EB%93%9C-for-beginners-b167d5175ef8&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1675131146713&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[Linux] 네트워크 트러블슈팅 가이드&quot; data-og-description=&quot;늘 네트워크를 활용하고 있기는 하지만 네트워크의 개념과 설비가 방대하기 때문에 전체적으로 이해하기는 쉽지 않은 분야이다.&amp;nbsp; 네트워크 이슈가 생겼을때 대응할 수 있는 기본적인 원인 파&quot; data-og-host=&quot;jaemunbro.medium.com&quot; data-og-source-url=&quot;https://jaemunbro.medium.com/linux-network-%EB%AC%B8%EC%A0%9C%ED%95%B4%EA%B2%B0-%EA%B0%80%EC%9D%B4%EB%93%9C-for-beginners-b167d5175ef8&quot; data-og-url=&quot;https://jaemunbro.medium.com/linux-network-%EB%AC%B8%EC%A0%9C%ED%95%B4%EA%B2%B0-%EA%B0%80%EC%9D%B4%EB%93%9C-for-beginners-b167d5175ef8&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/FjKO4/hyRsoAQR5d/v58eUwH2usD8ZuoDe7eBbK/img.png?width=1200&amp;amp;height=238&amp;amp;face=0_0_1200_238&quot;&gt;&lt;a href=&quot;https://jaemunbro.medium.com/linux-network-%EB%AC%B8%EC%A0%9C%ED%95%B4%EA%B2%B0-%EA%B0%80%EC%9D%B4%EB%93%9C-for-beginners-b167d5175ef8&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jaemunbro.medium.com/linux-network-%EB%AC%B8%EC%A0%9C%ED%95%B4%EA%B2%B0-%EA%B0%80%EC%9D%B4%EB%93%9C-for-beginners-b167d5175ef8&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/FjKO4/hyRsoAQR5d/v58eUwH2usD8ZuoDe7eBbK/img.png?width=1200&amp;amp;height=238&amp;amp;face=0_0_1200_238');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[Linux] 네트워크 트러블슈팅 가이드&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;늘 네트워크를 활용하고 있기는 하지만 네트워크의 개념과 설비가 방대하기 때문에 전체적으로 이해하기는 쉽지 않은 분야이다.&amp;nbsp; 네트워크 이슈가 생겼을때 대응할 수 있는 기본적인 원인 파&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;jaemunbro.medium.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://websecurity.tistory.com/103&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://websecurity.tistory.com/103&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1675132516693&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;리눅스(Linux) netstat 명령어 사용법, 네트워크 상태 확인하기&quot; data-og-description=&quot;netstat네트워크 연결상태, 라우팅테이블, 인터페이스 상태등을 보여주는 명령어[사용법]#&amp;gt; netstat [옵션] [옵션]옵션 설명-a모든 네트워크 상태 출력 [-all]-c현재 실행 명령을 매 초마다 실행 [--continu&quot; data-og-host=&quot;websecurity.tistory.com&quot; data-og-source-url=&quot;https://websecurity.tistory.com/103&quot; data-og-url=&quot;https://websecurity.tistory.com/103&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/pwFUK/hyRskkWSPT/O6NiJzx4bBSEKKzu1sDdB0/img.jpg?width=455&amp;amp;height=303&amp;amp;face=0_0_455_303,https://scrap.kakaocdn.net/dn/dXxfnd/hyRspfvj4W/qnCk9TqoXtVO4EZM85tCU0/img.jpg?width=455&amp;amp;height=303&amp;amp;face=0_0_455_303,https://scrap.kakaocdn.net/dn/UuIB1/hyRsqlbDjh/2YekjzAsfp2OXtzgH8CksK/img.png?width=704&amp;amp;height=416&amp;amp;face=0_0_704_416&quot;&gt;&lt;a href=&quot;https://websecurity.tistory.com/103&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://websecurity.tistory.com/103&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/pwFUK/hyRskkWSPT/O6NiJzx4bBSEKKzu1sDdB0/img.jpg?width=455&amp;amp;height=303&amp;amp;face=0_0_455_303,https://scrap.kakaocdn.net/dn/dXxfnd/hyRspfvj4W/qnCk9TqoXtVO4EZM85tCU0/img.jpg?width=455&amp;amp;height=303&amp;amp;face=0_0_455_303,https://scrap.kakaocdn.net/dn/UuIB1/hyRsqlbDjh/2YekjzAsfp2OXtzgH8CksK/img.png?width=704&amp;amp;height=416&amp;amp;face=0_0_704_416');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;리눅스(Linux) netstat 명령어 사용법, 네트워크 상태 확인하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;netstat네트워크 연결상태, 라우팅테이블, 인터페이스 상태등을 보여주는 명령어[사용법]#&amp;gt; netstat [옵션] [옵션]옵션 설명-a모든 네트워크 상태 출력 [-all]-c현재 실행 명령을 매 초마다 실행 [--continu&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;websecurity.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://deadheromaybewantsomething.tistory.com/30&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://deadheromaybewantsomething.tistory.com/30&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1675151883678&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;라우팅 테이블에 대해서&quot; data-og-description=&quot;라우팅 테이블 route 혹은 netstat라는 명령어를 사용해 라우팅 테이블을 확인할 수 있다. [root@was01 ~]# route Kerenl IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 192.168.1.0 * 255.255.255.0 U 0 0 0 eth0&quot; data-og-host=&quot;deadheromaybewantsomething.tistory.com&quot; data-og-source-url=&quot;https://deadheromaybewantsomething.tistory.com/30&quot; data-og-url=&quot;https://deadheromaybewantsomething.tistory.com/30&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cm46lT/hyRsvmPn8u/eH1XB5kCx33k9ST9oQ83YK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/ceizki/hyRskr3XPt/kVhITUYX58upBdMUGo58z0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://deadheromaybewantsomething.tistory.com/30&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://deadheromaybewantsomething.tistory.com/30&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cm46lT/hyRsvmPn8u/eH1XB5kCx33k9ST9oQ83YK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/ceizki/hyRskr3XPt/kVhITUYX58upBdMUGo58z0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;라우팅 테이블에 대해서&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;라우팅 테이블 route 혹은 netstat라는 명령어를 사용해 라우팅 테이블을 확인할 수 있다. [root@was01 ~]# route Kerenl IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 192.168.1.0 * 255.255.255.0 U 0 0 0 eth0&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;deadheromaybewantsomething.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.lesstif.com/lpt/linux-socket-ss-socket-statistics-91947283.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.lesstif.com/lpt/linux-socket-ss-socket-statistics-91947283.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1675994847679&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;linux socket 상태를 조회하는 ss(socket statistics) 명령어 사용법&quot; data-og-description=&quot;&quot; data-og-host=&quot;www.lesstif.com&quot; data-og-source-url=&quot;https://www.lesstif.com/lpt/linux-socket-ss-socket-statistics-91947283.html&quot; data-og-url=&quot;https://www.lesstif.com/lpt/linux-socket-ss-socket-statistics-91947283.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.lesstif.com/lpt/linux-socket-ss-socket-statistics-91947283.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.lesstif.com/lpt/linux-socket-ss-socket-statistics-91947283.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;linux socket 상태를 조회하는 ss(socket statistics) 명령어 사용법&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.lesstif.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Network</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/123</guid>
      <comments>https://co-no.tistory.com/entry/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-Linux-%ED%99%98%EA%B2%BD%EC%97%90%EC%84%9C-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EA%B4%80%EB%A0%A8-%ED%8A%B8%EB%9F%AC%EB%B8%94%EC%8A%88%ED%8C%85%EC%9D%84-%EC%9C%84%ED%95%9C-%EA%B8%B0%EB%B3%B8-command-%EA%B0%80%EC%9D%B4%EB%93%9C#entry123comment</comments>
      <pubDate>Tue, 14 Feb 2023 10:47:56 +0900</pubDate>
    </item>
    <item>
      <title>[MSSQL] Enable 계정 및 각 계정별 발급일, PW 변경일 확인</title>
      <link>https://co-no.tistory.com/entry/MSSQL-Enable-%EA%B3%84%EC%A0%95-%EB%B0%8F-%EA%B0%81-%EA%B3%84%EC%A0%95%EB%B3%84-%EB%B0%9C%EA%B8%89%EC%9D%BC-PW-%EB%B3%80%EA%B2%BD%EC%9D%BC-%ED%99%95%EC%9D%B8</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;DB admin으로서, 각 계정이 언제 생성되었는지, PW가 언제 변경되었는지 확인해야 되는 상황이 생길 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런 상황에서 유용한 sys.server_principals(T-SQL) 을 활용하여 원하는 정보를 쿼리로 획득해보자!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 현재 SQL Server에서 활성화된 계정을 확인할 필요가 있다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. MSSQL 상에서 Enabled 되어 있는 계정 확인&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1675665485646&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT *
FROM sys.server_principals
WHERE is_disabled = 0 AND type in ('S')&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1965&quot; data-origin-height=&quot;312&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wAThe/btrYf0PTqor/5h5iGyTuxfuI7I29kIdqj1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wAThe/btrYf0PTqor/5h5iGyTuxfuI7I29kIdqj1/img.png&quot; data-alt=&quot;sys.server_principals SELECT 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wAThe/btrYf0PTqor/5h5iGyTuxfuI7I29kIdqj1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwAThe%2FbtrYf0PTqor%2F5h5iGyTuxfuI7I29kIdqj1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;898&quot; height=&quot;143&quot; data-origin-width=&quot;1965&quot; data-origin-height=&quot;312&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;sys.server_principals SELECT 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;name&lt;/b&gt; : 보안 주체의 이름. 서버 내에서 고유. (sysname 데이터타입)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;principal_id&lt;/b&gt; : 보안 주체의 ID 번호. 서버 내에서 고유. (int 데이터 타입)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;sid&lt;/b&gt; : 보안 주체의 SID(보안 ID). Windows 보안 주체의 경우 Windows SID와 일치. (varbinary(85) 데이터타입)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;type&lt;/b&gt; : 보안 주체 유형. (char(1) 데이터타입)&lt;br /&gt;- &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;S&lt;/b&gt;&lt;/span&gt; : SQL 로그인&lt;br /&gt;- &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;U&lt;/b&gt;&lt;/span&gt; : Windows 로그인&lt;br /&gt;- &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;G&lt;/b&gt;&lt;/span&gt; : Windows 그룹&lt;br /&gt;- &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;R&lt;/b&gt;&lt;/span&gt; : 서버 역할(Role)&lt;br /&gt;- &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;C&lt;/b&gt;&lt;/span&gt; : 인증서에 매핑된 로그인&lt;br /&gt;- &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;E&lt;/b&gt;&lt;/span&gt; : Azure Active Directory 에서 외부 로그인&lt;br /&gt;- &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;X&lt;/b&gt;&lt;/span&gt; : Azure Active Directory 그룹 또는 애플리케이션의 외부 그룹&lt;br /&gt;- &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;K&lt;/b&gt;&lt;/span&gt; : 비대칭 키에 매핑된 로그인&lt;/li&gt;
&lt;li&gt;&lt;b&gt;type_desc&lt;/b&gt; : 보안 주체 유형에 대한 설명. 값은 아래 중에 하나.&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;SQL_LOGIN&lt;/span&gt; / &lt;span style=&quot;color: #409d00;&quot;&gt;WINDOWS_LOGIN&lt;/span&gt; / &lt;span style=&quot;color: #409d00;&quot;&gt;WINDOWS_GROUP&lt;/span&gt; / &lt;span style=&quot;color: #409d00;&quot;&gt;SERVER_ROLE&lt;/span&gt; / &lt;span style=&quot;color: #409d00;&quot;&gt;CERTIFICATE_MAPPED_LOGIN&lt;/span&gt; / &lt;span style=&quot;color: #409d00;&quot;&gt;EXTERNAL_LOGIN&lt;/span&gt; / &lt;span style=&quot;color: #409d00;&quot;&gt;EXTERNLA_GROUP&lt;/span&gt; / &lt;span style=&quot;color: #409d00;&quot;&gt;ASYMMETRIC_KEY_MAPPED_LOGIN&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;is_disabled&lt;/b&gt; : &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;1=로그인할 수 없는 상태&lt;/b&gt;&lt;/span&gt; / &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;0=로그인 가능한 상태&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;credential_id&lt;/b&gt; : 이 보안 주체와 연결된 자격증명의 ID. 이 보안 주체와 연결된 자격 증명이 없는 경우 NULL 이 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. MSSQL Enable된 계정의 &lt;br /&gt;Default 데이터베이스, 최초 생성일, 계정 관련 변경일, PW 변경일, 해당 PW 사용일 수 &lt;br /&gt;확인 쿼리&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1675662061939&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT NAME AS id
, default_database_name AS 기본_데이터베이스
, create_date AS 최초_생성일
, modify_date AS 계정설정_변경일
, LOGINPROPERTY(NAME, 'PasswordLastSetTime') AS 패스워드_변경일
, DATEDIFF(DD, CONVERT(SMALLDATETIME, LOGINPROPERTY(name, 'PasswordLastSetTime')), GETDATE()) AS 패스워드_사용일수
FROM sys.server_principals
WHERE is_disabled = 0 AND type in ('S')&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1557&quot; data-origin-height=&quot;389&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KFUoQ/btrYieAkNJo/f2n31NjDOdxwTHroDVOYL1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KFUoQ/btrYieAkNJo/f2n31NjDOdxwTHroDVOYL1/img.png&quot; data-alt=&quot;sys.server_principals 를 통한 패스워드 변경일 조회 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KFUoQ/btrYieAkNJo/f2n31NjDOdxwTHroDVOYL1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKFUoQ%2FbtrYieAkNJo%2Ff2n31NjDOdxwTHroDVOYL1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;708&quot; height=&quot;177&quot; data-origin-width=&quot;1557&quot; data-origin-height=&quot;389&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;sys.server_principals 를 통한 패스워드 변경일 조회 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 각 계정별 최초 생성일 및 패스워드 변경일 등의 유용한 정보를 쿼리를 통해 확인할 수 있다!&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&amp;amp;blogId=kdj0876&amp;amp;logNo=221631226899&quot;&gt;https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&amp;amp;blogId=kdj0876&amp;amp;logNo=221631226899&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1675661930174&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;MSSQL 활성화 계정 및 비밀번호 변경 이력 확인&quot; data-og-description=&quot;#mssql비밀번호변경이력 #MSSQL계정확인 #MSSQL보안확인 1. mssql 활성화 계정 확인 (is_disable...&quot; data-og-host=&quot;blog.naver.com&quot; data-og-source-url=&quot;https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&amp;amp;blogId=kdj0876&amp;amp;logNo=221631226899&quot; data-og-url=&quot;https://blog.naver.com/kdj0876/221631226899&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cMxfci/hyRww6UYi4/kJCOT8bF1VIvCscz8qlfDk/img.png?width=270&amp;amp;height=270&amp;amp;face=0_0_270_270&quot;&gt;&lt;a href=&quot;https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&amp;amp;blogId=kdj0876&amp;amp;logNo=221631226899&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&amp;amp;blogId=kdj0876&amp;amp;logNo=221631226899&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cMxfci/hyRww6UYi4/kJCOT8bF1VIvCscz8qlfDk/img.png?width=270&amp;amp;height=270&amp;amp;face=0_0_270_270');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;MSSQL 활성화 계정 및 비밀번호 변경 이력 확인&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;#mssql비밀번호변경이력 #MSSQL계정확인 #MSSQL보안확인 1. mssql 활성화 계정 확인 (is_disable...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;blog.naver.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/sql/relational-databases/system-catalog-views/sys-server-principals-transact-sql?view=sql-server-ver16&quot;&gt;https://learn.microsoft.com/ko-kr/sql/relational-databases/system-catalog-views/sys-server-principals-transact-sql?view=sql-server-ver16&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1675733510725&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;sys.server_principals(Transact-SQL) - SQL Server&quot; data-og-description=&quot;sys.server_principals(Transact-SQL)&quot; data-og-host=&quot;learn.microsoft.com&quot; data-og-source-url=&quot;https://learn.microsoft.com/ko-kr/sql/relational-databases/system-catalog-views/sys-server-principals-transact-sql?view=sql-server-ver16&quot; data-og-url=&quot;https://learn.microsoft.com/ko-kr/sql/relational-databases/system-catalog-views/sys-server-principals-transact-sql&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/BPq3m/hyRxYuKMpA/kGca4NjBtpeJRWZK4Ms5p0/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400&quot;&gt;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/sql/relational-databases/system-catalog-views/sys-server-principals-transact-sql?view=sql-server-ver16&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://learn.microsoft.com/ko-kr/sql/relational-databases/system-catalog-views/sys-server-principals-transact-sql?view=sql-server-ver16&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/BPq3m/hyRxYuKMpA/kGca4NjBtpeJRWZK4Ms5p0/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;sys.server_principals(Transact-SQL) - SQL Server&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;sys.server_principals(Transact-SQL)&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;learn.microsoft.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DB/SQL Server (MSSQL)</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/125</guid>
      <comments>https://co-no.tistory.com/entry/MSSQL-Enable-%EA%B3%84%EC%A0%95-%EB%B0%8F-%EA%B0%81-%EA%B3%84%EC%A0%95%EB%B3%84-%EB%B0%9C%EA%B8%89%EC%9D%BC-PW-%EB%B3%80%EA%B2%BD%EC%9D%BC-%ED%99%95%EC%9D%B8#entry125comment</comments>
      <pubDate>Tue, 7 Feb 2023 10:50:16 +0900</pubDate>
    </item>
    <item>
      <title>[MSSQL] [트러블슈팅] \nError converting data type nvarchar to float. [8114]</title>
      <link>https://co-no.tistory.com/entry/MSSQL-%ED%8A%B8%EB%9F%AC%EB%B8%94%EC%8A%88%ED%8C%85-nError-converting-data-type-nvarchar-to-float-8114</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;SQL Server 계정에 대한 권한 정리 및 패스워드 변경 작업&lt;/b&gt;을 하면서 겪은 상황이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;신규 계정을 생성한 후, 사용하는 DB에 대한 권한만 넣었는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DB 접근도 잘 되고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 프로시저에 대한 접근(SSMS 상에서 보임), 실행(&quot;1개 행 적용됨&quot; 메시지 출력 및 &quot;프로시져 실행 시작..&quot; 메시지 출력) 은 되는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;&quot;\nError converting data type nvarchar to float. [8114]&quot;&lt;/b&gt;&lt;/span&gt; 라는 메시지가 나타났다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에는 원래 접속하던 계정이 가지고 있던 권한(SA 권한이었다...) 에서 빠진 게 있나 하고, 시스템 DB에 대한 db_owner 권한도 넣어보고 했지만, 여전히 위의 에러코드가 출력되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러던 중, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;SA&lt;/b&gt;&lt;/span&gt;의 로그인 속성은 기본 언어가&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt; 한국어&lt;/b&gt;&lt;/span&gt;인 반면, 내가 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;새로 만든 계정&lt;/b&gt;&lt;/span&gt;은 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;English&lt;/b&gt;&lt;/span&gt; 인 것을 발견했다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 SQL Server 계정에 대한 '기본 언어' 속성을 한국어로 바꾸고 나니, 프로시저 실행이 잘 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아무래도 한글로 되어 있는 어떤 데이터를 인식을 못하여 float 데이터로 바꾸지 못하던 현상인 듯 하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;&quot;\nError converting data type nvarchar to float. [8114]&quot;&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;위의 에러 메시지로 &lt;b&gt;잘 되던 프로시저가 갑자기 잘 안된다면, &lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;해당 계정의 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;[로그인 속성] - [기본 언어]&lt;/b&gt;&lt;/span&gt; 가 NVARCHAR 타입으로 되어 있는 데이터의 언어와 맞게끔 변경해보도록 하자!&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;963&quot; data-origin-height=&quot;829&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beVLWO/btrXYql8Uzi/AkTCwuSdh2dG4b1010HVR0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/beVLWO/btrXYql8Uzi/AkTCwuSdh2dG4b1010HVR0/img.png&quot; data-alt=&quot;MSSQL 계정에 대한 기본 언어 설정 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/beVLWO/btrXYql8Uzi/AkTCwuSdh2dG4b1010HVR0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbeVLWO%2FbtrXYql8Uzi%2FAkTCwuSdh2dG4b1010HVR0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;661&quot; height=&quot;569&quot; data-origin-width=&quot;963&quot; data-origin-height=&quot;829&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;MSSQL 계정에 대한 기본 언어 설정 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DB/SQL Server (MSSQL)</category>
      <category>MSSQL 트러블슈팅</category>
      <category>SQL Server 계정 기본 언어</category>
      <category>SQL Server 계정 설정</category>
      <category>SQL Server 로그인 속성 기본 언어</category>
      <category>SQL Server 트러블슈팅</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/124</guid>
      <comments>https://co-no.tistory.com/entry/MSSQL-%ED%8A%B8%EB%9F%AC%EB%B8%94%EC%8A%88%ED%8C%85-nError-converting-data-type-nvarchar-to-float-8114#entry124comment</comments>
      <pubDate>Fri, 3 Feb 2023 09:50:22 +0900</pubDate>
    </item>
    <item>
      <title>[Java] JVM 실행 옵션 (3) - Advanced Runtime Options</title>
      <link>https://co-no.tistory.com/entry/Java-JVM-%EC%8B%A4%ED%96%89-%EC%98%B5%EC%85%98-3-Advanced-Runtime-Options</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;본 포스팅은 &lt;b&gt;java 8 버전 (openjdk 1.8)&lt;/b&gt;을 기준으로 작성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전 포스팅에 이어, 이번 포스팅에서는 &lt;b&gt;Java HotSpot Virtual Machine 의 런타임 동작을 컨트롤&lt;/b&gt; 하는 옵션인&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;Advanced Runtime Options&lt;/b&gt;&lt;/span&gt;에 대해 알아보도록 하자!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;들어가기에 앞서, JVM 실행 옵션 중 Advanced 옵션들은 모두 '&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;XX'&lt;/b&gt;&lt;/span&gt;가 붙는다는 것을 알아두자!&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;a id=&quot;BABCBGHF&quot;&gt;&lt;/a&gt;&lt;b&gt;-XX:+CheckEndorsedAndExtDirs&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;Java 애플리케이션이 *Endorsed-Standards Override Mechanism 또는 **Extension Mechanism을 사용하는 경우, java 커맨드가 실행되지 않도록 예방할 수 있는 옵션.&lt;/b&gt;&lt;/span&gt;&amp;nbsp; 이 옵션은 아래와 같은 확인 과정을 거쳐 java 애플리케이션이 위와 같은 메커니즘을 사용하는지 판단한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;java.ext.dirs&lt;/span&gt; &lt;/b&gt;또는&lt;b&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt; java.endorsed.dirs&lt;/span&gt;&lt;/b&gt; 시스템 속성의 설정 여부&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt;lib/endorsed&lt;/b&gt;&lt;/span&gt; 디렉토리 존재 여부&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt;lib/ext&lt;/b&gt; &lt;/span&gt;디렉토리에 JDK 이외의 다른 JAR 파일 존재 여부&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt;system-wide platform-specific extension&lt;/b&gt;&lt;/span&gt; 디렉토리에 JAR 파일 존재 여부&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;*Endorsed-Standards Override Mechanism&lt;/b&gt; : JDK는 CORBA, DOM, SAX와 같은 패키지를 Java Endorsed Standards 로 분류하고 런타임에 포함시켜 놓았는데, 이러한 Endorsed-Standards 라이브러리들을 지정된 버전 또는 다른 구현체(implementation)로 바꾸고 싶을때 override 하는 것을 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;**Extension Mechanism&lt;/b&gt; : Java 플랫폼에서 실행되는 모든 어플리케이션 상에서 cumstom API를 사용할 수 있도록 하는 표준적, 확장 가능한 방법을 제공하는 메커니즘을 의미한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;a id=&quot;BABCBGHF&quot;&gt;&lt;/a&gt;&lt;b&gt;-XX:+DisableAttachMechanism&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;:&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt; jcmd, jstack, jmpa jinfo와 같은 Tool들을 JVM에 연결하는 것을 disable 하는 옵션.&lt;/b&gt;&lt;/span&gt; Default는 해당 옵션이 꺼져 있어(-XX:-DisableAttachMechanism), 이와 같은 Tool들을 모두 JVM에 연결시킬 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;a id=&quot;BABCBGHF&quot;&gt;&lt;/a&gt;&lt;b&gt;-XX:ErrorFile=&lt;i&gt;filename&lt;/i&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: 복구할 수 없는 Error 가 발생했을 때, &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;해당 에러 데이터를 어떤 위치의 어떤 파일로 쓸지 정하는 옵션.&lt;/b&gt; &lt;/span&gt;디폴트로는, 현재 작업 디렉토리(JVM이 실행되는 현재 디렉토리)에 &lt;b&gt;hs_err_pid%p.log&lt;/b&gt; 라는 파일명으로 생성된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;&amp;nbsp;/var/log/java/java_error.log&lt;/b&gt;&lt;/span&gt; 라는 디렉토리로 해당 에러 파일을 생성하고자 한다면 아래와 같이 설정하면 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1664931280560&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;+XX:ErrorFile=/var/log/java/java_error.log&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;a id=&quot;BABCBGHF&quot;&gt;&lt;/a&gt;&lt;b&gt;-XX:+FailOverToOldVerifier&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;:&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt; 새로운 type checker가 fail 났을 때, 이전 verifier로 자동으로 Fail Over 할 수 있도록 하는 옵션.&lt;/b&gt;&lt;/span&gt; 디폴트로는, disable 되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;a id=&quot;BABCBGHF&quot;&gt;&lt;/a&gt;&lt;b&gt;-XX:+FlightRecorder&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;애플리케이션 런타임 동안 JFR(Java Flight Recorder) 를 사용할 수 있도록 하는 옵션.&lt;/b&gt; &lt;/span&gt;이 옵션은 commercial 기능이므로, 아래와 같이 '-XX:+UnlockCommercialFeatures' 옵션과 함께 사용해야 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1664935254711&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;java -XX:+UnlockCommercialFeatures -XX:+FlightRecorder&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;a id=&quot;BABCBGHF&quot;&gt;&lt;/a&gt;&lt;b&gt;-XX:FlightRecorderOptions=&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;i&gt;parameter&lt;/i&gt;=&lt;i&gt;value&lt;/i&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;JFR의 동작을 제어하도록 하는 파라미터를 넣어 사용하는 옵션.&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이 옵션은 아래처럼 사용하면 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1664936964503&quot; class=&quot;angelscript&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-XX:FlightRecorderOptions=defaultrecording=true,disk=true,maxchunksize=10M&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래는 사용 '&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;parameter&lt;/b&gt;&lt;/span&gt;'의 값으로 사용 가능한 것들이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;defaultrecording={true|false}&lt;/b&gt;&lt;br /&gt;: Java 애플리케이션에 작동하자마자 자동으로 레코딩을 시작할지 지정하는 파라미터. 디폴트로는 false이다.&amp;nbsp;&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;disk={true|false}&lt;/b&gt;&lt;br /&gt;: 디스크에 임시 데이터를 저장할 것인지 정하는 파라미터. 디폴트로는 false이다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;dumponexit={true|false}&lt;/b&gt;&lt;br /&gt;: JVM에 정상적으로 종료됐을 시, 덤프 파일 또는 JFR 데이터를 생성할 것인지 지정하는 파라미터. 디폴트로는 false이다. 이 파라미터를 사용하려면, defaultrecording 파라미터도 true로 설정하여야 한다. 또한 덤프 파일이 저장되는 경로는 아래에서 설명할 파라미터인 'dumponexitpath=path' 를 통해 지정한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;dumponexitpath=path&lt;/b&gt;&lt;br /&gt;: path로 지정한 곳에 JFR에 대한 덤프파일이 저장되는 파라미터. 만약 해당 경로에 이미 덤프파일이 존재한다면, 파일명 뒤에 날짜와 타임스탬프를 추가하여 새 덤프파일을 생성하게 된다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;globalbuffersize=size&lt;/b&gt;&lt;br /&gt;: data retention 에 사용될 primary memory의 총 공간을 지정하는 파라미터. 단위는 바이트이며, 디폴트로는 462848 바이트로 지정되어 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;loglevel={quiet|error|warning|info|debug|trace}&lt;/b&gt;&lt;br /&gt;: JFR에 의해 쓰여질 로그파일에 대한 로그레벨을 지정하는 파라미터. 디폴트로는 info 이다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;maxage=time&lt;/b&gt;&lt;br /&gt;: 디폴트 레코딩으로 보존될 데이터의 최대 시간을 지정하는 파라미터. 디폴트로는 15m(minutes) 이다. 이는 'disk=true' 파라미터가 지정되어 있어야 설정 가능하다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;maxchunksize=size&lt;/b&gt;&lt;br /&gt;: 레코딩 할 때의 최대 데이터 청크 사이즈를 지정하는 파라미터.&amp;nbsp; 디폴트로는 12MB 로 되어 있다. 이 파라미터 역시, 'disk=true' 파라미터가 지정되어 있어야 설정 가능한 파라미터이다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;maxsize=size&lt;/b&gt;&lt;br /&gt;: 레코딩 할 때의 최대 데이터 사이즈를 지정하는 파라미터. 디폴트로는 최대 사이즈가 지정 되어 있지 않는데, 이 때 값이 0이다. 이 파라미터 역시, 'disk=true' 파라미터가 지정되어 있어야 설정 가능한 파라미터이다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;repository=path&lt;/b&gt;&lt;br /&gt;: 임시 디스크 스토리지를 지정하는 파라미터. 디폴트로는 시스템 임시 디렉토리가 지정되어 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;samplethreads={true|false}&lt;/b&gt;&lt;br /&gt;: 스레드 샘플링을 사용할 지 정하는 파라미터. 디폴트로는 true로 되어 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;settings=path&lt;/b&gt;&lt;br /&gt;: 이벤트 설정 파일(JFC 타입)의 경로 및 이름을 지정하는 파라미터. 디폴트로는 'default.jfs' 로 되어 있는데, 이는 $JAVA_HOME/jre/lib/jfr 을 의미한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;stackdepth=depth&lt;/b&gt;&lt;br /&gt;: JFR에 의해 추적할 스택 깊이를 지정하는 파라미터. 디폴트로는 64이며, 지정할 수 있는 최댓값은 2048, 최솟값은 1이다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;threadbuffersize=size&lt;/b&gt;&lt;br /&gt;: 스레드당 로컬 버퍼 사이즈를 지정하는 파라미터. 높은 값을 가질 수록, global 스토리지로 플러쉬없이 데이터를 버퍼에 갖고 있을 수 있다. 디폴트로는 5 KB 로 되어 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;a id=&quot;BABCBGHF&quot;&gt;&lt;/a&gt;&lt;b&gt;-XX:LargePageSizeInBytes=&lt;i&gt;size&lt;/i&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;Solaris 환경에서 Java 힙에 사용될 페이지의 최대 사이즈를 지정하는 옵션.&lt;/b&gt;&lt;/span&gt; 이때 size 값은 2의 배수가 되어야 하며, 아래와 같이 사용한다.&lt;/p&gt;
&lt;pre id=&quot;code_1664937428218&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-XX:LargePageSizeInBytes=4m&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;a id=&quot;BABCBGHF&quot;&gt;&lt;/a&gt;&lt;b&gt;-XX:MaxDirectMemorySize=&lt;i&gt;size&lt;/i&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;New I/O(java.nio 패키지에 해당하는 부분)에 대한 direct-buffer 할당 최대 사이즈를 지정하는 옵션.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;a id=&quot;BABCBGHF&quot;&gt;&lt;/a&gt;&lt;b&gt;-XX:NativeMemoryTracking=&lt;i&gt;mode&lt;/i&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;JVM의 네이티브 메모리 사용에 대한 추적을 지정하는 옵션.&lt;/b&gt;&lt;/span&gt; '&lt;b&gt;mode&lt;/b&gt;' 에 들어갈 argument는 아래와 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;off&lt;/b&gt; : JVM 네이티브 메모리 사용에 대한 추적을 하지 않는 argument&lt;/li&gt;
&lt;li&gt;&lt;b&gt;summary&lt;/b&gt; : Java 힙, 클래스, 코드, 스레드와 같은 JVM 서브시스템의 메모리 사용량만 추적하는 argument&lt;/li&gt;
&lt;li&gt;&lt;b&gt;detail&lt;/b&gt; : summary에 더해, 각각의 CallSite, 가상 메모리 영역, commited 영역의 메모리 사용량까지 추적하는 argument&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;a id=&quot;BABCBGHF&quot;&gt;&lt;/a&gt;&lt;b&gt;-XX:ObjectAlignmentInBytes=&lt;i&gt;alignment&lt;/i&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;자바 객체에 대한 메모리 배정을 지정하는 옵션.&lt;/b&gt; &lt;/span&gt;디폴트로는&lt;b&gt; 8바이트&lt;/b&gt;로 지정되어 있다. '&lt;b&gt;alignment&lt;/b&gt;' 에 바이트 단위의 값이 들어가며, 이 값은 &lt;b&gt;8 ~ 256 범위의 2의 배수&lt;/b&gt;여야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;a id=&quot;BABCBGHF&quot;&gt;&lt;/a&gt;&lt;b&gt;-XX:OnError=&lt;i&gt;string&lt;/i&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;복구할 수 없는 에러가 나왔을 때, 큰 따옴표 안에 ';'(세미 콜론)을 구분자로 지정한 명령어를 수행하도록 하는 옵션.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같이 사용한다.&lt;/p&gt;
&lt;pre id=&quot;code_1664943914865&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-XX:OnError=&quot;gcore %p;dbx - %p&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;a id=&quot;BABCBGHF&quot;&gt;&lt;/a&gt;&lt;b&gt;-XX:OnOutOfMemoryError=&lt;i&gt;string&lt;/i&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;Out Of MemoryError Exception&lt;/span&gt;이 처음 발생할 때 실행할, 사용자 지정 명령 또는 일련의 '&lt;span style=&quot;background-color: #c1bef9;&quot;&gt;;&lt;/span&gt;'(세미콜론)으로 구분된 명령을 설정하는 옵션.&lt;/b&gt; &lt;/span&gt;string에 들어갈 문자열 형식은 -XX:OnError의 string 형식과 동일하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;a id=&quot;BABCBGHF&quot;&gt;&lt;/a&gt;&lt;b&gt;-XX:+PerfDataSaveToFile&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;:&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt; Java 애플리케이션이 종료될 때, jstat(1) 바이너리 데이터를 저장하는 옵션.&lt;/b&gt;&lt;/span&gt; 이 바이너리 데이터는 &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;hsperfdata_&amp;lt;pid&amp;gt;&lt;/b&gt;&lt;/span&gt; 라는 파일에 저장되며,다음과 같이&lt;b&gt; jstat 명령어&lt;/b&gt;를 사용함으로써 해당 파일에 있는 performance 데이터를 표시할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1665706552009&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;jstat -class file:///&amp;lt;path&amp;gt;/hsperfdata_&amp;lt;pid&amp;gt;
jstat -gc file:///&amp;lt;path&amp;gt;/hsperfdata_&amp;lt;pid&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-XX:-PreferContainerQuotaForCPUCount&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: 이 옵션이 enable 되어 있을 경우, &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;CPU CFS(Completely Fair Scheduler) 할당량 값을 기준으로 컨테이너 CPU 가용성을 계산&lt;/b&gt;&lt;/span&gt;한다. 만일 &lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt;-XX:ActiveProcessorCount&lt;/b&gt;&lt;/span&gt; 옵션을 이 옵션 사용할 때에 명시하지 않았다면, JVM은 사용가능한 프로세서 수 계산을 위해 컨테이너 CPU 가용성을 사용한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-XX:+PrintCommandLineFlags&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;명령줄에 나타난 인체공학적(?)으로 선택된 JVM 플래그들을 출력할 수 있게 해주는 옵션.&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;힙 공간 사이즈&lt;/b&gt;와 &lt;b&gt;선택된 garbage collector &lt;/b&gt;와 같은, JVM에 의해 인체공학적(?)으로 선택된 이 값들을 아는 것이 유용할 수 있다. 디폴트로 이 옵션은 Disable 되어 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-XX:+PrintContainerInfo&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;다음 항목들과 같은 컨테이너에 대한 정보를 출력하는 옵션.&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;cpuset.cpus&lt;/b&gt; : 둘 이상의 CPU 또는 코어가 있는 경우, &lt;b&gt;컨테이너에서 사용할 수 있는 CPU 또는 코어의 범위&lt;/b&gt;. '&lt;b&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;,&lt;/span&gt;&lt;/b&gt;'(쉼표) 또는 '&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;-&lt;/b&gt;&lt;/span&gt;'(하이픈)으로 구분되어 있음. 예를 들어, 값 '&lt;b&gt;0-3&lt;/b&gt;' 이 의미하는 바는, 컨테이너가 첫번째, 두번째, 세번째, 네번째 CPU를 사용할 수 있음을 의미함.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;cpuset.mems&lt;/b&gt; :&lt;b&gt; NUMA(Non-Uniform Memory Access) 시스템&lt;/b&gt; 상에서만 효과적으로 애플리케이션을 실행하도록 허용하는 &lt;b&gt;메모리 노드&lt;/b&gt;의 범위. &lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;'&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;,&lt;/span&gt;&lt;/b&gt;'(쉼표) 또는 '&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;-&lt;/b&gt;&lt;/span&gt;'(하이픈)으로 구분되어 있음.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;CPU Shares&lt;/b&gt; : 프로세스에 사용할 수 있는 CPU 공유량.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;CPU Quota&lt;/b&gt; : 프로세스가 실행되는 것이 보장되는 기간 대비 밀리세컨드(milliseconds).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;CPU Period&lt;/b&gt; : CFS 주기. ms 단위.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;OSContainer::active_processor_count&lt;/b&gt; : JVM에 사용할 액티브 프로세서 수&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Memoery Limit&lt;/b&gt; : 컨테이너가 사용할 수 있는 메모리 최대 사이즈. 바이트 단위.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Memory Soft Limit&lt;/b&gt; : Memory Limit 보다 작은 값으로, 컨테이너가 초과할 수도 있는 메모리 최대 사이즈. 바이트 단위.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Memory Usage&lt;/b&gt; : 이 프로세스에서 사용되고 있는 메모리 량. 바이트 단위.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Maximum Memory Usage&lt;/b&gt; : 이 프로세스에서 사용할 수 있는 메모리 최대 사이즈. 바이트 단위.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-XX:+PrintNMTStatistics&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;Native Memory Tracking 이 가능하다면, JVM 종료시, 해당 데이터를 출력&lt;/b&gt;&lt;/span&gt;하는 옵션. 디폴트로 이 옵션은 Disable 되어 있다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-XX:+RelaxAccessControlCheck&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;검증자(Verifier)의 Access Control 체크량을 줄이는 옵션.&lt;/b&gt;&lt;/span&gt; 디폴트로 이 옵션은 Disable 되어 있으며, 최신 바이트코드 버전이라면 무시될 수 있는 옵션이다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-XX:+ResourceManagement&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;애플리케이션의 런타임동안 Resource Management를 사용할 수 있도록 하는 옵션.&lt;/b&gt;&lt;/span&gt; 이 옵션은 아래와 같이 &lt;br /&gt;'&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt;-XX:+UnlockCommercialFeatures&lt;/b&gt;&lt;/span&gt;' 옵션과 함께 사용해야 하는 상용 옵션이다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1665711963802&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;java -XX:+UnlockCommercialFeatrures -XX:+ResourceManagement&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-XX:ResourceManagementSampleInterval=&lt;/span&gt;&lt;i&gt;value&lt;/i&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;(milliseconds)&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;Resource Management 측정에 대한 샘플링 간격 값을 지정하는 옵션.&lt;/b&gt;&lt;/span&gt; &lt;b&gt;ms&lt;/b&gt; 단위이다. &lt;br /&gt;이 옵션은 '&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt;-XX:+ResourceManagement&lt;/b&gt;&lt;/span&gt;' 옵션이 활성화 되어 있는 경우에만 사용 가능하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-XX:SharedArchiveFile=&lt;/span&gt;&lt;i&gt;path&lt;/i&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;:&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt; path에 CDS(Class Data Sharing) 아카이브 파일의 디렉토리를 명시&lt;/b&gt;&lt;/span&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-XX:SharedClassListFile=&lt;/span&gt;&lt;i&gt;file_name&lt;/i&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;CDS(Class Data Sharing) 아카이브에 저장할 클래스 파일의 이름이 들어 있는 텍스트 파일을 지정&lt;/b&gt;&lt;/span&gt;한다. 이 파일에는 '&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;/&lt;/b&gt;&lt;/span&gt;'(슬래시), '&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;.&lt;/b&gt;&lt;/span&gt;'(마침표)를 제외한, 한 줄당 하나의 클래스 파일의 full-name이 포함된다. 예를 들어, java.lang.Object 와 hello.Main 두 클래스들을 지정한다고 하면, 다음과 같이 텍스트 파일을 작성한다.&lt;/p&gt;
&lt;pre id=&quot;code_1665712447921&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;java/lang/Object
hello/Main&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 텍스트 파일에서 지정하는 클래스 파일들은 애플리케이션에서 일반적으로 사용하는 클래스 파일들이 포함되어야 하며, 여기에는 애플리케이션, extension 또는 부트스트랩 클래스 경로가 포함될 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-XX:+ShowMessageBoxOnError&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;JVM에서 복구할 수 없는 에러가 발생할 경우, 다이얼로그 상자를 표시하도록 하는 옵션.&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이 옵션을 Enable 하면, JVM이 종료되지 않은 상태로, 디버거를 연결하여 오류의 원인을 조사할 수 있다. 디폴트로 이 옵션은 Disable 되어 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-XX:StartFlightRecording=&lt;/span&gt;&lt;i&gt;parameter&lt;/i&gt;&lt;span style=&quot;color: #000000;&quot;&gt;=&lt;/span&gt;&lt;i&gt;value&lt;/i&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;:&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt; Java 애플리케이션에 대한 JFR 레코딩을 시작하는 옵션.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;'&lt;/span&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt;-XX:+UnlockCommercialFeatures&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;' 옵션과 함께 사용해야 하는 상용 옵션이다. 또한 이 옵션은 런타임 중에 레코딩을 시작하는 JFR.start 진단 명령과 동일하다. JFR 레코딩을 시작할 때, 다음과 같은 parameter 들을 지정할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;compress={true|false}&lt;/b&gt; : gzip 파일 압축 유틸리티를 사용하여 디스크에서 JFR 레코딩 로그 파일을 압축할지 여부를 지정.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;defaultrecording={true|false}&lt;/b&gt; : 레코딩이 연속적인 백그라운드 레코딩인지 아니면 제한된 시간동안만 동작하는 레코딩인지를 지정하는 parameter. 디폴트로는 false로 지정되어 있다. 연속적인 백그라운드 레코딩을 수행하려면, true로 지정해야 한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;delay=time&lt;/b&gt; : Java 애플리케이션 시작 시간과 레코딩 시작 사이의 지연 시간을 지정하는 parameter. 디폴트로는 값이 0으로 지정되어 있다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;dumponexit={true|false}&lt;/b&gt; : JVM이 적절한 방법으로 종료될 때, JFR 데이터의 덤프 파일을 생성해야 하는지에 대한 여부를 지정하는 parameter. 디폴트로는 false로 지정되어 있다. 덤프 파일은 'filename' 파라미터로 지정된 경로에 만들어진다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;duration=time&lt;/b&gt; : 레코딩의 기간을 지정. 디폴트로는 값이 0으로, 기간이 제한되어 있지 않음.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;filename=path&lt;/b&gt; : JFR 레코딩 로그 파일의 경로를 지정하는 parameter.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;name=identifier&lt;/b&gt; : JFR 레코딩에 대한 식별자를 지정. 디폴트로, Recording x 로 설정되어 있음.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;maxage=time&lt;/b&gt; : 기본 레코딩에 대해서 디스크 내에 보관될 최대 기한을 지정하는 parameter. 디폴트로 15분으로 지정되어 있음.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;maxsize=size&lt;/b&gt; : 기본 레코딩에 대해서 디스크 내에서 보관될 최대 크기를 지정하는 parameter. 바이트 단위이다. 디폴트로 0으로 지정되어 있어, 크기가 제한되어 있지 않다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;settings=path&lt;/b&gt; : 이벤트 설정 파일의 디렉토리를 지정하는 parameter. 디폴트로 $JAVA_HOME/jre/lib/jfr 에 있는 'default.jfc' 파일이 사용됨.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 옵션은 여러 parameter들을 쉼표로 구분하여 아래와 같이 사용한다.&lt;/p&gt;
&lt;pre id=&quot;code_1665713790409&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-XX:StartFlightRecording=filename=test.jfr,compress=true&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-XX:ThreadStackSize=&lt;/span&gt;&lt;i&gt;size&lt;/i&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;스레드 스택 크기를 설정하는 옵션.&lt;/b&gt;&lt;/span&gt; 기본값은 플랫폼에 따라 아래와 같이 달라진다. '&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt;-Xss&lt;/b&gt;&lt;/span&gt;' 옵션과 동일하다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;Linux&lt;/b&gt;/ ARM(32비트) : 320 KB&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Linux&lt;/b&gt;/ i386(32비트) : 320 KB&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Linux&lt;/b&gt;/ x64(64비트) : 1024 KB&lt;/li&gt;
&lt;li&gt;&lt;b&gt;OS X&lt;/b&gt;(64비트) : 1024 KB&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Oracle Solaris&lt;/b&gt;/ i386(32비트) : 320 KB&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Oracle Solaris&lt;/b&gt;/ x64(64비트) :1024 KB&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-XX:+TraceClassLoading&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;클래스가 로드될 때 Tracking을 활성화하는 옵션.&lt;/b&gt; &lt;/span&gt;디폴트로 Disable 되어 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-XX:+TraceClassLoadingPreorder&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;로드된 모든 클래스를 참조되는 순서대로 Tracking 하는 옵션.&lt;/b&gt;&lt;/span&gt; 디폴트로 Disable 되어 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-XX:+TraceClassResolution&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;*상수 풀(Constant Pool) resolution을 Tracking 하는 옵션.&lt;/b&gt; &lt;/span&gt;디폴트로 Disable 되어 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;* Constant Pool Resolution&lt;/b&gt; : &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;Resolution&lt;/b&gt;&lt;/span&gt;이란, &lt;b&gt;Symbolic reference&lt;/b&gt;로 표현된 Entry를 찾아서&lt;b&gt; Direct Reference&lt;/b&gt;로 변경하는 과정을 말하는데, 클래스의 모든 Symbolic Reference는 메서드 영역의 Constant Pool이라는 곳에 저장되기 때문에, 이 Resolution을 Constant Pool Resolution이라 부른다. 즉, Constant Pool Resolution 정보란, Constant Pool의 포인터 정보를 일컫는다. 이 포인터 정보(주소)를 보고, Constant Pool(메모리에서의 PEM 영역)을 찾아가는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-XX:+TraceClassUnloading&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;언로드되는 클래스들을 Tracking 하는 옵션.&lt;/b&gt; &lt;/span&gt;디폴트로 Disable 되어 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-XX:+TraceLoaderConstraints&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;:&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt; 로더 제약조건 레코딩을 Tracking 하는 옵션.&lt;/b&gt; &lt;/span&gt;디폴트로 Disable 되어 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-XX:+UnlockCommercialFeatures&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;상용 기능(Commercial Features)을 사용하도록 하는 옵션.&lt;/b&gt; &lt;/span&gt;상용 기능들은 아래 링크에 &lt;b&gt;Java SE Products&lt;/b&gt; 라고 정의되어&amp;nbsp; 있는, Oracle Java SE Advanced 또는 Oracle Java SE Suite 패키지에 포함되어 있다. 디폴트로 Disable 되어 있으며, 이는 상용 기능(별도의 기능) 없이 JVM이 실행된다는 의미이다. &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;만일 해당 JVM 프로세스에 이 옵션이 Enable되도록 설정한 이후에는, 프로세스가 종료되지 않는 이상, 중간에 해당 옵션을 Disable 할 수 없다.&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;이 옵션을 사용하지 않아도, &lt;b&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;jcmd&lt;/span&gt;&lt;/b&gt; 진단 명령을 사용하여 가동 중인 JVM 상에서 상용 기능의 잠금을 해제할 수 있다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;a href=&quot;http://www.oracle.com/technetwork/java/javase/terms/products/index.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://www.oracle.com/technetwork/java/javase/terms/products/index.html&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1665721534598&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Java SE Products&quot; data-og-description=&quot;Introducing Oracle Java SE Subscriptions The Java SE Advanced, Java SE Advanced Desktop, and Java SE Suite products have transitioned to a Java SE Subscriptions offering that provides more flexibility to customers. Customers who have Java SE Advanced, Java&quot; data-og-host=&quot;www.oracle.com&quot; data-og-source-url=&quot;http://www.oracle.com/technetwork/java/javase/terms/products/index.html&quot; data-og-url=&quot;https://www.oracle.com/java/technologies/se-products.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;http://www.oracle.com/technetwork/java/javase/terms/products/index.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;http://www.oracle.com/technetwork/java/javase/terms/products/index.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Java SE Products&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Introducing Oracle Java SE Subscriptions The Java SE Advanced, Java SE Advanced Desktop, and Java SE Suite products have transitioned to a Java SE Subscriptions offering that provides more flexibility to customers. Customers who have Java SE Advanced, Java&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.oracle.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-XX:+UseAltSigs&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;JVM 내부 신호로 사용되는 SIGUSR1 및 SIGUSR2 에 대한 대체신호를 지정하는 옵션&lt;/b&gt;&lt;/span&gt;. 디폴트로 Disable 되어 있으며,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;'&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt;-Xusealtsigs&lt;/b&gt;&lt;/span&gt;' 옵션과 동일하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-XX:+UseAppCDS&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;애플리케이션 클래스 데이터 공유(AppCDS) 기능을 Enable&lt;/b&gt;&lt;/span&gt; 하는 옵션. 이때 AppCDS를 사용하려면, CDS 덤프 타임 기간(-Xshare:dump 옵션) 및 애플리케이션 런타임 동안에 &lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;-XX:SharedClassListFile &lt;/span&gt;값&lt;/b&gt;과 &lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;-XX:SharedArchiveFile&lt;/span&gt; 값&lt;/b&gt;을&amp;nbsp; 지정해야 한다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이는 상용기능으로서, &lt;u&gt;-XX:+UnlockCommercialFeatures 옵션을 함께 사용&lt;/u&gt;해야 한다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-XX:-UseBiasedLocking&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;*Biased Lock 기능을 비활성화&lt;/b&gt;&lt;/span&gt;하는 옵션. 상당한 양의 제어되지 않은 synchronization 을 가지고 있는 애플리케이션의 경우, 이 옵션이 &lt;b&gt;활성화(+)&lt;/b&gt;되어 있는 상태에서 &lt;b&gt;상당한 속도 향상을 달성&lt;/b&gt;할 수 있는 반면, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;특정 패턴의 lock 기능이 있는 애플리케이션&lt;/b&gt;&lt;/span&gt;은 속도가 느려질 수 있으므로,&lt;b&gt; 비활성화(-)를 권장&lt;/b&gt;한다. &lt;b&gt;디폴트로 이 옵션은 Enabled&lt;/b&gt; 이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;*Biased Lock&lt;/b&gt; : 일반적으로 쓰레드 간 경쟁을 피하기 위해, 개발 시에 Synchronized 키워드를 통해 쉽게 lock을 설정하는데, 그렇게 하면 일부는 여러 쓰레드 간 경쟁이 발생하기보다는 동일한 쓰레드에 대해서만 엑세스가 일어나는 경우가 자주 발생한다. 이런 경우, 모니터를 할당 받고 해제하는 과정이 성능상 비효율적일 수 있는데, &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;Thread id 를 체크하여 lock을 획득하고자 하는 쓰레드가 반복해서 동일한 쓰레드라고 판단되면, OS lock을 사용하지 않도록 하는 lock&lt;/b&gt;&lt;/span&gt;을 말한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-XX:-UseCompressedOops&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;**Compressed OOPS 사용을 Disable&lt;/b&gt; &lt;/span&gt;하는 옵션. 디폴트로 이 옵션은 Enable 되어 있으며, Java 힙 크기가 32GB 미만일 때에 Compressed OOPS가 사용된다. 이 옵션이 Enable 되어 있으면, 개체 참조가 64비트 포인터 대신에 32비트 offset으로 표시되므로, 일반적으로 힙 크기가 32GB 미만인 환경에서 애플리케이션의 성능을 향상시킬 수 있다. 이 옵션은 64비트 JVM에 대해서만 동작한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;*OOPS(Ordinary Object Pointers)&lt;/b&gt; : java는 포인터가 없는데, 이 말은 즉슨&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt; 모든게 포인터가 될 수 있다&lt;/b&gt;&lt;/span&gt;는 말이기도 하다. jvm은 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;오브젝트의 레퍼런스를 관리하기 위해 OOPS라고 불리는 자료구조&lt;/b&gt;&lt;/span&gt;를 가지는데, 32비트 시스템(ILP32)에서는 oops가 최대 힙의 4GB 까지 사용할 수 있다. 64비트 시스템(LP64)에서는 oops가 최대 힙의 18.5EB(엑사바이트) 까지 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;**Compressed OOPS&lt;/b&gt; : &lt;b&gt;Java 에서는 OOPS가 차지하는 메모리의 양을 줄이기 위해 &lt;span style=&quot;color: #006dd7;&quot;&gt;Tricky 한 방법&lt;/span&gt;을 사용&lt;/b&gt;한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;Compressed OOPS&lt;/b&gt;&lt;/span&gt; 를 통해 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;32비트 만으로도 32GB 힙을 사용할 수 있도록 하는 것&lt;/b&gt;&lt;/span&gt;인데, 기존에는 OOPS가 4GB 만큼의 메모리 영역을 직접 관리하였다. 그러나 Compressed OOPS 방식을 통해, &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;OOPS 가 오브젝트를 레퍼런싱 하는 대신, 오브젝트의 offset 을 레퍼런싱&lt;/b&gt;&lt;/span&gt;하여, 3비트 만큼을 더 사용할 수 있으므로써, 64비트 방식이 아닐 때에도 2^32 (4GB) * 2^3&amp;nbsp; = 32 GB 만큼의 힙을 사용할 수 있도록 한다. 다만, 32GB 를 넘게 되면, 기존의 OOPS 방식을 사용하게 된다. (64비트 시스템)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-XX:-UseContainerSupport&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;VM&lt;/b&gt;&lt;/span&gt;에서는 VM이 도커 컨테이너 안에서 실행 중인 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;Java 프로세스에 대해서 사용할 수 있는 메모리 양과 프로세스 수를 결정&lt;/b&gt;&lt;/span&gt;할 수 있는&lt;b&gt; 자동 컨테이너 감지 기능(Automatic Container Detection)&lt;/b&gt;을 제공하는데, 이 정보를 사용하여 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;시스템 리소스를 할당하는 옵션&lt;/b&gt;&lt;/span&gt;이다. 이 옵션은 오직 Linux x64 플랫폼에서만 지원되며, 지원된다면 디폴트로 enable되어 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-XX:+UseHugeTLBFS&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: 리눅스의 경우, '&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;-XX:+UseLargePages&lt;/b&gt;&lt;/span&gt;' 옵션을 사용하는 것과 동일한 효과이다. &lt;b&gt;디폴트로 disable&lt;/b&gt; 되어 있다. 이 옵션은 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;메모리가 점유되어 있는 경우, 모든 *Large Page를 미리 할당하도록 하는 옵션&lt;/b&gt;&lt;/span&gt;이다. 이렇게 되면, JVM은 Large Page 메모리 영역을 동적으로 늘리거나 축소할 수 없게 된다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;*Large Page&lt;/b&gt; : &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;프로세서 TLB(Translation-Lookaside Buffers) 캐시에서 일부 작업을 제거할 수 있도록 하는 기술&lt;/b&gt;&lt;/span&gt;이다. 여기서 &lt;b&gt;TLB 캐시&lt;/b&gt;란, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;가상 메모리 주소를 물리적 메모리 주소로 변환하는 시간을 단축하는 데에 사용&lt;/b&gt;&lt;/span&gt;된다. 대부분의 아키텍처에서는 여러 Page 사이즈를 지원하며, 대부분 4KB를 기본값으로 가지는데, 메모리 점유가 매우 큰 애플리케이션의 경우, 메모리를 Large Page의 granularity(세분성)와 일치시켜주는 것이 TLB 캐시의 히트율을 높이는 방법으로 합리적이다. &lt;br /&gt;&amp;nbsp;x86-64 에서는 이러한 목적으로 2MB 및 1GB의 페이지를 사용할 수 있으며, 메모리 사용량이 많은 워크로드의 경우, 이러한 Large Page 기능이 매우 큰 영향을 미칠 수 있다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;그러나&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt; Large Pages 가 시스템 퍼포먼스에 부정적인 영향을 미치는 경우도 있다.&lt;/b&gt; &lt;/span&gt;예를 들어, &lt;u&gt;애플리케이션에 의해 많은 양의 메모리가 예약되어 있는 경우, Large Pages 기능은 오히려 regular memory 부족을 초래하고, 다른 애플리케이션에서의 과도한 페이징을 유발하며 이는 전체 시스템을 느리게 만들 수 있다.&lt;/u&gt; 또한, 오랜 기간 가동되고 있는 시스템의 경우, 과도한 단편화가 진행되어 있을 것인데, 이는 충분한 Large Page를 할당하지 못하게 하기도 한다. 만약 이렇게 Large Page를 할당하지 못할 경우, OS 또는 JVM에서 regular page를 사용하도록 전환하게 된다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-XX:+UseLargePages&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;:&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt; Large Page 메모리를 사용 가능하도록 하는 옵션&lt;/b&gt;&lt;/span&gt;으로, 디폴트로는 &lt;b&gt;disable&lt;/b&gt; 되어 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-XX:+UseMembar&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;스레드 상태 전환 시 'Membar(*Memory Barrier)' 를 활성화&lt;/b&gt;&lt;/span&gt; 하는 옵션. 이 옵션은 ARM을 제외한 모든 플랫폼에서는 디폴트로 Disable 되어 있고, ARM 시스템에서는 디폴트로 Enable 되어 있다. (ARM 서버에서 Disable 시키는 것은 권장하지 않는다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;*Memory Barrier&lt;/b&gt; : 메모리 베리어는 CPU나 컴파일러에게 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;barrier 명령문 전 후의 메모리 연산을 순서에 맞게 실행하도록 강제하는 기능&lt;/b&gt;&lt;/span&gt;을 말한다. 즉, barrier 이전에 나온 연산들이 barrier 이후에 나온 연산보다 먼저 실행이 되는게 보장되도록 하는 것이다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-XX:+UsePerfData&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;:&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt; 'perfdata' 기능을 활성화하는 옵션.&lt;/b&gt;&lt;/span&gt;&lt;b&gt; JVM 모니터링 및 퍼포먼스 테스트를 허용하기 위해 디폴트로 Enable&lt;/b&gt; 되어 있다. 이 옵션을 비활성화 한다면, 'hsperfdata_userid' 디렉토리가 생성되지 않는다.&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;* perfdata 또는 hsperfdata&lt;/b&gt; : Java 코드가 실행될 때, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;JVM에 의해 생성되는 로그 디렉토리&lt;/b&gt;&lt;/span&gt;로, 디폴트로 OS 에서 사용하고 있는 tmp 폴더에 생성되며, 파일 이름은 해당 JVM 프로세스의 PID로 된다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-XX:+UseTransparentHugePages&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;리눅스 환경에서 동적으로 증가 또는 축소가 가능한 Large Pages 기능을 활성화&lt;/b&gt;&lt;/span&gt; 하는 옵션. 이 옵션은 디폴트로 Disable 되어 있다. Large Page를 만들기 위해 OS가 다른 페이지를 이동할 때,&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt; transparent huge page&lt;/span&gt; 문제&lt;/b&gt;를 마주할 수 있는데, 이 옵션을 통해 해당 문제에 대해 테스트 해볼 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-XX:+AllowUserSignalHandlers&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: 애플리케이션에 의한 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;신호 핸들러를 설치할 수 있도록 하는&lt;/b&gt;&lt;/span&gt; 옵션. 디폴트로 이 옵션은 Disable 되어 있다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1664928058457&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;java&quot; data-og-description=&quot;Large Pages Also known as huge pages, large pages are memory pages that are significantly larger than the standard memory page size (which varies depending on the processor and operating system). Large pages optimize processor Translation-Lookaside Buffers&quot; data-og-host=&quot;docs.oracle.com&quot; data-og-source-url=&quot;https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html&quot; data-og-url=&quot;https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;java&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Large Pages Also known as huge pages, large pages are memory pages that are significantly larger than the standard memory page size (which varies depending on the processor and operating system). Large pages optimize processor Translation-Lookaside Buffers&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.oracle.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://fuirosun.tistory.com/entry/java-endorsed-override-mechanism&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://fuirosun.tistory.com/entry/java-endorsed-override-mechanism&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1664929601406&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;java endorsed override mechanism&quot; data-og-description=&quot;JDK 8u25 버전을 쓰다가 JDK 업데이트를 하려고 Release Note를 봤다. 8u40릴리즈 노트에 &amp;quot;endorsed-standards override mechanism&amp;quot;가 deprecated API로 잡혀있었는데 처음 들어보는 용어라 찾아봤다. 공식 문서는..&quot; data-og-host=&quot;fuirosun.tistory.com&quot; data-og-source-url=&quot;https://fuirosun.tistory.com/entry/java-endorsed-override-mechanism&quot; data-og-url=&quot;https://fuirosun.tistory.com/entry/java-endorsed-override-mechanism&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/eAN07f/hyP171gvtd/00fkVKv8KSMyXIYTwr2UpK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/eCPOk/hyP0zrzxdV/lHAz5dKNm4p5hjpKSSRMAk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://fuirosun.tistory.com/entry/java-endorsed-override-mechanism&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://fuirosun.tistory.com/entry/java-endorsed-override-mechanism&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/eAN07f/hyP171gvtd/00fkVKv8KSMyXIYTwr2UpK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/eCPOk/hyP0zrzxdV/lHAz5dKNm4p5hjpKSSRMAk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;java endorsed override mechanism&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;JDK 8u25 버전을 쓰다가 JDK 업데이트를 하려고 Release Note를 봤다. 8u40릴리즈 노트에 &quot;endorsed-standards override mechanism&quot;가 deprecated API로 잡혀있었는데 처음 들어보는 용어라 찾아봤다. 공식 문서는..&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;fuirosun.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://xephysis.tistory.com/6&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://xephysis.tistory.com/6&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1668469776540&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;JVM Compressed OOPS&quot; data-og-description=&quot;들어가는 말 몇 년 전 elasitcsearch 클러스터를 새로 구성했을 때 heap 관련 설정으로 찾았던 내용을 기록한다. 기본적으로는 ES 공식 가이드 (구버전)의 내용을 따라간다. 요약 jvm 기반의 애플리케이&quot; data-og-host=&quot;xephysis.tistory.com&quot; data-og-source-url=&quot;https://xephysis.tistory.com/6&quot; data-og-url=&quot;https://xephysis.tistory.com/6&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dptAk4/hyQzi3CEDN/FBWfptiAZysoAtaV6d6jc1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/dh8YQy/hyQzfMABMq/CDeqzStxQxdESsmMTrdkk1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://xephysis.tistory.com/6&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://xephysis.tistory.com/6&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dptAk4/hyQzi3CEDN/FBWfptiAZysoAtaV6d6jc1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/dh8YQy/hyQzfMABMq/CDeqzStxQxdESsmMTrdkk1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;JVM Compressed OOPS&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;들어가는 말 몇 년 전 elasitcsearch 클러스터를 새로 구성했을 때 heap 관련 설정으로 찾았던 내용을 기록한다. 기본적으로는 ES 공식 가이드 (구버전)의 내용을 따라간다. 요약 jvm 기반의 애플리케이&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;xephysis.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://yoojin99.github.io/cs/Memory-Barrier/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://yoojin99.github.io/cs/Memory-Barrier/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1669612141107&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Memory Barrier, 메모리 배리어란?&quot; data-og-description=&quot;Memory Barrier가 무엇인지 알아보자.&quot; data-og-host=&quot;yoojin99.github.io&quot; data-og-source-url=&quot;https://yoojin99.github.io/cs/Memory-Barrier/&quot; data-og-url=&quot;https://yoojin99.github.io/cs/Memory-Barrier/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bvWbj0/hyQJFJL0bH/LNcs3jXgkkEmfCTyhljnCK/img.png?width=678&amp;amp;height=563&amp;amp;face=0_0_678_563,https://scrap.kakaocdn.net/dn/bdCkn5/hyQHZXnN1t/nv2PnqVbQFCET2pAdFzBx0/img.jpg?width=512&amp;amp;height=406&amp;amp;face=160_202_290_344&quot;&gt;&lt;a href=&quot;https://yoojin99.github.io/cs/Memory-Barrier/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://yoojin99.github.io/cs/Memory-Barrier/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bvWbj0/hyQJFJL0bH/LNcs3jXgkkEmfCTyhljnCK/img.png?width=678&amp;amp;height=563&amp;amp;face=0_0_678_563,https://scrap.kakaocdn.net/dn/bdCkn5/hyQHZXnN1t/nv2PnqVbQFCET2pAdFzBx0/img.jpg?width=512&amp;amp;height=406&amp;amp;face=160_202_290_344');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Memory Barrier, 메모리 배리어란?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Memory Barrier가 무엇인지 알아보자.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;yoojin99.github.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Java</category>
      <category>Java 8</category>
      <category>Java Advanced Runtime Option</category>
      <category>jdk 8</category>
      <category>jvm execution option</category>
      <category>jvm 실행 옵션</category>
      <category>자바 실행 옵션</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/115</guid>
      <comments>https://co-no.tistory.com/entry/Java-JVM-%EC%8B%A4%ED%96%89-%EC%98%B5%EC%85%98-3-Advanced-Runtime-Options#entry115comment</comments>
      <pubDate>Mon, 28 Nov 2022 14:23:04 +0900</pubDate>
    </item>
    <item>
      <title>[Java] Spring 프레임워크에서의 MVC 패턴과 레이어드 아키텍처</title>
      <link>https://co-no.tistory.com/entry/Java-Spring-%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC%EC%97%90%EC%84%9C%EC%9D%98-MVC-%ED%8C%A8%ED%84%B4%EA%B3%BC-Service-DAO-DTO-VO-%EA%B0%9C%EB%85%90</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1. MVC 패턴이란?&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: 소프트웨어 공학에서 사용되는 &lt;b&gt;소프트웨어 디자인 패턴의 한 종류&lt;/b&gt;를 말하는데, &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;Model-View-Controller&lt;/b&gt;&lt;/span&gt;의 약자이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 패턴을 사용하는 궁극적인 목적은, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;사용자 인터페이스(Interface)로부터 비즈니스 로직(Logic)을 분리&lt;/b&gt;&lt;/span&gt;함으로써, 애플리케이션의 시각적 요소와 그 이면에서 실행되는 비즈니스 로직 간에 영향을 최소한으로 줄여, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;프로그램의 유지 보수성을 높이고, 성능을 향상시키는 데에 있다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2. MVC 패턴의 구성 요소와 원칙&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;모델(Model)&lt;/b&gt;&lt;br /&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;데이터와 관련된 책임&lt;/b&gt;&lt;/span&gt;을 담당하는 레이어&lt;br /&gt;- &lt;b&gt;[POJO] 비즈니스 로직&lt;/b&gt;을 수행한다.&lt;br /&gt;- 주로 상태 변화를 처리한다. (최근에는 Entity, VO, Aggregate로 나누어서 관리한다. -&amp;gt; &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;도메인 주도 설계&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;- &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;데이터와 그 데이터를 통한 행동을 갖는 객체&lt;/b&gt;&lt;/span&gt;이다.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;원칙)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&quot;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;Model은 Controller와 View에 의존해서는 안된다!&lt;/b&gt;&lt;/span&gt;&quot;&lt;br /&gt;☞ Model이 Controller, View의 책임을 가지면 안 된다는 것이다. &lt;b&gt;각 레이어에서 담당하는 책임이라는 것이 존재&lt;/b&gt;한다.&lt;br /&gt;☞ 오로지 &lt;u&gt;&lt;b&gt;'데이터'에 대한 '순수 로직'만 존재하는 것이 바람직&lt;/b&gt;&lt;/u&gt;하다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;뷰(View)&lt;/b&gt;&lt;br /&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;사용자에게 보여질 사용자 인터페이스(UI)를 담당&lt;/b&gt;&lt;/span&gt;하는 레이어&lt;br /&gt;- 웹에서는 &lt;b&gt;웹 브라우저로 렌더링 되는 페이지들&lt;/b&gt;을 View의 영역으로 말한다.&lt;br /&gt;- 모델이 처리한 데이터를 받아서 합산하고 사용자(Client)의 브라우저로 렌더링 되는 페이지이다.&lt;br /&gt;- 동적으로 처리되어야 할 데이터를 시각화 해주는 역할도 하는데, 이때 상황과 도메인에 따라 달라지는 값을 가져와야 하는 경우에만 Model에서 받아온다.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;원칙)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&quot;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;데이터 및 로직과 관련된 코드가 없어야 한다!&lt;/b&gt;&lt;/span&gt;&quot;&lt;br /&gt;☞ 오로지 UI에만 관여하는 레이어이므로, 당연하다.&lt;br /&gt;&lt;br /&gt;&quot;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;View는 Model에만 의존해야 한다!&lt;/b&gt;&lt;/span&gt;&quot;&lt;br /&gt;☞ 여기서 말하는 '&lt;b&gt;의존&lt;/b&gt;'은 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;코드상의 의존이 아닌, 순수 도메인 데이터에 대한 의존&lt;/b&gt;&lt;/span&gt;을 말한다.&lt;br /&gt;즉, &lt;b&gt;View에 사용되는 값은 오로지 &lt;span style=&quot;color: #006dd7;&quot;&gt;Model을 통해서 전달된 값이어야만&lt;/span&gt; 한다&lt;/b&gt;는 것이다.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;컨트롤러(Controller)&lt;/b&gt;&lt;br /&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;Model과 View를 연결&lt;/b&gt;&lt;/span&gt;해주는 레이어&lt;br /&gt;- 일종의 &lt;b&gt;중개자&lt;/b&gt;로서, 사용자의 요청에 맞는 서비스를 실행하는데, 이때 &lt;b&gt;실질적인 로직의 처리는 Model에서 진행&lt;/b&gt;하는 것이다.&lt;br /&gt;- &lt;b&gt;Model 에서 처리한 값을 View에 전달하여 반환&lt;/b&gt;하는 역할도 한다.&lt;br /&gt;- &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;사용자의 요청(웹 브라우저를 통해 들어오는 요청)을 가장 먼저 마주하는 레이어&lt;/b&gt;&lt;/span&gt;이다.(&lt;u&gt;URL을 요청 받으면, 그에 맞는 화면을 띄워주므로, View 보다도 먼저 마주한다고 볼 수 있다.&lt;/u&gt;)&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;원칙)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&quot;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;Controller는 Model과 View에 의존해야 한다!&lt;/b&gt;&lt;/span&gt;&quot;&lt;br /&gt;☞ 여기서 말하는 '&lt;b&gt;의존'&lt;/b&gt;은, &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;중개자 역할로서의 의존&lt;/b&gt;&lt;/span&gt;을 말한다. 즉, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;Controller 혼자 데이터(Model 영역)에 대한 처리를 단독으로 하면 안된다&lt;/b&gt;&lt;/span&gt;는 말이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3. Spring 프레임워크에서의 레이어드 아키텍처(Layered Architecture)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞서 우리는 MVC 패턴이 무엇인지에 대해 배웠는데, 실무에서는 단순히 Model - View - Controller 인 이 3가지로 구성하다 보면, 여러 문제가 발생할 수 있다. 큰 그림에서는 Model - View - Controller로 구분함으로써, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;비즈니스 로직 부분과 UI를 철저하게 구분한다는 원칙에는 변함이 없지만&lt;/b&gt;&lt;/span&gt;, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;백엔드 엔지니어가 실무 프로젝트를 다룬다면, Controller 부분과 Model 부분에서 보통 더 세분화하여 개발하곤 한다.&lt;/b&gt;&lt;/span&gt; 이 포스팅에서는 그러한 세분화된 패턴인 &lt;b&gt;레이어드 아키텍처&lt;/b&gt;에 대해 알아보기로 하자!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;769&quot; data-origin-height=&quot;532&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MySLQ/btrQcNbjNya/ufkk26MwTgTzxIJQKrJK01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MySLQ/btrQcNbjNya/ufkk26MwTgTzxIJQKrJK01/img.png&quot; data-alt=&quot;Layered Architecture / 출처 : rypro.tistory.com/216&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MySLQ/btrQcNbjNya/ufkk26MwTgTzxIJQKrJK01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMySLQ%2FbtrQcNbjNya%2Fufkk26MwTgTzxIJQKrJK01%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;461&quot; data-origin-width=&quot;769&quot; data-origin-height=&quot;532&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Layered Architecture / 출처 : rypro.tistory.com/216&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Presentation Layer&lt;/b&gt;&lt;br /&gt;- &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;사용자와 가장 가까운 계층&lt;/b&gt;&lt;/span&gt;으로, &lt;b&gt;사용자와의 상호작용을 담당&lt;/b&gt;.&lt;br /&gt;- Spring 에서의 MVC 패턴이 가장 도드라지게 나타나는 영역이며, 여기에 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;프론트-컨트롤러(DispatcherServlet), 컨트롤러, 뷰, 모델이 포함&lt;/b&gt;&lt;/span&gt;된다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Business Layer (Service Layer)&lt;/b&gt;&lt;br /&gt;- &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;실제 비즈니스 로직을 수행하는 컴포넌트&lt;/b&gt;&lt;/span&gt;로, &lt;b&gt;트랜잭션 및 실질적인 비즈니스 로직 수행&lt;/b&gt; 담당.&lt;br /&gt;- 컨트롤러(Presentation Layer)에서 요청을 보내면, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;*DAO(Data Access Layer) 를 이용하여 실제로 비즈니스 로직을 수행&lt;/b&gt;&lt;/span&gt;하게 된다.&lt;br /&gt;- 보통 하나의 비즈니스 로직은 하나의 트랜잭션(ACID 특징)으로 동작한다는 원칙이 있다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Data Access Layer(Repository Layer)&lt;/b&gt;&lt;br /&gt;- &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;데이터베이스에 연동되어 데이터의 저장과 조회를 담당&lt;/b&gt;&lt;/span&gt;하는 영역.&lt;br /&gt;- DB에 값을 저장하거나 가져오기 위해, &lt;b&gt;JDBC, MyBatis, JPA 등을 사용&lt;/b&gt;하여 구현한 DAO 영역이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;※ 실제 프로젝트에서의 패키지 구성&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;292&quot; data-origin-height=&quot;363&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bOuK5F/btrQaKTHOhf/qVKpBKXfMKqceNDGzDkIV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bOuK5F/btrQaKTHOhf/qVKpBKXfMKqceNDGzDkIV1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bOuK5F/btrQaKTHOhf/qVKpBKXfMKqceNDGzDkIV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbOuK5F%2FbtrQaKTHOhf%2FqVKpBKXfMKqceNDGzDkIV1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;292&quot; height=&quot;363&quot; data-origin-width=&quot;292&quot; data-origin-height=&quot;363&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;4. Domain Object / Entity / VO / DTO / DAO 의 개념&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;684&quot; data-origin-height=&quot;195&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nCjA2/btrQe2UTOpl/sUIMWGSB0oLtafTCSgvXU0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nCjA2/btrQe2UTOpl/sUIMWGSB0oLtafTCSgvXU0/img.png&quot; data-alt=&quot;DTO, DAO 이해를 위한 그림 / 출처 : https://velog.io/@ohzzi/Entity-DAO-DTO가-무엇이며-왜-사용할까&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nCjA2/btrQe2UTOpl/sUIMWGSB0oLtafTCSgvXU0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnCjA2%2FbtrQe2UTOpl%2FsUIMWGSB0oLtafTCSgvXU0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;684&quot; height=&quot;195&quot; data-origin-width=&quot;684&quot; data-origin-height=&quot;195&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;DTO, DAO 이해를 위한 그림 / 출처 : https://velog.io/@ohzzi/Entity-DAO-DTO가-무엇이며-왜-사용할까&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;Domain Object&lt;/b&gt;&lt;br /&gt;: 말 그대로 도메인 객체를 말하는데, 여기서 '&lt;b&gt;도메인(Domain)&lt;/b&gt;'이란, 일반적인 요구사항, 전문 용어, 그리고 컴퓨터 프로그래밍 분야에서 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;문제를 해결하기 위해 설계된 어떤 소프트웨어 프로그램에 대한 기능성을 정의&lt;/b&gt;&lt;/span&gt;하는 연구의 한 영역.&lt;br /&gt;&amp;nbsp;즉, &lt;b&gt;애플리케이션의 기능, (기획의) 요구사항을 개발하는 영역&lt;/b&gt;을 도메인이라고 정의하고 있다.&lt;br /&gt;예를 들어, &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;온라인 서점 사이트&lt;/b&gt;&lt;/span&gt;에서 책을 조회하고 구매한다고 가정할 때, 온라인 서점 소프트웨어는 상품의 조회, 구매, 결제 등의 기능을 제공해야 한다. 이때 '&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;온라인 서점&lt;/b&gt;&lt;/span&gt;'은 소&lt;b&gt;프트웨어로 해결하고자 하는 문제 영역, 즉 도메인에 해당된다.&lt;/b&gt;&lt;br /&gt;&amp;nbsp;이러한 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;도메인은 다시 하위 도메인으로 나눌 수 있으며&lt;/b&gt;&lt;/span&gt;, '온라인 서점'을 다시 예로 든다면, &lt;b&gt;하위 도메인으로는 '&lt;span style=&quot;color: #409d00;&quot;&gt;주문&lt;/span&gt;', '&lt;span style=&quot;color: #409d00;&quot;&gt;결제&lt;/span&gt;', '&lt;span style=&quot;color: #409d00;&quot;&gt;배송&lt;/span&gt;' 과 같이 나눌 수 있을 것이다.&lt;/b&gt;&lt;br /&gt;&amp;nbsp;&lt;u&gt;JPA 에서는 Entity와 Domain을 용어적인 측면에서 혼용하여 사용하기도 한다.&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Entity&lt;/b&gt;&lt;br /&gt;: &lt;b&gt;엔티티의 가장 큰 특징은 &lt;span style=&quot;color: #ee2323;&quot;&gt;식별자&lt;/span&gt;를 가진다는 것&lt;/b&gt;이다. 즉, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;식별자 외의 데이터가 변경된다고 해서, 그 식별자를 가진 객체가 다른 객체가 되지는 않는다는 것&lt;/b&gt;&lt;/span&gt;이다. 예를 들어, &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;Purchase&lt;/b&gt; &lt;/span&gt;라는 도메인이 &lt;b&gt;주문id를 식별자로&lt;/b&gt; 가진다고 하자. 이때 Purchase의 &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;주문 상태 데이터&lt;/b&gt;&lt;/span&gt;를 변경한다고 해서, &lt;b&gt;해당 주문이 다른 주문으로 되지는 않는다&lt;/b&gt;는 말이다.&lt;br /&gt;&amp;nbsp;또한 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;데이터베이스의 '테이블'과 혼동하면 곤란&lt;/b&gt;&lt;/span&gt;하다. 엔티티는 SQL 상에 실제로 존재하는 것이 아닌, 일종의 개념이다. 반면 데이터베이스의 테이블은 DB 또는 SQL 상에 실제로 존재하며, 물리적인 구조를 가지고 있다. 따라서 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;엔티티는 논리 모델에서 사용되고, 테이블은 물리 모델에서 사용되는 용어&lt;/b&gt;&lt;/span&gt;이다.&lt;br /&gt;&amp;nbsp;정리하면, Entity는 실체, 객체라는 의미를 담고 있으며, &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;업무에 필요하고 유용한 정보를 저장 및 관리하기 위한 집합적인 개념&lt;/b&gt;&lt;/span&gt;이라고 말할 수 있다.&amp;nbsp;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;&amp;nbsp;Spring&lt;/b&gt;&lt;/span&gt;에서 사용되는 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;Entity&lt;/b&gt;&lt;/span&gt;라는 용어는, 주로 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;ORM 혹은 ODM 등과 같이 DB의 Row 또는 Document를 객체에 매핑시켜주는 기술&lt;/b&gt;&lt;/span&gt;에서 사용된다. 즉, 이때의 Entity는 DB 의 데이터와 맵핑되는 객체를 말하며, 식별자가 존재하는 특성 덕분에&lt;b&gt; Setter를 이용하여 '&lt;span style=&quot;color: #ee2323;&quot;&gt;가변 객체&lt;/span&gt;'로서 사용&lt;/b&gt;할 수 있다.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;VO(Value Object)&lt;/b&gt;&lt;br /&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;값 그 자체를 표현하는 객체로 사용&lt;/b&gt;&lt;/span&gt;된다. VO는 Entity와 달리, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;식별자를 가지지 않는다.&lt;/b&gt; &lt;/span&gt;즉, &lt;u&gt;&lt;b&gt;VO 객체 내의 단 하나의 데이터라도 변경되면, 그 객체는 서로 다른 객체가 되어 버린다.&lt;/b&gt;&lt;/u&gt; 이 때문에 같은 객체임을 확실하게 보장하기 위해, VO는 일반적으로 '&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;불변 객체'&lt;/b&gt;&lt;/span&gt;로서 사용한다. 이 말은 &lt;b&gt;Setter 를 구현하지 않는다&lt;/b&gt;는 말이기도 하다. 또한 서로 다른 인스턴스이더라도 값이 같으면 같은 객체가 되기 때문에, &lt;b&gt;서로 같은 객체인지를 판단할 때, &lt;span style=&quot;color: #006dd7;&quot;&gt;equals&lt;/span&gt; 또는 &lt;span style=&quot;color: #006dd7;&quot;&gt;hashCode&lt;/span&gt; 를 구현하여 판별&lt;/b&gt;한다.&lt;br /&gt;&amp;nbsp;또한 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;Spring의 MyBatis 를 사용할 때 주로 VO 라는 개념을 사용&lt;/b&gt;&lt;/span&gt;한다. 그 이유로는, MyBatis는 *SQL-Mapper 이기 때문에, 어떠한 로직에 의해 가져온 데이터는 그저 맵핑되는 값을 가져온 것일 뿐, 실제 DB의 테이블과 매핑되는 것은 아니기 때문이다.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;★ MyBatis에서는 &lt;span style=&quot;color: #006dd7;&quot;&gt;VO&lt;/span&gt;! / JPA에서는 &lt;span style=&quot;color: #006dd7;&quot;&gt;Entity&lt;/span&gt;!&lt;/b&gt;&lt;br /&gt;&amp;nbsp;Spring에서 DB와의 연동 기술을 적용할 때, &lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;MyBatis(SQL-Mapper)&lt;/span&gt;를 사용하는 경우&lt;/b&gt;라면, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;VO&lt;/b&gt;&lt;/span&gt; 라고 표현 및 사용하고,&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;JPA(ORM 기술)&lt;/b&gt;&lt;/span&gt;를 사용하는 경우라면,&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt; Entity&lt;/b&gt;&lt;/span&gt; 라고 표현 및 사용한다.&lt;br /&gt;&lt;b&gt;&amp;nbsp;&lt;span style=&quot;color: #8a3db6;&quot;&gt;SQL-Mapper&lt;/span&gt;&lt;/b&gt; 는 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;RDBMS를 객체 지향 모델로 매핑하는 걸 도와주는 인터페이스(?)&lt;/b&gt;&lt;/span&gt;로 보면 된다. 즉, 객체를 SQL statement에 매핑시킬 수 있도록 도와주는 역할만 하므로, &lt;b&gt;SQL문을 명시해줘야 한다.&lt;/b&gt; 또한, 개발자가 작성한 SQL 문으로 해당되는 Row를 읽어온 후, 결과 값을 오브젝트화시켜 사용가능하도록 만들어준다.&lt;br /&gt;&amp;nbsp;&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;ORM(Object Relational Mapping)&lt;/b&gt;&lt;/span&gt;은 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;데이터베이스를 객체로 매핑함으로써, 객체 간의 관계를 바탕으로 테이블을 만들고 관리하는 것&lt;/b&gt;&lt;/span&gt;을 말한다. 즉 SQL-Mapper처럼 단순 인터페이스 역할이 아닌, 객체가 DB에 직접적으로 매핑된다는 특징을 가지고 있어,&lt;b&gt; RDBMS 상에서의 '관계' 까지 Object에 반영&lt;/b&gt;되며, 이로 인해 &lt;b&gt;SQL문을 명시하지 않고,&lt;/b&gt; 정해진 &lt;b&gt;직관적인 코드(메서드)로 데이터를 조작&lt;/b&gt;할 수 있게 해준다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;DTO(Data Transfer Object)&lt;/b&gt;&lt;br /&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;데이터 교환을 위한 객체&lt;/b&gt;&lt;/span&gt;이다. DB와 연동되어 있는 &lt;b&gt;VO 또는 Entity에서의 데이터 조작을 피하기 위해&lt;/b&gt;, DTO를 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;로직의 파라미터 및 리턴으로 사용&lt;/b&gt;&lt;/span&gt;한다. 데이터 교환만을 위해 사용되므로, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;DTO가 직접적인 로직을 갖지는 않으며, Getter와 Setter 만을 가진다.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;DAO(Data&amp;nbsp;Access&amp;nbsp;Object)&lt;/b&gt; &lt;br /&gt;:&amp;nbsp;&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;데이터베이스의&amp;nbsp;Data에&amp;nbsp;접근하기&amp;nbsp;위한&amp;nbsp;객체&lt;/b&gt;&lt;/span&gt;이다.&amp;nbsp;프로젝트의&amp;nbsp;서비스&amp;nbsp;레이어(실제&amp;nbsp;비즈니스&amp;nbsp;로직이&amp;nbsp;돌아가는&amp;nbsp;곳)와&amp;nbsp;실제&amp;nbsp;데이터베이스를&amp;nbsp;연결하는&amp;nbsp;역할을&amp;nbsp;하며,&amp;nbsp;특히&lt;b&gt;&amp;nbsp;JPA에서는&amp;nbsp;DB에&amp;nbsp;데이터를&amp;nbsp;CRUD&amp;nbsp;하는&amp;nbsp;'Repository'&amp;nbsp;객체들이&amp;nbsp;DAO에&amp;nbsp;해당&lt;/b&gt;된다. &lt;br /&gt;(정확하게&amp;nbsp;말하면&amp;nbsp;'&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;Repository&lt;/b&gt;&lt;/span&gt;'는&amp;nbsp;원래&amp;nbsp;&lt;b&gt;Entity&amp;nbsp;객체를&amp;nbsp;보관하고&amp;nbsp;관리하는&amp;nbsp;'저장소'&lt;/b&gt;를&amp;nbsp;말하며,&amp;nbsp;메모리에&amp;nbsp;로드된&amp;nbsp;객체&amp;nbsp;컬렉션에&amp;nbsp;대한&amp;nbsp;집합&amp;nbsp;처리를&amp;nbsp;위한&amp;nbsp;인터페이스&amp;nbsp;제공을&amp;nbsp;위한&amp;nbsp;역할이다. &lt;br /&gt;&amp;nbsp;'&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;DAO&lt;/b&gt;&lt;/span&gt;'는&amp;nbsp;퍼시스턴스&amp;nbsp;로직인&amp;nbsp;Entity&amp;nbsp;Bean을&amp;nbsp;대체하기&amp;nbsp;위해&amp;nbsp;만들어진&amp;nbsp;개념으로,&amp;nbsp;&lt;b&gt;DB의&amp;nbsp;CRUD&amp;nbsp;쿼리와&amp;nbsp;1:1&amp;nbsp;매칭되는&amp;nbsp;세밀한&amp;nbsp;단위의&amp;nbsp;오퍼레이션을&amp;nbsp;제공&lt;/b&gt;한다. &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;JPA&lt;/span&gt;를&amp;nbsp;활용한&amp;nbsp;개발&lt;/b&gt;에서는,&amp;nbsp;&lt;u&gt;데이터에&amp;nbsp;접근하도록&amp;nbsp;하는&amp;nbsp;DB접근&amp;nbsp;관련&amp;nbsp;로직(여러&amp;nbsp;오퍼레이션)을&amp;nbsp;모아둔&amp;nbsp;객체인&amp;nbsp;DAO의&amp;nbsp;기능이&amp;nbsp;하나의&amp;nbsp;Repository&amp;nbsp;안에&amp;nbsp;포함시켜&amp;nbsp;개발하는&amp;nbsp;경우가&amp;nbsp;많으므로&lt;/u&gt;,&amp;nbsp;&lt;b&gt;용어적인&amp;nbsp;측면에서&amp;nbsp;DAO와&amp;nbsp;Repository를&amp;nbsp;동일한&amp;nbsp;의미로&amp;nbsp;사용&lt;/b&gt;하기도&amp;nbsp;한다.)&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1667440395641&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* MemberService 코드 */

import {Group}.{Artifact}.domain.Member;
import {Group}.{Artifact}.repository.MemberRepository;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class MemberService {

    private final MemberRepository memberRepository;

    //회원 가입
    @Transactional
    public Long join(Member member) {
        validateDuplicateMember(member);    // 중복 회원 검증 로직
        memberRepository.save(member);
        return member.getId();
    }

    private void validateDuplicateMember(Member member) {
        //EXCEPTION
        List&amp;lt;Member&amp;gt; findMembers = memberRepository.findByEmpID(member.getEmp_ID());
       if (!findMembers.isEmpty()) {
           throw new IllegalStateException(&quot;이미 존재하는 회원입니다.&quot;);
       }
    }

    //회원 전체 조회
    public List&amp;lt;Member&amp;gt; findMembers() {
        return memberRepository.findAll();
    }
    
    //회원 단일 조회
    public Member findOne(Long memberId) {
        return memberRepository.findOne(memberId);
    }

    @Transactional
    public void update(Long id, String mem_Name) {
        Member member = memberRepository.findOne(id);
        member.setMem_Name(mem_Name);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1667440516283&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* Member 엔티티 */


import lombok.Getter;
import lombok.Setter;

import javax.persistence.*;

@Entity
@Getter @Setter
public class Member {

    @Id @GeneratedValue
    @Column(name = &quot;pri_member_id&quot;)
    private Long id;

    //권한 부여 위한 그룹 넘버링
    private Long GROUP_NO;

    //회원 사번
    private Long emp_ID;

    //회원 이름
    private String mem_Name;

    //회원 직급
    private String level;

    //회원 로그인 아이디
    private String mem_ID;
    //회원 패스워드
    private String mem_PWD;


}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1667439932259&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* MemberRepository 코드 */

import {Group}.{Artifact}.domain.Member;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;

import javax.persistence.EntityManager;
import java.util.List;

@Repository
@RequiredArgsConstructor
public class MemberRepository {

    private final EntityManager em;

    public void save(Member member) {
        em.persist(member);
    }

    public Member findOne(Long id) {
        return em.find(Member.class, id);
    }

    public List&amp;lt;Member&amp;gt; findAll() {
        return em.createQuery(&quot;SELECT m from Member m&quot;, Member.class).getResultList();
    }

    public List&amp;lt;Member&amp;gt; findByEmpID(Long emp_Id) {
        return em.createQuery(&quot;SELECT m from Member m WHERE m.emp_ID = :emp_ID&quot;, Member.class)
                .setParameter(&quot;emp_ID&quot;, emp_Id)
                .getResultList();
    }

//    public Member findByEmpID(Long emp_id) {
//        return em.find(Member.class, emp_id);
//    }

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://m.blog.naver.com/jysaa5/221751719334&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://m.blog.naver.com/jysaa5/221751719334&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1667288686430&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[용어] MVC, Spring Framework MVC, Controller, Service, DAO, DTO, VO - 개념&quot; data-og-description=&quot;MVC (Model-View-Controller) - 소프트웨어 공학에서 사용되는 소프트웨어 디자인 패턴이다. - 이 패...&quot; data-og-host=&quot;blog.naver.com&quot; data-og-source-url=&quot;https://m.blog.naver.com/jysaa5/221751719334&quot; data-og-url=&quot;https://blog.naver.com/jysaa5/221751719334&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ffC0K/hyQpzErKE6/wFsNgqncBnQcftyWiv7EYK/img.png?width=743&amp;amp;height=290&amp;amp;face=0_0_743_290&quot;&gt;&lt;a href=&quot;https://m.blog.naver.com/jysaa5/221751719334&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://m.blog.naver.com/jysaa5/221751719334&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ffC0K/hyQpzErKE6/wFsNgqncBnQcftyWiv7EYK/img.png?width=743&amp;amp;height=290&amp;amp;face=0_0_743_290');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[용어] MVC, Spring Framework MVC, Controller, Service, DAO, DTO, VO - 개념&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;MVC (Model-View-Controller) - 소프트웨어 공학에서 사용되는 소프트웨어 디자인 패턴이다. - 이 패...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;blog.naver.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@jybin96/Controller-Service-Repository-%EA%B0%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://velog.io/@jybin96/Controller-Service-Repository-%EA%B0%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1667288702196&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Controller, Service, Repository 가 무엇일까?&quot; data-og-description=&quot;찾아본 결과 Controller가 무엇인지 알기 전에 MVC 패턴에 대하여 먼저 아는 것이 중요합니다!MVC패턴은 Model-View-Controller의 약자로서 개발을 할 때 3가지 형태로 역학을 나누어 개발하는 방법론입니&quot; data-og-host=&quot;velog.io&quot; data-og-source-url=&quot;https://velog.io/@jybin96/Controller-Service-Repository-%EA%B0%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C&quot; data-og-url=&quot;https://velog.io/@jybin96/Controller-Service-Repository-가-무엇일까&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/JF3sd/hyQpxzPLmZ/4kzHPRilk9kohvSZ4paKxk/img.png?width=950&amp;amp;height=500&amp;amp;face=0_0_950_500,https://scrap.kakaocdn.net/dn/xotmr/hyQptRKL7M/TXfO3XHflHLwkBTCP4cp50/img.png?width=893&amp;amp;height=329&amp;amp;face=0_0_893_329,https://scrap.kakaocdn.net/dn/i0qyN/hyQqJyGkAH/Is5gdnMcVCKOfZv2fKQtVk/img.jpg?width=460&amp;amp;height=460&amp;amp;face=123_186_205_275&quot;&gt;&lt;a href=&quot;https://velog.io/@jybin96/Controller-Service-Repository-%EA%B0%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://velog.io/@jybin96/Controller-Service-Repository-%EA%B0%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/JF3sd/hyQpxzPLmZ/4kzHPRilk9kohvSZ4paKxk/img.png?width=950&amp;amp;height=500&amp;amp;face=0_0_950_500,https://scrap.kakaocdn.net/dn/xotmr/hyQptRKL7M/TXfO3XHflHLwkBTCP4cp50/img.png?width=893&amp;amp;height=329&amp;amp;face=0_0_893_329,https://scrap.kakaocdn.net/dn/i0qyN/hyQqJyGkAH/Is5gdnMcVCKOfZv2fKQtVk/img.jpg?width=460&amp;amp;height=460&amp;amp;face=123_186_205_275');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Controller, Service, Repository 가 무엇일까?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;찾아본 결과 Controller가 무엇인지 알기 전에 MVC 패턴에 대하여 먼저 아는 것이 중요합니다!MVC패턴은 Model-View-Controller의 약자로서 개발을 할 때 3가지 형태로 역학을 나누어 개발하는 방법론입니&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;velog.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://murphymoon.tistory.com/entry/%EC%9A%B0%EC%95%84%ED%95%9C-%ED%85%8C%ED%81%AC-MVC-%EB%A6%AC%EB%B7%B0-%EB%A0%88%EC%9D%B4%EC%96%B4-MVC-%ED%8C%A8%ED%84%B4-5%EB%A0%88%EC%9D%B4%EC%96%B4&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://murphymoon.tistory.com/entry/%EC%9A%B0%EC%95%84%ED%95%9C-%ED%85%8C%ED%81%AC-MVC-%EB%A6%AC%EB%B7%B0-%EB%A0%88%EC%9D%B4%EC%96%B4-MVC-%ED%8C%A8%ED%84%B4-5%EB%A0%88%EC%9D%B4%EC%96%B4&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1667289562864&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;우아한 테크 -MVC 패턴 리뷰- [레이어, MVC 패턴, 5레이어]&quot; data-og-description=&quot;발표자료들 범블비(2020) : MVC 패턴에 대한 설명 + MVC 패턴의 역사 제리(2021) : MVC 패턴의 활용성에 대한 원칙 해리&amp;amp;션(2019) : MVC의 Model, Controller, View에 대한 소개. 제이임(2019)의 MVC 패턴 : 미션과 관&quot; data-og-host=&quot;murphymoon.tistory.com&quot; data-og-source-url=&quot;https://murphymoon.tistory.com/entry/%EC%9A%B0%EC%95%84%ED%95%9C-%ED%85%8C%ED%81%AC-MVC-%EB%A6%AC%EB%B7%B0-%EB%A0%88%EC%9D%B4%EC%96%B4-MVC-%ED%8C%A8%ED%84%B4-5%EB%A0%88%EC%9D%B4%EC%96%B4&quot; data-og-url=&quot;https://murphymoon.tistory.com/entry/%EC%9A%B0%EC%95%84%ED%95%9C-%ED%85%8C%ED%81%AC-MVC-%EB%A6%AC%EB%B7%B0-%EB%A0%88%EC%9D%B4%EC%96%B4-MVC-%ED%8C%A8%ED%84%B4-5%EB%A0%88%EC%9D%B4%EC%96%B4&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dzAjcQ/hyQprTX8xo/4cSYA6old9bMoeF3Sk6srk/img.png?width=200&amp;amp;height=220&amp;amp;face=0_0_200_220,https://scrap.kakaocdn.net/dn/IXqme/hyQqS3s6Eo/QcTqvlwctvIH76Ug6Yofw1/img.png?width=200&amp;amp;height=220&amp;amp;face=0_0_200_220,https://scrap.kakaocdn.net/dn/bkVQ7Q/hyQpsFjaRA/9jpE9F1ivKmE0Nls21jLFK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot;&gt;&lt;a href=&quot;https://murphymoon.tistory.com/entry/%EC%9A%B0%EC%95%84%ED%95%9C-%ED%85%8C%ED%81%AC-MVC-%EB%A6%AC%EB%B7%B0-%EB%A0%88%EC%9D%B4%EC%96%B4-MVC-%ED%8C%A8%ED%84%B4-5%EB%A0%88%EC%9D%B4%EC%96%B4&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://murphymoon.tistory.com/entry/%EC%9A%B0%EC%95%84%ED%95%9C-%ED%85%8C%ED%81%AC-MVC-%EB%A6%AC%EB%B7%B0-%EB%A0%88%EC%9D%B4%EC%96%B4-MVC-%ED%8C%A8%ED%84%B4-5%EB%A0%88%EC%9D%B4%EC%96%B4&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dzAjcQ/hyQprTX8xo/4cSYA6old9bMoeF3Sk6srk/img.png?width=200&amp;amp;height=220&amp;amp;face=0_0_200_220,https://scrap.kakaocdn.net/dn/IXqme/hyQqS3s6Eo/QcTqvlwctvIH76Ug6Yofw1/img.png?width=200&amp;amp;height=220&amp;amp;face=0_0_200_220,https://scrap.kakaocdn.net/dn/bkVQ7Q/hyQpsFjaRA/9jpE9F1ivKmE0Nls21jLFK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;우아한 테크 -MVC 패턴 리뷰- [레이어, MVC 패턴, 5레이어]&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;발표자료들 범블비(2020) : MVC 패턴에 대한 설명 + MVC 패턴의 역사 제리(2021) : MVC 패턴의 활용성에 대한 원칙 해리&amp;amp;션(2019) : MVC의 Model, Controller, View에 대한 소개. 제이임(2019)의 MVC 패턴 : 미션과 관&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;murphymoon.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/questions/111159&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.inflearn.com/questions/111159&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1667351673097&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;domain과 repository 질문 - 인프런 | 질문 &amp;amp; 답변&quot; data-og-description=&quot;안녕하세요, 강의 듣다 궁금증이 생겨 질문 남깁니다. 질문 1. domain == vo, repository == dao 이렇게 똑같이 봐도 괜찮은 건가요? 같은 것이라면 왜 vo, dao가 아닌 다른 이름을 사용한 것인지, 다른 것이&quot; data-og-host=&quot;www.inflearn.com&quot; data-og-source-url=&quot;https://www.inflearn.com/questions/111159&quot; data-og-url=&quot;https://www.inflearn.com/questions/111159&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b1a1cd/hyQppI2xdM/1tEfcckGgfkrQHnvbkoYtk/img.jpg?width=1200&amp;amp;height=628&amp;amp;face=751_416_794_464,https://scrap.kakaocdn.net/dn/ctsbWH/hyQpwBlC3P/vtcsjCecXyf6x31KB7y02K/img.jpg?width=1200&amp;amp;height=628&amp;amp;face=751_416_794_464&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/questions/111159&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inflearn.com/questions/111159&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b1a1cd/hyQppI2xdM/1tEfcckGgfkrQHnvbkoYtk/img.jpg?width=1200&amp;amp;height=628&amp;amp;face=751_416_794_464,https://scrap.kakaocdn.net/dn/ctsbWH/hyQpwBlC3P/vtcsjCecXyf6x31KB7y02K/img.jpg?width=1200&amp;amp;height=628&amp;amp;face=751_416_794_464');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;domain과 repository 질문 - 인프런 | 질문 &amp;amp; 답변&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;안녕하세요, 강의 듣다 궁금증이 생겨 질문 남깁니다. 질문 1. domain == vo, repository == dao 이렇게 똑같이 봐도 괜찮은 건가요? 같은 것이라면 왜 vo, dao가 아닌 다른 이름을 사용한 것인지, 다른 것이&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inflearn.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/questions/16046&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.inflearn.com/questions/16046&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1667351675818&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;프로젝트 폴더 구조와 강의 일정에 관하여 질문이 있습니다. - 인프런 | 질문 &amp;amp; 답변&quot; data-og-description=&quot;1. 실무에서 프로젝트 구현시 보통 폴더 구조를 어떤식으로 하시나요? 프로젝트를 하는데 폴더 구조를 어떻게 해야 좋을지 궁금합니다. 강의와 같이 api 패키지를 하나 만들고 Controller 클래스 안&quot; data-og-host=&quot;www.inflearn.com&quot; data-og-source-url=&quot;https://www.inflearn.com/questions/16046&quot; data-og-url=&quot;https://www.inflearn.com/questions/16046&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/c90VTg/hyQqJsjcxi/2Mv4w5cygRHZXK9KmVx0n0/img.jpg?width=1200&amp;amp;height=628&amp;amp;face=751_416_794_464,https://scrap.kakaocdn.net/dn/mTeia/hyQqP68xiM/phWh5wS9uEoJwYAYyNtHpk/img.jpg?width=1200&amp;amp;height=628&amp;amp;face=751_416_794_464&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/questions/16046&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inflearn.com/questions/16046&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/c90VTg/hyQqJsjcxi/2Mv4w5cygRHZXK9KmVx0n0/img.jpg?width=1200&amp;amp;height=628&amp;amp;face=751_416_794_464,https://scrap.kakaocdn.net/dn/mTeia/hyQqP68xiM/phWh5wS9uEoJwYAYyNtHpk/img.jpg?width=1200&amp;amp;height=628&amp;amp;face=751_416_794_464');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;프로젝트 폴더 구조와 강의 일정에 관하여 질문이 있습니다. - 인프런 | 질문 &amp;amp; 답변&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;1. 실무에서 프로젝트 구현시 보통 폴더 구조를 어떤식으로 하시나요? 프로젝트를 하는데 폴더 구조를 어떻게 해야 좋을지 궁금합니다. 강의와 같이 api 패키지를 하나 만들고 Controller 클래스 안&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inflearn.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://rypro.tistory.com/216&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://rypro.tistory.com/216&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1667351688209&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[Spring] Layered Architecture&quot; data-og-description=&quot;Layered Architecture 효율적인 개발과 유지보수를 위해 어플리케이션을 계층화하여 개발하는 것을 말한다. 대체적으로 중/대규모 어플리케이션에서 사용하고 있다. Pressentation Layer - 사용자와 가장 &quot; data-og-host=&quot;rypro.tistory.com&quot; data-og-source-url=&quot;https://rypro.tistory.com/216&quot; data-og-url=&quot;https://rypro.tistory.com/216&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/QI3dm/hyQqWZvuwL/5n9HKyekG1HLOpRByGUkX0/img.jpg?width=800&amp;amp;height=553&amp;amp;face=0_0_800_553,https://scrap.kakaocdn.net/dn/bTIw04/hyQqX5agJW/H6h1fH3N3K45CKnwKvCgdk/img.jpg?width=800&amp;amp;height=553&amp;amp;face=0_0_800_553,https://scrap.kakaocdn.net/dn/EsQHw/hyQpC9pYBO/6NBUbtBXr8BULxFk3NgKkK/img.png?width=860&amp;amp;height=367&amp;amp;face=0_0_860_367&quot;&gt;&lt;a href=&quot;https://rypro.tistory.com/216&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://rypro.tistory.com/216&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/QI3dm/hyQqWZvuwL/5n9HKyekG1HLOpRByGUkX0/img.jpg?width=800&amp;amp;height=553&amp;amp;face=0_0_800_553,https://scrap.kakaocdn.net/dn/bTIw04/hyQqX5agJW/H6h1fH3N3K45CKnwKvCgdk/img.jpg?width=800&amp;amp;height=553&amp;amp;face=0_0_800_553,https://scrap.kakaocdn.net/dn/EsQHw/hyQpC9pYBO/6NBUbtBXr8BULxFk3NgKkK/img.png?width=860&amp;amp;height=367&amp;amp;face=0_0_860_367');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[Spring] Layered Architecture&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Layered Architecture 효율적인 개발과 유지보수를 위해 어플리케이션을 계층화하여 개발하는 것을 말한다. 대체적으로 중/대규모 어플리케이션에서 사용하고 있다. Pressentation Layer - 사용자와 가장&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;rypro.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://doing7.tistory.com/79&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://doing7.tistory.com/79&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1667355091290&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Domain, Entity, Value(Object)&quot; data-og-description=&quot;Spring 프로젝트 중에 Domain, Entity, VO(value object)라는 용어들이 반복적으로 등장하지만, 정작 이들의 차이를 모르고 있다는 생각이들었다. 이에 관련되어 더 공부하고자 DDD START 도메인 주도 설계(최&quot; data-og-host=&quot;doing7.tistory.com&quot; data-og-source-url=&quot;https://doing7.tistory.com/79&quot; data-og-url=&quot;https://doing7.tistory.com/79&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/HjwQo/hyQqKSk0aa/v4AGpHe0faEclAqeBXP1o0/img.png?width=800&amp;amp;height=603&amp;amp;face=0_0_800_603,https://scrap.kakaocdn.net/dn/biuQ0g/hyQpBipcUc/92VPa7FcHyoffuugINTKrK/img.png?width=800&amp;amp;height=603&amp;amp;face=0_0_800_603,https://scrap.kakaocdn.net/dn/OkJqU/hyQqMbxzUc/YbuadbBVYofA3AWkopsec0/img.png?width=1004&amp;amp;height=677&amp;amp;face=0_0_1004_677&quot;&gt;&lt;a href=&quot;https://doing7.tistory.com/79&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://doing7.tistory.com/79&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/HjwQo/hyQqKSk0aa/v4AGpHe0faEclAqeBXP1o0/img.png?width=800&amp;amp;height=603&amp;amp;face=0_0_800_603,https://scrap.kakaocdn.net/dn/biuQ0g/hyQpBipcUc/92VPa7FcHyoffuugINTKrK/img.png?width=800&amp;amp;height=603&amp;amp;face=0_0_800_603,https://scrap.kakaocdn.net/dn/OkJqU/hyQqMbxzUc/YbuadbBVYofA3AWkopsec0/img.png?width=1004&amp;amp;height=677&amp;amp;face=0_0_1004_677');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Domain, Entity, Value(Object)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Spring 프로젝트 중에 Domain, Entity, VO(value object)라는 용어들이 반복적으로 등장하지만, 정작 이들의 차이를 모르고 있다는 생각이들었다. 이에 관련되어 더 공부하고자 DDD START 도메인 주도 설계(최&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;doing7.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@gidskql6671/DTO-VO-Entity&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://velog.io/@gidskql6671/DTO-VO-Entity&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1667436541931&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;DTO, VO, Entity&quot; data-og-description=&quot;데이터를 다루기 위해 사용되는 개념들인 DTO, VO, Entity에 대해 정리하려고 한다.&quot; data-og-host=&quot;velog.io&quot; data-og-source-url=&quot;https://velog.io/@gidskql6671/DTO-VO-Entity&quot; data-og-url=&quot;https://velog.io/@gidskql6671/DTO-VO-Entity&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bIQZvv/hyQr7TJG7z/wTJr7j9pdVvF0EcdhATkUK/img.png?width=950&amp;amp;height=500&amp;amp;face=0_0_950_500,https://scrap.kakaocdn.net/dn/co0QYM/hyQqZiIRKb/pNV3CWrPZckvpoVxBdf4g0/img.jpg?width=460&amp;amp;height=460&amp;amp;face=0_0_460_460&quot;&gt;&lt;a href=&quot;https://velog.io/@gidskql6671/DTO-VO-Entity&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://velog.io/@gidskql6671/DTO-VO-Entity&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bIQZvv/hyQr7TJG7z/wTJr7j9pdVvF0EcdhATkUK/img.png?width=950&amp;amp;height=500&amp;amp;face=0_0_950_500,https://scrap.kakaocdn.net/dn/co0QYM/hyQqZiIRKb/pNV3CWrPZckvpoVxBdf4g0/img.jpg?width=460&amp;amp;height=460&amp;amp;face=0_0_460_460');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;DTO, VO, Entity&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;데이터를 다루기 위해 사용되는 개념들인 DTO, VO, Entity에 대해 정리하려고 한다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;velog.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Java</category>
      <category>DAO DTO 차이</category>
      <category>Entity VO 차이</category>
      <category>JPA DAO Repository</category>
      <category>MyBatis JPA 차이</category>
      <category>orm</category>
      <category>Spring Entity Domain</category>
      <category>Spring Layered Architecture</category>
      <category>Spring MVC 패턴</category>
      <category>Spring VO Entity</category>
      <category>SQL MAPPER</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/120</guid>
      <comments>https://co-no.tistory.com/entry/Java-Spring-%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC%EC%97%90%EC%84%9C%EC%9D%98-MVC-%ED%8C%A8%ED%84%B4%EA%B3%BC-Service-DAO-DTO-VO-%EA%B0%9C%EB%85%90#entry120comment</comments>
      <pubDate>Thu, 3 Nov 2022 11:14:54 +0900</pubDate>
    </item>
    <item>
      <title>[Java] Spring Boot에서 H2 데이터베이스 설치 및 테스트 작동 확인하기</title>
      <link>https://co-no.tistory.com/entry/Java-H2-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%EC%84%A4%EC%B9%98-%EB%B0%8F-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%9E%91%EB%8F%99-%ED%99%95%EC%9D%B8%ED%95%98%EA%B8%B0</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1. H2 데이터베이스 설치&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.h2database.com/html/main.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.h2database.com/html/main.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1666577267451&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;H2 Database Engine&quot; data-og-description=&quot;H2 Database Engine Welcome to H2, the Java SQL database. The main features of H2 are: Very fast, open source, JDBC API Embedded and server modes; in-memory databases Browser based Console application Small footprint: around 2.5 MB jar file size &amp;nbsp;&amp;nbsp;&amp;nbsp; Supp&quot; data-og-host=&quot;www.h2database.com&quot; data-og-source-url=&quot;https://www.h2database.com/html/main.html&quot; data-og-url=&quot;https://www.h2database.com/html/main.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.h2database.com/html/main.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.h2database.com/html/main.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;H2 Database Engine&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;H2 Database Engine Welcome to H2, the Java SQL database. The main features of H2 are: Very fast, open source, JDBC API Embedded and server modes; in-memory databases Browser based Console application Small footprint: around 2.5 MB jar file size &amp;nbsp;&amp;nbsp;&amp;nbsp; Supp&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.h2database.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 링크에서 OS에 맞는 버전을 설치하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;864&quot; data-origin-height=&quot;539&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bd8ze7/btrPoy7ydVk/GYgSO2scEpiFUmKAkIrjF0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bd8ze7/btrPoy7ydVk/GYgSO2scEpiFUmKAkIrjF0/img.png&quot; data-alt=&quot;H2 설치 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bd8ze7/btrPoy7ydVk/GYgSO2scEpiFUmKAkIrjF0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbd8ze7%2FbtrPoy7ydVk%2FGYgSO2scEpiFUmKAkIrjF0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;537&quot; height=&quot;335&quot; data-origin-width=&quot;864&quot; data-origin-height=&quot;539&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;H2 설치 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;H2를 실행하려면 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;H2가 설치되는 디렉토리를 반드시 기억해야 한다!&lt;/b&gt;&lt;/span&gt; 설치되기 전에 설치되는 디렉토리를 꼭 확인하자!&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2. H2 데이터베이스 실행하기&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;525&quot; data-origin-height=&quot;246&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHP1ZZ/btrPjl9leTd/vP4F58INung8x8Ku8LhQAk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHP1ZZ/btrPjl9leTd/vP4F58INung8x8Ku8LhQAk/img.png&quot; data-alt=&quot;H2의 디렉토리에서 'bin' 으로 이동 후 H2 실행&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHP1ZZ/btrPjl9leTd/vP4F58INung8x8Ku8LhQAk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHP1ZZ%2FbtrPjl9leTd%2FvP4F58INung8x8Ku8LhQAk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;525&quot; height=&quot;246&quot; data-origin-width=&quot;525&quot; data-origin-height=&quot;246&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;H2의 디렉토리에서 'bin' 으로 이동 후 H2 실행&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 OS가 &lt;b&gt;Windows 10&lt;/b&gt; 이므로, Powershell로 &lt;b&gt;H2가 설치된 디렉토리&lt;/b&gt;인 C:\Program Files (x86)\H2 로 이동한 뒤, 'bin' 디렉토리로 이동하여 '&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;h2.bat&lt;/b&gt;&lt;/span&gt;' 프로그램을 실행하였다. 그러면 H2 데이터베이스가 실행되면서, 아래 그림과 같은 H2 콘솔 화면이 뜨게 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1284&quot; data-origin-height=&quot;923&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDi63L/btrPrmlh3v9/3krSjkNlRvgGiykMmUOvKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDi63L/btrPrmlh3v9/3krSjkNlRvgGiykMmUOvKk/img.png&quot; data-alt=&quot;H2 실행한 후, 콘솔 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDi63L/btrPrmlh3v9/3krSjkNlRvgGiykMmUOvKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDi63L%2FbtrPrmlh3v9%2F3krSjkNlRvgGiykMmUOvKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;715&quot; height=&quot;514&quot; data-origin-width=&quot;1284&quot; data-origin-height=&quot;923&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;H2 실행한 후, 콘솔 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3. H2 데이터베이스 파일 만들기(DB 맨 처음 만들 때에만 하는 과정)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1034&quot; data-origin-height=&quot;715&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yNG3e/btrPmDVAr9Q/H4umhGTdwIMVwVK1XtfgV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yNG3e/btrPmDVAr9Q/H4umhGTdwIMVwVK1XtfgV0/img.png&quot; data-alt=&quot;H2 콘솔 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yNG3e/btrPmDVAr9Q/H4umhGTdwIMVwVK1XtfgV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyNG3e%2FbtrPmDVAr9Q%2FH4umhGTdwIMVwVK1XtfgV0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;563&quot; height=&quot;389&quot; data-origin-width=&quot;1034&quot; data-origin-height=&quot;715&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;H2 콘솔 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;H2 데이터베이스를 처음 만들 때에는 반드시 DB 파일을 생성해주어야&lt;/b&gt;&lt;/span&gt; 한다. [JDBC URL] 항목에 해당 DB 파일이 설치될 경로를 입력해주는 데, 이때 양식은 '&lt;b&gt;jdbc:h2:&lt;span style=&quot;color: #409d00;&quot;&gt;{DB 파일이 설치될 경로}&lt;/span&gt;&lt;/b&gt;' 이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 그림에서는 '&lt;b&gt;~/h2_db_testfile&lt;/b&gt;' 이라고 지정하여, &lt;u&gt;홈 디렉토리에 'h2_db_testfile' 이라는 이름으로 H2 데이터베이스 파일을 생성하겠다는 것&lt;/u&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;연결을 누르면 콘솔 창이 아래 그림처럼 이동하면서 DB에 연결된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;728&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LAk96/btrPlGkK9Su/LT0AJVx2BIGKyCkGOfFTKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LAk96/btrPlGkK9Su/LT0AJVx2BIGKyCkGOfFTKK/img.png&quot; data-alt=&quot;H2 DB에 연결된 화면 (H2 콘솔 창)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LAk96/btrPlGkK9Su/LT0AJVx2BIGKyCkGOfFTKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLAk96%2FbtrPlGkK9Su%2FLT0AJVx2BIGKyCkGOfFTKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;728&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;728&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;H2 DB에 연결된 화면 (H2 콘솔 창)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 홈 디렉토리로 이동하면 아래 그림과 같은 지정한 이름으로 &lt;b&gt;파일(&lt;span style=&quot;color: #006dd7;&quot;&gt;.mv 형식&lt;/span&gt;)이 생성된 것을 확인&lt;/b&gt;할 수 있을 것이다!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;141&quot; data-origin-height=&quot;163&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBLyvV/btrPrnR2FYI/kaBpTOmn7NqYrtUzlKYUh0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBLyvV/btrPrnR2FYI/kaBpTOmn7NqYrtUzlKYUh0/img.png&quot; data-alt=&quot;생성된 H2 데이터베이스 파일&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBLyvV/btrPrnR2FYI/kaBpTOmn7NqYrtUzlKYUh0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBLyvV%2FbtrPrnR2FYI%2FkaBpTOmn7NqYrtUzlKYUh0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;141&quot; height=&quot;163&quot; data-origin-width=&quot;141&quot; data-origin-height=&quot;163&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;생성된 H2 데이터베이스 파일&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;4. Spring Boot 프로젝트와 H2 데이터베이스 연동시키기 (application.yml 작성)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;613&quot; data-origin-height=&quot;935&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/50Wcl/btrPgF8rZMT/FEtIplABPnJ1a7hy4LRrtK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/50Wcl/btrPgF8rZMT/FEtIplABPnJ1a7hy4LRrtK/img.png&quot; data-alt=&quot;application.yml 디렉토리 반드시 확인!&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/50Wcl/btrPgF8rZMT/FEtIplABPnJ1a7hy4LRrtK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F50Wcl%2FbtrPgF8rZMT%2FFEtIplABPnJ1a7hy4LRrtK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;424&quot; height=&quot;647&quot; data-origin-width=&quot;613&quot; data-origin-height=&quot;935&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;application.yml 디렉토리 반드시 확인!&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;자 이제 H2 데이터베이스 파일도 생성된 것을 확인했으니, 우리가 작성하는 Spring Boot 프로젝트에서 생성한 DB로 연동하는 것을 해보자!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;우선 프로젝트 폴더 내의 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;[src] - [main] - [resources]&lt;/b&gt; &lt;/span&gt;디렉토리 아래에 '&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;application.yml&lt;/b&gt;&lt;/span&gt;' 파일을 생성해주자!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 디폴트로 '&lt;b&gt;application.properties&lt;/b&gt;' 라는 파일이 있을 텐데, 프로젝트의 설정 파일은 하나만 존재해야 하므로, 본 포스팅에서는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;해당 파일을 삭제하고 'application.yml' 파일로 새로 작성&lt;/b&gt;&lt;/span&gt;하기로 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;application.yml&lt;/b&gt; 파일의 내용은 아래와 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1666579120718&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;spring:
    datasource:
        url: jdbc:h2:tcp://localhost/~/h2_db_testfile;
        username: sa
        password:
        driver-class-name: org.h2.Driver
    
    jpa:
        hibernate:
            ddl-auto: create
        properties:
            hibernate:
                show_sql: true
                format_sql: true
                
logging:
    level:
        org.hibernate.SQL: debug&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 위 코드에서 보이는 &lt;b&gt;들여쓰기는 반드시 4칸&lt;/b&gt;으로 해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드를 하나하나 해석하자면 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;spring.&lt;b&gt;datasource&lt;/b&gt; : DB Connection 정보&lt;/li&gt;
&lt;li&gt;spring.jpa.hibernate.&lt;b&gt;ddl-auto&lt;/b&gt; :&amp;nbsp;&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;none&lt;/b&gt; &lt;/span&gt;: No action is performed. The schema will not be generated.&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;create&lt;/b&gt;&lt;/span&gt; : Create the schema, the data previously present (if there) in the schema is lost&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;create-drop&lt;/b&gt;&lt;/span&gt; : (default) Create the schema with destroying the data previously present(if there). It also drop the database schema when the SessionFactory is closed.&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;update&lt;/b&gt;&lt;/span&gt; : update the schema with the given values.&lt;br /&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;validate&lt;/b&gt;&lt;/span&gt; : validate the schema. It makes no change in the DB.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;spring.jpa.properties.hibernate.&lt;b&gt;show_sql&lt;/b&gt; : 콘솔에 JPA 실행 쿼리 표시할지 여부 지정&lt;/li&gt;
&lt;li&gt;spring.jpa.properties.hibernate.&lt;b&gt;format_sql&lt;/b&gt; : 실행쿼리를 가독성 있게 표현할지 여부 지정&lt;/li&gt;
&lt;li&gt;logging.level.&lt;b&gt;org.hibernate.SQL&lt;/b&gt; : 로깅 레벨을 지정&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;5. H2 데이터베이스에 잘 연동되었는지 테스트 하는 코드 작성&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;application.yml 작성을 통한 애플리케이션-DB 간 연동 과정을 마쳤으니, 이제 &lt;b&gt;실제로 애플리케이션의 로직이 DB에 잘 반영되는지 테스트&lt;/b&gt;를 해보자!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;5.1. Entity 클래스 생성 - '&lt;span style=&quot;color: #409d00;&quot;&gt;Member&lt;/span&gt;'&amp;nbsp;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트의 &lt;b&gt;[src] - [main] - [java] - [프로젝트 아티팩트]&lt;/b&gt; 디렉토리 아무 곳에 다음과 같은 '&lt;b&gt;Member&lt;/b&gt;' &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;엔티티 클래스&lt;/b&gt;&lt;/span&gt;를 생성해주자.&lt;/p&gt;
&lt;pre id=&quot;code_1666580534735&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import lombok.Getter;
import lombok.Setter;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
@Getter @Setter
public class Member {

    @Id
    @GeneratedValue
    private Long id;

    private String username;
}&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;5.2. Repository 클래스 - '&lt;span style=&quot;color: #409d00;&quot;&gt;MemberRepository&lt;/span&gt;'&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;[src] - [main] - [java] - [프로젝트 아티팩트]&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;디렉토리 아무 곳에 다음과 같은 '&lt;b&gt;MemberRepository&lt;/b&gt;' 클래스를 생성해주자.&lt;/p&gt;
&lt;pre id=&quot;code_1666580682576&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import org.springframework.stereotype.Repository;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Repository
public class MemberRepository {

    @PersistenceContext
    private EntityManager em;
	
    // H2 DB에 member 엔티티에 해당하는 데이터 생성
    public Long save(Member member) {
        em.persist(member);
        return member.getId();	// member 가 잘 생성되었는지 확인하기 위한 id 컬럼 조회
    }
	
    // 
    public Member find(Long id) {
        return em.find(Member.class, id); // 해당 id 값을 가지는 레코드 조회
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;5.3. 테스트 코드 작성 - '&lt;span style=&quot;color: #409d00;&quot;&gt;MemberRepositoryTest&lt;/span&gt;'&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트 내의 &lt;b&gt;[src] - [test] - [java] - [프로젝트 아티팩트]&lt;/b&gt; 디렉토리 아무 곳에 다음과 같은 '&lt;b&gt;MemberRepositoryTest&lt;/b&gt;' 클래스를 생성해 주자.&lt;/p&gt;
&lt;pre id=&quot;code_1666581057924&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import org.assertj.core.api.Assertions;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;


@RunWith(SpringRunner.class)
@SpringBootTest
public class MemberRepositoryTest {

    @Autowired MemberRepository memberRepository;

    @Test
    @Transactional
    @Rollback(false)	// H2 DB 상에서 직접 확인하기 위해, 테스트 이후에도 DB를 롤백하지 않겠다.
    public void testMember() throws Exception {
        //given
        Member member = new Member();
        member.setUsername(&quot;memberA&quot;);

        //when
        Long savedId = memberRepository.save(member);
        Member findMember = memberRepository.find(savedId);

        //then
        Assertions.assertThat(findMember.getId()).isEqualTo(member.getId());
        Assertions.assertThat(findMember.getUsername()).isEqualTo(member.getUsername());

    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 테스트 코드를 작성한 후, Run 하여 테스트 코드가 정상적으로 작동한다면, 애플리케이션과 H2 DB 간 연동이 잘 되었다는 것을 의미한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;419&quot; data-origin-height=&quot;350&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pz9q9/btrPoxnFygD/KMpHhVfLVtkEqCmcwWzka0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pz9q9/btrPoxnFygD/KMpHhVfLVtkEqCmcwWzka0/img.png&quot; data-alt=&quot;MemberRepositoryTest 테스트 코드 정상 작동&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pz9q9/btrPoxnFygD/KMpHhVfLVtkEqCmcwWzka0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fpz9q9%2FbtrPoxnFygD%2FKMpHhVfLVtkEqCmcwWzka0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;419&quot; height=&quot;350&quot; data-origin-width=&quot;419&quot; data-origin-height=&quot;350&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;MemberRepositoryTest 테스트 코드 정상 작동&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;6. H2 데이터베이스 상에서 쿼리 통한 직접 확인&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;791&quot; data-origin-height=&quot;399&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zdPmu/btrPp3mlF6U/MnNz9AMNHdJFiZtKlJrAl1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zdPmu/btrPp3mlF6U/MnNz9AMNHdJFiZtKlJrAl1/img.png&quot; data-alt=&quot;H2 콘솔 화면 - 생성한 테스트 데이터 조회&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zdPmu/btrPp3mlF6U/MnNz9AMNHdJFiZtKlJrAl1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzdPmu%2FbtrPp3mlF6U%2FMnNz9AMNHdJFiZtKlJrAl1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;696&quot; height=&quot;351&quot; data-origin-width=&quot;791&quot; data-origin-height=&quot;399&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;H2 콘솔 화면 - 생성한 테스트 데이터 조회&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;H2 콘솔로 DB에 접속하여, 직접 SELECT 쿼리를 날려서 데이터가 제대로 들어갔는지 확인할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 그림처럼&lt;b&gt; 테스트 코드에서 추가한 레코드가 존재한다면, 애플리케이션과 DB 간 연동이 되었다는 것을 이제 확신할 수 있을 것이다!&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;참고로 위 그림은 MEMBER 도메인에 'city', 'street', 'zipcode' 라는 튜플을 추가하고, 'id' 컬럼을 'member_id'로, 'username' 컬럼을 'name'으로 바꾼 것이다.&lt;/b&gt; &lt;/span&gt;&lt;u&gt;5.1. 과 똑같은 코드를 작성했다면, '&lt;b&gt;id&lt;/b&gt;', '&lt;b&gt;username&lt;/b&gt;' 컬럼이 나타날 것이다.&amp;nbsp;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;인프런&lt;/b&gt; - &lt;b&gt;실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발 (김영한 님 강의)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-JPA-%ED%99%9C%EC%9A%A9-1/unit/24278&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-JPA-%ED%99%9C%EC%9A%A9-1/unit/24278&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1666577114526&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;학습 페이지&quot; data-og-description=&quot;&quot; data-og-host=&quot;www.inflearn.com&quot; data-og-source-url=&quot;https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-JPA-%ED%99%9C%EC%9A%A9-1/unit/24278&quot; data-og-url=&quot;https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-JPA-%ED%99%9C%EC%9A%A9-1/unit/24278&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-JPA-%ED%99%9C%EC%9A%A9-1/unit/24278&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-JPA-%ED%99%9C%EC%9A%A9-1/unit/24278&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;학습 페이지&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inflearn.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-JPA-%ED%99%9C%EC%9A%A9-1/unit/24279&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-JPA-%ED%99%9C%EC%9A%A9-1/unit/24279&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1666577120049&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;학습 페이지&quot; data-og-description=&quot;&quot; data-og-host=&quot;www.inflearn.com&quot; data-og-source-url=&quot;https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-JPA-%ED%99%9C%EC%9A%A9-1/unit/24279&quot; data-og-url=&quot;https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-JPA-%ED%99%9C%EC%9A%A9-1/unit/24279&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-JPA-%ED%99%9C%EC%9A%A9-1/unit/24279&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-JPA-%ED%99%9C%EC%9A%A9-1/unit/24279&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;학습 페이지&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inflearn.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://vkein.tistory.com/entry/JPA-%EC%84%A4%EC%A0%95h2-%EC%83%98%ED%94%8C-applicationyml&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://vkein.tistory.com/entry/JPA-%EC%84%A4%EC%A0%95h2-%EC%83%98%ED%94%8C-applicationyml&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1666579622667&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;JPA 설정(h2) 샘플 (application.yml)&quot; data-og-description=&quot;spring: datasource: url: jdbc:h2:tcp://localhost/~/task_agile_test username: sa password: driver-class-name: org.h2.Driver jpa: database-platform: org.hibernate.dialect.H2Dialect open-in-view: false..&quot; data-og-host=&quot;vkein.tistory.com&quot; data-og-source-url=&quot;https://vkein.tistory.com/entry/JPA-%EC%84%A4%EC%A0%95h2-%EC%83%98%ED%94%8C-applicationyml&quot; data-og-url=&quot;https://vkein.tistory.com/entry/JPA-%EC%84%A4%EC%A0%95h2-%EC%83%98%ED%94%8C-applicationyml&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cHaRJc/hyQhJTZ4Ux/FIShpdXbWc31IebFQdim70/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/rGcPq/hyQhw771sy/buqSUaLDK1Zzt3vd6PHfq0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://vkein.tistory.com/entry/JPA-%EC%84%A4%EC%A0%95h2-%EC%83%98%ED%94%8C-applicationyml&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://vkein.tistory.com/entry/JPA-%EC%84%A4%EC%A0%95h2-%EC%83%98%ED%94%8C-applicationyml&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cHaRJc/hyQhJTZ4Ux/FIShpdXbWc31IebFQdim70/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/rGcPq/hyQhw771sy/buqSUaLDK1Zzt3vd6PHfq0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;JPA 설정(h2) 샘플 (application.yml)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;spring: datasource: url: jdbc:h2:tcp://localhost/~/task_agile_test username: sa password: driver-class-name: org.h2.Driver jpa: database-platform: org.hibernate.dialect.H2Dialect open-in-view: false..&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;vkein.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Java</category>
      <category>H2 application.yml 설정</category>
      <category>H2 IntelliJ 연동</category>
      <category>H2 테스트 코드</category>
      <category>Java H2 테스트</category>
      <category>Spring Boot H2</category>
      <category>Spring H2 연동</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/119</guid>
      <comments>https://co-no.tistory.com/entry/Java-H2-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%EC%84%A4%EC%B9%98-%EB%B0%8F-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%9E%91%EB%8F%99-%ED%99%95%EC%9D%B8%ED%95%98%EA%B8%B0#entry119comment</comments>
      <pubDate>Mon, 24 Oct 2022 13:34:00 +0900</pubDate>
    </item>
    <item>
      <title>[Ansible] 베이그런트(Vagrant)를 통해 Virtualbox 프로비저닝 하기</title>
      <link>https://co-no.tistory.com/entry/Ansible-%EB%B2%A0%EC%9D%B4%EA%B7%B8%EB%9F%B0%ED%8A%B8Vagrant%EB%A5%BC-%ED%86%B5%ED%95%B4-Virtualbox-%ED%94%84%EB%A1%9C%EB%B9%84%EC%A0%80%EB%8B%9D-%ED%95%98%EA%B8%B0</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;0. 베이그런트(Vagrant) 란?&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;포터블 가상화 소프트웨어 개발환경(Virtualbox, Hyper-X, Docker container, VMware, AWS 등)의 생성 및 유지보수를 위한 오픈 소스 소프트웨어&lt;/b&gt;&lt;/span&gt; 제품의 하나. '&lt;b&gt;HashiCorp&lt;/b&gt;' 회사의 제품이다. (베이그런트의 default 설치 디렉토리가 &lt;b&gt;C:\HashiCorp\Vagrant\&lt;/b&gt; 이므로 참고하자!)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;베이그런트 파일은 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;Ruby 로 작성되어&lt;/b&gt;&lt;/span&gt; 있으나, &lt;b&gt;PHP&lt;/b&gt;, &lt;b&gt;Python&lt;/b&gt;, &lt;b&gt;Java&lt;/b&gt;, &lt;b&gt;C#&lt;/b&gt;,&lt;b&gt; JS&lt;/b&gt; 와 같은 다른 프로그래밍 언어들로 작성된 프로젝트에서도 사용할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;※&lt;/b&gt; &lt;span style=&quot;background-color: #99cefa;&quot;&gt;&lt;b&gt;프로비저닝(Provisioning)&lt;/b&gt;&lt;/span&gt; : &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;사용자의 요구에 맞게 시스템 자원을 할당, 배치, 배포해 두었다가 필요시 시스템을 즉시 사용할 수 있는 상태로 미리 준비해 두는 것&lt;/b&gt;&lt;/span&gt;을 말한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;서버&lt;/b&gt; 리소스 프로비저닝,&lt;b&gt; OS&lt;/b&gt; 프로비저닝, &lt;b&gt;소프트웨어&lt;/b&gt; 프로비저닝, &lt;b&gt;스토리지&lt;/b&gt; 프로비저닝,&lt;b&gt; 계정&lt;/b&gt; 프로비저닝 등이 있으며, 이를 수동으로 처리하는 '&lt;b&gt;수동 프로비저닝&lt;/b&gt;'과 자동화 툴을 통해 처리하는 '&lt;b&gt;자동 프로비저닝&lt;/b&gt;'으로 나뉜다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Vagrant의 기초 명령어&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;vagrant &lt;span style=&quot;color: #006dd7;&quot;&gt;init&lt;/span&gt;&lt;/b&gt; &lt;br /&gt;: 프로비저닝을 해주는 예제 스크립트 생성&lt;/li&gt;
&lt;li&gt;&lt;b&gt;vagrant &lt;span style=&quot;color: #006dd7;&quot;&gt;up&lt;/span&gt;&lt;/b&gt; &lt;br /&gt;: Vagrant 파일을 읽어들여 프로비저닝을 진행&lt;/li&gt;
&lt;li&gt;&lt;b&gt;vagrant &lt;span style=&quot;color: #006dd7;&quot;&gt;halt&lt;/span&gt;&lt;/b&gt; &lt;br /&gt;: 베이그런트에서 다루는 host 들을 종료&lt;/li&gt;
&lt;li&gt;&lt;b&gt;vagrant &lt;span style=&quot;color: #006dd7;&quot;&gt;destroy&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;: 베이그런트의 host 들을 삭제&lt;/li&gt;
&lt;li&gt;&lt;b&gt;vagrant &lt;span style=&quot;color: #006dd7;&quot;&gt;ssh&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;: 베이그런트의 host 에 ssh 로 접속&lt;/li&gt;
&lt;li&gt;&lt;b&gt;vagrant &lt;span style=&quot;color: #006dd7;&quot;&gt;provision&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;: 베이그런트의 host 의 설정 변경 적용&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1. &lt;span style=&quot;color: #006dd7;&quot;&gt;notepad++&lt;/span&gt; 설치&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;노트패드란++&lt;/b&gt; 란?&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;문서 편집기이자, 소스 코드 편집기&lt;/b&gt;&lt;/span&gt;이다. Windows 에서 기본으로 제공하는 문서 편집기인 메모장에 견주어, notepad++ 는 탭 편집을 제공하므로 여러 개의 파일을 동시에 열어서 편집할 수 있다. 50개 이상의 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;프로그래밍, 스크립트, 마크업 언어에 대한 문법 강조 및 코드 접기를 지원&lt;/b&gt;&lt;/span&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;다른 문서 편집기가 편하다면 다른 걸 설치해도 상관 없다!&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;notepad++ 설치 링크&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://notepad-plus.en.softonic.com/download?utm_source=SEM&amp;amp;utm_medium=paid&amp;amp;utm_campaign=EN_UK_DSA&amp;amp;gclid=Cj0KCQjwy5maBhDdARIsAMxrkw2axoWUjmN-spAxl4-4mFVV3PpYu8T4pkKupFQJXXt5pGcZw874D4oaAp9ZEALw_wcB&quot;&gt;https://notepad-plus.en.softonic.com/download?utm_source=SEM&amp;amp;utm_medium=paid&amp;amp;utm_campaign=EN_UK_DSA&amp;amp;gclid=Cj0KCQjwy5maBhDdARIsAMxrkw2axoWUjmN-spAxl4-4mFVV3PpYu8T4pkKupFQJXXt5pGcZw874D4oaAp9ZEALw_wcB&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1665562726908&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Notepad++&quot; data-og-description=&quot;Free open-source text &amp;amp; code editor&quot; data-og-host=&quot;notepad-plus.en.softonic.com&quot; data-og-source-url=&quot;https://notepad-plus.en.softonic.com/download?utm_source=SEM&amp;amp;utm_medium=paid&amp;amp;utm_campaign=EN_UK_DSA&amp;amp;gclid=Cj0KCQjwy5maBhDdARIsAMxrkw2axoWUjmN-spAxl4-4mFVV3PpYu8T4pkKupFQJXXt5pGcZw874D4oaAp9ZEALw_wcB&quot; data-og-url=&quot;https://notepad-plus.en.softonic.com&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/pNmX5/hyP73rwAuj/e0MhCWUWK0F4wilemLWHaK/img.png?width=64&amp;amp;height=64&amp;amp;face=0_0_64_64&quot;&gt;&lt;a href=&quot;https://notepad-plus.en.softonic.com/download?utm_source=SEM&amp;amp;utm_medium=paid&amp;amp;utm_campaign=EN_UK_DSA&amp;amp;gclid=Cj0KCQjwy5maBhDdARIsAMxrkw2axoWUjmN-spAxl4-4mFVV3PpYu8T4pkKupFQJXXt5pGcZw874D4oaAp9ZEALw_wcB&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://notepad-plus.en.softonic.com/download?utm_source=SEM&amp;amp;utm_medium=paid&amp;amp;utm_campaign=EN_UK_DSA&amp;amp;gclid=Cj0KCQjwy5maBhDdARIsAMxrkw2axoWUjmN-spAxl4-4mFVV3PpYu8T4pkKupFQJXXt5pGcZw874D4oaAp9ZEALw_wcB&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/pNmX5/hyP73rwAuj/e0MhCWUWK0F4wilemLWHaK/img.png?width=64&amp;amp;height=64&amp;amp;face=0_0_64_64');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Notepad++&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Free open-source text &amp;amp; code editor&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;notepad-plus.en.softonic.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2. 베이그런트 &lt;span style=&quot;color: #006dd7;&quot;&gt;설치 및 초기화&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2.1. 베이그런트 설치&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Vagrant 설치 링크&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.vagrantup.com/downloads&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.vagrantup.com/downloads&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1665563119781&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Vagrant by HashiCorp&quot; data-og-description=&quot;Vagrant enables users to create and configure lightweight, reproducible, and portable development environments.&quot; data-og-host=&quot;www.vagrantup.com&quot; data-og-source-url=&quot;https://www.vagrantup.com/downloads&quot; data-og-url=&quot;https://www.vagrantup.com/downloads&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.vagrantup.com/downloads&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.vagrantup.com/downloads&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Vagrant by HashiCorp&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Vagrant enables users to create and configure lightweight, reproducible, and portable development environments.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.vagrantup.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 링크를 통해 베이그런트를 설치한 후, &lt;b&gt;정상적으로 설치되었는지 확인&lt;/b&gt;하기 위해, &lt;b&gt;cmd&lt;/b&gt; 창을 열어서&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt; 'vagrant' 를 입력&lt;/b&gt;&lt;/span&gt;하면 아래와 같이 나타나게 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1090&quot; data-origin-height=&quot;885&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4GdVe/btrOtI30paM/KoGwS6sRmMf2XoOGdEILW0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4GdVe/btrOtI30paM/KoGwS6sRmMf2XoOGdEILW0/img.png&quot; data-alt=&quot;Vagrant 정상 설치 이후 cmd&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4GdVe/btrOtI30paM/KoGwS6sRmMf2XoOGdEILW0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4GdVe%2FbtrOtI30paM%2FKoGwS6sRmMf2XoOGdEILW0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;695&quot; height=&quot;564&quot; data-origin-width=&quot;1090&quot; data-origin-height=&quot;885&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Vagrant 정상 설치 이후 cmd&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2.2. 베이그런트 초기화&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;546&quot; data-origin-height=&quot;147&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/myHTa/btrOscqYHfH/km23QKCGVhBAGulPOQiuzK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/myHTa/btrOscqYHfH/km23QKCGVhBAGulPOQiuzK/img.png&quot; data-alt=&quot;[vagrant 설치 디렉토리 이동] - [베이그런트 초기화]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/myHTa/btrOscqYHfH/km23QKCGVhBAGulPOQiuzK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmyHTa%2FbtrOscqYHfH%2Fkm23QKCGVhBAGulPOQiuzK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;546&quot; height=&quot;147&quot; data-origin-width=&quot;546&quot; data-origin-height=&quot;147&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[vagrant 설치 디렉토리 이동] - [베이그런트 초기화]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;'vagrant init' 명령어&lt;/b&gt;&lt;/span&gt;를 통해 &lt;b&gt;C:\HashiCorp&lt;/b&gt; 디렉토리에 &lt;b&gt;'Vagrantfile' 이라는 샘플 코드&lt;/b&gt;를 만들게 되는데, 이 샘플 코드를 수정하여 앞으로의 베이그런트 원하는 동작을 수행하게 될 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;899&quot; data-origin-height=&quot;1044&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/17cjH/btrOtF0uYtd/sRa86csXK06Qh0cl2y70r0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/17cjH/btrOtF0uYtd/sRa86csXK06Qh0cl2y70r0/img.png&quot; data-alt=&quot;'Vagrantfile' 샘플 코드&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/17cjH/btrOtF0uYtd/sRa86csXK06Qh0cl2y70r0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F17cjH%2FbtrOtF0uYtd%2FsRa86csXK06Qh0cl2y70r0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;614&quot; height=&quot;713&quot; data-origin-width=&quot;899&quot; data-origin-height=&quot;1044&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;'Vagrantfile' 샘플 코드&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3. 베이그런트 &lt;span style=&quot;color: #006dd7;&quot;&gt;파일 수정&lt;/span&gt; 및 &lt;span style=&quot;color: #006dd7;&quot;&gt;플러그인 설치&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3.1. 'Vagrantfile' 수정&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;724&quot; data-origin-height=&quot;325&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZJMft/btrOqFOHuJ1/qNdO2PmXJIJsAR53fXUca0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZJMft/btrOqFOHuJ1/qNdO2PmXJIJsAR53fXUca0/img.png&quot; data-alt=&quot;[config.vm.box] 수정하기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZJMft/btrOqFOHuJ1/qNdO2PmXJIJsAR53fXUca0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZJMft%2FbtrOqFOHuJ1%2FqNdO2PmXJIJsAR53fXUca0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;724&quot; height=&quot;325&quot; data-origin-width=&quot;724&quot; data-origin-height=&quot;325&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[config.vm.box] 수정하기&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;15번째 줄에 보면 '&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;config.vm.box&lt;/b&gt;&lt;/span&gt;' 라는 부분의 값이 &quot;&lt;b&gt;base&lt;/b&gt;&quot;로 되어 있는데, 이 값을 수정하여 Virtualbox 의 VM 이미지의 OS를 지정할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리가 하려고 하는 CentOS 설정 방법은 위 코드 14번째 줄에 '&lt;b&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;https://vagrantcloud.com/search&lt;/span&gt;&lt;/b&gt;' 에서 찾을 수 있다!&lt;/p&gt;
&lt;pre id=&quot;code_1665633791000&quot; class=&quot;ruby&quot; data-ke-language=&quot;ruby&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Vagrant.configure(&quot;2&quot;) do |config|
  config.vm.box = &quot;centos/7&quot;
end&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CentOS로 설정하는 법은 위와 같으므로, 아래 그림처럼 코드를 수정해준다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;706&quot; data-origin-height=&quot;328&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oDuw7/btrOtGMetBe/yFI7c6VBjRTcCVBuah7uwk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oDuw7/btrOtGMetBe/yFI7c6VBjRTcCVBuah7uwk/img.png&quot; data-alt=&quot;[config.vm.box] 값 수정 완료 후&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oDuw7/btrOtGMetBe/yFI7c6VBjRTcCVBuah7uwk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoDuw7%2FbtrOtGMetBe%2FyFI7c6VBjRTcCVBuah7uwk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;633&quot; height=&quot;294&quot; data-origin-width=&quot;706&quot; data-origin-height=&quot;328&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[config.vm.box] 값 수정 완료 후&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3.2. 베이그런트 플러그인 설치 - Virtualbox 확장팩 위함&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Virtualbox 의 경우, 각각의 VM들의 모든 기능을 사용하기 위해서는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;Virtualbox 확장팩이 필수적&lt;/b&gt;&lt;/span&gt;이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;베이그런트에서는 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;Virtualbox 확장팩을 설치할 수 있도록 하는 명령어&lt;/b&gt;&lt;/span&gt;를 자체 제공하는데, 이는 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1665634346699&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;vagrant plugin install vagrant-vbguest&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;576&quot; data-origin-height=&quot;98&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cewiB4/btrOs2hLSTR/zpAUnPHKCV6kkqkKfKGkZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cewiB4/btrOs2hLSTR/zpAUnPHKCV6kkqkKfKGkZk/img.png&quot; data-alt=&quot;베이그런트를 통한 Virtualbox 확장팩 설치 명령어 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cewiB4/btrOs2hLSTR/zpAUnPHKCV6kkqkKfKGkZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcewiB4%2FbtrOs2hLSTR%2FzpAUnPHKCV6kkqkKfKGkZk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;576&quot; height=&quot;98&quot; data-origin-width=&quot;576&quot; data-origin-height=&quot;98&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;베이그런트를 통한 Virtualbox 확장팩 설치 명령어 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;4. 프로비저닝한 &lt;span style=&quot;color: #006dd7;&quot;&gt;CentOS 이미지를 Virtualbox 에 설치&lt;/span&gt;하기&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1665643966922&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 아직 VM을 생성하지 않았다면,
vagrant up

# VM을 생성했으나, 중간에 멈추거나 에러가 나와서 다시 가동시키려고 한다면,
vagrant reload&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 3.2에서 설치한 Virtualbox 확장팩 버전에 문제가 있는지, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;아래와 같은 에러&lt;/b&gt;&lt;/span&gt;를 뿜으며 VM 생성이 제대로 되지 않았었다.&lt;/p&gt;
&lt;pre id=&quot;code_1665644054472&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Error: Nothing to do
Unmounting Virtualbox Guest Additions ISO from: /mnt
umount: /mnt: not mounted
==&amp;gt; servernfs: Checking for guest additions in VM...
    servernfs: No guest additions were detected on the base box for this VM! Guest
    servernfs: additions are required for forwarded ports, shared folders, host only
    servernfs: networking, and more. If SSH fails on this machine, please install
    servernfs: the guest additions and repackage the box to continue.
    servernfs:
    servernfs: This is not an error message; everything may continue to work properly,
    servernfs: in which case you may ignore this message.
The following SSH command responded with a non-zero exit status.
Vagrant assumes that this means the command failed!

umount /mnt

Stdout from the command:



Stderr from the command:

umount: /mnt: not mounted&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.devopsroles.com/vagrant-no-virtualbox-guest-additions-installation-found-fixed/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.devopsroles.com/vagrant-no-virtualbox-guest-additions-installation-found-fixed/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1665644066956&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Vagrant No VirtualBox Guest Additions installation found [Fixed] - DevopsRoles.com free 1&quot; data-og-description=&quot;How to fix the error Vagrant No VirtualBox Guest Additions installation found....&quot; data-og-host=&quot;www.devopsroles.com&quot; data-og-source-url=&quot;https://www.devopsroles.com/vagrant-no-virtualbox-guest-additions-installation-found-fixed/&quot; data-og-url=&quot;https://www.devopsroles.com/vagrant-no-virtualbox-guest-additions-installation-found-fixed/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b9kDso/hyP73zaFTC/kEGQshTzdo9Cy7YjMk01N0/img.png?width=640&amp;amp;height=405&amp;amp;face=0_0_640_405,https://scrap.kakaocdn.net/dn/f1Jzx/hyP8cCS92h/0pxdnyRhnDeQDI8o74XlF1/img.png?width=640&amp;amp;height=405&amp;amp;face=0_0_640_405,https://scrap.kakaocdn.net/dn/cNzmWc/hyP9iO1GeC/PAOkoO88FLjKlzoJbevgAk/img.png?width=640&amp;amp;height=405&amp;amp;face=0_0_640_405&quot;&gt;&lt;a href=&quot;https://www.devopsroles.com/vagrant-no-virtualbox-guest-additions-installation-found-fixed/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.devopsroles.com/vagrant-no-virtualbox-guest-additions-installation-found-fixed/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b9kDso/hyP73zaFTC/kEGQshTzdo9Cy7YjMk01N0/img.png?width=640&amp;amp;height=405&amp;amp;face=0_0_640_405,https://scrap.kakaocdn.net/dn/f1Jzx/hyP8cCS92h/0pxdnyRhnDeQDI8o74XlF1/img.png?width=640&amp;amp;height=405&amp;amp;face=0_0_640_405,https://scrap.kakaocdn.net/dn/cNzmWc/hyP9iO1GeC/PAOkoO88FLjKlzoJbevgAk/img.png?width=640&amp;amp;height=405&amp;amp;face=0_0_640_405');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Vagrant No VirtualBox Guest Additions installation found [Fixed] - DevopsRoles.com free 1&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;How to fix the error Vagrant No VirtualBox Guest Additions installation found....&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.devopsroles.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구글링해본 결과 위 링크의 게시글을 발견했는데, &lt;b&gt;Virtualbox 확장팩의 버전을 '&lt;span style=&quot;color: #006dd7;&quot;&gt;0.21&lt;/span&gt;' 로 재설치&lt;/b&gt;하면 된다고 하여 시도해봤더니, 베이그런트를 통한 Virtualbox에 CentOS 이미지 설치가 잘 되었다! 재설치 명령어는 아래와 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1665644200148&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 기존의 Virtualbox 확장팩 삭제
vagrant plugin uninstall vagarnt-vbguest

# '0.21' 버전의 Virtualbox 확장팩 설치
vagrant plugin install vagrant-vbguest --plugin-version 0.21

# 확장팩 재설치후, vagrant 다시 프로비저닝
vagrant reload&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;5. &lt;span style=&quot;color: #006dd7;&quot;&gt;베이그런트 ssh로 접속&lt;/span&gt;하여 상태 확인&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;vagrant ssh&lt;/b&gt;&lt;/span&gt;' 명령어를 입력하여 생성한 VM에 접속하면 아래와 같이 성공한 것을 볼 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;420&quot; data-origin-height=&quot;77&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FbyGZ/btrOvgAQ8x9/JLjs2ws1chckd01wqb9Kzk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FbyGZ/btrOvgAQ8x9/JLjs2ws1chckd01wqb9Kzk/img.png&quot; data-alt=&quot;vagrant ssh 접속 성공 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FbyGZ/btrOvgAQ8x9/JLjs2ws1chckd01wqb9Kzk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFbyGZ%2FbtrOvgAQ8x9%2FJLjs2ws1chckd01wqb9Kzk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;420&quot; height=&quot;77&quot; data-origin-width=&quot;420&quot; data-origin-height=&quot;77&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;vagrant ssh 접속 성공 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;인프런&lt;/b&gt; 강의 - &lt;b&gt;[기초-응용] 다양한 환경을 앤서블(Ansible)로 관리하기 with 베이그런트(Vagrant) (&lt;span style=&quot;color: #409d00;&quot;&gt;조훈&lt;/span&gt; 님 강의)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/ansible-%EC%9D%91%EC%9A%A9/unit/10185&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.inflearn.com/course/ansible-%EC%9D%91%EC%9A%A9/unit/10185&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1665563773762&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;학습 페이지&quot; data-og-description=&quot;&quot; data-og-host=&quot;www.inflearn.com&quot; data-og-source-url=&quot;https://www.inflearn.com/course/ansible-%EC%9D%91%EC%9A%A9/unit/10185&quot; data-og-url=&quot;https://www.inflearn.com/course/ansible-%EC%9D%91%EC%9A%A9/unit/10185&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/ansible-%EC%9D%91%EC%9A%A9/unit/10185&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inflearn.com/course/ansible-%EC%9D%91%EC%9A%A9/unit/10185&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;학습 페이지&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inflearn.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DevOps/Ansible</category>
      <category>vagrant</category>
      <category>vagrant centos</category>
      <category>vagrant provisioning</category>
      <category>vagrant virtualbox</category>
      <category>vagrant virtualbox guest additions</category>
      <category>vagrant 프로비저닝</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/118</guid>
      <comments>https://co-no.tistory.com/entry/Ansible-%EB%B2%A0%EC%9D%B4%EA%B7%B8%EB%9F%B0%ED%8A%B8Vagrant%EB%A5%BC-%ED%86%B5%ED%95%B4-Virtualbox-%ED%94%84%EB%A1%9C%EB%B9%84%EC%A0%80%EB%8B%9D-%ED%95%98%EA%B8%B0#entry118comment</comments>
      <pubDate>Thu, 13 Oct 2022 16:34:20 +0900</pubDate>
    </item>
    <item>
      <title>[Git] 브랜치(branch) 전략 - git-flow 방식 / github-flow 방식 / git-lab 방식</title>
      <link>https://co-no.tistory.com/entry/Git-%EB%B8%8C%EB%9E%9C%EC%B9%98branch-%EC%A0%84%EB%9E%B5-git-flow-%EB%B0%A9%EC%8B%9D-github-flow-%EB%B0%A9%EC%8B%9D-git-lab-%EB%B0%A9%EC%8B%9D</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1. &lt;span style=&quot;color: #006dd7;&quot;&gt;브랜치(branch)&lt;/span&gt; 란?&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;브랜치(branch)&lt;/b&gt; : &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;독립적으로 어떤 작업을 진행하기 위한 개념.&lt;/b&gt;&lt;/span&gt; 필요에 의해 만들어지는 각각의 브랜치는 다른 브랜치의 영향을 받지 않으므로, &lt;b&gt;여러 작업을 동시에 진행할 수 있도록 해주는 개념&lt;/b&gt;이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;567&quot; data-origin-height=&quot;346&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byUl0n/btrNY0Lyuf3/kGqMcCsubkTy6ym9JfhcX1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byUl0n/btrNY0Lyuf3/kGqMcCsubkTy6ym9JfhcX1/img.png&quot; data-alt=&quot;브랜치 개념 / 출처 : backlog.com/git-tutorial/kr/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byUl0n/btrNY0Lyuf3/kGqMcCsubkTy6ym9JfhcX1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbyUl0n%2FbtrNY0Lyuf3%2FkGqMcCsubkTy6ym9JfhcX1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;430&quot; height=&quot;262&quot; data-origin-width=&quot;567&quot; data-origin-height=&quot;346&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;브랜치 개념 / 출처 : backlog.com/git-tutorial/kr/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;브랜치의 기본적인 메커니즘은 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 명이서 동시에 작업을 할 때, 다른 사람의 작업에 영향을 주거나 받지 않도록, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;메인 브랜치(master)에서 각자의 작업 전용 브랜치를 만든다.&lt;/b&gt;&lt;/span&gt; 그리고 &lt;b&gt;각자 작업을 진행한 후, 작업이 끝난 사람은 메인 브랜치에 자신의 브랜치의 변경 사항을 적용&lt;/b&gt;함으로써, 다른 사람의 작업에 영향을 받지 않고 독립적으로 특정 작업을 수행하여 그 결과를 하나로 모아 나가게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나의 '&lt;b&gt;작업 단위&lt;/b&gt;'인 브랜치를 통해 작업하는 &lt;u&gt;중간 중간에 기록을 남기게 되므로, 작업 중간에 발생하는 문제의 원인을 찾아 대첵을 세우기 수월해진다.&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;601&quot; data-origin-height=&quot;466&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dvvFrp/btrNZoFoT0s/stKmEOJqkmDsKDrfzOUGMk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dvvFrp/btrNZoFoT0s/stKmEOJqkmDsKDrfzOUGMk/img.png&quot; data-alt=&quot;브랜치의 개념(2) / 초록색=메인브랜치 / 출처 : backlog.com/git-tutorial/kr&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dvvFrp/btrNZoFoT0s/stKmEOJqkmDsKDrfzOUGMk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdvvFrp%2FbtrNZoFoT0s%2FstKmEOJqkmDsKDrfzOUGMk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;463&quot; height=&quot;359&quot; data-origin-width=&quot;601&quot; data-origin-height=&quot;466&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;브랜치의 개념(2) / 초록색=메인브랜치 / 출처 : backlog.com/git-tutorial/kr&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2. &lt;span style=&quot;color: #006dd7;&quot;&gt;origin/master&lt;/span&gt; 브랜치와 &lt;span style=&quot;color: #006dd7;&quot;&gt;master&lt;/span&gt; 브랜치&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;git을 사용하다 보면, '&lt;b&gt;origin/master&lt;/b&gt;' 와 '&lt;b&gt;master&lt;/b&gt;' 라는 용어를 보게 될텐데, 처음 보면 도대체 무슨 말인지 알 수 없을 때가 있다. 간단히 말하면, '&lt;b&gt;origin/master&lt;/b&gt;'는 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;원격 저장소의 master 브랜치&lt;/b&gt;&lt;/span&gt;를 말하고, '&lt;b&gt;master&lt;/b&gt;'는 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;로컬 저장소의 메인 브랜치(master 브랜치)&lt;/b&gt;&lt;/span&gt; 를 말한다. 대부분 원격 저장소의 master 브랜치(origin/master)는 소스코드의 배포 직전 최종본이므로, 가장 최신 기능과 안정적인 버전인 상태로 두고, 로컬 저장소에 이 원격 저장소의 소스코드를 불러와 수정 작업을 진행하게 된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;그렇다면 &lt;u&gt;현재 내가 어떤 브랜치에서 작업을 하고 있는지 확인을 해야&lt;/u&gt; 되는데, 이것이 바로&amp;nbsp; '&lt;b&gt;HEAD&lt;/b&gt;'라는 개념이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;git 에서 HEAD는 특정 브랜치의 마지막 커밋에 대한 포인터이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;447&quot; data-origin-height=&quot;150&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjCoZh/btrNXUSXffV/HZzOQ89XKwR2QPqnMqWN40/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjCoZh/btrNXUSXffV/HZzOQ89XKwR2QPqnMqWN40/img.png&quot; data-alt=&quot;HEAD 개념(1) / 출처 : soy3on.tistory.com/152&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjCoZh/btrNXUSXffV/HZzOQ89XKwR2QPqnMqWN40/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjCoZh%2FbtrNXUSXffV%2FHZzOQ89XKwR2QPqnMqWN40%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;447&quot; height=&quot;150&quot; data-origin-width=&quot;447&quot; data-origin-height=&quot;150&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;HEAD 개념(1) / 출처 : soy3on.tistory.com/152&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;위 그림을 보면, 'HEAD'가 '&lt;b&gt;master&lt;/b&gt;' 와 '&lt;b&gt;origin/master&lt;/b&gt;', '&lt;b&gt;origin/HEAD&lt;/b&gt;'를 화살표를 통해 가리키고 있는 것을 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 &lt;b&gt;현재 내가 작업하고 있는 브랜치&lt;/b&gt;가 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;로컬 저장소의 master&lt;/b&gt;&lt;/span&gt;이며, 이 로컬 저장소 master 브랜치의 &lt;b&gt;최종 커밋이 origin/master 브랜치의 최종 커밋과 일치한다는 것을 의미&lt;/b&gt;한다. 즉, &lt;u&gt;원격 저장소의 소스코드 내용과 로컬 저장소의 소스코드 내용이 일치한다는 것&lt;/u&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'&lt;b&gt;origin/&lt;span style=&quot;color: #8a3db6;&quot;&gt;HEAD&lt;/span&gt;&lt;/b&gt;' 에서의 '&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;HEAD&lt;/b&gt;&lt;/span&gt;'는 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;원격 저장소의 현재 작업 위치&lt;/b&gt;&lt;/span&gt;를 나타내므로, 현재 원격 저장소의 작업 위치는 &lt;b&gt;'origin' 브랜치임을 의미&lt;/b&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;참고로 위&lt;span style=&quot;color: #f3c000;&quot;&gt;&lt;b&gt; git log는 아래에서 위로 봐야 시간 순서와 일치한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 내 로컬 저장소에서 '&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;f3.txt&lt;/b&gt;&lt;/span&gt;' 라는 파일을 생성하고, 이를 &lt;b&gt;로컬 저장소의 'master' 브랜치에 커밋하면 어떻게 될까?&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;366&quot; data-origin-height=&quot;165&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yCDy6/btrNZjKZeIE/t09RvBGZaBNZvKdANYD2fK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yCDy6/btrNZjKZeIE/t09RvBGZaBNZvKdANYD2fK/img.png&quot; data-alt=&quot;HEAD 개념(2) / 출처 : soy3on.tistory.com/152&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yCDy6/btrNZjKZeIE/t09RvBGZaBNZvKdANYD2fK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyCDy6%2FbtrNZjKZeIE%2Ft09RvBGZaBNZvKdANYD2fK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;366&quot; height=&quot;165&quot; data-origin-width=&quot;366&quot; data-origin-height=&quot;165&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;HEAD 개념(2) / 출처 : soy3on.tistory.com/152&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;위 그림처럼&lt;u&gt;&lt;b&gt; 'HEAD' 가 'master'만을 가리키는 것&lt;/b&gt;&lt;/u&gt;을 볼 수 있는데, 이는 &lt;b&gt;현재 최종 커밋&lt;/b&gt;이 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;로컬 저장소의 'master' 브랜치&lt;/b&gt;&lt;/span&gt;임을 의미한다. 또한 이는 'f3.txt' 파일을 생성한 후 커밋한 후, &lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;원격 저장소로의 push는 진행하지 않았기 때문에,&lt;/b&gt; &lt;/span&gt;원격 저장소의 메인 브랜치인 &lt;u&gt;'origin/master' 브랜치와는 최종 커밋이 서로 다름을 의미&lt;/u&gt;한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;388&quot; data-origin-height=&quot;94&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/m1BBB/btrNX84wY7x/FBWkENvA9UMz5FvsrCWbRk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/m1BBB/btrNX84wY7x/FBWkENvA9UMz5FvsrCWbRk/img.png&quot; data-alt=&quot;git status / 출처 : soy3on.tistory.com/152&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/m1BBB/btrNX84wY7x/FBWkENvA9UMz5FvsrCWbRk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fm1BBB%2FbtrNX84wY7x%2FFBWkENvA9UMz5FvsrCWbRk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;388&quot; height=&quot;94&quot; data-origin-width=&quot;388&quot; data-origin-height=&quot;94&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;git status / 출처 : soy3on.tistory.com/152&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이 상태에서 위 그림처럼 '&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;git status&lt;/b&gt;&lt;/span&gt;' 명령어의 출력 결과를 확인하면 더 확실히 이해할 수 있다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'&lt;b&gt;On branch master&lt;/b&gt;' : &lt;b&gt;현재 checkout 된(작업하고 있는)&lt;/b&gt; 브랜치가 '&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;master&lt;/b&gt;&lt;/span&gt;' 브랜치이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'&lt;b&gt;Your branch is ahead of 'origin/master' by 1 commit.&lt;/b&gt;' : 현재 당신이 작업하고 있는 브랜치는 &lt;b&gt;'origin/master' 브랜치보다 1커밋 앞선다.&lt;/b&gt; 즉, &lt;b&gt;현재 작업하고 있는 master 브랜치가&lt;/b&gt; 원격 저장소의 'origin/master' 브랜치보다 1 커밋 변경사항이 생겼다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;git status 명령어를 통해 push 하라는 메시지도 받을 수 있으니, &lt;span style=&quot;color: #f3c000;&quot;&gt;&lt;b&gt;현재 내 작업 상황과 원격 저장소의 싱크가 맞는지 궁금하면 git status 를 잘 활용하면 될 것이다!&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3. 브랜치 전략을 세워야 하는 이유&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;브랜치 전략이란?&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;여러 명의 협업자가 Git의 브랜치(branch)를 사용하여 하나의 공동 저장소를 효율적으로 사용하기 위한 전략 (Work-Flow)&lt;/b&gt;&lt;/span&gt;을 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;브랜치 전략을 세우지 않고 그때그때마다 필요한 브랜치를 마구 생성하거나, 또는 하나의 브랜치로만 계속 개발을 하게 된다면&lt;/u&gt;, 체계 없는 브랜치 생성과 병합이 생길 수 있고, 이에 따른 중구난방 흩어진 이슈와 커밋(개발 히스토리) 관리가 되지 않으며, 이는 곧 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;협업의 어려움과 프로젝트의 마감의 연기, 중단&lt;/b&gt;&lt;/span&gt;까지 이어질 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;브랜치 전략 수립의 목표는, 범용적으로 사용되는 '&lt;b&gt;Git-flow&lt;/b&gt;', '&lt;b&gt;Github-flow&lt;/b&gt;', '&lt;b&gt;Gitlab-flow&lt;/b&gt;' 를 참고하여 각 회사 또는 조직마다의 환경 및 제약 조건을 반영한, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;최상의 코드 품질 및 유지 보수성을 목적에 둔 코드 저장 관리 방식&lt;/b&gt;&lt;/span&gt;이 되어야 한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 범용적으로 사용되는 '&lt;b&gt;Git-flow&lt;/b&gt;', '&lt;b&gt;Github-flow&lt;/b&gt;', '&lt;b&gt;Gitlab-flow&lt;/b&gt;' 의 개념에 대해 알아보자!&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;4. 브랜치 전략의 종류&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4.1.&lt;span style=&quot;color: #006dd7;&quot;&gt; Git-flow&lt;/span&gt; 방식&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;597&quot; data-origin-height=&quot;784&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/p7xC5/btrNZkDe3nU/hkgq4rklWVN5nXoWhB4LRK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/p7xC5/btrNZkDe3nU/hkgq4rklWVN5nXoWhB4LRK/img.png&quot; data-alt=&quot;Git-flow 방식의 예시 / 출처 : https://nvie.com/posts/a-successful-git-branching-model/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/p7xC5/btrNZkDe3nU/hkgq4rklWVN5nXoWhB4LRK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fp7xC5%2FbtrNZkDe3nU%2Fhkgq4rklWVN5nXoWhB4LRK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;506&quot; height=&quot;664&quot; data-origin-width=&quot;597&quot; data-origin-height=&quot;784&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Git-flow 방식의 예시 / 출처 : https://nvie.com/posts/a-successful-git-branching-model/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2010년, 'nvie'라는 닉네임을 사용하는 개발자에 의해 알려지기 시작한 방식으로, &lt;u&gt;프로젝트의 규모가 어느정도 있다면, 대부분의 팀들이 채택하는 방식&lt;/u&gt;이다. 그러나 최근에는 Git-flow 방식은 &lt;b&gt;소프트웨어 버전 관리가 필요한 APP&lt;/b&gt;이나 &lt;b&gt;솔루션&lt;/b&gt;, 또는&lt;b&gt; public API&lt;/b&gt;에 적합한 워크플로우라고 보는 시선도 많다. &lt;u&gt;웹 어플리케이션에서 Git-flow는 고려할 전략이 아니라고 본다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;브랜치를 대략 5가지로 구분&lt;/b&gt;&lt;/span&gt;하는데 &lt;b&gt;각 브랜치마다의 기능 및 목적 &lt;/b&gt;은 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;master&lt;/b&gt; : &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;제품 출시&lt;/b&gt;&lt;/span&gt;를 위한 코드&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;develop&lt;/b&gt; : master 브랜치를 최초 base로 둔, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;다음 버전의 개발&lt;/b&gt;&lt;/span&gt;을 위한 코드&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;feature/&lt;span style=&quot;color: #409d00;&quot;&gt;{feature_name}&lt;/span&gt;&lt;/b&gt; : &lt;b&gt;제품의 세부 기능(새로운 기능) 개발&lt;/b&gt;을 위한 코드&lt;br /&gt;- &lt;b&gt;베이스 브랜치&lt;/b&gt; : develop&lt;br /&gt;- &lt;b&gt;merge의 목적지&lt;/b&gt; : develop&lt;br /&gt;- origin 브랜치에는 반영하지 않고, &lt;u&gt;주로 개발자의 repo에만 존재&lt;/u&gt;하는 경우가 많음.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;release&lt;/b&gt; : 어느정도 완성된 develop 브랜치를 최초 base로 둔, &lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;제품 출시 준비(QA 등)&lt;/b&gt;&lt;/span&gt;를 위한 코드&lt;br /&gt;- &lt;b&gt;베이스 브랜치&lt;/b&gt; : develop&lt;br /&gt;- &lt;b&gt;merge의 목적지&lt;/b&gt; : develop, master&lt;br /&gt;- &lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;안정적인 상태의 develop 브랜치에서 release 브랜치를 생성&lt;/b&gt;&lt;/span&gt;한 후, develop 브랜치에서는 다음 버전 배포를 위한 새로운 기능 개발에 주력하도록 만들 수 있게 된다.&amp;nbsp;&lt;br /&gt;- &lt;b&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;release 브랜치에서는 디버그에 대한 부분만 커밋하도록&lt;/span&gt;&lt;/b&gt; 하며, 완전한 deploy에 대한 준비가 완료되었다고 판단되었을 때, master로의 병합을 진행한다.&lt;br /&gt;- merge를 끝낸 후에는, &lt;b&gt;tag 명령&lt;/b&gt;을 통해 배포 버전에 대한 기록을 남기도록 한다.&lt;br /&gt;- release 에서 수정된 커밋들이 master로의 merge 까지 완료되었다면, 이후 새로운 안정적인 develop 브랜치 구성을 위해, develop 브랜치로의 merge를 수행한다.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;hotfix&lt;/b&gt; : master 브랜치를 최초 base로 둔, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;이미 출시된 버전의 버그 수정&lt;/b&gt;&lt;/span&gt;을 위한 코드&lt;br /&gt;-&amp;nbsp;&lt;b&gt;베이스 브랜치&lt;/b&gt; : master&lt;br /&gt;-&amp;nbsp;&lt;b&gt;merge의 목적지&amp;nbsp;&lt;/b&gt;: develop, master&lt;br /&gt;- 배포된 제품(origin/master)에서 버그가 발생했을 경우, &lt;b&gt;신속한 처리를 위한 브랜치&lt;/b&gt;이다. 버그에 대한 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;수정이 완료된 후에는 develop, master에 곧장 반영&lt;/b&gt;&lt;/span&gt;하며, &lt;b&gt;tag&lt;/b&gt;를 통한 관련 정보를 기록해둔다. &lt;b&gt;이후 버그를 해결하면 제거&lt;/b&gt;하는 것이 원칙이다.&amp;nbsp;&lt;br /&gt;-&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt; release 브랜치가 이미 생성되어 관리중인 상태&lt;/b&gt;&lt;/span&gt;라면, &lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;해당 브랜치에 hotfix 정보를 병합&lt;/b&gt;&lt;/span&gt;시켜 다음 deploy 시(master로의 merge), 반영이 정상적으로 이루어질 수 있도록 해야 한다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Git-flow 방식을 &lt;b&gt;운용하는 구조 및 흐름&lt;/b&gt;은 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;가장 많이 사용하는 브랜치(base를 두는)&lt;/b&gt;는 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;master&lt;/b&gt;&lt;/span&gt; 와 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;develop&lt;/b&gt;&lt;/span&gt;이 되며, 정상적인 프로젝트를 진행하기 위해서는 둘 모두를 운용해야 한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;feature, release, hotfix&lt;/b&gt; 브랜치는 사용하지 않는다면 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;지워도 오류가 발생하지 않아야 하며&lt;/b&gt;&lt;/span&gt;, 깔끔한 프로젝트 진행을 원한다면 필요 없어진 것들은 지우고, &lt;b&gt;필요한 상황이 왔을 때에만 따로 만드는 것을 권장&lt;/b&gt;한다.&lt;/li&gt;
&lt;li&gt;&lt;u&gt;대부분의 작업은 develop 브랜치에 취합한다고 생각하면 되고&lt;/u&gt;, QA를 통해 &lt;b&gt;더 이상의 변동사항이 없을 것이라고 판단될 때 master 브랜치로의 병합&lt;/b&gt;을 진행한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;master가 아닌 나머지 브랜치들&lt;/b&gt;은&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt; master의 변동사항을 꾸준히 주시&lt;/b&gt;&lt;/span&gt;해야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4.2. &lt;span style=&quot;color: #006dd7;&quot;&gt;Github-flow&lt;/span&gt; 방식&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;925&quot; data-origin-height=&quot;292&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/csaRBW/btrN0DJnoVu/ffBbd4MJloYPEKp9o6vuqK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/csaRBW/btrN0DJnoVu/ffBbd4MJloYPEKp9o6vuqK/img.png&quot; data-alt=&quot;Github-flow 방식의 프로세스 / 출처 : subicura.com/git/guide/github-flow.html&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/csaRBW/btrN0DJnoVu/ffBbd4MJloYPEKp9o6vuqK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcsaRBW%2FbtrN0DJnoVu%2FffBbd4MJloYPEKp9o6vuqK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;698&quot; height=&quot;220&quot; data-origin-width=&quot;925&quot; data-origin-height=&quot;292&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Github-flow 방식의 프로세스 / 출처 : subicura.com/git/guide/github-flow.html&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;619&quot; data-origin-height=&quot;629&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1mK24/btrNZn77kk4/2ThCkkCf7PdjqWBk9htf2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1mK24/btrNZn77kk4/2ThCkkCf7PdjqWBk9htf2k/img.png&quot; data-alt=&quot;Github-flow 예시 / 출처 : brownbears.tistory.com/603&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1mK24/btrNZn77kk4/2ThCkkCf7PdjqWBk9htf2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1mK24%2FbtrNZn77kk4%2F2ThCkkCf7PdjqWBk9htf2k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;439&quot; height=&quot;446&quot; data-origin-width=&quot;619&quot; data-origin-height=&quot;629&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Github-flow 예시 / 출처 : brownbears.tistory.com/603&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;2011년, GitHub CIO인 Scott Chacon이 처음 언급한 방식으로, &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;Git-flow&lt;/span&gt; 가 가진 가장 큰 문제는 개발자가 요구하는 상황보다 훨씬 더 복잡한 프로세스&lt;/b&gt;라고 지적하면서 생겨난 방식이다. &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;Work-flow를 단순화해야 개발자들이 빨리 습득할 수 있으며, 단순할수록 오버헤드가 발생하지 않아&lt;/b&gt; &lt;/span&gt;브랜치 전략을 이해하지 못하여 생기는 문제를 줄일 수 있다고 보는 관점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;등장한 배경처럼 진행 방식 또한 굉장히 단순하다. 따라서 &lt;b&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;상시 배포&lt;/span&gt;가 가능하고 그렇게 수행하는 프로젝트에 적절한 방법&lt;/b&gt;이다. 또한 상시 배포 환경이므로,&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt; CI/CD 자동화가 되어 있는 것이 바람직&lt;/b&gt;&lt;/span&gt;하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Github-flow&lt;/b&gt; 의 &lt;b&gt;메커니즘 및&lt;/b&gt;&amp;nbsp;&lt;b&gt;정책&lt;/b&gt;은 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;origin/master&lt;/b&gt; 브랜치는 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;언제든지 배포가 가능&lt;/b&gt;&lt;/span&gt;하다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;새로운 프로젝트&lt;/b&gt;는 &lt;b&gt;master 브랜치를 기반으로&lt;/b&gt; 별도 브랜치를 생성하여 작업을 진행한다.&lt;/li&gt;
&lt;li&gt;기본적으로 개발 브랜치는 &lt;b&gt;개발자 로컬에 &lt;span style=&quot;color: #006dd7;&quot;&gt;commit&lt;/span&gt;&lt;/b&gt; 하고&lt;b&gt;, 정기적으로 원격 브랜치에 &lt;span style=&quot;color: #006dd7;&quot;&gt;push&lt;/span&gt;&lt;/b&gt; 한다.&lt;/li&gt;
&lt;li&gt;피드백 또는 도움이 필요하거나, 코드를 &lt;b&gt;merge할 준비가 되었다면&lt;span style=&quot;color: #006dd7;&quot;&gt; pull request&lt;/span&gt; 를 만든다.&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;다른 사람들의 피드백과 master 브랜치의 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;최종 승인자가 검토 및 승인을 마치면 master 브랜치(원격 저장소)에 merge&lt;/b&gt;&lt;/span&gt; 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4.3. Gitlab-flow 방식&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;333&quot; data-origin-height=&quot;548&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bnqOPA/btrN2YMM58d/IL63jPrXRIloGq9e09tFIk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bnqOPA/btrN2YMM58d/IL63jPrXRIloGq9e09tFIk/img.png&quot; data-alt=&quot;pre-production 브랜치가 없는 GitLab-flow 방식 / 출처 : brownbears.tistory.com/605&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bnqOPA/btrN2YMM58d/IL63jPrXRIloGq9e09tFIk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbnqOPA%2FbtrN2YMM58d%2FIL63jPrXRIloGq9e09tFIk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;244&quot; height=&quot;402&quot; data-origin-width=&quot;333&quot; data-origin-height=&quot;548&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;pre-production 브랜치가 없는 GitLab-flow 방식 / 출처 : brownbears.tistory.com/605&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;567&quot; data-origin-height=&quot;617&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kKdMh/btrNZj5Yw0l/kgrIVHl6dWaCXoXqubibQk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kKdMh/btrNZj5Yw0l/kgrIVHl6dWaCXoXqubibQk/img.png&quot; data-alt=&quot;pre-production 브랜치가 추가된 GitLab-flow 방식 / 출처 : brownbears.tistory.com/605&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kKdMh/btrNZj5Yw0l/kgrIVHl6dWaCXoXqubibQk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkKdMh%2FbtrNZj5Yw0l%2FkgrIVHl6dWaCXoXqubibQk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;408&quot; height=&quot;444&quot; data-origin-width=&quot;567&quot; data-origin-height=&quot;617&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;pre-production 브랜치가 추가된 GitLab-flow 방식 / 출처 : brownbears.tistory.com/605&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Gitlab-flow&lt;/b&gt; 방식의 &lt;b&gt;메커니즘 및 정책&lt;/b&gt;은 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;production 브랜치&lt;/b&gt;&lt;/span&gt;는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;오직 배포만을 담당&lt;/b&gt;&lt;/span&gt;한다. (&lt;b&gt;Git-flow 방식에서의 master 브랜치&lt;/b&gt;와 동일 취급)&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;master 브랜치&lt;/b&gt;&lt;/span&gt;는&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt; production 브랜치로의 병합을 목적&lt;/b&gt;&lt;/span&gt;으로 한다. (&lt;b&gt;Git-flow 방식에서의 develop 브랜치&lt;/b&gt;와 비슷한 역할)&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;pre-production 브랜치&lt;/b&gt;&lt;/span&gt;가 존재한다면, production 브랜치로 merge 하기 전, &lt;b&gt;QA 과정을 진행&lt;/b&gt;한다. (&lt;u&gt;스테이징 서버&lt;/u&gt;와 비슷)&lt;/li&gt;
&lt;li&gt;실제 기능을 개발하는&lt;b&gt; feature 브랜치&lt;/b&gt;는&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt; master 브랜치에서 분기(생성)&lt;/b&gt;&lt;/span&gt;하도록 한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;production 브랜치&lt;/b&gt;에서 릴리즈된 코드가&lt;u&gt; 항상 프로젝트의 최신 버전 상태를 유지할 필요가 없다.&lt;/u&gt;&lt;br /&gt;&lt;b&gt;최신 버전의 상태는 &lt;span style=&quot;color: #006dd7;&quot;&gt;master 브랜치&lt;/span&gt; 또는 &lt;span style=&quot;color: #006dd7;&quot;&gt;pre-production 브랜치&lt;/span&gt;가 담당&lt;/b&gt;하게 되는 것이다.&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;마치며&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;위 3가지 Work-flow 중 어떤 것이 가장 나은 방식이라고 딱 정할 수 없다.&lt;/b&gt; &lt;/span&gt;프로젝트, 개발자, 개발 환경, 팀 환경, 릴리즈 계획 등 모든 상황을 검토한 후, 가장 적절한 방법을 선택하는 것이 가장 나은 방식이 된다. 대신 수년간 검증되어 온&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt; 위 3가지 방식을 골자로 하여&lt;/span&gt; &lt;span style=&quot;color: #ee2323;&quot;&gt;해당 프로젝트 또는 팀 환경에 맞게 변형한다면, 최고의 Work-flow 가 탄생할 것&lt;/span&gt;&lt;/b&gt;이라고 본다.&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;http://blog.hwahae.co.kr/all/tech/tech-tech/9507/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://blog.hwahae.co.kr/all/tech/tech-tech/9507/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1665100303714&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Git 브랜치 전략 수립을 위한 전문가의 조언들 &amp;ndash; 화해 블로그 | 기술 블로그&quot; data-og-description=&quot;Git 브랜치 전략 효과적으로 VCS를 사용하려면 프로젝트 여건에 어울리는 브랜치 전략을 세워야 합니다. 이를 위한 첫 번째는 바로 브랜치 전략에 대한 비교 분석입니다. Git기반으로 워크플로우&quot; data-og-host=&quot;blog.hwahae.co.kr&quot; data-og-source-url=&quot;http://blog.hwahae.co.kr/all/tech/tech-tech/9507/&quot; data-og-url=&quot;http://blog.hwahae.co.kr/all/tech/tech-tech/9507/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dJANtH/hyP2c4i2pD/VGhXCnkBe9Qe6WLaSvwwqk/img.jpg?width=1050&amp;amp;height=660&amp;amp;face=0_0_1050_660,https://scrap.kakaocdn.net/dn/crqkeZ/hyP3zXPFIz/4WkeHSoih8a8kxleokmogK/img.jpg?width=1520&amp;amp;height=1990&amp;amp;face=0_0_1520_1990,https://scrap.kakaocdn.net/dn/qLLMC/hyP3DeRz0p/RPUVQIAV0Z6qYjx9HUPQb0/img.jpg?width=1520&amp;amp;height=1990&amp;amp;face=0_0_1520_1990&quot;&gt;&lt;a href=&quot;http://blog.hwahae.co.kr/all/tech/tech-tech/9507/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;http://blog.hwahae.co.kr/all/tech/tech-tech/9507/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dJANtH/hyP2c4i2pD/VGhXCnkBe9Qe6WLaSvwwqk/img.jpg?width=1050&amp;amp;height=660&amp;amp;face=0_0_1050_660,https://scrap.kakaocdn.net/dn/crqkeZ/hyP3zXPFIz/4WkeHSoih8a8kxleokmogK/img.jpg?width=1520&amp;amp;height=1990&amp;amp;face=0_0_1520_1990,https://scrap.kakaocdn.net/dn/qLLMC/hyP3DeRz0p/RPUVQIAV0Z6qYjx9HUPQb0/img.jpg?width=1520&amp;amp;height=1990&amp;amp;face=0_0_1520_1990');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Git 브랜치 전략 수립을 위한 전문가의 조언들 &amp;ndash; 화해 블로그 | 기술 블로그&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Git 브랜치 전략 효과적으로 VCS를 사용하려면 프로젝트 여건에 어울리는 브랜치 전략을 세워야 합니다. 이를 위한 첫 번째는 바로 브랜치 전략에 대한 비교 분석입니다. Git기반으로 워크플로우&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;blog.hwahae.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://backlog.com/git-tutorial/kr/stepup/stepup1_1.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://backlog.com/git-tutorial/kr/stepup/stepup1_1.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1665100712143&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;누구나 쉽게 이해할 수 있는 Git 입문~버전 관리를 완벽하게 이용해보자~ | Backlog&quot; data-og-description=&quot;누구나 쉽게 알 수 있는 Git에 입문하신 것을 환영합니다. Git을 사용해 버전 관리를 할 수 있도록 함께 공부해봅시다!&quot; data-og-host=&quot;backlog.com&quot; data-og-source-url=&quot;https://backlog.com/git-tutorial/kr/stepup/stepup1_1.html&quot; data-og-url=&quot;https://backlog.com/git-guide/kr/stepup/stepup1_1.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://backlog.com/git-tutorial/kr/stepup/stepup1_1.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://backlog.com/git-tutorial/kr/stepup/stepup1_1.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;누구나 쉽게 이해할 수 있는 Git 입문~버전 관리를 완벽하게 이용해보자~ | Backlog&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;누구나 쉽게 알 수 있는 Git에 입문하신 것을 환영합니다. Git을 사용해 버전 관리를 할 수 있도록 함께 공부해봅시다!&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;backlog.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://soy3on.tistory.com/152&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://soy3on.tistory.com/152&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1665102923211&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;HEAD -&amp;gt; master, origin/master의 의미&quot; data-og-description=&quot;  HEAD -&amp;gt; master, origin/master의 의미 다음은 git log --oneline 을 입력했을 때의 결과 창이다. git log --oneline 이 때, 맨 위의 HEAD -&amp;gt; master, origin/master와 같은 로그의 의미는 뭘까? 간단하게 말..&quot; data-og-host=&quot;soy3on.tistory.com&quot; data-og-source-url=&quot;https://soy3on.tistory.com/152&quot; data-og-url=&quot;https://soy3on.tistory.com/152&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bTV2XD/hyP2jh3No9/LpBpN1Zjt1Ze9rCeUnibd1/img.png?width=445&amp;amp;height=149&amp;amp;face=0_0_445_149,https://scrap.kakaocdn.net/dn/ctyyCi/hyP16we3hp/QxTMYCHHl8QNWJb5j9dIik/img.png?width=445&amp;amp;height=149&amp;amp;face=0_0_445_149&quot;&gt;&lt;a href=&quot;https://soy3on.tistory.com/152&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://soy3on.tistory.com/152&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bTV2XD/hyP2jh3No9/LpBpN1Zjt1Ze9rCeUnibd1/img.png?width=445&amp;amp;height=149&amp;amp;face=0_0_445_149,https://scrap.kakaocdn.net/dn/ctyyCi/hyP16we3hp/QxTMYCHHl8QNWJb5j9dIik/img.png?width=445&amp;amp;height=149&amp;amp;face=0_0_445_149');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;HEAD -&amp;gt; master, origin/master의 의미&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;  HEAD -&amp;gt; master, origin/master의 의미 다음은 git log --oneline 을 입력했을 때의 결과 창이다. git log --oneline 이 때, 맨 위의 HEAD -&amp;gt; master, origin/master와 같은 로그의 의미는 뭘까? 간단하게 말..&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;soy3on.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://blog.lulab.net/programming-tools/the-need-for-a-git-branch-strategy/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://blog.lulab.net/programming-tools/the-need-for-a-git-branch-strategy/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1665109393398&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Git 브랜치 전략(Git flow, Changes)의 필요&quot; data-og-description=&quot;즐겁게 코딩을 하면서 즐기는 공간 '룰루랄라코딩'입니다. 'Git 브랜치 전략(Git flow, Changes)의 필요'을 한 번 살펴보세요.&quot; data-og-host=&quot;blog.lulab.net&quot; data-og-source-url=&quot;https://blog.lulab.net/programming-tools/the-need-for-a-git-branch-strategy/&quot; data-og-url=&quot;https://blog.lulab.net/programming-tools/the-need-for-a-git-branch-strategy/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/f2zV0/hyP2jPXGRs/101ap6pPrkAp0dohoD69t0/img.png?width=1150&amp;amp;height=1524&amp;amp;face=0_0_1150_1524,https://scrap.kakaocdn.net/dn/HqyJd/hyP2bEoZ5T/CrUe3WZEELQONFKNenYP0K/img.png?width=1150&amp;amp;height=1524&amp;amp;face=0_0_1150_1524&quot;&gt;&lt;a href=&quot;https://blog.lulab.net/programming-tools/the-need-for-a-git-branch-strategy/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://blog.lulab.net/programming-tools/the-need-for-a-git-branch-strategy/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/f2zV0/hyP2jPXGRs/101ap6pPrkAp0dohoD69t0/img.png?width=1150&amp;amp;height=1524&amp;amp;face=0_0_1150_1524,https://scrap.kakaocdn.net/dn/HqyJd/hyP2bEoZ5T/CrUe3WZEELQONFKNenYP0K/img.png?width=1150&amp;amp;height=1524&amp;amp;face=0_0_1150_1524');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Git 브랜치 전략(Git flow, Changes)의 필요&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;즐겁게 코딩을 하면서 즐기는 공간 '룰루랄라코딩'입니다. 'Git 브랜치 전략(Git flow, Changes)의 필요'을 한 번 살펴보세요.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;blog.lulab.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://codingtrainee.tistory.com/156&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://codingtrainee.tistory.com/156&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1665110606747&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Git Flow와 GitHub Flow의 이해&quot; data-og-description=&quot;Git Flow 기본적인 가지의 이름은 아래의 5가지로 구분하곤 한다. feature &amp;gt; develop &amp;gt; release &amp;gt; hotfix &amp;gt; master 위 순서들은 왼쪽으로 갈수록 포괄적인 가지이며 master branch를 병합할 경우 그 왼쪽에 있는 h..&quot; data-og-host=&quot;codingtrainee.tistory.com&quot; data-og-source-url=&quot;https://codingtrainee.tistory.com/156&quot; data-og-url=&quot;https://codingtrainee.tistory.com/156&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b98weJ/hyP3vON2hr/K2iGBbSvTnjZdfTkkU52k0/img.png?width=800&amp;amp;height=1060&amp;amp;face=0_0_800_1060,https://scrap.kakaocdn.net/dn/bjlvvk/hyP3Gv0WBN/hLrrVJJ5KNSK7djnBP7Eu1/img.png?width=800&amp;amp;height=1060&amp;amp;face=0_0_800_1060,https://scrap.kakaocdn.net/dn/A6X1z/hyP3BuJe3j/fO67Gkhf100ZGMwMkNwGl1/img.png?width=1150&amp;amp;height=1524&amp;amp;face=0_0_1150_1524&quot;&gt;&lt;a href=&quot;https://codingtrainee.tistory.com/156&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://codingtrainee.tistory.com/156&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b98weJ/hyP3vON2hr/K2iGBbSvTnjZdfTkkU52k0/img.png?width=800&amp;amp;height=1060&amp;amp;face=0_0_800_1060,https://scrap.kakaocdn.net/dn/bjlvvk/hyP3Gv0WBN/hLrrVJJ5KNSK7djnBP7Eu1/img.png?width=800&amp;amp;height=1060&amp;amp;face=0_0_800_1060,https://scrap.kakaocdn.net/dn/A6X1z/hyP3BuJe3j/fO67Gkhf100ZGMwMkNwGl1/img.png?width=1150&amp;amp;height=1524&amp;amp;face=0_0_1150_1524');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Git Flow와 GitHub Flow의 이해&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Git Flow 기본적인 가지의 이름은 아래의 5가지로 구분하곤 한다. feature &amp;gt; develop &amp;gt; release &amp;gt; hotfix &amp;gt; master 위 순서들은 왼쪽으로 갈수록 포괄적인 가지이며 master branch를 병합할 경우 그 왼쪽에 있는 h..&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;codingtrainee.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@kw2577/Git-branch-%EC%A0%84%EB%9E%B5&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://velog.io/@kw2577/Git-branch-%EC%A0%84%EB%9E%B5&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1665117508457&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Git branch 전략(Git-Flow, Github-Flow, Gitlab-Flow)&quot; data-og-description=&quot;Branch란?브랜치란 독립적으로 어떤 작업을 진행하기 위한 개념입니다. 필요에 의해 만들어지는 각각의 브랜치는 다른 브랜치의 영향을 받지 않기 때문에, 여러 작업을 동시에 진행할 수 있습니&quot; data-og-host=&quot;velog.io&quot; data-og-source-url=&quot;https://velog.io/@kw2577/Git-branch-%EC%A0%84%EB%9E%B5&quot; data-og-url=&quot;https://velog.io/@kw2577/Git-branch-전략&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bwYoMz/hyP3Hu3uPR/AFw7fTfAghMSJl8NMXYAMK/img.jpg?width=750&amp;amp;height=467&amp;amp;face=0_0_750_467,https://scrap.kakaocdn.net/dn/VkjAl/hyP3GQspRG/6MIaROhSXAFnUsdb8rXD61/img.jpg?width=750&amp;amp;height=467&amp;amp;face=0_0_750_467,https://scrap.kakaocdn.net/dn/Xuxas/hyP3JTXJA8/ciwhMaeetj8KqFZ2SOfDiK/img.png?width=746&amp;amp;height=954&amp;amp;face=0_0_746_954&quot;&gt;&lt;a href=&quot;https://velog.io/@kw2577/Git-branch-%EC%A0%84%EB%9E%B5&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://velog.io/@kw2577/Git-branch-%EC%A0%84%EB%9E%B5&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bwYoMz/hyP3Hu3uPR/AFw7fTfAghMSJl8NMXYAMK/img.jpg?width=750&amp;amp;height=467&amp;amp;face=0_0_750_467,https://scrap.kakaocdn.net/dn/VkjAl/hyP3GQspRG/6MIaROhSXAFnUsdb8rXD61/img.jpg?width=750&amp;amp;height=467&amp;amp;face=0_0_750_467,https://scrap.kakaocdn.net/dn/Xuxas/hyP3JTXJA8/ciwhMaeetj8KqFZ2SOfDiK/img.png?width=746&amp;amp;height=954&amp;amp;face=0_0_746_954');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Git branch 전략(Git-Flow, Github-Flow, Gitlab-Flow)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Branch란?브랜치란 독립적으로 어떤 작업을 진행하기 위한 개념입니다. 필요에 의해 만들어지는 각각의 브랜치는 다른 브랜치의 영향을 받지 않기 때문에, 여러 작업을 동시에 진행할 수 있습니&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;velog.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DevOps/Github</category>
      <category>git branch</category>
      <category>git branch 전략</category>
      <category>git 브랜치</category>
      <category>git 브랜치 전략</category>
      <category>git-flow</category>
      <category>git-flow github-flow 차이</category>
      <category>github-flow</category>
      <category>gitlab-flow</category>
      <category>origin/head 의미</category>
      <category>origin/master master 차이</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/117</guid>
      <comments>https://co-no.tistory.com/entry/Git-%EB%B8%8C%EB%9E%9C%EC%B9%98branch-%EC%A0%84%EB%9E%B5-git-flow-%EB%B0%A9%EC%8B%9D-github-flow-%EB%B0%A9%EC%8B%9D-git-lab-%EB%B0%A9%EC%8B%9D#entry117comment</comments>
      <pubDate>Fri, 7 Oct 2022 13:53:25 +0900</pubDate>
    </item>
    <item>
      <title>[Git] Git의 기본 개념과 용어 정리</title>
      <link>https://co-no.tistory.com/entry/Git-Git%EC%9D%98-%EA%B8%B0%EB%B3%B8-%EA%B0%9C%EB%85%90%EA%B3%BC-%EC%9A%A9%EC%96%B4-%EC%A0%95%EB%A6%AC</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;조별 과제를 모두 해본 적이 있을 것이다. 조별 과제를 하다 보면, 발표 자료 PPT나 발표 대본 스크립트 등을 여러 사람이역할 분담하여 작성하면서 최종으로 사용하게 될 자료가 계속 바뀌게 되는데, 이때 어떤 게 가장 최신 버전인지 헷갈린 경험이 분명 있을 것이다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;프로그래밍 코드도 마찬가지다. 프로그래밍 코드는 특히나 이런 발표 자료보다 더더욱 많은 프로젝트 참여자, 각 참여자가 수정하는 사항들이 더더욱 많이 생기게 마련이다. 이번 포스팅에서는 프로그래밍에서 형상관리에 엄청난 도움을 주는 'Git'이라는 툴에 대해 알아보도록 하자!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;361&quot; data-origin-height=&quot;244&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cQr7bA/btrNXUqCEfg/9y8m3eFlmVzQ34Ea3kv5O1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cQr7bA/btrNXUqCEfg/9y8m3eFlmVzQ34Ea3kv5O1/img.png&quot; data-alt=&quot;문서 관리의 중요성 / 출처 : https://backlog.com/git-tutorial/kr/intro/intro1_1.html&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cQr7bA/btrNXUqCEfg/9y8m3eFlmVzQ34Ea3kv5O1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcQr7bA%2FbtrNXUqCEfg%2F9y8m3eFlmVzQ34Ea3kv5O1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;283&quot; height=&quot;191&quot; data-origin-width=&quot;361&quot; data-origin-height=&quot;244&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;문서 관리의 중요성 / 출처 : https://backlog.com/git-tutorial/kr/intro/intro1_1.html&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1. 'Git'을 왜 써야 할까?&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&amp;nbsp; 1-1. Git 의 &lt;span style=&quot;color: #8a3db6;&quot;&gt;정의&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; : &lt;b&gt;컴퓨터 파일의 변경사항을 추적&lt;/b&gt;하고 여러 명의 사용자들 간에 &lt;b&gt;해당 파일들의 작업을 조율&lt;/b&gt;하기 위한 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;분산 버전 관리 시스템.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp; 1-2. &lt;span style=&quot;color: #006dd7;&quot;&gt;*형상 관리&lt;/span&gt;를 하는 이유&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &lt;b&gt;* 형상 관리&lt;/b&gt; : 소프트웨어 구성 관리&lt;span style=&quot;background-color: #ffffff; color: #202122;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #202122;&quot;&gt;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #202122;&quot;&gt;Software Configuration Management&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;background-color: #ffffff; color: #202122;&quot;&gt;) 또는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;형상 관리&lt;/b&gt;&lt;span style=&quot;background-color: #ffffff; color: #202122;&quot;&gt;는 소&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;프트웨어의 변경사항을 체계적으로 추적하고 통제하는 것&lt;/b&gt;&lt;/span&gt;으로, 형상 관리는 일반적인 단순 버전관리 기반의 소프트웨어 운용을 좀 더 포괄적인 학술 분야의 형태로 넓히는 근간을 이야기한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #202122;&quot;&gt;다음 그림을 살펴보자. &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;사람 A,B,C,D가 나눠서 협업하여 진행&lt;/b&gt;&lt;/span&gt;하는 &lt;b&gt;프로젝트 'X'&lt;/b&gt;가 있다고 가정해보자. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;379&quot; data-origin-height=&quot;226&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bmT0r0/btrNXViNRg8/FwGYI53ev4UJYzVR6K6zd1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bmT0r0/btrNXViNRg8/FwGYI53ev4UJYzVR6K6zd1/img.png&quot; data-alt=&quot;협업 프로젝트 'X' / 출처 : cupjoo.tistory.com/6&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bmT0r0/btrNXViNRg8/FwGYI53ev4UJYzVR6K6zd1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbmT0r0%2FbtrNXViNRg8%2FFwGYI53ev4UJYzVR6K6zd1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;343&quot; height=&quot;205&quot; data-origin-width=&quot;379&quot; data-origin-height=&quot;226&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;협업 프로젝트 'X' / 출처 : cupjoo.tistory.com/6&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;협업하는 프로그래밍 프로젝트를 경험해봤다면 다음과 같은 문제가 충분히 발생할 수 있다는 걸 분명 알 것이다!&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;u&gt;A가 맡은 기능을 다 구현했는데, B가 맡은 파트를 아직 완성하지 못해서&lt;/u&gt; B의 완성된 코드를 공유받지 못해 다음 단계로 나갈 수가 없는 상황&lt;/li&gt;
&lt;li&gt;B가 코드를 완성하고 A의 코드와 &lt;u&gt;합쳤으나, 코드 충돌이 발생하여 심각한 에러&lt;/u&gt;가 발생, 애플리케이션이 정상 작동하지 않는 상황. 이로 인해&lt;u&gt;, C와 D는 A와 B의 코드가 완성되어야 진행할 수 있기 때문에 하염없이 기다리는 상황&lt;/u&gt;이다.&lt;/li&gt;
&lt;li&gt;A와 B의 코드가 완성되어(Code 1) 이제 C가 Code 1에 본인의 기능을 추가한 Code 2를 코딩하고 있는데, 심각한 에러가 발생하여, &lt;u&gt;Code 2의 처음 상황(Code 1)으로 돌아가야 하나, 백업해 둔 사람이 아무도 없는 상황&lt;/u&gt;&lt;/li&gt;
&lt;li&gt;어찌저찌하여 Code 2까지 완성했고, D가 Code 2에 이은 Code 3 을 작성하는 중에, 호환성 문제를 발견하여 Code 1 부분에서 수정이 필요한 상황인데,&lt;u&gt; 어느 부분에서 수정을 해야 하는 지 알 수 없는 상황&lt;/u&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 상황 하나하나가 모두 협업 프로젝트를 진행해봤다면 알겠지만, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;잘못하면 시간만 어마어마하게 잡아먹을 수 있는 아찔한 상황&lt;/b&gt;&lt;/span&gt;이다. &lt;u&gt;이러한 상황을 방지하기 위해 협업 프로젝트에서의 &lt;b&gt;형상 관리는 필수&lt;/b&gt;&lt;/u&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Git&lt;/b&gt;은 이러한 형상 관리를 매우 편리하게 도와주는 &lt;b&gt;Tool&lt;/b&gt;로서, 분산 버전 관리를 통해 &lt;b&gt;작업 일지 기록&lt;/b&gt;이나 &lt;b&gt;협업&lt;/b&gt;, &lt;b&gt;백업&lt;/b&gt; 등을 가능하게 해준다. 또한 &lt;b&gt;형상 관리 Tool 들 중 현재로선 점유율이 가장 높은&lt;/b&gt; 관계로, 개발자를 하기로 마음 먹었다면 git에 대해 반드시 알아야 한다!&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2. Git 의 개념과 용어 정리&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;343&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Q54dU/btrNWp56DZQ/w0EpIgeOoemuRQ8JzRk2Q1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Q54dU/btrNWp56DZQ/w0EpIgeOoemuRQ8JzRk2Q1/img.png&quot; data-alt=&quot;Git의 단순한 구조 / 출처 : cupjoo.tistory.com/6&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Q54dU/btrNWp56DZQ/w0EpIgeOoemuRQ8JzRk2Q1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQ54dU%2FbtrNWp56DZQ%2Fw0EpIgeOoemuRQ8JzRk2Q1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;441&quot; height=&quot;251&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;343&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Git의 단순한 구조 / 출처 : cupjoo.tistory.com/6&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 그림을 보면, Git의 구조를 대충 파악할 수 있다. 요약하면 이렇다. &lt;b&gt;최종 소스코드를 저장하고 공유하는 역할&lt;/b&gt;인 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;원격 저장소&lt;/b&gt;&lt;/span&gt;가 있고, 여기에서&lt;b&gt; 소스코드를 내 로컬 저장소(내 PC)로 받아와서 소스코드를 수정&lt;/b&gt;한 후, &lt;b&gt;다시 원격 저장소로 업로드&lt;/b&gt;하는 구조이다. 그럼 이제 Git에서 실제 사용하는 용어를 중심으로 Git이 어떤 기능을 가지고 있는지 살펴보자!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2.1. Git의 저장소의 종류&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;● Remote Repository (원격 저장소) &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;원격 서버(GitHub)에 저장된 저장소&lt;/b&gt;&lt;/span&gt;로, &lt;u&gt;여러 사람이 함께 공유&lt;/u&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;b&gt;●&lt;span&gt; &amp;nbsp;&lt;/span&gt;&lt;/b&gt;Local Repository (로컬 저장소)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;사용자가 직접 관리하는 저장소&lt;/b&gt;&lt;/span&gt;로, &lt;b&gt;내 PC 에 저장&lt;/b&gt;되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2.2. 프로젝트의 전체 복사&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;506&quot; data-origin-height=&quot;396&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DkAyR/btrNWpSKPtL/XHheawoKLIQ33UIsaWXeik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DkAyR/btrNWpSKPtL/XHheawoKLIQ33UIsaWXeik/img.png&quot; data-alt=&quot;clone 과 fork의 구분&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DkAyR/btrNWpSKPtL/XHheawoKLIQ33UIsaWXeik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDkAyR%2FbtrNWpSKPtL%2FXHheawoKLIQ33UIsaWXeik%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;506&quot; height=&quot;396&quot; data-origin-width=&quot;506&quot; data-origin-height=&quot;396&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;clone 과 fork의 구분&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;●&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;Clone&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;Remote Repository 에서 내 Local Repository로 복사&lt;/b&gt;&lt;/span&gt;하여 &lt;b&gt;내 PC에 새로운 저장소를 만드는 것.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;- Clone 한 원본 Repository(Remote) 를 &lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt;origin&lt;/b&gt;&lt;/span&gt; 으로 갖고 있는데, 기본적으로 이 origin에 대한 권한이 없으면, 해당 저장소로 push 할 수 없다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;- Clone을 하게 되면, 내 PC의 지정된 폴더에 &lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt;.git&lt;/b&gt; &lt;/span&gt;이라는 숨겨진 폴더가 생성되고, 이러한 &lt;b&gt;.git 폴더를 가지고 있는 폴더&lt;/b&gt;를 '&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;작업 폴더(Working Directory)&lt;/b&gt;&lt;/span&gt;' 라고 한다. 이 작업 폴더는 자동으로 github의 Remote Repository와 링크가 맺어지게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;●&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;fork&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;다&lt;/b&gt;&lt;b&gt;른 사람의 Remote Repository(Github) 에서 내 Remote Repository(Github)으로 복제&lt;/b&gt;&lt;/span&gt;하는 기능.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;원본(다른 사람의 Remote Repo)과 연결&lt;/b&gt;&lt;/span&gt;되어 있으며, 여기서 '&lt;b&gt;연결되어 있다&lt;/b&gt;'의 의미는, Original Repository에 어떤 변화가 생기면,&lt;b&gt; forked 된 Repository로 &lt;span style=&quot;color: #006dd7;&quot;&gt;Fetch&lt;/span&gt;나 &lt;span style=&quot;color: #006dd7;&quot;&gt;Rebase&lt;/span&gt;의 기능을 통해 변동사항을 반영&lt;/b&gt;할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 원본(다른 사람의 Remote Repo)에 &lt;u&gt;내가 수정한 코드를 적용하고 싶으면,&lt;/u&gt; &lt;b&gt;해당 저장소에 &lt;span style=&quot;color: #006dd7;&quot;&gt;PR(Pull Request)&lt;/span&gt;를 해야&lt;/b&gt; 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때, 원본의 관리자로부터 &lt;u&gt;승인을 받으면, 내가 수정한 코드가 &lt;b&gt;Commit&amp;amp;Merge&lt;/b&gt;&lt;/u&gt; 되어, 원본 Repo (다른 사람의 Remote Repo)에 반영된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;2.3. 내 로컬 Repo 에서의 변경 사항 관리&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;446&quot; data-origin-height=&quot;177&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cUn2Nn/btrNYpw9CCU/xJExmp6pZUH1c1On2m8m81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cUn2Nn/btrNYpw9CCU/xJExmp6pZUH1c1On2m8m81/img.png&quot; data-alt=&quot;Stage의 개념 / 출처 : cupjoo.tistory.com/6&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cUn2Nn/btrNYpw9CCU/xJExmp6pZUH1c1On2m8m81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcUn2Nn%2FbtrNYpw9CCU%2FxJExmp6pZUH1c1On2m8m81%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;446&quot; height=&quot;177&quot; data-origin-width=&quot;446&quot; data-origin-height=&quot;177&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Stage의 개념 / 출처 : cupjoo.tistory.com/6&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;※ Stage(Staging)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: 특정 파일이나 코드를 변경한 후 해당 이력을 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;*Index 에 기록하는 행위.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;*Index&lt;/b&gt; : &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;commit 을 통해 변경사항들이 반영되기 전, 해당 변경 사항의 이력들이 저장되는 '공간'&lt;/b&gt;&lt;/span&gt;을 말한다. Staging Area 라고도 한다. &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;commit 되기 이전의 임시 저장소&lt;/b&gt;&lt;/span&gt;라고 생각하면 된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;●&lt;span&gt; Add&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;: &lt;b&gt;작업 폴더(Working Directory)&lt;/b&gt; 는 &lt;u&gt;처음에는 아직 관리 대상(Tracked)이 아니다.&lt;/u&gt; Untracked 인 상태는 아무런 히스토리 정보를 가지지 못하는데, 우리가 Git을 사용하는 목적은 이러한 히스토리를 관리하기 위함이다. 따라서 &lt;b&gt;해당 작업 폴더를 관리 대상으로 삼기 위해, &lt;span style=&quot;color: #8a3db6;&quot;&gt;add 명령어&lt;/span&gt;를 수행해주어야 한다.&lt;/b&gt; 처음 add 명령을 수행하면, Index 가 생기고, 이후 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;모든 수정 사항에 대한 Staging 행위(add 명령을 통해 수행)가 Index 에 저장&lt;/b&gt;&lt;/span&gt;된다.&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;●&lt;span&gt; Commit&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;Staging 된 파일들을 Local Repository에 등록하는 행위.&lt;/b&gt;&lt;/span&gt; &lt;b&gt;스냅샷의 형태&lt;/b&gt;로 Local Repository에 저장되며, &lt;u&gt;하나의 commit 단위로 해당 파일을 &lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;롤백&lt;/span&gt;&lt;/b&gt;할 수도 있고, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;미래(?) (더 이후 시점의 commit)로&lt;/b&gt;&lt;/span&gt; 갈 수도 있다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2.4. Local Repository -&amp;gt; Remote Repository 변경사항 반영하기&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;●&lt;span&gt;&lt;span&gt; Push&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;현재 내 로컬 저장소에서 작업한 변경 사항들을 원격 저장소에 반영하는 것&lt;/b&gt;&lt;/span&gt;을 말한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;- 로컬 저장소의 &lt;b&gt;commit 된 모든 내용 그대로 원격 저장소에&lt;/b&gt; 올린다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;- 대부분 &lt;b&gt;commit 직후에 수행&lt;/b&gt;하여 원격 저장소에 곧바로 변경사항을 적용시킬 때 사용하며, &lt;u&gt;&lt;b&gt;push가 완료되면, 로컬 저장소와 원격 저장소의 소스코드 내용이 동일하게 된다.&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;●&lt;span&gt;&lt;span&gt; Merge&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;두 개 이상의 개발 히스토리(branch) 를 하나로 합치는 작업&lt;/b&gt;&lt;/span&gt;을 의미한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;- merge를 하게 되면, &lt;b&gt;각각의 개발자가 작업한 히스토리가 &lt;span style=&quot;color: #006dd7;&quot;&gt;모두 보존(Preserved)&lt;/span&gt;&lt;/b&gt; 된다는 특징이 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;●&lt;span&gt;&lt;span&gt; Rebase&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;branch 의 base 를 재설정하여 다시 커밋을 재적용하는 작업&lt;/b&gt;&lt;/span&gt;을 의미한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1030&quot; data-origin-height=&quot;725&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/z5Fx5/btrNXMtv1OP/TK5OO15KgwK9ckgtpqlSV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/z5Fx5/btrNXMtv1OP/TK5OO15KgwK9ckgtpqlSV1/img.png&quot; data-alt=&quot;Git Rebase 개념&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/z5Fx5/btrNXMtv1OP/TK5OO15KgwK9ckgtpqlSV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fz5Fx5%2FbtrNXMtv1OP%2FTK5OO15KgwK9ckgtpqlSV1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;565&quot; height=&quot;398&quot; data-origin-width=&quot;1030&quot; data-origin-height=&quot;725&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Git Rebase 개념&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1242&quot; data-origin-height=&quot;714&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yvvh0/btrNX8bSGXn/bI7BZkCZ26yj48WbFaVLXk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yvvh0/btrNX8bSGXn/bI7BZkCZ26yj48WbFaVLXk/img.png&quot; data-alt=&quot;Git Rebase 예시 / 출처 : devowen.com/430&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yvvh0/btrNX8bSGXn/bI7BZkCZ26yj48WbFaVLXk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fyvvh0%2FbtrNX8bSGXn%2FbI7BZkCZ26yj48WbFaVLXk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;691&quot; height=&quot;397&quot; data-origin-width=&quot;1242&quot; data-origin-height=&quot;714&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Git Rebase 예시 / 출처 : devowen.com/430&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;- &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;git rebase master feature-2&lt;/b&gt;&lt;/span&gt; 는 feature-2 브랜치를 master 브랜치로 리베이스 한다는 의미로, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;master 브랜치의 가장 최근 commit 뒤로 feature-2 브랜치의 commit들이 붙게 된다. &lt;/b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;이때 엄밀히 말하면, feature-2의 commit들은 rebase 되면서, 아예 다른 commit이 되는 것이므로, &lt;b&gt;C5*, C6*&lt;/b&gt; 로 표기하는 것이 맞다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;- 각 branch들은 해당 branch의 최초 히스토리가 되는 base 지점을 가지고 있는데, 이러한 &lt;b&gt;base 지점을 새로운 브랜치로 갱신&lt;/b&gt;하여, &lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;히스토리를 하나로 통합하기 위해 사용&lt;/span&gt;&lt;/b&gt;한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;- &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;Rebase 는 충돌을 유발할 수 있어&lt;/b&gt;&lt;/span&gt;, &lt;b&gt;아래의 원칙&lt;/b&gt;을 지키는 것이 바람직하다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;&lt;u&gt;원격 저장소에 올라간 커밋&lt;/u&gt;&lt;/b&gt;&lt;/span&gt;은 리베이스 하지 말 것.&lt;/li&gt;
&lt;li&gt;rebase 전에 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;rebase 하려는 브랜치 끝에서 백업 브랜치를 만들어&lt;/b&gt;&lt;/span&gt; 놓을 것.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;u&gt;&lt;b&gt;큰 규모의 팀&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;에서는 되도록 merge를 할 것.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;2.5. Remote Repository -&amp;gt; Local Repository 로 변경사항 가져오기&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;●&lt;span&gt;&lt;span&gt;&lt;span&gt; Pull&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;원격 저장소에 있는 변경사항들을 로컬 저장소로 가져와 소스코드를 병합(Merge)&lt;/b&gt;&lt;/span&gt;하는 명령어.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;- &lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;Fetch + Merge&lt;/span&gt; 의 개념&lt;/b&gt;으로 보면 된다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;- 일단 한 번은 원격 저장소와 링크가 맺어져 있어야&lt;b&gt;(Clone 또는 Fork 이후) 실행 가능한 명령어&lt;/b&gt;이다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;●&lt;span&gt;&lt;span&gt;&lt;span&gt; Fetch&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;: &lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;원격 저장소에 있는 변경 사항들을 &lt;b&gt;로컬 저장소에 병합하기 전,&lt;/b&gt; &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;해당 변경 내용들을 확인만 하려고 할 때&lt;/b&gt; &lt;/span&gt;사용하는 명령어.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;- 로컬 저장소로 &lt;u&gt;&lt;b&gt;변경된 소스코드 내용을 가져오지는 않음&lt;/b&gt;&lt;/u&gt; (코드 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;합치려면 Merge가 필요&lt;/b&gt;&lt;/span&gt;함.)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;- &lt;b&gt;원격 저장소의 최신 commit 이력을 로컬 저장소의 &lt;span style=&quot;color: #ee2323;&quot;&gt;이름 없는 브랜치&lt;/span&gt;로서 가져오게&lt;/b&gt; 된다. 이 브랜치는 '&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;FETCH_HEAD&lt;/b&gt;&lt;/span&gt;'의 이름으로 &lt;b&gt;Checkout 도 가능&lt;/b&gt;하다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://cupjoo.tistory.com/6&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://cupjoo.tistory.com/6&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1665036966450&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Git에 대해 알아보자 1. Git의 개념과 Git Flow&quot; data-og-description=&quot;개발을 하다 보면 Git이나 GitHub, GitLab 같은 용어를 상당히 자주 듣게 된다. 오픈소스 프로젝트에 참여하려 했더니 GitHub 아이디를 물어보는 것도 모자라 인턴 지원을 하는데도 GitHub 주소를 알려달&quot; data-og-host=&quot;cupjoo.tistory.com&quot; data-og-source-url=&quot;https://cupjoo.tistory.com/6&quot; data-og-url=&quot;https://cupjoo.tistory.com/6&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cnphYt/hyP16vNuXx/WVbtra440DcmqSaVaVQPk0/img.jpg?width=728&amp;amp;height=464&amp;amp;face=0_0_728_464,https://scrap.kakaocdn.net/dn/eMhkM/hyP3EErbF1/KymXtU3PhGfiZr2KfRrDMK/img.jpg?width=728&amp;amp;height=464&amp;amp;face=0_0_728_464,https://scrap.kakaocdn.net/dn/c0sHbo/hyP3GvuIaV/R8zWkpL4SHKVVqhVbPcbU1/img.png?width=728&amp;amp;height=964&amp;amp;face=0_0_728_964&quot;&gt;&lt;a href=&quot;https://cupjoo.tistory.com/6&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://cupjoo.tistory.com/6&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cnphYt/hyP16vNuXx/WVbtra440DcmqSaVaVQPk0/img.jpg?width=728&amp;amp;height=464&amp;amp;face=0_0_728_464,https://scrap.kakaocdn.net/dn/eMhkM/hyP3EErbF1/KymXtU3PhGfiZr2KfRrDMK/img.jpg?width=728&amp;amp;height=464&amp;amp;face=0_0_728_464,https://scrap.kakaocdn.net/dn/c0sHbo/hyP3GvuIaV/R8zWkpL4SHKVVqhVbPcbU1/img.png?width=728&amp;amp;height=964&amp;amp;face=0_0_728_964');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Git에 대해 알아보자 1. Git의 개념과 Git Flow&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;개발을 하다 보면 Git이나 GitHub, GitLab 같은 용어를 상당히 자주 듣게 된다. 오픈소스 프로젝트에 참여하려 했더니 GitHub 아이디를 물어보는 것도 모자라 인턴 지원을 하는데도 GitHub 주소를 알려달&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;cupjoo.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://ux.stories.pe.kr/182&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://ux.stories.pe.kr/182&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1665037013335&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;그림으로 보는 Git의 개념 이해하기&quot; data-og-description=&quot;Git은 Svn 이후로 현재 가장 많이 사용되어지는 형상관리 툴입니다. 위키백과를 보면 아래와 같이 정의를 하고 있습니다. 깃(Git /ɡɪt/)은 컴퓨터 파일의 변경사항을 추적하고 여러 명의 사용자들 &quot; data-og-host=&quot;ux.stories.pe.kr&quot; data-og-source-url=&quot;https://ux.stories.pe.kr/182&quot; data-og-url=&quot;https://ux.stories.pe.kr/182&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/zMtwW/hyP3v8zetG/2ZkhNvsyRDIIC2dEui0Pk0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/sSIvL/hyP18UJppz/IGCJoRdyAu8ZtQTqKnFKF1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/crEcrZ/hyP2fTOSQR/BU7ivK9OBWHfWIStsIM6O1/img.png?width=1280&amp;amp;height=885&amp;amp;face=0_0_1280_885&quot;&gt;&lt;a href=&quot;https://ux.stories.pe.kr/182&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://ux.stories.pe.kr/182&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/zMtwW/hyP3v8zetG/2ZkhNvsyRDIIC2dEui0Pk0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/sSIvL/hyP18UJppz/IGCJoRdyAu8ZtQTqKnFKF1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/crEcrZ/hyP2fTOSQR/BU7ivK9OBWHfWIStsIM6O1/img.png?width=1280&amp;amp;height=885&amp;amp;face=0_0_1280_885');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;그림으로 보는 Git의 개념 이해하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Git은 Svn 이후로 현재 가장 많이 사용되어지는 형상관리 툴입니다. 위키백과를 보면 아래와 같이 정의를 하고 있습니다. 깃(Git /ɡɪt/)은 컴퓨터 파일의 변경사항을 추적하고 여러 명의 사용자들&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;ux.stories.pe.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://wlqmffl0102.github.io/posts/Git-organizing-the-terms/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://wlqmffl0102.github.io/posts/Git-organizing-the-terms/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1665037028273&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Git 용어 정리&quot; data-og-description=&quot;Git 여담으로 끼워넣겠습니다. 전혀 모르고 하다보면 어느순간 이해하게 됩니다만, 그렇지만 간단한것은 한번씩 짚고 넘어가려고 합니다. 깃 블로그 만들기에는 꼭 필요한 내용은 아닙니다. 넘&quot; data-og-host=&quot;wlqmffl0102.github.io&quot; data-og-source-url=&quot;https://wlqmffl0102.github.io/posts/Git-organizing-the-terms/&quot; data-og-url=&quot;https://wlqmffl0102.github.io/posts/Git-organizing-the-terms/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bCjGmo/hyP2d2MTfE/xnxFV4ZWulBAKsw19KEn41/img.png?width=720&amp;amp;height=720&amp;amp;face=462_308_649_512&quot;&gt;&lt;a href=&quot;https://wlqmffl0102.github.io/posts/Git-organizing-the-terms/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://wlqmffl0102.github.io/posts/Git-organizing-the-terms/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bCjGmo/hyP2d2MTfE/xnxFV4ZWulBAKsw19KEn41/img.png?width=720&amp;amp;height=720&amp;amp;face=462_308_649_512');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Git 용어 정리&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Git 여담으로 끼워넣겠습니다. 전혀 모르고 하다보면 어느순간 이해하게 됩니다만, 그렇지만 간단한것은 한번씩 짚고 넘어가려고 합니다. 깃 블로그 만들기에는 꼭 필요한 내용은 아닙니다. 넘&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;wlqmffl0102.github.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://backlog.com/git-tutorial/kr/intro/intro1_1.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://backlog.com/git-tutorial/kr/intro/intro1_1.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1665037085368&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;누구나 쉽게 이해할 수 있는 Git 입문~버전 관리를 완벽하게 이용해보자~ | Backlog&quot; data-og-description=&quot;누구나 쉽게 알 수 있는 Git에 입문하신 것을 환영합니다. Git을 사용해 버전 관리를 할 수 있도록 함께 공부해봅시다!&quot; data-og-host=&quot;backlog.com&quot; data-og-source-url=&quot;https://backlog.com/git-tutorial/kr/intro/intro1_1.html&quot; data-og-url=&quot;https://backlog.com/git-guide/kr/intro/intro1_1.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://backlog.com/git-tutorial/kr/intro/intro1_1.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://backlog.com/git-tutorial/kr/intro/intro1_1.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;누구나 쉽게 이해할 수 있는 Git 입문~버전 관리를 완벽하게 이용해보자~ | Backlog&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;누구나 쉽게 알 수 있는 Git에 입문하신 것을 환영합니다. Git을 사용해 버전 관리를 할 수 있도록 함께 공부해봅시다!&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;backlog.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DevOps/Github</category>
      <category>git add commit</category>
      <category>git clone fork</category>
      <category>git command</category>
      <category>git pull fetch</category>
      <category>git rebase merge</category>
      <category>git 개념</category>
      <category>git 명령어</category>
      <category>git 용어</category>
      <category>git 용어 정리</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/116</guid>
      <comments>https://co-no.tistory.com/entry/Git-Git%EC%9D%98-%EA%B8%B0%EB%B3%B8-%EA%B0%9C%EB%85%90%EA%B3%BC-%EC%9A%A9%EC%96%B4-%EC%A0%95%EB%A6%AC#entry116comment</comments>
      <pubDate>Fri, 7 Oct 2022 08:47:44 +0900</pubDate>
    </item>
    <item>
      <title>[Java] JVM 실행 옵션 (2) - Non-Standard Options</title>
      <link>https://co-no.tistory.com/entry/Java-jvm-%EC%8B%A4%ED%96%89-%EC%98%B5%EC%85%98-2-Non-Standard-Options</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;본 포스팅은 &lt;b&gt;java 8 버전 (openjdk 1.8)&lt;/b&gt; 을 기준으로 작성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전 포스팅에 이어, 이번 포스팅에서는 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;Java HotSpot Virtual Machine&lt;/b&gt; &lt;/span&gt;에 특정한 범용 옵션인, Non-Standard Option 들에 대해 살펴보도록 하자! 들어가기에 앞서, Non-Standard Option 의 경우, &lt;b&gt;모든 옵션 앞에&lt;/b&gt; '&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;X&lt;/b&gt;&lt;/span&gt;'가 붙는다는 것을 알아두자!&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Non-Standard Options&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;a id=&quot;BABHDABI&quot;&gt;&lt;/a&gt;&lt;b&gt;-X&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: 사용 가능한 모든 -X 옵션(Non-Standard Option)에 대해&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt; 도움말을 출력&lt;/b&gt;&lt;/span&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;a id=&quot;BABHDABI&quot;&gt;&lt;/a&gt;&lt;b&gt;-Xbatch&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;u&gt;JVM은 디폴트로 백그라운드 작업으로 컴파일&lt;/u&gt;하고, 백그라운드 컴파일이 끝날때까지 메소드를 인터프리터 모드에서 동작하게 되는데, 이 옵션을 사용하면 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;백그라운드 컴파일을 Disable&lt;/b&gt; &lt;/span&gt;하게 된다. 이렇게 함으로써, 모든 메서드들은 동작이 완료될때까지 &lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;포그라운드(foreground) 방식으로 동작하게 된다. &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이는 &lt;b&gt;Advanced JIT Compiler Option&lt;/b&gt;의 '&lt;b&gt;-XX:-BackgroundCompilation&lt;/b&gt;' 과 같은 효과이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;a id=&quot;BABHDABI&quot;&gt;&lt;/a&gt;&lt;b&gt;-Xbootclasspath:&lt;i&gt;path&lt;/i&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;:&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt; 부트 클래스 파일을 검색할&lt;/b&gt;&lt;b&gt; 디렉토리, JAR 파일, ZIP 아카이브를 ':'(colon, 콜론) 으로 구분하여 지정하는 옵션.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이렇게 지정한 파일들은 jvm이 실행될 때 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;JDK에 포함된 부트 클래스 파일을 대신하여 실행되도록&lt;/b&gt;&lt;/span&gt; 한다. 단, 이 옵션을 사용하여 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;rt.jar 안에 있는 클래스를 재정의(Overriding) 하는 애플리케이션을 배포하여서는 안된다.&lt;/b&gt;&lt;/span&gt; 이는 JRE 바이너리 코드 라이센스에 위반된는 행위이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;a id=&quot;BABHDABI&quot;&gt;&lt;/a&gt;&lt;b&gt;-Xbootclasspath/a:&lt;i&gt;path&lt;/i&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: 'Xbootclasspath:path' 옵션과 동일한데, 지정한 경로 앞에 '&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;a&lt;/b&gt;&lt;/span&gt;'를 붙이므로써, 해당 경로는 &lt;b&gt;디폴트 부트스트랩 클래스 경로의 &lt;span style=&quot;color: #8a3db6;&quot;&gt;하위 경로&lt;/span&gt;로 지정&lt;/b&gt;되어 부트 클래스 파일을 검색하는 옵션이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;a id=&quot;BABHDABI&quot;&gt;&lt;/a&gt;&lt;b&gt;-Xbootclasspath/p:&lt;i&gt;path&lt;/i&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: 'Xbootclasspath:path' 옵션과 동일한데, 지정한 경로 앞에 '&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;p&lt;/b&gt;&lt;/span&gt;'를 붙이므로써, 해당 경로는 &lt;b&gt;디폴트 부트스트랩 클래스 경로의 &lt;span style=&quot;color: #8a3db6;&quot;&gt;상위 경로&lt;/span&gt;로 지정&lt;/b&gt;되어 부트 클래스 파일을 검색하는 옵션이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;a id=&quot;BABHDABI&quot;&gt;&lt;/a&gt;&lt;b&gt;-Xcheck:jni&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;*JNI(Java Native Interface) 기능에 대한 추가 검사를 수행&lt;/b&gt;&lt;/span&gt;하는 옵션. &lt;b&gt;JNI 요청을 처리하기 전, JNI 함수와 런타임 환경 데이터에 전달된 매개 변수를 확인&lt;/b&gt;한다. 만약 잘못된 결과 데이터가 나온다면 이는 네이티브 코드에 문제가 있음을 나타내며, 이러한 경우 복구할 수 없는 에러와 함께 JVM을 종료하게 된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;*JNI(Java Native Inteface)&lt;/b&gt; : JVM 위에서 실행되고 있는 java 코드가 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;네이티브 응용 프로그램(하드웨어 및 OS 플랫폼에 종속된 프로그램 등), C, C++, 어셈블리 같은 java 와는 다른 언어로 작성된 라이브러리들을 호출하거나 반대로 호출되는 것을 가능케 하는 프로그래밍 프레임워크&lt;/b&gt;&lt;/span&gt;를 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이는 일부 하드웨어를 처리해야 하거나, 매우 까다로운 프로세스의 성능 향상을 요하거나, 타 언어로 작성된 기존의 라이브러리를 java로 재작성하려고 할 때 사용하는데, 이를 달성하기 위해 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;JDK에서는 JVM 에서 실행되는 바이트코드(.java 파일이 컴파일 된 .class파일)와 기본코드(.java 파일) 사이에 브릿지&lt;/b&gt;&lt;/span&gt;를 도입해야 하는데 이 브릿지 역할을 JNI가 하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;a id=&quot;BABHDABI&quot;&gt;&lt;/a&gt;&lt;b&gt;-Xcomp&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;:&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt; 첫 번째 메서드 호출 시, 강제로 컴파일하도록 하는 옵션&lt;/b&gt;&lt;/span&gt;이다. 원래 JVM에서는 디폴트로, 효율적인 컴파일을 위한 정보 수집을 위해&lt;b&gt; Client 버전의 경우 1,000개의 인터프리트된 메서드 호출, Server 버전의 경우 10,000개의 인터프리트된 메서드 호출을 수행&lt;/b&gt;하는데, 이 옵션을 사용하게 되면 인터프리트된 메서드 호출을 Disable하여,&lt;b&gt; 전체 컴파일의 효율성을 포기하고 컴파일 자체의 퍼포먼스를 높이기 위해 사용&lt;/b&gt;된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;a id=&quot;BABHDABI&quot;&gt;&lt;/a&gt;&lt;b&gt;-Xdiag&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;추가적인 진단 메시지를 출력&lt;/b&gt;&lt;/span&gt;하는 옵션.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;a id=&quot;BABHDABI&quot;&gt;&lt;/a&gt;&lt;b&gt;-Xfuture&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: 클래스 파일 형식 규격을 엄격하게 준수하도록 하는&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt; 'strict class-file check'를 Enable&lt;/b&gt;&lt;/span&gt; 하는 옵션. 미래 릴리즈(?)에서는 strict check가 디폴트로 될 것이므로, 개발자에게는 새로운 코드를 개발할 때 이 옵션을 사용하는 것이 권장된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;a id=&quot;BABHDABI&quot;&gt;&lt;/a&gt;&lt;b&gt;-Xint&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;애플리케이션을 interpreted-only 모드로 작동&lt;/b&gt;&lt;/span&gt;시킨다. 이렇게 되면, &lt;b&gt;네이티브 코드로의 컴파일이 disable&lt;/b&gt;되며, 모든 바이트코드가 인터프리터에 의해 실행된다. 즉, &lt;u&gt;JIT 컴파일러에 의한 성능 이점이 이 모드에서는 나타나지 않게 된다.&amp;nbsp;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;a id=&quot;BABHDABI&quot;&gt;&lt;/a&gt;&lt;b&gt;-Xinternalversion&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;-version 옵션보다 자세한 JVM 버전 정보를 출력&lt;/b&gt;&lt;/span&gt;한 후 jvm을 종료하는 옵션.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;a id=&quot;BABHDABI&quot;&gt;&lt;/a&gt;&lt;b&gt;-Xloggc:&lt;i&gt;filename&lt;/i&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;로깅을 위해 상세 GC 이벤트 정보를 리다이렉션할 파일을 설정하는 옵션&lt;/b&gt;&lt;/span&gt;. 이때 해당 파일에 기록된 정보는, 기록된 각 이벤트 전 첫번째 GC 이벤트 이후에 경과된 시간으로, &lt;u&gt;-verbose:gc 의 출력 결과와 비슷&lt;/u&gt;하다. 따라서 동일한 java 명령어 내에서 -Xloggc 옵션과 -verbose:gc 옵션이 함께 쓰였다면, -Xloggc 옵션으로 재정의 된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;a id=&quot;BABHDABI&quot;&gt;&lt;/a&gt;&lt;b&gt;-Xmaxjitcodesize=&lt;i&gt;size&lt;/i&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;JIT-컴파일 코드에 대한 최대 캐시 사이즈(바이트 단위)를 지정하는 옵션.&lt;/b&gt;&lt;/span&gt; 디폴트 캐시 사이즈는 240 MB 이며, 만약 '-XX:TieredCompilation' 옵션을 사용하여 계층형 컴파일 옵션을 disable 했을 경우, 디폴트 캐시 사이즈는 48 MB 가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같이, 킬로바이트면 &lt;b&gt;k/K&lt;/b&gt;, 메가바이트면 &lt;b&gt;m/M,&lt;/b&gt; 기가바이트면 &lt;b&gt;g/G&lt;/b&gt;를 숫자 뒤에 붙여 사용한다.&lt;/p&gt;
&lt;pre id=&quot;code_1664848994025&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-Xmaxjitcodesize=240m&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;'-XX:ReservedCodeCacheSize' 옵션과 동일하게 사용&lt;/b&gt;&lt;/span&gt;된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;a id=&quot;BABHDABI&quot;&gt;&lt;/a&gt;&lt;b&gt;-Xmixed&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: 네이티브 코드로 컴파일 된 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;hot method를 제외한, 모든 바이트 코드를 인터프리터를 통해 실행하는 옵션.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;a id=&quot;BABHDABI&quot;&gt;&lt;/a&gt;&lt;b&gt;-Xmn&lt;i&gt;size&lt;/i&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;힙 메모리의 nursery 영역의 최대 사이즈를 설정하는 옵션.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;JVM의 힙 영역은 물리적으로 두 부분으로 나눠지는데, nursery(young generation) 파트와 tenure(old generation) 파트이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;여기서 nursery 파트는 새로운 객체를 할당하기 위해 힙에 확보된 공간으로, nursery 가 가득 차게 되면, young collction 또는 minor GC 라는 가비지 컬렉션이 수행된다. 이 과정 중, 살아있는 객체들만 체크하고 나머지는 다 없애버리게 되는데, 남아있는 객체들 중 어느정도 오래 머물렀던 객체들을 tenure 파트에 이동시켜 nursery의 공간을 다시 한번 확보하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;nursery 파트의 공간이 너무 작으면, 많은 minor GC 가 발생하게 될 것이고, 공간이 너무 크다면, 완료되는데에 오랜 시간이 걸리는 full GC 만 수행되게 될 것이다.&lt;/u&gt; &lt;b&gt;오라클에서는 전체 힙 사이즈의 25% ~ 50% 만 nursery 파트의 공간으로 잡을 것을 권장&lt;/b&gt;한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;nursery 파트의 최대 사이즈를 &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;256 MB로 설정하는 옵션&lt;/b&gt;&lt;/span&gt; 예시는 아래와 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1664850911164&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-Xmn256m
-Xmn262144k
-Xmn268435456 		# 단위를 표시 안 하면 바이트 단위임.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;a id=&quot;BABHDABI&quot;&gt;&lt;/a&gt;&lt;b&gt;-Xms&lt;i&gt;size&lt;/i&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;힙 메모리(nursery 파트 + tenure 파트)의 최소 및 초기 사이즈를 설정&lt;/b&gt;&lt;/span&gt;하는 옵션.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 옵션이 지정되지 않았다면, nursery 파트에 대한 초기 힙 사이즈는 '&lt;b&gt;-Xmn&lt;/b&gt;' 옵션 또는 '&lt;b&gt;-XX:NewSize&lt;/b&gt;' 옵션을 통해 정해진 사이즈로 지정된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용 예시는 '-Xmn' 옵션과 동일하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;a id=&quot;BABHDABI&quot;&gt;&lt;/a&gt;&lt;b&gt;-Xmx&lt;i&gt;size&lt;/i&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;힙 메모리(nursery 파트 + tenure 파트)의 최대 사이즈를 설정&lt;/b&gt;&lt;/span&gt;하는 옵션.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;JVM Server 모드&lt;/b&gt;의 경우, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;-Xms 와 -Xms 가 동일하게 설정&lt;/b&gt;&lt;/span&gt;된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용 예시는 '-Xmn' 옵션과 동일하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-Xnoclassgc&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;:&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt; 클래스에 대한 GC(Garbage Collection)을 Disable 하는 옵션.&lt;/b&gt; &lt;/span&gt;GC 타임을 없애므로써, 애플리케이션 구동 간에 &lt;b&gt;interruption 을 단축&lt;/b&gt;시킨다. 그러나 메모리 부족에 관한 Exception이 발생할 확률이 매우 높으므로, 주의하여 사용해야 한다.&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-Xprof&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;실행 중인 프로그램을 프로파일링하고, 프로파일링 데이터를 표준 출력으로 보내는 옵션.&lt;/b&gt;&lt;/span&gt; 이 옵션은 프로그램 개발에 유용한 옵션으로, Production 시스템에서는 사용되지 않는다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-Xrs&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;JVM에 의한 OS 신호 사용을 줄이는 옵션.&lt;/b&gt;&lt;/span&gt; 예를 들면, 기본적으로 JVM은 OS가 종료 중이거나, 사용자 로그아웃 중임을 알리는 신호를 OS에서 포착하여 자체적으로 종료하는데, 이 동작으로 인해 사용자가 OS상에서 로그아웃 할 때 Application Server 서비스까지 종료되는 문제가 발생하게 된다. OS 사용자 로그아웃 여부와 관계없이 Java 애플리케이션이 종료되지 않고 실행되기 위해 해당 옵션을 사용한다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-Xshare:&lt;/span&gt;&lt;i&gt;mode&lt;/i&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;*CDS(Class Data Sharing) 모드를 설정하는 옵션.&lt;/b&gt;&lt;/span&gt; 가능한 '&lt;b&gt;mode&lt;/b&gt;' 에 대한 매개변수로는 아래와 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;auto&lt;/b&gt; : &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;CDS가 가능하다면 사용한다&lt;/b&gt;&lt;/span&gt;는 옵션. Java HotSpot 32비트 Client의 디폴트 옵션.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;on&lt;/b&gt; : CDS를 사용해야 하는 옵션으로, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;CDS가 사용될 수 없다면 에러 메시지를 호출하고 JVM 종료.&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;off&lt;/b&gt; : &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;CDS를 사용하지 않는 옵션.&lt;/b&gt; &lt;/span&gt;Java HotSpot 32비트 서버, 64비트 서버, 64비트 클라이언트의 디폴트 옵션.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;dump&lt;/b&gt; : &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;수동으로 CDS 아카이브를 생성.&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;*&lt;/b&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;CDS(Class Data Sharing)&lt;/b&gt; : JVM 기동 시 성능을 향상하기 위한 목적으로, JVM에서 공통으로 사용하는 클래스들을 공유저장소에 위치시키고 이를 각 JVM 들이 공유하여 사용하는 방식을 제공하는 모드.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-XshowSettings:&lt;/span&gt;&lt;i&gt;category&lt;/i&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;설정을 출력&lt;/b&gt;&lt;/span&gt;하고 JVM 실행을 계속 한다. &lt;b&gt;'category'&lt;/b&gt; 매개변수에 들어갈 수 있는 옵션으로는 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;all&lt;/b&gt; : 설정의 모든 카테고리를 출력. 디폴트 옵션이다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;locale&lt;/b&gt; : locale과 관련된 설정을 출력.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;properties&lt;/b&gt; : 시스템 속성과 관련된 설정을 출력.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;vm&lt;/b&gt; : JVM과 관련된 설정을 출력.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-Xss&lt;/span&gt;&lt;i&gt;size&lt;/i&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;스레드 스택 사이즈를 설정하는 옵션.&lt;/b&gt;&lt;/span&gt; 아래는 플랫폼별 스레드 스택 사이즈의 디폴트 값을 나타낸다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;Linux/ARM (32비트) : 320 KB&lt;/li&gt;
&lt;li&gt;Linux/i386 (32비트) : 320 KB&lt;/li&gt;
&lt;li&gt;Linux/x64 (64비트) : 1024 KB&lt;/li&gt;
&lt;li&gt;OS X (64비트) : 1024 KB&lt;/li&gt;
&lt;li&gt;Oracle Solaris/i386 (32비트) : 320 KB&lt;/li&gt;
&lt;li&gt;Oracle Solaris/x64 (64비트) : 1024 KB&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-Xusealtsigs&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;:&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt; JVM 인터널 신호에 대한 SIGUSR1, SIGUSR2를 대신하여 대체 신호를 사용하는 옵션.&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-Xverify:&lt;/span&gt;&lt;i&gt;mode&lt;/i&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;바이트코드 검증자 모드를 설정하는 옵션.&lt;/b&gt; &lt;/span&gt;바이트코드 검증은 클래스 파일이 적절하게 형성되었는지, JVM 스펙에 따른 클래스 파일에 대한 제약사항을 잘 따랐는지를 검증한다. 가능한 '&lt;b&gt;mode&lt;/b&gt;' 매개변수로는 아래와 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;remote&lt;/b&gt; : 부트스트랩 클래스 로더에 의해 로드되지 않는 모든 바이트 코드를 검증. 디폴트 옵션이다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;all&lt;/b&gt; : 모든 바이트코드를 검증.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;none&lt;/b&gt; : 모든 바이트 코드에 대한 검증을 Disable&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1664840114701&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;java&quot; data-og-description=&quot;Large Pages Also known as huge pages, large pages are memory pages that are significantly larger than the standard memory page size (which varies depending on the processor and operating system). Large pages optimize processor Translation-Lookaside Buffers&quot; data-og-host=&quot;docs.oracle.com&quot; data-og-source-url=&quot;https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html&quot; data-og-url=&quot;https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;java&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Large Pages Also known as huge pages, large pages are memory pages that are significantly larger than the standard memory page size (which varies depending on the processor and operating system). Large pages optimize processor Translation-Lookaside Buffers&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.oracle.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@vrooming13/JNI-JAVA-Native-Interface&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://velog.io/@vrooming13/JNI-JAVA-Native-Interface&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1664844171984&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;JNI (JAVA Native Interface)&quot; data-og-description=&quot;  JNI란? 자바 네이티브 인터페이스는 자바 가상머신(JVM)위에서 실행되고 있는 자바코드가 네이티브 응용 프로그램(하드웨어와 운영 체제 플랫폼에 종속된 프로그램들) 그리고 C, C++ 그리고 어&quot; data-og-host=&quot;velog.io&quot; data-og-source-url=&quot;https://velog.io/@vrooming13/JNI-JAVA-Native-Interface&quot; data-og-url=&quot;https://velog.io/@vrooming13/JNI-JAVA-Native-Interface&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bKX2Cu/hyP0G4pn1k/0hL81fuQ09JBk5DPcPzeu0/img.png?width=440&amp;amp;height=268&amp;amp;face=0_0_440_268,https://scrap.kakaocdn.net/dn/fHykp/hyP0Ky0b20/kExPSPpSijKwoSMLHJ1SJk/img.png?width=440&amp;amp;height=268&amp;amp;face=0_0_440_268,https://scrap.kakaocdn.net/dn/bfy3S6/hyP0F5vGTI/ToEd7As0akJbG5MzAOBkH0/img.jpg?width=500&amp;amp;height=500&amp;amp;face=0_0_500_500&quot;&gt;&lt;a href=&quot;https://velog.io/@vrooming13/JNI-JAVA-Native-Interface&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://velog.io/@vrooming13/JNI-JAVA-Native-Interface&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bKX2Cu/hyP0G4pn1k/0hL81fuQ09JBk5DPcPzeu0/img.png?width=440&amp;amp;height=268&amp;amp;face=0_0_440_268,https://scrap.kakaocdn.net/dn/fHykp/hyP0Ky0b20/kExPSPpSijKwoSMLHJ1SJk/img.png?width=440&amp;amp;height=268&amp;amp;face=0_0_440_268,https://scrap.kakaocdn.net/dn/bfy3S6/hyP0F5vGTI/ToEd7As0akJbG5MzAOBkH0/img.jpg?width=500&amp;amp;height=500&amp;amp;face=0_0_500_500');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;JNI (JAVA Native Interface)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;  JNI란? 자바 네이티브 인터페이스는 자바 가상머신(JVM)위에서 실행되고 있는 자바코드가 네이티브 응용 프로그램(하드웨어와 운영 체제 플랫폼에 종속된 프로그램들) 그리고 C, C++ 그리고 어&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;velog.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://shinjekim.github.io/java/2020/01/06/%EC%9E%90%EB%B0%94%EC%9D%98-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EA%B5%AC%EC%A1%B0/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://shinjekim.github.io/java/2020/01/06/%EC%9E%90%EB%B0%94%EC%9D%98-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EA%B5%AC%EC%A1%B0/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1664851054456&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;[Java] 자바의 메모리 구조 &amp;middot; Challengist&quot; data-og-description=&quot;[Java] 자바의 메모리 구조 06 Jan 2020 | Java 자바의 메모리 구조 자바(JVM)의 메모리 영역은 heap, stack, static이 전부인것으로 알고있었다. 그런데 구글링을 해보니 블로그마다 설명하는 용어가 조금씩 &quot; data-og-host=&quot;shinjekim.github.io&quot; data-og-source-url=&quot;https://shinjekim.github.io/java/2020/01/06/%EC%9E%90%EB%B0%94%EC%9D%98-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EA%B5%AC%EC%A1%B0/&quot; data-og-url=&quot;https://shinjekim.github.io/java/2020/01/06/%EC%9E%90%EB%B0%94%EC%9D%98-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EA%B5%AC%EC%A1%B0/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/blEZuC/hyP0GpXLla/O1r4wEm6fbifZ8YP2dRy20/img.png?width=1444&amp;amp;height=758&amp;amp;face=0_0_1444_758,https://scrap.kakaocdn.net/dn/yeT48/hyP0DNySeU/1kcTvnQS0R6zhVh86Uq5jk/img.png?width=1472&amp;amp;height=478&amp;amp;face=0_0_1472_478&quot;&gt;&lt;a href=&quot;https://shinjekim.github.io/java/2020/01/06/%EC%9E%90%EB%B0%94%EC%9D%98-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EA%B5%AC%EC%A1%B0/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://shinjekim.github.io/java/2020/01/06/%EC%9E%90%EB%B0%94%EC%9D%98-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EA%B5%AC%EC%A1%B0/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/blEZuC/hyP0GpXLla/O1r4wEm6fbifZ8YP2dRy20/img.png?width=1444&amp;amp;height=758&amp;amp;face=0_0_1444_758,https://scrap.kakaocdn.net/dn/yeT48/hyP0DNySeU/1kcTvnQS0R6zhVh86Uq5jk/img.png?width=1472&amp;amp;height=478&amp;amp;face=0_0_1472_478');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[Java] 자바의 메모리 구조 &amp;middot; Challengist&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;[Java] 자바의 메모리 구조 06 Jan 2020 | Java 자바의 메모리 구조 자바(JVM)의 메모리 영역은 heap, stack, static이 전부인것으로 알고있었다. 그런데 구글링을 해보니 블로그마다 설명하는 용어가 조금씩&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;shinjekim.github.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://johngrib.github.io/wiki/jvm-memory/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://johngrib.github.io/wiki/jvm-memory/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1664851058792&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;JVM 메모리 구조와 GC&quot; data-og-description=&quot;작성중인 문서&quot; data-og-host=&quot;johngrib.github.io&quot; data-og-source-url=&quot;https://johngrib.github.io/wiki/jvm-memory/&quot; data-og-url=&quot;https://johngrib.github.io/wiki/jvm-memory/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bKi4Bu/hyP0Dtc33O/ptZcfLTLqMida7flh8SIn0/img.png?width=170&amp;amp;height=170&amp;amp;face=0_0_170_170&quot;&gt;&lt;a href=&quot;https://johngrib.github.io/wiki/jvm-memory/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://johngrib.github.io/wiki/jvm-memory/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bKi4Bu/hyP0Dtc33O/ptZcfLTLqMida7flh8SIn0/img.png?width=170&amp;amp;height=170&amp;amp;face=0_0_170_170');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;JVM 메모리 구조와 GC&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;작성중인 문서&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;johngrib.github.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Java</category>
      <category>java non-standard option</category>
      <category>java Xmnsize</category>
      <category>java Xmssize</category>
      <category>java Xmxsize</category>
      <category>java 실행 옵션</category>
      <category>java 옵션</category>
      <author>코_노</author>
      <guid isPermaLink="true">https://co-no.tistory.com/114</guid>
      <comments>https://co-no.tistory.com/entry/Java-jvm-%EC%8B%A4%ED%96%89-%EC%98%B5%EC%85%98-2-Non-Standard-Options#entry114comment</comments>
      <pubDate>Tue, 4 Oct 2022 13:15:23 +0900</pubDate>
    </item>
  </channel>
</rss>