<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>확장성 Archives - 어제와 내일의 나 그 사이의 이야기</title>
	<atom:link href="https://lycos7560.com/tag/%ED%99%95%EC%9E%A5%EC%84%B1/feed/" rel="self" type="application/rss+xml" />
	<link></link>
	<description>생각의 흐름을 타고 다니며 만드는 블로그</description>
	<lastBuildDate>Wed, 04 Feb 2026 20:16:10 +0000</lastBuildDate>
	<language>ko-KR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://lycos7560.com/wp-content/uploads/2022/11/cropped-cropped-cropped-log-1-150x150-1-80x80.png</url>
	<title>확장성 Archives - 어제와 내일의 나 그 사이의 이야기</title>
	<link></link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>MySQL 데이터베이스 &#038; 테이블 용량 확인</title>
		<link>https://lycos7560.com/etc/mysql-%eb%8d%b0%ec%9d%b4%ed%84%b0%eb%b2%a0%ec%9d%b4%ec%8a%a4-%ed%85%8c%ec%9d%b4%eb%b8%94-%ec%9a%a9%eb%9f%89-%ed%99%95%ec%9d%b8/40431/</link>
					<comments>https://lycos7560.com/etc/mysql-%eb%8d%b0%ec%9d%b4%ed%84%b0%eb%b2%a0%ec%9d%b4%ec%8a%a4-%ed%85%8c%ec%9d%b4%eb%b8%94-%ec%9a%a9%eb%9f%89-%ed%99%95%ec%9d%b8/40431/#respond</comments>
		
		<dc:creator><![CDATA[lycos7560]]></dc:creator>
		<pubDate>Wed, 04 Feb 2026 20:16:04 +0000</pubDate>
				<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[개인 공부 저장용]]></category>
		<category><![CDATA[기타]]></category>
		<category><![CDATA[AWS_RDS]]></category>
		<category><![CDATA[Backend]]></category>
		<category><![CDATA[BackendDeveloper]]></category>
		<category><![CDATA[BigData]]></category>
		<category><![CDATA[CloudDatabase]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[DataAnalysis]]></category>
		<category><![CDATA[DataBase]]></category>
		<category><![CDATA[DatabaseEngineer]]></category>
		<category><![CDATA[DatabaseHealth]]></category>
		<category><![CDATA[DatabaseOptimization]]></category>
		<category><![CDATA[DatabaseSize]]></category>
		<category><![CDATA[DatabaseStorage]]></category>
		<category><![CDATA[DatabaseTuning]]></category>
		<category><![CDATA[DataCleanup]]></category>
		<category><![CDATA[DataFree]]></category>
		<category><![CDATA[DataLength]]></category>
		<category><![CDATA[DataManagement]]></category>
		<category><![CDATA[DataStructure]]></category>
		<category><![CDATA[DataUsage]]></category>
		<category><![CDATA[DBA]]></category>
		<category><![CDATA[DBMS]]></category>
		<category><![CDATA[DBPerformance]]></category>
		<category><![CDATA[DBStatistics]]></category>
		<category><![CDATA[DB관리]]></category>
		<category><![CDATA[DB단편화]]></category>
		<category><![CDATA[DB모니터링]]></category>
		<category><![CDATA[DB상태체크]]></category>
		<category><![CDATA[DB용량확인]]></category>
		<category><![CDATA[DB튜닝]]></category>
		<category><![CDATA[DeveloperLife]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[DiskUsage]]></category>
		<category><![CDATA[Efficiency]]></category>
		<category><![CDATA[Fragmentation]]></category>
		<category><![CDATA[Indexing]]></category>
		<category><![CDATA[IndexSize]]></category>
		<category><![CDATA[InformationDesign]]></category>
		<category><![CDATA[InformationSchema]]></category>
		<category><![CDATA[Insight]]></category>
		<category><![CDATA[Maintenance]]></category>
		<category><![CDATA[mariadb]]></category>
		<category><![CDATA[Metrics]]></category>
		<category><![CDATA[Monitoring]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Optimization]]></category>
		<category><![CDATA[OptimizeTable]]></category>
		<category><![CDATA[PerformanceTuning]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[QueryOptimization]]></category>
		<category><![CDATA[QueryPerformance]]></category>
		<category><![CDATA[QueryTips]]></category>
		<category><![CDATA[RDBMS]]></category>
		<category><![CDATA[RelationalDatabase]]></category>
		<category><![CDATA[Scalability]]></category>
		<category><![CDATA[ServerManagement]]></category>
		<category><![CDATA[ServerSide]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQLQuery]]></category>
		<category><![CDATA[SQLTutorial]]></category>
		<category><![CDATA[Storage]]></category>
		<category><![CDATA[SystemAdministration]]></category>
		<category><![CDATA[TableRows]]></category>
		<category><![CDATA[TableSize]]></category>
		<category><![CDATA[TechnicalPost]]></category>
		<category><![CDATA[TechStack]]></category>
		<category><![CDATA[WebDevelopment]]></category>
		<category><![CDATA[개발자일상]]></category>
		<category><![CDATA[공부]]></category>
		<category><![CDATA[관계형데이터베이스]]></category>
		<category><![CDATA[기술블로그]]></category>
		<category><![CDATA[기초]]></category>
		<category><![CDATA[데브옵스]]></category>
		<category><![CDATA[데이터구조]]></category>
		<category><![CDATA[데이터베이스]]></category>
		<category><![CDATA[데이터베이스기초]]></category>
		<category><![CDATA[데이터분석]]></category>
		<category><![CDATA[데이터사용량]]></category>
		<category><![CDATA[데이터정리]]></category>
		<category><![CDATA[디스크사용량]]></category>
		<category><![CDATA[마리아DB]]></category>
		<category><![CDATA[백엔드]]></category>
		<category><![CDATA[백엔드개발자]]></category>
		<category><![CDATA[빅데이터]]></category>
		<category><![CDATA[서버관리]]></category>
		<category><![CDATA[서버사이드]]></category>
		<category><![CDATA[성능최적화]]></category>
		<category><![CDATA[시스템관리]]></category>
		<category><![CDATA[용량최적화]]></category>
		<category><![CDATA[웹개발]]></category>
		<category><![CDATA[유지보수]]></category>
		<category><![CDATA[인덱스용량]]></category>
		<category><![CDATA[인덱싱]]></category>
		<category><![CDATA[인사이트]]></category>
		<category><![CDATA[인포메이션스키마]]></category>
		<category><![CDATA[정보설계]]></category>
		<category><![CDATA[지표분석]]></category>
		<category><![CDATA[최적화]]></category>
		<category><![CDATA[코딩]]></category>
		<category><![CDATA[쿼리꿀팁]]></category>
		<category><![CDATA[쿼리최적화]]></category>
		<category><![CDATA[클라우드DB]]></category>
		<category><![CDATA[테이블용량]]></category>
		<category><![CDATA[프로그래밍]]></category>
		<category><![CDATA[행개수]]></category>
		<category><![CDATA[확장성]]></category>
		<category><![CDATA[효율성]]></category>
		<guid isPermaLink="false">https://lycos7560.com/?p=40431</guid>

					<description><![CDATA[<p>1. 모든 데이터베이스별 총 용량 확인 현재 서버에 있는 모든 DB의 크기를 한눈에 비교하고 싶을 때 사용합니다. 용량이 큰 순서대로 정렬되어 출력됩니다. 2. 특정 데이터베이스 내의 테이블별 용량 상세 확인 &#8220;어떤 테이블이 용량을 다 잡아먹고 있지?&#8221;라는 궁금증이 생겼을 때 사용합니다. 데이터 크기와 인덱스 크기를 구분해서 보여줍니다. 데이터 크기와 인덱스 크기를 구분 3. 전체 서버의 총 [&#8230;]</p>
<p>The post <a href="https://lycos7560.com/etc/mysql-%eb%8d%b0%ec%9d%b4%ed%84%b0%eb%b2%a0%ec%9d%b4%ec%8a%a4-%ed%85%8c%ec%9d%b4%eb%b8%94-%ec%9a%a9%eb%9f%89-%ed%99%95%ec%9d%b8/40431/">MySQL 데이터베이스 &amp; 테이블 용량 확인</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></description>
										<content:encoded><![CDATA[				<div class="wp-block-uagb-table-of-contents uagb-toc__align-left uagb-toc__columns-1  uagb-block-37ada8aa      "
					data-scroll= "1"
					data-offset= "30"
					style=""
				>
				<div class="uagb-toc__wrap">
						<div class="uagb-toc__title">
							목차						</div>
																						<div class="uagb-toc__list-wrap ">
						<ol class="uagb-toc__list"><li class="uagb-toc__list"><a href="#1-모든-데이터베이스별-총-용량-확인" class="uagb-toc-link__trigger">1. 모든 데이터베이스별 총 용량 확인</a><li class="uagb-toc__list"><a href="#2-특정-데이터베이스-내의-테이블별-용량-상세-확인" class="uagb-toc-link__trigger">2. 특정 데이터베이스 내의 테이블별 용량 상세 확인</a><li class="uagb-toc__list"><a href="#3-전체-서버의-총-합계-용량-확인" class="uagb-toc-link__trigger">3. 전체 서버의 총 합계 용량 확인</a><li class="uagb-toc__list"><a href="#4-참고" class="uagb-toc-link__trigger">4. 참고</a></ol>					</div>
									</div>
				</div>
			


<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">1. 모든 데이터베이스별 총 용량 확인</h2>



<p>현재 서버에 있는 <strong>모든 DB의 크기를 한눈에 비교</strong>하고 싶을 때 사용합니다. </p>



<p>용량이 큰 순서대로 정렬되어 출력됩니다.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="sql" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">SELECT 
    table_schema AS 'Database Name',
    ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS 'Size (MB)',
    ROUND(SUM(data_free) / 1024 / 1024, 2) AS 'Free Space (MB)'
FROM 
    information_schema.tables
GROUP BY 
    table_schema
ORDER BY 
    (SUM(data_length + index_length)) DESC;</pre>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">2. 특정 데이터베이스 내의 테이블별 용량 상세 확인</h2>



<p>&#8220;어떤 테이블이 용량을 다 잡아먹고 있지?&#8221;라는 궁금증이 생겼을 때 사용합니다. </p>



<p><strong>데이터 크기와 인덱스 크기를 구분</strong>해서 보여줍니다.</p>



<p><strong>데이터 크기와 인덱스 크기를 구분</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="sql" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">SELECT 
    table_name AS 'Table Name',
    table_rows AS 'Total Rows',
    ROUND(data_length / 1024 / 1024, 2) AS 'Data Size (MB)',
    ROUND(index_length / 1024 / 1024, 2) AS 'Index Size (MB)',
    ROUND((data_length + index_length) / 1024 / 1024, 2) AS 'Total Size (MB)'
FROM 
    information_schema.tables
WHERE 
    table_schema = '데이터베이스명' -- 여기에 DB 이름 입력
ORDER BY 
    (data_length + index_length) DESC;</pre>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">3. 전체 서버의 총 합계 용량 확인</h2>



<p>서버 전체에서 <strong>MySQL이 사용하는 총 디스크 용량</strong>만 깔끔하게 보고 싶을 때 유용합니다.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="sql" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">SELECT 
    ROUND(SUM(data_length + index_length) / 1024 / 1024 / 1024, 2) AS 'Total Global Size (GB)'
FROM 
    information_schema.tables;</pre>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">4. 참고</h2>



<ul class="wp-block-list">
<li><strong>data_length</strong>: 실제 데이터가 들어있는 물리적 크기입니다.</li>



<li><strong>index_length</strong>: 인덱스(색인)가 차지하는 크기입니다. 데이터는 적은데 인덱스가 너무 크면 최적화(<code>OPTIMIZE TABLE</code>)를 고려해야 합니다.</li>



<li><strong>data_free</strong>: <code>DELETE</code> 등으로 삭제된 행이 차지하던 &#8216;비어있는 공간&#8217;입니다. 이 값이 너무 크면 디스크 공간 낭비가 심하다는 뜻입니다.</li>
</ul>



<p></p>
<p>The post <a href="https://lycos7560.com/etc/mysql-%eb%8d%b0%ec%9d%b4%ed%84%b0%eb%b2%a0%ec%9d%b4%ec%8a%a4-%ed%85%8c%ec%9d%b4%eb%b8%94-%ec%9a%a9%eb%9f%89-%ed%99%95%ec%9d%b8/40431/">MySQL 데이터베이스 &amp; 테이블 용량 확인</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://lycos7560.com/etc/mysql-%eb%8d%b0%ec%9d%b4%ed%84%b0%eb%b2%a0%ec%9d%b4%ec%8a%a4-%ed%85%8c%ec%9d%b4%eb%b8%94-%ec%9a%a9%eb%9f%89-%ed%99%95%ec%9d%b8/40431/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Apache Virtual Host Guide (Apache 가상 호스트 설정)</title>
		<link>https://lycos7560.com/ubuntu/apache-%ea%b0%80%ec%83%81%ed%98%b8%ec%8a%a4%ed%8a%b8-%ec%84%a4%ec%a0%95-%ea%b0%80%ec%9d%b4%eb%93%9c/40358/</link>
					<comments>https://lycos7560.com/ubuntu/apache-%ea%b0%80%ec%83%81%ed%98%b8%ec%8a%a4%ed%8a%b8-%ec%84%a4%ec%a0%95-%ea%b0%80%ec%9d%b4%eb%93%9c/40358/#respond</comments>
		
		<dc:creator><![CDATA[lycos7560]]></dc:creator>
		<pubDate>Tue, 25 Nov 2025 14:56:56 +0000</pubDate>
				<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[기타]]></category>
		<category><![CDATA[301Redirect]]></category>
		<category><![CDATA[301리다이렉트]]></category>
		<category><![CDATA[403Forbidden]]></category>
		<category><![CDATA[404NotFound]]></category>
		<category><![CDATA[500Error]]></category>
		<category><![CDATA[502Error]]></category>
		<category><![CDATA[503Error]]></category>
		<category><![CDATA[504GatewayTimeout]]></category>
		<category><![CDATA[AccessControl]]></category>
		<category><![CDATA[AccessLog]]></category>
		<category><![CDATA[AllowOverride]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[Apache2]]></category>
		<category><![CDATA[ApacheModules]]></category>
		<category><![CDATA[ARecord]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[Backend]]></category>
		<category><![CDATA[Backup]]></category>
		<category><![CDATA[BasicAuth]]></category>
		<category><![CDATA[BestPractices]]></category>
		<category><![CDATA[Brotli]]></category>
		<category><![CDATA[BrowserCache]]></category>
		<category><![CDATA[Caching]]></category>
		<category><![CDATA[Certbot]]></category>
		<category><![CDATA[Cheatsheet]]></category>
		<category><![CDATA[chmod]]></category>
		<category><![CDATA[Chown]]></category>
		<category><![CDATA[CLI]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[Clustering]]></category>
		<category><![CDATA[CNAME]]></category>
		<category><![CDATA[command]]></category>
		<category><![CDATA[Compression]]></category>
		<category><![CDATA[ConfigTest]]></category>
		<category><![CDATA[CrtFile]]></category>
		<category><![CDATA[CSR]]></category>
		<category><![CDATA[CSRF]]></category>
		<category><![CDATA[Curl]]></category>
		<category><![CDATA[Debian]]></category>
		<category><![CDATA[Debug]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[DirectoryIndex]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[DNS]]></category>
		<category><![CDATA[DocumentRoot]]></category>
		<category><![CDATA[Domain]]></category>
		<category><![CDATA[EC2]]></category>
		<category><![CDATA[ErrorLog]]></category>
		<category><![CDATA[firewall]]></category>
		<category><![CDATA[Flask]]></category>
		<category><![CDATA[FreeSSL]]></category>
		<category><![CDATA[Guide]]></category>
		<category><![CDATA[Gzip]]></category>
		<category><![CDATA[HighAvailability]]></category>
		<category><![CDATA[Hosting]]></category>
		<category><![CDATA[HowTo]]></category>
		<category><![CDATA[HSTS]]></category>
		<category><![CDATA[htpasswd]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[HTTP2]]></category>
		<category><![CDATA[HTTP3]]></category>
		<category><![CDATA[HTTPS]]></category>
		<category><![CDATA[Infrastructure]]></category>
		<category><![CDATA[IP]]></category>
		<category><![CDATA[Iptables]]></category>
		<category><![CDATA[Journalctl]]></category>
		<category><![CDATA[KeepAlive]]></category>
		<category><![CDATA[KeyFile]]></category>
		<category><![CDATA[LetsEncrypt]]></category>
		<category><![CDATA[LinuxCommands]]></category>
		<category><![CDATA[LinuxServer]]></category>
		<category><![CDATA[LoadBalancing]]></category>
		<category><![CDATA[LoadTest]]></category>
		<category><![CDATA[LogAnalysis]]></category>
		<category><![CDATA[Manual]]></category>
		<category><![CDATA[mod_deflate]]></category>
		<category><![CDATA[mod_expires]]></category>
		<category><![CDATA[mod_headers]]></category>
		<category><![CDATA[mod_proxy]]></category>
		<category><![CDATA[mod_rewrite]]></category>
		<category><![CDATA[mod_ssl]]></category>
		<category><![CDATA[MPM]]></category>
		<category><![CDATA[MPM_Event]]></category>
		<category><![CDATA[MPM_Worker]]></category>
		<category><![CDATA[NameServer]]></category>
		<category><![CDATA[netstat]]></category>
		<category><![CDATA[network]]></category>
		<category><![CDATA[Nodejs]]></category>
		<category><![CDATA[OpenSSL]]></category>
		<category><![CDATA[Optimization]]></category>
		<category><![CDATA[options]]></category>
		<category><![CDATA[PemFile]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Permission]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[port]]></category>
		<category><![CDATA[PortForwarding]]></category>
		<category><![CDATA[PrivateKey]]></category>
		<category><![CDATA[Proxy]]></category>
		<category><![CDATA[ProxyPass]]></category>
		<category><![CDATA[ProxyPassReverse]]></category>
		<category><![CDATA[PublicKey]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Redirect]]></category>
		<category><![CDATA[Reference]]></category>
		<category><![CDATA[RequireAllGranted]]></category>
		<category><![CDATA[Restore]]></category>
		<category><![CDATA[ReverseProxy]]></category>
		<category><![CDATA[Rewrite]]></category>
		<category><![CDATA[RewriteRule]]></category>
		<category><![CDATA[Scalability]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[SelfSigned]]></category>
		<category><![CDATA[ServerConfig]]></category>
		<category><![CDATA[ServerMaintenance]]></category>
		<category><![CDATA[ServerMigration]]></category>
		<category><![CDATA[ServerMonitoring]]></category>
		<category><![CDATA[ServerName]]></category>
		<category><![CDATA[Service]]></category>
		<category><![CDATA[SpeedUp]]></category>
		<category><![CDATA[ss]]></category>
		<category><![CDATA[SSL]]></category>
		<category><![CDATA[study]]></category>
		<category><![CDATA[subdomain]]></category>
		<category><![CDATA[sysadmin]]></category>
		<category><![CDATA[systemctl]]></category>
		<category><![CDATA[systemd]]></category>
		<category><![CDATA[TCP]]></category>
		<category><![CDATA[Terminal]]></category>
		<category><![CDATA[TLS]]></category>
		<category><![CDATA[Tomcat]]></category>
		<category><![CDATA[Troubleshooting]]></category>
		<category><![CDATA[TUTORIAL]]></category>
		<category><![CDATA[UbuntuServer]]></category>
		<category><![CDATA[ufw]]></category>
		<category><![CDATA[URLRewrite]]></category>
		<category><![CDATA[Vhost]]></category>
		<category><![CDATA[VirtualHost]]></category>
		<category><![CDATA[VPS]]></category>
		<category><![CDATA[WAS]]></category>
		<category><![CDATA[WebAdmin]]></category>
		<category><![CDATA[WebDev]]></category>
		<category><![CDATA[WebPerformance]]></category>
		<category><![CDATA[WebSecurity]]></category>
		<category><![CDATA[WebServer]]></category>
		<category><![CDATA[WebSocket]]></category>
		<category><![CDATA[Wget]]></category>
		<category><![CDATA[WSS]]></category>
		<category><![CDATA[XSS]]></category>
		<category><![CDATA[가상호스트]]></category>
		<category><![CDATA[가이드]]></category>
		<category><![CDATA[고가용성]]></category>
		<category><![CDATA[공부]]></category>
		<category><![CDATA[권한설정]]></category>
		<category><![CDATA[기본인증]]></category>
		<category><![CDATA[기초]]></category>
		<category><![CDATA[네임서버]]></category>
		<category><![CDATA[네트워크]]></category>
		<category><![CDATA[데비안]]></category>
		<category><![CDATA[뎁스옵스]]></category>
		<category><![CDATA[도메인]]></category>
		<category><![CDATA[디버깅]]></category>
		<category><![CDATA[레퍼런스]]></category>
		<category><![CDATA[렛츠인크립트]]></category>
		<category><![CDATA[로그분석]]></category>
		<category><![CDATA[로드밸런싱]]></category>
		<category><![CDATA[리눅스명령어]]></category>
		<category><![CDATA[리눅스서버]]></category>
		<category><![CDATA[리다이렉트]]></category>
		<category><![CDATA[리버스프록시]]></category>
		<category><![CDATA[매뉴얼]]></category>
		<category><![CDATA[명령어]]></category>
		<category><![CDATA[모범사례]]></category>
		<category><![CDATA[무료인증서]]></category>
		<category><![CDATA[문제해결]]></category>
		<category><![CDATA[방화벽]]></category>
		<category><![CDATA[백업]]></category>
		<category><![CDATA[백엔드]]></category>
		<category><![CDATA[보안]]></category>
		<category><![CDATA[복구]]></category>
		<category><![CDATA[부하테스트]]></category>
		<category><![CDATA[브라우저캐시]]></category>
		<category><![CDATA[사설인증서]]></category>
		<category><![CDATA[사용법]]></category>
		<category><![CDATA[서버모니터링]]></category>
		<category><![CDATA[서버설정]]></category>
		<category><![CDATA[서버유지보수]]></category>
		<category><![CDATA[서버이전]]></category>
		<category><![CDATA[서브도메인]]></category>
		<category><![CDATA[설정확인]]></category>
		<category><![CDATA[성능최적화]]></category>
		<category><![CDATA[속도향상]]></category>
		<category><![CDATA[시스템관리]]></category>
		<category><![CDATA[아파치]]></category>
		<category><![CDATA[아파치2]]></category>
		<category><![CDATA[아파치모듈]]></category>
		<category><![CDATA[압축]]></category>
		<category><![CDATA[액세스로그]]></category>
		<category><![CDATA[에러로그]]></category>
		<category><![CDATA[우분투]]></category>
		<category><![CDATA[웹개발]]></category>
		<category><![CDATA[웹보안]]></category>
		<category><![CDATA[웹서버]]></category>
		<category><![CDATA[웹성능]]></category>
		<category><![CDATA[웹소켓]]></category>
		<category><![CDATA[웹어드민]]></category>
		<category><![CDATA[웹호스팅]]></category>
		<category><![CDATA[인증서]]></category>
		<category><![CDATA[인프라]]></category>
		<category><![CDATA[접근제어]]></category>
		<category><![CDATA[최적화]]></category>
		<category><![CDATA[치트시트]]></category>
		<category><![CDATA[캐싱]]></category>
		<category><![CDATA[클라우드]]></category>
		<category><![CDATA[클러스터링]]></category>
		<category><![CDATA[터미널]]></category>
		<category><![CDATA[튜토리얼]]></category>
		<category><![CDATA[포트]]></category>
		<category><![CDATA[포트포워딩]]></category>
		<category><![CDATA[프록시]]></category>
		<category><![CDATA[확장성]]></category>
		<guid isPermaLink="false">https://lycos7560.com/?p=40358</guid>

					<description><![CDATA[<p>기본 설정 확인 Apache 상태 및 설정 검증 필수 모듈 활성화 가상호스트 생성 1. 설정 파일 생성 2. 기본 HTTP 가상호스트 3. HTTP → HTTPS 리다이렉트 4. HTTPS 가상호스트 (정적 파일) 다양한 설정 예제 리버스 프록시 WebSocket 프록시 여러 백엔드로 로드 밸런싱 경로별 다른 백엔드 라우팅 특정 IP만 접근 허용 SSL/HTTPS 설정 Certbot으로 SSL 인증서 [&#8230;]</p>
<p>The post <a href="https://lycos7560.com/ubuntu/apache-%ea%b0%80%ec%83%81%ed%98%b8%ec%8a%a4%ed%8a%b8-%ec%84%a4%ec%a0%95-%ea%b0%80%ec%9d%b4%eb%93%9c/40358/">Apache Virtual Host Guide (Apache 가상 호스트 설정)</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></description>
										<content:encoded><![CDATA[				<div class="wp-block-uagb-table-of-contents uagb-toc__align-left uagb-toc__columns-1  uagb-block-692d8850      "
					data-scroll= "1"
					data-offset= "30"
					style=""
				>
				<div class="uagb-toc__wrap">
						<div class="uagb-toc__title">
							목차						</div>
																						<div class="uagb-toc__list-wrap ">
						<ol class="uagb-toc__list"><li class="uagb-toc__list"><a href="#기본-설정-확인" class="uagb-toc-link__trigger">기본 설정 확인</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#apache-상태-및-설정-검증" class="uagb-toc-link__trigger">Apache 상태 및 설정 검증</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#필수-모듈-활성화" class="uagb-toc-link__trigger">필수 모듈 활성화</a></li></ul></li><li class="uagb-toc__list"><a href="#가상호스트-생성" class="uagb-toc-link__trigger">가상호스트 생성</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#1-설정-파일-생성" class="uagb-toc-link__trigger">1. 설정 파일 생성</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#2-기본-http-가상호스트" class="uagb-toc-link__trigger">2. 기본 HTTP 가상호스트</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#3-http-https-리다이렉트" class="uagb-toc-link__trigger">3. HTTP → HTTPS 리다이렉트</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#4-https-가상호스트-정적-파일" class="uagb-toc-link__trigger">4. HTTPS 가상호스트 (정적 파일)</a></li></ul></li></ul></li><li class="uagb-toc__list"><a href="#다양한-설정-예제" class="uagb-toc-link__trigger">다양한 설정 예제</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#리버스-프록시" class="uagb-toc-link__trigger">리버스 프록시</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#websocket-프록시" class="uagb-toc-link__trigger">WebSocket 프록시</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#여러-백엔드로-로드-밸런싱" class="uagb-toc-link__trigger">여러 백엔드로 로드 밸런싱</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#경로별-다른-백엔드-라우팅" class="uagb-toc-link__trigger">경로별 다른 백엔드 라우팅</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#특정-ip만-접근-허용" class="uagb-toc-link__trigger">특정 IP만 접근 허용</a></li></ul></li></ul></li></ul></li><li class="uagb-toc__list"><a href="#sslhttps-설정" class="uagb-toc-link__trigger">SSL/HTTPS 설정</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#certbot으로-ssl-인증서-발급" class="uagb-toc-link__trigger">Certbot으로 SSL 인증서 발급</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#ssl-설정-최적화" class="uagb-toc-link__trigger">SSL 설정 최적화</a></li></ul></li></ul></li></ul></li></ul></li><li class="uagb-toc__list"><a href="#가상호스트-관리" class="uagb-toc-link__trigger">가상호스트 관리</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#활성화비활성화" class="uagb-toc-link__trigger">활성화/비활성화</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#모듈-관리" class="uagb-toc-link__trigger">모듈 관리</a></li></ul></li></ul></li></ul></li></ul></li></ul></li><li class="uagb-toc__list"><a href="#문제-해결" class="uagb-toc-link__trigger">문제 해결</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#로그-확인" class="uagb-toc-link__trigger">로그 확인</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#연결-테스트" class="uagb-toc-link__trigger">연결 테스트</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#포트-및-프로세스-확인" class="uagb-toc-link__trigger">포트 및 프로세스 확인</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#일반적인-문제-해결" class="uagb-toc-link__trigger">일반적인 문제 해결</a></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li><li class="uagb-toc__list"><a href="#보안-강화" class="uagb-toc-link__trigger">보안 강화</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#보안-헤더-설정" class="uagb-toc-link__trigger">보안 헤더 설정</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#접근-제어" class="uagb-toc-link__trigger">접근 제어</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#htpasswd-파일-생성" class="uagb-toc-link__trigger">.htpasswd 파일 생성</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#rate-limiting-mod-ratelimit" class="uagb-toc-link__trigger">Rate Limiting (mod_ratelimit)</a></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li><li class="uagb-toc__list"><a href="#성능-최적화" class="uagb-toc-link__trigger">성능 최적화</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#캐싱-설정" class="uagb-toc-link__trigger">캐싱 설정</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#gzip-brotli-압축" class="uagb-toc-link__trigger">Gzip &amp; Brotli 압축</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#keepalive-설정" class="uagb-toc-link__trigger">KeepAlive 설정</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#mpm-설정-최적화" class="uagb-toc-link__trigger">MPM 설정 최적화</a></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li><li class="uagb-toc__list"><a href="#디렉토리-구조" class="uagb-toc-link__trigger">디렉토리 구조</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#apache-설정-파일-구조" class="uagb-toc-link__trigger">Apache 설정 파일 구조</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#웹-컨텐츠-디렉토리" class="uagb-toc-link__trigger">웹 컨텐츠 디렉토리</a></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li><li class="uagb-toc__list"><a href="#유용한-명령어-모음" class="uagb-toc-link__trigger">유용한 명령어 모음</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#빠른-참조" class="uagb-toc-link__trigger">빠른 참조</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#자주-사용하는-작업" class="uagb-toc-link__trigger">자주 사용하는 작업</a></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li><li class="uagb-toc__list"><a href="#문제-상황별-체크리스트" class="uagb-toc-link__trigger">문제 상황별 체크리스트</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#사이트가-접속되지-않을-때" class="uagb-toc-link__trigger">사이트가 접속되지 않을 때</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#502-bad-gateway-발생-시" class="uagb-toc-link__trigger">502 Bad Gateway 발생 시</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#ssl-인증서-오류-시" class="uagb-toc-link__trigger">SSL 인증서 오류 시</a></ul></ul></ul></ul></ul></ul></ul></ul></ul></ul></ul></ol>					</div>
									</div>
				</div>
			


<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">기본 설정 확인</h2>



<h3 class="wp-block-heading">Apache 상태 및 설정 검증</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># Apache 서비스 상태 확인
sudo systemctl status apache2

# 설정 파일 문법 검사
sudo apache2ctl configtest

# 활성화된 가상호스트 목록 확인
sudo apache2ctl -S

# Apache 버전 확인
apache2 -v

# 로드된 모듈 확인
apache2ctl -M
</pre>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">필수 모듈 활성화</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># 프록시 및 SSL 관련 모듈 활성화
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod ssl
sudo a2enmod rewrite
sudo a2enmod headers

# 변경사항 적용
sudo systemctl restart apache2
</pre>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">가상호스트 생성</h2>



<h3 class="wp-block-heading">1. 설정 파일 생성</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># 새 가상호스트 설정 파일 생성
sudo vim /etc/apache2/sites-available/testdomain.conf
</pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">2. 기본 HTTP 가상호스트</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">&lt;VirtualHost *:80>
    ServerName testdomain.com
    ServerAlias www.testdomain.com
    ServerAdmin admin@testdomain.com
    
    DocumentRoot /var/www/testdomain
    
    &lt;Directory /var/www/testdomain>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    &lt;/Directory>
    
    ErrorLog ${APACHE_LOG_DIR}/testdomain_error.log
    CustomLog ${APACHE_LOG_DIR}/testdomain_access.log combined
&lt;/VirtualHost>
</pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">3. HTTP → HTTPS 리다이렉트</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">&lt;VirtualHost *:80>
    ServerName testdomain.com
    ServerAlias www.testdomain.com
    
    # 모든 HTTP 요청을 HTTPS로 리다이렉트
    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
    
    ErrorLog ${APACHE_LOG_DIR}/testdomain_http_error.log
    CustomLog ${APACHE_LOG_DIR}/testdomain_http_access.log combined
&lt;/VirtualHost>
</pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">4. HTTPS 가상호스트 (정적 파일)</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">&lt;VirtualHost *:443>
    ServerName testdomain.com
    ServerAlias www.testdomain.com
    ServerAdmin admin@testdomain.com
    
    DocumentRoot /var/www/testdomain
    
    &lt;Directory /var/www/testdomain>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    &lt;/Directory>
    
    # SSL 설정
    SSLEngine on
    Include /etc/letsencrypt/options-ssl-apache.conf
    SSLCertificateFile /etc/letsencrypt/live/testdomain.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/testdomain.com/privkey.pem
    
    # 보안 헤더
    Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
    Header always set X-Content-Type-Options nosniff
    Header always set X-Frame-Options SAMEORIGIN
    Header always set X-XSS-Protection "1; mode=block"
    
    ErrorLog ${APACHE_LOG_DIR}/testdomain_https_error.log
    CustomLog ${APACHE_LOG_DIR}/testdomain_https_access.log combined
&lt;/VirtualHost>
</pre>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">다양한 설정 예제</h2>



<h3 class="wp-block-heading">리버스 프록시 </h3>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">&lt;VirtualHost *:443>
    ServerName api.testdomain.com
    
    # SSL 설정
    SSLEngine on
    SSLProxyEngine on
    Include /etc/letsencrypt/options-ssl-apache.conf
    SSLCertificateFile /etc/letsencrypt/live/api.testdomain.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/api.testdomain.com/privkey.pem
    
    # 프록시 설정
    ProxyPreserveHost On
    ProxyPass / http://localhost:3000/
    ProxyPassReverse / http://localhost:3000/
    
    # 프록시 헤더 설정
    RequestHeader set X-Forwarded-Proto "https"
    RequestHeader set X-Forwarded-Port "443"
    ProxyAddHeaders On
    
    # 타임아웃 설정
    ProxyTimeout 300
    
    # 요청 크기 제한 해제
    LimitRequestBody 0
    LimitRequestLine 65536
    LimitRequestFieldSize 65536
    
    ErrorLog ${APACHE_LOG_DIR}/api_error.log
    CustomLog ${APACHE_LOG_DIR}/api_access.log combined
&lt;/VirtualHost>
</pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">WebSocket 프록시</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">&lt;VirtualHost *:443>
    ServerName ws.testdomain.com
    
    SSLEngine on
    SSLProxyEngine on
    Include /etc/letsencrypt/options-ssl-apache.conf
    SSLCertificateFile /etc/letsencrypt/live/ws.testdomain.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/ws.testdomain.com/privkey.pem
    
    # WebSocket 지원을 위한 프록시 설정
    ProxyPreserveHost On
    RewriteEngine On
    RewriteCond %{HTTP:Upgrade} =websocket [NC]
    RewriteRule /(.*)           ws://localhost:8080/$1 [P,L]
    RewriteCond %{HTTP:Upgrade} !=websocket [NC]
    RewriteRule /(.*)           http://localhost:8080/$1 [P,L]
    
    ProxyPassReverse / http://localhost:8080/
    
    ErrorLog ${APACHE_LOG_DIR}/ws_error.log
    CustomLog ${APACHE_LOG_DIR}/ws_access.log combined
&lt;/VirtualHost>
</pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">여러 백엔드로 로드 밸런싱</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">sudo a2enmod proxy_balancer
sudo a2enmod lbmethod_byrequests</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">&lt;Proxy balancer://mycluster>
    BalancerMember http://localhost:3001
    BalancerMember http://localhost:3002
    BalancerMember http://localhost:3003
    ProxySet lbmethod=byrequests
&lt;/Proxy>

&lt;VirtualHost *:443>
    ServerName testdomain.com
    
    SSLEngine on
    Include /etc/letsencrypt/options-ssl-apache.conf
    SSLCertificateFile /etc/letsencrypt/live/testdomain.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/testdomain.com/privkey.pem
    
    ProxyPreserveHost On
    ProxyPass / balancer://mycluster/
    ProxyPassReverse / balancer://mycluster/
    
    ErrorLog ${APACHE_LOG_DIR}/testdomain_error.log
    CustomLog ${APACHE_LOG_DIR}/testdomain_access.log combined
&lt;/VirtualHost>
</pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">경로별 다른 백엔드 라우팅</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">&lt;VirtualHost *:443>
    ServerName testdomain.com
    
    SSLEngine on
    Include /etc/letsencrypt/options-ssl-apache.conf
    SSLCertificateFile /etc/letsencrypt/live/testdomain.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/testdomain.com/privkey.pem
    
    # API 요청은 백엔드 서버로
    ProxyPass /api http://localhost:8000/api
    ProxyPassReverse /api http://localhost:8000/api
    
    # 정적 파일은 직접 제공
    DocumentRoot /var/www/testdomain
    &lt;Directory /var/www/testdomain>
        Require all granted
    &lt;/Directory>
    
    ErrorLog ${APACHE_LOG_DIR}/testdomain_error.log
    CustomLog ${APACHE_LOG_DIR}/testdomain_access.log combined
&lt;/VirtualHost>
</pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">특정 IP만 접근 허용</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">&lt;VirtualHost *:443>
    ServerName admin.testdomain.com
    
    SSLEngine on
    Include /etc/letsencrypt/options-ssl-apache.conf
    SSLCertificateFile /etc/letsencrypt/live/admin.testdomain.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/admin.testdomain.com/privkey.pem
    
    DocumentRoot /var/www/admin
    
    &lt;Directory /var/www/admin>
        # 특정 IP만 허용
        Require ip 192.168.1.0/24
        Require ip 10.0.0.5
    &lt;/Directory>
    
    ErrorLog ${APACHE_LOG_DIR}/admin_error.log
    CustomLog ${APACHE_LOG_DIR}/admin_access.log combined
&lt;/VirtualHost>
</pre>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">SSL/HTTPS 설정</h2>



<h3 class="wp-block-heading">Certbot으로 SSL 인증서 발급</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># 자동 설정 (권장)
sudo certbot --apache -d testdomain.com -d www.testdomain.com

# 인증서만 발급 (수동 설정)
sudo certbot certonly --standalone -d testdomain.com -d www.testdomain.com

# 와일드카드 인증서 발급
sudo certbot certonly --manual --preferred-challenges dns -d testdomain.com -d *.testdomain.com

# 인증서 갱신 테스트
sudo certbot renew --dry-run

# 인증서 강제 갱신
sudo certbot renew --force-renewal

# 인증서 자동 갱신 크론잡 설정
sudo crontab -e
# 매일 새벽 2시에 갱신 확인
0 2 * * * certbot renew --quiet
</pre>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">SSL 설정 최적화</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># /etc/letsencrypt/options-ssl-apache.conf 참고
# 또는 직접 설정

SSLEngine on
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
SSLHonorCipherOrder off
SSLSessionTickets off

# OCSP Stapling 활성화
SSLUseStapling on
SSLStaplingCache "shmcb:logs/stapling-cache(150000)"
</pre>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">가상호스트 관리</h2>



<h3 class="wp-block-heading">활성화/비활성화</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># 가상호스트 활성화
sudo a2ensite testdomain.conf

# 가상호스트 비활성화
sudo a2dissite testdomain.conf

# 기본 사이트 비활성화
sudo a2dissite 000-default.conf

# 설정 적용 (다운타임 없음)
sudo systemctl reload apache2

# 설정 재시작 (다운타임 발생)
sudo systemctl restart apache2
</pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">모듈 관리</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># 모듈 활성화
sudo a2enmod 모듈명

# 모듈 비활성화
sudo a2dismod 모듈명

# 자주 사용하는 모듈들
sudo a2enmod rewrite      # URL 재작성
sudo a2enmod headers      # HTTP 헤더 조작
sudo a2enmod proxy        # 프록시 기능
sudo a2enmod proxy_http   # HTTP 프록시
sudo a2enmod proxy_wstunnel  # WebSocket 프록시
sudo a2enmod ssl          # SSL/TLS
sudo a2enmod deflate      # 압축
sudo a2enmod expires      # 캐시 제어
</pre>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">문제 해결</h2>



<h3 class="wp-block-heading">로그 확인</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># 실시간 에러 로그 모니터링
sudo tail -f /var/log/apache2/error.log

# 실시간 액세스 로그 모니터링
sudo tail -f /var/log/apache2/access.log

# 특정 가상호스트 로그
sudo tail -f /var/log/apache2/testdomain_error.log

# 마지막 100줄 확인
sudo tail -100 /var/log/apache2/error.log

# 특정 키워드로 검색
sudo grep "testdomain" /var/log/apache2/*.log

# 에러만 필터링
sudo grep "error" /var/log/apache2/error.log

# 최근 에러 (systemd)
sudo journalctl -u apache2 -n 50
</pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">연결 테스트</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># HTTP 응답 헤더 확인
curl -I http://testdomain.com/

# HTTPS 응답 헤더 확인
curl -I https://testdomain.com/

# 상세 디버깅 정보
curl -v https://testdomain.com/

# POST 요청 테스트
curl -X POST https://testdomain.com/api/endpoint \
  -H "Content-Type: application/json" \
  -d '{"key":"value"}'

# SSL 인증서 정보 확인
openssl s_client -connect testdomain.com:443 -servername testdomain.com &lt; /dev/null

# 백엔드 서비스 테스트
curl -v http://localhost:3000/
</pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">포트 및 프로세스 확인</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># 특정 포트 사용 확인
sudo netstat -tlnp | grep :80
sudo netstat -tlnp | grep :443
sudo netstat -tlnp | grep :3000

# 또는 ss 명령어 사용 (더 빠름)
sudo ss -tlnp | grep :80

# Apache 프로세스 확인
ps aux | grep apache2

# 열린 파일 확인
sudo lsof -i :80
sudo lsof -i :443
</pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">일반적인 문제 해결</h3>



<h4 class="wp-block-heading">포트 충돌 문제 체크</h4>



<p>Apache + Nginx 동시 사용 시 자주 발생<br>특히 Certbot &#8211;apache 사용 시 충돌할 수 있음.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">sudo ss -tlnp | grep :80
sudo ss -tlnp | grep :443

// 만약 Nginx가 잡고 있다면
sudo systemctl stop nginx
sudo systemctl disable nginx
</pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading">403 Forbidden 오류</h4>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># Directory 권한 확인
&lt;Directory /var/www/testdomain>
    Require all granted
    # 또는
    Options +Indexes
&lt;/Directory>

# 파일 시스템 권한 확인
sudo chmod -R 755 /var/www/testdomain
sudo chown -R www-data:www-data /var/www/testdomain
</pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading">500 Internal Server Error</h4>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># 설정 문법 오류 확인
sudo apache2ctl configtest

# .htaccess 문제 확인
sudo tail -50 /var/log/apache2/error.log

# SELinux 확인 (CentOS/RHEL)
sudo setenforce 0  # 임시 비활성화
</pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading">SSL 인증서 오류</h4>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># 인증서 파일 존재 확인
ls -la /etc/letsencrypt/live/testdomain.com/

# 인증서 유효기간 확인
sudo certbot certificates

# 인증서 갱신
sudo certbot renew

# SSL 인증서 권한 변경 주의
# SSLCertificateFile: file '/etc/letsencrypt/live/.../fullchain.pem' does not exist or is empty // 원인은 보통 인증서 폴더 권한 문제

sudo chmod 755 /etc/letsencrypt/live
sudo chmod 644 /etc/letsencrypt/live/DOMAIN/fullchain.pem
sudo chmod 600 /etc/letsencrypt/live/DOMAIN/privkey.pem

</pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading">프록시 오류 (502 Bad Gateway)</h4>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># 백엔드 서비스 작동 확인
curl http://localhost:3000/

# SELinux 설정 (CentOS/RHEL)
sudo setsebool -P httpd_can_network_connect 1

# 프록시 타임아웃 늘리기
ProxyTimeout 600
</pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading">Proxy 헤더 관련 ForwardedHeaders 추가</h4>



<p>ASP.NET Core, Node.js, Django 모두 HTTPS 프록시 환경에서 필수</p>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">RequestHeader set X-Forwarded-For %{REMOTE_ADDR}s
RequestHeader set X-Forwarded-Proto https
RequestHeader set X-Forwarded-Host %{HTTP_HOST}s

# (예시) ASP.NET Core
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});</pre>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">보안 강화</h2>



<h3 class="wp-block-heading">보안 헤더 설정</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">&lt;VirtualHost *:443>
    ServerName testdomain.com
    
    # ... SSL 설정 ...
    
    # HSTS (HTTP Strict Transport Security)
    Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
    
    # XSS 방지
    Header always set X-XSS-Protection "1; mode=block"
    
    # MIME 타입 스니핑 방지
    Header always set X-Content-Type-Options "nosniff"
    
    # 클릭재킹 방지
    Header always set X-Frame-Options "SAMEORIGIN"
    
    # Referrer 정책
    Header always set Referrer-Policy "strict-origin-when-cross-origin"
    
    # CSP (Content Security Policy)
    Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline';"
    
    # 서버 정보 숨기기
    ServerTokens Prod
    ServerSignature Off
&lt;/VirtualHost>
</pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">접근 제어</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># IP 기반 접근 제어
&lt;Directory /var/www/admin>
    # 특정 IP만 허용
    Require ip 192.168.1.0/24
    Require ip 10.0.0.5
    
    # 또는 특정 IP 차단
    Require all granted
    Require not ip 192.168.1.100
&lt;/Directory>

# HTTP Basic 인증
&lt;Directory /var/www/protected>
    AuthType Basic
    AuthName "Restricted Area"
    AuthUserFile /etc/apache2/.htpasswd
    Require valid-user
&lt;/Directory>
</pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">.htpasswd 파일 생성</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># htpasswd 파일 생성 (첫 사용자)
sudo htpasswd -c /etc/apache2/.htpasswd username

# 추가 사용자 등록 (-c 옵션 제거)
sudo htpasswd /etc/apache2/.htpasswd username2
</pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">Rate Limiting (mod_ratelimit)</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">&lt;Location /api>
    SetOutputFilter RATE_LIMIT
    SetEnv rate-limit 400
    SetEnv rate-initial-burst 100
&lt;/Location>
</pre>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">성능 최적화</h2>



<h3 class="wp-block-heading">캐싱 설정</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">&lt;VirtualHost *:443>
    ServerName testdomain.com
    
    # ... 기본 설정 ...
    
    # 정적 파일 캐싱
    &lt;IfModule mod_expires.c>
        ExpiresActive On
        
        # 이미지
        ExpiresByType image/jpg "access plus 1 year"
        ExpiresByType image/jpeg "access plus 1 year"
        ExpiresByType image/gif "access plus 1 year"
        ExpiresByType image/png "access plus 1 year"
        ExpiresByType image/webp "access plus 1 year"
        ExpiresByType image/svg+xml "access plus 1 year"
        
        # CSS/JS
        ExpiresByType text/css "access plus 1 month"
        ExpiresByType application/javascript "access plus 1 month"
        
        # 폰트
        ExpiresByType font/woff2 "access plus 1 year"
        ExpiresByType font/woff "access plus 1 year"
        
        # HTML
        ExpiresByType text/html "access plus 1 hour"
    &lt;/IfModule>
    
    # Cache-Control 헤더
    &lt;FilesMatch "\.(jpg|jpeg|png|gif|webp|svg|css|js|woff|woff2)$">
        Header set Cache-Control "max-age=31536000, public"
    &lt;/FilesMatch>
&lt;/VirtualHost>
</pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">Gzip &amp; Brotli 압축</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">&lt;IfModule mod_deflate.c>
    # 압축 활성화
    AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css
    AddOutputFilterByType DEFLATE application/javascript application/json
    AddOutputFilterByType DEFLATE application/xml application/xhtml+xml
    AddOutputFilterByType DEFLATE image/svg+xml
    
    # 이미지는 압축 제외 (이미 압축됨)
    SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|webp)$ no-gzip
&lt;/IfModule>


sudo apt install libapache2-mod-brotli
sudo a2enmod brotli

&lt;IfModule mod_brotli.c>
    BrotliCompressionQuality 5
    AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/css application/javascript application/json image/svg+xml
&lt;/IfModule></pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">KeepAlive 설정</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># /etc/apache2/apache2.conf

# KeepAlive 활성화
KeepAlive On

# 최대 요청 수
MaxKeepAliveRequests 100

# 타임아웃 (초)
KeepAliveTimeout 5
</pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">MPM 설정 최적화</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># /etc/apache2/mods-available/mpm_event.conf

&lt;IfModule mpm_event_module>
    StartServers             2
    MinSpareThreads          25
    MaxSpareThreads          75
    ThreadLimit              64
    ThreadsPerChild          25
    MaxRequestWorkers        150
    MaxConnectionsPerChild   0
&lt;/IfModule>
</pre>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">디렉토리 구조</h2>



<h3 class="wp-block-heading">Apache 설정 파일 구조</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">/etc/apache2/
├── apache2.conf              # 메인 설정 파일
├── ports.conf                # 포트 설정
├── conf-available/           # 사용 가능한 설정
├── conf-enabled/             # 활성화된 설정
├── mods-available/           # 사용 가능한 모듈
├── mods-enabled/             # 활성화된 모듈 (심볼릭 링크)
├── sites-available/          # 사용 가능한 가상호스트
│   ├── 000-default.conf
│   ├── testdomain.conf
│   └── api.testdomain.conf
├── sites-enabled/            # 활성화된 가상호스트 (심볼릭 링크)
│   ├── 000-default.conf -> ../sites-available/000-default.conf
│   └── testdomain.conf -> ../sites-available/testdomain.conf
└── envvars                   # 환경 변수
</pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">웹 컨텐츠 디렉토리</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">/var/www/
├── html/                     # 기본 DocumentRoot
├── testdomain/               # 가상호스트 디렉토리
│   ├── public/
│   ├── index.html
│   └── .htaccess
└── logs/                     # 로그 (선택사항)
</pre>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">유용한 명령어 모음</h2>



<h3 class="wp-block-heading">빠른 참조</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># 설정 테스트
sudo apache2ctl configtest

# 가상호스트 목록
sudo apache2ctl -S

# 설정 리로드 (무중단)
sudo systemctl reload apache2

# 재시작
sudo systemctl restart apache2

# 상태 확인
sudo systemctl status apache2

# 로그 실시간 모니터링
sudo tail -f /var/log/apache2/error.log

# 특정 도메인 설정 확인
sudo apache2ctl -D DUMP_VHOSTS | grep testdomain

# 활성화된 모듈 목록
apache2ctl -M

# 설정 파일 문법 체크
sudo apachectl -t
</pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">자주 사용하는 작업</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># 새 가상호스트 생성부터 활성화까지
sudo vim /etc/apache2/sites-available/newsite.conf
sudo a2ensite newsite.conf
sudo apache2ctl configtest
sudo systemctl reload apache2

# SSL 인증서 발급 및 자동 설정
sudo certbot --apache -d newsite.com

# 로그 분석
sudo tail -1000 /var/log/apache2/access.log | grep "POST" | wc -l

# 디스크 사용량 확인
sudo du -sh /var/log/apache2/*

# 오래된 로그 정리
sudo find /var/log/apache2/ -name "*.log.*" -mtime +30 -delete
</pre>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">문제 상황별 체크리스트</h2>



<h3 class="wp-block-heading">사이트가 접속되지 않을 때</h3>



<ul class="wp-block-list">
<li>[ ] Apache 서비스 작동 확인: <code>sudo systemctl status apache2</code></li>



<li>[ ] 포트 리스닝 확인: <code>sudo netstat -tlnp | grep :80</code></li>



<li>[ ] 방화벽 확인: <code>sudo ufw status</code></li>



<li>[ ] DNS 설정 확인: <code>nslookup testdomain.com</code></li>



<li>[ ] 가상호스트 활성화 확인: <code>sudo apache2ctl -S</code></li>



<li>[ ] 설정 문법 확인: <code>sudo apache2ctl configtest</code></li>
</ul>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">502 Bad Gateway 발생 시</h3>



<ul class="wp-block-list">
<li>[ ] 백엔드 서비스 작동 확인: <code>curl http://localhost:3000/</code></li>



<li>[ ] 프록시 설정 확인: ProxyPass, ProxyPassReverse</li>



<li>[ ] SELinux 설정 확인 (CentOS/RHEL)</li>



<li>[ ] 타임아웃 설정 확인: ProxyTimeout</li>



<li>[ ] 에러 로그 확인: <code>sudo tail -50 /var/log/apache2/error.log</code></li>
</ul>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">SSL 인증서 오류 시</h3>



<ul class="wp-block-list">
<li>[ ] 인증서 파일 존재 확인</li>



<li>[ ] 인증서 유효기간 확인: <code>sudo certbot certificates</code></li>



<li>[ ] 인증서 경로 확인</li>



<li>[ ] 포트 443 리스닝 확인</li>



<li>[ ] SSL 모듈 활성화 확인: <code>apache2ctl -M | grep ssl</code></li>
</ul>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<p></p>
<p>The post <a href="https://lycos7560.com/ubuntu/apache-%ea%b0%80%ec%83%81%ed%98%b8%ec%8a%a4%ed%8a%b8-%ec%84%a4%ec%a0%95-%ea%b0%80%ec%9d%b4%eb%93%9c/40358/">Apache Virtual Host Guide (Apache 가상 호스트 설정)</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://lycos7560.com/ubuntu/apache-%ea%b0%80%ec%83%81%ed%98%b8%ec%8a%a4%ed%8a%b8-%ec%84%a4%ec%a0%95-%ea%b0%80%ec%9d%b4%eb%93%9c/40358/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>JWT(Json Web Token) 정리</title>
		<link>https://lycos7560.com/etc/jwtjson-web-token-%ec%a0%95%eb%a6%ac/40306/</link>
					<comments>https://lycos7560.com/etc/jwtjson-web-token-%ec%a0%95%eb%a6%ac/40306/#respond</comments>
		
		<dc:creator><![CDATA[lycos7560]]></dc:creator>
		<pubDate>Mon, 13 Oct 2025 00:14:01 +0000</pubDate>
				<category><![CDATA[개인 공부 저장용]]></category>
		<category><![CDATA[기타]]></category>
		<category><![CDATA[Access Control]]></category>
		<category><![CDATA[Access Token]]></category>
		<category><![CDATA[API Gateway]]></category>
		<category><![CDATA[API Security]]></category>
		<category><![CDATA[API 보안]]></category>
		<category><![CDATA[Audience]]></category>
		<category><![CDATA[Authentication]]></category>
		<category><![CDATA[Authentication Flow]]></category>
		<category><![CDATA[Authorization]]></category>
		<category><![CDATA[Authorization Header]]></category>
		<category><![CDATA[Authorization Server]]></category>
		<category><![CDATA[Backend]]></category>
		<category><![CDATA[Base64URL]]></category>
		<category><![CDATA[Bearer]]></category>
		<category><![CDATA[Claim Types]]></category>
		<category><![CDATA[Claims]]></category>
		<category><![CDATA[CSRF]]></category>
		<category><![CDATA[DataBase]]></category>
		<category><![CDATA[Decoding]]></category>
		<category><![CDATA[Expiration]]></category>
		<category><![CDATA[Frontend]]></category>
		<category><![CDATA[Header]]></category>
		<category><![CDATA[HMAC]]></category>
		<category><![CDATA[HS256]]></category>
		<category><![CDATA[HttpOnly Cookie]]></category>
		<category><![CDATA[HTTPS]]></category>
		<category><![CDATA[Identity]]></category>
		<category><![CDATA[Issued At]]></category>
		<category><![CDATA[Issuer]]></category>
		<category><![CDATA[Json Web Token]]></category>
		<category><![CDATA[JWT]]></category>
		<category><![CDATA[JWT Structure]]></category>
		<category><![CDATA[JWT Verification]]></category>
		<category><![CDATA[JWT 검증]]></category>
		<category><![CDATA[JWT 구조]]></category>
		<category><![CDATA[LocalStorage]]></category>
		<category><![CDATA[Login]]></category>
		<category><![CDATA[Logout]]></category>
		<category><![CDATA[Microservices]]></category>
		<category><![CDATA[Not Before]]></category>
		<category><![CDATA[OAuth]]></category>
		<category><![CDATA[OAuth2]]></category>
		<category><![CDATA[OpenID Connect]]></category>
		<category><![CDATA[Payload]]></category>
		<category><![CDATA[Private Key]]></category>
		<category><![CDATA[Public Key]]></category>
		<category><![CDATA[Redis]]></category>
		<category><![CDATA[Refresh Token]]></category>
		<category><![CDATA[Resource Server]]></category>
		<category><![CDATA[REST API]]></category>
		<category><![CDATA[REST 인증]]></category>
		<category><![CDATA[RFC 7519]]></category>
		<category><![CDATA[RS256]]></category>
		<category><![CDATA[Scalability]]></category>
		<category><![CDATA[Secret Key]]></category>
		<category><![CDATA[Security Best Practice]]></category>
		<category><![CDATA[Security Token]]></category>
		<category><![CDATA[Session Management]]></category>
		<category><![CDATA[Sessionless]]></category>
		<category><![CDATA[Signature]]></category>
		<category><![CDATA[Stateless]]></category>
		<category><![CDATA[Stateless Authentication]]></category>
		<category><![CDATA[Subject]]></category>
		<category><![CDATA[Token]]></category>
		<category><![CDATA[Token Expiration]]></category>
		<category><![CDATA[Token Revocation]]></category>
		<category><![CDATA[Token Rotation]]></category>
		<category><![CDATA[Token Storage]]></category>
		<category><![CDATA[Token Validation]]></category>
		<category><![CDATA[Web Application Security]]></category>
		<category><![CDATA[Web Security]]></category>
		<category><![CDATA[Web Token]]></category>
		<category><![CDATA[XSS]]></category>
		<category><![CDATA[개인키]]></category>
		<category><![CDATA[게이트웨이]]></category>
		<category><![CDATA[공개키]]></category>
		<category><![CDATA[대상자]]></category>
		<category><![CDATA[대칭키 서명]]></category>
		<category><![CDATA[데이터베이스]]></category>
		<category><![CDATA[디코딩]]></category>
		<category><![CDATA[레디스]]></category>
		<category><![CDATA[로그아웃]]></category>
		<category><![CDATA[로그인]]></category>
		<category><![CDATA[로컬스토리지]]></category>
		<category><![CDATA[리소스 서버]]></category>
		<category><![CDATA[리프레시 토큰]]></category>
		<category><![CDATA[마이크로서비스]]></category>
		<category><![CDATA[만료시간]]></category>
		<category><![CDATA[무상태]]></category>
		<category><![CDATA[무상태 인증]]></category>
		<category><![CDATA[발급자]]></category>
		<category><![CDATA[발행시간]]></category>
		<category><![CDATA[백엔드]]></category>
		<category><![CDATA[베어러]]></category>
		<category><![CDATA[보안 연결]]></category>
		<category><![CDATA[보안 토큰]]></category>
		<category><![CDATA[비대칭키 서명]]></category>
		<category><![CDATA[비밀키]]></category>
		<category><![CDATA[사용자 식별]]></category>
		<category><![CDATA[서명]]></category>
		<category><![CDATA[세션 관리]]></category>
		<category><![CDATA[세션리스]]></category>
		<category><![CDATA[알고리즘]]></category>
		<category><![CDATA[액세스 토큰]]></category>
		<category><![CDATA[오픈아이디 커넥트]]></category>
		<category><![CDATA[웹 보안]]></category>
		<category><![CDATA[웹 애플리케이션 보안]]></category>
		<category><![CDATA[웹 토큰]]></category>
		<category><![CDATA[유효시작]]></category>
		<category><![CDATA[인가]]></category>
		<category><![CDATA[인가 서버]]></category>
		<category><![CDATA[인증]]></category>
		<category><![CDATA[인증 헤더]]></category>
		<category><![CDATA[인증 흐름]]></category>
		<category><![CDATA[인코딩]]></category>
		<category><![CDATA[접근 제어]]></category>
		<category><![CDATA[제이슨 웹 토큰]]></category>
		<category><![CDATA[주제]]></category>
		<category><![CDATA[쿠키 보안]]></category>
		<category><![CDATA[크로스사이트 요청 위조]]></category>
		<category><![CDATA[크로스사이트스크립팅]]></category>
		<category><![CDATA[클레임]]></category>
		<category><![CDATA[클레임 타입]]></category>
		<category><![CDATA[토큰]]></category>
		<category><![CDATA[토큰 검증]]></category>
		<category><![CDATA[토큰 만료]]></category>
		<category><![CDATA[토큰 저장]]></category>
		<category><![CDATA[토큰 폐기]]></category>
		<category><![CDATA[토큰 회전]]></category>
		<category><![CDATA[페이로드]]></category>
		<category><![CDATA[표준]]></category>
		<category><![CDATA[프론트엔드]]></category>
		<category><![CDATA[해시 기반 메시지 인증]]></category>
		<category><![CDATA[헤더]]></category>
		<category><![CDATA[확장성]]></category>
		<guid isPermaLink="false">https://lycos7560.com/?p=40306</guid>

					<description><![CDATA[<p>🔥 JWT(Json Web Token) 정리 https://www.jwt.io/introduction#how-json-web-tokens-work 1️⃣ 개요 JWT(Json Web Token) 는 클라이언트와 서버 간에 정보를 안전하게 전달하기 위한 토큰 기반 인증 방식입니다. 이는 RFC 7519 에 정의된 개방형 표준(Open Standard) 입니다. JWT는 JSON 형식의 데이터를 Base64URL로 인코딩하고, 디지털 서명(Signature) 을 통해 위변조를 방지합니다. 2️⃣ JWT의 구조 JWT는 .(점) 으로 구분된 3개의 부분으로 구성됩니다. 구분 [&#8230;]</p>
<p>The post <a href="https://lycos7560.com/etc/jwtjson-web-token-%ec%a0%95%eb%a6%ac/40306/">JWT(Json Web Token) 정리</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></description>
										<content:encoded><![CDATA[				<div class="wp-block-uagb-table-of-contents uagb-toc__align-left uagb-toc__columns-1  uagb-block-0b15c4b2      "
					data-scroll= "1"
					data-offset= "30"
					style=""
				>
				<div class="uagb-toc__wrap">
						<div class="uagb-toc__title">
							목차						</div>
																						<div class="uagb-toc__list-wrap ">
						<ol class="uagb-toc__list"><li class="uagb-toc__list"><a href="#jwtjson-web-token-정리" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f525.png" alt="🔥" class="wp-smiley" style="height: 1em; max-height: 1em;" /> JWT(Json Web Token) 정리</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#1-개요" class="uagb-toc-link__trigger">1&#x20e3; 개요</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#2-jwt의-구조" class="uagb-toc-link__trigger">2&#x20e3; JWT의 구조</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#예시" class="uagb-toc-link__trigger">예시</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#결과" class="uagb-toc-link__trigger">결과</a></li></ul><li class="uagb-toc__list"><a href="#3-jwt의-동작-방식" class="uagb-toc-link__trigger">3&#x20e3; JWT의 동작 방식</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#4-jwt의-장점과-단점" class="uagb-toc-link__trigger">4&#x20e3; JWT의 장점과 단점</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#5-jwt의-주요-claim" class="uagb-toc-link__trigger">5&#x20e3; JWT의 주요 Claim</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#6-refresh-token-전략" class="uagb-toc-link__trigger">6&#x20e3; Refresh Token 전략</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#7-jwt-사용-시-보안-주의사항" class="uagb-toc-link__trigger">7&#x20e3; JWT 사용 시 보안 주의사항</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#결론" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2728.png" alt="✨" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 결론</a></ul></ol>					</div>
									</div>
				</div>
			


<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>



<h1 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f525.png" alt="🔥" class="wp-smiley" style="height: 1em; max-height: 1em;" /> JWT(Json Web Token) 정리</h1>



<p><a href="https://www.jwt.io/introduction#how-json-web-tokens-work" target="_blank" rel="noreferrer noopener">https://www.jwt.io/introduction#how-json-web-tokens-work</a></p>



<h2 class="wp-block-heading">1&#x20e3; 개요</h2>



<p><strong>JWT(Json Web Token)</strong> 는 클라이언트와 서버 간에 정보를 <strong>안전하게 전달하기 위한 토큰 기반 인증 방식</strong>입니다.</p>



<p>이는 <strong>RFC 7519</strong> 에 정의된 <strong>개방형 표준(Open Standard)</strong> 입니다.</p>



<p>JWT는 JSON 형식의 데이터를 <strong>Base64URL로 인코딩</strong>하고, <strong>디지털 서명(Signature)</strong> 을 통해 <strong>위변조를 방지</strong>합니다.</p>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">2&#x20e3; JWT의 구조</h2>



<p>JWT는 <strong><code>.</code>(점)</strong> 으로 구분된 <strong>3개의 부분</strong>으로 구성됩니다.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">
xxxxx.yyyyy.zzzzz
</pre>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>구분</th><th>이름</th><th>설명</th></tr></thead><tbody><tr><td>1</td><td>Header</td><td>토큰의 타입(JWT)과 서명 알고리즘(HS256, RS256 등)을 명시</td></tr><tr><td>2</td><td>Payload</td><td>사용자 정보나 클레임(Claims)을 포함</td></tr><tr><td>3</td><td>Signature</td><td>Header와 Payload를 비밀키로 서명하여 위변조 방지</td></tr></tbody></table></figure>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">예시</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="json" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// Header (헤더)
Header: 
{
  "alg": "HS256",
  "typ": "JWT"
}

// Payload (페이로드) - 클레임(Claim)
Payload:
{
  "sub": "1234567890",      // 주제 (Subject)
  "name": "John Doe",       // 사용자 이름
  "admin": true,            // 역할
  "iat": 1516239022,        // 발행 시간 (Issued At)
  "exp": 1516242622         // 만료 시간 (Expiration)
}

// Signature (서명)
Signature:
HMACSHA256(
  base64UrlEncode(header) + "." + base64UrlEncode(payload),
  secret
)
</pre>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">결과</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.
TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
</pre>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">3&#x20e3; JWT의 동작 방식</h2>



<p>1. 사용자가 로그인 요청을 전송</p>



<p>2. 서버는 사용자의 인증 정보(아이디, 비밀번호 등)를 검증</p>



<p>3. 인증에 성공하면 <strong>JWT 토큰을 생성하여 클라이언트에게 발급</strong></p>



<p>4. 클라이언트는 이후 요청마다 <strong>Authorization 헤더</strong>에 토큰을 포함</p>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Authorization: Bearer &lt;JWT_TOKEN>

## 예시
Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1laWQiOiIxIiwidW5pcXVlX25hbWUiOiJhZG1pbiIsImVtYWlsIjoiYWRtaW5AZGVtby5jb20iLCJMb2dpblRpbWUiOiIyMDI1LTEwLTEyVDIyOjEwOjMwLjY3NDg3ODVaIiwicm9sZSI6WyJBZG1pbiIsIlVzZXIiXSwibmJmIjoxNzYwMzA3MDMwLCJleHAiOjE3NjAzMTA2MzAsImlhdCI6MTc2MDMwNzAzMCwiaXNzIjoibHljb3M3NTYwLmNvbSIsImF1ZCI6Ik15QXVkaWVuY2UifQ.Vo2eV6JLLJLg_qBvfalPZI87n8UVQRCn5mAAhRjDnuU</pre>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<p>5. 서버는 요청을 받을 때마다 JWT 토큰의 <strong>유효성(Signature 및 만료 시간)</strong> 을 검증</p>



<p>6. 유효한 경우 요청을 처리하고, 그렇지 않으면 401 Unauthorized 응</p>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">4&#x20e3; JWT의 장점과 단점</h2>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th><strong>장점</strong></th><th>설명</th></tr></thead><tbody><tr><td><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 확장성</td><td>세션을 서버 메모리에 저장하지 않아도 되므로, 서버 확장에 유리</td></tr><tr><td><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 무상태성</td><td>서버가 사용자 상태를 기억하지 않아도 됨 (Stateless)</td></tr><tr><td><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 범용성</td><td>웹, 모바일, API 등 다양한 환경에서 동일한 인증 방식 사용 가능</td></tr></tbody></table></figure>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th><strong>단점</strong></th><th>설명</th></tr></thead><tbody><tr><td><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 토큰 무효화 어려움</td><td>만료 전까지 유효 → 즉시 로그아웃 구현 어려움</td></tr><tr><td><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 보안 주의 필요</td><td>비밀키 유출 시 전체 시스템 위험, XSS/CSRF 취약</td></tr><tr><td><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 크기 문제</td><td>세션 ID보다 커서 네트워크 트래픽 증가 가능, <em><strong>매 요청마다 JWT 토큰 전송 → 트래픽 증가</strong></em></td></tr></tbody></table></figure>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">5&#x20e3; JWT의 주요 Claim</h2>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Claim</th><th>설명</th></tr></thead><tbody><tr><td><code>iss</code></td><td>토큰 발급자 (Issuer)</td></tr><tr><td><code>sub</code></td><td>토큰 제목 / 사용자 식별자 (Subject)</td></tr><tr><td><code>aud</code></td><td>토큰 대상자 (Audience)</td></tr><tr><td><code>exp</code></td><td>만료 시간 (Expiration Time)</td></tr><tr><td><code>nbf</code></td><td>이 시간 이전에는 유효하지 않음 (Not Before)</td></tr><tr><td><code>iat</code></td><td>토큰 발급 시간 (Issued At)</td></tr><tr><td><code>jti</code></td><td>JWT 고유 식별자 (JWT ID)</td></tr></tbody></table></figure>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">6&#x20e3; Refresh Token 전략</h2>



<p>Access Token의 수명이 짧기 때문에, <strong>Refresh Token</strong>을 사용해 재발급하는 구조가 일반적입니다.</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>구분</th><th>역할</th></tr></thead><tbody><tr><td>Access Token</td><td>짧은 만료 시간(5~30분) → 요청 인증용</td></tr><tr><td>Refresh Token</td><td>긴 만료 시간(1~14일) → 새로운 Access Token 발급용</td></tr></tbody></table></figure>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<p>1. 로그인 시 Access Token + Refresh Token 발급</p>



<p>2. Access Token 만료 시 Refresh Token으로 갱신 요청</p>



<p>3. 서버는 Refresh Token 검증 후 새로운 Access Token 발급</p>



<p>4. Refresh Token 탈취 시 위험하므로 DB나 Redis에 저장해 관리<br><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Refresh Token 탈취 시 장기 인증이 노출될 수 있으므로, IP / User-Agent 기반 검증 또는 토큰 회전(Token Rotation) 권장</p>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">7&#x20e3; JWT 사용 시 보안 주의사항</h2>



<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>HTTPS 필수 사용</strong> (평문 노출 방지)</p>



<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Authorization 헤더</strong> 사용 (쿠키보다 안전)</p>



<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>짧은 만료 시간 + Refresh Token 병행</strong></p>



<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>민감정보(비밀번호 등)는 Payload에 절대 포함 금지</strong></p>



<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>IP, User-Agent 등 부가 정보 검증</strong> 가능</p>



<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>HttpOnly Cookie + Secure 옵션</strong>으로 XSS 방지</p>



<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>서명키(secret)</strong> 는 .env 또는 KeyVault 등 안전한 저장소 사용</p>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2728.png" alt="✨" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 결론</h2>



<p>JWT는 <strong>확장성과 무상태성</strong>을 제공하는 강력한 인증 수단이지만, <strong>보안 관리(비밀키, 만료, 저장 위치 등)</strong> 가 핵심입니다.</p>



<p>실제 운영환경에서는 <strong>Access/Refresh Token 분리 + HTTPS + 짧은 만료</strong>를 조합해 <strong>안전하고 효율적인 인증 시스템</strong>을 구축해야 합니다.</p>



<p></p>
<p>The post <a href="https://lycos7560.com/etc/jwtjson-web-token-%ec%a0%95%eb%a6%ac/40306/">JWT(Json Web Token) 정리</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://lycos7560.com/etc/jwtjson-web-token-%ec%a0%95%eb%a6%ac/40306/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>기본적인 Docker 명령어 연습</title>
		<link>https://lycos7560.com/docker/%ea%b8%b0%eb%b3%b8%ec%a0%81%ec%9d%b8-docker-%eb%aa%85%eb%a0%b9%ec%96%b4-%ec%97%b0%ec%8a%b5/40181/</link>
					<comments>https://lycos7560.com/docker/%ea%b8%b0%eb%b3%b8%ec%a0%81%ec%9d%b8-docker-%eb%aa%85%eb%a0%b9%ec%96%b4-%ec%97%b0%ec%8a%b5/40181/#respond</comments>
		
		<dc:creator><![CDATA[lycos7560]]></dc:creator>
		<pubDate>Wed, 30 Jul 2025 14:02:17 +0000</pubDate>
				<category><![CDATA[Docker]]></category>
		<category><![CDATA[Application]]></category>
		<category><![CDATA[architecture]]></category>
		<category><![CDATA[Auto Scaling]]></category>
		<category><![CDATA[Automation]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[Azure]]></category>
		<category><![CDATA[Backup]]></category>
		<category><![CDATA[Base Image]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[Build]]></category>
		<category><![CDATA[CI/CD]]></category>
		<category><![CDATA[Cloud Computing]]></category>
		<category><![CDATA[Cloud Native]]></category>
		<category><![CDATA[Cloud Provider]]></category>
		<category><![CDATA[Compliance]]></category>
		<category><![CDATA[Container]]></category>
		<category><![CDATA[Container as a Service]]></category>
		<category><![CDATA[Container Registry]]></category>
		<category><![CDATA[Container Runtime]]></category>
		<category><![CDATA[Containerization]]></category>
		<category><![CDATA[Continuous Deployment]]></category>
		<category><![CDATA[Continuous Integration]]></category>
		<category><![CDATA[Deployment]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[Docker Compose]]></category>
		<category><![CDATA[Docker Desktop]]></category>
		<category><![CDATA[Docker Engine]]></category>
		<category><![CDATA[Docker Hub]]></category>
		<category><![CDATA[Dockerfile]]></category>
		<category><![CDATA[Enterprise]]></category>
		<category><![CDATA[Environment Variables]]></category>
		<category><![CDATA[GitOps]]></category>
		<category><![CDATA[Google Cloud]]></category>
		<category><![CDATA[Guest OS]]></category>
		<category><![CDATA[Health Check]]></category>
		<category><![CDATA[Host OS]]></category>
		<category><![CDATA[Hypervisor]]></category>
		<category><![CDATA[IaC]]></category>
		<category><![CDATA[Image]]></category>
		<category><![CDATA[Image Optimization]]></category>
		<category><![CDATA[Infrastructure]]></category>
		<category><![CDATA[Infrastructure as Code]]></category>
		<category><![CDATA[Isolation]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[Layer]]></category>
		<category><![CDATA[Legacy System]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Load Balancing]]></category>
		<category><![CDATA[Logging]]></category>
		<category><![CDATA[Microservices]]></category>
		<category><![CDATA[Migration]]></category>
		<category><![CDATA[Modernization]]></category>
		<category><![CDATA[Monitoring]]></category>
		<category><![CDATA[Multi-stage Build]]></category>
		<category><![CDATA[network]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Orchestration]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[pipeline]]></category>
		<category><![CDATA[Port Mapping]]></category>
		<category><![CDATA[Portability]]></category>
		<category><![CDATA[Production]]></category>
		<category><![CDATA[Pull]]></category>
		<category><![CDATA[Push]]></category>
		<category><![CDATA[Registry]]></category>
		<category><![CDATA[Resource Efficiency]]></category>
		<category><![CDATA[Run]]></category>
		<category><![CDATA[Scalability]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Security Scanning]]></category>
		<category><![CDATA[Service Mesh]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Staging]]></category>
		<category><![CDATA[study]]></category>
		<category><![CDATA[Swarm]]></category>
		<category><![CDATA[Tag]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[Troubleshooting]]></category>
		<category><![CDATA[Virtual Machine]]></category>
		<category><![CDATA[vm]]></category>
		<category><![CDATA[Volume]]></category>
		<category><![CDATA[Vulnerability]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[가상머신]]></category>
		<category><![CDATA[개발]]></category>
		<category><![CDATA[게스트 OS]]></category>
		<category><![CDATA[격리]]></category>
		<category><![CDATA[공부]]></category>
		<category><![CDATA[구글 클라우드]]></category>
		<category><![CDATA[기초]]></category>
		<category><![CDATA[깃옵스]]></category>
		<category><![CDATA[네트워크]]></category>
		<category><![CDATA[데브옵스]]></category>
		<category><![CDATA[도커]]></category>
		<category><![CDATA[도커 데스크톱]]></category>
		<category><![CDATA[도커 엔진]]></category>
		<category><![CDATA[도커 컴포즈]]></category>
		<category><![CDATA[도커 허브]]></category>
		<category><![CDATA[도커파일]]></category>
		<category><![CDATA[레거시 시스템]]></category>
		<category><![CDATA[레이어]]></category>
		<category><![CDATA[레지스트리]]></category>
		<category><![CDATA[로깅]]></category>
		<category><![CDATA[로드 밸런싱]]></category>
		<category><![CDATA[리눅스]]></category>
		<category><![CDATA[리소스 효율성]]></category>
		<category><![CDATA[마이그레이션]]></category>
		<category><![CDATA[마이크로서비스]]></category>
		<category><![CDATA[멀티 스테이지 빌드]]></category>
		<category><![CDATA[모니터링]]></category>
		<category><![CDATA[모범 사례]]></category>
		<category><![CDATA[배포]]></category>
		<category><![CDATA[백업]]></category>
		<category><![CDATA[베이스 이미지]]></category>
		<category><![CDATA[보안]]></category>
		<category><![CDATA[보안 스캔]]></category>
		<category><![CDATA[볼륨]]></category>
		<category><![CDATA[빌드]]></category>
		<category><![CDATA[서비스 메시]]></category>
		<category><![CDATA[서비스형 컨테이너]]></category>
		<category><![CDATA[성능]]></category>
		<category><![CDATA[소프트웨어 개발]]></category>
		<category><![CDATA[스웜]]></category>
		<category><![CDATA[스테이징]]></category>
		<category><![CDATA[실행]]></category>
		<category><![CDATA[아마존 웹 서비스]]></category>
		<category><![CDATA[아이아씨]]></category>
		<category><![CDATA[아키텍처]]></category>
		<category><![CDATA[애저]]></category>
		<category><![CDATA[애플리케이션]]></category>
		<category><![CDATA[엔터프라이즈]]></category>
		<category><![CDATA[오케스트레이션]]></category>
		<category><![CDATA[오픈 소스]]></category>
		<category><![CDATA[윈도우]]></category>
		<category><![CDATA[이미지]]></category>
		<category><![CDATA[이미지 최적화]]></category>
		<category><![CDATA[이식성]]></category>
		<category><![CDATA[인프라스트럭처]]></category>
		<category><![CDATA[자동 확장]]></category>
		<category><![CDATA[자동화]]></category>
		<category><![CDATA[지속적 배포]]></category>
		<category><![CDATA[지속적 통합]]></category>
		<category><![CDATA[취약점]]></category>
		<category><![CDATA[컨테이너]]></category>
		<category><![CDATA[컨테이너 런타임]]></category>
		<category><![CDATA[컨테이너 레지스트리]]></category>
		<category><![CDATA[컨테이너화]]></category>
		<category><![CDATA[컴플라이언스]]></category>
		<category><![CDATA[코드형 인프라]]></category>
		<category><![CDATA[쿠버네티스]]></category>
		<category><![CDATA[클라우드 네이티브]]></category>
		<category><![CDATA[클라우드 제공자]]></category>
		<category><![CDATA[클라우드 컴퓨팅]]></category>
		<category><![CDATA[태그]]></category>
		<category><![CDATA[테스팅]]></category>
		<category><![CDATA[트러블슈팅]]></category>
		<category><![CDATA[파이프라인]]></category>
		<category><![CDATA[포트 매핑]]></category>
		<category><![CDATA[푸시]]></category>
		<category><![CDATA[풀]]></category>
		<category><![CDATA[프로덕션]]></category>
		<category><![CDATA[하이퍼바이저]]></category>
		<category><![CDATA[헬스 체크]]></category>
		<category><![CDATA[현대화]]></category>
		<category><![CDATA[호스트 OS]]></category>
		<category><![CDATA[확장성]]></category>
		<guid isPermaLink="false">https://lycos7560.com/?p=40181</guid>

					<description><![CDATA[<p>기본적인 Docker 명령어 항목 의미 docker run 새로운 컨테이너를 생성하고 실행 -d Detached mode → 백그라운드에서 실행 ubuntu 사용할 이미지 이름 (없으면 자동으로 Docker Hub에서 pull함) sleep 10 컨테이너 내부에서 실행할 명령어 (10초 동안 대기) .NET Image 추가 두 항목의 IMAGE ID가 동일REPOSITORY: mcr.microsoft.com/dotnet/sdkTAG: 9.0 → IMAGE ID: 08fe223b9022TAG: latest → IMAGE ID: 08fe223b9022이유: latest [&#8230;]</p>
<p>The post <a href="https://lycos7560.com/docker/%ea%b8%b0%eb%b3%b8%ec%a0%81%ec%9d%b8-docker-%eb%aa%85%eb%a0%b9%ec%96%b4-%ec%97%b0%ec%8a%b5/40181/">기본적인 Docker 명령어 연습</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></description>
										<content:encoded><![CDATA[				<div class="wp-block-uagb-table-of-contents uagb-toc__align-left uagb-toc__columns-1  uagb-block-05d805a4      "
					data-scroll= "1"
					data-offset= "30"
					style=""
				>
				<div class="uagb-toc__wrap">
						<div class="uagb-toc__title">
							목차						</div>
																						<div class="uagb-toc__list-wrap ">
						<ol class="uagb-toc__list"><li class="uagb-toc__list"><a href="#기본적인-docker-명령어" class="uagb-toc-link__trigger">기본적인 Docker 명령어</a><li class="uagb-toc__list"><a href="#net-image-추가" class="uagb-toc-link__trigger">.NET Image 추가</a></ol>					</div>
									</div>
				</div>
			


<hr class="wp-block-separator has-alpha-channel-opacity is-style-wide" style="margin-top:var(--wp--preset--spacing--40);margin-bottom:var(--wp--preset--spacing--40)"/>



<h2 class="wp-block-heading">기본적인 Docker 명령어</h2>



<div class="wp-block-uagb-container uagb-block-8ea15a0c alignfull uagb-is-root-container"><div class="uagb-container-inner-blocks-wrap">
<div class="wp-block-uagb-container uagb-block-78e1b8eb">
<figure class="wp-block-image size-full"><img fetchpriority="high" decoding="async" width="694" height="521" src="https://lycos7560.com/wp-content/uploads/2025/07/image-24.png" alt="" class="wp-image-40182" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-24.png 694w, https://lycos7560.com/wp-content/uploads/2025/07/image-24-300x225.png 300w" sizes="(max-width: 694px) 100vw, 694px" /></figure>
</div>



<div class="wp-block-uagb-container uagb-block-b5e6ec6e">
<figure class="wp-block-image size-full"><img decoding="async" width="1876" height="938" src="https://lycos7560.com/wp-content/uploads/2025/07/image-25.png" alt="" class="wp-image-40183" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-25.png 1876w, https://lycos7560.com/wp-content/uploads/2025/07/image-25-300x150.png 300w, https://lycos7560.com/wp-content/uploads/2025/07/image-25-768x384.png 768w, https://lycos7560.com/wp-content/uploads/2025/07/image-25-1536x768.png 1536w" sizes="(max-width: 1876px) 100vw, 1876px" /></figure>
</div>
</div></div>



<div class="wp-block-uagb-container uagb-block-1d798c28 alignfull uagb-is-root-container"><div class="uagb-container-inner-blocks-wrap">
<div class="wp-block-uagb-container uagb-block-c832cc9d">
<figure class="wp-block-image size-full"><img decoding="async" width="969" height="505" src="https://lycos7560.com/wp-content/uploads/2025/07/image-26.png" alt="" class="wp-image-40184" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-26.png 969w, https://lycos7560.com/wp-content/uploads/2025/07/image-26-300x156.png 300w, https://lycos7560.com/wp-content/uploads/2025/07/image-26-768x400.png 768w" sizes="(max-width: 969px) 100vw, 969px" /><figcaption class="wp-element-caption">PowerShell 에서 Docker 버전 확인</figcaption></figure>



<pre class="EnlighterJSRAW" data-enlighter-language="powershell" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">docker --version</pre>
</div>



<div class="wp-block-uagb-container uagb-block-7b55c5ea">
<figure class="wp-block-image size-full"><img decoding="async" width="549" height="472" src="https://lycos7560.com/wp-content/uploads/2025/07/image-27.png" alt="" class="wp-image-40186" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-27.png 549w, https://lycos7560.com/wp-content/uploads/2025/07/image-27-300x258.png 300w" sizes="(max-width: 549px) 100vw, 549px" /></figure>



<pre class="EnlighterJSRAW" data-enlighter-language="powershell" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// Docker Hub에서 hello-world 이미지를 다운로드하는 명령어
docker pull hello-world</pre>



<figure class="wp-block-image size-full"><img decoding="async" width="901" height="241" src="https://lycos7560.com/wp-content/uploads/2025/07/image-28.png" alt="" class="wp-image-40187" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-28.png 901w, https://lycos7560.com/wp-content/uploads/2025/07/image-28-300x80.png 300w, https://lycos7560.com/wp-content/uploads/2025/07/image-28-768x205.png 768w" sizes="(max-width: 901px) 100vw, 901px" /><figcaption class="wp-element-caption">처음에는 docker를 잠시 멈추어 놓아서 실패</figcaption></figure>
</div>
</div></div>



<div class="wp-block-uagb-container uagb-block-498467b0 alignfull uagb-is-root-container"><div class="uagb-container-inner-blocks-wrap">
<div class="wp-block-uagb-container uagb-block-13b563ab">
<figure class="wp-block-image size-full"><img decoding="async" width="887" height="297" src="https://lycos7560.com/wp-content/uploads/2025/07/image-29.png" alt="" class="wp-image-40188" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-29.png 887w, https://lycos7560.com/wp-content/uploads/2025/07/image-29-300x100.png 300w, https://lycos7560.com/wp-content/uploads/2025/07/image-29-768x257.png 768w" sizes="(max-width: 887px) 100vw, 887px" /><figcaption class="wp-element-caption">다운로드 완료 후 이미지 확인</figcaption></figure>



<pre class="EnlighterJSRAW" data-enlighter-language="powershell" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">docker images</pre>
</div>



<div class="wp-block-uagb-container uagb-block-10c0d61c">
<figure class="wp-block-image size-full"><img decoding="async" width="1380" height="490" src="https://lycos7560.com/wp-content/uploads/2025/07/image-30.png" alt="" class="wp-image-40189" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-30.png 1380w, https://lycos7560.com/wp-content/uploads/2025/07/image-30-300x107.png 300w, https://lycos7560.com/wp-content/uploads/2025/07/image-30-768x273.png 768w" sizes="(max-width: 1380px) 100vw, 1380px" /><figcaption class="wp-element-caption">Desktop에서도 확인이 가능하</figcaption></figure>
</div>
</div></div>



<div class="wp-block-uagb-container uagb-block-5f7b883f alignfull uagb-is-root-container"><div class="uagb-container-inner-blocks-wrap">
<div class="wp-block-uagb-container uagb-block-f890a406">
<figure class="wp-block-image size-full"><img decoding="async" width="668" height="440" src="https://lycos7560.com/wp-content/uploads/2025/07/image-31.png" alt="" class="wp-image-40190" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-31.png 668w, https://lycos7560.com/wp-content/uploads/2025/07/image-31-300x198.png 300w" sizes="(max-width: 668px) 100vw, 668px" /><figcaption class="wp-element-caption">hello-world 이미지 실행</figcaption></figure>



<pre class="EnlighterJSRAW" data-enlighter-language="powershell" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">docker run hello-world</pre>
</div>



<div class="wp-block-uagb-container uagb-block-17c9d70c">
<figure class="wp-block-image size-full"><img decoding="async" width="1181" height="230" src="https://lycos7560.com/wp-content/uploads/2025/07/image-32.png" alt="" class="wp-image-40191" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-32.png 1181w, https://lycos7560.com/wp-content/uploads/2025/07/image-32-300x58.png 300w, https://lycos7560.com/wp-content/uploads/2025/07/image-32-768x150.png 768w" sizes="(max-width: 1181px) 100vw, 1181px" /></figure>



<pre class="EnlighterJSRAW" data-enlighter-language="powershell" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// 실행 중인 컨테이너 목록만 출력
docker ps

모든 컨테이너 목록 출력
// 중지된, 종료된, 에러 난 컨테이너도 포함해서 모두 보여줌
docker ps -a</pre>
</div>
</div></div>



<div class="wp-block-uagb-container uagb-block-e9226391 alignfull uagb-is-root-container"><div class="uagb-container-inner-blocks-wrap">
<div class="wp-block-uagb-container uagb-block-83c0597d">
<figure class="wp-block-image size-full"><img decoding="async" width="1105" height="477" src="https://lycos7560.com/wp-content/uploads/2025/07/image-33.png" alt="" class="wp-image-40192" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-33.png 1105w, https://lycos7560.com/wp-content/uploads/2025/07/image-33-300x130.png 300w, https://lycos7560.com/wp-content/uploads/2025/07/image-33-768x332.png 768w" sizes="(max-width: 1105px) 100vw, 1105px" /><figcaption class="wp-element-caption">이미지를 제거하려면 실행중인 container를 모두 제거해야한다.</figcaption></figure>



<pre class="EnlighterJSRAW" data-enlighter-language="powershell" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">docker ps // 컨테이너 확인
docker ps -a // 모든 컨테이너 확인
docker rm 5fea
docker rm 6c465
docker rm 0fe
docker rm 1957
docker ps -a // 모든 컨테이너 확인
docker images // 이미지 검색
docker rmi ec1538 // 이미지 제거</pre>
</div>



<div class="wp-block-uagb-container uagb-block-0047b3d5">
<figure class="wp-block-image size-full"><img decoding="async" width="1309" height="525" src="https://lycos7560.com/wp-content/uploads/2025/07/image-34.png" alt="" class="wp-image-40193" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-34.png 1309w, https://lycos7560.com/wp-content/uploads/2025/07/image-34-300x120.png 300w, https://lycos7560.com/wp-content/uploads/2025/07/image-34-768x308.png 768w" sizes="(max-width: 1309px) 100vw, 1309px" /><figcaption class="wp-element-caption">이미지 제거 적용됨</figcaption></figure>
</div>
</div></div>



<div class="wp-block-uagb-container uagb-block-97073334 alignfull uagb-is-root-container"><div class="uagb-container-inner-blocks-wrap">
<div class="wp-block-uagb-container uagb-block-8a80809e">
<figure class="wp-block-image size-full"><img decoding="async" width="1590" height="702" src="https://lycos7560.com/wp-content/uploads/2025/07/image-35.png" alt="" class="wp-image-40194" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-35.png 1590w, https://lycos7560.com/wp-content/uploads/2025/07/image-35-300x132.png 300w, https://lycos7560.com/wp-content/uploads/2025/07/image-35-768x339.png 768w, https://lycos7560.com/wp-content/uploads/2025/07/image-35-1536x678.png 1536w" sizes="(max-width: 1590px) 100vw, 1590px" /></figure>
</div>



<div class="wp-block-uagb-container uagb-block-d6288adb">
<figure class="wp-block-image size-full"><img decoding="async" width="982" height="256" src="https://lycos7560.com/wp-content/uploads/2025/07/image-36.png" alt="" class="wp-image-40195" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-36.png 982w, https://lycos7560.com/wp-content/uploads/2025/07/image-36-300x78.png 300w, https://lycos7560.com/wp-content/uploads/2025/07/image-36-768x200.png 768w" sizes="(max-width: 982px) 100vw, 982px" /></figure>



<pre class="EnlighterJSRAW" data-enlighter-language="powershell" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">docker run -d ubuntu sleep 10</pre>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>항목</th><th>의미</th></tr></thead><tbody><tr><td><code>docker run</code></td><td>새로운 컨테이너를 생성하고 실행</td></tr><tr><td><code>-d</code></td><td><strong>Detached mode</strong> → 백그라운드에서 실행</td></tr><tr><td><code>ubuntu</code></td><td>사용할 이미지 이름 (없으면 자동으로 Docker Hub에서 pull함)</td></tr><tr><td><code>sleep 10</code></td><td>컨테이너 내부에서 실행할 명령어 (10초 동안 대기)</td></tr></tbody></table></figure>
</div>
</div></div>



<hr class="wp-block-separator has-alpha-channel-opacity is-style-wide" style="margin-top:var(--wp--preset--spacing--40);margin-bottom:var(--wp--preset--spacing--40)"/>



<h2 class="wp-block-heading">.NET Image 추가</h2>



<div class="wp-block-uagb-container uagb-block-cf968062 alignfull uagb-is-root-container"><div class="uagb-container-inner-blocks-wrap">
<div class="wp-block-uagb-container uagb-block-deb4736b">
<figure class="wp-block-image size-full"><img decoding="async" width="1824" height="1016" src="https://lycos7560.com/wp-content/uploads/2025/07/image-37.png" alt="" class="wp-image-40196" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-37.png 1824w, https://lycos7560.com/wp-content/uploads/2025/07/image-37-300x167.png 300w, https://lycos7560.com/wp-content/uploads/2025/07/image-37-768x428.png 768w, https://lycos7560.com/wp-content/uploads/2025/07/image-37-1536x856.png 1536w" sizes="(max-width: 1824px) 100vw, 1824px" /><figcaption class="wp-element-caption"><a href="https://hub.docker.com/r/microsoft/dotnet-sdk" target="_blank" rel="noreferrer noopener">https://hub.docker.com/r/microsoft/dotnet-sdk</a></figcaption></figure>



<pre class="EnlighterJSRAW" data-enlighter-language="powershell" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">docker pull mcr.microsoft.com/dotnet/sdk:8.0
docker images</pre>
</div>



<div class="wp-block-uagb-container uagb-block-1095baf6">
<figure class="wp-block-image size-full"><img decoding="async" width="645" height="304" src="https://lycos7560.com/wp-content/uploads/2025/07/image-38.png" alt="" class="wp-image-40197" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-38.png 645w, https://lycos7560.com/wp-content/uploads/2025/07/image-38-300x141.png 300w" sizes="(max-width: 645px) 100vw, 645px" /></figure>



<figure class="wp-block-image size-full is-resized"><img decoding="async" width="763" height="165" src="https://lycos7560.com/wp-content/uploads/2025/07/image-39.png" alt="" class="wp-image-40198" style="width:763px;height:auto" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-39.png 763w, https://lycos7560.com/wp-content/uploads/2025/07/image-39-300x65.png 300w" sizes="(max-width: 763px) 100vw, 763px" /></figure>



<p>두 항목의 <strong><code>IMAGE ID</code>가 동일</strong><br>REPOSITORY: mcr.microsoft.com/dotnet/sdk<br>TAG: 9.0 → IMAGE ID: 08fe223b9022<br>TAG: latest → IMAGE ID: 08fe223b9022<br>이유: <code>latest</code> 태그는 <strong>별칭(alias)</strong> 이기 때문이다<br>도커에서 태그(<code>TAG</code>)는 특정 이미지 버전을 <strong>지칭하는 이름</strong>일 뿐이며, <strong>동일한 이미지에 여러 개의 태그를 붙일 수 있습니다.</strong><br>=> <code>9.0</code> 버전의 이미지에 <code>latest</code>라는 이름을 <strong>추가로 붙여 놓은 것</strong></p>
</div>
</div></div>



<p></p>
<p>The post <a href="https://lycos7560.com/docker/%ea%b8%b0%eb%b3%b8%ec%a0%81%ec%9d%b8-docker-%eb%aa%85%eb%a0%b9%ec%96%b4-%ec%97%b0%ec%8a%b5/40181/">기본적인 Docker 명령어 연습</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://lycos7560.com/docker/%ea%b8%b0%eb%b3%b8%ec%a0%81%ec%9d%b8-docker-%eb%aa%85%eb%a0%b9%ec%96%b4-%ec%97%b0%ec%8a%b5/40181/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Docker / Virtual Machine 차이점</title>
		<link>https://lycos7560.com/docker/docker-virtual-machine-%ec%b0%a8%ec%9d%b4%ec%a0%90/40173/</link>
					<comments>https://lycos7560.com/docker/docker-virtual-machine-%ec%b0%a8%ec%9d%b4%ec%a0%90/40173/#respond</comments>
		
		<dc:creator><![CDATA[lycos7560]]></dc:creator>
		<pubDate>Wed, 30 Jul 2025 12:57:01 +0000</pubDate>
				<category><![CDATA[Docker]]></category>
		<category><![CDATA[Application]]></category>
		<category><![CDATA[architecture]]></category>
		<category><![CDATA[Auto Scaling]]></category>
		<category><![CDATA[Automation]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[Azure]]></category>
		<category><![CDATA[Backup]]></category>
		<category><![CDATA[Base Image]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[Build]]></category>
		<category><![CDATA[CI/CD]]></category>
		<category><![CDATA[Cloud Computing]]></category>
		<category><![CDATA[Cloud Native]]></category>
		<category><![CDATA[Cloud Provider]]></category>
		<category><![CDATA[Compliance]]></category>
		<category><![CDATA[Container]]></category>
		<category><![CDATA[Container as a Service]]></category>
		<category><![CDATA[Container Registry]]></category>
		<category><![CDATA[Container Runtime]]></category>
		<category><![CDATA[Containerization]]></category>
		<category><![CDATA[Continuous Deployment]]></category>
		<category><![CDATA[Continuous Integration]]></category>
		<category><![CDATA[Deployment]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[Docker Compose]]></category>
		<category><![CDATA[Docker Desktop]]></category>
		<category><![CDATA[Docker Engine]]></category>
		<category><![CDATA[Docker Hub]]></category>
		<category><![CDATA[Dockerfile]]></category>
		<category><![CDATA[Enterprise]]></category>
		<category><![CDATA[Environment Variables]]></category>
		<category><![CDATA[GitOps]]></category>
		<category><![CDATA[Google Cloud]]></category>
		<category><![CDATA[Guest OS]]></category>
		<category><![CDATA[Health Check]]></category>
		<category><![CDATA[Host OS]]></category>
		<category><![CDATA[Hypervisor]]></category>
		<category><![CDATA[IaC]]></category>
		<category><![CDATA[Image]]></category>
		<category><![CDATA[Image Optimization]]></category>
		<category><![CDATA[Infrastructure]]></category>
		<category><![CDATA[Infrastructure as Code]]></category>
		<category><![CDATA[Isolation]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[Layer]]></category>
		<category><![CDATA[Legacy System]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Load Balancing]]></category>
		<category><![CDATA[Logging]]></category>
		<category><![CDATA[Microservices]]></category>
		<category><![CDATA[Migration]]></category>
		<category><![CDATA[Modernization]]></category>
		<category><![CDATA[Monitoring]]></category>
		<category><![CDATA[Multi-stage Build]]></category>
		<category><![CDATA[network]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Orchestration]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[pipeline]]></category>
		<category><![CDATA[Port Mapping]]></category>
		<category><![CDATA[Portability]]></category>
		<category><![CDATA[Production]]></category>
		<category><![CDATA[Pull]]></category>
		<category><![CDATA[Push]]></category>
		<category><![CDATA[Registry]]></category>
		<category><![CDATA[Resource Efficiency]]></category>
		<category><![CDATA[Run]]></category>
		<category><![CDATA[Scalability]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Security Scanning]]></category>
		<category><![CDATA[Service Mesh]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Staging]]></category>
		<category><![CDATA[study]]></category>
		<category><![CDATA[Swarm]]></category>
		<category><![CDATA[Tag]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[Troubleshooting]]></category>
		<category><![CDATA[Virtual Machine]]></category>
		<category><![CDATA[vm]]></category>
		<category><![CDATA[Volume]]></category>
		<category><![CDATA[Vulnerability]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[가상머신]]></category>
		<category><![CDATA[개발]]></category>
		<category><![CDATA[게스트 OS]]></category>
		<category><![CDATA[격리]]></category>
		<category><![CDATA[공부]]></category>
		<category><![CDATA[구글 클라우드]]></category>
		<category><![CDATA[기초]]></category>
		<category><![CDATA[깃옵스]]></category>
		<category><![CDATA[네트워크]]></category>
		<category><![CDATA[데브옵스]]></category>
		<category><![CDATA[도커]]></category>
		<category><![CDATA[도커 데스크톱]]></category>
		<category><![CDATA[도커 엔진]]></category>
		<category><![CDATA[도커 컴포즈]]></category>
		<category><![CDATA[도커 허브]]></category>
		<category><![CDATA[도커파일]]></category>
		<category><![CDATA[레거시 시스템]]></category>
		<category><![CDATA[레이어]]></category>
		<category><![CDATA[레지스트리]]></category>
		<category><![CDATA[로깅]]></category>
		<category><![CDATA[로드 밸런싱]]></category>
		<category><![CDATA[리눅스]]></category>
		<category><![CDATA[리소스 효율성]]></category>
		<category><![CDATA[마이그레이션]]></category>
		<category><![CDATA[마이크로서비스]]></category>
		<category><![CDATA[멀티 스테이지 빌드]]></category>
		<category><![CDATA[모니터링]]></category>
		<category><![CDATA[모범 사례]]></category>
		<category><![CDATA[배포]]></category>
		<category><![CDATA[백업]]></category>
		<category><![CDATA[베이스 이미지]]></category>
		<category><![CDATA[보안]]></category>
		<category><![CDATA[보안 스캔]]></category>
		<category><![CDATA[볼륨]]></category>
		<category><![CDATA[빌드]]></category>
		<category><![CDATA[서비스 메시]]></category>
		<category><![CDATA[서비스형 컨테이너]]></category>
		<category><![CDATA[성능]]></category>
		<category><![CDATA[소프트웨어 개발]]></category>
		<category><![CDATA[스웜]]></category>
		<category><![CDATA[스테이징]]></category>
		<category><![CDATA[실행]]></category>
		<category><![CDATA[아마존 웹 서비스]]></category>
		<category><![CDATA[아이아씨]]></category>
		<category><![CDATA[아키텍처]]></category>
		<category><![CDATA[애저]]></category>
		<category><![CDATA[애플리케이션]]></category>
		<category><![CDATA[엔터프라이즈]]></category>
		<category><![CDATA[오케스트레이션]]></category>
		<category><![CDATA[오픈 소스]]></category>
		<category><![CDATA[윈도우]]></category>
		<category><![CDATA[이미지]]></category>
		<category><![CDATA[이미지 최적화]]></category>
		<category><![CDATA[이식성]]></category>
		<category><![CDATA[인프라스트럭처]]></category>
		<category><![CDATA[자동 확장]]></category>
		<category><![CDATA[자동화]]></category>
		<category><![CDATA[지속적 배포]]></category>
		<category><![CDATA[지속적 통합]]></category>
		<category><![CDATA[취약점]]></category>
		<category><![CDATA[컨테이너]]></category>
		<category><![CDATA[컨테이너 런타임]]></category>
		<category><![CDATA[컨테이너 레지스트리]]></category>
		<category><![CDATA[컨테이너화]]></category>
		<category><![CDATA[컴플라이언스]]></category>
		<category><![CDATA[코드형 인프라]]></category>
		<category><![CDATA[쿠버네티스]]></category>
		<category><![CDATA[클라우드 네이티브]]></category>
		<category><![CDATA[클라우드 제공자]]></category>
		<category><![CDATA[클라우드 컴퓨팅]]></category>
		<category><![CDATA[태그]]></category>
		<category><![CDATA[테스팅]]></category>
		<category><![CDATA[트러블슈팅]]></category>
		<category><![CDATA[파이프라인]]></category>
		<category><![CDATA[포트 매핑]]></category>
		<category><![CDATA[푸시]]></category>
		<category><![CDATA[풀]]></category>
		<category><![CDATA[프로덕션]]></category>
		<category><![CDATA[하이퍼바이저]]></category>
		<category><![CDATA[헬스 체크]]></category>
		<category><![CDATA[현대화]]></category>
		<category><![CDATA[호스트 OS]]></category>
		<category><![CDATA[확장성]]></category>
		<category><![CDATA[환경 변수]]></category>
		<guid isPermaLink="false">https://lycos7560.com/?p=40173</guid>

					<description><![CDATA[<p>현대 소프트웨어 개발에서 가상화 기술은 필수적인 요소입니다. 전통적인 가상머신(Virtual Machine)과 Docker 컨테이너 기술의 차이점을 알아봅니다. 1. 아키텍처 비교 1.1 Virtual Machine 아키텍처 Virtual Machine은 다음과 같은 계층 구조를 가집니다: 특징: 1.2 Docker 아키텍처 Docker는 다음과 같은 경량화된 구조를 가집니다: 특징: 2. 핵심 차이점 분석 2.1 운영체제 레이어 구분 Virtual Machine Docker Guest OS 필수 불필요 [&#8230;]</p>
<p>The post <a href="https://lycos7560.com/docker/docker-virtual-machine-%ec%b0%a8%ec%9d%b4%ec%a0%90/40173/">Docker / Virtual Machine 차이점</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></description>
										<content:encoded><![CDATA[				<div class="wp-block-uagb-table-of-contents uagb-toc__align-left uagb-toc__columns-1  uagb-block-a0bc8ff7      "
					data-scroll= "1"
					data-offset= "30"
					style=""
				>
				<div class="uagb-toc__wrap">
						<div class="uagb-toc__title">
							목차						</div>
																						<div class="uagb-toc__list-wrap ">
						<ol class="uagb-toc__list"><li class="uagb-toc__list"><a href="#1-아키텍처-비교" class="uagb-toc-link__trigger">1. 아키텍처 비교</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#11-virtual-machine-아키텍처" class="uagb-toc-link__trigger">1.1 Virtual Machine 아키텍처</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#12-docker-아키텍처" class="uagb-toc-link__trigger">1.2 Docker 아키텍처</a></li></ul></li><li class="uagb-toc__list"><a href="#2-핵심-차이점-분석" class="uagb-toc-link__trigger">2. 핵심 차이점 분석</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#21-운영체제-레이어" class="uagb-toc-link__trigger">2.1 운영체제 레이어</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#22-리소스-사용량" class="uagb-toc-link__trigger">2.2 리소스 사용량</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#virtual-machine" class="uagb-toc-link__trigger">Virtual Machine</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#docker" class="uagb-toc-link__trigger">Docker</a></li></ul><li class="uagb-toc__list"><a href="#23-성능-비교" class="uagb-toc-link__trigger">2.3 성능 비교</a></li></ul></li></ul></li><li class="uagb-toc__list"><a href="#3-장단점-비교" class="uagb-toc-link__trigger">3. 장단점 비교</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#31-virtual-machine" class="uagb-toc-link__trigger">3.1 Virtual Machine</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#장점" class="uagb-toc-link__trigger">장점</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#단점" class="uagb-toc-link__trigger">단점</a></li></ul><li class="uagb-toc__list"><a href="#32-docker" class="uagb-toc-link__trigger">3.2 Docker</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#장점" class="uagb-toc-link__trigger">장점</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#단점" class="uagb-toc-link__trigger">단점</a></li></ul></li></ul></li></ul></li></ul></li><li class="uagb-toc__list"><a href="#4-사용-사례별-권장사항" class="uagb-toc-link__trigger">4. 사용 사례별 권장사항</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#41-virtual-machine이-적합한-경우" class="uagb-toc-link__trigger">4.1 Virtual Machine이 적합한 경우</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#42-docker가-적합한-경우" class="uagb-toc-link__trigger">4.2 Docker가 적합한 경우</a></li></ul></li></ul></li></ul></li></ul></li></ul></li><li class="uagb-toc__list"><a href="#5-하이브리드-접근법" class="uagb-toc-link__trigger">5. 하이브리드 접근법</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#51-vm-위의-docker" class="uagb-toc-link__trigger">5.1 VM 위의 Docker</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#52-클라우드-환경" class="uagb-toc-link__trigger">5.2 클라우드 환경</a></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li><li class="uagb-toc__list"><a href="#6-결론" class="uagb-toc-link__trigger">6. 결론</a></ul></ul></ul></ul></ul></ul></ol>					</div>
									</div>
				</div>
			


<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<p>현대 소프트웨어 개발에서 가상화 기술은 필수적인 요소입니다.</p>



<p>전통적인 가상머신(Virtual Machine)과 Docker 컨테이너 기술의 차이점을 알아봅니다.</p>



<figure class="wp-block-image size-full"><img decoding="async" width="1668" height="710" src="https://lycos7560.com/wp-content/uploads/2025/07/image-20.png" alt="" class="wp-image-40174" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-20.png 1668w, https://lycos7560.com/wp-content/uploads/2025/07/image-20-300x128.png 300w, https://lycos7560.com/wp-content/uploads/2025/07/image-20-768x327.png 768w, https://lycos7560.com/wp-content/uploads/2025/07/image-20-1536x654.png 1536w" sizes="(max-width: 1668px) 100vw, 1668px" /></figure>



<ul class="wp-block-list">
<li><strong>Infrastructure</strong> (물리적 하드웨어) </li>



<li><strong>Host OS</strong> (호스트 운영체제) </li>



<li><strong>Hypervisor</strong> (가상화 관리자) </li>



<li><strong>Guest OS</strong> (각 가상머신마다 독립된 운영체제) </li>



<li><strong>bins/lib</strong> (각 VM마다 독립된 바이너리/라이브러리) </li>



<li><strong>App 1, 2, 3</strong> (애플리케이션들)</li>
</ul>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">1. 아키텍처 비교</h2>



<h3 class="wp-block-heading">1.1 Virtual Machine 아키텍처</h3>



<p>Virtual Machine은 다음과 같은 계층 구조를 가집니다:</p>



<figure class="wp-block-image size-full"><img decoding="async" width="765" height="723" src="https://lycos7560.com/wp-content/uploads/2025/07/image-21.png" alt="" class="wp-image-40175" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-21.png 765w, https://lycos7560.com/wp-content/uploads/2025/07/image-21-300x284.png 300w" sizes="(max-width: 765px) 100vw, 765px" /></figure>



<p><strong>특징:</strong></p>



<ul class="wp-block-list">
<li>각 가상머신은 독립된 Guest OS를 보유</li>



<li>하드웨어 가상화를 통한 완전한 격리</li>



<li>Hypervisor가 하드웨어 리소스 관리</li>
</ul>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">1.2 Docker 아키텍처</h3>



<p>Docker는 다음과 같은 경량화된 구조를 가집니다:</p>



<figure class="wp-block-image size-full"><img decoding="async" width="746" height="692" src="https://lycos7560.com/wp-content/uploads/2025/07/image-22.png" alt="" class="wp-image-40176" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-22.png 746w, https://lycos7560.com/wp-content/uploads/2025/07/image-22-300x278.png 300w" sizes="(max-width: 746px) 100vw, 746px" /></figure>



<p><strong>특징:</strong></p>



<ul class="wp-block-list">
<li>Guest OS 레이어 제거</li>



<li>Host OS 커널 공유</li>



<li>컨테이너 단위의 프로세스 격리</li>
</ul>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">2. 핵심 차이점 분석</h2>



<h3 class="wp-block-heading">2.1 운영체제 레이어</h3>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>구분</th><th>Virtual Machine</th><th>Docker</th></tr></thead><tbody><tr><td>Guest OS</td><td>필수</td><td>불필요</td></tr><tr><td>커널</td><td>각 VM마다 독립</td><td>Host OS 커널 공유</td></tr><tr><td>부팅 과정</td><td>OS 전체 부팅</td><td>프로세스 시작</td></tr></tbody></table></figure>



<h3 class="wp-block-heading">2.2 리소스 사용량</h3>



<h4 class="wp-block-heading">Virtual Machine</h4>



<ul class="wp-block-list">
<li><strong>메모리</strong>: GB 단위 (OS + 애플리케이션)</li>



<li><strong>디스크</strong>: 수 GB ~ 수십 GB</li>



<li><strong>CPU</strong>: OS 오버헤드 포함</li>



<li><strong>네트워크</strong>: 가상 네트워크 스택</li>
</ul>



<h4 class="wp-block-heading">Docker</h4>



<ul class="wp-block-list">
<li><strong>메모리</strong>: MB 단위 (애플리케이션만)</li>



<li><strong>디스크</strong>: MB ~ GB 단위</li>



<li><strong>CPU</strong>: 최소한의 오버헤드</li>



<li><strong>네트워크</strong>: Host 네트워크 스택 공유</li>
</ul>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">2.3 성능 비교</h3>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>항목</th><th>Virtual Machine</th><th>Docker</th></tr></thead><tbody><tr><td>시작 시간</td><td>1-5분</td><td>1-10초</td></tr><tr><td>메모리 오버헤드</td><td>높음 (OS 포함)</td><td>낮음 (애플리케이션만)</td></tr><tr><td>I/O 성능</td><td>가상화 오버헤드</td><td>네이티브에 근접</td></tr><tr><td>밀도</td><td>낮음 (서버당 수십 개)</td><td>높음 (서버당 수백-수천 개)</td></tr></tbody></table></figure>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">3. 장단점 비교</h2>



<h3 class="wp-block-heading">3.1 Virtual Machine</h3>



<h4 class="wp-block-heading">장점</h4>



<ul class="wp-block-list">
<li><strong>완전한 격리</strong>: 하드웨어 레벨의 보안 격리</li>



<li><strong>OS 다양성</strong>: 다양한 운영체제 동시 실행 가능</li>



<li><strong>성숙한 기술</strong>: 오랜 기간 검증된 안정성</li>



<li><strong>강력한 보안</strong>: 하이퍼바이저 레벨 보안</li>
</ul>



<h4 class="wp-block-heading">단점</h4>



<ul class="wp-block-list">
<li><strong>높은 리소스 사용량</strong>: OS 오버헤드</li>



<li><strong>느린 시작</strong>: 부팅 시간 필요</li>



<li><strong>관리 복잡성</strong>: 각 VM의 OS 관리 필요</li>



<li><strong>낮은 밀도</strong>: 제한적인 VM 수</li>
</ul>



<h3 class="wp-block-heading">3.2 Docker</h3>



<h4 class="wp-block-heading">장점</h4>



<ul class="wp-block-list">
<li><strong>경량성</strong>: 최소한의 리소스 사용</li>



<li><strong>빠른 시작</strong>: 초 단위 컨테이너 시작</li>



<li><strong>높은 밀도</strong>: 단일 호스트에 많은 컨테이너</li>



<li><strong>일관성</strong>: &#8220;한 번 빌드, 어디서든 실행&#8221;</li>



<li><strong>DevOps 친화적</strong>: CI/CD 파이프라인 최적화</li>
</ul>



<h4 class="wp-block-heading">단점</h4>



<ul class="wp-block-list">
<li><strong>보안 취약점</strong>: 커널 공유로 인한 잠재적 위험</li>



<li><strong>OS 제약</strong>: Linux 컨테이너는 Linux에서만</li>



<li><strong>복잡한 네트워킹</strong>: 컨테이너 간 통신 설정</li>



<li><strong>데이터 지속성</strong>: 컨테이너 재시작 시 데이터 손실 위험</li>
</ul>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">4. 사용 사례별 권장사항</h2>



<h3 class="wp-block-heading">4.1 Virtual Machine이 적합한 경우</h3>



<p><strong>기업 환경</strong></p>



<ul class="wp-block-list">
<li>레거시 애플리케이션 운영</li>



<li>서로 다른 OS가 필요한 환경</li>



<li>강력한 보안 격리가 필요한 경우</li>



<li>규제 준수가 중요한 산업</li>
</ul>



<p><strong>기술적 요구사항</strong></p>



<ul class="wp-block-list">
<li>Windows와 Linux 애플리케이션 동시 운영</li>



<li>커널 수준의 소프트웨어 개발</li>



<li>완전한 네트워크 격리 필요</li>



<li>다양한 OS 버전 테스트</li>
</ul>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">4.2 Docker가 적합한 경우</h3>



<p><strong>현대적 애플리케이션 개발</strong></p>



<ul class="wp-block-list">
<li>마이크로서비스 아키텍처</li>



<li>클라우드 네이티브 애플리케이션</li>



<li>지속적 통합/배포 (CI/CD)</li>



<li>개발 환경 표준화</li>
</ul>



<p><strong>운영 효율성</strong></p>



<ul class="wp-block-list">
<li>빠른 스케일링이 필요한 서비스</li>



<li>리소스 효율성이 중요한 환경</li>



<li>개발팀 간 환경 일관성</li>



<li>컨테이너 오케스트레이션 (Kubernetes)</li>
</ul>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">5. 하이브리드 접근법</h2>



<p>많은 조직에서는 두 기술을 함께 사용합니다:</p>



<h3 class="wp-block-heading">5.1 VM 위의 Docker</h3>



<ul class="wp-block-list">
<li>VM으로 기본 격리 제공</li>



<li>VM 내에서 Docker로 애플리케이션 컨테이너화</li>



<li>보안과 효율성의 균형</li>
</ul>



<h3 class="wp-block-heading">5.2 클라우드 환경</h3>



<ul class="wp-block-list">
<li>AWS ECS, Google Cloud Run 등</li>



<li>관리형 컨테이너 서비스</li>



<li>인프라 추상화</li>
</ul>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">6. 결론</h2>



<p>Virtual Machine과 Docker는 각각 고유한 장점과 적용 영역을 가지고 있습니다.</p>



<p><strong>Virtual Machine</strong>은 강력한 격리와 다양한 OS 지원이 필요한 전통적인 엔터프라이즈 환경에 적합하며, </p>



<p><strong>Docker</strong>는 현대적인 클라우드 네이티브 애플리케이션 개발과 운영에 최적화되어 있습니다.</p>



<p>성공적인 시스템 설계를 위해서는 각 기술의 특성을 정확히 이해하고, 프로젝트의 요구사항에 맞는 적절한 선택을 하는 것이 중요합니다. </p>



<p>많은 경우 두 기술을 적절히 조합하여 사용하는 하이브리드 접근법이 최적의 결과를 제공할 수 있습니다.</p>
<p>The post <a href="https://lycos7560.com/docker/docker-virtual-machine-%ec%b0%a8%ec%9d%b4%ec%a0%90/40173/">Docker / Virtual Machine 차이점</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://lycos7560.com/docker/docker-virtual-machine-%ec%b0%a8%ec%9d%b4%ec%a0%90/40173/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>ASP.NET Core Route Constraints</title>
		<link>https://lycos7560.com/c/asp-net/asp-net-core-route-constraints/40140/</link>
					<comments>https://lycos7560.com/c/asp-net/asp-net-core-route-constraints/40140/#respond</comments>
		
		<dc:creator><![CDATA[lycos7560]]></dc:creator>
		<pubDate>Mon, 28 Jul 2025 04:02:09 +0000</pubDate>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[.NET Development]]></category>
		<category><![CDATA[Action Method]]></category>
		<category><![CDATA[alpha]]></category>
		<category><![CDATA[Alphabetic]]></category>
		<category><![CDATA[alphanum]]></category>
		<category><![CDATA[Alphanumeric]]></category>
		<category><![CDATA[API Development]]></category>
		<category><![CDATA[API 개발]]></category>
		<category><![CDATA[app.UseEndpoints()]]></category>
		<category><![CDATA[app.UseRouting()]]></category>
		<category><![CDATA[Application Routing]]></category>
		<category><![CDATA[ASP.NET Core]]></category>
		<category><![CDATA[Attribute Routing]]></category>
		<category><![CDATA[Backend Development]]></category>
		<category><![CDATA[bool]]></category>
		<category><![CDATA[Boolean]]></category>
		<category><![CDATA[Catch-all parameter]]></category>
		<category><![CDATA[Conditional Routing]]></category>
		<category><![CDATA[Constraint]]></category>
		<category><![CDATA[Constraint Mapping]]></category>
		<category><![CDATA[Constraint Pattern]]></category>
		<category><![CDATA[ConstraintMap]]></category>
		<category><![CDATA[Controller]]></category>
		<category><![CDATA[Convention-based Routing]]></category>
		<category><![CDATA[custom]]></category>
		<category><![CDATA[datetime]]></category>
		<category><![CDATA[decimal]]></category>
		<category><![CDATA[Default Value]]></category>
		<category><![CDATA[double]]></category>
		<category><![CDATA[Dynamic Path]]></category>
		<category><![CDATA[Endpoint]]></category>
		<category><![CDATA[Endpoint Routing]]></category>
		<category><![CDATA[Explicit Routing]]></category>
		<category><![CDATA[Extensibility]]></category>
		<category><![CDATA[float]]></category>
		<category><![CDATA[guid]]></category>
		<category><![CDATA[HTTP Methods]]></category>
		<category><![CDATA[HTTP Request]]></category>
		<category><![CDATA[HTTP 메서드]]></category>
		<category><![CDATA[HTTP 요청]]></category>
		<category><![CDATA[HttpContext]]></category>
		<category><![CDATA[IEndpointRouteBuilder]]></category>
		<category><![CDATA[Implicit Routing]]></category>
		<category><![CDATA[int]]></category>
		<category><![CDATA[Integer]]></category>
		<category><![CDATA[IRouteConstraint]]></category>
		<category><![CDATA[Lambda Handler]]></category>
		<category><![CDATA[Length]]></category>
		<category><![CDATA[length()]]></category>
		<category><![CDATA[long]]></category>
		<category><![CDATA[MapGet()]]></category>
		<category><![CDATA[MapPost()]]></category>
		<category><![CDATA[max()]]></category>
		<category><![CDATA[Maximum]]></category>
		<category><![CDATA[Maximum Length]]></category>
		<category><![CDATA[maxlength()]]></category>
		<category><![CDATA[Middleware]]></category>
		<category><![CDATA[min()]]></category>
		<category><![CDATA[Minimal API]]></category>
		<category><![CDATA[Minimum]]></category>
		<category><![CDATA[Minimum Length]]></category>
		<category><![CDATA[minlength()]]></category>
		<category><![CDATA[MVC Pattern]]></category>
		<category><![CDATA[MVC 패턴]]></category>
		<category><![CDATA[Optional Parameter]]></category>
		<category><![CDATA[Parameter Binding]]></category>
		<category><![CDATA[Path Constraint]]></category>
		<category><![CDATA[Path Matching]]></category>
		<category><![CDATA[Placeholder]]></category>
		<category><![CDATA[range()]]></category>
		<category><![CDATA[Razor Pages]]></category>
		<category><![CDATA[Regex]]></category>
		<category><![CDATA[Request Processing]]></category>
		<category><![CDATA[Request Routing]]></category>
		<category><![CDATA[required]]></category>
		<category><![CDATA[Required Parameter]]></category>
		<category><![CDATA[RESTful API]]></category>
		<category><![CDATA[Route Builder]]></category>
		<category><![CDATA[Route Constraint]]></category>
		<category><![CDATA[Route Control]]></category>
		<category><![CDATA[Route Data]]></category>
		<category><![CDATA[Route Definition]]></category>
		<category><![CDATA[Route Handler]]></category>
		<category><![CDATA[Route Options]]></category>
		<category><![CDATA[Route Parameter]]></category>
		<category><![CDATA[Route Parameter Validation]]></category>
		<category><![CDATA[Route Priority]]></category>
		<category><![CDATA[Route Restriction]]></category>
		<category><![CDATA[Route Template]]></category>
		<category><![CDATA[RouteValueDictionary]]></category>
		<category><![CDATA[Routing Configuration]]></category>
		<category><![CDATA[Routing Engine]]></category>
		<category><![CDATA[Routing Middleware]]></category>
		<category><![CDATA[Routing Rules]]></category>
		<category><![CDATA[Routing System]]></category>
		<category><![CDATA[routing table]]></category>
		<category><![CDATA[SEO Friendly]]></category>
		<category><![CDATA[SEO 친화적]]></category>
		<category><![CDATA[study]]></category>
		<category><![CDATA[url]]></category>
		<category><![CDATA[URL Constraint]]></category>
		<category><![CDATA[URL Design]]></category>
		<category><![CDATA[URL Matching]]></category>
		<category><![CDATA[URL Parsing]]></category>
		<category><![CDATA[URL Path Variable]]></category>
		<category><![CDATA[URL Segment]]></category>
		<category><![CDATA[URL Structure]]></category>
		<category><![CDATA[URL Validity]]></category>
		<category><![CDATA[URL 경로 변수]]></category>
		<category><![CDATA[URL 구조]]></category>
		<category><![CDATA[URL 매칭]]></category>
		<category><![CDATA[URL 설계]]></category>
		<category><![CDATA[URL 세그먼트]]></category>
		<category><![CDATA[URL 유효성]]></category>
		<category><![CDATA[URL 파싱]]></category>
		<category><![CDATA[Validation]]></category>
		<category><![CDATA[Web Application]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Web Framework]]></category>
		<category><![CDATA[경로 매칭]]></category>
		<category><![CDATA[경로 일치]]></category>
		<category><![CDATA[경로 제약]]></category>
		<category><![CDATA[공부]]></category>
		<category><![CDATA[규칙 기반 라우팅]]></category>
		<category><![CDATA[기본값]]></category>
		<category><![CDATA[기초]]></category>
		<category><![CDATA[동적 경로]]></category>
		<category><![CDATA[라우트]]></category>
		<category><![CDATA[라우트 데이터]]></category>
		<category><![CDATA[라우트 빌더]]></category>
		<category><![CDATA[라우트 옵션]]></category>
		<category><![CDATA[라우트 우선순위]]></category>
		<category><![CDATA[라우트 정의]]></category>
		<category><![CDATA[라우트 제약]]></category>
		<category><![CDATA[라우트 제어]]></category>
		<category><![CDATA[라우트 제한]]></category>
		<category><![CDATA[라우트 템플릿]]></category>
		<category><![CDATA[라우트 파라미터 유효성]]></category>
		<category><![CDATA[라우트 핸들러]]></category>
		<category><![CDATA[라우팅]]></category>
		<category><![CDATA[라우팅 규칙]]></category>
		<category><![CDATA[라우팅 매개변수]]></category>
		<category><![CDATA[라우팅 미들웨어]]></category>
		<category><![CDATA[라우팅 설정]]></category>
		<category><![CDATA[라우팅 시스템]]></category>
		<category><![CDATA[라우팅 엔진]]></category>
		<category><![CDATA[라우팅 테이블]]></category>
		<category><![CDATA[람다 핸들러]]></category>
		<category><![CDATA[매개변수 바인딩]]></category>
		<category><![CDATA[명시적 라우팅]]></category>
		<category><![CDATA[미들웨어]]></category>
		<category><![CDATA[백엔드 개발]]></category>
		<category><![CDATA[사용자 지정]]></category>
		<category><![CDATA[선택적 매개변수]]></category>
		<category><![CDATA[속성 라우팅]]></category>
		<category><![CDATA[암시적 라우팅]]></category>
		<category><![CDATA[애플리케이션 라우팅]]></category>
		<category><![CDATA[액션 메서드]]></category>
		<category><![CDATA[엔드포인트]]></category>
		<category><![CDATA[엔드포인트 라우팅]]></category>
		<category><![CDATA[요청 라우팅]]></category>
		<category><![CDATA[요청 처리]]></category>
		<category><![CDATA[웹 애플리케이션]]></category>
		<category><![CDATA[웹 프레임워크]]></category>
		<category><![CDATA[유효성 검사]]></category>
		<category><![CDATA[정규식]]></category>
		<category><![CDATA[제약 조건 매핑]]></category>
		<category><![CDATA[제약 조건 패턴]]></category>
		<category><![CDATA[제한 조건]]></category>
		<category><![CDATA[조건부 라우팅]]></category>
		<category><![CDATA[캐치올 매개변수]]></category>
		<category><![CDATA[컨트롤러]]></category>
		<category><![CDATA[플레이스홀더]]></category>
		<category><![CDATA[확장성]]></category>
		<guid isPermaLink="false">https://lycos7560.com/?p=40140</guid>

					<description><![CDATA[<p>🔥 ASP.NET Core Route Constraints (라우트 제한 조건) https://learn.microsoft.com/en-us/aspnet/core/fundamentals/routing?view=aspnetcore-8.0 ASP.NET Core의 라우팅 시스템에서 라우트 제한 조건(Route Constraints)은 URL 경로의 특정 세그먼트(라우팅 매개변수)에 대한 유효성 검사 규칙을 정의하는 강력한 기능입니다. 이를 통해 특정 URL 패턴이 매칭되기 위한 조건을 명시하고, 잘못된 형식의 URL 요청이 특정 라우트에 매칭되는 것을 방지할 수 있습니다. 1️⃣ 라우트 제한 조건의 필요성 1. [&#8230;]</p>
<p>The post <a href="https://lycos7560.com/c/asp-net/asp-net-core-route-constraints/40140/">ASP.NET Core Route Constraints</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></description>
										<content:encoded><![CDATA[				<div class="wp-block-uagb-table-of-contents uagb-toc__align-left uagb-toc__columns-1  uagb-block-ce724247      "
					data-scroll= "1"
					data-offset= "30"
					style=""
				>
				<div class="uagb-toc__wrap">
						<div class="uagb-toc__title">
							목차						</div>
																						<div class="uagb-toc__list-wrap ">
						<ol class="uagb-toc__list"><li class="uagb-toc__list"><a href="#aspnet-core-route-constraints-라우트-제한-조건" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f525.png" alt="🔥" class="wp-smiley" style="height: 1em; max-height: 1em;" /> ASP.NET Core Route Constraints (라우트 제한 조건)</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#1-라우트-제한-조건의-필요성" class="uagb-toc-link__trigger">1&#x20e3; 라우트 제한 조건의 필요성</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#2-라우트-제한-조건-정의-방법" class="uagb-toc-link__trigger">2&#x20e3; 라우트 제한 조건 정의 방법</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#3-주요-라우트-제한-조건-종류-및-예시" class="uagb-toc-link__trigger">3&#x20e3; 주요 라우트 제한 조건 종류 및 예시</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#타입-기반-제한-조건" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 타입 기반 제한 조건</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#길이-및-범위-기반-제한-조건" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 길이 및 범위 기반 제한 조건</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#정규식-기반-제한-조건" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 정규식 기반 제한 조건</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#다른-일반적인-제한-조건" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 다른 일반적인 제한 조건</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#사용자-지정-라우트-제한-조건-custom-route-constraints" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 사용자 지정 라우트 제한 조건 (Custom Route Constraints)</a></li></ul><li class="uagb-toc__list"><a href="#4-endpoint-selection-order-엔드포인트-선택-순서" class="uagb-toc-link__trigger">4&#x20e3; Endpoint Selection Order (엔드포인트 선택 순서)</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#명시적-순서-order-property" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 명시적 순서 (Order Property)</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#라우트-템플릿의-구체성-specificity" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 라우트 템플릿의 구체성 (Specificity):</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#정의-순서-declaration-order" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 정의 순서 (Declaration Order):</a></ul></ul></ol>					</div>
									</div>
				</div>
			


<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f525.png" alt="🔥" class="wp-smiley" style="height: 1em; max-height: 1em;" /> ASP.NET Core Route Constraints (라우트 제한 조건)</h2>



<p><a href="https://learn.microsoft.com/en-us/aspnet/core/fundamentals/routing?view=aspnetcore-8.0" target="_blank" rel="noreferrer noopener">https://learn.microsoft.com/en-us/aspnet/core/fundamentals/routing?view=aspnetcore-8.0</a></p>



<p>ASP.NET Core의 라우팅 시스템에서 <strong>라우트 제한 조건(Route Constraints)</strong>은 URL 경로의 특정 세그먼트(라우팅 매개변수)에 대한 유효성 검사 규칙을 정의하는 강력한 기능입니다. </p>



<p>이를 통해 특정 URL 패턴이 매칭되기 위한 조건을 명시하고, 잘못된 형식의 URL 요청이 특정 라우트에 매칭되는 것을 방지할 수 있습니다.</p>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">1&#x20e3; 라우트 제한 조건의 필요성</h3>



<p>1. <strong>정확한 라우트 매칭</strong>: <br>동일한 경로 프리픽스를 가지는 여러 라우트 중에서 가장 적절한 라우트를 선택할 수 있도록 돕습니다.</p>



<ul class="wp-block-list">
<li>예: <code>/products/123</code> (ID로 조회)와 <code>/products/shoes</code> (이름으로 조회)를 구분</li>
</ul>



<p>2. <strong>유효성 검사</strong>: <br>특정 매개변수가 예상하는 형식(예: 숫자, GUID, 날짜)인지 강제하여, 컨트롤러 액션 또는 핸들러에서 타입 변환 오류를 줄입니다.</p>



<p>3. <strong>보안 및 견고성</strong>: <br>잘못된 형식의 입력으로 인한 잠재적인 오류나 공격 시도를 줄이는 데 기여합니다.</p>



<p>4. <strong>URL 디자인 강화</strong>: <br>더욱 명확하고 의미론적인 URL 구조를 유지할 수 있도록 돕습니다.</p>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">2&#x20e3; 라우트 제한 조건 정의 방법</h3>



<p>라우트 제한 조건은 라우트 템플릿 내에서 라우팅 매개변수 이름 뒤에 <strong>콜론(<code>:</code>)을 붙이고 제한 조건 이름을 지정하여 정의</strong>합니다.</p>



<p>{매개변수명:제한조건이름}</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// Program.cs 또는 Startup.cs의 UseEndpoints 블록
endpoints.MapGet("/products/{id:int}", (int id) => Results.Ok($"Product ID: {id}"));</pre>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">3&#x20e3; 주요 라우트 제한 조건 종류 및 예시</h3>



<p>ASP.NET Core는 다양한 내장 라우트 제한 조건을 제공합니다.</p>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 타입 기반 제한 조건</h4>



<p>ASP.NET Core는 다양한 내장 라우트 제한 조건을 제공합니다.</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><tbody><tr><td>제한 조건</td><td>설명</td><td>예시</td><td>매칭되는 URL</td><td>매칭되지 않는 URL</td></tr><tr><td>int</td><td>32비트 정수로 매칭됩니다.</td><td>{id:int}</td><td>/items/123</td><td>/items/abc, /items/1.5</td></tr><tr><td>bool</td><td>불리언 값(true/false)으로 매칭됩니다.</td><td>{isActive:bool}</td><td>/status/true</td><td>/status/other</td></tr><tr><td>datetime</td><td>DateTime 형식으로 매칭됩니다.</td><td>{date:datetime}</td><td>/events/2023-10-26</td><td>/events/today</td></tr><tr><td>decimal</td><td>decimal 형식으로 매칭됩니다.</td><td>{price:decimal}</td><td>/products/99.99</td><td>/products/abc</td></tr><tr><td>double</td><td>double 형식으로 매칭됩니다.</td><td>{value:double}</td><td>/data/3.14159</td><td>/data/xyz</td></tr><tr><td>float</td><td>float 형식으로 매칭됩니다.</td><td>{measurement:float}</td><td>/sensor/0.5f</td><td>/sensor/abc</td></tr><tr><td>guid</td><td>GUID(Globally Unique Identifier)로 매칭됩니다.</td><td>{itemId:guid}</td><td>/item/a1b2c3d4-e5f6-7890-1234-567890abcdef</td><td>/item/invalid-guid</td></tr><tr><td>long</td><td>64비트 정수로 매칭됩니다.</td><td>{userId:long}</td><td>/users/9876543210</td><td>/users/short</td></tr></tbody></table></figure>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// Program.cs 또는 Startup.cs
app.UseEndpoints(endpoints =>
{
    // 정수형 ID만 허용
    endpoints.MapGet("/products/{id:int}", (int id) => Results.Ok($"Getting product by ID: {id}"));

    // GUID 형식의 아이템 ID만 허용
    endpoints.MapGet("/items/{itemId:guid}", (Guid itemId) => Results.Ok($"Getting item by GUID: {itemId}"));

    // 특정 날짜 형식의 이벤트만 허용
    endpoints.MapGet("/events/on/{date:datetime}", (DateTime date) => Results.Ok($"Events on: {date.ToShortDateString()}"));
});</pre>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 길이 및 범위 기반 제한 조건</h4>



<p>매개변수 값의 길이 또는 숫자 범위를 제한합니다.</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><tbody><tr><td>제한 조건</td><td>설명</td><td>예시</td><td>매칭되는 URL</td><td>매칭되지 않는 URL</td></tr><tr><td>min(value)</td><td>최소값 value 이상이어야 합니다.</td><td>{age:min(18)}</td><td>/users/age/18, /users/age/25</td><td>/users/age/17, /users/age/abc</td></tr><tr><td>max(value)</td><td>최대값 value 이하여야 합니다.</td><td>{quantity:max(100)}</td><td>/order/items/50</td><td>/order/items/101</td></tr><tr><td>range(min,max)</td><td>min과 max 사이의 값이어야 합니다.</td><td>{year:range(2000,2024)}</td><td>/posts/2023</td><td>/posts/1999, /posts/2025</td></tr><tr><td>minlength(length)</td><td>최소 length 길이 이상이어야 합니다.</td><td>{code:minlength(3)}</td><td>/code/abc, /code/abcd</td><td>/code/ab</td></tr><tr><td>maxlength(length)</td><td>최대 length 길이 이하여야 합니다.</td><td>{name:maxlength(10)}</td><td>/user/john</td><td>/user/someverylongname</td></tr><tr><td>length(min,max)</td><td>min과 max 사이의 길이어야 합니다.</td><td>{zip:length(5,9)}</td><td>/zip/12345, /zip/12345-6789</td><td>/zip/123, /zip/1234567890</td></tr></tbody></table></figure>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">app.UseEndpoints(endpoints =>
{
    // 연령이 18세 이상인 사용자만 허용
    endpoints.MapGet("/users/age/{age:min(18)}", (int age) => Results.Ok($"Adult user, age: {age}"));

    // 재고 수량이 10개에서 100개 사이인 경우에만 유효
    endpoints.MapGet("/inventory/{count:range(10,100)}", (int count) => Results.Ok($"Checking inventory count: {count}"));

    // 최소 5자, 최대 10자의 사용자 이름만 허용
    endpoints.MapGet("/profile/{username:length(5,10)}", (string username) => Results.Ok($"Profile for user: {username}"));
});</pre>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 정규식 기반 제한 조건</h4>



<p>정규 표현식(Regular Expression)을 사용하여 매개변수 값의 패턴을 지정합니다. </p>



<p>이는 가장 유연한 제한 조건입니다.</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><tbody><tr><td>제한 조건</td><td>설명</td><td>예시</td><td>매칭되는 URL</td><td>매칭되지 않는 URL</td></tr><tr><td>regex(pattern)</td><td>pattern 정규식과 일치해야 합니다.</td><td>{code:regex(^[A-Z]{3}\\d{4}$)}</td><td>/item/ABC1234</td><td>/item/abc1234, /item/ABC123</td></tr></tbody></table></figure>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">app.UseEndpoints(endpoints =>
{
    // "abc"로 시작하고 숫자로 끝나는 코드만 허용
    endpoints.MapGet("/validate/{code:regex(abc\\d+)}", (string code) => Results.Ok($"Validated code: {code}"));

    // 상품 코드가 "PROD-"로 시작하고 4자리 숫자로 끝나는 경우만 허용
    endpoints.MapGet("/productcodes/{productCode:regex(^PROD-\\d{{4}}$)}", (string productCode) => Results.Ok($"Valid product code: {productCode}"));
    // 참고: 정규식 내의 중괄호는 이스케이프 필요 ({{, }})
});</pre>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 다른 일반적인 제한 조건</h4>



<figure class="wp-block-table"><table class="has-fixed-layout"><tbody><tr><td>제한 조건</td><td>설명</td><td>예시</td><td>매칭되는 URL</td><td>매칭되지 않는 URL</td></tr><tr><td>alpha</td><td>알파벳 문자(a-z, A-Z)만 허용합니다.</td><td>{name:alpha}</td><td>/users/john</td><td>/users/john123</td></tr><tr><td>alphanum</td><td>알파벳 문자 또는 숫자만 허용합니다.</td><td>{token:alphanum}</td><td>/api/token/abc123</td><td>/api/token/abc-123</td></tr><tr><td>required</td><td>매개변수가 반드시 존재해야 합니다. (?와 함께 사용 불가)</td><td>{country:required}</td><td>/location/korea</td><td>/location/</td></tr><tr><td>url</td><td>유효한 URL 형식이어야 합니다.</td><td>{redirectUrl:url}</td><td>/redirect/https://google.com</td><td>/redirect/not-a-url</td></tr><tr><td>minlength, maxlength, length</td><td>string 형식에 대한 길이 제한</td><td>위 &#8220;길이 및 범위 기반&#8221; 섹션 참고</td><td></td><td></td></tr></tbody></table></figure>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">app.UseEndpoints(endpoints =>
{
    // 이름은 알파벳만 허용
    endpoints.MapGet("/greet/{name:alpha}", (string name) => Results.Ok($"Hello, {name}!"));

    // 토큰은 알파벳 또는 숫자만 허용
    endpoints.MapGet("/verify/{token:alphanum}", (string token) => Results.Ok($"Verifying token: {token}"));

    // 국가 매개변수는 반드시 제공되어야 함
    endpoints.MapGet("/country/{country:required}", (string country) => Results.Ok($"Selected country: {country}"));
});</pre>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 사용자 지정 라우트 제한 조건 (Custom Route Constraints)</h4>



<p>내장된 제한 조건만으로는 부족할 때, <code>IRouteConstraint</code> 인터페이스를 구현하여 자신만의 커스텀 라우트 제한 조건을 만들 수 있습니다.</p>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<p><code>IRouteConstraint</code> 인터페이스 구현</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using System.Globalization;

public class CustomYearConstraint : IRouteConstraint
{
    public bool Match(HttpContext? httpContext, IRouter? route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection)
    {
        // routeKey는 매개변수 이름 (예: "year")
        // values는 모든 라우팅 매개변수와 그 값들을 담고 있는 딕셔너리
        if (values.TryGetValue(routeKey, out object? value))
        {
            if (value is string yearString &amp;&amp; int.TryParse(yearString, out int year))
            {
                // 2000년 이후의 연도만 허용하는 예시
                return year >= 2000 &amp;&amp; year &lt;= DateTime.Now.Year + 1;
            }
        }
        return false;
    }
}</pre>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<p>제한 조건 등록</p>



<p><code>Startup.cs</code>의 <code>ConfigureServices</code> 또는 <code>Program.cs</code>에서 <code>AddRouting</code> 메서드를 사용하여 커스텀 제한 조건을 등록합니다.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// Program.cs
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRouting(options =>
{
    options.ConstraintMap.Add("customYear", typeof(CustomYearConstraint));
});

var app = builder.Build();

app.UseRouting();
app.UseEndpoints(endpoints =>
{
    // /articles/2023 와 같이 customYear 제한 조건을 사용
    endpoints.MapGet("/articles/{year:customYear}", (int year) => Results.Ok($"Articles from year: {year}"));
});

app.Run();

//  사용 예시:
//  /articles/2023 -> 매칭됨
//  /articles/1999 -> 매칭되지 않음
//  /articles/2026 (현재 연도가 2025년이라면) -> 매칭되지 않음 (DateTime.Now.Year + 1 조건에 따라)</pre>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">4&#x20e3; Endpoint Selection Order (엔드포인트 선택 순서)</h3>



<p>라우팅 시스템이 여러 엔드포인트 중 어떤 엔드포인트를 현재 요청에 매칭시킬지 결정하는 방식에 대한 내용입니다. </p>



<p>이는 라우트 제한 조건(Route Constraints)의 <strong>라우트 순서</strong>와 밀접하게 관련되어 있습니다.</p>



<p>ASP.NET Core의 Endpoint Selection Order는 주로 다음 원칙에 따라 이루어집니다.</p>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>명시적 순서 (Order Property)</strong></h4>



<p>가장 직접적인 제어 방법은 엔드포인트에 <code>Order</code> 속성을 부여하는 것입니다. 숫자가 낮을수록 우선순위가 높습니다. </p>



<p>이는 <code>MapControllerRoute</code>나 <code>MapRazorPages</code>와 같은 메서드에는 직접 적용하기 어렵고, 주로 <code>MapGet</code> 등의 Minimal API 엔드포인트나 사용자 지정 <code>RouteEndpoint</code>를 만들 때 사용됩니다.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">app.UseEndpoints(endpoints =>
{
    // Order가 -10인 엔드포인트 (가장 높은 우선순위)
    app.MapGet("/priority-test", () => "High priority").WithOrder(-10);

    // Order가 0인 기본 엔드포인트 (기본값)
    endpoints.MapGet("/test", () => "Normal priority");
});</pre>



<p>Note: <br><code>WithMetadata</code>를 통해 <code>RouteEndpointBuilder</code>에 직접 <code>Order</code>를 지정하는 것은 일반적인 사용법은 아니며, 실제로는 내부적으로 복잡한 로직을 통해 우선순위가 결정되거나 <code>RouteEndpoint.Order</code> 속성이 설정됩니다. <br>예를 들어, <code>MapRazorPages</code>나 <code>MapControllers</code>에서 생성되는 엔드포인트는 내부적으로 우선순위를 가집니다.)</p>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong><strong>라우트 템플릿의 구체성 (Specificity)</strong>:</strong></h4>



<p>이것이 가장 일반적이고 중요한 순서 결정 기준입니다. </p>



<p>라우팅 시스템은 요청 URL과 가장 &#8220;구체적으로&#8221; 일치하는 라우트 템플릿을 선호합니다. </p>



<p>구체성은 다음과 같은 요소에 의해 결정됩니다:</p>



<p><strong>리터럴 세그먼트의 수</strong>: 더 많은 리터럴(고정된 문자열) 세그먼트를 포함하는 라우트가 더 높은 우선순위를 가집니다.</p>



<ul class="wp-block-list">
<li><code>/products/all</code> (2개의 리터럴)이 <code>/products/{id}</code> (1개의 리터럴, 1개의 매개변수)보다 우선순위가 높습니다.</li>
</ul>



<p><strong>라우트 제한 조건의 사용</strong>: 제한 조건이 있는 매개변수는 제한 조건이 없는 매개변수보다 더 구체적인 것으로 간주됩니다.</p>



<ul class="wp-block-list">
<li><code>/products/{id:int}</code>는 <code>/products/{id}</code>보다 우선순위가 높습니다. (<code>/products/123</code>이 주어지면, <code>id:int</code>가 먼저 매칭됨)</li>
</ul>



<p><strong>선택적 매개변수</strong>: 선택적 매개변수가 없는 라우트가 더 구체적인 것으로 간주됩니다.</p>



<ul class="wp-block-list">
<li><code>/users/{id}</code>가 <code>/users/{id?}</code>보다 우선순위가 높습니다.</li>
</ul>



<p><strong>Catch-all 매개변수 (<code>*</code> 또는 <code>**</code>)</strong>: 가장 덜 구체적인 것으로 간주되어 거의 항상 마지막에 매칭됩니다.</p>



<ul class="wp-block-list">
<li><code>/files/{*path}</code>는 일반적으로 다른 모든 구체적인 라우트 뒤에 위치해야 합니다.</li>
</ul>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong><strong><strong>정의 순서 (Declaration Order)</strong>:</strong></strong></h4>



<p>동일한 구체성을 가진 두 개 이상의 라우트가 있을 경우, <code>UseEndpoints</code> 또는 <code>Map()</code> 계열 메서드에서 <strong>먼저 정의된 라우트가 우선순위를 가집니다.</strong> </p>



<p>이 때문에 &#8220;라우트 순서&#8221; 섹션에서 언급했듯이, 더 구체적인 라우트를 항상 먼저 정의하는 것이 중요합니다.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">app.UseEndpoints(endpoints =>
{
    // 이 라우트가 먼저 정의됨
    endpoints.MapGet("/products/special", () => "Special Product Page");

    // 이 라우트는 구체성이 동일하지만 나중에 정의됨
    endpoints.MapGet("/products/{name}", (string name) => $"Product by Name: {name}");

    // /products/special 요청 시, "Special Product Page"가 반환됨
    // 만약 순서가 바뀌면 "/products/{name}"에 매칭되어 "Product by Name: special"이 반환될 수 있음
});</pre>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<p><strong>Endpoint Selection Order는 복합적인 요소들의 상호작용으로 결정됩니다. </strong></p>



<p><strong>라우트 제한 조건은 이 선택 과정에서 라우트의 &#8220;구체성&#8221;을 높여 특정 URL 패턴에 대한 우선순위를 부여하는 핵심적인 방법입니다.</strong> </p>



<p>개발자는 이러한 원칙을 이해하고 라우트를 신중하게 정의하여 예상치 못한 라우팅 문제를 방지해야 합니다.</p>



<p></p>
<p>The post <a href="https://lycos7560.com/c/asp-net/asp-net-core-route-constraints/40140/">ASP.NET Core Route Constraints</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://lycos7560.com/c/asp-net/asp-net-core-route-constraints/40140/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>리버스 프록시(Reverse Proxy) 개념</title>
		<link>https://lycos7560.com/etc/%eb%a6%ac%eb%b2%84%ec%8a%a4-%ed%94%84%eb%a1%9d%ec%8b%9creverse-proxy-%ea%b0%9c%eb%85%90/40122/</link>
					<comments>https://lycos7560.com/etc/%eb%a6%ac%eb%b2%84%ec%8a%a4-%ed%94%84%eb%a1%9d%ec%8b%9creverse-proxy-%ea%b0%9c%eb%85%90/40122/#respond</comments>
		
		<dc:creator><![CDATA[lycos7560]]></dc:creator>
		<pubDate>Sun, 27 Jul 2025 17:54:12 +0000</pubDate>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[기타]]></category>
		<category><![CDATA[A/B Testing]]></category>
		<category><![CDATA[A/B 테스트]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[API Gateway]]></category>
		<category><![CDATA[API 게이트웨이]]></category>
		<category><![CDATA[Application Proxy]]></category>
		<category><![CDATA[Asynchronous Processing]]></category>
		<category><![CDATA[Authentication]]></category>
		<category><![CDATA[Authorization]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[Azure]]></category>
		<category><![CDATA[Backend Server]]></category>
		<category><![CDATA[Caching]]></category>
		<category><![CDATA[CDN]]></category>
		<category><![CDATA[Certificate Management]]></category>
		<category><![CDATA[client]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[Compression]]></category>
		<category><![CDATA[Container]]></category>
		<category><![CDATA[Content Delivery]]></category>
		<category><![CDATA[Content Delivery Network]]></category>
		<category><![CDATA[Cookie Management]]></category>
		<category><![CDATA[DDoS Protection]]></category>
		<category><![CDATA[DDoS 방어]]></category>
		<category><![CDATA[Deployment]]></category>
		<category><![CDATA[Developer]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Distributed Processing]]></category>
		<category><![CDATA[Edge Computing]]></category>
		<category><![CDATA[Envoy]]></category>
		<category><![CDATA[Error Page]]></category>
		<category><![CDATA[firewall]]></category>
		<category><![CDATA[Gateway]]></category>
		<category><![CDATA[Gateway Pattern]]></category>
		<category><![CDATA[GCP]]></category>
		<category><![CDATA[HAProxy]]></category>
		<category><![CDATA[Header Manipulation]]></category>
		<category><![CDATA[High Availability]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[HTTP/2]]></category>
		<category><![CDATA[HTTPS]]></category>
		<category><![CDATA[Inbound Traffic]]></category>
		<category><![CDATA[Infrastructure]]></category>
		<category><![CDATA[Intermediary]]></category>
		<category><![CDATA[Kestrel]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[L7 스위치]]></category>
		<category><![CDATA[Layer 7 Switch]]></category>
		<category><![CDATA[Load Balancing]]></category>
		<category><![CDATA[Log Analysis]]></category>
		<category><![CDATA[Microservices]]></category>
		<category><![CDATA[Monitoring]]></category>
		<category><![CDATA[MSA]]></category>
		<category><![CDATA[Multi-tenancy]]></category>
		<category><![CDATA[network]]></category>
		<category><![CDATA[Nginx]]></category>
		<category><![CDATA[Offloading]]></category>
		<category><![CDATA[On-premise]]></category>
		<category><![CDATA[Operations]]></category>
		<category><![CDATA[Outbound Proxy]]></category>
		<category><![CDATA[Performance Optimization]]></category>
		<category><![CDATA[Protocol Conversion]]></category>
		<category><![CDATA[Proxy]]></category>
		<category><![CDATA[QUIC]]></category>
		<category><![CDATA[Request Forwarding]]></category>
		<category><![CDATA[Request Routing]]></category>
		<category><![CDATA[Response]]></category>
		<category><![CDATA[Reverse Proxy]]></category>
		<category><![CDATA[Scalability]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Security Layer]]></category>
		<category><![CDATA[Server Protection]]></category>
		<category><![CDATA[Service Discovery]]></category>
		<category><![CDATA[Service Mesh]]></category>
		<category><![CDATA[Service Proxy]]></category>
		<category><![CDATA[Session Persistence]]></category>
		<category><![CDATA[SSL Termination]]></category>
		<category><![CDATA[SSL 종료]]></category>
		<category><![CDATA[State Management]]></category>
		<category><![CDATA[Sticky Session]]></category>
		<category><![CDATA[System Architecture]]></category>
		<category><![CDATA[TLS Handshake]]></category>
		<category><![CDATA[TLS 핸드셰이크]]></category>
		<category><![CDATA[Traffic Management]]></category>
		<category><![CDATA[Traffic Splitting]]></category>
		<category><![CDATA[URL Rewriting]]></category>
		<category><![CDATA[URL 재작성]]></category>
		<category><![CDATA[User Experience]]></category>
		<category><![CDATA[UX]]></category>
		<category><![CDATA[Virtual Hosting]]></category>
		<category><![CDATA[WAF]]></category>
		<category><![CDATA[Web Acceleration]]></category>
		<category><![CDATA[Web Application]]></category>
		<category><![CDATA[Web Application Firewall]]></category>
		<category><![CDATA[Web Cache]]></category>
		<category><![CDATA[Web Proxy]]></category>
		<category><![CDATA[Web Server]]></category>
		<category><![CDATA[Web Service]]></category>
		<category><![CDATA[가상 호스팅]]></category>
		<category><![CDATA[개발자]]></category>
		<category><![CDATA[게이트웨이]]></category>
		<category><![CDATA[게이트웨이 패턴]]></category>
		<category><![CDATA[고가용성]]></category>
		<category><![CDATA[네트워크]]></category>
		<category><![CDATA[데브옵스]]></category>
		<category><![CDATA[로그 분석]]></category>
		<category><![CDATA[로드 밸런싱]]></category>
		<category><![CDATA[리버스 프록시]]></category>
		<category><![CDATA[마이크로서비스]]></category>
		<category><![CDATA[멀티테넌시]]></category>
		<category><![CDATA[모니터링]]></category>
		<category><![CDATA[방화벽]]></category>
		<category><![CDATA[배포]]></category>
		<category><![CDATA[백엔드 서버]]></category>
		<category><![CDATA[보안]]></category>
		<category><![CDATA[보안 계층]]></category>
		<category><![CDATA[부하 분산]]></category>
		<category><![CDATA[부하 분산 장치]]></category>
		<category><![CDATA[분산 처리]]></category>
		<category><![CDATA[비동기 처리]]></category>
		<category><![CDATA[사용자 경험]]></category>
		<category><![CDATA[상태 관리]]></category>
		<category><![CDATA[서버 보호]]></category>
		<category><![CDATA[서비스 디스커버리]]></category>
		<category><![CDATA[서비스 메쉬]]></category>
		<category><![CDATA[서비스 프록시]]></category>
		<category><![CDATA[성능 최적화]]></category>
		<category><![CDATA[세션 유지]]></category>
		<category><![CDATA[시스템 아키텍처]]></category>
		<category><![CDATA[아웃바운드 프록시]]></category>
		<category><![CDATA[압축]]></category>
		<category><![CDATA[애플리케이션 프록시]]></category>
		<category><![CDATA[에러 페이지]]></category>
		<category><![CDATA[엣지 컴퓨팅]]></category>
		<category><![CDATA[오프로딩]]></category>
		<category><![CDATA[온프레미스]]></category>
		<category><![CDATA[요청 라우팅]]></category>
		<category><![CDATA[요청 전달]]></category>
		<category><![CDATA[운영]]></category>
		<category><![CDATA[웹 가속]]></category>
		<category><![CDATA[웹 방화벽]]></category>
		<category><![CDATA[웹 서버]]></category>
		<category><![CDATA[웹 서비스]]></category>
		<category><![CDATA[웹 애플리케이션]]></category>
		<category><![CDATA[웹 캐시]]></category>
		<category><![CDATA[웹 프록시]]></category>
		<category><![CDATA[응답]]></category>
		<category><![CDATA[인가]]></category>
		<category><![CDATA[인바운드 트래픽]]></category>
		<category><![CDATA[인증]]></category>
		<category><![CDATA[인증서 관리]]></category>
		<category><![CDATA[인프라]]></category>
		<category><![CDATA[중간자]]></category>
		<category><![CDATA[캐싱]]></category>
		<category><![CDATA[컨테이너]]></category>
		<category><![CDATA[콘텐츠 전송]]></category>
		<category><![CDATA[쿠버네티스]]></category>
		<category><![CDATA[쿠키 관리]]></category>
		<category><![CDATA[클라우드]]></category>
		<category><![CDATA[클라이언트]]></category>
		<category><![CDATA[트래픽 관리]]></category>
		<category><![CDATA[트래픽 분할]]></category>
		<category><![CDATA[프로토콜 변환]]></category>
		<category><![CDATA[프록시]]></category>
		<category><![CDATA[헤더 조작]]></category>
		<category><![CDATA[확장성]]></category>
		<guid isPermaLink="false">https://lycos7560.com/?p=40122</guid>

					<description><![CDATA[<p>❓ 리버스 프록시(Reverse Proxy) 리버스 프록시(Reverse Proxy) 서버는 인터넷으로부터의 클라이언트 요청을 받아 백엔드 서버(실제 콘텐츠나 애플리케이션을 호스팅하는 서버)로 전달하고, 백엔드 서버로부터 받은 응답을 다시 클라이언트에게 전달하는 서버입니다. 정리하자면 웹 서비스의 최전선에 위치하여 클라이언트와 실제 서버 사이의 중개자 역할 일반적인 포워드 프록시(Forward Proxy)가 클라이언트가 인터넷에 접속하기 위해 사용하는 것(예: 회사 네트워크에서 외부 웹사이트 접속)과는 반대로, 리버스 [&#8230;]</p>
<p>The post <a href="https://lycos7560.com/etc/%eb%a6%ac%eb%b2%84%ec%8a%a4-%ed%94%84%eb%a1%9d%ec%8b%9creverse-proxy-%ea%b0%9c%eb%85%90/40122/">리버스 프록시(Reverse Proxy) 개념</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></description>
										<content:encoded><![CDATA[				<div class="wp-block-uagb-table-of-contents uagb-toc__align-left uagb-toc__columns-1  uagb-block-32d5faea      "
					data-scroll= "1"
					data-offset= "30"
					style=""
				>
				<div class="uagb-toc__wrap">
						<div class="uagb-toc__title">
							목차						</div>
																						<div class="uagb-toc__list-wrap ">
						<ol class="uagb-toc__list"><li class="uagb-toc__list"><a href="#리버스-프록시reverse-proxy" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2753.png" alt="❓" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 리버스 프록시(Reverse Proxy)</a><li class="uagb-toc__list"><a href="#리버스-프록시는-왜-사용하는가" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f300.png" alt="🌀" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 리버스 프록시는 왜 사용하는가?</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#1-보안-강화-security" class="uagb-toc-link__trigger">1&#x20e3; 보안 강화 (Security)</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#2-로드-밸런싱-load-balancing" class="uagb-toc-link__trigger">2&#x20e3; 로드 밸런싱 (Load Balancing)</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#3-성능-최적화-performance-optimization" class="uagb-toc-link__trigger">3&#x20e3; 성능 최적화 (Performance Optimization)</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#4-쉬운-유지보수-및-확장-maintainability-scalability" class="uagb-toc-link__trigger">4&#x20e3; 쉬운 유지보수 및 확장 (Maintainability &amp; Scalability)</a></li></ul></li><li class="uagb-toc__list"><a href="#동작-방식-요약" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4d9.png" alt="📙" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 동작 방식 요약</a><li class="uagb-toc__list"><a href="#대표적인-리버스-프록시-소프트웨어" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f60a.png" alt="😊" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 대표적인 리버스 프록시 소프트웨어</a></ul></ol>					</div>
									</div>
				</div>
			


<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2753.png" alt="❓" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 리버스 프록시(Reverse Proxy)</h2>



<p><strong>리버스 프록시(Reverse Proxy)</strong> 서버는 인터넷으로부터의 클라이언트 요청을 받아 백엔드 서버(실제 콘텐츠나 애플리케이션을 호스팅하는 서버)로 전달하고, </p>



<p>백엔드 서버로부터 받은 응답을 다시 클라이언트에게 전달하는 서버입니다. </p>



<p>정리하자면 <strong>웹 서비스의 최전선에 위치하여 클라이언트와 실제 서버 사이의 중개자 역할</strong></p>



<p>일반적인 <strong>포워드 프록시(Forward Proxy)가 클라이언트가 인터넷에 접속하기 위해 사용하는 것(예: 회사 네트워크에서 외부 웹사이트 접속)</strong>과는 반대로, </p>



<p><strong>리버스 프록시(Reverse Proxy)는 서버 앞단에서 서버로 들어오는 요청을 처리</strong>합니다.</p>



<div class="wp-block-uagb-container uagb-block-fbf8b3c1 alignfull uagb-is-root-container"><div class="uagb-container-inner-blocks-wrap">
<div class="wp-block-uagb-container uagb-block-3a8748f6">
<figure class="wp-block-image size-full"><img decoding="async" width="1920" height="720" src="https://lycos7560.com/wp-content/uploads/2025/07/Reverse_proxy_h2g2bob.svg_.png" alt="" class="wp-image-40123" srcset="https://lycos7560.com/wp-content/uploads/2025/07/Reverse_proxy_h2g2bob.svg_.png 1920w, https://lycos7560.com/wp-content/uploads/2025/07/Reverse_proxy_h2g2bob.svg_-300x113.png 300w, https://lycos7560.com/wp-content/uploads/2025/07/Reverse_proxy_h2g2bob.svg_-768x288.png 768w, https://lycos7560.com/wp-content/uploads/2025/07/Reverse_proxy_h2g2bob.svg_-1536x576.png 1536w" sizes="(max-width: 1920px) 100vw, 1920px" /><figcaption class="wp-element-caption">Reverse Proxy<br><a href="https://ko.wikipedia.org/wiki/%EB%A6%AC%EB%B2%84%EC%8A%A4_%ED%94%84%EB%A1%9D%EC%8B%9C#/media/%ED%8C%8C%EC%9D%BC:Reverse_proxy_h2g2bob.svg" target="_blank" rel="noreferrer noopener">https://ko.wikipedia.org/wiki/%EB%A6%AC%EB%B2%84%EC%8A%A4_%ED%94%84%EB%A1%9D%EC%8B%9C#/media/%ED%8C%8C%EC%9D%BC:Reverse_proxy_h2g2bob.svg</a></figcaption></figure>
</div>



<div class="wp-block-uagb-container uagb-block-68dc1c5c">
<figure class="wp-block-image size-full"><img decoding="async" width="1920" height="960" src="https://lycos7560.com/wp-content/uploads/2025/07/forward_proxy_flow.png" alt="" class="wp-image-40124" srcset="https://lycos7560.com/wp-content/uploads/2025/07/forward_proxy_flow.png 1920w, https://lycos7560.com/wp-content/uploads/2025/07/forward_proxy_flow-300x150.png 300w, https://lycos7560.com/wp-content/uploads/2025/07/forward_proxy_flow-768x384.png 768w, https://lycos7560.com/wp-content/uploads/2025/07/forward_proxy_flow-1536x768.png 1536w" sizes="(max-width: 1920px) 100vw, 1920px" /><figcaption class="wp-element-caption"><strong>Forward Proxy</strong><br><a href="https://www.cloudflare.com/ko-kr/learning/cdn/glossary/reverse-proxy/" target="_blank" rel="noreferrer noopener">https://www.cloudflare.com/ko-kr/learning/cdn/glossary/reverse-proxy/</a></figcaption></figure>
</div>
</div></div>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f300.png" alt="🌀" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 리버스 프록시는 왜 사용하는가?</h2>



<p>리버스 프록시는 아래과 같은 주요 이점 때문에 웹 아키텍처에서 필수적인 요소로 자리를 잡았습니다.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">1&#x20e3; 보안 강화 (Security)</h3>



<ul class="wp-block-list">
<li><strong>직접적인 서버 노출 방지:</strong> <br>실제 백엔드 서버의 IP 주소나 내부 구조를 외부 클라이언트에게 숨겨 보안 위험을 줄입니다. 공격자는 리버스 프록시만 볼 수 있습니다.</li>



<li><strong>공격 방어:</strong> <br>DDoS 공격, SQL Injection, XSS 공격 등 다양한 웹 공격에 대한 1차 방어선 역할을 수행합니다. 수상한 트래픽을 필터링하거나 차단할 수 있습니다.</li>



<li><strong>SSL/TLS 암호화 종료 (SSL/TLS Termination):</strong> <br>클라이언트와의 암호화된 통신(HTTPS)을 리버스 프록시가 대신 처리하고, 백엔드 서버와의 통신은 암호화되지 않은 HTTP로 전환할 수 있습니다.<br>이는 백엔드 서버의 부하를 줄여주고, SSL 인증서 관리의 중앙화를 가능하게 합니다.</li>
</ul>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">2&#x20e3; 로드 밸런싱 (Load Balancing)</h3>



<ul class="wp-block-list">
<li>리버스 프록시는 여러 개의 백엔드 서버로 트래픽을 효율적으로 분산하여 <strong>특정 서버에 부하가 집중되는 것을 방지</strong>합니다. <br>이를 통해 서비스의 <strong>안정성과 가용성을 높이고, 대규모 트래픽을 처리할 수 있도록 확장성을 제공</strong>합니다.</li>



<li>서버 중 하나에 문제가 발생하면, 해당 서버로의 트래픽을 중단하고 정상 작동하는 다른 서버로 요청을 보낼 수 있습니다.</li>
</ul>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">3&#x20e3; 성능 최적화 (Performance Optimization)</h3>



<ul class="wp-block-list">
<li><strong>캐싱 (Caching):</strong> <br>자주 요청되는 정적 콘텐츠(이미지, CSS, JavaScript 파일 등)를 리버스 프록시 서버에 캐싱하여, <br>백엔드 서버로의 요청을 줄이고 클라이언트에게 더 빠르게 응답할 수 있습니다.</li>



<li><strong>압축 (Compression):</strong> <br>클라이언트에게 보내는 응답 데이터를 압축하여 전송량을 줄이고 로딩 속도를 향상시킵니다.</li>
</ul>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">4&#x20e3; 쉬운 유지보수 및 확장 (Maintainability &amp; Scalability)</h3>



<ul class="wp-block-list">
<li>백엔드 서버를 추가하거나 제거할 때, 클라이언트는 리버스 프록시의 주소만 알기 때문에 변경 사항을 알 필요가 없습니다. <br>이는 서버 아키텍처를 유연하게 관리할 수 있도록 해줍니다.</li>



<li>A/B 테스트, URL 재작성, 특정 요청 라우팅 등 복잡한 트래픽 관리 정책을 구현하기 용이합니다.</li>
</ul>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4d9.png" alt="📙" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 동작 방식 요약</h2>



<ol class="wp-block-list">
<li><strong>클라이언트 요청:</strong> <br>웹 브라우저와 같은 클라이언트가 특정 웹 서비스(예: <code>www.example.com</code>)에 요청을 보냅니다.</li>



<li><strong>리버스 프록시 수신:</strong> <br>이 요청은 DNS 설정을 통해 <strong>리버스 프록시 서버</strong>로 전달됩니다.</li>



<li><strong>요청 처리 및 전달:</strong> <br>리버스 프록시 서버는 요청을 검사하고, 설정된 규칙(로드 밸런싱 알고리즘, URL 경로 등)에 따라 적절한 <strong>백엔드 서버</strong>를 선택하여 요청을 전달합니다. <br>(이때, SSL/TLS 종료가 이루어질 수 있습니다.)</li>



<li><strong>응답 수신 및 전달:</strong> <br>백엔드 서버는 요청을 처리하고 응답을 리버스 프록시 서버로 보냅니다. <br>리버스 프록시는 이 응답을 받아 (캐싱, 압축 등의 처리를 거쳐) 최종적으로 클라이언트에게 전달합니다.</li>
</ol>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f60a.png" alt="😊" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 대표적인 리버스 프록시 소프트웨어</h2>



<ul class="wp-block-list">
<li><strong>Nginx (엔진엑스):</strong> <br>가장 널리 사용되는 웹 서버이자 리버스 프록시 서버입니다. 고성능과 경량성이 특징입니다.</li>



<li><strong>Apache HTTP Server (아파치):</strong> <br><code>mod_proxy</code> 모듈을 통해 리버스 프록시 기능을 제공합니다.</li>



<li><strong>HAProxy:</strong> <br>고가용성 로드 밸런싱 및 프록싱에 특화된 솔루션입니다.</li>



<li><strong>Envoy Proxy:</strong> <br>마이크로서비스 아키텍처에서 많이 사용되는 최신 프록시입니다.</li>
</ul>



<p></p>
<p>The post <a href="https://lycos7560.com/etc/%eb%a6%ac%eb%b2%84%ec%8a%a4-%ed%94%84%eb%a1%9d%ec%8b%9creverse-proxy-%ea%b0%9c%eb%85%90/40122/">리버스 프록시(Reverse Proxy) 개념</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://lycos7560.com/etc/%eb%a6%ac%eb%b2%84%ec%8a%a4-%ed%94%84%eb%a1%9d%ec%8b%9creverse-proxy-%ea%b0%9c%eb%85%90/40122/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>ASP.NET Core의 미들웨어(Middleware)</title>
		<link>https://lycos7560.com/c/asp-net-core%ec%9d%98-%eb%af%b8%eb%93%a4%ec%9b%a8%ec%96%b4middleware/40130/</link>
					<comments>https://lycos7560.com/c/asp-net-core%ec%9d%98-%eb%af%b8%eb%93%a4%ec%9b%a8%ec%96%b4middleware/40130/#respond</comments>
		
		<dc:creator><![CDATA[lycos7560]]></dc:creator>
		<pubDate>Thu, 24 Jul 2025 23:32:09 +0000</pubDate>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[action]]></category>
		<category><![CDATA[API Gateway]]></category>
		<category><![CDATA[API 게이트웨이]]></category>
		<category><![CDATA[ASP.NET Core]]></category>
		<category><![CDATA[ASP.NET Core MVC]]></category>
		<category><![CDATA[async]]></category>
		<category><![CDATA[Asynchronous]]></category>
		<category><![CDATA[Authentication]]></category>
		<category><![CDATA[Authorization]]></category>
		<category><![CDATA[Await]]></category>
		<category><![CDATA[Caching]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[Compression]]></category>
		<category><![CDATA[Conditional Middleware]]></category>
		<category><![CDATA[Configuration]]></category>
		<category><![CDATA[Configure]]></category>
		<category><![CDATA[Container]]></category>
		<category><![CDATA[Controller]]></category>
		<category><![CDATA[Conventional Middleware]]></category>
		<category><![CDATA[CORS]]></category>
		<category><![CDATA[Cross-Origin Resource Sharing]]></category>
		<category><![CDATA[Custom Middleware]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[DELETE]]></category>
		<category><![CDATA[Dependency Injection]]></category>
		<category><![CDATA[Deployment]]></category>
		<category><![CDATA[Developer]]></category>
		<category><![CDATA[Development Environment]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[DI]]></category>
		<category><![CDATA[Error Handling]]></category>
		<category><![CDATA[event]]></category>
		<category><![CDATA[Event-driven]]></category>
		<category><![CDATA[Exception Handling]]></category>
		<category><![CDATA[Extension Method]]></category>
		<category><![CDATA[Factory-based Middleware]]></category>
		<category><![CDATA[filter]]></category>
		<category><![CDATA[GET]]></category>
		<category><![CDATA[HEAD]]></category>
		<category><![CDATA[Headers]]></category>
		<category><![CDATA[HTTP Context]]></category>
		<category><![CDATA[HTTP Method]]></category>
		<category><![CDATA[HTTP Request]]></category>
		<category><![CDATA[HTTP Response]]></category>
		<category><![CDATA[HTTP 메서드]]></category>
		<category><![CDATA[HTTP 요청]]></category>
		<category><![CDATA[HTTP 응답]]></category>
		<category><![CDATA[HTTP 컨텍스트]]></category>
		<category><![CDATA[HTTP/1.1]]></category>
		<category><![CDATA[HTTP/2]]></category>
		<category><![CDATA[HttpContext]]></category>
		<category><![CDATA[HTTPS Redirection]]></category>
		<category><![CDATA[HTTPS 리디렉션]]></category>
		<category><![CDATA[IApplicationBuilder]]></category>
		<category><![CDATA[IMiddleware]]></category>
		<category><![CDATA[Integration Testing]]></category>
		<category><![CDATA[Invoke]]></category>
		<category><![CDATA[Kestrel]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[Logging]]></category>
		<category><![CDATA[Logging Provider]]></category>
		<category><![CDATA[Maintainability]]></category>
		<category><![CDATA[Microservices]]></category>
		<category><![CDATA[Middleware]]></category>
		<category><![CDATA[Middleware Chain]]></category>
		<category><![CDATA[Minimal APIs]]></category>
		<category><![CDATA[Modularization]]></category>
		<category><![CDATA[next]]></category>
		<category><![CDATA[Non-Terminal Middleware]]></category>
		<category><![CDATA[Ops]]></category>
		<category><![CDATA[options]]></category>
		<category><![CDATA[Order Critical]]></category>
		<category><![CDATA[PATCH]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[pipeline]]></category>
		<category><![CDATA[POST]]></category>
		<category><![CDATA[Production Environment]]></category>
		<category><![CDATA[Program.cs]]></category>
		<category><![CDATA[Protocol]]></category>
		<category><![CDATA[PUT]]></category>
		<category><![CDATA[Request Body]]></category>
		<category><![CDATA[Request Flow]]></category>
		<category><![CDATA[Request Pipeline]]></category>
		<category><![CDATA[RequestDelegate]]></category>
		<category><![CDATA[Response Body]]></category>
		<category><![CDATA[Response Flow]]></category>
		<category><![CDATA[Reusability]]></category>
		<category><![CDATA[Reverse Proxy]]></category>
		<category><![CDATA[Routing]]></category>
		<category><![CDATA[Run]]></category>
		<category><![CDATA[Scalability]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Separation of Concerns]]></category>
		<category><![CDATA[Service Container]]></category>
		<category><![CDATA[Short-circuit]]></category>
		<category><![CDATA[Single Responsibility Principle]]></category>
		<category><![CDATA[SoC]]></category>
		<category><![CDATA[SSL]]></category>
		<category><![CDATA[Startup]]></category>
		<category><![CDATA[Static Files]]></category>
		<category><![CDATA[Status Code]]></category>
		<category><![CDATA[study]]></category>
		<category><![CDATA[Terminal Middleware]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[TLS]]></category>
		<category><![CDATA[Unit Testing]]></category>
		<category><![CDATA[Use]]></category>
		<category><![CDATA[UseWhen]]></category>
		<category><![CDATA[Web Application]]></category>
		<category><![CDATA[Web Application Framework]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Web Server]]></category>
		<category><![CDATA[Web Service]]></category>
		<category><![CDATA[WebApplication]]></category>
		<category><![CDATA[WebApplicationBuilder]]></category>
		<category><![CDATA[개발 환경]]></category>
		<category><![CDATA[개발자]]></category>
		<category><![CDATA[공부]]></category>
		<category><![CDATA[관심사의 분리]]></category>
		<category><![CDATA[기초]]></category>
		<category><![CDATA[단락]]></category>
		<category><![CDATA[단위 테스트]]></category>
		<category><![CDATA[단일 책임 원칙]]></category>
		<category><![CDATA[디버깅]]></category>
		<category><![CDATA[라우팅]]></category>
		<category><![CDATA[로깅]]></category>
		<category><![CDATA[로깅 프로바이더]]></category>
		<category><![CDATA[리버스 프록시]]></category>
		<category><![CDATA[마이크로서비스]]></category>
		<category><![CDATA[모듈화]]></category>
		<category><![CDATA[미들웨어]]></category>
		<category><![CDATA[미들웨어 체인]]></category>
		<category><![CDATA[배포]]></category>
		<category><![CDATA[보안]]></category>
		<category><![CDATA[비동기]]></category>
		<category><![CDATA[비종료 미들웨어]]></category>
		<category><![CDATA[상태 코드]]></category>
		<category><![CDATA[서비스 메쉬]]></category>
		<category><![CDATA[서비스 컨테이너]]></category>
		<category><![CDATA[설정]]></category>
		<category><![CDATA[성능]]></category>
		<category><![CDATA[순서 중요]]></category>
		<category><![CDATA[압축]]></category>
		<category><![CDATA[액션]]></category>
		<category><![CDATA[예외 처리]]></category>
		<category><![CDATA[오류 처리]]></category>
		<category><![CDATA[요청 본문]]></category>
		<category><![CDATA[요청 파이프라인]]></category>
		<category><![CDATA[요청 흐름]]></category>
		<category><![CDATA[웹 개발]]></category>
		<category><![CDATA[웹 서버]]></category>
		<category><![CDATA[웹 서비스]]></category>
		<category><![CDATA[웹 애플리케이션]]></category>
		<category><![CDATA[웹 애플리케이션 프레임워크]]></category>
		<category><![CDATA[유지보수성]]></category>
		<category><![CDATA[응답 본문]]></category>
		<category><![CDATA[응답 흐름]]></category>
		<category><![CDATA[의존성 주입]]></category>
		<category><![CDATA[이벤트]]></category>
		<category><![CDATA[이벤트 드리븐]]></category>
		<category><![CDATA[인가]]></category>
		<category><![CDATA[인증]]></category>
		<category><![CDATA[재사용성]]></category>
		<category><![CDATA[정적 파일]]></category>
		<category><![CDATA[조건부 미들웨어]]></category>
		<category><![CDATA[종료 미들웨어]]></category>
		<category><![CDATA[최소 API]]></category>
		<category><![CDATA[캐싱]]></category>
		<category><![CDATA[커스텀 미들웨어]]></category>
		<category><![CDATA[컨벤셔널 미들웨어]]></category>
		<category><![CDATA[컨테이너]]></category>
		<category><![CDATA[컨트롤러]]></category>
		<category><![CDATA[쿠버네티스]]></category>
		<category><![CDATA[클라우드]]></category>
		<category><![CDATA[테스트]]></category>
		<category><![CDATA[통합 테스트]]></category>
		<category><![CDATA[파이프라인]]></category>
		<category><![CDATA[팩토리 기반 미들웨어]]></category>
		<category><![CDATA[프로덕션 환경]]></category>
		<category><![CDATA[프로토콜]]></category>
		<category><![CDATA[필터]]></category>
		<category><![CDATA[헤더]]></category>
		<category><![CDATA[확장 메서드]]></category>
		<category><![CDATA[확장성]]></category>
		<guid isPermaLink="false">https://lycos7560.com/?p=40130</guid>

					<description><![CDATA[<p>❓ 미들웨어(Middleware) https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-8.0 ASP.NET Core의 미들웨어는 모든 HTTP 요청과 응답 파이프라인을 형성하는 일련의 구성 요소입니다. 각 미들웨어 구성 요소는 다음을 수행할 수 있습니다: 이러한 파이프라인을 통해 애플리케이션의 로직을 모듈화하고, 인증, 로깅, 오류 처리, 라우팅 등과 같은 기능을 깔끔하고 유지 관리하기 쉬운 방식으로 추가할 수 있습니다. ⛓️ 미들웨어 체인 (요청 파이프라인) ASP.NET Core 요청 파이프라인은 차례로 [&#8230;]</p>
<p>The post <a href="https://lycos7560.com/c/asp-net-core%ec%9d%98-%eb%af%b8%eb%93%a4%ec%9b%a8%ec%96%b4middleware/40130/">ASP.NET Core의 미들웨어(Middleware)</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></description>
										<content:encoded><![CDATA[				<div class="wp-block-uagb-table-of-contents uagb-toc__align-left uagb-toc__columns-1  uagb-block-db9d164c      "
					data-scroll= "1"
					data-offset= "30"
					style=""
				>
				<div class="uagb-toc__wrap">
						<div class="uagb-toc__title">
							목차						</div>
																						<div class="uagb-toc__list-wrap ">
						<ol class="uagb-toc__list"><li class="uagb-toc__list"><a href="#미들웨어middleware" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2753.png" alt="❓" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 미들웨어(Middleware)</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#미들웨어-체인-요청-파이프라인" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26d3.png" alt="⛓" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 미들웨어 체인 (요청 파이프라인)</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#요청-파이프라인-단락short-circuiting" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2702.png" alt="✂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 요청 파이프라인 단락(Short-circuiting)</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#단락과-nextinvoke-이후-코드-실행" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 단락과 next.Invoke() 이후 코드 실행</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#경고-응답-전송-후-작업-주의" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 경고: 응답 전송 후 작업 주의</a></li></ul><li class="uagb-toc__list"><a href="#appuse-vs-apprun" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1fae0.png" alt="🫠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> app.Use vs. app.Run</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#aspnet-core의-커스텀-미들웨어" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2753.png" alt="❓" class="wp-smiley" style="height: 1em; max-height: 1em;" /> ASP.NET Core의 커스텀 미들웨어</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#커스텀-미들웨어-클래스의-구조" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f527.png" alt="🔧" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 커스텀 미들웨어 클래스의 구조</a></li></ul><li class="uagb-toc__list"><a href="#커스텀-컨벤셔널-미들웨어-custom-conventional-middleware" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f525.png" alt="🔥" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 커스텀 컨벤셔널 미들웨어 (Custom Conventional Middleware)</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#미들웨어-파이프라인의-이상적인-순서" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f500.png" alt="🔀" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 미들웨어 파이프라인의 이상적인 순서</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#usewhen" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> UseWhen()</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#usewhen-작동-방식" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2728.png" alt="✨" class="wp-smiley" style="height: 1em; max-height: 1em;" /> UseWhen() 작동 방식</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#usewhen-사용-시점" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f98b.png" alt="🦋" class="wp-smiley" style="height: 1em; max-height: 1em;" /> UseWhen() 사용 시점</a></ul></ul></ol>					</div>
									</div>
				</div>
			


<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2753.png" alt="❓" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 미들웨어(Middleware)</h2>



<p><a href="https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-8.0" target="_blank" rel="noreferrer noopener">https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-8.0</a></p>



<p>ASP.NET Core의 <strong>미들웨어</strong>는 모든 HTTP 요청과 응답 <strong>파이프라인을 형성하는 일련의 구성 요소</strong>입니다.</p>



<p>각 미들웨어 구성 요소는 다음을 수행할 수 있습니다:</p>



<ul class="wp-block-list">
<li>들어오는 <strong>요청을 검사</strong>합니다.</li>



<li>요청 또는 응답을 <strong>수정</strong>합니다 (필요한 경우).</li>



<li>파이프라인의 다음 미들웨어를 <strong>호출</strong>하거나, 프로세스를 <strong>단락(short-circuit)</strong>시키고 자체적으로 응답을 생성합니다.</li>
</ul>



<p>이러한 파이프라인을 통해 <strong>애플리케이션의 로직을 모듈화하고, 인증, 로깅, 오류 처리, 라우팅 등과 </strong>같은 기능을 깔끔하고<strong> 유지 관리하기 쉬운 방식으로 추가</strong>할 수 있습니다.</p>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26d3.png" alt="⛓" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 미들웨어 체인 (요청 파이프라인)</h3>



<p>ASP.NET Core 요청 파이프라인은 차례로 호출되는 일련의 요청 대리자로 구성됩니다.</p>



<p>요청 파이프라인을 일련의 연결된 파이프라고 상상해 보세요. </p>



<p>각 미들웨어 조각은 이 파이프라인의 밸브와 같아서, <strong>정보의 흐름을 제어하고 다양한 단계에서 특정 작업을 적용</strong>할 수 있습니다. </p>



<p>미들웨어를 등록하는 <strong>순서는 매우 중요</strong>하며, 등록된 순서대로 실행됩니다.</p>



<figure class="wp-block-image size-full"><img decoding="async" width="607" height="389" src="https://lycos7560.com/wp-content/uploads/2025/07/image-12.png" alt="" class="wp-image-40131" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-12.png 607w, https://lycos7560.com/wp-content/uploads/2025/07/image-12-300x192.png 300w" sizes="(max-width: 607px) 100vw, 607px" /><figcaption class="wp-element-caption"><a href="https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-8.0" target="_blank" rel="noreferrer noopener">https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-8.0</a></figcaption></figure>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<p>각 델리게이트는 <strong>다음 델리게이트를 호출하기 전과 후에 작업</strong>을 수행할 수 있습니다. </p>



<p>예외 처리 델리게이트는 파이프라인의 후반 단계에서 발생하는 예외를 Catch할 수 있도록 파이프라인의 <strong>초기에 호출</strong>되어야 합니다.</p>



<p>가장 간단한 ASP.NET Core 앱은 모든 요청을 처리하는 <strong>단일 요청 델리게이트</strong>를 설정합니다. </p>



<p>이 경우에는 실제 요청 파이프라인이 포함되지 않습니다. </p>



<p>대신, 모든 HTTP 요청에 대한 응답으로 단일 익명 함수가 호출됩니다.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.Run(async context =>
{
    await context.Response.WriteAsync("Hello world!");
});

app.Run(); // 이 app.Run은 위의 app.Run이 파이프라인을 종료하므로 실행되지 않습니다.</pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<p><strong><code>Use</code> 메서드를 사용하면 여러 요청 델리게이트를 체인으로 연결</strong>할 수 있습니다. </p>



<p>이때 <code>next</code> 매개변수는 파이프라인의 다음 델리게이트를 나타냅니다.</p>



<p><code>next</code> 매개변수를 호출하지 않음으로써 <strong>파이프라인을 단락(short-circuit)</strong>시킬 수 있습니다. </p>



<p>다음 예시에서 보여주듯이, 일반적으로 <code>next</code> 델리게이트를 호출하기 전과 후에 모두 작업을 수행할 수 있습니다.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">var builder = WebApplication.CreateBuilder(args); // 웹 애플리케이션 빌더를 생성합니다.
var app = builder.Build(); // 빌더를 사용하여 웹 애플리케이션 인스턴스를 생성합니다.

// 첫 번째 미들웨어: app.Use()를 사용하여 파이프라인에 추가합니다.
app.Use(async (context, next) =>
{
    // 응답에 쓸 수 있는 작업을 수행합니다. (예: 헤더 추가, 응답의 시작 부분 작성)
    // 이 부분의 코드는 다음 미들웨어가 실행되기 전에 실행됩니다.

    await next.Invoke(); // 다음 미들웨어(이 경우 app.Run)를 호출하여 제어를 넘깁니다.

    // 응답에 쓰지 않는 로깅 또는 다른 작업을 수행합니다.
    // 이 부분의 코드는 다음 미들웨어가 실행된 후(응답이 생성된 후) 실행됩니다.
});

// 두 번째 미들웨어: app.Run()을 사용하여 파이프라인에 추가합니다.
// app.Run()은 파이프라인을 종료하는 미들웨어입니다.
app.Run(async context =>
{
    // 이 미들웨어는 "Hello from 2nd delegate."를 응답에 작성하고 파이프라인을 종료합니다.
    await context.Response.WriteAsync("Hello from 2nd delegate.");
});

// 이 app.Run()은 위의 app.Run()이 이미 파이프라인을 종료했기 때문에 실행되지 않습니다.
app.Run();</pre>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2702.png" alt="✂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 요청 파이프라인 단락(Short-circuiting)</h3>



<p>ASP.NET Core의 미들웨어 파이프라인에서, 특정 델리게이트(미들웨어)가 요청을 <strong>다음 델리게이트로 전달하지 않을 때</strong> 이를 <strong>요청 파이프라인을 단락(short-circuiting)시킨다</strong>고 합니다. </p>



<p>파이프라인 단락은 불필요한 작업을 피할 수 있기 때문에 종종 유용합니다.</p>



<p>예를 들어, <strong>정적 파일 미들웨어(Static File Middleware)</strong>는 요청된 파일이 정적 파일(이미지, CSS, JavaScript 등)일 경우 해당 요청을 처리하고</p>



<p> 파이프라인의 나머지 부분을 단락시킴으로써 <strong>종료 미들웨어(terminal middleware)</strong> 역할을 할 수 있습니다. </p>



<p>이렇게 되면 정적 파일을 제공한 후에는 <strong>인증이나 라우팅과 같은 다른 미들웨어들이 실행될 필요가 없으므로 효율성이 높아집니다.</strong></p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 단락과 <code>next.Invoke()</code> 이후 코드 실행</h4>



<p>파이프라인의 추가적인 처리를 종료시키는 미들웨어보다 <strong>앞서 파이프라인에 추가된 미들웨어</strong>는 여전히 <code>next.Invoke()</code> 구문 이후의 코드를 처리합니다. </p>



<p>즉, 비록 파이프라인이 단락되어 최종 응답이 더 이상 아래로 전달되지 않더라도, <code>next.Invoke()</code>를 호출했던 이전 미들웨어들은 응답이 완료된 후 자신의 후처리 로직을 실행할 수 있습니다.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 경고: 응답 전송 후 작업 주의</h4>



<p><strong>응답이 클라이언트에게 이미 전송되었거나 전송되기 시작한 후에는 <code>next.Invoke()</code>를 호출하거나 응답에 쓰려고 시도하지 마세요.</strong> </p>



<p><code>HttpResponse</code>가 시작된 후에는 응답에 변경을 가하려고 하면 <strong>예외가 발생</strong>합니다. </p>



<p>예를 들어, 응답이 시작된 후 헤더나 상태 코드를 설정하려고 하면 예외가 발생합니다.</p>



<p><code>next.Invoke()</code> 호출 후 응답 본문에 쓰는 것은 다음과 같은 문제를 야기할 수 있습니다:</p>



<ul class="wp-block-list">
<li><strong>프로토콜 위반:</strong> 명시된 <code>Content-Length</code>보다 더 많은 내용을 작성하는 것과 같은 프로토콜 위반을 초래할 수 있습니다.</li>



<li><strong>본문 형식 손상:</strong> CSS 파일에 HTML 푸터(footer)를 작성하는 것처럼 본문 형식을 손상시킬 수 있습니다.</li>
</ul>



<p><code>HasStarted</code> 속성은 헤더가 전송되었는지 또는 본문이 작성되었는지 여부를 나타내는 유용한 힌트가 될 수 있습니다.</p>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1fae0.png" alt="🫠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <code>app.Use</code> vs. <code>app.Run</code></h3>



<p>이 두 메서드는 파이프라인에 미들웨어를 추가하는 데 기본적이지만, 핵심적인 차이점이 있습니다:</p>



<p><code><strong>app.Use(async (context, next) => { ... })</strong></code></p>



<ul class="wp-block-list">
<li><strong>요청 수정 불가:</strong> <br>마지막 단계이므로 요청을 다음으로 전달하기 전에 수정할 수 없습니다.</li>



<li><strong>비종료(Non-Terminal) 미들웨어:</strong> <br>이 유형의 미들웨어는 일반적으로 어떤 작업을 수행한 다음, <code>next</code> 델리게이트를 호출하여 파이프라인의 다음 미들웨어로 제어를 전달합니다.</li>



<li><strong>요청/응답 수정 가능:</strong> <br>요청을 다음으로 전달하기 전에 요청이나 응답을 변경할 수 있습니다.</li>



<li><strong>예시:</strong> <br>인증, 로깅, 커스텀 헤더 추가 등.</li>
</ul>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<p><code>a<strong>pp.Run(async (context) => { ... })</strong></code></p>



<ul class="wp-block-list">
<li><strong>종료(Terminal) 미들웨어:</strong> <br>이 미들웨어는 <code>next</code>를 호출하지 않습니다. <br>파이프라인을 종료하고 <strong>자체적으로 응답을 생성</strong>합니다.</li>



<li><strong>최종 응답에 주로 사용:</strong> <br>더 이상 처리가 필요 없는 요청(예: 간단한 메시지 반환)을 처리하는 데 일반적으로 사용됩니다.</li>
</ul>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// 여러 app.Run 호출의 결과

app.Run(async (HttpContext context) => {
    await context.Response.WriteAsync("Hello");
});

app.Run(async (HttpContext context) => {
    await context.Response.WriteAsync("Hello again");
});

app.Run(); // 이 app.Run은 위의 app.Run들이 이미 파이프라인을 종료했기 때문에 절대 실행되지 않습니다.</pre>



<p>이 코드에서는 <strong>오직 첫 번째 <code>app.Run</code> 미들웨어만 실행됩니다.</strong> </p>



<p>&#8220;Hello&#8221;를 응답에 작성하여 파이프라인을 종료하고, 그 뒤의 <code>app.Run</code> (이것은 &#8220;Hello again&#8221;을 작성할 것임)은 실행될 기회를 얻지 못합니다.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// app.Use와 app.Run으로 미들웨어 체인 연결하기

// 미들웨어 1
app.Use(async (context, next) => {
    await context.Response.WriteAsync("Hello "); // 1. "Hello " 작성
    await next(context); // 2. 다음 미들웨어 호출
});

// 미들웨어 2
app.Use(async (context, next) => {
    await context.Response.WriteAsync("Hello again "); // 3. "Hello again " 작성
    await next(context); // 4. 다음 미들웨어 호출 (이 경우 app.Run)
});

// 미들웨어 3 (종료 미들웨어)
app.Run(async (HttpContext context) => {
    await context.Response.WriteAsync("Hello again"); // 5. "Hello again" 작성 후 파이프라인 종료
});</pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<p>이 코드는 미들웨어를 올바르게 연결하는 방법을 보여줍니다.</p>



<ol start="1" class="wp-block-list">
<li>첫 번째 <code>app.Use</code>는 응답에 &#8220;Hello &#8220;를 작성하고 <code>next</code>를 호출하여 다음 미들웨어로 제어를 전달합니다.</li>



<li>두 번째 <code>app.Use</code>는 &#8220;Hello again &#8220;을 작성하고 역시 <code>next</code>를 호출합니다.</li>



<li>마지막 <code>app.Run</code> (종료 미들웨어)는 &#8220;Hello again&#8221;을 작성하고 파이프라인을 종료합니다.</li>
</ol>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2753.png" alt="❓" class="wp-smiley" style="height: 1em; max-height: 1em;" /> ASP.NET Core의 커스텀 미들웨어</h3>



<p>ASP.NET Core는 다양한 내장 미들웨어 구성 요소를 제공하지만, 때로는 애플리케이션 고유의 특정 요구 사항을 해결하기 위해 자신만의 <strong>커스텀 미들웨어</strong>를 만들어야 할 수도 있습니다. </p>



<p>커스텀 미들웨어를 통해 다음을 수행할 수 있습니다:</p>



<ul class="wp-block-list">
<li><strong>로직 캡슐화:</strong> <br>관련 작업(예: 로깅, 보안 검사, 사용자 정의 헤더)을 재사용 가능한 구성 요소로 묶습니다.</li>



<li><strong>동작 사용자 정의:</strong> <br>애플리케이션의 요구 사항에 정확히 맞게 요청/응답 파이프라인을 조정합니다.</li>



<li><strong>코드 구성 개선:</strong> <br>미들웨어 코드를 깔끔하고 유지 관리하기 쉽게 만듭니다.</li>
</ul>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f527.png" alt="🔧" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 커스텀 미들웨어 클래스의 구조</h4>



<p><strong><code>IMiddleware</code> 구현:</strong> 이 인터페이스는 단 하나의 메서드 <code>InvokeAsync(HttpContext context, RequestDelegate next)</code>를 요구합니다. </p>



<p>이 메서드는 미들웨어 로직의 핵심입니다</p>



<p><code>InvokeAsync</code> 또는 <code>Invoke</code> 메서드</p>



<ul class="wp-block-list">
<li><strong><code>context</code>:</strong> <br><code>HttpContext</code>는 요청 및 응답 객체에 대한 접근을 제공합니다.</li>



<li><strong><code>next</code>:</strong> <br><code>RequestDelegate</code>는 파이프라인의 다음 미들웨어를 호출할 수 있도록 합니다.</li>
</ul>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// MyCustomMiddleware.cs
namespace MiddlewareExample.CustomMiddleware
{
    public class MyCustomMiddleware : IMiddleware // IMiddleware 인터페이스 구현
    {
        public async Task InvokeAsync(HttpContext context, RequestDelegate next)
        {
            await context.Response.WriteAsync("My Custom Middleware - Starts\n"); // 1. 응답 시작 부분에 출력
            await next(context); // 2. 다음 미들웨어 호출
            await context.Response.WriteAsync("My Custom Middleware - Ends\n"); // 3. 다음 미들웨어 완료 후 응답 끝 부분에 출력
        }
    }

    // 쉽게 등록하기 위한 확장 메서드
    public static class CustomMiddlewareExtension
    {
        public static IApplicationBuilder UseMyCustomMiddleware(this IApplicationBuilder app)
        {
            return app.UseMiddleware&lt;MyCustomMiddleware>();
        }
    }
}</pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// Program.cs (또는 Startup.cs)
using MiddlewareExample.CustomMiddleware;

// ... (다른 설정 코드) ...

builder.Services.AddTransient&lt;MyCustomMiddleware>(); // 트랜지언트 서비스로 등록

app.Use(async (HttpContext context, RequestDelegate next) => {
    await context.Response.WriteAsync("From Middleware 1\n"); // 첫 번째 미들웨어: 시작 부분
    await next(context);
});

app.UseMyCustomMiddleware(); // 확장 메서드를 사용하여 커스텀 미들웨어 추가

app.Run(async (HttpContext context) => {
    await context.Response.WriteAsync("From Middleware 3\n"); // 세 번째 미들웨어: 파이프라인 종료
});</pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<ul class="wp-block-list">
<li><strong>등록:</strong> <br>ASP.NET Core가 필요할 때 <code>MyCustomMiddleware</code> 인스턴스를 생성할 수 있도록 이를 트랜지언트 서비스로 등록합니다.</li>



<li><strong>파이프라인 통합:</strong> <br><code>app.UseMyCustomMiddleware()</code> 확장 메서드는 커스텀 미들웨어를 파이프라인에 추가합니다.</li>



<li><strong>실행 순서:</strong> <br>미들웨어 구성 요소는 파이프라인에 추가된 순서대로 실행됩니다. 이 경우 순서는 미들웨어 1, <code>MyCustomMiddleware</code>, 그리고 미들웨어 3이 됩니다.</li>
</ul>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f525.png" alt="🔥" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 커스텀 컨벤셔널 미들웨어 (Custom Conventional Middleware)</h3>



<p>ASP.NET Core 미들웨어에는 두 가지 유형이 있습니다: <strong>컨벤셔널(Conventional)</strong>과 <strong>팩토리 기반(Factory-based)</strong> </p>



<p>예시에서 보여진 컨벤셔널 미들웨어는 HTTP 요청 및 응답 처리를 위한 커스텀 로직을 캡슐화하는 간단하면서도 강력한 방법입니다.</p>



<p>주요 특징</p>



<ul class="wp-block-list">
<li><strong>클래스 기반:</strong> <br>컨벤셔널 미들웨어는 클래스로 구현됩니다.</li>



<li><strong>생성자 주입:</strong> <br>의존성(있는 경우)을 생성자를 통해 받습니다.</li>



<li><strong><code>Invoke</code> 메서드:</strong> <br>이 메서드는 각 요청을 처리하는 로직을 포함하는 미들웨어의 핵심입니다.</li>



<li><strong><code>RequestDelegate</code>:</strong> <br><code>Invoke</code> 메서드는 <code>RequestDelegate</code> 매개변수(<code>_next</code>로 명명)를 받습니다. 이 델리게이트는 파이프라인의 다음 미들웨어를 나타냅니다.</li>



<li><strong>유연성:</strong> <br><code>Invoke</code> 메서드 내에서 요청 및 응답 객체를 완벽하게 제어할 수 있습니다.</li>
</ul>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-image size-full"><img decoding="async" width="689" height="343" src="https://lycos7560.com/wp-content/uploads/2025/07/image-13.png" alt="" class="wp-image-40132" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-13.png 689w, https://lycos7560.com/wp-content/uploads/2025/07/image-13-300x149.png 300w" sizes="(max-width: 689px) 100vw, 689px" /></figure>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// NameConcatenationMiddleware.cs
public class NameConcatenationMiddleware
{
    private readonly RequestDelegate _next;

    public NameConcatenationMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        if (context.Request.Query.ContainsKey("firstname") &amp;&amp;
            context.Request.Query.ContainsKey("lastname"))
        {
            string fullName = $"{context.Request.Query["firstname"]} {context.Request.Query["lastname"]}";
            await context.Response.WriteAsync(fullName);
            return; // 명시적으로 반환하여 다음 미들웨어 호출 방지
        }
        
        await _next(context);
    }
}

// MiddlewareExtensions.cs
public static class MiddlewareExtensions
{
    public static IApplicationBuilder UseNameConcatenation(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware&lt;NameConcatenationMiddleware>();
    }
}</pre>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f500.png" alt="🔀" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 미들웨어 파이프라인의 이상적인 순서</h3>



<p>미들웨어의 순서는 애플리케이션의 동작과 효율성, 보안에 큰 영향을 미칩니다. </p>



<p>다음은 일반적으로 권장되는 이상적인 순서입니다</p>



<figure class="wp-block-image size-full"><img decoding="async" width="858" height="485" src="https://lycos7560.com/wp-content/uploads/2025/07/image-14.png" alt="" class="wp-image-40133" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-14.png 858w, https://lycos7560.com/wp-content/uploads/2025/07/image-14-300x170.png 300w, https://lycos7560.com/wp-content/uploads/2025/07/image-14-768x434.png 768w" sizes="(max-width: 858px) 100vw, 858px" /><figcaption class="wp-element-caption"><a href="https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-8.0" target="_blank" rel="noreferrer noopener">https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-8.0</a></figcaption></figure>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<p><strong>예외/오류 처리(Exception/Error Handling):</strong></p>



<ul class="wp-block-list">
<li><strong>목적:</strong> 파이프라인의 어느 곳에서든 발생하는 예외를 Catch하고 처리합니다.</li>



<li><strong>예시:</strong> <code>UseExceptionHandler</code> (프로덕션용), <code>UseDeveloperExceptionPage</code> (개발 환경용).</li>



<li><strong>이유:</strong> 예외를 초기에 Catch하여 파이프라인 아래로 전파되어 더 큰 문제를 일으키는 것을 방지합니다.</li>
</ul>



<p><strong>HTTPS 리디렉션(HTTPS Redirection):</strong></p>



<ul class="wp-block-list">
<li><strong>목적:</strong> 보안을 위해 HTTP 요청을 HTTPS로 리디렉션합니다.</li>



<li><strong>예시:</strong> <code>UseHttpsRedirection</code>.</li>



<li><strong>이유:</strong> 보안을 최우선으로 하여 모든 통신이 암호화되도록 합니다.</li>
</ul>



<p><strong>정적 파일(Static Files):</strong></p>



<ul class="wp-block-list">
<li><strong>목적:</strong> 이미지, CSS, JavaScript 파일과 같은 정적 파일을 클라이언트에게 직접 제공합니다.</li>



<li><strong>예시:</strong> <code>UseStaticFiles</code>.</li>



<li><strong>이유:</strong> 정적 파일 요청은 빠르게 처리되어야 하며, 불필요하게 파이프라인의 다른 무거운 구성 요소를 거치지 않도록 일찍 처리합니다.</li>
</ul>



<p><strong>라우팅(Routing):</strong></p>



<ul class="wp-block-list">
<li><strong>목적:</strong> URL을 기반으로 들어오는 요청을 특정 엔드포인트에 매칭합니다.</li>



<li><strong>예시:</strong> <code>UseRouting</code>, <code>UseEndpoints</code>.</li>



<li><strong>이유:</strong> 라우팅은 애플리케이션의 핵심 로직이 요청을 어떻게 처리할지 결정하는 기반이 됩니다.</li>
</ul>



<p><strong>CORS (Cross-Origin Resource Sharing):</strong></p>



<ul class="wp-block-list">
<li><strong>목적:</strong> 다른 도메인으로부터의 안전한 교차 출처(cross-origin) 요청을 가능하게 합니다.</li>



<li><strong>예시:</strong> <code>UseCors</code>.</li>



<li><strong>이유:</strong> 인증/인가 전에 위치하여, 사전 요청(preflight request)이 불필요하게 인증/인가 미들웨어를 거치지 않도록 합니다.</li>
</ul>



<p><strong>인증(Authentication):</strong></p>



<ul class="wp-block-list">
<li><strong>목적:</strong> 사용자 신원을 확인하고 사용자 주체(principal)를 설정합니다.</li>



<li><strong>예시:</strong> <code>UseAuthentication</code>.</li>



<li><strong>이유:</strong> 사용자가 누구인지 확인한 후에 리소스에 대한 접근 권한을 부여할 수 있습니다.</li>
</ul>



<p><strong>인가(Authorization):</strong></p>



<ul class="wp-block-list">
<li><strong>목적:</strong> 사용자가 특정 리소스에 접근하거나 특정 작업을 수행할 수 있는지 여부를 결정합니다.</li>



<li><strong>예시:</strong> <code>UseAuthorization</code>.</li>



<li><strong>이유:</strong> 인증된 사용자에게만 권한 부여 여부를 검사합니다.</li>
</ul>



<p><strong>커스텀 미들웨어(Custom Middleware):</strong></p>



<ul class="wp-block-list">
<li><strong>목적:</strong> 로깅, 기능 플래그 등 애플리케이션별 미들웨어 구성 요소를 처리합니다.</li>



<li><strong>이유:</strong> 애플리케이션별 로직을 적절한 단계에서 파이프라인 내에 배치합니다.</li>
</ul>



<p><strong>MVC/Razor Pages/Minimal APIs:</strong></p>



<ul class="wp-block-list">
<li><strong>목적:</strong> 실제 애플리케이션의 최종 엔드포인트 처리 로직을 실행합니다.</li>



<li><strong>예시:</strong> <code>MapControllers()</code>, <code>MapRazorPages()</code>, <code>MapGet()</code> 등.</li>
</ul>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-image size-full"><img decoding="async" width="848" height="589" src="https://lycos7560.com/wp-content/uploads/2025/07/image-15.png" alt="" class="wp-image-40134" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-15.png 848w, https://lycos7560.com/wp-content/uploads/2025/07/image-15-300x208.png 300w, https://lycos7560.com/wp-content/uploads/2025/07/image-15-768x533.png 768w" sizes="(max-width: 848px) 100vw, 848px" /><figcaption class="wp-element-caption"><a href="https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-8.0" target="_blank" rel="noreferrer noopener">https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-8.0</a></figcaption></figure>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<p><code>Program.cs</code> 파일에 미들웨어 구성 요소가 추가되는 순서는 요청 시 미들웨어 구성 요소가 호출되는 순서를 정의하며, 응답 시에는 역순으로 호출됩니다. </p>



<p>이러한 <strong>순서는 보안, 성능 및 기능에 매우 중요합니다.</strong></p>



<p><code>Program.cs</code>의 다음 강조 표시된 코드는 보안 관련 미들웨어 구성 요소를 일반적으로 권장되는 순서로 추가하는 예시입니다:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="19-43" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using WebMiddleware.Data;

var builder = WebApplication.CreateBuilder(args);

var connectionString = builder.Configuration.GetConnectionString("DefaultConnection")
    ?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found.");
builder.Services.AddDbContext&lt;ApplicationDbContext>(options =>
    options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();

builder.Services.AddDefaultIdentity&lt;IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores&lt;ApplicationDbContext>();
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseMigrationsEndPoint();
}
else
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();
// app.UseCookiePolicy();

app.UseRouting();
// app.UseRateLimiter();
// app.UseRequestLocalization();
// app.UseCors();

app.UseAuthentication();
app.UseAuthorization();
// app.UseSession();
// app.UseResponseCompression();
// app.UseResponseCaching();

app.MapRazorPages();
app.MapDefaultControllerRoute();

app.Run();</pre>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> UseWhen()</h3>



<p><code>UseWhen()</code>은 ASP.NET Core의 <code>IApplicationBuilder</code> 인터페이스에 있는 강력한 확장 메서드입니다. </p>



<p>이는 <strong>조건(predicate)에 따라 미들웨어를 요청 파이프라인에 조건부로 추가</strong>할 수 있도록 합니다. </p>



<p>즉, 특정 조건이 충족될 때만 특정 미들웨어 구성 요소가 실행되는 동적인 파이프라인을 만들 수 있습니다.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">app.UseWhen(
    context => /* 여기에 조건 */, // HttpContext를 받아 true/false 반환
    app => /* 이 분기에서 실행될 미들웨어 구성 */ // 조건이 true일 때 실행될 미들웨어 파이프라인
);</pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<ul class="wp-block-list">
<li><strong><code>context</code>:</strong> <br>현재 요청을 나타내는 <code>HttpContext</code> 객체입니다.</li>



<li><strong>Predicate (조건):</strong> <br><code>HttpContext</code>를 받아들이고 미들웨어 분기가 실행되어야 할 경우 <code>true</code>를, 그렇지 않을 경우 <code>false</code>를 반환하는 함수입니다.</li>



<li><strong>Middleware Configuration (미들웨어 구성):</strong> <br>조건이 <code>true</code>일 때 실행되어야 할 미들웨어 구성 요소를 구성하는 액션입니다. <br>여기서 <code>app.Use()</code>, <code>app.Run()</code>, 또는 다른 미들웨어 등록 메서드를 사용합니다.</li>
</ul>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2728.png" alt="✨" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <code>UseWhen()</code> 작동 방식</h4>



<ul class="wp-block-list">
<li><strong>조건 평가:</strong> <br>요청이 들어오면 <code>UseWhen()</code> 메서드는 먼저 <code>HttpContext</code>에 대해 조건 함수를 평가합니다.</li>



<li><strong>분기(조건이 true일 경우):</strong> <br>조건이 <code>true</code>를 반환하면, 구성 액션에 지정된 미들웨어 분기가 실행됩니다. <br>요청은 이 분기를 통해 흐르며, 수정되거나 응답을 생성할 수 있습니다.</li>



<li><strong>메인 파이프라인 재진입:</strong> <br>분기가 실행된 후(또는 조건이 <code>false</code>여서 건너뛰어진 경우), 요청 흐름은 메인 파이프라인으로 다시 진입하여 <code>UseWhen()</code> 호출 뒤에 등록된 다음 미들웨어 구성 요소로 계속 진행됩니다.</li>
</ul>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">app.UseWhen(
    context => context.Request.Query.ContainsKey("username"), // 조건: 쿼리 문자열에 "username"이 있는지 확인
    app => {
        app.Use(async (context, next) =>
        {
            await context.Response.WriteAsync("Hello from Middleware branch\n"); // 분기 미들웨어: "Hello from Middleware branch" 작성
            await next(); // 다음 미들웨어 호출
        });
    });

app.Run(async context =>
{
    await context.Response.WriteAsync("Hello from middleware at main chain"); // 메인 파이프라인 미들웨어
});</pre>



<ul class="wp-block-list">
<li><strong>조건:</strong> <br><code>context.Request.Query.ContainsKey("username")</code> 조건은 쿼리 문자열에 &#8220;username&#8221;이라는 매개변수가 포함되어 있는지 확인합니다.</li>



<li><strong>분기 미들웨어:</strong> <br>&#8220;username&#8221; 매개변수가 존재하면 분기 미들웨어가 실행됩니다. <br>이 미들웨어는 응답에 &#8220;Hello from Middleware branch&#8221;를 작성하고 <code>next</code>를 호출하여 나머지 파이프라인이 계속되도록 합니다.</li>



<li><strong>메인 파이프라인:</strong> <br>마지막 <code>app.Run</code> 미들웨어는 메인 파이프라인의 일부입니다. <br>이는 응답에 &#8220;Hello from middleware at main chain&#8221;을 작성합니다.</li>
</ul>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f98b.png" alt="🦋" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <code>UseWhen()</code> 사용 시점</h4>



<ul class="wp-block-list">
<li><strong>조건부 기능:</strong> <br>요청에 따라 특정 기능을 활성화하거나 비활성화합니다 (예: 특정 사용자에게만 로깅, 쿼리 매개변수에 따른 캐싱 규칙 적용).</li>



<li><strong>동적 파이프라인:</strong> <br>다양한 요청에 맞춰 조정되는 파이프라인을 만듭니다 (예: 특정 경로에 대해 다른 인증 미들웨어).</li>



<li><strong>A/B 테스트:</strong> <br>실험을 위해 사용자 하위 집합을 대체 미들웨어 분기를 통해 라우팅합니다.</li>



<li><strong>디버깅 및 진단:</strong> <br>개발 환경에서만 진단 미들웨어를 적용합니다.</li>
</ul>



<p></p>
<p>The post <a href="https://lycos7560.com/c/asp-net-core%ec%9d%98-%eb%af%b8%eb%93%a4%ec%9b%a8%ec%96%b4middleware/40130/">ASP.NET Core의 미들웨어(Middleware)</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://lycos7560.com/c/asp-net-core%ec%9d%98-%eb%af%b8%eb%93%a4%ec%9b%a8%ec%96%b4middleware/40130/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Microsoft.Extensions.Hosting, 호스팅 모델(Hosting Model)</title>
		<link>https://lycos7560.com/c/microsoft-extensions-hosting-%ed%98%b8%ec%8a%a4%ed%8c%85-%eb%aa%a8%eb%8d%b8hosting-model/40109/</link>
					<comments>https://lycos7560.com/c/microsoft-extensions-hosting-%ed%98%b8%ec%8a%a4%ed%8c%85-%eb%aa%a8%eb%8d%b8hosting-model/40109/#respond</comments>
		
		<dc:creator><![CDATA[lycos7560]]></dc:creator>
		<pubDate>Fri, 11 Jul 2025 14:31:34 +0000</pubDate>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[AddHostedService]]></category>
		<category><![CDATA[AddScoped]]></category>
		<category><![CDATA[AddSingleton]]></category>
		<category><![CDATA[AddTransient]]></category>
		<category><![CDATA[appsettings.json]]></category>
		<category><![CDATA[ASP.NET Core]]></category>
		<category><![CDATA[async]]></category>
		<category><![CDATA[Await]]></category>
		<category><![CDATA[Background Service]]></category>
		<category><![CDATA[BackgroundService]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[Build]]></category>
		<category><![CDATA[CancellationToken]]></category>
		<category><![CDATA[Clean Code]]></category>
		<category><![CDATA[Cloud Native]]></category>
		<category><![CDATA[Code Quality]]></category>
		<category><![CDATA[Command Line Arguments]]></category>
		<category><![CDATA[Configuration]]></category>
		<category><![CDATA[ConfigureAppConfiguration]]></category>
		<category><![CDATA[ConfigureLogging]]></category>
		<category><![CDATA[ConfigureServices]]></category>
		<category><![CDATA[Console Application]]></category>
		<category><![CDATA[Console Logger]]></category>
		<category><![CDATA[CreateDefaultBuilder]]></category>
		<category><![CDATA[Cross Platform]]></category>
		<category><![CDATA[Debug Logger]]></category>
		<category><![CDATA[Dependency Injection]]></category>
		<category><![CDATA[Design Patterns]]></category>
		<category><![CDATA[DI]]></category>
		<category><![CDATA[Enterprise Application]]></category>
		<category><![CDATA[Environment Variables]]></category>
		<category><![CDATA[Error Handling]]></category>
		<category><![CDATA[Event Log]]></category>
		<category><![CDATA[Exception Handling]]></category>
		<category><![CDATA[Extensions.Hosting]]></category>
		<category><![CDATA[Framework]]></category>
		<category><![CDATA[Generic Host]]></category>
		<category><![CDATA[Graceful Shutdown]]></category>
		<category><![CDATA[Health Checks]]></category>
		<category><![CDATA[Host]]></category>
		<category><![CDATA[Hosting Model]]></category>
		<category><![CDATA[IHost]]></category>
		<category><![CDATA[IHostBuilder]]></category>
		<category><![CDATA[IHostedService]]></category>
		<category><![CDATA[Infrastructure]]></category>
		<category><![CDATA[Integration Testing]]></category>
		<category><![CDATA[Interlocked]]></category>
		<category><![CDATA[IOptions]]></category>
		<category><![CDATA[Lifecycle Management]]></category>
		<category><![CDATA[Log Provider]]></category>
		<category><![CDATA[Logging]]></category>
		<category><![CDATA[LogLevel]]></category>
		<category><![CDATA[Maintainability]]></category>
		<category><![CDATA[Memory Management]]></category>
		<category><![CDATA[Microservices]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[Mocking]]></category>
		<category><![CDATA[Options Pattern]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[resource management]]></category>
		<category><![CDATA[RunAsync]]></category>
		<category><![CDATA[Scalability]]></category>
		<category><![CDATA[Service Lifetime]]></category>
		<category><![CDATA[Service Registration]]></category>
		<category><![CDATA[ServiceProvider]]></category>
		<category><![CDATA[Software Architecture]]></category>
		<category><![CDATA[SOLID Principles]]></category>
		<category><![CDATA[StartAsync]]></category>
		<category><![CDATA[StopAsync]]></category>
		<category><![CDATA[Structured Logging]]></category>
		<category><![CDATA[Task]]></category>
		<category><![CDATA[Testability]]></category>
		<category><![CDATA[Thread Safety]]></category>
		<category><![CDATA[Timer]]></category>
		<category><![CDATA[Unit Testing]]></category>
		<category><![CDATA[Windows Service]]></category>
		<category><![CDATA[Worker Service]]></category>
		<category><![CDATA[WPF Application]]></category>
		<category><![CDATA[구성 관리]]></category>
		<category><![CDATA[구조화된 로깅]]></category>
		<category><![CDATA[단위 테스트]]></category>
		<category><![CDATA[디자인 패턴]]></category>
		<category><![CDATA[로그 프로바이더]]></category>
		<category><![CDATA[로깅]]></category>
		<category><![CDATA[리소스 관리]]></category>
		<category><![CDATA[마이크로서비스]]></category>
		<category><![CDATA[메모리 관리]]></category>
		<category><![CDATA[명령줄 인수]]></category>
		<category><![CDATA[모범 사례]]></category>
		<category><![CDATA[모킹]]></category>
		<category><![CDATA[백그라운드 서비스]]></category>
		<category><![CDATA[생명 주기 관리]]></category>
		<category><![CDATA[서비스 등록]]></category>
		<category><![CDATA[서비스 생명주기]]></category>
		<category><![CDATA[성능]]></category>
		<category><![CDATA[소프트웨어 아키텍처]]></category>
		<category><![CDATA[스레드 안전성]]></category>
		<category><![CDATA[엔터프라이즈 애플리케이션]]></category>
		<category><![CDATA[예외 처리]]></category>
		<category><![CDATA[오류 처리]]></category>
		<category><![CDATA[옵션 패턴]]></category>
		<category><![CDATA[워커 서비스]]></category>
		<category><![CDATA[윈도우 서비스]]></category>
		<category><![CDATA[유지보수성]]></category>
		<category><![CDATA[의존성 주입]]></category>
		<category><![CDATA[인프라]]></category>
		<category><![CDATA[정상적인 종료]]></category>
		<category><![CDATA[제네릭 호스트]]></category>
		<category><![CDATA[코드 품질]]></category>
		<category><![CDATA[콘솔 애플리케이션]]></category>
		<category><![CDATA[크로스 플랫폼]]></category>
		<category><![CDATA[클린 코드]]></category>
		<category><![CDATA[테스트 용이성]]></category>
		<category><![CDATA[통합 테스트]]></category>
		<category><![CDATA[프레임워크]]></category>
		<category><![CDATA[헬스 체크]]></category>
		<category><![CDATA[호스팅 모델]]></category>
		<category><![CDATA[확장성]]></category>
		<category><![CDATA[환경 변수]]></category>
		<guid isPermaLink="false">https://lycos7560.com/?p=40109</guid>

					<description><![CDATA[<p>개요 Microsoft.Extensions.Hosting 네임스페이스는 .NET 애플리케이션의 호스팅 모델(Hosting Model)을 제공하는 핵심 구성 요소입니다. Host 클래스는 이 모델의 시작점 역할을 하며, 애플리케이션의 생명 주기(lifecycle), 구성(configuration), 의존성 주입(dependency injection, DI), 로깅(logging) 등 다양한 인프라 서비스를 중앙 집중식으로 관리합니다. 이 호스팅 모델은 ASP.NET Core 애플리케이션에서 시작되었지만, 현재는 콘솔 애플리케이션, 백그라운드 서비스, Windows 서비스, WPF 애플리케이션 등 다양한 종류의 .NET [&#8230;]</p>
<p>The post <a href="https://lycos7560.com/c/microsoft-extensions-hosting-%ed%98%b8%ec%8a%a4%ed%8c%85-%eb%aa%a8%eb%8d%b8hosting-model/40109/">Microsoft.Extensions.Hosting, 호스팅 모델(Hosting Model)</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></description>
										<content:encoded><![CDATA[				<div class="wp-block-uagb-table-of-contents uagb-toc__align-left uagb-toc__columns-1  uagb-block-c19625a0      "
					data-scroll= "1"
					data-offset= "30"
					style=""
				>
				<div class="uagb-toc__wrap">
						<div class="uagb-toc__title">
							목차						</div>
																						<div class="uagb-toc__list-wrap ">
						<ol class="uagb-toc__list"><li class="uagb-toc__list"><a href="#개요" class="uagb-toc-link__trigger">개요</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#1-host-클래스의-목적과-역할" class="uagb-toc-link__trigger">1. Host 클래스의 목적과 역할</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#2-host-클래스-핵심-인터페이스-및-메서드" class="uagb-toc-link__trigger">2. Host 클래스 핵심 인터페이스 및 메서드</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#1-ihostbuilder-인터페이스" class="uagb-toc-link__trigger">(1) IHostBuilder 인터페이스</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#2-ihost-인터페이스" class="uagb-toc-link__trigger">(2) IHost 인터페이스</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#3-ihostedservice-인터페이스" class="uagb-toc-link__trigger">(3) IHostedService 인터페이스</a></li></ul><li class="uagb-toc__list"><a href="#3-hostcreatedefaultbuilder-메서드의-이점" class="uagb-toc-link__trigger">3. Host.CreateDefaultBuilder() 메서드의 이점</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#예시-코드-콘솔-애플리케이션에서-host-사용하기" class="uagb-toc-link__trigger">예시 코드: 콘솔 애플리케이션에서 Host 사용하기</a></ul></ul></ol>					</div>
									</div>
				</div>
			


<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">개요</h2>



<p>Microsoft.Extensions.Hosting 네임스페이스는 .NET 애플리케이션의 호스팅 모델(Hosting Model)을 제공하는 핵심 구성 요소입니다. </p>



<p>Host 클래스는 이 모델의 시작점 역할을 하며, 애플리케이션의 생명 주기(lifecycle), 구성(configuration), 의존성 주입(dependency injection, DI), 로깅(logging) 등 다양한 인프라 서비스를 중앙 집중식으로 관리합니다.</p>



<p>이 호스팅 모델은 ASP.NET Core 애플리케이션에서 시작되었지만, 현재는 콘솔 애플리케이션, 백그라운드 서비스, Windows 서비스, WPF 애플리케이션 등 다양한 종류의 .NET 애플리케이션에서 표준적인 방식으로 사용되고 있습니다.</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">1. <code>Host</code> 클래스의 목적과 역할</h3>



<p><code>Host</code> 클래스는 특정 애플리케이션 유형에 구애받지 않고, 공통적인 인프라 기능을 쉽게 통합하고 관리할 수 있도록 설계되었습니다.</p>



<ul class="wp-block-list">
<li><strong>생명 주기 관리</strong>: 애플리케이션의 시작(<code>StartAsync</code>) 및 종료(<code>StopAsync</code>)를 관리하고, 이 과정에서 필요한 서비스들이 올바른 순서로 초기화되고 정리될 수 있도록 합니다.</li>



<li><strong>의존성 주입 (DI)</strong>: 애플리케이션 전반에 걸쳐 강력한 DI 컨테이너를 제공하여, 서비스 간의 느슨한 결합을 촉진하고 테스트 용이성을 향상시킵니다.</li>



<li><strong>구성 (Configuration)</strong>: <code>appsettings.json</code>, 환경 변수, 명령줄 인수 등 다양한 소스에서 설정을 로드하고 관리하는 일관된 방법을 제공합니다.</li>



<li><strong>로깅 (Logging)</strong>: 다양한 로깅 프로바이더(콘솔, 파일, 데이터베이스 등)를 쉽게 통합하고, 로깅 레벨을 유연하게 제어할 수 있도록 합니다.</li>



<li><strong>백그라운드 서비스 (IHostedService)</strong>: 장시간 실행되는 백그라운드 작업을 호스트의 생명 주기에 통합하여 관리할 수 있도록 합니다. 이는 API를 제공하지 않고 단순히 작업을 수행하는 서비스에 특히 유용합니다.</li>
</ul>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">2. <code>Host</code> 클래스 핵심 인터페이스 및 메서드</h3>



<p><code>Host</code> 클래스 자체보다는, 이와 관련된 <code>IHost</code> 및 <code>IHostBuilder</code> 인터페이스를 이해하는 것이 중요합니다.</p>



<h4 class="wp-block-heading">(1) <code>IHostBuilder</code> 인터페이스</h4>



<p><code>IHostBuilder</code>는 호스트를 <strong>구성(Configure)</strong>하는 데 사용되는 인터페이스입니다. </p>



<p><code>Host.CreateDefaultBuilder()</code> 메서드가 반환하는 객체가 바로 <strong><code>IHostBuilder</code> </strong>타입입니다. </p>



<p>이 빌더를 통해 다음을 정의할 수 있습니다:</p>



<ul class="wp-block-list">
<li><strong><code>ConfigureAppConfiguration</code></strong>: <br>설정 소스(파일, 환경 변수 등)를 추가하거나 커스터마이징합니다.</li>
</ul>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">.ConfigureAppConfiguration((context, config) =>
{
    config.AddJsonFile("custom.json", optional: true)
          .AddEnvironmentVariables()
          .AddCommandLine(args);
})</pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<ul class="wp-block-list">
<li><strong><code>ConfigureLogging</code></strong>: <br>로깅 프로바이더(콘솔, 디버그, 파일 등)를 추가하고 로깅 필터링 규칙을 정의합니다.</li>
</ul>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">.ConfigureLogging((context, logging) =>
{
    logging.AddConsole()
           .AddDebug()
           .SetMinimumLevel(LogLevel.Information);
})</pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<ul class="wp-block-list">
<li><strong><code>ConfigureServices</code></strong>: <br>의존성 주입 컨테이너에 애플리케이션의 서비스들을 등록합니다. <br><code>AddSingleton</code>, <code>AddScoped</code>, <code>AddTransient</code> 등의 메서드를 사용하여 서비스의 생명 주기를 지정할 수 있습니다.</li>
</ul>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">.ConfigureServices((context, services) =>
{
    services.AddSingleton&lt;ISingletonService, SingletonService>();
    services.AddScoped&lt;IScopedService, ScopedService>();
    services.AddTransient&lt;ITransientService, TransientService>();
    services.AddHostedService&lt;MyBackgroundService>();
})</pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<ul class="wp-block-list">
<li><strong><code>UseConsoleLifetime</code></strong>: <br>콘솔 애플리케이션의 경우, <code>Ctrl+C</code>와 같은 콘솔 시그널을 감지하여 호스트를 정상적으로 종료하도록 설정합니다. <br>(이는 <code>Host.CreateDefaultBuilder()</code>에 의해 기본적으로 포함됩니다.)</li>



<li><strong><code>Build()</code></strong>: <br><code>IHostBuilder</code>에 정의된 모든 구성을 기반으로 최종 <code>IHost</code> 인스턴스를 생성합니다.</li>
</ul>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading">(2) <code>IHost</code> 인터페이스</h4>



<p><code>IHost</code>는 <strong>빌드된 호스트 인스턴스</strong>를 나타내며, 실제로 애플리케이션을 실행하고 관리하는 데 사용됩니다. </p>



<p>주요 메서드는 다음과 같습니다</p>



<ul class="wp-block-list">
<li><strong><code>Services</code></strong>: <br>등록된 모든 서비스 인스턴스에 접근할 수 있는 <code>IServiceProvider</code>를 제공합니다. <br>이를 통해 런타임에 필요한 서비스를 resolve(가져오기)할 수 있습니다.</li>



<li><strong><code>StartAsync(CancellationToken cancellationToken)</code></strong>: <br>호스트를 비동기적으로 시작합니다. 이 메서드가 호출되면 등록된 모든 <code>IHostedService</code> 인스턴스의 <code>StartAsync</code> 메서드가 호출됩니다.</li>



<li><strong><code>StopAsync(CancellationToken cancellationToken)</code></strong>: <br>호스트를 비동기적으로 종료합니다. 등록된 모든 <code>IHostedService</code> 인스턴스의 <code>StopAsync</code> 메서드가 호출되어 리소스를 정리할 기회를 줍니다.</li>



<li><strong><code>RunAsync(CancellationToken cancellationToken = default)</code></strong>: <br><code>StartAsync</code>를 호출하고, 호스트가 종료될 때까지 대기한 후 <code>StopAsync</code>를 호출합니다. <br>대부분의 콘솔 애플리케이션에서 메인 실행 루프로 사용됩니다.</li>
</ul>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading">(3) <code>IHostedService</code> 인터페이스</h4>



<p><code>IHostedService</code>는 호스트의 생명 주기에 통합되어 백그라운드 작업을 수행하는 서비스들을 정의하는 인터페이스입니다. </p>



<p><code>StartAsync</code>와 <code>StopAsync</code> 두 가지 메서드를 구현해야 합니다.</p>



<ul class="wp-block-list">
<li><strong><code>StartAsync(CancellationToken cancellationToken)</code></strong>: <br>호스트가 시작될 때 호출됩니다. 장시간 실행되는 작업을 시작하는 데 사용됩니다.</li>



<li><strong><code>StopAsync(CancellationToken cancellationToken)</code></strong>: <br>호스트가 종료될 때 호출됩니다. <code>StartAsync</code>에서 시작된 작업을 정상적으로 중지하고 리소스를 정리하는 데 사용됩니다.</li>
</ul>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">3. <code>Host.CreateDefaultBuilder()</code> 메서드의 이점</h3>



<p>이 메서드는 많은 &#8220;관습(conventions)&#8221;을 제공하여 애플리케이션 초기 설정을 간소화하는 장점이 있습니다.</p>



<ul class="wp-block-list">
<li><strong>일관성</strong>: <br>모든 .NET 애플리케이션 유형(웹, 콘솔, 백그라운드 서비스)에서 동일한 방식으로 인프라를 설정할 수 있게 하여 코드의 일관성을 유지합니다.</li>



<li><strong>생산성</strong>: <br>설정, 로깅, DI 등 반복적인 초기화 코드를 작성할 필요 없이 바로 비즈니스 로직에 집중할 수 있도록 합니다.</li>



<li><strong>확장성</strong>: <br>기본 설정을 사용하면서도 <code>ConfigureAppConfiguration</code>, <code>ConfigureServices</code> 등의 메서드를 통해 언제든지 필요에 따라 커스터마이징하고 확장할 수 있습니다.</li>



<li><strong>테스트 용이성</strong>: <br>DI 컨테이너를 중심으로 설계되어, 단위 테스트 및 통합 테스트에서 의존성을 쉽게 Mocking하거나 대체할 수 있습니다.<br>참고: Mocking &#8211; 테스트 코드 작성 시 가짜 객체(Mock)를 만들어 실제 객체 대신 사용하는 기법</li>
</ul>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading">예시 코드: 콘솔 애플리케이션에서 <code>Host</code> 사용하기</h4>



<p>콘솔 애플리케이션에서 <code>Host</code> 클래스를 사용하여 백그라운드 서비스(카운터)를 실행하고, 설정 및 로깅을 사용하는 예제</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<ul class="wp-block-list">
<li><code>Microsoft.Extensions.Hosting</code> NuGet 패키지를 설치</li>
</ul>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">dotnet add package Microsoft.Extensions.Hosting</pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<ul class="wp-block-list">
<li><code>appsettings.json</code> 파일을 추가하고 내용을 작성합니다.</li>
</ul>



<pre class="EnlighterJSRAW" data-enlighter-language="json" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AppConfig": {
    "IntervalSeconds": 2
  }
}</pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<ul class="wp-block-list">
<li><code>Services/MyBackgroundService.cs</code> (커스텀 <code>IHostedService</code> 구현):</li>
</ul>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Configuration; // IConfiguration 주입을 위해 추가
using System;
using System.Threading;
using System.Threading.Tasks;

namespace MyConsoleApp.Services
{
    // IHostedService를 구현하여 호스트의 생명 주기에 통합될 백그라운드 서비스를 정의합니다.
    public class MyBackgroundService : IHostedService, IDisposable
    {
        private readonly ILogger&lt;MyBackgroundService> _logger;
        private readonly IConfiguration _configuration;
        private Timer? _timer;
        private int _executionCount = 0;
        private int _intervalSeconds;

        public MyBackgroundService(ILogger&lt;MyBackgroundService> logger, IConfiguration configuration)
        {
            _logger = logger;
            _configuration = configuration;

            // appsettings.json에서 설정 값 읽기
            _intervalSeconds = _configuration.GetValue&lt;int>("AppConfig:IntervalSeconds", 5); // 기본값 5초
        }

        // 호스트가 시작될 때 호출됩니다.
        public Task StartAsync(CancellationToken cancellationToken)
        {
            _logger.LogInformation("MyBackgroundService가 시작되었습니다.");

            // 타이머를 설정하여 지정된 간격마다 DoWork 메서드를 호출합니다.
            _timer = new Timer(DoWork, null, TimeSpan.Zero, TimeSpan.FromSeconds(_intervalSeconds));

            return Task.CompletedTask; // 비동기 작업 시작을 알리고 즉시 반환
        }

        // 타이머에 의해 주기적으로 호출되는 실제 작업 메서드
        private void DoWork(object? state)
        {
            var count = Interlocked.Increment(ref _executionCount);
            _logger.LogInformation(
                "MyBackgroundService가 {count}번째 작업을 수행 중입니다. 현재 시간: {time}",
                count, DateTimeOffset.Now);
        }

        // 호스트가 종료될 때 호출됩니다.
        public Task StopAsync(CancellationToken cancellationToken)
        {
            _logger.LogInformation("MyBackgroundService가 중지되고 있습니다.");

            // 타이머를 중지하고 리소스를 해제합니다.
            // Change(Timeout.Infinite, 0)은 타이머를 비활성화하는 표준 방법입니다.
            _timer?.Change(Timeout.Infinite, 0);

            _logger.LogInformation("MyBackgroundService가 중지되었습니다.");
            return Task.CompletedTask; // 작업 완료를 알립니다.
        }

        // 리소스 해제를 위한 Dispose 메서드 (IHostedService는 IDisposable을 구현하는 경우가 많음)
        public void Dispose()
        {
            _timer?.Dispose();
        }
    }
}</pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<ul class="wp-block-list">
<li><code>Program.cs</code> 구현:</li>
</ul>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using MyConsoleApp.Services; // MyBackgroundService를 사용하기 위해 추가
using System;
using System.Threading.Tasks;

namespace MyConsoleApp
{
    public class Program
    {
        public static async Task Main(string[] args)
        {
            Console.WriteLine("콘솔 애플리케이션 호스트가 시작됩니다. 종료하려면 Ctrl+C를 누르세요.");

            // 1. IHostBuilder 인스턴스 생성: Host.CreateDefaultBuilder()는 기본적인 구성(config, logging, DI)을 설정합니다.
            var builder = Host.CreateDefaultBuilder(args)
                // 2. 서비스 컨테이너 구성: 의존성 주입을 위한 서비스들을 등록합니다.
                .ConfigureServices((hostContext, services) =>
                {
                    // MyBackgroundService를 IHostedService로 등록합니다.
                    // 호스트가 시작될 때 StartAsync가 호출되고, 종료될 때 StopAsync가 호출됩니다.
                    services.AddHostedService&lt;MyBackgroundService>();

                    // 여기에 다른 서비스들도 등록할 수 있습니다. 예:
                    // services.AddSingleton&lt;IMyService, MyService>();
                    // services.AddScoped&lt;IOtherService, OtherService>();
                })
                // 3. 로깅 구성 (선택 사항: CreateDefaultBuilder가 기본 설정 제공하지만, 커스터마이징 가능)
                .ConfigureLogging(logging =>
                {
                    logging.ClearProviders(); // 기본 로깅 프로바이더를 지우고 새로 추가하거나
                    logging.AddConsole();    // 콘솔 로거를 추가합니다.
                    // logging.AddDebug();    // 디버그 로거 추가
                });
                // 4. 기타 구성 (선택 사항: 파일 경로, 환경 등)
                // .UseContentRoot(Directory.GetCurrentDirectory())
                // .UseEnvironment("Development")
                // .ConfigureAppConfiguration((hostingContext, config) => {
                //    config.AddJsonFile("custom.json", optional: true);
                // });

            // 5. IHost 인스턴스 빌드: 구성된 빌더를 바탕으로 실제 호스트를 생성합니다.
            var host = builder.Build();

            // 6. 호스트 실행: 등록된 모든 IHostedService를 시작하고 애플리케이션 종료를 대기합니다.
            // Ctrl+C 시그널을 감지하여 정상적으로 종료됩니다.
            await host.RunAsync();

            Console.WriteLine("콘솔 애플리케이션 호스트가 종료되었습니다.");
        }
    }
}</pre>



<p></p>



<p></p>



<p></p>



<p></p>
<p>The post <a href="https://lycos7560.com/c/microsoft-extensions-hosting-%ed%98%b8%ec%8a%a4%ed%8c%85-%eb%aa%a8%eb%8d%b8hosting-model/40109/">Microsoft.Extensions.Hosting, 호스팅 모델(Hosting Model)</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://lycos7560.com/c/microsoft-extensions-hosting-%ed%98%b8%ec%8a%a4%ed%8c%85-%eb%aa%a8%eb%8d%b8hosting-model/40109/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Unity Canvas Scaler</title>
		<link>https://lycos7560.com/unity/unity-canvas-scaler/40382/</link>
					<comments>https://lycos7560.com/unity/unity-canvas-scaler/40382/#respond</comments>
		
		<dc:creator><![CDATA[lycos7560]]></dc:creator>
		<pubDate>Sat, 14 Dec 2024 19:42:10 +0000</pubDate>
				<category><![CDATA[Unity]]></category>
		<category><![CDATA[9:16]]></category>
		<category><![CDATA[9:21]]></category>
		<category><![CDATA[Anchor]]></category>
		<category><![CDATA[Android Development]]></category>
		<category><![CDATA[Aspect Ratio]]></category>
		<category><![CDATA[Best Practice]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Canvas]]></category>
		<category><![CDATA[Canvas Group]]></category>
		<category><![CDATA[Canvas Render]]></category>
		<category><![CDATA[Canvas Scaler]]></category>
		<category><![CDATA[Clipping]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[Constant Physical Size]]></category>
		<category><![CDATA[Constant Pixel Size]]></category>
		<category><![CDATA[Cross Platform]]></category>
		<category><![CDATA[Development Tips]]></category>
		<category><![CDATA[Device Simulator]]></category>
		<category><![CDATA[DPI]]></category>
		<category><![CDATA[Dynamic UI]]></category>
		<category><![CDATA[Expand Mode]]></category>
		<category><![CDATA[Frontend]]></category>
		<category><![CDATA[Game Design]]></category>
		<category><![CDATA[Game Development]]></category>
		<category><![CDATA[Game Engine]]></category>
		<category><![CDATA[Game Programming]]></category>
		<category><![CDATA[Graphic Design]]></category>
		<category><![CDATA[Guide]]></category>
		<category><![CDATA[Hierarchy]]></category>
		<category><![CDATA[How-to]]></category>
		<category><![CDATA[Indie Game]]></category>
		<category><![CDATA[iOS Development]]></category>
		<category><![CDATA[Landscape Mode]]></category>
		<category><![CDATA[Layout]]></category>
		<category><![CDATA[Letterbox]]></category>
		<category><![CDATA[Match Width or Height]]></category>
		<category><![CDATA[Mobile Game]]></category>
		<category><![CDATA[Mobile UX]]></category>
		<category><![CDATA[Multi-resolution]]></category>
		<category><![CDATA[Notch]]></category>
		<category><![CDATA[Optimization]]></category>
		<category><![CDATA[Pillarbox]]></category>
		<category><![CDATA[Pivot]]></category>
		<category><![CDATA[Pixel Density]]></category>
		<category><![CDATA[Portrait Mode]]></category>
		<category><![CDATA[PPI]]></category>
		<category><![CDATA[PPU]]></category>
		<category><![CDATA[Professional UI]]></category>
		<category><![CDATA[Punch Hole]]></category>
		<category><![CDATA[Rect Transform]]></category>
		<category><![CDATA[Reference Pixels Per Unit]]></category>
		<category><![CDATA[Reference Resolution]]></category>
		<category><![CDATA[Responsive UI]]></category>
		<category><![CDATA[Safe Area]]></category>
		<category><![CDATA[Scalability]]></category>
		<category><![CDATA[Scale With Screen Size]]></category>
		<category><![CDATA[Scaler]]></category>
		<category><![CDATA[Screen Match Mode]]></category>
		<category><![CDATA[Screen Resolution]]></category>
		<category><![CDATA[scripting]]></category>
		<category><![CDATA[Shrink Mode]]></category>
		<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[Sprite]]></category>
		<category><![CDATA[study]]></category>
		<category><![CDATA[Tablet UI]]></category>
		<category><![CDATA[Tech Blog]]></category>
		<category><![CDATA[Technical Artist]]></category>
		<category><![CDATA[TUTORIAL]]></category>
		<category><![CDATA[UGUI]]></category>
		<category><![CDATA[UI]]></category>
		<category><![CDATA[UI Canvas]]></category>
		<category><![CDATA[UI Container]]></category>
		<category><![CDATA[UI Layout Group]]></category>
		<category><![CDATA[UI Optimization]]></category>
		<category><![CDATA[UI Scaling]]></category>
		<category><![CDATA[UI 레이아웃 그룹]]></category>
		<category><![CDATA[UI 스케일링]]></category>
		<category><![CDATA[UI 최적화]]></category>
		<category><![CDATA[UI 캔버스]]></category>
		<category><![CDATA[UI 컨테이너]]></category>
		<category><![CDATA[Unity 2D]]></category>
		<category><![CDATA[Unity 3D]]></category>
		<category><![CDATA[Unity UI System]]></category>
		<category><![CDATA[User Experience]]></category>
		<category><![CDATA[User Interface]]></category>
		<category><![CDATA[UX]]></category>
		<category><![CDATA[Visual studio]]></category>
		<category><![CDATA[가로 모드]]></category>
		<category><![CDATA[가이드]]></category>
		<category><![CDATA[개발 팁]]></category>
		<category><![CDATA[게임 디자인]]></category>
		<category><![CDATA[게임 엔진]]></category>
		<category><![CDATA[게임 프로그래밍]]></category>
		<category><![CDATA[게임개발]]></category>
		<category><![CDATA[계층 구조]]></category>
		<category><![CDATA[공부]]></category>
		<category><![CDATA[그래픽 디자인]]></category>
		<category><![CDATA[기술 블로그]]></category>
		<category><![CDATA[기준 해상도]]></category>
		<category><![CDATA[기초]]></category>
		<category><![CDATA[노치 디자인]]></category>
		<category><![CDATA[다중 해상도]]></category>
		<category><![CDATA[동적 UI]]></category>
		<category><![CDATA[디바이스 시뮬레이터]]></category>
		<category><![CDATA[레이아웃]]></category>
		<category><![CDATA[레터박스]]></category>
		<category><![CDATA[렉트 트랜스폼]]></category>
		<category><![CDATA[모바일 UX]]></category>
		<category><![CDATA[모바일 게임]]></category>
		<category><![CDATA[반응형 UI]]></category>
		<category><![CDATA[방법론]]></category>
		<category><![CDATA[베스트 프랙티스]]></category>
		<category><![CDATA[비주얼 스튜디오]]></category>
		<category><![CDATA[세로 모드]]></category>
		<category><![CDATA[세이프 에어리어]]></category>
		<category><![CDATA[소프트웨어 공학]]></category>
		<category><![CDATA[슈링크 모드]]></category>
		<category><![CDATA[스크린 매치 모드]]></category>
		<category><![CDATA[스크립팅]]></category>
		<category><![CDATA[스프라이트]]></category>
		<category><![CDATA[씨샵]]></category>
		<category><![CDATA[아이폰 개발]]></category>
		<category><![CDATA[안드로이드 개발]]></category>
		<category><![CDATA[앵커]]></category>
		<category><![CDATA[유니티]]></category>
		<category><![CDATA[유니티 2D]]></category>
		<category><![CDATA[유니티 3D]]></category>
		<category><![CDATA[익스팬드 모드]]></category>
		<category><![CDATA[인디 게임]]></category>
		<category><![CDATA[최적화]]></category>
		<category><![CDATA[캔버스 그룹]]></category>
		<category><![CDATA[캔버스 렌더]]></category>
		<category><![CDATA[캔버스 스케일러]]></category>
		<category><![CDATA[코딩]]></category>
		<category><![CDATA[크로스 플랫폼]]></category>
		<category><![CDATA[클리핑]]></category>
		<category><![CDATA[태블릿 UI]]></category>
		<category><![CDATA[테크니컬 아티스트]]></category>
		<category><![CDATA[튜토리얼]]></category>
		<category><![CDATA[펀치홀]]></category>
		<category><![CDATA[프로페셔널 UI]]></category>
		<category><![CDATA[프론트엔드]]></category>
		<category><![CDATA[피벗]]></category>
		<category><![CDATA[픽셀 밀도]]></category>
		<category><![CDATA[필러박스]]></category>
		<category><![CDATA[화면 비율]]></category>
		<category><![CDATA[화면 해상도]]></category>
		<category><![CDATA[확장성]]></category>
		<guid isPermaLink="false">https://lycos7560.com/?p=40382</guid>

					<description><![CDATA[<p>Canvas Scaler (캔버스 스케일러) https://docs.unity3d.com/Packages/com.unity.ugui@2.0/manual/script-CanvasScaler.html 캔버스 내 모든 UI 요소의 전체적인 스케일(크기)과 픽셀 밀도를 제어하는 데 사용하는 컴포넌트 이 스케일링은 폰트 크기와 이미지 테두리(Borders)를 포함하여 캔버스 아래에 있는 모든 요소에 영향을 미친다. 1. 주요 속성 (Properties) 속성 기능 UI Scale Mode 캔버스의 UI 요소가 스케일링되는 방식을 결정 &#8211; Constant Pixel Size 화면 크기에 상관없이 UI [&#8230;]</p>
<p>The post <a href="https://lycos7560.com/unity/unity-canvas-scaler/40382/">Unity Canvas Scaler</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>


				<div class="wp-block-uagb-table-of-contents uagb-toc__align-left uagb-toc__columns-1  uagb-block-e856a7fc      "
					data-scroll= "1"
					data-offset= "30"
					style=""
				>
				<div class="uagb-toc__wrap">
						<div class="uagb-toc__title">
							목차						</div>
																						<div class="uagb-toc__list-wrap ">
						<ol class="uagb-toc__list"><li class="uagb-toc__list"><a href="#canvas-scaler-캔버스-스케일러" class="uagb-toc-link__trigger">Canvas Scaler (캔버스 스케일러)</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#1-주요-속성-properties" class="uagb-toc-link__trigger">1. 주요 속성 (Properties)</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#1-scale-with-screen-size" class="uagb-toc-link__trigger">(1) Scale With Screen Size</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#2-constant-pixel-size" class="uagb-toc-link__trigger">(2) Constant Pixel Size</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#3-constant-physical-size" class="uagb-toc-link__trigger">(3) Constant Physical Size</a></li></ul><li class="uagb-toc__list"><a href="#2-언제-사용하나요" class="uagb-toc-link__trigger">2. 언제 사용하나요?</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#1-모바일-게임-scale-with-screen-size" class="uagb-toc-link__trigger">(1) 모바일 게임 &#8211; Scale With Screen Size</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#2-도구-모음-정교한-그래픽-툴-constant-pixel-size" class="uagb-toc-link__trigger">(2) 도구 모음, 정교한 그래픽 툴 &#8211; Constant Pixel Size</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#3-실제-크기가-중요-constant-physical-size" class="uagb-toc-link__trigger">(3) 실제 크기가 중요 &#8211; Constant Physical Size</a></ul></ul></ol>					</div>
									</div>
				</div>
			


<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">Canvas Scaler (캔버스 스케일러)</h2>



<p><a href="https://docs.unity3d.com/Packages/com.unity.ugui@2.0/manual/script-CanvasScaler.html" target="_blank" rel="noreferrer noopener">https://docs.unity3d.com/Packages/com.unity.ugui@2.0/manual/script-CanvasScaler.html</a></p>



<p>캔버스 내 모든 UI 요소의 <strong>전체적인 스케일(크기)과 픽셀 밀도</strong>를 제어하는 데 사용하는 컴포넌트</p>



<p>이 스케일링은 폰트 크기와 이미지 테두리(Borders)를 포함하여 <strong>캔버스 아래에 있는 모든 요소에 영향</strong>을 미친다.</p>



<hr class="wp-block-separator has-alpha-channel-opacity is-style-default" style="margin-top:var(--wp--preset--spacing--30);margin-bottom:var(--wp--preset--spacing--30)"/>



<h3 class="wp-block-heading">1. <strong>주요 속성 (Properties)</strong></h3>



<figure class="wp-block-image size-full"><img decoding="async" width="399" height="119" src="https://lycos7560.com/wp-content/uploads/2026/01/image.png" alt="" class="wp-image-40383" srcset="https://lycos7560.com/wp-content/uploads/2026/01/image.png 399w, https://lycos7560.com/wp-content/uploads/2026/01/image-300x89.png 300w" sizes="(max-width: 399px) 100vw, 399px" /></figure>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><td><strong>속성</strong></td><td><strong>기능</strong></td></tr></thead><tbody><tr><td><strong>UI Scale Mode</strong></td><td>캔버스의 UI 요소가 스케일링되는 방식을 결정</td></tr><tr><td><strong>&#8211; Constant Pixel Size</strong></td><td>화면 크기에 상관없이 UI 요소가 동일한 <strong>픽셀 크기</strong>를 유지</td></tr><tr><td><strong>&#8211; Scale With Screen Size</strong></td><td>화면이 커질수록 UI 요소도 함께 커짐 (가장 많이 사용)</td></tr><tr><td><strong>&#8211; Constant Physical Size</strong></td><td>화면 크기나 해상도에 상관없이 UI 요소가 동일한 <strong>물리적 크기(mm 등)</strong>를 유지</td></tr></tbody></table></figure>



<h4 class="wp-block-heading">(1) Scale With Screen Size</h4>



<figure class="wp-block-image size-full"><img decoding="async" width="402" height="152" src="https://lycos7560.com/wp-content/uploads/2026/01/image-1.png" alt="" class="wp-image-40384" srcset="https://lycos7560.com/wp-content/uploads/2026/01/image-1.png 402w, https://lycos7560.com/wp-content/uploads/2026/01/image-1-300x113.png 300w" sizes="(max-width: 402px) 100vw, 402px" /></figure>



<p>특정 <strong>기준 해상도(Reference Resolution)</strong>를 설정하고, 현재 화면에 맞춰 UI를 키우거나 줄입니다.</p>



<p><strong>Reference Resolution</strong>: UI 레이아웃을 설계할 때 기준이 되는 해상도입니다.</p>



<p><strong>Screen Match Mode</strong>: 현재 화면 비율이 기준 해상도와 다를 때 캔버스 영역을 맞추는 방식입니다.</p>



<ul class="wp-block-list">
<li><strong>Match Width or Height</strong>: 가로 폭이나 세로 높이 중 하나를 기준으로(또는 그 사이 값으로) 스케일을 조절합니다.</li>



<li><strong>Expand</strong>: 캔버스 크기가 기준 해상도보다 작아지지 않도록 가로나 세로 방향으로 확장합니다.</li>



<li><strong>Shrink</strong>: 캔버스 크기가 기준 해상도보다 커지지 않도록 가로나 세로 방향으로 자릅니다(Crop).</li>
</ul>



<p><strong>Match</strong>: 가로(0)와 세로(1) 중 어느 쪽을 스케일링 기준으로 삼을지 결정합니다.</p>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading">(2) Constant Pixel Size</h4>



<figure class="wp-block-image size-full"><img decoding="async" width="402" height="104" src="https://lycos7560.com/wp-content/uploads/2026/01/image-3.png" alt="" class="wp-image-40386" srcset="https://lycos7560.com/wp-content/uploads/2026/01/image-3.png 402w, https://lycos7560.com/wp-content/uploads/2026/01/image-3-300x78.png 300w" sizes="(max-width: 402px) 100vw, 402px" /></figure>



<p>UI 요소의 위치와 크기가 <strong>화면의 픽셀 단위로 지정</strong>됩니다.</p>



<ul class="wp-block-list">
<li><strong>Scale Factor</strong>: 캔버스 내 모든 UI 요소에 일괄적으로 적용되는 스케일 값입니다.</li>



<li><strong>Reference Pixels Per Unit</strong>: 스프라이트의 &#8216;Pixels Per Unit&#8217; 설정이 이 값과 같다면, 스프라이트의 1픽셀은 UI상의 1유닛(픽셀)과 대응합니다.</li>
</ul>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading">(3) Constant Physical Size</h4>



<figure class="wp-block-image size-full"><img decoding="async" width="400" height="138" src="https://lycos7560.com/wp-content/uploads/2026/01/image-2.png" alt="" class="wp-image-40385" srcset="https://lycos7560.com/wp-content/uploads/2026/01/image-2.png 400w, https://lycos7560.com/wp-content/uploads/2026/01/image-2-300x104.png 300w" sizes="(max-width: 400px) 100vw, 400px" /></figure>



<p>UI 요소의 크기를 밀리미터(mm), 포인트(points), 파이카(picas) 등 <strong>물리적 단위</strong>로 지정합니다.</p>



<ul class="wp-block-list">
<li><strong>Physical Unit</strong>: 위치와 크기를 지정할 물리적 단위입니다.</li>



<li><strong>Fallback Screen DPI</strong>: 기기의 DPI를 알 수 없을 때 가정할 기본 DPI 값입니다.</li>



<li><strong>Default Sprite DPI</strong>: 스프라이트의 픽셀 밀도 기준입니다.</li>



<li><strong>Reference Pixels Per Unit</strong>: 스프라이트의 &#8216;Pixels Per Unit&#8217; 설정이 이 값과 같다면, 스프라이트의 1픽셀은 UI상의 1유닛(픽셀)과 대응합니다.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity" style="margin-top:var(--wp--preset--spacing--60);margin-bottom:var(--wp--preset--spacing--60)"/>



<h3 class="wp-block-heading">2. 언제 사용하나요?</h3>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><td><strong>모드</strong></td><td><strong>핵심 개념</strong></td><td><strong>주 사용처</strong></td></tr></thead><tbody><tr><td><strong>Scale With Screen Size</strong></td><td><strong>비율</strong> 중심</td><td>일반적인 모든 모바일/PC 게임</td></tr><tr><td><strong>Constant Pixel Size</strong></td><td><strong>픽셀 수</strong> 중심</td><td>전문 도구, 캔버스 좌표가 중요한 앱</td></tr><tr><td><strong>Constant Physical Size</strong></td><td><strong>실제 길이(cm)</strong> 중심</td><td>물리적 크기가 고정되어야 하는 특수 목적 앱</td></tr></tbody></table></figure>



<h4 class="wp-block-heading">(1) <strong>모바일 게임</strong> &#8211; Scale With Screen Size</h4>



<p><strong>가장 많이 사용하며, 모바일 게임 개발의 표준입니다.</strong></p>



<ul class="wp-block-list">
<li><strong>언제 사용하나?</strong>
<ul class="wp-block-list">
<li>대부분의 <strong>모바일 게임, PC 게임</strong>을 만들 때.</li>



<li>화면이 커지면 UI도 그에 비례해서 커지길 원할 때.</li>



<li>다양한 해상도(아이폰, 갤럭시, 태블릿 등)에 대응해야 할 때.</li>
</ul>
</li>



<li><strong>특징:</strong> 기준 해상도(예: 1440&#215;2560)를 정해두면 유니티가 알아서 기기 화면에 맞춰 UI를 키우거나 줄여줍니다. 개발자는 한 가지 사이즈만 고민하면 됩니다.</li>
</ul>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading">(2) <strong>도구 모음</strong>, <strong>정교한 그래픽 툴</strong> &#8211; Constant Pixel Size</h4>



<p><strong>픽셀 숫자를 그대로 유지합니다.</strong></p>



<ul class="wp-block-list">
<li><strong>언제 사용하나?</strong>
<ul class="wp-block-list">
<li><strong>웹 브라우저의 도구 모음</strong>이나 <strong>정교한 그래픽 툴</strong> 같은 앱을 만들 때.</li>



<li>해상도가 높아져도 아이콘이 커지지 않고, 대신 <strong>더 넓은 작업 공간</strong>을 보여주고 싶을 때.</li>



<li>저해상도와 고해상도에서 UI의 &#8220;선명도&#8221;를 1:1 픽셀 매칭으로 유지하고 싶을 때.</li>
</ul>
</li>



<li><strong>특징:</strong> 100&#215;100 픽셀 버튼은 4K 모니터에서도 100&#215;100 픽셀입니다. 따라서 고해상도 기기일수록 UI가 매우 작게 보입니다.</li>
</ul>



<figure class="wp-block-image size-full is-resized"><img decoding="async" width="1207" height="511" src="https://lycos7560.com/wp-content/uploads/2024/12/image-222.png" alt="" class="wp-image-40394" style="aspect-ratio:2.3621642749455583;width:472px;height:auto" srcset="https://lycos7560.com/wp-content/uploads/2024/12/image-222.png 1207w, https://lycos7560.com/wp-content/uploads/2024/12/image-222-300x127.png 300w, https://lycos7560.com/wp-content/uploads/2024/12/image-222-768x325.png 768w" sizes="(max-width: 1207px) 100vw, 1207px" /><figcaption class="wp-element-caption">그림판</figcaption></figure>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading">(3) <strong>실제 크기가 중요</strong> &#8211; Constant Physical Size</h4>



<p><strong>실제 자(Ruler)로 쟀을 때의 물리적 크기를 유지합니다.</strong></p>



<ul class="wp-block-list">
<li><strong>언제 사용하나?</strong>
<ul class="wp-block-list">
<li><strong>실제 크기가 중요한 앱:</strong> 예를 들어 화면에 대고 길이를 재는 &#8216;자(Ruler) 앱&#8217;이나, 사람의 손가락 크기에 맞춰 버튼 크기가 물리적으로 일정해야 하는 특수 장비용 앱.</li>



<li>화면의 밀도(DPI)와 상관없이 버튼이 항상 1cm가 되어야 할 때.</li>
</ul>
</li>



<li><strong>특징:</strong> 기기가 5인치든 10인치든 상관없이 버튼의 실제 길이를 유지하려 노력합니다. 기기가 화면의 DPI 정보를 정확히 전달해줘야 정상 작동합니다.</li>
</ul>



<p></p>
<p>The post <a href="https://lycos7560.com/unity/unity-canvas-scaler/40382/">Unity Canvas Scaler</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://lycos7560.com/unity/unity-canvas-scaler/40382/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
