<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>어제보다 성장한 오늘</title>
    <link>https://xzio.tistory.com/</link>
    <description>프로그래밍 IT 블로그</description>
    <language>ko</language>
    <pubDate>Sat, 8 Aug 2026 03:29:37 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>Wings of Freedom</managingEditor>
    <image>
      <title>어제보다 성장한 오늘</title>
      <url>https://tistory1.daumcdn.net/tistory/2796349/attach/d9514bcf9ccf4709ba800d4d18c8edd1</url>
      <link>https://xzio.tistory.com</link>
    </image>
    <item>
      <title>Codex vs Claude Code, 뭘 언제 써야 할까 &amp;mdash; 백엔드 개발자의 정리</title>
      <link>https://xzio.tistory.com/2682</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;image.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brIPwm/dJMcaalz6HE/20MiVQ5npbrPvdKck5WNJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brIPwm/dJMcaalz6HE/20MiVQ5npbrPvdKck5WNJk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brIPwm/dJMcaalz6HE/20MiVQ5npbrPvdKck5WNJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbrIPwm%2FdJMcaalz6HE%2F20MiVQ5npbrPvdKck5WNJk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;1024&quot; data-filename=&quot;image.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-sourcepos=&quot;3:1-3:166;50-215&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-sourcepos=&quot;3:1-3:166;50-215&quot; data-ke-size=&quot;size16&quot;&gt;에이전트형 코딩 도구가 이제 '자동완성'을 한참 넘어섰다. 코드베이스를 읽고, 파일을 고치고, 테스트를 돌리고, PR까지 열어두는 걸 하나의 지시로 해낸다. 그중 실무에서 가장 자주 비교선상에 오르는 두 도구가 OpenAI의 &lt;b&gt;Codex&lt;/b&gt;와 Anthropic의 &lt;b&gt;Claude Code&lt;/b&gt;다.&lt;/p&gt;
&lt;p data-sourcepos=&quot;5:1-5:105;217-321&quot; data-ke-size=&quot;size16&quot;&gt;팀에 공유하려고 둘을 나란히 정리하다 보니, 결론이 생각보다 단순했다. &quot;어느 게 더 좋냐&quot;가 아니라 &lt;b&gt;&quot;어떤 작업에 어느 걸 쓰느냐&quot;&lt;/b&gt; 의 문제라는 것. 아래에 그 근거를 정리했다.&lt;/p&gt;
&lt;blockquote data-sourcepos=&quot;7:1-7:98;323-420&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-sourcepos=&quot;7:3-7:98;325-420&quot; data-ke-size=&quot;size16&quot;&gt;참고: 아래 수치&amp;middot;요금&amp;middot;기능은 모두 &lt;b&gt;2026년 7월 기준&lt;/b&gt;이다. 이 바닥은 몇 주 단위로 바뀌니, 실제 도입을 결정할 땐 공식 페이지에서 한 번 더 확인하길 권한다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-sourcepos=&quot;11:1-11:42;427-468&quot; data-ke-size=&quot;size26&quot;&gt;먼저 용어 정리 &amp;mdash; &quot;GPT Pro Codex&quot;는 별도 제품이 아니다&lt;/h2&gt;
&lt;p data-sourcepos=&quot;13:1-13:136;470-605&quot; data-ke-size=&quot;size16&quot;&gt;간혹 &quot;GPT Pro Codex&quot;라는 표현을 보는데, 이건 별도의 제품이 아니라 &lt;b&gt;ChatGPT Pro 요금제에서 쓰는 Codex&lt;/b&gt;를 가리킨다. Codex 자체는 요금제와 무관한 하나의 도구이고, Pro는 사용량 한도가 큰 플랜일 뿐이다.&lt;/p&gt;
&lt;p data-sourcepos=&quot;15:1-15:191;607-797&quot; data-ke-size=&quot;size16&quot;&gt;그리고 하나 더. Codex라는 이름은 OpenAI가 시기마다 다른 것에 붙여 와서 혼란스럽다. 2021년의 최초 Codex 코딩 모델(지금은 폐기), 2025년 5월의 Codex Cloud 프리뷰, 그리고 &lt;b&gt;2026년 현재의 GPT-5.5 기반 통합 에이전트&lt;/b&gt;가 전부 같은 이름을 쓴다. 이 글에서 말하는 건 세 번째, 지금 버전이다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-sourcepos=&quot;19:1-19:36;804-839&quot; data-ke-size=&quot;size26&quot;&gt;Codex &amp;mdash; 속도와 토큰 효율에 최적화된 위임형 에이전트&lt;/h2&gt;
&lt;p data-sourcepos=&quot;21:1-21:86;841-926&quot; data-ke-size=&quot;size16&quot;&gt;Codex는 하나의 제품이라기보다 &lt;b&gt;여러 표면(surface)의 묶음&lt;/b&gt;에 가깝다. 하나의 계정&amp;middot;모델&amp;middot;엔진을 공유하는 여러 진입점을 우산처럼 아우른다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;23:1-27:30;928-1148&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;23:1-23:70;928-997&quot;&gt;&lt;b&gt;CLI(터미널)&lt;/b&gt;: Rust로 작성된 오픈소스, GitHub 스타 6.7만 개 이상, npm/Homebrew로 설치&lt;/li&gt;
&lt;li data-sourcepos=&quot;24:1-24:30;998-1027&quot;&gt;&lt;b&gt;데스크톱 앱&lt;/b&gt;: macOS / Windows&lt;/li&gt;
&lt;li data-sourcepos=&quot;25:1-25:51;1028-1078&quot;&gt;&lt;b&gt;IDE 확장&lt;/b&gt;: VS Code, Cursor, Windsurf, JetBrains&lt;/li&gt;
&lt;li data-sourcepos=&quot;26:1-26:40;1079-1118&quot;&gt;&lt;b&gt;ChatGPT 내 클라우드 에이전트&lt;/b&gt;: 작업을 클라우드에 위임&lt;/li&gt;
&lt;li data-sourcepos=&quot;27:1-27:30;1119-1148&quot;&gt;&lt;b&gt;GitHub 봇, 컴퓨터 유즈(화면 조작)&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-sourcepos=&quot;29:1-29:145;1150-1294&quot; data-ke-size=&quot;size16&quot;&gt;현재 세대는 &lt;b&gt;GPT-5.5&lt;/b&gt; 기반이다. GPT-4.5 이후 OpenAI가 처음으로 완전히 재훈련한 모델로, 2026년 4월 23일 '에이전트 우선' 훈련을 명시하며 나왔다. 출시 시점 기준 매주 약 400만 명의 개발자가 Codex를 쓰고 있다고 한다.&lt;/p&gt;
&lt;p data-sourcepos=&quot;31:1-31:234;1296-1529&quot; data-ke-size=&quot;size16&quot;&gt;동작 방식의 특징은 세 가지로 요약된다. 첫째, &lt;b&gt;클라우드 샌드박스&lt;/b&gt;에서 저장소의 복제 스냅샷 위에 작업한다(그래서 저장소가 활발히 바뀌는 중이면 드리프트가 생길 수 있다). 둘째, 매니저-워커 구조의 &lt;b&gt;서브에이전트&lt;/b&gt;를 최대 8개까지 병렬로 돌린다. 셋째, 설정은 AGENTS.md 파일로 하는데 기본 상한이 32 KiB이고 초과분은 조용히 잘리므로, 지시 세트가 크면 파일을 하위 디렉터리로 쪼개야 한다.&lt;/p&gt;
&lt;p data-sourcepos=&quot;33:1-33:35;1531-1565&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;요금&lt;/b&gt;은 별도 구독 없이 ChatGPT 플랜에 번들된다.&lt;/p&gt;
&lt;div data-sourcepos=&quot;35:1-40:65;1567-1800&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; border: 1px solid #ddd;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;플랜가격&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;Codex&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;사용량&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Plus&lt;/td&gt;
&lt;td&gt;$20/월&lt;/td&gt;
&lt;td&gt;GPT-5.5 기준 5시간 창당 15~80 메시지 (가벼운 개인용)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pro 5x&lt;/td&gt;
&lt;td&gt;$100/월&lt;/td&gt;
&lt;td&gt;Plus 대비 5배 한도&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pro 20x&lt;/td&gt;
&lt;td&gt;$200/월&lt;/td&gt;
&lt;td&gt;Plus 대비 20배 한도&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API 키&lt;/td&gt;
&lt;td&gt;토큰 과금&lt;/td&gt;
&lt;td&gt;gpt-5.3-codex 기준 입력 $1.75 / 출력 $14 (100만 토큰)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p data-sourcepos=&quot;42:1-42:48;1802-1849&quot; data-ke-size=&quot;size16&quot;&gt;2026년 4월 2일부터 메시지 단위 과금에서 API 스타일의 토큰 요율로 전환됐다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-sourcepos=&quot;46:1-46:44;1856-1899&quot; data-ke-size=&quot;size26&quot;&gt;Claude Code &amp;mdash; 깊은 추론과 통제에 최적화된 로컬 우선 에이전트&lt;/h2&gt;
&lt;p data-sourcepos=&quot;48:1-48:151;1901-2051&quot; data-ke-size=&quot;size16&quot;&gt;Claude Code도 터미널 기반 에이전트로, 다단계 작업을 하나의 지시로 처리한다는 점은 같다. 다만 지향점이 다르다. Codex가 접근성과 비동기 실행에 무게를 둔다면, Claude Code는 &lt;b&gt;깊이(depth)와 데이터에 대한 통제(control)&lt;/b&gt; 쪽이다.&lt;/p&gt;
&lt;p data-sourcepos=&quot;50:1-50:180;2053-2232&quot; data-ke-size=&quot;size16&quot;&gt;기본 모델은 &lt;b&gt;Opus 4.8&lt;/b&gt;(2026년 5월 28일 출시)이고, Claude 5 계열을 세션별로 바꿔 쓸 수 있다. 기본 1M 토큰 컨텍스트, 최대 12.8만 토큰 출력, 적응형 사고를 지원한다. Anthropic은 이 모델이 &quot;자신이 작성한 코드의 결함을 그냥 지나칠 확률이 이전 대비 약 4배 낮다&quot;고 밝혔다.&lt;/p&gt;
&lt;p data-sourcepos=&quot;52:1-52:315;2234-2548&quot; data-ke-size=&quot;size16&quot;&gt;Codex와 대비되는 핵심 세 가지는 이렇다. 첫째, &lt;b&gt;실제 파일시스템에 직접 접근&lt;/b&gt;한다. 스냅샷이 아니라 실제 저장소 상태 위에서 동작하니 드리프트 걱정이 없다. 둘째, 멀티 에이전트가 &lt;b&gt;Agent Teams&lt;/b&gt; 형태다. 팀원 에이전트들이 공유 작업 목록과 메일박스로 서로 직접 소통한다(Codex의 단일 오케스트레이터 보고 방식과 대비된다). 셋째, 설정 파일 CLAUDE.md가 &lt;b&gt;계층형&lt;/b&gt;이다. 전역에서 코딩 표준을 잡고, 프로젝트 수준에서 제한하고, 모듈 수준에서 오버라이드를 허용할 수 있다. AGENTS.md는 이를 기본 지원하지 않는다.&lt;/p&gt;
&lt;p data-sourcepos=&quot;54:1-54:110;2550-2659&quot; data-ke-size=&quot;size16&quot;&gt;거버넌스 관점에선 26개의 라이프사이클 훅으로 깊은 커스터마이징이 가능하고(Codex엔 직접 대응물이 없다), 리서치 프리뷰인 Workflows는 대규모 엔터프라이즈 코드 마이그레이션을 겨냥한다.&lt;/p&gt;
&lt;p data-sourcepos=&quot;56:1-56:48;2661-2708&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;요금&lt;/b&gt;은 Claude 구독에 번들되며, 인증 경로가 두 가지라는 점이 핵심이다.&lt;/p&gt;
&lt;div data-sourcepos=&quot;58:1-63:66;2710-2910&quot;&gt;&lt;br /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; border: 1px solid #ddd;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;경로&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;가격&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;특징&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pro&lt;/td&gt;
&lt;td&gt;$20/월&lt;/td&gt;
&lt;td&gt;정액, 토큰 미터링 없음, 사용 상한 존재&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Max 5x&lt;/td&gt;
&lt;td&gt;$100/월&lt;/td&gt;
&lt;td&gt;Pro의 5배&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Max 20x&lt;/td&gt;
&lt;td&gt;$200/월&lt;/td&gt;
&lt;td&gt;Pro의 20배&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API 키&lt;/td&gt;
&lt;td&gt;토큰 과금&lt;/td&gt;
&lt;td&gt;Opus 4.8 기준 입력 $5 / 출력 $25 (100만 토큰). CI&amp;middot;자동화용&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p data-sourcepos=&quot;65:1-65:155;2912-3066&quot; data-ke-size=&quot;size16&quot;&gt;한 가지 운영상 주의점. 확장 사고(extended thinking)가 기본 활성이고 사고 토큰은 출력 요율(입력의 5배)로 과금되므로, 단순 작업에선 낭비가 된다. MAX_THINKING_TOKENS로 상한을 낮추거나 /effort로 조절하는 습관을 들이는 게 좋다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-sourcepos=&quot;69:1-69:9;3073-3081&quot; data-ke-size=&quot;size26&quot;&gt;정면 비교&lt;/h2&gt;
&lt;h3 data-sourcepos=&quot;71:1-71:26;3083-3108&quot; data-ke-size=&quot;size23&quot;&gt;벤치마크 &amp;mdash; 벤치마크마다 승자가 다르다&lt;/h3&gt;
&lt;p data-sourcepos=&quot;73:1-73:81;3110-3190&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;중요한 전제 하나&lt;/b&gt;. 아래 수치 대부분은 벤더가 자체 보고한 값이고, 스캐폴드 차이에 따라 흔들린다. 작은 격차는 동점으로 보는 게 맞다.&lt;/p&gt;
&lt;div data-sourcepos=&quot;75:1-79:53;3192-3427&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; border: 1px solid #ddd;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;경로&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;Codex (GPT-5.5)&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;Claude Code (Opus)&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;승자&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SWE-bench Verified&lt;/td&gt;
&lt;td&gt;~88.7%&lt;/td&gt;
&lt;td&gt;88.6% (4.8)&lt;/td&gt;
&lt;td&gt;사실상 동점&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SWE-bench Pro (더 어려움)&lt;/td&gt;
&lt;td&gt;58.6%&lt;/td&gt;
&lt;td&gt;69.2% (4.8)&lt;/td&gt;
&lt;td&gt;Claude&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Terminal-Bench 2.0&lt;/td&gt;
&lt;td&gt;82.7%&lt;/td&gt;
&lt;td&gt;69.4% (4.7)&lt;/td&gt;
&lt;td&gt;Codex&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p data-sourcepos=&quot;81:1-81:149;3429-3577&quot; data-ke-size=&quot;size16&quot;&gt;참고로 &quot;88.7% Verified, 1위&quot;라는 널리 인용되는 수치는 OpenAI 공식 발표가 아니라 애그리게이터 리더보드에서 나온 것이라 조심해서 봐야 한다. 정리하면, 터미널&amp;middot;시스템 작업은 Codex가, 복잡한 멀티파일 실무 문제는 Claude가 강한 경향이다.&lt;/p&gt;
&lt;p data-sourcepos=&quot;81:1-81:149;3429-3577&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-sourcepos=&quot;83:1-83:30;3579-3608&quot; data-ke-size=&quot;size23&quot;&gt;토큰 효율과 비용 &amp;mdash; Codex의 결정적 강점&lt;/h3&gt;
&lt;p data-sourcepos=&quot;85:1-85:65;3610-3674&quot; data-ke-size=&quot;size16&quot;&gt;실무 도입에서 가장 크게 작용하는 지점이 여기다. Codex는 토큰 효율에 맞춰 튜닝돼 있고, 그 격차가 꽤 크다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;87:1-89:96;3676-3941&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;87:1-87:91;3676-3766&quot;&gt;&lt;b&gt;토큰 사용량&lt;/b&gt;: Figma-to-code 벤치마크에서 Codex는 약 150만 토큰, Claude Code는 약 620만 토큰. 대략 &lt;b&gt;4배 차이&lt;/b&gt;.&lt;/li&gt;
&lt;li data-sourcepos=&quot;88:1-88:79;3767-3845&quot;&gt;&lt;b&gt;실비용 사례&lt;/b&gt;: 문서화된 Express.js 리팩터 작업에서 Codex는 약 $15, Claude Code는 약 $155가 들었다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;89:1-89:96;3846-3941&quot;&gt;&lt;b&gt;품질이라는 대가&lt;/b&gt;: 대신 같은 리팩터의 블라인드 품질 평가에서는 Claude Code 출력이 67%, Codex가 25% 비율로 &quot;더 깨끗하다&quot;는 평가를 받았다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-sourcepos=&quot;91:1-91:63;3943-4005&quot; data-ke-size=&quot;size16&quot;&gt;한마디로 &quot;같은 결과에 Codex가 훨씬 싸다. 대신 첫 결과물의 품질은 Claude가 낫다&quot;는 트레이드오프다.&lt;/p&gt;
&lt;p data-sourcepos=&quot;91:1-91:63;3943-4005&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-sourcepos=&quot;93:1-93:15;4007-4021&quot; data-ke-size=&quot;size23&quot;&gt;아키텍처와 거버넌스&lt;/h3&gt;
&lt;div data-sourcepos=&quot;95:1-102:45;4023-4360&quot;&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; border: 1px solid #dddddd; height: 133px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;b&gt;구분&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;b&gt;Codex&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;b&gt;Claude Code&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;실행 위치&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;클라우드 샌드박스(복제 스냅샷)&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;로컬, 실제 파일시스템 직접 접근&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;저장소 드리프트&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;활발히 변경 중이면 발생 가능&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;실제 상태 기준이라 없음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;설정 파일&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;AGENTS.md (평면, 32KiB 상한)&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;CLAUDE.md (계층형)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;멀티 에이전트&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;서브에이전트(매니저-워커, 최대 8)&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;Agent Teams(팀원 간 직접 소통)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;샌드박싱&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;OS 커널 레벨&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;애플리케이션 레이어 훅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;공통점&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;둘 다 MCP 지원, 1M 컨텍스트, $20 진입&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;(동일)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-sourcepos=&quot;106:1-106:36;4367-4402&quot; data-ke-size=&quot;size26&quot;&gt;그래서 Java/Spring 백엔드 팀은 어떻게 써야 하나&lt;/h2&gt;
&lt;p data-sourcepos=&quot;108:1-108:46;4404-4449&quot; data-ke-size=&quot;size16&quot;&gt;우리처럼 Spring Boot 기반 백엔드를 다루는 팀 맥락에서 정리하면 이렇다.&lt;/p&gt;
&lt;p data-sourcepos=&quot;110:1-110:137;4451-4587&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;계층형 CLAUDE.md는 멀티모듈에서 확실히 유리하다.&lt;/b&gt; Maven/Gradle 멀티모듈에 전사 코딩 컨벤션까지 얹힌 구조라면, 전역/프로젝트/모듈 3단 설정이 실질적인 이점이 된다. AGENTS.md는 파일을 쪼개야 하는 제약이 있다.&lt;/p&gt;
&lt;p data-sourcepos=&quot;112:1-112:107;4589-4695&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;로컬 파일 직접 접근은 상태 동기화가 중요한 작업에서 안전하다.&lt;/b&gt; 로컬 스테이징이나 멀티 인스턴스 환경처럼 실제 상태와의 동기화가 중요한 작업에선 스냅샷 방식보다 직접 접근이 안심된다.&lt;/p&gt;
&lt;p data-sourcepos=&quot;114:1-114:129;4697-4825&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;MCP 연동은 양쪽 다 재활용 가능하다.&lt;/b&gt; 이미 Jira/Atlassian을 MCP로 붙여 쓰고 있다면, 프로젝트 스코프 .mcp.json 구성은 두 도구 모두 MCP 표준을 지원하므로 어느 쪽에서든 그대로 쓸 수 있다.&lt;/p&gt;
&lt;p data-sourcepos=&quot;116:1-116:136;4827-4962&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;비용은 작업 성격으로 나눠 통제하는 게 답이다.&lt;/b&gt; 테스트 보일러플레이트, 단순 리팩터, 마이그레이션 스윕 같은 반복 대량 작업은 Codex의 토큰 효율이 유리하다. 반면 아키텍처 설계나 리뷰 품질이 중요한 작업은 Claude 쪽이 낫다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-sourcepos=&quot;120:1-120:29;4969-4997&quot; data-ke-size=&quot;size26&quot;&gt;결론 &amp;mdash; 고르는 문제가 아니라 라우팅하는 문제&lt;/h2&gt;
&lt;p data-sourcepos=&quot;122:1-122:217;4999-5215&quot; data-ke-size=&quot;size16&quot;&gt;벤치마크는 사실상 백중세다. 실제 선택 기준은 결국 &lt;b&gt;&quot;토큰 효율(Codex) vs 코드 품질&amp;middot;통제(Claude)&quot;&lt;/b&gt; 로 수렴한다. 단순&amp;middot;반복 작업은 Codex로, 설계와 복잡한 멀티파일 작업은 Claude로 &amp;mdash; 업계의 정론도 &quot;허드렛일은 Codex로 라우팅하고, 아키텍처와 오케스트레이션은 Claude에 남겨두라&quot;는 쪽이다. 실제로 2026년 현재 잘 쓰는 개발자들은 둘 다 쓴다.&lt;/p&gt;
&lt;div data-sourcepos=&quot;124:1-130:41;5217-5445&quot;&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; border: 1px solid #ddd;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;구분&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;Codex&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;Claude Code&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;성격&lt;/td&gt;
&lt;td&gt;속도&amp;middot;토큰 효율&amp;middot;비동기 위임&lt;/td&gt;
&lt;td&gt;깊은 추론&amp;middot;코드 품질&amp;middot;통제&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;실행&lt;/td&gt;
&lt;td&gt;클라우드 샌드박스(스냅샷)&lt;/td&gt;
&lt;td&gt;로컬 직접 파일 접근&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;설정&lt;/td&gt;
&lt;td&gt;AGENTS.md(평면)&lt;/td&gt;
&lt;td&gt;CLAUDE.md(계층형)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;모델&lt;/td&gt;
&lt;td&gt;GPT-5.5&lt;/td&gt;
&lt;td&gt;Opus 4.8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;강점 작업&lt;/td&gt;
&lt;td&gt;터미널/시스템, 대량 반복&lt;/td&gt;
&lt;td&gt;멀티파일 설계, 품질&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p data-sourcepos=&quot;132:1-132:108;5447-5554&quot; data-ke-size=&quot;size16&quot;&gt;둘 중 하나를 고르는 문제가 아니라, 작업 성격에 따라 나눠 쓰는 문제다. 아직 한쪽만 쓰고 있다면, 다음 스프린트에 같은 작업을 양쪽에 한 번씩 돌려보고 체감 차이를 직접 기록해보길 권한다.&lt;/p&gt;</description>
      <category>AI/AI</category>
      <category>ai 코딩 도구</category>
      <category>Anthropic</category>
      <category>claude code</category>
      <category>claude opus</category>
      <category>codex</category>
      <category>GPT-5.5</category>
      <category>openai</category>
      <category>개발 생산성</category>
      <category>백엔드 개발</category>
      <category>코딩 에이전트</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2682</guid>
      <comments>https://xzio.tistory.com/2682#entry2682comment</comments>
      <pubDate>Wed, 8 Jul 2026 14:44:05 +0900</pubDate>
    </item>
    <item>
      <title>ChatGPT란 무엇인가? 초보자를 위한 완벽 가이드</title>
      <link>https://xzio.tistory.com/2681</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;01_hero.png&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;630&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ciNRg9/dJMcacDvLHJ/zwAFFxIqavxwesgOgvlDKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ciNRg9/dJMcacDvLHJ/zwAFFxIqavxwesgOgvlDKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ciNRg9/dJMcacDvLHJ/zwAFFxIqavxwesgOgvlDKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FciNRg9%2FdJMcacDvLHJ%2FzwAFFxIqavxwesgOgvlDKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1200&quot; height=&quot;630&quot; data-filename=&quot;01_hero.png&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;630&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI가 뭔지 모르던 내가 직접 써보고, 공부하며 정리한 솔직한 이야기&lt;br /&gt;읽는 시간 약 7분 &amp;middot; 입문자 대상&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;들어가며 &amp;mdash; 솔직히 처음엔 그냥 채팅 앱인 줄 알았다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2022년 말, 주변에서 &quot;ChatGPT 써봤어?&quot;라는 말이 자꾸 들리기 시작했다. 처음엔 별 관심 없었다. 그냥 또 잠깐 유행하는 앱이겠지 싶었다. 근데 직접 써보고 나서 생각이 완전히 바뀌었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;질문 하나를 입력했더니, 그냥 검색 결과를 복붙한 게 아니라 마치 옆에 있는 사람이 설명해주듯 답변이 나왔다. 그 순간 &quot;아, 이건 다르구나&quot;를 느꼈다. 이 글은 그때부터 내가 직접 공부하고 경험하면서 정리한 내용이다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;ChatGPT, 한 줄로 설명하자면&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ChatGPT는 OpenAI라는 미국 AI 연구 회사가 만든 &lt;b&gt;대화형 인공지능&lt;/b&gt;이다. 쉽게 말하면, 채팅창에 말을 걸면 사람처럼 대화해주는 AI다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 단순히 미리 저장된 답변을 꺼내 보여주는 게 아니다. 수백억 개의 문장을 학습해서, 질문의 맥락을 파악하고 그에 맞는 답변을 &lt;i&gt;그 자리에서 생성&lt;/i&gt;한다. 그래서 같은 질문도 상황에 따라 다르게 답변이 나오기도 한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  &lt;b&gt;GPT = Generative Pre-trained Transformer&lt;/b&gt;&lt;br /&gt;번역하면 &quot;사전 학습된 생성형 변환기&quot;. 쉽게 말해 &lt;b&gt;엄청난 양의 글을 미리 읽고 학습해서 새로운 글을 생성할 수 있는 AI&lt;/b&gt;라는 뜻이다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;작동 원리를 아주 간단히 설명하면&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;02_how_it_works.png&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;500&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bouFLX/dJMcacDvLIy/UJi4aasAzioRfI7ojNzVC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bouFLX/dJMcacDvLIy/UJi4aasAzioRfI7ojNzVC1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bouFLX/dJMcacDvLIy/UJi4aasAzioRfI7ojNzVC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbouFLX%2FdJMcacDvLIy%2FUJi4aasAzioRfI7ojNzVC1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1200&quot; height=&quot;500&quot; data-filename=&quot;02_how_it_works.png&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;500&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;검색엔진처럼 어딘가에서 답을 &quot;찾아오는&quot; 게 아니라, 매번 새롭게 &quot;만들어내는&quot; 것이 핵심이다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;ChatGPT는 어떻게 탄생했나&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;03_timeline.png&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;480&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bRQbgV/dJMcacDvLIO/Mxg8Z8erN5AFZtQlAvEL5k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bRQbgV/dJMcacDvLIO/Mxg8Z8erN5AFZtQlAvEL5k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bRQbgV/dJMcacDvLIO/Mxg8Z8erN5AFZtQlAvEL5k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRQbgV%2FdJMcacDvLIO%2FMxg8Z8erN5AFZtQlAvEL5k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1200&quot; height=&quot;480&quot; data-filename=&quot;03_timeline.png&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;480&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;table data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;연도&lt;/th&gt;
&lt;th&gt;사건&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;2015년&lt;/td&gt;
&lt;td&gt;OpenAI 설립. 일론 머스크, 샘 올트먼 등이 &quot;안전한 AI 개발&quot;을 목표로 비영리 연구소 설립&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2020년&lt;/td&gt;
&lt;td&gt;GPT-3 공개. 놀라운 성능이었지만 일반인이 쓰기엔 문턱이 높았음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2022년 11월&lt;/td&gt;
&lt;td&gt;&lt;b&gt;ChatGPT 출시.&lt;/b&gt; 채팅 형태의 인터페이스로 누구나 쉽게 사용 가능. 출시 5일 만에 100만 유저 돌파&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2023년&lt;/td&gt;
&lt;td&gt;GPT-4 출시. 이미지 인식, 플러그인, 음성 대화까지 기능 대폭 확장&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;현재&lt;/td&gt;
&lt;td&gt;전 세계 월간 활성 사용자 1억 명 이상. 계속 발전 중&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;내가 실제로 써본 방법들&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;04_screenshot.png&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;700&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MU8rS/dJMcaijns0B/4KnLGVU9AQykkuK2TCA8Ok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MU8rS/dJMcaijns0B/4KnLGVU9AQykkuK2TCA8Ok/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MU8rS/dJMcaijns0B/4KnLGVU9AQykkuK2TCA8Ok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMU8rS%2FdJMcaijns0B%2F4KnLGVU9AQykkuK2TCA8Ok%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1200&quot; height=&quot;700&quot; data-filename=&quot;04_screenshot.png&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;700&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음엔 &quot;이걸 어디다 쓰지?&quot; 싶었는데, 쓰다 보니 생각보다 쓸 곳이 많았다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;✏️ 글쓰기 보조&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이메일 초안, 보고서, 블로그 글 구성을 잡는 데 진짜 유용하다. &quot;이 내용으로 정중한 거절 이메일 써줘&quot; 같은 식으로 쓰면 초안이 금방 나온다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  코딩 도우미&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드 오류 설명, 함수 작성, 언어 문법 질문까지 빠르게 해결된다. 개발자가 아니어도 간단한 자동화 스크립트 정도는 뚝딱 만들 수 있다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  학습 파트너&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모르는 개념을 &quot;초등학생도 이해할 수 있게 설명해줘&quot;라고 하면 정말 잘 풀어준다. 교과서보다 훨씬 쉽게 설명해주는 경우가 많다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  번역 &amp;amp; 요약&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;긴 영문 문서를 붙여넣고 &quot;핵심만 한국어로 요약해줘&quot;하면 끝이다. 번역 품질도 충분히 실용적인 수준이다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt; ️ 여행 계획&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일정, 숙소 유형, 예산 조건을 주면 꽤 그럴듯한 여행 계획을 뽑아준다. 물론 최신 정보는 직접 확인해야 한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  아이디어 발상&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;막혔을 때 &quot;이런 주제로 아이디어 10개 줘&quot;하면 바로 나온다. 브레인스토밍 파트너로 쓰기 좋다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;무료로도 충분할까?&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;05_free_vs_plus.png&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;580&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cQ9bbu/dJMcacDvLI4/q5NiFSKIXPzIT41X3Zp6L0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cQ9bbu/dJMcacDvLI4/q5NiFSKIXPzIT41X3Zp6L0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cQ9bbu/dJMcacDvLI4/q5NiFSKIXPzIT41X3Zp6L0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcQ9bbu%2FdJMcacDvLI4%2Fq5NiFSKIXPzIT41X3Zp6L0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1200&quot; height=&quot;580&quot; data-filename=&quot;05_free_vs_plus.png&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;580&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;table data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;항목&lt;/th&gt;
&lt;th&gt;무료 버전&lt;/th&gt;
&lt;th&gt;유료 버전 (Plus, $20/월)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;사용 모델&lt;/td&gt;
&lt;td&gt;GPT-4o mini&lt;/td&gt;
&lt;td&gt;GPT-4o (최신)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;사용량 제한&lt;/td&gt;
&lt;td&gt;있음&lt;/td&gt;
&lt;td&gt;대폭 완화&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;이미지 생성&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅ DALL&amp;middot;E 3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;파일 분석&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅ PDF, 엑셀 등&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;응답 속도&lt;/td&gt;
&lt;td&gt;보통&lt;/td&gt;
&lt;td&gt;우선 접속, 빠름&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;음성 대화&lt;/td&gt;
&lt;td&gt;제한적&lt;/td&gt;
&lt;td&gt;✅ 고급 음성&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음 시작한다면 &lt;b&gt;무료 버전으로도 충분히 체험&lt;/b&gt;해볼 수 있다. 자주 쓰게 되면 그때 업그레이드를 고민해도 전혀 늦지 않는다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;이렇게 쓰면 훨씬 잘 나온다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;써보면서 깨달은 건데, &lt;b&gt;어떻게 질문하느냐가 답변 품질을 결정&lt;/b&gt;한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 역할을 줘라&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;❌ &quot;도쿄 여행 일정 짜줘&quot;&lt;br /&gt;✅ &quot;너는 10년 경력의 여행 플래너야. 예산 50만 원으로 도쿄 3박 4일 일정을 짜줘. 대중교통 위주로.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 조건을 구체적으로&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;❌ &quot;글 써줘&quot;&lt;br /&gt;✅ &quot;초등학생도 이해할 수 있게, 500자 내로, 핵심 3가지를 포함해서 써줘&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 마음에 안 들면 이어서 요청&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;이 부분을 더 쉽게 바꿔줘&quot;&lt;br /&gt;&quot;좀 더 짧게 요약해줘&quot;&lt;br /&gt;&quot;2번 항목을 더 구체적으로 설명해줘&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. 사실 확인은 직접 해야 한다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ChatGPT는 틀린 정보를 &lt;b&gt;자신 있게&lt;/b&gt; 말하기도 한다. 이를 &quot;환각(Hallucination)&quot;이라고 부른다. 중요한 사실관계는 반드시 따로 확인해야 한다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;결국 &quot;도구&quot;라는 걸 잊지 말자&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ChatGPT를 몇 달 써본 결론은 이거다. &lt;b&gt;완벽하지 않지만, 잘 쓰면 생산성을 몇 배로 올려주는 도구다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;글쓰기 속도가 빨라졌고, 모르는 개념도 빠르게 파악할 수 있게 됐다. 무엇보다 &quot;이거 어떻게 하지?&quot;라고 막힐 때 일단 물어볼 수 있는 상대가 생겼다는 게 크다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI가 내 일을 다 대신해준다는 기대보다, &lt;b&gt;내 생각을 빠르게 실행할 수 있게 도와주는 조수&lt;/b&gt;로 생각하면 딱 맞는 것 같다. 일단 한번 써보는 걸 추천한다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  &lt;b&gt;시작하는 법&lt;/b&gt;&lt;br /&gt;&lt;a href=&quot;https://chat.openai.com&quot;&gt;chat.openai.com&lt;/a&gt; 접속 &amp;rarr; 구글 계정으로 무료 가입 &amp;rarr; 채팅창에 한국어로 바로 질문하면 된다. 한국어 지원 잘 됩니다.&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <category>AI/ChatGPT</category>
      <category>AI</category>
      <category>AI입문</category>
      <category>ChatGPT</category>
      <category>ChatGPT사용법</category>
      <category>GPT4</category>
      <category>openai</category>
      <category>생성형ai</category>
      <category>인공지능</category>
      <category>챗GPT</category>
      <category>챗gpt사용법</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2681</guid>
      <comments>https://xzio.tistory.com/2681#entry2681comment</comments>
      <pubDate>Sun, 14 Jun 2026 23:26:25 +0900</pubDate>
    </item>
    <item>
      <title>GitHub spec-kit: AI 코딩 에이전트를 제대로 쓰는 법</title>
      <link>https://xzio.tistory.com/2680</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Claude Code나 Cursor를 쓰다 보면 이런 경험이 한 번씩 있을 것이다. 원하는 걸 설명했고, 에이전트가 뚝딱 코드를 짜줬는데 &amp;mdash; 컴파일도 되고, 언뜻 봐도 그럴싸한데 &amp;mdash; 막상 돌려보면 내가 원했던 게 아니다. 그렇다고 에이전트가 못 만든 게 아니다. 내가 원하는 게 뭔지 제대로 알려주지 않은 거다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GitHub에서 이 문제를 정면으로 다룬 오픈소스 툴킷을 내놨다. 이름은 &lt;b&gt;spec-kit&lt;/b&gt;이다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;spec-kit이 말하는 문제: &quot;바이브 코딩&quot;의 한계&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GitHub은 이 문제를 꽤 직접적으로 표현한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;우리는 AI 코딩 에이전트를 검색 엔진처럼 쓰고 있다. 그런데 에이전트는 검색 엔진이 아니라, 패턴 인식은 잘하지만 모호한 지시에는 취약한 '글자 그대로 받아들이는 페어 프로그래머'에 가깝다.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 나온 개념이 &lt;b&gt;Spec-Driven Development(SDD)&lt;/b&gt;, 즉 스펙 주도 개발이다. 핵심 철학은 단순하다:&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;스펙이 코드를 섬기는 게 아니라, 코드가 스펙을 섬긴다.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PRD나 스펙 문서를 구현의 참고 자료가 아니라, 구현을 생성하는 &lt;b&gt;소스&lt;/b&gt;로 삼는다는 뜻이다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;spec-kit이란 뭔가&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;spec-kit은 두 가지로 구성된다:&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;Specify CLI&lt;/b&gt; &amp;mdash; 프로젝트를 SDD 방식으로 부트스트랩해주는 커맨드라인 툴&lt;/li&gt;
&lt;li&gt;&lt;b&gt;템플릿 + 슬래시 커맨드&lt;/b&gt; &amp;mdash; AI 에이전트가 실행할 수 있는 스펙 구조, 기술 계획, 태스크 분해 방식을 정의한 파일들&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Claude Code, GitHub Copilot, Gemini CLI, Cursor, Windsurf, Codex CLI 등 30개 이상의 AI 코딩 에이전트를 지원한다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;설치 방법&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Python 3.11 이상이 필요하다. uv로 설치하는 게 공식 권장 방법이다.&lt;/p&gt;
&lt;pre class=&quot;vala&quot;&gt;&lt;code&gt;# uv 설치 (없으면)
curl -LsSf https://astral.sh/uv/install.sh | sh

# specify CLI 설치
uv tool install specify-cli --from git+https://github.com/github/spec-kit

# 프로젝트 초기화
specify init 
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;초기화하면 선택한 AI 에이전트와 플랫폼에 맞는 템플릿이 프로젝트 안에 생성된다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;핵심 워크플로: 4단계 슬래시 커맨드&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;speckit_workflow_diagram.png&quot; data-origin-width=&quot;2720&quot; data-origin-height=&quot;2480&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dsmWIl/dJMb99Ugh61/eZ2kR73dBGH7k5hAn2MEv0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dsmWIl/dJMb99Ugh61/eZ2kR73dBGH7k5hAn2MEv0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dsmWIl/dJMb99Ugh61/eZ2kR73dBGH7k5hAn2MEv0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdsmWIl%2FdJMb99Ugh61%2FeZ2kR73dBGH7k5hAn2MEv0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2720&quot; height=&quot;2480&quot; data-filename=&quot;speckit_workflow_diagram.png&quot; data-origin-width=&quot;2720&quot; data-origin-height=&quot;2480&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;spec-kit의 워크플로는 순서대로 실행하는 슬래시 커맨드로 구성된다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1단계: /speckit.constitution&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트의 불변 원칙을 세운다. 아키텍처 결정, 코딩 컨벤션, 보안 요구사항 같은 &quot;무슨 일이 있어도 바꾸지 않을 것들&quot;을 명문화한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2단계: /speckit.specify&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;무엇을(what)&lt;/b&gt; 만들 것인지, &lt;b&gt;왜(why)&lt;/b&gt; 만드는 건지를 기술한다. 이 단계에서는 기술 스택을 결정하지 않는다. 요구사항에 집중한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3단계: /speckit.plan&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기술 계획을 세운다. 여기서 스택, 아키텍처, 구현 방향을 결정한다. specify에서 나온 &quot;what&quot;을 기반으로 &quot;how&quot;를 설계한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4단계: /speckit.tasks &amp;rarr; /speckit.implement&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;계획을 AI 에이전트가 하나씩 실행할 수 있는 작은 태스크 단위로 쪼갠다. 그리고 에이전트가 태스크를 순서대로 구현한다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;이게 기존 방식과 뭐가 다른가&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구분 기존 방식 (바이브 코딩) spec-kit (SDD)&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;시작점&lt;/td&gt;
&lt;td&gt;프롬프트&lt;/td&gt;
&lt;td&gt;스펙 문서&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;에이전트 역할&lt;/td&gt;
&lt;td&gt;프롬프트 해석&lt;/td&gt;
&lt;td&gt;스펙 실행&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;오류 원인&lt;/td&gt;
&lt;td&gt;의도 전달 실패&lt;/td&gt;
&lt;td&gt;스펙 불일치&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;변경 비용&lt;/td&gt;
&lt;td&gt;높음 (맥락 재설명)&lt;/td&gt;
&lt;td&gt;낮음 (스펙 수정)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 유용한 시나리오는 세 가지라고 GitHub이 강조한다:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;그린필드 프로젝트&lt;/b&gt;: 처음부터 SDD로 시작하면 방향이 흔들리지 않는다&lt;/li&gt;
&lt;li&gt;&lt;b&gt;기존 시스템의 새 기능 추가&lt;/b&gt;: 기존 코드베이스의 맥락을 스펙에 담아 에이전트에게 전달한다&lt;/li&gt;
&lt;li&gt;&lt;b&gt;레거시 현대화&lt;/b&gt;: 기존 코드가 &quot;무엇을 해야 하는지&quot;를 스펙으로 먼저 정리한 뒤 마이그레이션&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;실제로 써보니&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;솔직히 처음엔 &quot;그냥 문서 잘 쓰라는 거 아닌가?&quot; 싶었다. 그런데 써보면 미묘하게 다르다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에 Claude Code에 &quot;이런 앱 만들어줘&quot;라고 하면 에이전트가 스스로 가정을 채운다. 내가 생각하는 아키텍처가 아닐 수도 있고, 내가 원하는 라이브러리를 안 쓸 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;spec-kit 방식은 먼저 스펙을 내가 직접 정의하고, 에이전트는 그 스펙 안에서만 움직인다. &quot;무엇을 만들지&quot;가 명확하게 고정되니 에이전트가 엉뚱한 방향으로 가는 일이 줄어든다. 태스크 단위로 나눠서 하나씩 구현하는 것도, 긴 컨텍스트에서 에이전트가 길을 잃는 걸 방지하는 데 효과적이다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;참고&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;GitHub 레포: &lt;a href=&quot;https://github.com/github/spec-kit&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;github/spec-kit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;공식 블로그: &lt;a href=&quot;https://github.blog/ai-and-ml/generative-ai/spec-driven-development-with-ai-get-started-with-a-new-open-source-toolkit/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Spec-driven development with AI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;현재 GitHub 스타 111k+, 릴리즈 55회 이상 (2026년 6월 기준)&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>AI/AI</category>
      <category>AI에이전트</category>
      <category>AI코딩</category>
      <category>claudecode</category>
      <category>cursor</category>
      <category>GeminiCLI</category>
      <category>Github</category>
      <category>githubcopilot</category>
      <category>SDD</category>
      <category>spec-kit</category>
      <category>스펙주도개발</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2680</guid>
      <comments>https://xzio.tistory.com/2680#entry2680comment</comments>
      <pubDate>Sun, 14 Jun 2026 22:28:11 +0900</pubDate>
    </item>
    <item>
      <title>Claude Code + CodeGraph: AI 코딩 비용을 절반으로 줄이는 방법</title>
      <link>https://xzio.tistory.com/2679</link>
      <description>&lt;div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Claude Code를 쓰다 보면 항상 마주치는 장면이 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;pre class=&quot;bash&quot; style=&quot;color: #eaecf0;&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;⏺ Explore(&quot;인증 미들웨어가 JWT를 어떻게 검증하지?&quot;)
⎿ Done (52 tool uses &amp;middot; 89.4k tokens &amp;middot; 1m 37s)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;질문 하나 던졌을 뿐인데 Claude는 수십 번 파일을 뒤지고, 토큰을 잔뜩 태우고, 거의 2분이 지나서야 겨우 실제 작업을 시작한다. 이게 매 세션마다 반복된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 문제를 깔끔하게 해결해 주는 오픈소스 도구를 발견했다. 바로 &lt;b&gt;CodeGraph&lt;/b&gt;다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;문제의 본질: &quot;탐색 세금&quot;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Claude Code는 코드베이스에 대한 기억이 없다. 그래서 매번 Explore 에이전트를 띄워서 grep, glob, Read 호출로 파일을 샅샅이 뒤진다. 이 툴 호출 하나하나가 토큰을 소모하고, 파일을 스캔할수록 컨텍스트 윈도우가 줄어든다. &lt;span data-state=&quot;closed&quot;&gt;&lt;a href=&quot;https://medium.com/@me_82386/i-cut-my-claude-code-api-costs-by-40-with-one-tool-12cf4306a1ab&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;&lt;span&gt;Medium&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제로 측정해 봤더니 하나의 아키텍처 질문에 60번 툴 호출, 157,800 토큰, 거의 2분이 필요했다. 근데 이 중 대부분은 &quot;어디에 뭐가 있는지&quot; 찾는 탐색 작업이지, 실제 코드 분석이 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI 코딩 에이전트가 코드베이스 아키텍처에 대한 질문을 받으면, 탐색 하위 에이전트들을 생성해서 심볼 정의를 찾기 위해 grep, 패턴으로 파일을 찾기 위해 glob, 파일 내용을 처리하기 위해 Read를 호출한다. 이 호출들은 각각 별도의 툴 인보케이션으로 토큰 비용이 발생하고 레이턴시를 추가한다. &lt;span data-state=&quot;closed&quot;&gt;&lt;a href=&quot;https://tosea.ai/blog/codegraph-claude-code-cursor-guide-2026&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;&lt;span&gt;Tosea&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이게 바로 **탐색 세금(discovery tax)**이다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;mcp-app-modal-toolu_011U3TtAagKDViphJcYLTriQ&quot;&gt;
&lt;div id=&quot;mcp-app-modal-frame-toolu_011U3TtAagKDViphJcYLTriQ&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;without_codegraph_flow.png&quot; data-origin-width=&quot;2720&quot; data-origin-height=&quot;1680&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKJV6l/dJMb997NASw/0mMK8zo9SkHFwqL8R9hMGK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKJV6l/dJMb997NASw/0mMK8zo9SkHFwqL8R9hMGK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKJV6l/dJMb997NASw/0mMK8zo9SkHFwqL8R9hMGK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKJV6l%2FdJMb997NASw%2F0mMK8zo9SkHFwqL8R9hMGK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2720&quot; height=&quot;1680&quot; data-filename=&quot;without_codegraph_flow.png&quot; data-origin-width=&quot;2720&quot; data-origin-height=&quot;1680&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;mcp-app-container-toolu_011U3TtAagKDViphJcYLTriQ&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;CodeGraph란 무엇인가?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CodeGraph는 코드베이스의 사전 인덱싱된 지식 그래프(심볼, 콜 그래프, 임포트, 상속, 코드 구조)를 빌드하는 오픈소스 도구다. 에이전트가 파일을 하나씩 스캔하는 대신 그 그래프를 한 번에 쿼리한다. Claude Code용 MCP 서버로 실행되며, MIT 라이센스, 19개 이상의 언어를 지원하고, 100% 로컬에서 동작한다. &lt;span data-state=&quot;closed&quot;&gt;&lt;a href=&quot;https://dev.to/arshtechpro/codegraph-stop-your-ai-agent-from-grepping-the-same-files-50-times-3bgm&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;&lt;span&gt;DEV Community&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;핵심 아이디어는 단순하다. 에이전트가 탐색하기 전에 &lt;b&gt;지도를 먼저 건네주는 것&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CodeGraph는 로컬 코드 인텔리전스 라이브러리 + CLI + MCP 서버로, tree-sitter로 코드를 파싱하고 심볼/엣지/파일을 SQLite(FTS5)에 저장한 뒤, MCP를 통해 AI 에이전트에게 지식 그래프를 노출한다. 프로젝트별 데이터는 .codegraph/ 폴더에 저장되며, 추출은 LLM 요약이 아닌 AST 기반으로 결정적(deterministic)이다. &lt;span data-state=&quot;closed&quot;&gt;&lt;a href=&quot;https://github.com/colbymchenry/codegraph/blob/main/CLAUDE.md&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;&lt;span&gt;GitHub&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;codegraph_architecture.png&quot; data-origin-width=&quot;2720&quot; data-origin-height=&quot;1960&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5HWgE/dJMcahkwN0q/WRIn2YQskvtbwzrmsJpE91/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5HWgE/dJMcahkwN0q/WRIn2YQskvtbwzrmsJpE91/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5HWgE/dJMcahkwN0q/WRIn2YQskvtbwzrmsJpE91/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5HWgE%2FdJMcahkwN0q%2FWRIn2YQskvtbwzrmsJpE91%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2720&quot; height=&quot;1960&quot; data-filename=&quot;codegraph_architecture.png&quot; data-origin-width=&quot;2720&quot; data-origin-height=&quot;1960&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;div id=&quot;mcp-app-modal-toolu_01Laidvj7TbyPz4FC63nRUwN&quot;&gt;
&lt;div id=&quot;mcp-app-modal-frame-toolu_01Laidvj7TbyPz4FC63nRUwN&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;mcp-app-container-toolu_01Laidvj7TbyPz4FC63nRUwN&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;실제 성능 차이&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;7개의 실제 오픈소스 코드베이스, 7가지 언어를 대상으로 CodeGraph 유무를 비교한 공식 벤치마크 결과(Claude Opus 4.8, 2026년 6월 재검증): 평균 16% 비용 절감, 47% 토큰 감소, 22% 속도 향상, 58% 툴 호출 감소. &lt;span data-state=&quot;closed&quot;&gt;&lt;a href=&quot;https://github.com/colbymchenry/codegraph&quot;&gt;&lt;span&gt;&lt;span&gt;GitHub&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;03_benchmark_chart.svg&quot; data-origin-width=&quot;680&quot; data-origin-height=&quot;380&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Dk0vL/dJMcahEJr1T/JDOrhLxdkVvkAi5Dmakl1K/tfile.svg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Dk0vL/dJMcahEJr1T/JDOrhLxdkVvkAi5Dmakl1K/tfile.svg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Dk0vL/dJMcahEJr1T/JDOrhLxdkVvkAi5Dmakl1K/tfile.svg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDk0vL%2FdJMcahEJr1T%2FJDOrhLxdkVvkAi5Dmakl1K%2Ftfile.svg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;680&quot; height=&quot;380&quot; data-filename=&quot;03_benchmark_chart.svg&quot; data-origin-width=&quot;680&quot; data-origin-height=&quot;380&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;div id=&quot;mcp-app-modal-toolu_01Rvsqsg9qvf7Ecmkf7KvPKw&quot;&gt;
&lt;div id=&quot;mcp-app-modal-frame-toolu_01Rvsqsg9qvf7Ecmkf7KvPKw&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;mcp-app-container-toolu_01Rvsqsg9qvf7Ecmkf7KvPKw&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 VS Code 환경에서는 툴 호출이 최대 81%까지 줄어들었는데, 대형 레포일수록 파일 탐색 오버헤드가 크기 때문이다. 반대로 100개 미만의 소규모 프로젝트에서는 효과가 미미하다. &lt;span data-state=&quot;closed&quot;&gt;&lt;a href=&quot;https://dev.to/jovan_chan_9500711396d4e6/codegraph-setup-guide-2026-cut-claude-code-tool-calls-by-58-41ln&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;&lt;span&gt;DEV Community&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;설치 방법 (3줄이면 끝)&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;bash&lt;/div&gt;
&lt;div&gt;
&lt;pre class=&quot;properties&quot; style=&quot;color: #eaecf0;&quot;&gt;&lt;code&gt;# 1. 설치
npm install -g @colbymchenry/codegraph

# 2. 프로젝트 인덱싱
cd my-project
codegraph init

# 3. 상태 확인
codegraph status&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CodeGraph v0.9.9는 프로그래매틱 라이브러리 사용을 위해 Node.js 22+가 필요하다. CLI와 MCP 서버는 자체 런타임을 번들링하므로, 글로벌 설치 시 Node 버전을 별도로 관리할 필요가 없다. &lt;span data-state=&quot;closed&quot;&gt;&lt;a href=&quot;https://dev.to/jovan_chan_9500711396d4e6/codegraph-setup-guide-2026-cut-claude-code-tool-calls-by-58-41ln&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;&lt;span&gt;DEV Community&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Claude Code에서 MCP 서버를 활성화하려면 .claude/settings.json에 다음을 추가하면 된다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;json&lt;/div&gt;
&lt;div&gt;
&lt;pre class=&quot;javascript&quot; style=&quot;color: #eaecf0;&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;{
  &quot;mcpServers&quot;: {
    &quot;codegraph&quot;: {
      &quot;command&quot;: &quot;codegraph&quot;,
      &quot;args&quot;: [&quot;mcp&quot;]
    }
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;실제로 어떻게 동작하나?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CodeGraph를 적용하면 Claude Code의 흐름이 완전히 달라진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Before (CodeGraph 없이)&lt;/b&gt;:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;pre class=&quot;routeros&quot; style=&quot;color: #eaecf0;&quot;&gt;&lt;code&gt;⏺ Explore(&quot;JWT 검증 로직 찾기&quot;)
  &amp;rarr; grep &amp;rarr; glob &amp;rarr; Read &amp;rarr; Read &amp;rarr; Read &amp;rarr; ...
⎿ Done (52 tool uses &amp;middot; 89.4k tokens &amp;middot; 1m 37s)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;After (CodeGraph 적용)&lt;/b&gt;:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;pre class=&quot;routeros&quot; style=&quot;color: #eaecf0;&quot;&gt;&lt;code&gt;⏺ codegraph_explore(&quot;JWT validation middleware&quot;)
⎿ AuthMiddleware.kt:23 - validateToken()
  JwtService.kt:45  - verify(), decode()
  TokenRepository.kt:12 - findByToken()
Done (1 tool use &amp;middot; 3.2k tokens &amp;middot; 4s)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;codegraph_explore는 관련 없는 구현들을 시그니처로 축약하면서도, 수천 줄짜리 파일 안에 묻혀 있어도 답을 완전히 보여준다. 응답 크기가 파일 수가 아닌 답변의 내용에 맞게 최적화된다. &lt;span data-state=&quot;closed&quot;&gt;&lt;a href=&quot;https://github.com/colbymchenry/codegraph&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;&lt;span&gt;GitHub&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;언제 쓰면 좋을까?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CodeGraph는 토큰 소모와 툴 호출 빈도라는 AI 지원 개발의 핵심 문제를 해결한다. 100% 로컬에서 동작하기 때문에 민감한 코드가 외부로 나갈 걱정이 없다. &lt;span data-state=&quot;closed&quot;&gt;&lt;a href=&quot;https://aitoolly.com/ai-news/article/2026-05-23-codegraph-a-pre-indexed-knowledge-graph-optimizing-local-code-intelligence-for-claude-code-and-curso&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;&lt;span&gt;AIToolly&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쉽게 판단하자면, 아래 상황이면 바로 써볼 만하다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;파일이 100개 이상인 프로젝트를 Claude Code로 작업할 때&lt;/li&gt;
&lt;li&gt;&quot;Explore 에이전트가 같은 파일을 계속 반복 스캔한다&quot;는 느낌이 들 때&lt;/li&gt;
&lt;li&gt;Claude Code 비용이 부담될 때&lt;/li&gt;
&lt;li&gt;코드베이스 아키텍처 질문을 자주 던질 때&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반대로 작은 프로젝트나 파일 수가 적은 경우엔 효과가 제한적이다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;마무리&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CodeGraph의 핵심 아이디어는 생각해 보면 당연하다. AI에게 코드를 탐색하게 두는 게 아니라, 미리 인덱싱된 지식 그래프를 주는 것. Spring Boot 쓸 때 Entity를 매번 파일로 뒤지는 게 아니라 DB 스키마를 보는 것과 비슷한 개념이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI 코딩 도구의 중요한 방향을 보여주는 프로젝트다. 더 강력한 모델만이 답이 아니라, 모델에게 더 좋은 로컬 코드 컨텍스트를 제공하는 것도 하나의 답이다. &lt;span data-state=&quot;closed&quot;&gt;&lt;a href=&quot;https://knightli.com/en/2026/05/23/codegraph-local-code-knowledge-graph-ai-coding-agent/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;&lt;span&gt;KnightLi Blog&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GitHub 레포는 colbymchenry/codegraph에서 확인할 수 있다. MIT 라이센스 오픈소스다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>AI/Claude</category>
      <category>AI 개발도구</category>
      <category>AI 비용 절감</category>
      <category>AI 코딩</category>
      <category>claude code</category>
      <category>CodeGraph</category>
      <category>MCP</category>
      <category>개발자 도구</category>
      <category>코드그래프</category>
      <category>클로드 코드</category>
      <category>토큰 절약</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2679</guid>
      <comments>https://xzio.tistory.com/2679#entry2679comment</comments>
      <pubDate>Sun, 14 Jun 2026 22:20:37 +0900</pubDate>
    </item>
    <item>
      <title>Claude Code용 상태 표시줄 플러그인 - 한 줄로 컨텍스트, 속도 제한, 비용 확인</title>
      <link>https://xzio.tistory.com/2678</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;a href=&quot;https://github.com/uppinote20/claude-dashboard&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/uppinote20/claude-dashboard&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2664&quot; data-origin-height=&quot;1126&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWuGAg/dJMcafr9fuu/UndypkEVigPSHyPjLxZhH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWuGAg/dJMcafr9fuu/UndypkEVigPSHyPjLxZhH1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWuGAg/dJMcafr9fuu/UndypkEVigPSHyPjLxZhH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWuGAg%2FdJMcafr9fuu%2FUndypkEVigPSHyPjLxZhH1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2664&quot; height=&quot;1126&quot; data-origin-width=&quot;2664&quot; data-origin-height=&quot;1126&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 바로 클로드에서 생성 가능합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1504&quot; data-origin-height=&quot;754&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bYp3V5/dJMcafr9fuP/petwlI4xxSqvwk6YHAYTEk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bYp3V5/dJMcafr9fuP/petwlI4xxSqvwk6YHAYTEk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bYp3V5/dJMcafr9fuP/petwlI4xxSqvwk6YHAYTEk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbYp3V5%2FdJMcafr9fuP%2FpetwlI4xxSqvwk6YHAYTEk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1504&quot; height=&quot;754&quot; data-origin-width=&quot;1504&quot; data-origin-height=&quot;754&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1198&quot; data-origin-height=&quot;562&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ay6EQ/dJMcagECPTK/N1E3u1M2UXwvVxeB9J09tk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ay6EQ/dJMcagECPTK/N1E3u1M2UXwvVxeB9J09tk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ay6EQ/dJMcagECPTK/N1E3u1M2UXwvVxeB9J09tk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAy6EQ%2FdJMcagECPTK%2FN1E3u1M2UXwvVxeB9J09tk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1198&quot; height=&quot;562&quot; data-origin-width=&quot;1198&quot; data-origin-height=&quot;562&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 디스플레이 모드도 선택하고&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1078&quot; data-origin-height=&quot;642&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b2mzmn/dJMcaa5smMB/bjKcqEkkfYtVekWS259Xqk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b2mzmn/dJMcaa5smMB/bjKcqEkkfYtVekWS259Xqk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b2mzmn/dJMcaa5smMB/bjKcqEkkfYtVekWS259Xqk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb2mzmn%2FdJMcaa5smMB%2FbjKcqEkkfYtVekWS259Xqk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1078&quot; height=&quot;642&quot; data-origin-width=&quot;1078&quot; data-origin-height=&quot;642&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 대답을 끝냅니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1576&quot; data-origin-height=&quot;162&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxBUrn/dJMcagdx3MZ/8MQhHWeGMaMJ5jMNog56LK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxBUrn/dJMcagdx3MZ/8MQhHWeGMaMJ5jMNog56LK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxBUrn/dJMcagdx3MZ/8MQhHWeGMaMJ5jMNog56LK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxBUrn%2FdJMcagdx3MZ%2F8MQhHWeGMaMJ5jMNog56LK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1576&quot; height=&quot;162&quot; data-origin-width=&quot;1576&quot; data-origin-height=&quot;162&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 이와 같은 사용량을 확인 할 수 있어요.&lt;/p&gt;</description>
      <category>AI/Claude</category>
      <category>claude code</category>
      <category>클로드 코드</category>
      <category>플러그인</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2678</guid>
      <comments>https://xzio.tistory.com/2678#entry2678comment</comments>
      <pubDate>Fri, 27 Feb 2026 18:29:29 +0900</pubDate>
    </item>
    <item>
      <title>소스트리 강제 푸시(force push)</title>
      <link>https://xzio.tistory.com/2674</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;main 브랜치에 잘 못 머지하여, 소스트리로 이 전 상태로 되돌리는 방법입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;macOS 기준입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설정 &amp;gt; 고급에서 강제 푸시를 허용 체크&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;843&quot; data-origin-height=&quot;491&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AzOnc/dJMcaf6pdiO/UMFjdaotmD3hsJfLCppF3K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AzOnc/dJMcaf6pdiO/UMFjdaotmD3hsJfLCppF3K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AzOnc/dJMcaf6pdiO/UMFjdaotmD3hsJfLCppF3K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAzOnc%2FdJMcaf6pdiO%2FUMFjdaotmD3hsJfLCppF3K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;843&quot; height=&quot;491&quot; data-origin-width=&quot;843&quot; data-origin-height=&quot;491&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;9e56a49 잘 못 푸시하여 &quot;b597627&quot;로 원복하려고 합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;404&quot; data-origin-height=&quot;202&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dkO1Rn/dJMcadHt8xD/lujbhxANo1QsLT4mYFMQWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dkO1Rn/dJMcadHt8xD/lujbhxANo1QsLT4mYFMQWk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dkO1Rn/dJMcadHt8xD/lujbhxANo1QsLT4mYFMQWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdkO1Rn%2FdJMcadHt8xD%2FlujbhxANo1QsLT4mYFMQWk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;404&quot; height=&quot;202&quot; data-origin-width=&quot;404&quot; data-origin-height=&quot;202&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;되돌리고자 하는 커밋을 오른쪽 마우스를 클릭하여, &quot;이 커밋으로 초기화&quot; 클릭&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;473&quot; data-origin-height=&quot;522&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/p80y0/dJMcagqHFyW/UcTrq9eqf1rqNe8xnlb0Z0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/p80y0/dJMcagqHFyW/UcTrq9eqf1rqNe8xnlb0Z0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/p80y0/dJMcagqHFyW/UcTrq9eqf1rqNe8xnlb0Z0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fp80y0%2FdJMcagqHFyW%2FUcTrq9eqf1rqNe8xnlb0Z0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;473&quot; height=&quot;522&quot; data-origin-width=&quot;473&quot; data-origin-height=&quot;522&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용중인 모드에서 &quot;Hard - 모든 작업 상태 내 변경 사항을 버림&quot;을 선택 후, 확인&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;403&quot; data-origin-height=&quot;158&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GX0C0/dJMcaaD1Fx0/xboB0RIByIKKDcV6oMQhHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GX0C0/dJMcaaD1Fx0/xboB0RIByIKKDcV6oMQhHk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GX0C0/dJMcaaD1Fx0/xboB0RIByIKKDcV6oMQhHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGX0C0%2FdJMcaaD1Fx0%2FxboB0RIByIKKDcV6oMQhHk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;403&quot; height=&quot;158&quot; data-origin-width=&quot;403&quot; data-origin-height=&quot;158&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 1 아래 화살표가 표시되지만 푸시 버튼을 클릭&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;590&quot; data-origin-height=&quot;257&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bQCZdR/dJMb99LSmE0/sqsE0SkkXQQZPNSTkZvhxK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bQCZdR/dJMb99LSmE0/sqsE0SkkXQQZPNSTkZvhxK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bQCZdR/dJMb99LSmE0/sqsE0SkkXQQZPNSTkZvhxK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbQCZdR%2FdJMb99LSmE0%2FsqsE0SkkXQQZPNSTkZvhxK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;590&quot; height=&quot;257&quot; data-origin-width=&quot;590&quot; data-origin-height=&quot;257&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;강제 푸시&quot; 체크박스를 선택하고 확인 버튼 클릭&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;642&quot; data-origin-height=&quot;264&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cs5Zzv/dJMcahC8Fs5/1rkelqQSrwnoH0WJIqtqs1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cs5Zzv/dJMcahC8Fs5/1rkelqQSrwnoH0WJIqtqs1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cs5Zzv/dJMcahC8Fs5/1rkelqQSrwnoH0WJIqtqs1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcs5Zzv%2FdJMcahC8Fs5%2F1rkelqQSrwnoH0WJIqtqs1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;642&quot; height=&quot;264&quot; data-origin-width=&quot;642&quot; data-origin-height=&quot;264&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 예전 상태로 돌아가는 것을 확인 할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;408&quot; data-origin-height=&quot;187&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b9yO0B/dJMb99ZqNW4/jKKffnkmtaYT0wJCrBaZfk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b9yO0B/dJMb99ZqNW4/jKKffnkmtaYT0wJCrBaZfk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b9yO0B/dJMb99ZqNW4/jKKffnkmtaYT0wJCrBaZfk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb9yO0B%2FdJMb99ZqNW4%2FjKKffnkmtaYT0wJCrBaZfk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;408&quot; height=&quot;187&quot; data-origin-width=&quot;408&quot; data-origin-height=&quot;187&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>형상관리/Bitbucket</category>
      <category>Force Push</category>
      <category>GIT</category>
      <category>sourcetree</category>
      <category>강제 푸시</category>
      <category>강제푸시</category>
      <category>소스트리</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2674</guid>
      <comments>https://xzio.tistory.com/2674#entry2674comment</comments>
      <pubDate>Thu, 15 Jan 2026 11:28:58 +0900</pubDate>
    </item>
    <item>
      <title>React npx create-react-app npm error code EEXIST</title>
      <link>https://xzio.tistory.com/2672</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;img.png&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;1000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/040Wx/btsQR3RYI0K/Sff5hr4k48KWctX8qDd0k0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/040Wx/btsQR3RYI0K/Sff5hr4k48KWctX8qDd0k0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/040Wx/btsQR3RYI0K/Sff5hr4k48KWctX8qDd0k0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F040Wx%2FbtsQR3RYI0K%2FSff5hr4k48KWctX8qDd0k0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;380&quot; height=&quot;380&quot; data-filename=&quot;img.png&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;1000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;react 프로젝트를 만들기 위해 아래 명령어 입력&lt;/p&gt;
&lt;pre id=&quot;code_1758869052048&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ npx create-react-app .&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;입력시 아래와 같은 에러 발생&lt;/p&gt;
&lt;pre id=&quot;code_1758869016931&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npm error code EEXIST
npm error syscall mkdir
npm error path /Users/{유저명}/.npm/_cacache/content-v2/sha512/6c
npm error errno EEXIST
npm error Invalid response body while trying to fetch https://registry.npmjs.org/typescript: EACCES: permission denied, mkdir '/Users/greencar/.npm/_cacache/content-v2/sha512/6c'
npm error File exists: /Users/{유저명}/.npm/_cacache/content-v2/sha512/6c
npm error Remove the existing file and try again, or run npm
npm error with --force to overwrite files recklessly.
npm error A complete log of this run can be found in: /Users/{유저명}/.npm/_logs/2025-09-26T05_31_22_425Z-debug-0.log&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;node.js를 삭제하고 설치해 보았지만 동일하게 에러&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 명령어로 캐시를 삭제 시도&lt;/p&gt;
&lt;pre id=&quot;code_1758869226801&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ npm cache verify&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 명령어를 입력하면 아래와 같이 노출되는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'chown'은 'change owner'의 약자이다. 즉 해당 디렉토리 안에 있는 모든 파일에 대한 소유 권한을 그룹 ID 20, 사용자 ID 501에 할당한다는 의미였다.&lt;/p&gt;
&lt;pre id=&quot;code_1758869275706&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npm error code EACCES
npm error syscall open
npm error path /Users/{유저명}/.npm/_cacache/index-v5/02/f5/edc1bbb9c74c3776beb4a96bd21991b46bb40507edd7be8d7c966577dcb5
npm error errno -13
npm error
npm error Your cache folder contains root-owned files, due to a bug in
npm error previous versions of npm which has since been addressed.
npm error
npm error To permanently fix this problem, please run:
npm error   sudo chown -R 501:20 &quot;/Users/{유저명}/.npm&quot;
npm error A complete log of this run can be found in: /Users/{유저명}/.npm/_logs/2025-09-26T06_36_08_194Z-debug-0.log&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 알려준 명령어 입력&lt;/p&gt;
&lt;pre id=&quot;code_1758869532492&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ sudo chown -R 501:20 &quot;/Users/{유저명}/.npm&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시 &quot;npx create-react-app .&quot;을 입력하니 정상적으로 react app이 생서되었다.&lt;/p&gt;</description>
      <category>JavaScript FrontEnd/React</category>
      <category>error</category>
      <category>react</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2672</guid>
      <comments>https://xzio.tistory.com/2672#entry2672comment</comments>
      <pubDate>Fri, 26 Sep 2025 15:53:51 +0900</pubDate>
    </item>
    <item>
      <title>IntelliJ AI Pro / AI Ultimate 라이센스 구매 및 할당 방법</title>
      <link>https://xzio.tistory.com/2670</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;회사에서 jetBrains AI 사용할 기회가 생겼습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 기회에 라이센스 할당 방법 기록합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;JetBrains AI Assistant 란?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공식문서에 따르면, JetBrain AI 서비스는 고객의 데이터 보안을 최우선으로 생각하며, 고개 데이터를 수집하거나 교육 목적으로 사용할 가능성이 있는 LLM 제공업체와 협력하지 않는다고 합니다. 그리고 OpenAI 및 JetBrain 자체적으로 개발한 다양한 소규모 LLM 모델들과 함께 작동한다고 합니다.&lt;br /&gt;(주의)Intellj 2024.3 버전부터 사용할수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;라이센스&amp;nbsp;구매&amp;nbsp;및&amp;nbsp;할당&amp;nbsp;방법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JetBrains 마스터 계정으로 로그인하여 라이센스 구매&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1174&quot; data-origin-height=&quot;442&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cEp9fk/btsQpYrj9oi/Q7wPfVkURw9KNJrWsCNHH0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cEp9fk/btsQpYrj9oi/Q7wPfVkURw9KNJrWsCNHH0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cEp9fk/btsQpYrj9oi/Q7wPfVkURw9KNJrWsCNHH0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcEp9fk%2FbtsQpYrj9oi%2FQ7wPfVkURw9KNJrWsCNHH0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1174&quot; height=&quot;442&quot; data-origin-width=&quot;1174&quot; data-origin-height=&quot;442&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구매하면 아래와 같이 Transactions / Invoices에 구매 목록이 보여집니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1362&quot; data-origin-height=&quot;272&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MjZYU/btsQrnjybkY/2mC3KD46ERwsQCxvApIRf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MjZYU/btsQrnjybkY/2mC3KD46ERwsQCxvApIRf0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MjZYU/btsQrnjybkY/2mC3KD46ERwsQCxvApIRf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMjZYU%2FbtsQrnjybkY%2F2mC3KD46ERwsQCxvApIRf0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1362&quot; height=&quot;272&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1362&quot; data-origin-height=&quot;272&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주문번호를 클릭하면 아래와 같은 화면이 보여지고, &quot;View order licenses&quot; 버튼을 클릭&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;951&quot; data-origin-height=&quot;308&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c5xhQv/btsQrIORFxD/KGccwzR3iORViW0DQz2zLk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c5xhQv/btsQrIORFxD/KGccwzR3iORViW0DQz2zLk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c5xhQv/btsQrIORFxD/KGccwzR3iORViW0DQz2zLk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc5xhQv%2FbtsQrIORFxD%2FKGccwzR3iORViW0DQz2zLk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;951&quot; height=&quot;308&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;951&quot; data-origin-height=&quot;308&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라이센스ID가 보여지면 해당 구성원 계정으로 Assign 버튼으로 할당&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;831&quot; data-origin-height=&quot;283&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/020d5/btsQsgEgI4J/TekvWIHcAE2cbuUoc0K941/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/020d5/btsQsgEgI4J/TekvWIHcAE2cbuUoc0K941/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/020d5/btsQsgEgI4J/TekvWIHcAE2cbuUoc0K941/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F020d5%2FbtsQsgEgI4J%2FTekvWIHcAE2cbuUoc0K941%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;831&quot; height=&quot;283&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;831&quot; data-origin-height=&quot;283&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;586&quot; data-origin-height=&quot;261&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QppX9/btsQsgxwBSR/9dvOxI05C15NMkoqnPtDq1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QppX9/btsQsgxwBSR/9dvOxI05C15NMkoqnPtDq1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QppX9/btsQsgxwBSR/9dvOxI05C15NMkoqnPtDq1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQppX9%2FbtsQsgxwBSR%2F9dvOxI05C15NMkoqnPtDq1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;586&quot; height=&quot;261&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;586&quot; data-origin-height=&quot;261&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;261&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bsGZbN/btsQqBWZ6Bu/Nuw6IDxkkkAUyPK8VFek9K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bsGZbN/btsQqBWZ6Bu/Nuw6IDxkkkAUyPK8VFek9K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bsGZbN/btsQqBWZ6Bu/Nuw6IDxkkkAUyPK8VFek9K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbsGZbN%2FbtsQqBWZ6Bu%2FNuw6IDxkkkAUyPK8VFek9K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;378&quot; height=&quot;261&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;261&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 라이센스 할당 완료&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;566&quot; data-origin-height=&quot;280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rOLXd/btsQqW0QcYz/krY50s6dWHjhsZFPRHkak1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rOLXd/btsQqW0QcYz/krY50s6dWHjhsZFPRHkak1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rOLXd/btsQqW0QcYz/krY50s6dWHjhsZFPRHkak1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrOLXd%2FbtsQqW0QcYz%2FkrY50s6dWHjhsZFPRHkak1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;566&quot; height=&quot;280&quot; data-origin-width=&quot;566&quot; data-origin-height=&quot;280&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI Assitant 플러그인 설치&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;566&quot; data-origin-height=&quot;200&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bf79U6/btsQqop01eY/8trfHnyIuSg0rzNreXu8E1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bf79U6/btsQqop01eY/8trfHnyIuSg0rzNreXu8E1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bf79U6/btsQqop01eY/8trfHnyIuSg0rzNreXu8E1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbf79U6%2FbtsQqop01eY%2F8trfHnyIuSg0rzNreXu8E1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;566&quot; height=&quot;200&quot; data-origin-width=&quot;566&quot; data-origin-height=&quot;200&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JetBrains Junie 설치&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;569&quot; data-origin-height=&quot;242&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wrgst/btsQrU9jGFt/q7Pb0l7GqZgXrM7qj5ouR0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wrgst/btsQrU9jGFt/q7Pb0l7GqZgXrM7qj5ouR0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wrgst/btsQrU9jGFt/q7Pb0l7GqZgXrM7qj5ouR0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fwrgst%2FbtsQrU9jGFt%2Fq7Pb0l7GqZgXrM7qj5ouR0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;569&quot; height=&quot;242&quot; data-origin-width=&quot;569&quot; data-origin-height=&quot;242&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI Chat에서 &quot;Manage License&quot;를 클릭하면&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;285&quot; data-origin-height=&quot;182&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xTIHc/btsQqJAHwcc/EamW209bYeHG1Z8jW3MPT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xTIHc/btsQqJAHwcc/EamW209bYeHG1Z8jW3MPT1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xTIHc/btsQqJAHwcc/EamW209bYeHG1Z8jW3MPT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxTIHc%2FbtsQqJAHwcc%2FEamW209bYeHG1Z8jW3MPT1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;285&quot; height=&quot;182&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;285&quot; data-origin-height=&quot;182&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 라이센스 할당 된 것을 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;629&quot; data-origin-height=&quot;352&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dcgnTa/btsQpenTJD5/S8vkwgwAmS5wMKCPObPrk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dcgnTa/btsQpenTJD5/S8vkwgwAmS5wMKCPObPrk1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dcgnTa/btsQpenTJD5/S8vkwgwAmS5wMKCPObPrk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdcgnTa%2FbtsQpenTJD5%2FS8vkwgwAmS5wMKCPObPrk1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;629&quot; height=&quot;352&quot; data-origin-width=&quot;629&quot; data-origin-height=&quot;352&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이와 같이 intellij 안에서 AI와 채팅을 하며 사용 할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;629&quot; data-origin-height=&quot;408&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bf9ewT/btsQrtEbTWO/wRf3iUkjhrAUzoZl65YisK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bf9ewT/btsQrtEbTWO/wRf3iUkjhrAUzoZl65YisK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bf9ewT/btsQrtEbTWO/wRf3iUkjhrAUzoZl65YisK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbf9ewT%2FbtsQrtEbTWO%2FwRf3iUkjhrAUzoZl65YisK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;629&quot; height=&quot;408&quot; data-origin-width=&quot;629&quot; data-origin-height=&quot;408&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;junie도 사용 가능한데, 정확히 뭔지 몰라서 AI Assistant에 물어보았습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1757408024599&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;다음은 JetBrains Junie에 대한 요약입니다.
Junie가 무엇인가
- Junie는 JetBrains가 개발한 AI 코딩 에이전트로, 개발자와 함께 또는 독립적으로 코딩 작업을 수행합니다.
프로젝트 맥락을 이해하고 코드 검색&amp;middot;분석, 멀티파일 편집, IDE 인스펙션 기반 수정,
코드/테스트 실행, 변경 검증 등을 자동으로 처리할 수 있습니다.

무엇을 할 수 있나
- 프로젝트 구조와 컨텍스트를 활용해 관련 코드 탐색/분석
- IDE 인스펙션을 활용한 코드 수정 및 리팩터링
- 테스트/애플리케이션 실행, 경고&amp;middot;오류 감소를 위한 반복 작업 수행
- 변경사항 검토와 가이드 제공, 복잡한 작업 협업 지원

이용 가능 IDE와 제한
- 2025.1부터 AI Assistant와 함께 설치되지만, 지원 IDE가 제한됩니다
- 중국 본토에서는 지역 제한으로 제공되지 않으며, 현재 AI Enterprise 라이선스 티어에서는 제공되지 않습니다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI Assistant를 이용해 코딩 한번 해봐야겠습니다.&lt;/p&gt;</description>
      <category>IDE Tool/IntelliJ IDEA</category>
      <category>AI Assistant</category>
      <category>AI Pro</category>
      <category>AI Ultimate</category>
      <category>IntelliJ</category>
      <category>junie</category>
      <category>라이센스</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2670</guid>
      <comments>https://xzio.tistory.com/2670#entry2670comment</comments>
      <pubDate>Tue, 9 Sep 2025 18:00:30 +0900</pubDate>
    </item>
    <item>
      <title>[Java] Map을 Key, Value로 정렬하기</title>
      <link>https://xzio.tistory.com/2669</link>
      <description>&lt;h2 id=&quot;개요&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;개요&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Java에서 Map 정렬이 필요할 때, 그 방법에 대해 알아보겠습니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;정렬 기준은 key, value 두가지로 나눌 수 있습니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;1-key-값을-기준으로-정렬하기&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;1. Key 값을 기준으로 정렬하기&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;map 의 keySet을 이용하여 정렬합니다.&lt;br /&gt;오름차순 시에는 Collection.sort(), 내림차순 시에는 Collection.reverse() 메소드를 사용하여 정렬합니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1757320074448&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.*;

public class Sort {

    public static void main(String[] args) {

        Map&amp;lt;String, Integer&amp;gt; map = new HashMap&amp;lt;&amp;gt;();

        map.put(&quot;A&quot;, 10);
        map.put(&quot;D&quot;, 30);
        map.put(&quot;C&quot;, 20);
        map.put(&quot;B&quot;, 40);


        List&amp;lt;String&amp;gt; keySet = new ArrayList&amp;lt;&amp;gt;(map.keySet());

        // 키 값으로 오름차순 정렬
        Collections.sort(keySet);

        for (String key : keySet) {
            System.out.print(&quot;Key : &quot; + key);
            System.out.println(&quot;, Val : &quot; + map.get(key));
        }
       
        /*  결과
            Key : A, Val : 10
            Key : B, Val : 40
            Key : C, Val : 20
            Key : D, Val : 30
         */
        
        

        // 키 값으로 내림차순 정렬
        Collections.reverse(keySet);

        for (String key : keySet) {
            System.out.print(&quot;Key : &quot; + key);
            System.out.println(&quot;, Val : &quot; + map.get(key));
        }
        
        /*  결과
            Key : D, Val : 30
            Key : C, Val : 20
            Key : B, Val : 40
            Key : A, Val : 10
        */
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 id=&quot;2value-값을-기준으로-정렬하기&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;2.Value 값을 기준으로 정렬하기&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Value 값을 기준으로 정렬할 때는 comparator를 사용하여 정렬합니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;comparator는 람다 표현식으로 간단하게 표현할 수도 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1757320099141&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.*;

public class Sort {

    public static void main(String[] args) {

		Map&amp;lt;String, Integer&amp;gt; map = new HashMap&amp;lt;&amp;gt;();

        map.put(&quot;A&quot;, 10);
        map.put(&quot;D&quot;, 30);
        map.put(&quot;C&quot;, 20);
        map.put(&quot;B&quot;, 40);


        List&amp;lt;String&amp;gt; keySet = new ArrayList&amp;lt;&amp;gt;(map.keySet());

        // Value 값으로 오름차순 정렬
        keySet.sort(new Comparator&amp;lt;String&amp;gt;() {
            @Override
            public int compare(String o1, String o2) {
                return map.get(o1).compareTo(map.get(o2));
            }
        });

        for (String key : keySet) {
            System.out.print(&quot;Key : &quot; + key);
            System.out.println(&quot;, Val : &quot; + map.get(key));
        }

        /*
            결과
            Key : A, Val : 10
            Key : C, Val : 20
            Key : D, Val : 30
            Key : B, Val : 40
         */

        // Value 값으로 내림차순 정렬
        // 위 comparator 람다 표현식으로
        keySet.sort((o1, o2) -&amp;gt; map.get(o2).compareTo(map.get(o1)));

        for (String key : keySet) {
            System.out.print(&quot;Key : &quot; + key);
            System.out.println(&quot;, Val : &quot; + map.get(key));
        }

        /* 결과
            Key : B, Val : 40
            Key : D, Val : 30
            Key : C, Val : 20
            Key : A, Val : 10
         */
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JAVA BASIC/Collection(컬렉션) - 자료구조</category>
      <category>Java</category>
      <category>key</category>
      <category>map</category>
      <category>VALUE</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2669</guid>
      <comments>https://xzio.tistory.com/2669#entry2669comment</comments>
      <pubDate>Mon, 8 Sep 2025 17:30:26 +0900</pubDate>
    </item>
    <item>
      <title>Deployment Patterns</title>
      <link>https://xzio.tistory.com/2665</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;867&quot; data-origin-height=&quot;366&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XK92e/btsQadul8L8/lJT1RZVcIbVCsq9SbO8dNK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XK92e/btsQadul8L8/lJT1RZVcIbVCsq9SbO8dNK/img.png&quot; data-alt=&quot;기존 가상화 방식 -&amp;amp;gt; 서버 가상화 -&amp;amp;gt; 컨테이너 가상화&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XK92e/btsQadul8L8/lJT1RZVcIbVCsq9SbO8dNK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXK92e%2FbtsQadul8L8%2FlJT1RZVcIbVCsq9SbO8dNK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;867&quot; height=&quot;366&quot; data-origin-width=&quot;867&quot; data-origin-height=&quot;366&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;기존 가상화 방식 -&amp;gt; 서버 가상화 -&amp;gt; 컨테이너 가상화&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Containers&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Virtualization&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;210&quot; data-origin-height=&quot;231&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3WrQh/btsP8knTJa9/2T9fplpzn9uLaY5IE5NFi1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3WrQh/btsP8knTJa9/2T9fplpzn9uLaY5IE5NFi1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3WrQh/btsP8knTJa9/2T9fplpzn9uLaY5IE5NFi1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3WrQh%2FbtsP8knTJa9%2F2T9fplpzn9uLaY5IE5NFi1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;210&quot; height=&quot;231&quot; data-origin-width=&quot;210&quot; data-origin-height=&quot;231&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Isolation
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;각 마이크로서비스는 자체 컨테이너에서 실행&lt;/li&gt;
&lt;li&gt;다른&amp;nbsp;마이크로서비스와&amp;nbsp;호스트&amp;nbsp;운영&amp;nbsp;체제로부터&amp;nbsp;격리&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Scalability
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;컨테이너화 된 마이크로서비스의 인스턴스를 더 많이 실행 -&amp;gt; 수평적 확장&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Portability
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;컨테이너를 통해 마이크로서비스를 쉽게 배포&lt;/li&gt;
&lt;li&gt;컨테이너 런타임을 지원하는 모든 컴퓨터나 클라우드 플랫폼에서 실행&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Resiliency
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;마이크로서비스는 독립적으로 배포하고 확장할 수 있도록 설계&lt;/li&gt;
&lt;li&gt;빠르게 시작 및 중지 -&amp;gt; 애플리케이션의 복원력이 향상&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Container&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Orchestration&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;tools&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;363&quot; data-origin-height=&quot;366&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lZ2wm/btsQaNIS06m/KthgQB21UDuIfk4SBn5rbk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lZ2wm/btsQaNIS06m/KthgQB21UDuIfk4SBn5rbk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lZ2wm/btsQaNIS06m/KthgQB21UDuIfk4SBn5rbk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlZ2wm%2FbtsQaNIS06m%2FKthgQB21UDuIfk4SBn5rbk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;363&quot; height=&quot;366&quot; data-origin-width=&quot;363&quot; data-origin-height=&quot;366&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;컨테이너화된 애플리케이션의 배포, 확장, 관리 자동화
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기본 인프라 추상화&lt;/li&gt;
&lt;li&gt;리소스 할당, 로드 밸런싱, 모니터링 작업처리&lt;/li&gt;
&lt;li&gt;효율적, 확장 가능한 방식으로 실행, 관리&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;클러스터 전체에서 컨테이너화된 워크로드의 배포, 확장 및 운영 문제를 자동화&lt;/li&gt;
&lt;li&gt;각 마이크로서비스를 컨테이너 이미지로 패키징 -&amp;gt; 컨테이너 레지스트리 푸시&lt;/li&gt;
&lt;li&gt;컨테이너 오케스트레이터 -&amp;gt; 마이크로서비스를 노드 클러스터에 배포&lt;/li&gt;
&lt;li&gt;컨테이너를&amp;nbsp;노드에&amp;nbsp;스케줄링,&amp;nbsp;상태&amp;nbsp;모니터링,&amp;nbsp;자체&amp;nbsp;복구&amp;nbsp;기능&amp;nbsp;처리&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Kubernetes&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;오픈 소스 컨테이너 오케스트레이션 플랫폼
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;컨테이너화된 애플리케이션을 배포, 관리 및 확장 -&amp;gt; 프로세스 자동화&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;자체 복구
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Kubernetes는 실패한 컨테이너를 자동으로 재시작&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;자동 확장
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;필요에 따라 마이크로서비스를 자동으로 확장/축소&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;부하 분산
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;마이크로서비스의 트래픽 자동 분산&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;선언적 구성
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;구성 파일을 사용하여 마이크로서비스에 필요한 상태 지정 -&amp;gt; 애플리케이션 배포/관리 자동화&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Reference&lt;/b&gt;&lt;br /&gt;마이크로서비스&amp;nbsp;디자인&amp;nbsp;패턴&amp;nbsp;완벽&amp;nbsp;가이드&lt;br /&gt;&lt;a href=&quot;https://www.inflearn.com/course/%EB%A7%88%EC%9D%B4%ED%81%AC%EB%A1%9C%EC%84%9C%EB%B9%84%EC%8A%A4-%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4-msa&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.inflearn.com/course/%EB%A7%88%EC%9D%B4%ED%81%AC%EB%A1%9C%EC%84%9C%EB%B9%84%EC%8A%A4-%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4-msa&lt;/a&gt;&lt;/p&gt;</description>
      <category>기타 정보/MSA</category>
      <category>deployment</category>
      <category>microservice</category>
      <category>MSA</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2665</guid>
      <comments>https://xzio.tistory.com/2665#entry2665comment</comments>
      <pubDate>Wed, 27 Aug 2025 17:02:50 +0900</pubDate>
    </item>
    <item>
      <title>Scalability</title>
      <link>https://xzio.tistory.com/2664</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;동시에&amp;nbsp;수용&amp;nbsp;가능한&amp;nbsp;요청&amp;nbsp;수는&amp;nbsp;얼마인가?&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; width=&quot;629&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td width=&quot;114&quot; height=&quot;24&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;동시접속자&lt;/span&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;수&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;143&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;초당&lt;/span&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;요청&lt;/span&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;수&lt;/span&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;(RPS)&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;372&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;권장&lt;/span&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;시스템&lt;/span&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;설계&lt;/span&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;및&lt;/span&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;고려사항&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&quot;114&quot; height=&quot;24&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;500&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;143&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;50 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;RPS&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;372&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;단일&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;서버로&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;처리&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;가능하나&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;향후&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;확장을&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;대비한&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;설계&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;필요&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&quot;114&quot; height=&quot;24&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1K&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;143&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;100 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;RPS&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;372&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;로드&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;밸런서를&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;도입하여&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;두&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;대의&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;서버로&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;부하&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;분산&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;고려&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&quot;114&quot; height=&quot;24&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2K&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;143&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;200 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;RPS&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;372&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;세션&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;상태&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;관리를&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;위한&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;분산&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;캐시&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;도입&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;검토&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&quot;114&quot; height=&quot;24&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;5K&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;143&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;500 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;RPS&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;372&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;데이터베이스&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;샤딩&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;또는&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;리플리케이션&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;고려&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&quot;114&quot; height=&quot;24&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;10K&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;143&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1,000&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;RPS&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;372&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;콘텐츠&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;전송&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;네트워크&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;(CDN)&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;활용하여&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;정적&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;자원&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;제공&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;최적화&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&quot;114&quot; height=&quot;24&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;20K&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;143&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2,000&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;RPS&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;372&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;마이크로서비스&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;아키텍처&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;도입&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;검토&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&quot;114&quot; height=&quot;24&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;50K&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;143&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;5,000&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;RPS&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;372&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;서비스&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;메시&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;도입&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;및&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;오케스트레이션&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;도구&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;활용&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;고려&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&quot;114&quot; height=&quot;24&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;100K&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;143&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;10,000&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;RPS&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;372&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;글로벌&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;로드&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;밸런싱&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;및&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;멀티&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;리전&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;배포&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;검토&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&quot;114&quot; height=&quot;41&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;500K&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;143&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;50,000&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;RPS&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;372&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;대규모&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;분산&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;시스템&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;설계&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;및&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;데이터&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;일관성&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;유지&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;전략&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;수립 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;필요&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Vertical&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Scaling&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;ndash;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Scale&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;up&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;246&quot; data-origin-height=&quot;365&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/buBa78/btsP8HCV5lz/AHjX6zkMhKAZCOBHpgiki0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/buBa78/btsP8HCV5lz/AHjX6zkMhKAZCOBHpgiki0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/buBa78/btsP8HCV5lz/AHjX6zkMhKAZCOBHpgiki0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbuBa78%2FbtsP8HCV5lz%2FAHjX6zkMhKAZCOBHpgiki0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;246&quot; height=&quot;365&quot; data-origin-width=&quot;246&quot; data-origin-height=&quot;365&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기본적으로 노드를 더 강하게 구성
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;하드웨어를 더 추가하여 서버를 더 강하게&lt;/li&gt;
&lt;li&gt;단일 노드에 더 많은 리소스를 추가&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;기존 인프라를 유지하면서 더 많은 컴퓨팅 파워 추가
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;최적화를 통해 더 많은 요청 처리&lt;/li&gt;
&lt;li&gt;기존 코드에 대한 변경 X&lt;/li&gt;
&lt;li&gt;증가하는 작업 부하 -&amp;gt; CPU, RAM 및 DISK 추가&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;확장성 제한
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;하드웨어에도 최대 용량 제한이 있음&lt;/li&gt;
&lt;li&gt;수백만 개의 요청 처리 -&amp;gt; 수평적 확장 또는 더 많은 컴퓨팅 확장 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Horizontal&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Scaling&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;ndash;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Scale&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;out&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;256&quot; data-origin-height=&quot;263&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eLc4TW/btsQafyR5pZ/FnnPA7kiP66LcHZzNswgWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eLc4TW/btsQafyR5pZ/FnnPA7kiP66LcHZzNswgWk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eLc4TW/btsQafyR5pZ/FnnPA7kiP66LcHZzNswgWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeLc4TW%2FbtsQafyR5pZ%2FFnnPA7kiP66LcHZzNswgWk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;256&quot; height=&quot;263&quot; data-origin-width=&quot;256&quot; data-origin-height=&quot;263&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서로 다른 서버 간에 부하 분할(분산)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기존 사양을 변경하지 않고 더 많은 머신 인스턴스를 추가&lt;/li&gt;
&lt;li&gt;여러 머신에서 처리 능력과 부하 분산을 공유&lt;/li&gt;
&lt;li&gt;리소스 풀에 더 많은 머신을 추가&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;확장성과 안정성을 모두 만족
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;분산 아키텍처의 확장&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;여러 서버로 분할할 때의 고려사항
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;상태가 있는지 여부&lt;/li&gt;
&lt;li&gt;데이터베이스 서버 -&amp;gt; CAP 정리 / 관리 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Load&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Balancer&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;417&quot; data-origin-height=&quot;204&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cppncK/btsP9BJbzDc/jCppFOnjpDSAqahV8dv2KK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cppncK/btsP9BJbzDc/jCppFOnjpDSAqahV8dv2KK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cppncK/btsP9BJbzDc/jCppFOnjpDSAqahV8dv2KK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcppncK%2FbtsP9BJbzDc%2FjCppFOnjpDSAqahV8dv2KK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;417&quot; height=&quot;204&quot; data-origin-width=&quot;417&quot; data-origin-height=&quot;204&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모든 애플리케이션 노드에 걸쳐 트래픽 분산
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;응답성과 가용성을 개선&lt;/li&gt;
&lt;li&gt;다양한 알고리즘을 사용하여 여러 백엔드 서버에 트래픽 분산 -&amp;gt; 해싱 알고리즘&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;내결함성이 있어야 하며 가용성을 개선&lt;/li&gt;
&lt;li&gt;수평적 확장성 문제를 해결
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모든&amp;nbsp;키를&amp;nbsp;다시&amp;nbsp;정렬할&amp;nbsp;필요&amp;nbsp;없음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Distributed&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Caching&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;439&quot; data-origin-height=&quot;418&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cLU4pi/btsP89sqine/Oj7dzCQKPiPVku4iocNVtK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cLU4pi/btsP89sqine/Oj7dzCQKPiPVku4iocNVtK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cLU4pi/btsP89sqine/Oj7dzCQKPiPVku4iocNVtK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcLU4pi%2FbtsP89sqine%2FOj7dzCQKPiPVku4iocNVtK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;439&quot; height=&quot;418&quot; data-origin-width=&quot;439&quot; data-origin-height=&quot;418&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;자주 액세스하는 데이터
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;메모리에서 빠르게 액세스할 수 있는 캐시에 저장&lt;/li&gt;
&lt;li&gt;시스템 성능 개선&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;캐시로 대기 시간을 줄이고 애플리케이션을 더 빠르게 만듬
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;마이크로서비스의 성능, 확장성, 가용성을 높임&lt;/li&gt;
&lt;li&gt;요청 수가 증가 -&amp;gt; 캐싱은 고가용성으로 요청 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;애플리케이션 요청이 자주 변경되지 않는 데이터
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;캐싱이&amp;nbsp;매우&amp;nbsp;효율적&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;자주 액세스하는 데이터를 캐시에 로컬로 저장
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;마이크로서비스는 외부 시스템에 대한 반복적인 호출하는 대신 응답 시간이 더 빨라짐&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;향상된 성능
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서비스는 DB 또는 기타 외부 시스템에 대한 반복적인 호출 줄임&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;복원성
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;외부 시스템을 사용할 수 없게 되어도 서비스가 계속 작동 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;확장성
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서비스가&amp;nbsp;외부&amp;nbsp;시스템을&amp;nbsp;확장할&amp;nbsp;필요&amp;nbsp;없이&amp;nbsp;증가된&amp;nbsp;트래픽을&amp;nbsp;처리&amp;nbsp;가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Distributed&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Caching Type&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;In-memory cache
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;컴퓨터의 주 메모리에 데이터 저장&lt;/li&gt;
&lt;li&gt;가장 빠른 유형의 캐시&lt;/li&gt;
&lt;li&gt;캐시를 다시 시작하거나 컴퓨터를 종료하면 데이터가 손실&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Disk cache
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;HDD나 SDD에 데이터 저장&lt;/li&gt;
&lt;li&gt;디스크 캐시는 메모리 내 캐시보다 느리지만 데이터 유지 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;분산 캐시
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;여러 컴퓨터에 분산&lt;/li&gt;
&lt;li&gt;MSA와 같은 분산 시스템에서 사용&lt;/li&gt;
&lt;li&gt;데이터를 여러 위치에서 저장하고 액세스&lt;/li&gt;
&lt;li&gt;시스템의&amp;nbsp;성능과&amp;nbsp;확장성&amp;nbsp;개선&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Caching&amp;nbsp;Strategies&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Cache Aside
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;클라이언트가 백엔드 서비스에 요청하기 전에 캐시에서 데이터 확인&lt;/li&gt;
&lt;li&gt;마이크로서비스가 DB에서 데이터를 읽어야 하는 경우 먼저 캐시 확인&lt;/li&gt;
&lt;li&gt;데이터가 사용 가능한 경우(Cache Hit) -&amp;gt; 캐시된 데이터가 반환&lt;/li&gt;
&lt;li&gt;데이터를 사용할 수 없는 경우(Cache Miss) -&amp;gt; DB에 데이터를 쿼리&lt;/li&gt;
&lt;li&gt;클라이언트는 백엔드 서비스에서 데이터를 검색 -&amp;gt; 다음 요청을 위해 캐시 저장&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Read-Through
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Cache Miss 발생 -&amp;gt; DB에서 누락된 데이터를 로드하고 캐시를 채우고 애플리케이션에 반환&lt;/li&gt;
&lt;li&gt;클라이언트가 캐시에서 찾을 수 없는 데이터를 요청 -&amp;gt; 캐시가 자동으로 DB에서 데이터를 검색&lt;/li&gt;
&lt;li&gt;캐시는 항상 DB와 일관성 유지&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Write-Through
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터가 백엔드 서비스에 기록될 때마다 캐시&amp;nbsp; 업데이트&lt;/li&gt;
&lt;li&gt;캐시는 항상 최신 데이터를 보유하지만, 쓰기 작업 수가 더 많아질 수 있음&lt;/li&gt;
&lt;li&gt;데이터는 먼저 캐시에 기록되고 그 다음 DB에 기록&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Write-Back or Write-Behind
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;캐시 업데이트를 나중으로 미룸&lt;/li&gt;
&lt;li&gt;쓰기 작업 수가 줄어들지만 캐시에 최신 데이터가 없을 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Reference&lt;/b&gt;&lt;br /&gt;마이크로서비스&amp;nbsp;디자인&amp;nbsp;패턴&amp;nbsp;완벽&amp;nbsp;가이드&lt;br /&gt;&lt;a href=&quot;https://www.inflearn.com/course/%EB%A7%88%EC%9D%B4%ED%81%AC%EB%A1%9C%EC%84%9C%EB%B9%84%EC%8A%A4-%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4-msa&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.inflearn.com/course/%EB%A7%88%EC%9D%B4%ED%81%AC%EB%A1%9C%EC%84%9C%EB%B9%84%EC%8A%A4-%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4-msa&lt;/a&gt;&lt;/p&gt;</description>
      <category>기타 정보/MSA</category>
      <category>microservice</category>
      <category>MSA</category>
      <category>scalability</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2664</guid>
      <comments>https://xzio.tistory.com/2664#entry2664comment</comments>
      <pubDate>Wed, 27 Aug 2025 16:46:48 +0900</pubDate>
    </item>
    <item>
      <title>Authentication &amp;amp; Authorization</title>
      <link>https://xzio.tistory.com/2663</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;450&quot; data-origin-height=&quot;235&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2Qasj/btsP7wu76yz/DLnXzQLud7FKYUYOxqYv0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2Qasj/btsP7wu76yz/DLnXzQLud7FKYUYOxqYv0k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2Qasj/btsP7wu76yz/DLnXzQLud7FKYUYOxqYv0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2Qasj%2FbtsP7wu76yz%2FDLnXzQLud7FKYUYOxqYv0k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;450&quot; height=&quot;235&quot; data-origin-width=&quot;450&quot; data-origin-height=&quot;235&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Authentication&amp;nbsp;&amp;nbsp;(Verifying&amp;nbsp;&amp;nbsp;Identity)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사용자의 신원을 확인하는 과정 (Who are you?)&lt;/li&gt;
&lt;li&gt;시스템 접근을 요청하는 사용자의 신원 판별&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;방법)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Password-Based Authentication&lt;/li&gt;
&lt;li&gt;Passwordless Authentication&lt;/li&gt;
&lt;li&gt;2FA/MFA (Two-Factor Authentication / Multi- Factor Authentication)&lt;/li&gt;
&lt;li&gt;Single sign-on (SSO)&lt;/li&gt;
&lt;li&gt;Social authentication&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Ex)&amp;nbsp;Authentication:&amp;nbsp;ID/PW&amp;nbsp;로그인&lt;/li&gt;
&lt;li&gt;MSA에서의 인증 인가의 중요성
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Microservices는 각각의 서비스가 독립적으로 동작  별도의 보안 영역 구성&lt;/li&gt;
&lt;li&gt;서비스 간 보안 신뢰성 보장 및 확장 가능성 유지 필수&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;주요 역할
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;개별 서비스마다 별도의 보안 정책 수립 가능&lt;/li&gt;
&lt;li&gt;서비스 간 안전한 데이터 교환 가능&lt;/li&gt;
&lt;li&gt;개별&amp;nbsp;서비스&amp;nbsp;접근&amp;nbsp;시&amp;nbsp;사용자의&amp;nbsp;권한&amp;nbsp;및&amp;nbsp;역할&amp;nbsp;명확히&amp;nbsp;구분&amp;nbsp;가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Basic&amp;nbsp;Authentication&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;간단한 사용자 이름과 비밀번호 기반 인증 방식&lt;/li&gt;
&lt;li&gt;장점: 구현 간단, 빠른 적용 가능&lt;/li&gt;
&lt;li&gt;단점:&amp;nbsp;보안&amp;nbsp;취약,&amp;nbsp;암호화&amp;nbsp;필수(HTTPS&amp;nbsp;사용&amp;nbsp;권장)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;OAuth&amp;nbsp;2.0&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;449&quot; data-origin-height=&quot;312&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Qw8Yp/btsP8zZmkEN/CoOgvhujNFawMkKanwdAHK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Qw8Yp/btsP8zZmkEN/CoOgvhujNFawMkKanwdAHK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Qw8Yp/btsP8zZmkEN/CoOgvhujNFawMkKanwdAHK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQw8Yp%2FbtsP8zZmkEN%2FCoOgvhujNFawMkKanwdAHK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;449&quot; height=&quot;312&quot; data-origin-width=&quot;449&quot; data-origin-height=&quot;312&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;타사 서비스가 사용자를 대신하여 접근 권한을 얻을 수 있도록 허용하는 권한 위임 프로토콜&lt;/li&gt;
&lt;li&gt;장점: 높은 보안, 다양한 권한 수준 설정 가능&lt;/li&gt;
&lt;li&gt;단점:&amp;nbsp;구현&amp;nbsp;복잡성&amp;nbsp;증가&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;JWT&amp;nbsp;(JSON&amp;nbsp;Web&amp;nbsp;Token)&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;449&quot; data-origin-height=&quot;312&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/p5TNB/btsQaU2dpCv/jAJS9DaKLDa3wauNFMK3LK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/p5TNB/btsQaU2dpCv/jAJS9DaKLDa3wauNFMK3LK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/p5TNB/btsQaU2dpCv/jAJS9DaKLDa3wauNFMK3LK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fp5TNB%2FbtsQaU2dpCv%2FjAJS9DaKLDa3wauNFMK3LK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;449&quot; height=&quot;312&quot; data-origin-width=&quot;449&quot; data-origin-height=&quot;312&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;무상태(Stateless) 방식의 인증 및 인가를 지원하는 토큰 기반 인증 방식&lt;/li&gt;
&lt;li&gt;장점: 확장성 높음, 서비스 간 인증 정보 공유 쉬움&lt;/li&gt;
&lt;li&gt;단점:&amp;nbsp;토큰&amp;nbsp;탈취&amp;nbsp;시&amp;nbsp;문제&amp;nbsp;발생,&amp;nbsp;토큰&amp;nbsp;관리&amp;nbsp;주의&amp;nbsp;필요&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Rate&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Limiting&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;403&quot; data-origin-height=&quot;320&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cbWILe/btsP93FoWUy/h2bkfvREFnku72oXNgc6K1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cbWILe/btsP93FoWUy/h2bkfvREFnku72oXNgc6K1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cbWILe/btsP93FoWUy/h2bkfvREFnku72oXNgc6K1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcbWILe%2FbtsP93FoWUy%2Fh2bkfvREFnku72oXNgc6K1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;403&quot; height=&quot;320&quot; data-origin-width=&quot;403&quot; data-origin-height=&quot;320&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;API에 유입되는 요청 수를 제한하여 시스템 과부하 및 남용 방지&lt;/li&gt;
&lt;li&gt;공격, 과도한 트래픽으로 인한 서비스 장애 방지&lt;/li&gt;
&lt;li&gt;서비스 안정성 및 가용성 보장 필수&lt;/li&gt;
&lt;li&gt;장점
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서비스의 과부하 방비, 악의적 공격 최소화, 안정성 향상&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;단점
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;과도한 제한 시 사용자 경험 저하 가능성, 관리 및 설정의 복잡성&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;구현 방법
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;요청 횟수 기반 제한 (예: 분당 요청수 제한)&lt;/li&gt;
&lt;li&gt;토큰 버킷 알고리즘(Token Bucket), 리키 버킷(Leaky Bucket) 알고리즘 적용&lt;/li&gt;
&lt;li&gt;Redis&amp;nbsp;등&amp;nbsp;빠른&amp;nbsp;메모리&amp;nbsp;기반&amp;nbsp;저장소&amp;nbsp;사용해&amp;nbsp;구현&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Rate&amp;nbsp;Limiting Strategies&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Throttling&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;정의: 단기간 과다 요청 시 속도를 제한하거나 요청을 거부하는 방법&lt;/li&gt;
&lt;li&gt;장점: 급작스런 트래픽 스파이크 대응 가능&lt;/li&gt;
&lt;li&gt;단점:&amp;nbsp;정상&amp;nbsp;사용자의&amp;nbsp;요청도&amp;nbsp;일시적&amp;nbsp;차단&amp;nbsp;가능성&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;IP&amp;nbsp;Blocking&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;정의: 특정 IP에서 오는 요청을 차단하거나 제한&lt;/li&gt;
&lt;li&gt;장점: 악성 IP로부터 보호 가능&lt;/li&gt;
&lt;li&gt;단점:&amp;nbsp;정상&amp;nbsp;사용자가&amp;nbsp;VPN&amp;nbsp;등을&amp;nbsp;사용할&amp;nbsp;경우&amp;nbsp;차단&amp;nbsp;위험&amp;nbsp;존재&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;Quota&amp;nbsp;Management&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;정의: 사용자나 앱 별로 명시적 요청 할당량 설정&lt;/li&gt;
&lt;li&gt;장점: 서비스 제공자에게 효율적 관리, 비즈니스 모델 연동 가능&lt;/li&gt;
&lt;li&gt;단점:&amp;nbsp;복잡한&amp;nbsp;사용자&amp;nbsp;관리&amp;nbsp;및&amp;nbsp;부가적&amp;nbsp;인프라&amp;nbsp;필요&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>기타 정보/MSA</category>
      <category>Authentication</category>
      <category>Authorization</category>
      <category>microservice</category>
      <category>MSA</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2663</guid>
      <comments>https://xzio.tistory.com/2663#entry2663comment</comments>
      <pubDate>Wed, 27 Aug 2025 16:10:48 +0900</pubDate>
    </item>
    <item>
      <title>Observability: Distributed Logging/Tracing</title>
      <link>https://xzio.tistory.com/2662</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;453&quot; data-origin-height=&quot;365&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lKqCW/btsP76XdrUa/qVNb2rfq6J2CiYGZ7YbYN1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lKqCW/btsP76XdrUa/qVNb2rfq6J2CiYGZ7YbYN1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lKqCW/btsP76XdrUa/qVNb2rfq6J2CiYGZ7YbYN1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlKqCW%2FbtsP76XdrUa%2FqVNb2rfq6J2CiYGZ7YbYN1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;453&quot; height=&quot;365&quot; data-origin-width=&quot;453&quot; data-origin-height=&quot;365&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;마이크로서비스의 복잡한 종속성을 모니터링하고 관리하기 위한 전략 필요&lt;/li&gt;
&lt;li&gt;마이크로서비스로 구성된 시스템의 동작과 성능을 모니터링, 이해, 관리 -&amp;gt; Observability&lt;/li&gt;
&lt;li&gt;Distributed Logging
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;여러 서비스 인스턴스 -&amp;gt; 로그 수집, 저장 및 분석&lt;/li&gt;
&lt;li&gt;시간 경과에 따른 시스템 동작, 패턴, 추세 식별&lt;/li&gt;
&lt;li&gt;시스템 성능 확인 -&amp;gt; 병목 현상 식별 -&amp;gt; 문제 해결&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Distributed Tracing
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;시스템을 통한 요청 흐름 추적 -&amp;gt; 분산 추적 구현&lt;/li&gt;
&lt;li&gt;장바구니 항목 추가 -&amp;gt; 장바구니 서비스 -&amp;gt; 결제 처리 서비스 -&amp;gt; 제품 카탈로그 서비스 추적&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Observability:&amp;nbsp;Elastic&amp;nbsp;Stack&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;317&quot; data-origin-height=&quot;84&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/C62Qj/btsP9GDFWER/7C0npK6bLfijGva1s2RBu1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/C62Qj/btsP9GDFWER/7C0npK6bLfijGva1s2RBu1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/C62Qj/btsP9GDFWER/7C0npK6bLfijGva1s2RBu1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FC62Qj%2FbtsP9GDFWER%2F7C0npK6bLfijGva1s2RBu1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;317&quot; height=&quot;84&quot; data-origin-width=&quot;317&quot; data-origin-height=&quot;84&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;로그 데이터 및 기타 유형의 데이터를 수집, 저장 및 분석하기 위한 오픈 소스 도구&lt;/li&gt;
&lt;li&gt;Elasticsearch
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;로그 데이터 및 기타 데이터 저장, 인덱싱&lt;/li&gt;
&lt;li&gt;분산 검색 및 분석 엔진&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Logstash
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;다양한 소스에서 로그 데이터 수집 -&amp;gt; Elasticsearch로 전송&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Kibana
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터를 기반으로 대시보드와 시각화, 탐색 도구&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Beats
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;로그 데이터를 수집하여 전송 (데이터 전송기 모음)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;시간 경과에 따른 시스템 동작 파악 -&amp;gt; 패턴과 추세 식별 -&amp;gt; 문제 해결 유용&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Observability:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;OpenTelemetry&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Zipkin&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;417&quot; data-origin-height=&quot;444&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b4XmML/btsP75D2olN/bkYCYWr4HAevPSv0wfntO0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b4XmML/btsP75D2olN/bkYCYWr4HAevPSv0wfntO0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b4XmML/btsP75D2olN/bkYCYWr4HAevPSv0wfntO0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb4XmML%2FbtsP75D2olN%2FbkYCYWr4HAevPSv0wfntO0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;417&quot; height=&quot;444&quot; data-origin-width=&quot;417&quot; data-origin-height=&quot;444&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;OpenTelemetry
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;원격 측정 데이터, 추적, 메트릭 및 로그 수집&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Zipkin
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;마이크로서비스에서 추적 데이터를 수집하고 저장&lt;/li&gt;
&lt;li&gt;웹 UI를 제공하는 분산 추적 시스템&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Zipkin + OpenTelemetry -&amp;gt; 마이크로서비스 분산 추적 (OpenTelemetry SDK)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;요청이 시스템을 통과할 때 추적 데이터를 수집, 저장, 시각화&lt;/li&gt;
&lt;li&gt;OpenTelemetry SDK에서 수집한 추적 데이터 -&amp;gt; 각 서비스 인스턴스에 통합&lt;/li&gt;
&lt;li&gt;Zipkin 서버로 전송&lt;/li&gt;
&lt;li&gt;Zipkin&amp;nbsp;UI를&amp;nbsp;사용하여&amp;nbsp;추적&amp;nbsp;데이터를&amp;nbsp;시각화,&amp;nbsp;분석,&amp;nbsp;패턴이나&amp;nbsp;추세&amp;nbsp;식별&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Reference&lt;/b&gt;&lt;br /&gt;마이크로서비스&amp;nbsp;디자인&amp;nbsp;패턴&amp;nbsp;완벽&amp;nbsp;가이드&lt;br /&gt;&lt;a href=&quot;https://www.inflearn.com/course/%EB%A7%88%EC%9D%B4%ED%81%AC%EB%A1%9C%EC%84%9C%EB%B9%84%EC%8A%A4-%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4-msa&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.inflearn.com/course/%EB%A7%88%EC%9D%B4%ED%81%AC%EB%A1%9C%EC%84%9C%EB%B9%84%EC%8A%A4-%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4-msa&lt;/a&gt;&lt;/p&gt;</description>
      <category>기타 정보/MSA</category>
      <category>microservice</category>
      <category>MSA</category>
      <category>observability</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2662</guid>
      <comments>https://xzio.tistory.com/2662#entry2662comment</comments>
      <pubDate>Wed, 27 Aug 2025 15:47:25 +0900</pubDate>
    </item>
    <item>
      <title>Resilience Patterns</title>
      <link>https://xzio.tistory.com/2661</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;449&quot; data-origin-height=&quot;416&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OLQ4a/btsP8enBRHU/xT9aCFg3ctPSuYKMRVQv80/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OLQ4a/btsP8enBRHU/xT9aCFg3ctPSuYKMRVQv80/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OLQ4a/btsP8enBRHU/xT9aCFg3ctPSuYKMRVQv80/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOLQ4a%2FbtsP8enBRHU%2FxT9aCFg3ctPSuYKMRVQv80%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;449&quot; height=&quot;416&quot; data-origin-width=&quot;449&quot; data-origin-height=&quot;416&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Resilience&amp;nbsp;Patterns&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;장애가 발생할 것이라고 가정 -&amp;gt; 장애 수용
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;특히 분산 시스템에서 예상치 못한 장애 처리 필요&lt;/li&gt;
&lt;li&gt;네트워크 또는 컨테이너 장애 시 마이크로서비스는 요청을 다시 시도하기 위한 전략 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;최악의 시나리오에 대비할 수 있는 장애를 허용(극복) 하는 마이크로서비스 설계
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;단일 마이크로서비스가 실패하거나 잠시 응답하지 못할 수 있음&lt;/li&gt;
&lt;li&gt;서비스&amp;nbsp;과부하,&amp;nbsp;늦은&amp;nbsp;응답,&amp;nbsp;네트워크&amp;nbsp;문제&amp;nbsp;등&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;마이크로서비스의 회복성(Resilience) 설계
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;장애에 대한 복원성(회복성)&lt;/li&gt;
&lt;li&gt;부분적 장애 허용&lt;/li&gt;
&lt;li&gt;장애가 발생할 것이라고 가정하고 복원성(회복성)을 위한 마이크로서비스를 설계&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;장애 허용(Fault Tolerance)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;다운타임이나 데이터 손실 없이 대응&lt;/li&gt;
&lt;li&gt;장애 후 App을 완전히 작동하는 상태로 되돌림&lt;/li&gt;
&lt;li&gt;장애를 우아하게 처리 (Graceful shutdown)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;회복성(Resilience)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;마이크로서비스 시스템은 장애 또는 중단하더라도 효과적으로 계속 작동 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;내결합성(Fault tolerance)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;일부 구성 요소 내에서 하나 이상의 오류가 발생하는 경우에는&amp;nbsp;시스템은&amp;nbsp;정상적으로&amp;nbsp;작동&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;서비스 간 통신은 분산되고 많은 내부 또는 외부 네트워크 트래픽이 트랜잭션을 위해 생성
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모놀리식에 비해 내구성 보장이 어려움&lt;/li&gt;
&lt;li&gt;서비스 간 통신 필요성과 외부 서비스에 대한 종속성 증가&lt;/li&gt;
&lt;li&gt;오류가 발생할 가능성이 증가&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Resilience Pattern (회복성 패턴)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;중단 없는 마이크로서비스를 제공&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;회복성 패턴 종류
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Retry Pattern&lt;/li&gt;
&lt;li&gt;Circuit Breaker Pattern&lt;/li&gt;
&lt;li&gt;Bulkhead Pattern&lt;/li&gt;
&lt;li&gt;Timeout Pattern&lt;/li&gt;
&lt;li&gt;Fallback&amp;nbsp;Pattern&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Resilience:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Retry&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Pattern&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;449&quot; data-origin-height=&quot;404&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Vsuik/btsP9EMxVPW/qWjvf45bU5e80KXjuYdgRk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Vsuik/btsP9EMxVPW/qWjvf45bU5e80KXjuYdgRk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Vsuik/btsP9EMxVPW/qWjvf45bU5e80KXjuYdgRk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVsuik%2FbtsP9EMxVPW%2FqWjvf45bU5e80KXjuYdgRk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;449&quot; height=&quot;404&quot; data-origin-width=&quot;449&quot; data-origin-height=&quot;404&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;HTTP, gRPC 등을 사용하는 서비스 간 통신
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;네트워크, 서버 및 물리적 오류가 발생할 수 있음&lt;/li&gt;
&lt;li&gt;Tx의 서비스 중 하나가 500 Error Code 반환 -&amp;gt; Tx이 중단, 오류 반환&lt;/li&gt;
&lt;li&gt;사용자가 동일한 Tx 다시 시작 -&amp;gt; 정상 작동&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;마이크로서비스는 일시적인 오류로 인해 실패 가능
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이러한 오류는 짧은 시간 내에 발생, 이후에 수정 됨&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Retry Pattern
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;실패할 경우 작업을 자동으로 재시도&lt;/li&gt;
&lt;li&gt;마이크로서비스가 자체 수정 -&amp;gt; 스스로를 수정할 시간 허용&lt;/li&gt;
&lt;li&gt;서비스에 지속적인 장애 발생, 장시간 사용할 수 없는 경우 -&amp;gt; 실패한 요청이 지나치게 많아지게 됨&lt;/li&gt;
&lt;li&gt;Circuit&amp;nbsp;Breaker,&amp;nbsp;Fallback&amp;nbsp;추가&amp;nbsp;구현&amp;nbsp;필요&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Resilience:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Circuit&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Breaker&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Pattern&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;435&quot; data-origin-height=&quot;402&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WVq3n/btsQaj8XutN/IscoLJkc8nLnHxCOryjXAK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WVq3n/btsQaj8XutN/IscoLJkc8nLnHxCOryjXAK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WVq3n/btsQaj8XutN/IscoLJkc8nLnHxCOryjXAK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWVq3n%2FbtsQaj8XutN%2FIscoLJkc8nLnHxCOryjXAK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;435&quot; height=&quot;402&quot; data-origin-width=&quot;435&quot; data-origin-height=&quot;402&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;전자시스템 회로를 보호하기 위해 시스템에 장애가 발생할 경우 더 이상의 부하 전달 중지하는 기능&lt;/li&gt;
&lt;li&gt;Circuit Breaker Pattern
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;외부 의존성(종속성)에 대한 장애로부터 보호&lt;/li&gt;
&lt;li&gt;한 서비스의 장애가 다른 서비스에 연쇄 효과를 미치지 않도록 차단&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;서비스 간 통신 모니터링 -&amp;gt; 오류 추적
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;시스템의 오류가 특정 임계값(Threshold)을 초과 -&amp;gt; Circuit Breaker가 작동되고(Open) 통신 차단 -&amp;gt; 미리 결정된 오류 메시지 반환&lt;/li&gt;
&lt;li&gt;Circuit Breaker가 열려 있는 동안 통신 트래픽을 계속 모니터링&lt;/li&gt;
&lt;li&gt;요청된 서비스가 성공적인 결과를 반환하면 Circuit Breaker&amp;nbsp;종료(Close)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;421&quot; data-origin-height=&quot;402&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dD37wU/btsQarspDwC/MTIgkUCm7dkDXKALYDpaSk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dD37wU/btsQarspDwC/MTIgkUCm7dkDXKALYDpaSk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dD37wU/btsQarspDwC/MTIgkUCm7dkDXKALYDpaSk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdD37wU%2FbtsQarspDwC%2FMTIgkUCm7dkDXKALYDpaSk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;421&quot; height=&quot;402&quot; data-origin-width=&quot;421&quot; data-origin-height=&quot;402&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Close(닫힘)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Circuit Breaker가 닫힘&lt;/li&gt;
&lt;li&gt;모든 요청이 실행&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Open(열림)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Circuit Breaker가 열림&lt;/li&gt;
&lt;li&gt;오류가 발생하는 동안 애플리케이션이 작업을 반복적으로 실행하려고 하지 않도록 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Half Open(반열림)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Circuit Breaker는 오류가 계속 발생하는지 확인하기 위해 몇 가지 작업을 실행&lt;/li&gt;
&lt;li&gt;오류가 발생하면 Circuit Breaker가 열림&lt;/li&gt;
&lt;li&gt;오류가&amp;nbsp;발생하지&amp;nbsp;않으면&amp;nbsp;Circuit&amp;nbsp;Breaker는&amp;nbsp;닫힘&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Resilience:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Bulkhead&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Pattern&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;436&quot; data-origin-height=&quot;389&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ch4iio/btsQaNaWWpR/cMuWtb4TXTkKgbB0meEA4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ch4iio/btsQaNaWWpR/cMuWtb4TXTkKgbB0meEA4k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ch4iio/btsQaNaWWpR/cMuWtb4TXTkKgbB0meEA4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fch4iio%2FbtsQaNaWWpR%2FcMuWtb4TXTkKgbB0meEA4k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;436&quot; height=&quot;389&quot; data-origin-width=&quot;436&quot; data-origin-height=&quot;389&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Bulkhead Pattern
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;분산 시스템에서 장애를 격리하는 데 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;마이크로서비스에서 개별 서비스 인스턴스 또는 서비스 인스턴스 그룹을 서로 격리
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;시스템의 한 부분에서 장애가 발생해도 전체 시스템에 영향을 미치지 않도록 함&lt;/li&gt;
&lt;li&gt;한 위치에서 서비스를 격기하여 다른 서비스에 영향을 미치지 않도록 함&lt;/li&gt;
&lt;li&gt;오류 장소를 격리하고 나머지 서비스를 보호&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use-case
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서비스에 부하가 많고 다른 서비스 인스턴스와 리소스 경합 위험이 있는 경우&lt;/li&gt;
&lt;li&gt;서비스가 연쇄 장애 위험이 있는 경우&lt;/li&gt;
&lt;li&gt;다운스트림&amp;nbsp;서비스를&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;없게&amp;nbsp;되거나&amp;nbsp;성능&amp;nbsp;문제가&amp;nbsp;발생하는&amp;nbsp;경우&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Resilience:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Timeout&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Pattern&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;489&quot; data-origin-height=&quot;452&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXaUAH/btsP8G4ZbDn/kxHUjDz99BJG35iAkttlAk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXaUAH/btsP8G4ZbDn/kxHUjDz99BJG35iAkttlAk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXaUAH/btsP8G4ZbDn/kxHUjDz99BJG35iAkttlAk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXaUAH%2FbtsP8G4ZbDn%2FkxHUjDz99BJG35iAkttlAk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;489&quot; height=&quot;452&quot; data-origin-width=&quot;489&quot; data-origin-height=&quot;452&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서비스 응답을 무한정 기다리지 않고 예외 발생
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서비스 호출이 완료되는 데 예상보다 오래 걸리는 경우 사용&lt;/li&gt;
&lt;li&gt;최대 시간 제한 설정&lt;/li&gt;
&lt;li&gt;Timeout 오류 발생&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;마이크로서비스에서 서비스 호출이 완료되는 데 너무 오래 걸리는 것을 방지&lt;/li&gt;
&lt;li&gt;특정 서비스가 요청을 완료하는 데 예상보다 오래 걸리는 경우 -&amp;gt; 요청을 취소하고 오류&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Resilience:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Fallback&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Pattern&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;442&quot; data-origin-height=&quot;410&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LuFjm/btsP81nNCMZ/XSHUY7HAIaGuXYkQXJHCS1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LuFjm/btsP81nNCMZ/XSHUY7HAIaGuXYkQXJHCS1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LuFjm/btsP81nNCMZ/XSHUY7HAIaGuXYkQXJHCS1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLuFjm%2FbtsP81nNCMZ%2FXSHUY7HAIaGuXYkQXJHCS1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;442&quot; height=&quot;410&quot; data-origin-width=&quot;442&quot; data-origin-height=&quot;410&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;요청이 실패하거나 시간 초과될 경우 대체 동작이나 응답 제공
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서비스를 사용할 수 없는 경우&lt;/li&gt;
&lt;li&gt;클라이언트는 캐시 된 버전의 데이터 사용&lt;/li&gt;
&lt;li&gt;사용자에게 기본 메시지 표시 -&amp;gt; 대체 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;서비스 호출이 실패하거나 시간 초과될 경우 호출되는 Fallback 함수 정의
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Fallback 함수에서 대체 응답 제공&lt;/li&gt;
&lt;li&gt;특정 서비스를 사용할 수 없거나 요청을 완료하는데 너무 오래 걸리는 경우&lt;/li&gt;
&lt;li&gt;오류 메시지 표시 or 나중에 다시 시도할 수 있는 옵션&amp;nbsp;제공&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Reference&lt;/b&gt;&lt;br /&gt;마이크로서비스&amp;nbsp;디자인&amp;nbsp;패턴&amp;nbsp;완벽&amp;nbsp;가이드&lt;br /&gt;&lt;a href=&quot;https://www.inflearn.com/course/%EB%A7%88%EC%9D%B4%ED%81%AC%EB%A1%9C%EC%84%9C%EB%B9%84%EC%8A%A4-%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4-msa&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.inflearn.com/course/%EB%A7%88%EC%9D%B4%ED%81%AC%EB%A1%9C%EC%84%9C%EB%B9%84%EC%8A%A4-%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4-msa&lt;/a&gt;&lt;/p&gt;</description>
      <category>기타 정보/MSA</category>
      <category>microservice</category>
      <category>MSA</category>
      <category>resilience</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2661</guid>
      <comments>https://xzio.tistory.com/2661#entry2661comment</comments>
      <pubDate>Wed, 27 Aug 2025 15:36:22 +0900</pubDate>
    </item>
    <item>
      <title>EDA (Event-Driven Architecture)</title>
      <link>https://xzio.tistory.com/2660</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;468&quot; data-origin-height=&quot;311&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ywdPL/btsP8DAnuu7/Ueyu7e8KK6PyR6xBY8W7D0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ywdPL/btsP8DAnuu7/Ueyu7e8KK6PyR6xBY8W7D0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ywdPL/btsP8DAnuu7/Ueyu7e8KK6PyR6xBY8W7D0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FywdPL%2FbtsP8DAnuu7%2FUeyu7e8KK6PyR6xBY8W7D0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;468&quot; height=&quot;311&quot; data-origin-width=&quot;468&quot; data-origin-height=&quot;311&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Event-Driven&amp;nbsp;Architecture&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;마이크로서비스는 서로의 API를 직접 호출하는 것 대신
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이벤트 메시지를 발행(Publish) / 구독(Subscribe) 하여 통신 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;데이터가 필요할 때 요청 대신 서비스에서 이벤트 소비&lt;/li&gt;
&lt;li&gt;이벤트를 통한 서비스 간 비동기 소통
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;느슨한 결합 (Loose Coupling)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;분리된 통신 -&amp;gt; 독립적, 서비스간 의존성 최소화, 확장성 및 유연성 향상&lt;/li&gt;
&lt;li&gt;실시간 메시징 플랫폼
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;메시지 큐나 이벤트 버스를 사용&lt;/li&gt;
&lt;li&gt;이벤트가 발생하는 대로 Publish -&amp;gt; Subscribe&lt;/li&gt;
&lt;li&gt;CDC 사용 -&amp;gt; DB 변경 사항 추적 시스템 (실시간 이벤트)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;대용량 처리 (이벤트)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;필요에 따라 이벤트 소비자 추가 -&amp;gt; 수평적 확장 가능&lt;/li&gt;
&lt;li&gt;이벤트 버스 -&amp;gt; 이벤트를 병렬로 처리, 분배&lt;/li&gt;
&lt;li&gt;시스템의&amp;nbsp;다른&amp;nbsp;서비스들이&amp;nbsp;서로&amp;nbsp;간에&amp;nbsp;충돌&amp;nbsp;없이&amp;nbsp;사용&amp;nbsp;가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;이벤트 스트림 처리
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;실시간으로 이벤트 스트림 캡처/처리&lt;/li&gt;
&lt;li&gt;데이터의 실시간 처리 -&amp;gt; 분석&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;이벤트 허브
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터 수집/배포를 위한 중앙 허브 역할&lt;/li&gt;
&lt;li&gt;마이크로서비스에 스트림 Publish / Subscribe&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Publish 된 메시지들에 대한
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;실시간 메시징 플랫폼&lt;/li&gt;
&lt;li&gt;스트림 처리&lt;/li&gt;
&lt;li&gt;이벤트 허브&lt;/li&gt;
&lt;li&gt;일괄 처리&lt;/li&gt;
&lt;li&gt;데이터&amp;nbsp;Intelligence&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Event-Driven Architecture 장점&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이벤트 스트리밍&lt;/li&gt;
&lt;li&gt;실시간 처리&lt;/li&gt;
&lt;li&gt;대량 이벤트&lt;/li&gt;
&lt;li&gt;서비스 분리, 확장성 증가&lt;/li&gt;
&lt;li&gt;탄력성&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Event-Driven Architecture 단점&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;복잡성 증가, 이벤트 구동으로 인해 시스템 설계가 더 복잡해짐&lt;/li&gt;
&lt;li&gt;디버깅이 어려움&lt;/li&gt;
&lt;li&gt;이벤트 게시 프로세스에 대기 시간 추가&lt;/li&gt;
&lt;li&gt;분산 트랜잭션 처리 필요&lt;/li&gt;
&lt;li&gt;설정&amp;nbsp;및&amp;nbsp;유지&amp;nbsp;관리가&amp;nbsp;어려움&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Reference&lt;/b&gt;&lt;br /&gt;마이크로서비스&amp;nbsp;디자인&amp;nbsp;패턴&amp;nbsp;완벽&amp;nbsp;가이드&lt;br /&gt;&lt;a href=&quot;https://www.inflearn.com/course/%EB%A7%88%EC%9D%B4%ED%81%AC%EB%A1%9C%EC%84%9C%EB%B9%84%EC%8A%A4-%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4-msa&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.inflearn.com/course/%EB%A7%88%EC%9D%B4%ED%81%AC%EB%A1%9C%EC%84%9C%EB%B9%84%EC%8A%A4-%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4-msa&lt;/a&gt;&lt;/p&gt;</description>
      <category>기타 정보/MSA</category>
      <category>EDA</category>
      <category>Event-Driven Architecture</category>
      <category>microservice</category>
      <category>MSA</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2660</guid>
      <comments>https://xzio.tistory.com/2660#entry2660comment</comments>
      <pubDate>Wed, 27 Aug 2025 14:49:08 +0900</pubDate>
    </item>
    <item>
      <title>Distributed Transaction(Saga Pattern, Outbox, CDC)</title>
      <link>https://xzio.tistory.com/2659</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;467&quot; data-origin-height=&quot;341&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cqaoqw/btsP6fAoqjR/XsenAApCntsSPOEUCDHkiK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cqaoqw/btsP6fAoqjR/XsenAApCntsSPOEUCDHkiK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cqaoqw/btsP6fAoqjR/XsenAApCntsSPOEUCDHkiK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcqaoqw%2FbtsP6fAoqjR%2FXsenAApCntsSPOEUCDHkiK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;467&quot; height=&quot;341&quot; data-origin-width=&quot;467&quot; data-origin-height=&quot;341&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Saga 디자인 패턴
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;분산 Tx -&amp;gt; 데이터 일관성 관리&lt;/li&gt;
&lt;li&gt;Pub/Sub 패턴&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;마이크로서비스를 순차적으로 업데이트
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서비스들의 다음 Tx을 트리거 이벤트로 게시&lt;/li&gt;
&lt;li&gt;여러 서비스들의 일련의 로컬 Tx -&amp;gt; 전체 실행 Tx 관리&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Tx 단계 중 하나가 실패
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Saga 패턴을 통해 Tx을 롤백&lt;/li&gt;
&lt;li&gt;이전 마이크로서비스에 롤백 이벤트 게시 (보상 트랜잭션)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Choreography&amp;nbsp;/&amp;nbsp;Orchestration&amp;nbsp;-&amp;nbsp;based&amp;nbsp;SAGA&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Choreography-based&amp;nbsp;SAGA&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;666&quot; data-origin-height=&quot;377&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lEk61/btsP56p9eQw/LYb0pBErtNv2jNk8VkcCQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lEk61/btsP56p9eQw/LYb0pBErtNv2jNk8VkcCQ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lEk61/btsP56p9eQw/LYb0pBErtNv2jNk8VkcCQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlEk61%2FbtsP56p9eQw%2FLYb0pBErtNv2jNk8VkcCQ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;377&quot; data-origin-width=&quot;666&quot; data-origin-height=&quot;377&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Broker를 이용하여 다른 서비스와 통신
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Pub/Sub(게시-구독) 원칙&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;마이크로서비스가 실시간으로 다른 서비스에 이벤트 게시 -&amp;gt; 분산 + 유연한 방식 제공&lt;/li&gt;
&lt;li&gt;각 마이크로서비스
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;자체 로컬 트랜잭션을 실행&lt;/li&gt;
&lt;li&gt;이벤트 게시 (메시지 브로커 시스템)&lt;/li&gt;
&lt;li&gt;다른&amp;nbsp;마이크로서비스에서&amp;nbsp;로컬&amp;nbsp;트랜잭션&amp;nbsp;트리거&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;Choreography-based SAGA 장점&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;분산화, 유연성&lt;/li&gt;
&lt;li&gt;단일 장애 지점(SPOF)을 피할 수 있음&lt;/li&gt;
&lt;li&gt;간단한 워크 플로우&lt;/li&gt;
&lt;li&gt;Tx&amp;nbsp;많지&amp;nbsp;않은&amp;nbsp;간단한&amp;nbsp;경우&amp;nbsp;적합&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;Choreography-based SAGA 단점&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;복잡성 증가&lt;/li&gt;
&lt;li&gt;순환 이벤트 소비 위험&lt;/li&gt;
&lt;li&gt;분산 시스템의 특정 요구 사항과 제약 조건이 다르기 때문에, 일부 시스템에는 적합하지 않을&amp;nbsp;수&amp;nbsp;있음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Orchestration-based&amp;nbsp;SAGA&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;829&quot; data-origin-height=&quot;453&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b8gPv0/btsP7BJskdq/GTvuR8cc1xcV7GYW4MjXP0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b8gPv0/btsP7BJskdq/GTvuR8cc1xcV7GYW4MjXP0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b8gPv0/btsP7BJskdq/GTvuR8cc1xcV7GYW4MjXP0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb8gPv0%2FbtsP7BJskdq%2FGTvuR8cc1xcV7GYW4MjXP0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;829&quot; height=&quot;453&quot; data-origin-width=&quot;829&quot; data-origin-height=&quot;453&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;중앙 Orchestrator 서비스를 사용하여 트랜잭션 구성
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Event를 중앙 Orchestrator가 구독 후 각&lt;/li&gt;
&lt;li&gt;서비스 호출&lt;/li&gt;
&lt;li&gt;개별 사가 또는 마이크로서비스를 조정/관리&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Orchestrator
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;트랜잭션 시작 -&amp;gt; 각 Saga가 올바른 순서로 단계를 수행 하도록&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Saga 중 하나가 단계를 완료하지 못할 경우
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Orchestrator 는 보상 트랜잭션 사용&lt;/li&gt;
&lt;li&gt;변경 사항 롤백 -&amp;gt; 시스템을 원래 상태로 복원&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;Orchestration-based SAGA 장점&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;트랜잭션을 위한 명확하고 중앙 집중화 된 제어/관리 제공&lt;/li&gt;
&lt;li&gt;시스템의 이해/디버깅/Tx 추가/수정 용이&lt;/li&gt;
&lt;li&gt;많은&amp;nbsp;단계가&amp;nbsp;포함된&amp;nbsp;복잡한&amp;nbsp;워크플로우에&amp;nbsp;적합&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;Orchestration-based SAGA 단점&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;단일 장애 지점 발생 가능&lt;/li&gt;
&lt;li&gt;Orchestrator 다운 시 전체 다운&lt;/li&gt;
&lt;li&gt;모든&amp;nbsp;Tx가&amp;nbsp;Orchestrator를&amp;nbsp;거치기&amp;nbsp;때문에,&amp;nbsp;시스템에&amp;nbsp;부하&amp;nbsp;많이&amp;nbsp;걸릴&amp;nbsp;수&amp;nbsp;있음&amp;nbsp;(Bottleneck)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Compensating&amp;nbsp;Transaction&amp;nbsp;Pattern&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;815&quot; data-origin-height=&quot;453&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/67NyM/btsP9dAXaf4/VkgKXWMugoLNKKIsUnY1K1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/67NyM/btsP9dAXaf4/VkgKXWMugoLNKKIsUnY1K1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/67NyM/btsP9dAXaf4/VkgKXWMugoLNKKIsUnY1K1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F67NyM%2FbtsP9dAXaf4%2FVkgKXWMugoLNKKIsUnY1K1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;815&quot; height=&quot;453&quot; data-origin-width=&quot;815&quot; data-origin-height=&quot;453&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Compensating Transaction Pattern
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;SAGA 패턴의 Rollback 프로세스&lt;/li&gt;
&lt;li&gt;이전에 실행된 Tx의 단계를 역순으로 제공&lt;/li&gt;
&lt;li&gt;원래 작업의 단계별 실행 결과를 취소&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;최종적으로 일관된 작업이며 실패할 수 있음
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;시스템은 실패 지점에서 보상 트랜잭션을 재개하고 계속할 수 있어야 함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;보상 트랜잭션의 단계
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Idempotent&amp;nbsp;(멱등)&amp;nbsp;명령으로&amp;nbsp;정의&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Transactional&amp;nbsp;Outbox&amp;nbsp;Pattern&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;613&quot; data-origin-height=&quot;414&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPyknX/btsP6UinDxI/ZmmikioLya0MqbZPhrPktk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPyknX/btsP6UinDxI/ZmmikioLya0MqbZPhrPktk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPyknX/btsP6UinDxI/ZmmikioLya0MqbZPhrPktk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbPyknX%2FbtsP6UinDxI%2FZmmikioLya0MqbZPhrPktk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;613&quot; height=&quot;414&quot; data-origin-width=&quot;613&quot; data-origin-height=&quot;414&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;마이크로서비스의 DB에 &quot;Outbox&quot; 테이블 저장
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이벤트를 안정적으로 게시할 수 있도록 제공&lt;/li&gt;
&lt;li&gt;Outbox 테이블에 모든 이벤트가 포함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;단일 트랜잭션으로 DB에 두 개의 별도 데이터 저장
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;API가 이벤트 메시지를 직접 게시 X&lt;/li&gt;
&lt;li&gt;메시지가 동일한 트랜잭션으로 DB 테이블에 저장&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;하나의 데이터가 관련 DB 테이블과 Outbox 테이블에 동시 저장
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;정의된 시간 간격으로 Message Broker에 이벤트 게시 (Event Bus)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;메시지를 트리거한 트랜잭션이 실패
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;마이크로서비스에서&amp;nbsp;다른&amp;nbsp;마이크로서비스로&amp;nbsp;메시지가&amp;nbsp;안정적으로&amp;nbsp;전달&amp;nbsp;가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;CDC&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Change&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Data&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Capture&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;464&quot; data-origin-height=&quot;308&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFcAZw/btsP78tpz0g/Mn8Ns8dW9UYS5oqJGYIbO1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFcAZw/btsP78tpz0g/Mn8Ns8dW9UYS5oqJGYIbO1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFcAZw/btsP78tpz0g/Mn8Ns8dW9UYS5oqJGYIbO1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFcAZw%2FbtsP78tpz0g%2FMn8Ns8dW9UYS5oqJGYIbO1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;464&quot; height=&quot;308&quot; data-origin-width=&quot;464&quot; data-origin-height=&quot;308&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CDC
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;DB에서 삽입, 업데이트, 삭제 활동 캡처&lt;/li&gt;
&lt;li&gt;다른 시스템에서 사용할 수 있도록 하는 DB의 데이터에서 발생하는 변경 사항 추적&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;일반적으로 DB의 Tx 로그를 지속적으로 모니터링
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;변경 사항 확인&lt;/li&gt;
&lt;li&gt;변경 사항 추출&lt;/li&gt;
&lt;li&gt;시스템 전파&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;일괄 처리 기반 데이터 동기화에 의존하지 않음&lt;/li&gt;
&lt;li&gt;DB&amp;nbsp;간&amp;nbsp;데이터&amp;nbsp;복제,&amp;nbsp;MSA&amp;nbsp;시스템&amp;nbsp;간&amp;nbsp;데이터&amp;nbsp;동기화,&amp;nbsp;실시간&amp;nbsp;데이터&amp;nbsp;분석&amp;nbsp;활성화에&amp;nbsp;사용&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Distributed&amp;nbsp;DB:&amp;nbsp;CockroachDB&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;521&quot; data-origin-height=&quot;438&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bQ1bRy/btsP68m8GQY/k8GdgqQWrNQPMt31hpJ240/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bQ1bRy/btsP68m8GQY/k8GdgqQWrNQPMt31hpJ240/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bQ1bRy/btsP68m8GQY/k8GdgqQWrNQPMt31hpJ240/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbQ1bRy%2FbtsP68m8GQY%2Fk8GdgqQWrNQPMt31hpJ240%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;521&quot; height=&quot;438&quot; data-origin-width=&quot;521&quot; data-origin-height=&quot;438&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CockroachDB는 확장 가능하고, 복원력이 뛰어나며, 사용하기 쉬운 분산 DB 관리 시스템&lt;/li&gt;
&lt;li&gt;작업 부하가 증가함에 따라 클러스터에 노드를 추가하여 수평적으로 확장 가능&lt;/li&gt;
&lt;li&gt;다중 활성 가용성 및 분산 트랜잭션과 같은 기능을 통해 데이터 일관성 및 강력한 내구성 지원&lt;/li&gt;
&lt;li&gt;CDC + Transaction Outbox Pattern
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Built-in&amp;nbsp;CDC&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Distributed&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;DB:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Azure&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Cosmos&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;DB&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;653&quot; data-origin-height=&quot;377&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3mTFc/btsP6J2BzTu/VIavlfXdKtrB4R0zj5zL4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3mTFc/btsP6J2BzTu/VIavlfXdKtrB4R0zj5zL4k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3mTFc/btsP6J2BzTu/VIavlfXdKtrB4R0zj5zL4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3mTFc%2FbtsP6J2BzTu%2FVIavlfXdKtrB4R0zj5zL4k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;653&quot; height=&quot;377&quot; data-origin-width=&quot;653&quot; data-origin-height=&quot;377&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Azure Cosmos DB는 전 세계적으로 분산된 다중 모델 DB 서비스&lt;/li&gt;
&lt;li&gt;Document, Key-Value, Column-family, Graph 다양한 DB 모델을 지원
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;SQL, MongoDB, Cassandra, Azure Table Storage와 같은 여러 API를 통해 액세스&lt;/li&gt;
&lt;li&gt;변경 피드 API 사용 -&amp;gt; 데이터 변경 사항에 액세스하고 애플리케이션 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CDC를 기본적 지원
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;거의 실시간으로 DB에 적용된 데이터 변경 사항을 추적 -&amp;gt; 다른 시스템에 전파&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;SAGA&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Transactional&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Outbox&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;CDC&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Pattern&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;764&quot; data-origin-height=&quot;448&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b4rXDF/btsP5GSpP6Z/USjnf1CDTbWVzDParaWtC0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b4rXDF/btsP5GSpP6Z/USjnf1CDTbWVzDParaWtC0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b4rXDF/btsP5GSpP6Z/USjnf1CDTbWVzDParaWtC0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb4rXDF%2FbtsP5GSpP6Z%2FUSjnf1CDTbWVzDParaWtC0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;764&quot; height=&quot;448&quot; data-origin-width=&quot;764&quot; data-origin-height=&quot;448&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;DB 무결성 유지 트랜잭션&lt;/li&gt;
&lt;li&gt;실시간 동기화&lt;/li&gt;
&lt;li&gt;데이터와 최신 상태를 유지&lt;/li&gt;
&lt;li&gt;데이터 분리 및 이벤트 전파(Propagate)&lt;/li&gt;
&lt;li&gt;마이크로서비스의&amp;nbsp;확장&amp;nbsp;및&amp;nbsp;유지&amp;nbsp;관리가&amp;nbsp;더&amp;nbsp;쉬움&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;단점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Outbox, CDC 설계로 인해 복잡성 증가&lt;/li&gt;
&lt;li&gt;이벤트 게시 프로세스에 지연 시간 추가&lt;/li&gt;
&lt;li&gt;데이터베이스의 성능 부담&lt;/li&gt;
&lt;li&gt;설정&amp;nbsp;및&amp;nbsp;유지&amp;nbsp;관리가&amp;nbsp;어려움&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Reference&lt;/b&gt;&lt;br /&gt;마이크로서비스&amp;nbsp;디자인&amp;nbsp;패턴&amp;nbsp;완벽&amp;nbsp;가이드&lt;br /&gt;&lt;a href=&quot;https://www.inflearn.com/course/%EB%A7%88%EC%9D%B4%ED%81%AC%EB%A1%9C%EC%84%9C%EB%B9%84%EC%8A%A4-%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4-msa&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.inflearn.com/course/%EB%A7%88%EC%9D%B4%ED%81%AC%EB%A1%9C%EC%84%9C%EB%B9%84%EC%8A%A4-%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4-msa&lt;/a&gt;&lt;/p&gt;</description>
      <category>기타 정보/MSA</category>
      <category>CDC</category>
      <category>distributed</category>
      <category>microservice</category>
      <category>MSA</category>
      <category>outbox</category>
      <category>SAGA</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2659</guid>
      <comments>https://xzio.tistory.com/2659#entry2659comment</comments>
      <pubDate>Wed, 27 Aug 2025 11:22:00 +0900</pubDate>
    </item>
    <item>
      <title>CQRS - Command Query Responsibility Segregation</title>
      <link>https://xzio.tistory.com/2658</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;459&quot; data-origin-height=&quot;344&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkTTVh/btsP87gboZv/07onOS6ytcCMWKmYT8YXk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkTTVh/btsP87gboZv/07onOS6ytcCMWKmYT8YXk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkTTVh/btsP87gboZv/07onOS6ytcCMWKmYT8YXk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkTTVh%2FbtsP87gboZv%2F07onOS6ytcCMWKmYT8YXk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;459&quot; height=&quot;344&quot; data-origin-width=&quot;459&quot; data-origin-height=&quot;344&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CQRS&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;DB를 읽기 및 쓰기 작업 분리
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;비효율적인 조인이나 복잡한 쿼리를 피하기 위해 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Command
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터 상태를 애플리케이션에 반영/변경&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Query
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;복잡한 조인 작업 처리, 결과 반환&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;애플리케이션 성능 개선
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CQRS&lt;/li&gt;
&lt;li&gt;이벤트 소싱 패턴&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CQRS&amp;nbsp;Level&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 72px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 20%; height: 18px;&quot;&gt;단계&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 18px;&quot;&gt;분리 수준&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 18px;&quot;&gt;장점&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 18px;&quot;&gt;단점&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 18px;&quot;&gt;Usecase&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 20%; height: 18px;&quot;&gt;1단계&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 18px;&quot;&gt;Controller&amp;nbsp;및&amp;nbsp;Service&amp;nbsp;만&amp;nbsp;분리&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 18px;&quot;&gt;간단한&amp;nbsp;구조,&amp;nbsp;구현&amp;nbsp;난이도&amp;nbsp;낮음&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 18px;&quot;&gt;성능상&amp;nbsp;큰&amp;nbsp;장점&amp;nbsp;없음,&amp;nbsp;확장성&amp;nbsp;제한적&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 18px;&quot;&gt;&lt;span&gt;&lt;span&gt;소규모,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;프로토타입, &lt;/span&gt;&lt;span&gt;MVP&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;프로젝트&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 20%; height: 18px;&quot;&gt;2단계&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 18px;&quot;&gt;&lt;span&gt;&lt;span&gt;Controller,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Service, &lt;/span&gt;&lt;span&gt;데이터&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;모델&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;(DB&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Schema)&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 18px;&quot;&gt;&lt;span&gt;&lt;span&gt;읽기&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;모델을&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;조회&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;최적화하여 &lt;/span&gt;&lt;span&gt;성능&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;향상&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;가능&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 18px;&quot;&gt;&lt;span&gt;&lt;span&gt;구현&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;및&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;관리&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;복잡성&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;증가&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 18px;&quot;&gt;&lt;span&gt;&lt;span&gt;중간&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;규모&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;프로젝트 &lt;/span&gt;&lt;span&gt;(조회&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;성능&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;중요)&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 20%; height: 18px;&quot;&gt;3단계&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 18px;&quot;&gt;&lt;span&gt;&lt;span&gt;Controller,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Service,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;데이터&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;모델 &lt;/span&gt;&lt;span&gt;(DB&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Schema),&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;물리적&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;DB&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;분리&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 18px;&quot;&gt;&lt;span&gt;&lt;span&gt;읽기/쓰기&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;성능&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;및 &lt;/span&gt;&lt;span&gt;확장성&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;극대화&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 18px;&quot;&gt;&lt;span&gt;&lt;span&gt;복잡성,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;비용, &lt;/span&gt;&lt;span&gt;관리&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;난이도&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;증가&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 18px;&quot;&gt;&lt;span&gt;&lt;span&gt;대규모,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;고성능, &lt;/span&gt;&lt;span&gt;고확장성&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;필요&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;프로젝트&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Event&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Sourcing&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Pattern&lt;/span&gt; &lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;428&quot; data-origin-height=&quot;460&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/di4axs/btsP6aerPRg/ptHjCLXA11GNAbjmlNOjRK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/di4axs/btsP6aerPRg/ptHjCLXA11GNAbjmlNOjRK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/di4axs/btsP6aerPRg/ptHjCLXA11GNAbjmlNOjRK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdi4axs%2FbtsP6aerPRg%2FptHjCLXA11GNAbjmlNOjRK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;428&quot; height=&quot;460&quot; data-origin-width=&quot;428&quot; data-origin-height=&quot;460&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Application -&amp;gt; 엔티티의 상태 + 데이터 저장&lt;/li&gt;
&lt;li&gt;빈번한 DB 업데이트 작업
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터베이스 성능, 응답성 및 확장성 한계에 부정적인 영향으로 인해 상태관리를 별도 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Event Sourcing Pattern
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터의 변경 이력(상태 변화)을 DB(Event Store) 저장&lt;/li&gt;
&lt;li&gt;상태를 직접 저장하지 않고, 발생한 이벤트들을 저장&lt;/li&gt;
&lt;li&gt;저장된 이벤트를 재생(Replay)해서 상태 복원&lt;/li&gt;
&lt;li&gt;최신 데이터 상태만 DB에 저장 X&lt;/li&gt;
&lt;li&gt;모든 이벤트를 순차적으로 DB에 저장 O&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Event Store
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이벤트 데이터베이스 -&amp;gt; 이벤트 저장소&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;데이터가 변경될 때마다 새 레코드 생성
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;발생한 이벤트의 순차적 기록&lt;/li&gt;
&lt;li&gt;기록(저장) 된 이벤트를 재생(Replay)하여 현재 상태 복원&lt;/li&gt;
&lt;li&gt;Replay Events -&amp;gt; 데이터의 최신 상태로 빌드 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;순차적 이벤트 목록
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Materialized View 생성&lt;/li&gt;
&lt;li&gt;쿼리를 수행하기 위한 데이터의 최종 상태 사용&lt;/li&gt;
&lt;li&gt;이벤트를 통한 상태 관리와 복원&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;이벤트 저장소
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Read DB로 변환&lt;/li&gt;
&lt;li&gt;메시지&amp;nbsp;브로커&amp;nbsp;시스템의&amp;nbsp;Pub/Sub&amp;nbsp;패턴&amp;nbsp;사용&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Reference&lt;br /&gt;마이크로서비스&amp;nbsp;디자인&amp;nbsp;패턴&amp;nbsp;완벽&amp;nbsp;가이드&lt;br /&gt;&lt;a href=&quot;https://www.inflearn.com/course/%EB%A7%88%EC%9D%B4%ED%81%AC%EB%A1%9C%EC%84%9C%EB%B9%84%EC%8A%A4-%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4-msa&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.inflearn.com/course/%EB%A7%88%EC%9D%B4%ED%81%AC%EB%A1%9C%EC%84%9C%EB%B9%84%EC%8A%A4-%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4-msa&lt;/a&gt;&lt;/p&gt;</description>
      <category>기타 정보/MSA</category>
      <category>CQRS</category>
      <category>microservice</category>
      <category>MSA</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2658</guid>
      <comments>https://xzio.tistory.com/2658#entry2658comment</comments>
      <pubDate>Tue, 26 Aug 2025 18:07:03 +0900</pubDate>
    </item>
    <item>
      <title>Database Sharding Pattern</title>
      <link>https://xzio.tistory.com/2657</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;515&quot; data-origin-height=&quot;390&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SQBuf/btsP64kIq6X/LXNOJr3WJQmPd6TDKWFZ5k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SQBuf/btsP64kIq6X/LXNOJr3WJQmPd6TDKWFZ5k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SQBuf/btsP64kIq6X/LXNOJr3WJQmPd6TDKWFZ5k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSQBuf%2FbtsP64kIq6X%2FLXNOJr3WJQmPd6TDKWFZ5k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;515&quot; height=&quot;390&quot; data-origin-width=&quot;515&quot; data-origin-height=&quot;390&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;K8s에 적합 -&amp;gt; 수평적 확장 분산 DB&lt;/li&gt;
&lt;li&gt;데이터 분할 -&amp;gt; 수평 및 기능적 데이터 분할&lt;/li&gt;
&lt;li&gt;DB Sharding Pattern -&amp;gt; 확장성, 가용성 등&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;단점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서비스 간 쿼리 -&amp;gt; 복잡한 JOIN에는 작업이 필요함&lt;/li&gt;
&lt;li&gt;읽기-쓰기 DB 분리되기 어려움&lt;/li&gt;
&lt;li&gt;분산&amp;nbsp;트랜잭션&amp;nbsp;관리&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Problems&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;복잡한 JOIN 작업이 있는 크로스 서비스 쿼리&lt;/li&gt;
&lt;li&gt;대규모로 읽기 및 쓰기 작업&lt;/li&gt;
&lt;li&gt;분산&amp;nbsp;트랜잭션&amp;nbsp;관리&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Solutions&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;마이크로서비스 데이터 쿼리 패턴&lt;/li&gt;
&lt;li&gt;Materialized View Pattern&lt;/li&gt;
&lt;li&gt;CQRS Design Pattern&lt;/li&gt;
&lt;li&gt;Event&amp;nbsp;Sourcing&amp;nbsp;Pattern&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Horizontal&amp;nbsp;Partitioning&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;515&quot; data-origin-height=&quot;390&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/r19oa/btsP73Flgto/Ibx3luyJrIAn2coX80xUPk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/r19oa/btsP73Flgto/Ibx3luyJrIAn2coX80xUPk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/r19oa/btsP73Flgto/Ibx3luyJrIAn2coX80xUPk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fr19oa%2FbtsP73Flgto%2FIbx3luyJrIAn2coX80xUPk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;515&quot; height=&quot;390&quot; data-origin-width=&quot;515&quot; data-origin-height=&quot;390&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;수평 분할 -&amp;gt; 샤딩
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;샤드는 데이터의 특정 하위 집합을 보유&lt;/li&gt;
&lt;li&gt;파티션 키를 기준으로 테이블 데이터를 수평으로 분할&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;각 파티션은 별도의 데이터 저장소이지만 모든 파티션은 동일한 스키마를 갖고 있음
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터 요청은 더 많은 서버에 부하를 분산하고 더 많은 성능을 제공&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;파티션 키는 모든 파티션에 데이터를 분배하는 데 제공&lt;/li&gt;
&lt;li&gt;수평 분할의 단점
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;잘못된&amp;nbsp;파티션&amp;nbsp;키&amp;nbsp;설정&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Vertical&amp;nbsp;Partitioning&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;459&quot; data-origin-height=&quot;344&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eiqBvy/btsP7ls03J8/sP1XYwpidY1cIjJEowiku0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eiqBvy/btsP7ls03J8/sP1XYwpidY1cIjJEowiku0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eiqBvy/btsP7ls03J8/sP1XYwpidY1cIjJEowiku0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeiqBvy%2FbtsP7ls03J8%2FsP1XYwpidY1cIjJEowiku0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;459&quot; height=&quot;344&quot; data-origin-width=&quot;459&quot; data-origin-height=&quot;344&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;수직 분할은 &quot;행 분할&amp;rdquo;&lt;/li&gt;
&lt;li&gt;각 분할은 데이터베이스의 테이블에 대한 열의 하위 집합을 보유&lt;/li&gt;
&lt;li&gt;열에 따라 분할된 데이터는 가장 많이 방문한 열과 다른 서버의 다른 열로 나눌 수 있음&lt;/li&gt;
&lt;li&gt;Ex)&amp;nbsp;거의&amp;nbsp;변경되지&amp;nbsp;않는&amp;nbsp;열과&amp;nbsp;자주&amp;nbsp;변경되는&amp;nbsp;열로&amp;nbsp;다른&amp;nbsp;서버에&amp;nbsp;나눕니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Reference&lt;/b&gt;&lt;br /&gt;마이크로서비스&amp;nbsp;디자인&amp;nbsp;패턴&amp;nbsp;완벽&amp;nbsp;가이드&lt;br /&gt;&lt;a href=&quot;https://www.inflearn.com/course/%EB%A7%88%EC%9D%B4%ED%81%AC%EB%A1%9C%EC%84%9C%EB%B9%84%EC%8A%A4-%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4-msa&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.inflearn.com/course/%EB%A7%88%EC%9D%B4%ED%81%AC%EB%A1%9C%EC%84%9C%EB%B9%84%EC%8A%A4-%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4-msa&lt;/a&gt;&lt;/p&gt;</description>
      <category>기타 정보/MSA</category>
      <category>microservice</category>
      <category>MSA</category>
      <category>Sharding</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2657</guid>
      <comments>https://xzio.tistory.com/2657#entry2657comment</comments>
      <pubDate>Tue, 26 Aug 2025 16:20:57 +0900</pubDate>
    </item>
    <item>
      <title>Asynchronous Communications</title>
      <link>https://xzio.tistory.com/2656</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;동기 통신 방식 문제점&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;장시간 실행되어야 하는 작업은 동기 통신으로 처리하기 어려움&lt;/li&gt;
&lt;li&gt;여러 마이크로서비스를 호출 -&amp;gt; 지연 시간 증가&lt;/li&gt;
&lt;li&gt;성능&amp;nbsp;,확장성&amp;nbsp;및&amp;nbsp;가용성&amp;nbsp;문제&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;805&quot; data-origin-height=&quot;453&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RWpZq/btsP6J8ZzTe/SFOBghGOhLxL0krZhgObdk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RWpZq/btsP6J8ZzTe/SFOBghGOhLxL0krZhgObdk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RWpZq/btsP6J8ZzTe/SFOBghGOhLxL0krZhgObdk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRWpZq%2FbtsP6J8ZzTe%2FSFOBghGOhLxL0krZhgObdk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;805&quot; height=&quot;453&quot; data-origin-width=&quot;805&quot; data-origin-height=&quot;453&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;장점&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;새로운 Subscriber 서비스를 쉽게 추가&lt;/li&gt;
&lt;li&gt;유연한 확장성 증가&lt;/li&gt;
&lt;li&gt;수신된 메시지를 규모에 맞게 배포&lt;/li&gt;
&lt;li&gt;Event&amp;nbsp;Driven&amp;nbsp;Microservice&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;단점&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Message Broker의 SPOF(단일 장애 지점)&lt;/li&gt;
&lt;li&gt;디버깅이 어려움&lt;/li&gt;
&lt;li&gt;FIFO를 위해 별도의 구현 필요&lt;/li&gt;
&lt;li&gt;정확히&amp;nbsp;한&amp;nbsp;번만&amp;nbsp;필요한&amp;nbsp;경우&amp;nbsp;성능&amp;nbsp;및&amp;nbsp;확장성&amp;nbsp;문제가&amp;nbsp;발생할&amp;nbsp;수&amp;nbsp;있음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Reference&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마이크로서비스&amp;nbsp;디자인&amp;nbsp;패턴&amp;nbsp;완벽&amp;nbsp;가이드&lt;a href=&quot;https://www.inflearn.com/course/%EB%A7%88%EC%9D%B4%ED%81%AC%EB%A1%9C%EC%84%9C%EB%B9%84%EC%8A%A4-%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4-msa&quot;&gt;https://www.inflearn.com/course/%EB%A7%88%EC%9D%B4%ED%81%AC%EB%A1%9C%EC%84%9C%EB%B9%84%EC%8A%A4-%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4-msa&lt;/a&gt;&lt;/p&gt;</description>
      <category>기타 정보/MSA</category>
      <category>microservice</category>
      <category>MSA</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2656</guid>
      <comments>https://xzio.tistory.com/2656#entry2656comment</comments>
      <pubDate>Tue, 26 Aug 2025 15:53:17 +0900</pubDate>
    </item>
    <item>
      <title>API Gateway Patterns</title>
      <link>https://xzio.tistory.com/2655</link>
      <description>&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;API gateway patterns
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;gateway routing&lt;/li&gt;
&lt;li&gt;gateway aggregation&lt;/li&gt;
&lt;li&gt;gateway offloding pattern&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Backend for Frontend pattern&lt;/li&gt;
&lt;li&gt;Service&amp;nbsp;Registry&amp;nbsp;/&amp;nbsp;Discovery&amp;nbsp;pattern&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Gateway&amp;nbsp;Routing&amp;nbsp;Pattern&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;431&quot; data-origin-height=&quot;307&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VKbiF/btsP56wxHJU/9XgQh1n3XROLVo98qSIZRk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VKbiF/btsP56wxHJU/9XgQh1n3XROLVo98qSIZRk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VKbiF/btsP56wxHJU/9XgQh1n3XROLVo98qSIZRk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVKbiF%2FbtsP56wxHJU%2F9XgQh1n3XROLVo98qSIZRk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;431&quot; height=&quot;307&quot; data-origin-width=&quot;431&quot; data-origin-height=&quot;307&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;단일 Endpoint -&amp;gt; 여러 마이크로서비스로 요청
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Routing, Reverse Proxy&lt;/li&gt;
&lt;li&gt;각 서비스에 대한 요청을 라우팅하는 Gateway의 Endpoint 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Client에서 여러 마이크로서비스 사용할 경우
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;마이크로서비스가 변경되어도 클라이언트의 코드 변경이 필요하지 않음&lt;/li&gt;
&lt;li&gt;Routing만 변경 (오류 수정 용이)&lt;/li&gt;
&lt;li&gt;클라이언트 코드의 단순화&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;다양한 API 버전에 대해 Routing 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Gateway&amp;nbsp;Aggregation&amp;nbsp;Pattern&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;439&quot; data-origin-height=&quot;314&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RckuT/btsP564pS17/ZhEBbKPkIeZgMKiOR7UkLK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RckuT/btsP564pS17/ZhEBbKPkIeZgMKiOR7UkLK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RckuT/btsP564pS17/ZhEBbKPkIeZgMKiOR7UkLK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRckuT%2FbtsP564pS17%2FZhEBbKPkIeZgMKiOR7UkLK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;439&quot; height=&quot;314&quot; data-origin-width=&quot;439&quot; data-origin-height=&quot;314&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;클라이언트 로직 수행에 여러 개의 다른 백엔드 마이크로서비스를 호출해야 하는 경우 사용
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;잦은 통신 발생 (Cost 증가)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;단일 Endpoint를 노출 -&amp;gt; 여러 마이크로서비스로 요청 집계(Aggregate)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;여러 백엔드 서비스에 요청을 전송한 다음 집계한 내용을 클라이언트로 전달&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;클라이언트&amp;nbsp;애플리케이션에서&amp;nbsp;복잡한&amp;nbsp;내부&amp;nbsp;백엔드&amp;nbsp;서비스&amp;nbsp;통신에&amp;nbsp;대한&amp;nbsp;추상화&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Backend for Frontend pattern&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;439&quot; data-origin-height=&quot;314&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eEPTTd/btsP5qPMFC5/248pjInK5rPux7h4j8sSaK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eEPTTd/btsP5qPMFC5/248pjInK5rPux7h4j8sSaK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eEPTTd/btsP5qPMFC5/248pjInK5rPux7h4j8sSaK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeEPTTd%2FbtsP5qPMFC5%2F248pjInK5rPux7h4j8sSaK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;439&quot; height=&quot;314&quot; data-origin-width=&quot;439&quot; data-origin-height=&quot;314&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;단일 API Gateway -&amp;gt; SPOF
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;단일하고 복잡한 API Gateway는 아키텍처에 병목 현상 발생&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;특정 Frontend 애플리케이션에 따라 API Gateway 분리&lt;/li&gt;
&lt;li&gt;BFF를 위한 여러 API gateway를 생성하고 클라이언트에 따라 경계를 구분
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사용자 인터페이스에 따라 여러 API Gateway 생성&lt;/li&gt;
&lt;li&gt;클라이언트 애플리케이션에 내부 마이크로서비스와 연결되는 집중 된 인터페이스 제공&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;대규모 시스템 -&amp;gt; 여러 API Gateway 노출
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Web&amp;nbsp;/&amp;nbsp;Mobile&amp;nbsp;/&amp;nbsp;Desktop&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;장점
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;클라이언트 중심 인터페이스&lt;/li&gt;
&lt;li&gt;Frontend 클라이언트 애플리케이션을 위한 집주오하 된 인터페이스&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;단점
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;지연 시간 증가&lt;/li&gt;
&lt;li&gt;여러&amp;nbsp;클라이언트&amp;nbsp;애플리케이션이&amp;nbsp;있는&amp;nbsp;대규모&amp;nbsp;마이크로서비스에&amp;nbsp;적합&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Reference&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마이크로서비스&amp;nbsp;디자인&amp;nbsp;패턴&amp;nbsp;완벽&amp;nbsp;가이드&lt;a href=&quot;https://www.inflearn.com/course/%EB%A7%88%EC%9D%B4%ED%81%AC%EB%A1%9C%EC%84%9C%EB%B9%84%EC%8A%A4-%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4-msa&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.inflearn.com/course/%EB%A7%88%EC%9D%B4%ED%81%AC%EB%A1%9C%EC%84%9C%EB%B9%84%EC%8A%A4-%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4-msa&lt;/a&gt;&lt;/p&gt;</description>
      <category>기타 정보/MSA</category>
      <category>gateway</category>
      <category>microservice</category>
      <category>MSA</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2655</guid>
      <comments>https://xzio.tistory.com/2655#entry2655comment</comments>
      <pubDate>Tue, 26 Aug 2025 15:32:08 +0900</pubDate>
    </item>
    <item>
      <title>Microservice Architecture 통신</title>
      <link>https://xzio.tistory.com/2654</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;MSA 통신 스타일&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;HTTP, REST, gRPC, GraphQL
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Request&lt;/li&gt;
&lt;li&gt;Response&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;HTTP, WebSocket
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Push&lt;/li&gt;
&lt;li&gt;Real time&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;HTTP, AMQP
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Polling (short / long)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Event-Driven Architecture (EDA)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Publish&lt;/li&gt;
&lt;li&gt;Subscribe&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. Request/Response 통신 방법&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;477&quot; data-origin-height=&quot;241&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Y0Ve3/btsP6LLijBv/z4rhKZWskc8uhNNRQK72o0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Y0Ve3/btsP6LLijBv/z4rhKZWskc8uhNNRQK72o0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Y0Ve3/btsP6LLijBv/z4rhKZWskc8uhNNRQK72o0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FY0Ve3%2FbtsP6LLijBv%2Fz4rhKZWskc8uhNNRQK72o0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;477&quot; height=&quot;241&quot; data-origin-width=&quot;477&quot; data-origin-height=&quot;241&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;HTTP, REST
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;동기식 요청/응답 방식&lt;/li&gt;
&lt;li&gt;마이크로서비스 API&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;RESTful API
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;HTTP protocol + method&lt;/li&gt;
&lt;li&gt;GET / POST / PUT / DELETE / PATCH&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;gRPC
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;내부 마이크로서비스 간 통신이 잦을 때&lt;/li&gt;
&lt;li&gt;고성능 + 낮은 지연 시간&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;GraphQL
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;요청 시 사용하는 쿼리에 따라 다른 응답&lt;/li&gt;
&lt;li&gt;HTTP 요청 회수 및 응답 사이즈 줄임&lt;/li&gt;
&lt;li&gt;필요한 데이터 구조 정의 -&amp;gt; 유연성 + 효율성&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. HTTP, WebSocket 기반의 Push + Real time 통신&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;456&quot; data-origin-height=&quot;277&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvOHiv/btsP6Y4Sfiy/owt9yZCtCHL5iKoe42EAL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvOHiv/btsP6Y4Sfiy/owt9yZCtCHL5iKoe42EAL0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvOHiv/btsP6Y4Sfiy/owt9yZCtCHL5iKoe42EAL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbvOHiv%2FbtsP6Y4Sfiy%2Fowt9yZCtCHL5iKoe42EAL0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;456&quot; height=&quot;277&quot; data-origin-width=&quot;456&quot; data-origin-height=&quot;277&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;WebSocket API&lt;/li&gt;
&lt;li&gt;채팅 애플리케이션 (one to many)&lt;/li&gt;
&lt;li&gt;스트리밍 대시보드 -&amp;gt; 양방향 통신 애플리케이션&lt;/li&gt;
&lt;li&gt;클라이언트, 서버 모두 메시지 전송 가능&lt;/li&gt;
&lt;li&gt;백엔드&amp;nbsp;서버는&amp;nbsp;연결&amp;nbsp;된&amp;nbsp;모든&amp;nbsp;사용자에&amp;nbsp;데이터&amp;nbsp;푸시&amp;nbsp;가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. AMQP&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Polling (short, long)&lt;/li&gt;
&lt;li&gt;일정한 시간 마다 새로 고침 (메일 등)&lt;/li&gt;
&lt;li&gt;불필요한 통신 발생 가능&lt;/li&gt;
&lt;li&gt;연결을&amp;nbsp;열고&amp;nbsp;닫는데&amp;nbsp;비용이&amp;nbsp;큼&amp;nbsp;-&amp;gt;&amp;nbsp;확장성에&amp;nbsp;취약&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. EDA&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;491&quot; data-origin-height=&quot;291&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7VLiv/btsP5tq9ZtJ/65vKUi4R4h8emoKatpHGg1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7VLiv/btsP5tq9ZtJ/65vKUi4R4h8emoKatpHGg1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7VLiv/btsP5tq9ZtJ/65vKUi4R4h8emoKatpHGg1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7VLiv%2FbtsP5tq9ZtJ%2F65vKUi4R4h8emoKatpHGg1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;491&quot; height=&quot;291&quot; data-origin-width=&quot;491&quot; data-origin-height=&quot;291&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;마이크로서비스 간 호출 대신 이벤트 생성
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;비동기 방식&lt;/li&gt;
&lt;li&gt;Message Broker System에서 메시지 소비&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;AMQP (Advanced Message Queuing Protocol)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Publish / Subscribe&lt;/li&gt;
&lt;li&gt;Kakfa&amp;nbsp;/&amp;nbsp;RabbitMQ&amp;nbsp;queue&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Reference&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마이크로서비스&amp;nbsp;디자인&amp;nbsp;패턴&amp;nbsp;완벽&amp;nbsp;가이드&lt;a href=&quot;https://www.inflearn.com/course/%EB%A7%88%EC%9D%B4%ED%81%AC%EB%A1%9C%EC%84%9C%EB%B9%84%EC%8A%A4-%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4-msa&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.inflearn.com/course/%EB%A7%88%EC%9D%B4%ED%81%AC%EB%A1%9C%EC%84%9C%EB%B9%84%EC%8A%A4-%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4-msa&lt;/a&gt;&lt;/p&gt;</description>
      <category>기타 정보/MSA</category>
      <category>architecture</category>
      <category>microservice</category>
      <category>MSA</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2654</guid>
      <comments>https://xzio.tistory.com/2654#entry2654comment</comments>
      <pubDate>Mon, 25 Aug 2025 14:27:26 +0900</pubDate>
    </item>
    <item>
      <title>Microservice Architecture</title>
      <link>https://xzio.tistory.com/2653</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;451&quot; data-origin-height=&quot;418&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/diirJ5/btsP45XTkjH/Lkhi39YrNFpX7kYNhz5Km1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/diirJ5/btsP45XTkjH/Lkhi39YrNFpX7kYNhz5Km1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/diirJ5/btsP45XTkjH/Lkhi39YrNFpX7kYNhz5Km1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdiirJ5%2FbtsP45XTkjH%2FLkhi39YrNFpX7kYNhz5Km1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;451&quot; height=&quot;418&quot; data-origin-width=&quot;451&quot; data-origin-height=&quot;418&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Microservice Architecture 개요&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;MSA는 비즈니스 경계(역량)을 중심으로 구축
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;완전히 자동화된 배포 프로세스 + 독립적인 배포&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;MSA는 잘 정의 된 API를 통해 통신하며, 작고 독립적인 서비스로 분해
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;소규모 팀에 의해 관리&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;MSA 서비스는 클라우드 네이티브 아키텍처 방식으로 개발
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;독립적으로 배포 가능한 요소로 구성 (느슨한 결합)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;MSA는 자체 기술 스택을 가지고 REST API 방식으로 통신
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;비즈니스 역량에 따라 제한된 컨텍스트로 구성&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;단일&amp;nbsp;책임&amp;nbsp;원칙(Single&amp;nbsp;Responsibility&amp;nbsp;Principle)에&amp;nbsp;따라&amp;nbsp;서비스의&amp;nbsp;책임&amp;nbsp;분리&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;Microservice Architecture 장점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;민첩한 배포
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;MSA는 애플리케이션을 더 쉽게 확장하고 빠르게 개발하며, 새로운 기능에 대한 배포 시간을 단축&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;유연한 확장성
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;MSA는 전체 애플리케이션을 확장하지 않고, 하위 서비스를 독립적으로 확장 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;소규모의 집중된 팀
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;MSA의 서비스는 단일 팀에 의해 단일 기능을 개발, 빌드, 테스트 가능하도록 구성&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;소규모의 분리된 코드 관리
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;MSA는 다른 서비스와 코드나 데이터 스토리지를 공유하지 않기 때문에 종속성이 최소화 -&amp;gt; 새로운 기능 추가 용이&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CI/CD
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;MSA는 CI/CD를 가능하게 하여 새로운 기능에 대해 쉽게 추가 또는 롤백이 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;다양한 기술 스택
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;소규모 팀에 의한 서비스 개발을 위해 가장 적합한 기술 스택 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Resilience &amp;amp; Fault isolation
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;MSA는 장애 허용(Fault tolerance)으로 서비스 오류 시 재시도 및 회로 차단 패턴 구현&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Data isolation
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;MSA&amp;nbsp;설계에&amp;nbsp;따라&amp;nbsp;스토리지의&amp;nbsp;분리되어,&amp;nbsp;데이터&amp;nbsp;변경에&amp;nbsp;따른&amp;nbsp;영향을&amp;nbsp;최소화&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;Microservice Architecture 단점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Complexity
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;각 서비스는 간단하지만 전체 시스템은 복잡&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;수십, 수백 개의 서비스들에 대한 배포 및 통신으로 인해 시스템 복잡
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Network latency&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;서비스 간 통신으로 인해 네트워크 지연 문제 증가
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Development &amp;amp; Testing&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;여러 서비스로 분산되어 개발
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모놀리스 방식보다 개발과 테스트가 복잡하고 어려움&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Data integrity
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서비스 별로 고유한 데이터 스토리지를 갖음&lt;/li&gt;
&lt;li&gt;데이터 일관성에 어려움&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Deployment
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서비스 개수가 늘어나기 때문에 생기는 배포의 어려움&lt;/li&gt;
&lt;li&gt;DevOps 자동화 프로세스 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Logging &amp;amp; Monitoring
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;분산 시스템으로 구성된 서비스들의 중앙 집중화 된 로그 필요&lt;/li&gt;
&lt;li&gt;문제의 원인 파악을 위한 중앙 집중화 된 모니터링 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Debugging
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서비스 별로 분리 된 개발 환경을 갖지 때문에 디버깅이 어려움&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;제한된 팀 규모, 소규모 팀
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;MSA를 처리할 수 있는 팀 부재 -&amp;gt; 서비스 제공 시간 지연&lt;/li&gt;
&lt;li&gt;MSA 자체의 배포 및 관리만 처리하는 소규모 팀&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Reference&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마이크로서비스&amp;nbsp;디자인&amp;nbsp;패턴&amp;nbsp;완벽&amp;nbsp;가이드&lt;a href=&quot;https://www.inflearn.com/course/%EB%A7%88%EC%9D%B4%ED%81%AC%EB%A1%9C%EC%84%9C%EB%B9%84%EC%8A%A4-%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4-msa&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.inflearn.com/course/%EB%A7%88%EC%9D%B4%ED%81%AC%EB%A1%9C%EC%84%9C%EB%B9%84%EC%8A%A4-%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4-msa&lt;/a&gt;&lt;/p&gt;</description>
      <category>기타 정보/MSA</category>
      <category>architecture</category>
      <category>microservice</category>
      <category>MSA</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2653</guid>
      <comments>https://xzio.tistory.com/2653#entry2653comment</comments>
      <pubDate>Mon, 25 Aug 2025 11:02:43 +0900</pubDate>
    </item>
    <item>
      <title>Modular Monolithic Architecture</title>
      <link>https://xzio.tistory.com/2652</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;433&quot; data-origin-height=&quot;332&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cXLHRF/btsP3ykAGSn/KdCfZzudkPYzF1hFWnqwVK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cXLHRF/btsP3ykAGSn/KdCfZzudkPYzF1hFWnqwVK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cXLHRF/btsP3ykAGSn/KdCfZzudkPYzF1hFWnqwVK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcXLHRF%2FbtsP3ykAGSn%2FKdCfZzudkPYzF1hFWnqwVK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;433&quot; height=&quot;332&quot; data-origin-width=&quot;433&quot; data-origin-height=&quot;332&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Modular Monolithic Architecture 개요&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;애플리케이션 로직을 모듈별로 분리
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;각 모듈은 독립적이고 고립적, 자체 기능 캡슐화&lt;/li&gt;
&lt;li&gt;자체 비즈니스 로직, 데이터베이스 스키마를 가짐&lt;/li&gt;
&lt;li&gt;코드를 독립적인 모듈로 구분&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;각 모듈은 자체 논리적 분리, 계층적 아키텍처 스타일 또는 Clean Architecture로 구성
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모듈은 애플리케이션 도메인의 Bounded Context를 나타냄&lt;/li&gt;
&lt;li&gt;도메인 컨텍스트의 기능을 모듈로 그룹화&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;모듈&amp;nbsp;간의&amp;nbsp;종속성을&amp;nbsp;줄이고&amp;nbsp;다른&amp;nbsp;모듈에&amp;nbsp;영향을&amp;nbsp;미치지&amp;nbsp;않고&amp;nbsp;모듈을&amp;nbsp;개발하거나&amp;nbsp;수정&amp;nbsp;가능&lt;/li&gt;
&lt;li&gt;분리 된 모듈은 나중에 아키텍처를 Refactoring 가능
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;독립적으로 배포, 확장&lt;/li&gt;
&lt;li&gt;잠재적인&amp;nbsp;Microservice&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;Modular Monolithic Architecture 장점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Encapsulation
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;비즈니스 로직이 모듈에 캡슐화 -&amp;gt; 높은 재사용성 제공, 일관 된 데이터, 단순한 Communication pattern&lt;/li&gt;
&lt;li&gt;모듈에 따른 코드 분리&lt;/li&gt;
&lt;li&gt;재사용 가능한 코드, 리팩토링이 쉬움&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Dependency
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모듈식 모놀리스 아키텍처를 사용하면 애플리케이션 종속성이 더 체계적이고 직관적&lt;/li&gt;
&lt;li&gt;개발자는 애플리케이션의 어느 부분에 어떤 종속성이 필요한지 쉽게 평가 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Complexity
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;수백 개의 마이크로서비스보다 모듈식 모놀리스를 관리하기가 더 쉬움&lt;/li&gt;
&lt;li&gt;모듈식 모놀리스는 기본 인프라와 낮은 운영 비용으로 운영 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Team
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;개발자가 코드의 여러 부분에서 작업하기가 더 쉬움&lt;/li&gt;
&lt;li&gt;개발자&amp;nbsp;팀을&amp;nbsp;효과적으로&amp;nbsp;나누고&amp;nbsp;서로에게&amp;nbsp;최소한의&amp;nbsp;영향을&amp;nbsp;미치는&amp;nbsp;비즈니스&amp;nbsp;요구&amp;nbsp;사항&amp;nbsp;구현&amp;nbsp;가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;Modular Monolithic Architecture 단점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Polyglot
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기술 다양화의 어려움&lt;/li&gt;
&lt;li&gt;Polyglot 기술 스택은 Modular Monolithic Architecture와 함께 사용할 수 없음&lt;/li&gt;
&lt;li&gt;Microservice의 모든 이점을 제공하지 않음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Deployment
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;애플리케이션이 단일 단위 -&amp;gt; 독립적으로 확장 및 배포 불가&lt;/li&gt;
&lt;li&gt;애플리케이션은&amp;nbsp;확장성&amp;nbsp;한계&amp;nbsp;-&amp;gt;&amp;nbsp;성능&amp;nbsp;문제&amp;nbsp;-&amp;gt;&amp;nbsp;Microservice화&amp;nbsp;필요&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Monolithic Architecture, Modular Monolithic Architecture 패키지 구조 비교&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 557px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 557px;&quot;&gt;
&lt;td style=&quot;width: 50%; text-align: center; height: 557px;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;그림1.jpg&quot; data-origin-width=&quot;330&quot; data-origin-height=&quot;536&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lClZV/btsP6biIALU/dI72uWVXVs8Q4KBuM9kSZK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lClZV/btsP6biIALU/dI72uWVXVs8Q4KBuM9kSZK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lClZV/btsP6biIALU/dI72uWVXVs8Q4KBuM9kSZK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlClZV%2FbtsP6biIALU%2FdI72uWVXVs8Q4KBuM9kSZK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;330&quot; height=&quot;536&quot; data-filename=&quot;그림1.jpg&quot; data-origin-width=&quot;330&quot; data-origin-height=&quot;536&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br /&gt;Monolithic Architecture&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center; height: 557px;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;그림2.jpg&quot; data-origin-width=&quot;298&quot; data-origin-height=&quot;518&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mfMEi/btsP27oTJ5u/E41jfr7YvkDOrfwCKBFOX1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mfMEi/btsP27oTJ5u/E41jfr7YvkDOrfwCKBFOX1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mfMEi/btsP27oTJ5u/E41jfr7YvkDOrfwCKBFOX1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmfMEi%2FbtsP27oTJ5u%2FE41jfr7YvkDOrfwCKBFOX1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;298&quot; height=&quot;518&quot; data-filename=&quot;그림2.jpg&quot; data-origin-width=&quot;298&quot; data-origin-height=&quot;518&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;span&gt;&lt;br /&gt;&lt;/span&gt;Modular Monolithic Architecture&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Reference&lt;/b&gt;&lt;br /&gt;마이크로서비스&amp;nbsp;디자인&amp;nbsp;패턴&amp;nbsp;완벽&amp;nbsp;가이드&lt;br /&gt;&lt;a href=&quot;https://www.inflearn.com/course/%EB%A7%88%EC%9D%B4%ED%81%AC%EB%A1%9C%EC%84%9C%EB%B9%84%EC%8A%A4-%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4-msa&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.inflearn.com/course/%EB%A7%88%EC%9D%B4%ED%81%AC%EB%A1%9C%EC%84%9C%EB%B9%84%EC%8A%A4-%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4-msa&lt;/a&gt;&lt;/p&gt;</description>
      <category>기타 정보/MSA</category>
      <category>modular</category>
      <category>Monolithic</category>
      <category>MSA</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2652</guid>
      <comments>https://xzio.tistory.com/2652#entry2652comment</comments>
      <pubDate>Fri, 22 Aug 2025 11:26:46 +0900</pubDate>
    </item>
    <item>
      <title>Monolithic Architecture</title>
      <link>https://xzio.tistory.com/2651</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;330&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/omD1m/btsPZqIk4Ta/Jrj4ENKCRLoMMnKwB2KHb1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/omD1m/btsPZqIk4Ta/Jrj4ENKCRLoMMnKwB2KHb1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/omD1m/btsPZqIk4Ta/Jrj4ENKCRLoMMnKwB2KHb1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FomD1m%2FbtsPZqIk4Ta%2FJrj4ENKCRLoMMnKwB2KHb1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;378&quot; height=&quot;330&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;330&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Monolithic Architecture 개요&lt;span style=&quot;color: #1f415e;&quot;&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;소프트웨어 개발에 대한 기존 접근 방식&lt;/li&gt;
&lt;li&gt;단일 단위로 완전한 애플리케이션 개발
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;대부분의 레거시 애플리케이션&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;단일 코드베이스 개발
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;UI + Biz Layer + Data Layer -&amp;gt; 동일한 코드베이스&lt;/li&gt;
&lt;li&gt;단일&amp;nbsp;패키지(jar/war)&amp;nbsp;파일로&amp;nbsp;대규모&amp;nbsp;배포&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;오랜 된 아키텍처 -&amp;gt; 특정 시나리오에는 여전히 유효&lt;/li&gt;
&lt;li&gt;작은 애플리케이션&lt;/li&gt;
&lt;li&gt;빌드 / 테스트 / 배포 / 문제 해결 / 수직 확장(Scale Up)&lt;/li&gt;
&lt;li&gt;Microservice에 비해 개발이 간단&lt;/li&gt;
&lt;li&gt;쉬운 배포 -&amp;gt; 단일 jar/war 파일&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;Monolithic Architecture 장점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;개발이 간편
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기존 개발팀은 모놀리식 애플리케이션을 개발할 수 있는 올바른 지식과 역량을 갖추고 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;디버깅 및 테스트가 더 간편
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;디버깅 및 테스트가 훨씬 더 간편&lt;/li&gt;
&lt;li&gt;단일 코드 기반 -&amp;gt; End-to-End 테스트를 훨씬 더 빠르게 실행 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;배포 간편
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;여러 배포를 처리할 필요 없이, 파일이나 디렉토리 하나만 배포하는 형태&lt;/li&gt;
&lt;li&gt;단일&amp;nbsp;jar/war&amp;nbsp;파일만&amp;nbsp;배포되므로&amp;nbsp;배포가&amp;nbsp;더&amp;nbsp;용이&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;Monolithic Architecture 단점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;시간이 지남에 따라 복잡해짐 -&amp;gt; 이해하기 어려움
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;시간이 지남에 따라 크기가 너무 커져서 관리 어려워짐&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;새로운 변경을 하는 것이 어려움
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;매우 긴밀한 결합으로 인해 복잡한 애플리케이션에서 새로운 변경을 구현하는 것이 더 어려움&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;확장하기 어려움
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;구성 요소를 독립적으로 확장할 수 없음 -&amp;gt; 전체 애플리케이션을 확장&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;새로운 기술 도입에 대한 장벽
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모놀리스에서&amp;nbsp;발견되는&amp;nbsp;상호&amp;nbsp;연결된&amp;nbsp;종속성&amp;nbsp;문제&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;reference&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마이크로서비스&amp;nbsp;디자인&amp;nbsp;패턴&amp;nbsp;완벽&amp;nbsp;가이드&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://www.inflearn.com/course/%EB%A7%88%EC%9D%B4%ED%81%AC%EB%A1%9C%EC%84%9C%EB%B9%84%EC%8A%A4-%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4-msa&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.inflearn.com/course/%EB%A7%88%EC%9D%B4%ED%81%AC%EB%A1%9C%EC%84%9C%EB%B9%84%EC%8A%A4-%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4-msa&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;/div&gt;</description>
      <category>기타 정보/MSA</category>
      <category>Monolithic</category>
      <category>MSA</category>
      <category>마이크로서비스</category>
      <category>모놀리식</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2651</guid>
      <comments>https://xzio.tistory.com/2651#entry2651comment</comments>
      <pubDate>Thu, 21 Aug 2025 11:17:50 +0900</pubDate>
    </item>
    <item>
      <title>[Kafka Connect] Connector Rest API 정리</title>
      <link>https://xzio.tistory.com/2649</link>
      <description>&lt;h2 id=&quot;connector&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;Connector&lt;/h2&gt;
&lt;h4 id=&quot;connector-목록-조회&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;connector 목록 조회&lt;/h4&gt;
&lt;pre class=&quot;routeros&quot; style=&quot;background-color: #fbfcfd; color: #24292e; text-align: left;&quot;&gt;&lt;code&gt;curl -X GET &quot;http://localhost:8083/connectors/&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;connector-상세-정보-조회&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;connector 상세 정보 조회&lt;/h4&gt;
&lt;pre class=&quot;routeros&quot; style=&quot;background-color: #fbfcfd; color: #24292e; text-align: left;&quot;&gt;&lt;code&gt;curl -X GET &quot;http://localhost:8083/connectors?expand=status&amp;amp;expand=info&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;connector-config-조회&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;connector config 조회&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;GET 으로도 동일하게 동작함&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;sas&quot; style=&quot;background-color: #fbfcfd; color: #24292e; text-align: left;&quot;&gt;&lt;code&gt;curl -X PUT &quot;http://localhost:8083/connectors/{connector_name}/config&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;특정-connector-상태-조회&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;특정 connector 상태 조회&lt;/h4&gt;
&lt;pre class=&quot;routeros&quot; style=&quot;background-color: #fbfcfd; color: #24292e; text-align: left;&quot;&gt;&lt;code&gt;curl -X GET &quot;http://localhost:8083/connectors/{connector_name}/status&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;connector-재시작&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;connector 재시작&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;※ task는 재시작되지 않음&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;nginx&quot; style=&quot;background-color: #fbfcfd; color: #24292e; text-align: left;&quot;&gt;&lt;code&gt;curl -X POST &quot;http://localhost:8083/connectors/{connector_name}/restart&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;connector-일시중지-pause&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;connector 일시중지 (pause)&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;비동기 방식이므로 상태 조회시 바로 PAUSE 를 리턴하지 않을 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;sas&quot; style=&quot;background-color: #fbfcfd; color: #24292e; text-align: left;&quot;&gt;&lt;code&gt;curl -X PUT &quot;http://localhost:8083/connectors/{connector_name}/pause&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;connector-복귀-resume&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;connector 복귀 (resume)&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;pause 상태인 connector 를 복귀시킨다.&lt;/li&gt;
&lt;li&gt;비동기 방식이므로 상태 조회시 바로 RUNNING을 리턴하지 않을 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;connector-삭제&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;connector 삭제&lt;/h4&gt;
&lt;pre class=&quot;sas&quot; style=&quot;background-color: #fbfcfd; color: #24292e; text-align: left;&quot;&gt;&lt;code&gt;curl -X DELETE &quot;http://localhost:8083/connectors/{connector_name}&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 id=&quot;task&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;Task&lt;/h2&gt;
&lt;h4 id=&quot;connector의-task-목록-조회&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;connector의 task 목록 조회&lt;/h4&gt;
&lt;pre class=&quot;routeros&quot; style=&quot;background-color: #fbfcfd; color: #24292e; text-align: left;&quot;&gt;&lt;code&gt;curl -X GET &quot;http://localhost:8083/connectors/{connector_name}/tasks&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;connector-의-task-상태-조회&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;connector 의 task 상태 조회&lt;/h4&gt;
&lt;pre class=&quot;routeros&quot; style=&quot;background-color: #fbfcfd; color: #24292e; text-align: left;&quot;&gt;&lt;code&gt;curl -X GET &quot;http://localhost:8083/connectors/{connector_name}/tasks/{task_id}/status&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;connector-의-task-재시작&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;connector 의 task 재시작&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;※ connector 가 RUNNING, task 가 FAIL 일 경우 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;dust&quot; style=&quot;background-color: #fbfcfd; color: #24292e; text-align: left;&quot;&gt;&lt;code&gt;curl -X POST &quot;http://localhost:8083/connectors/{connector_name}/tasks/{task_id}/restart&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 id=&quot;topic&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;Topic&lt;/h2&gt;
&lt;h4 id=&quot;connector-topic-조회&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;connector topic 조회&lt;/h4&gt;
&lt;pre class=&quot;routeros&quot; style=&quot;background-color: #fbfcfd; color: #24292e; text-align: left;&quot;&gt;&lt;code&gt;curl -X GET &quot;http://localhost:8083/connectors/{connector_name}/topics&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;connector-topic-reset&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;connector topic reset&lt;/h4&gt;
&lt;pre class=&quot;sas&quot; style=&quot;background-color: #fbfcfd; color: #24292e; text-align: left;&quot;&gt;&lt;code&gt;curl -X PUT &quot;http://localhost:8083/connectors/{connector_name}/topics/reset&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 id=&quot;connector-plugin&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;Connector Plugin&lt;/h2&gt;
&lt;h4 id=&quot;kafka-connector-cluster-에-설치된-모든-plugin-목록-조회&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;Kafka Connector Cluster 에 설치된 모든 plugin 목록 조회&lt;/h4&gt;
&lt;pre class=&quot;routeros&quot; style=&quot;background-color: #fbfcfd; color: #24292e; text-align: left;&quot;&gt;&lt;code&gt;curl -X GET &quot;http://localhost:8083/connector-plugins&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;kafka-connector-plgin-validate&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;Kafka Connector plgin validate&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;※ plugin 종류에 따라 필수 field가 다를 수 있음&lt;/li&gt;
&lt;li&gt;ex) FileStreamSinkConnector 로 test-topic 에 대해 validate 할 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;scilab&quot; style=&quot;background-color: #fbfcfd; color: #24292e; text-align: left;&quot;&gt;&lt;code&gt;echo '{&quot;connector.class&quot;: &quot;org.apache.kafka.connect.file.FileStreamSinkConnector&quot;, &quot;tasks.max&quot;: &quot;1&quot;, &quot;topics&quot;: &quot;test-topic&quot;}' | curl -X PUT -d -@ &quot;http://localhost:8083/connector-plugins/FileStreamSinkConnector/config/validate&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.confluent.io/platform/current/connect/references/restapi.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;reference : 공식 Document&lt;/a&gt;&lt;/p&gt;</description>
      <category>Apache Kafka/Kafka Connect</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2649</guid>
      <comments>https://xzio.tistory.com/2649#entry2649comment</comments>
      <pubDate>Fri, 16 May 2025 13:53:01 +0900</pubDate>
    </item>
    <item>
      <title>IntelliJ &amp;quot;Server's Certificate is not trusted&amp;quot; 메시지 노출 해결</title>
      <link>https://xzio.tistory.com/2638</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;IntelliJ를 회사에서 사용하다 보면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;SSL 통신을 할 때, 회사에서는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;방화벽 문제로 인해서 Server Certificates 오류가 발생 할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;Server's Certificate is not trusted&quot; 메시지가 계속 노출 됩니다.&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;570&quot; data-origin-height=&quot;175&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/v2YiM/btsL7dMRXDW/YPKn0FCsmXNjLeaThnm6UK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/v2YiM/btsL7dMRXDW/YPKn0FCsmXNjLeaThnm6UK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/v2YiM/btsL7dMRXDW/YPKn0FCsmXNjLeaThnm6UK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fv2YiM%2FbtsL7dMRXDW%2FYPKn0FCsmXNjLeaThnm6UK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;570&quot; height=&quot;175&quot; data-origin-width=&quot;570&quot; data-origin-height=&quot;175&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;아래와 같이 해결&lt;/h3&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;File &amp;gt; Settings &amp;gt; Tools &amp;gt; Server Certificates 에서 Accept non-trusted certificates automatically 체크박스 체크&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;233&quot; data-origin-height=&quot;526&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d2nIML/btsL7NtnLZr/lOIqylMRiVBKmy5pj6qXYK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d2nIML/btsL7NtnLZr/lOIqylMRiVBKmy5pj6qXYK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d2nIML/btsL7NtnLZr/lOIqylMRiVBKmy5pj6qXYK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd2nIML%2FbtsL7NtnLZr%2FlOIqylMRiVBKmy5pj6qXYK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;233&quot; height=&quot;526&quot; data-origin-width=&quot;233&quot; data-origin-height=&quot;526&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;659&quot; data-origin-height=&quot;138&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DaqOO/btsL8Ygon4u/u6XcsV2PocB57mFhKlZaq0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DaqOO/btsL8Ygon4u/u6XcsV2PocB57mFhKlZaq0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DaqOO/btsL8Ygon4u/u6XcsV2PocB57mFhKlZaq0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDaqOO%2FbtsL8Ygon4u%2Fu6XcsV2PocB57mFhKlZaq0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;659&quot; height=&quot;138&quot; data-origin-width=&quot;659&quot; data-origin-height=&quot;138&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>IDE Tool/IntelliJ IDEA</category>
      <category>certificate</category>
      <category>IntelliJ</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2638</guid>
      <comments>https://xzio.tistory.com/2638#entry2638comment</comments>
      <pubDate>Wed, 5 Feb 2025 13:59:41 +0900</pubDate>
    </item>
    <item>
      <title>[Git] SSL certificate problem : self signed certificate 오류</title>
      <link>https://xzio.tistory.com/2637</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;회사 업무용 PC에서 인터넷 공인망을 차단하여&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SSL&amp;nbsp;certificate&amp;nbsp;problem&amp;nbsp;:&amp;nbsp;self&amp;nbsp;signed&amp;nbsp;certificate&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메시지가 노출되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원인은&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SSL 보안서버 인증서를 구매하여 사용하지 않고, Open SSL 인증서를 사용한 경우 git push시 SSL에러가 발생합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저의 경우는 인터넷을 차단하여 인증기관을 연결하지 못해 메시지 노출되었네요.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이를 해결하기 위해&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;CA에서 인증하는 절차를 무시&lt;/b&gt;하는 방법이 있습니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;windows  경우 cmd에서, macOs는 terminal에서 아래 명령어를 입력&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1738289053457&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git config --global http.sslVerify false&lt;/code&gt;&lt;/pre&gt;
&lt;div style=&quot;background-color: #ffffff; color: #f0f0f0; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;명령어를 사용하여 global값을 설정합니다.&lt;/p&gt;</description>
      <category>형상관리/Git</category>
      <category>GIT</category>
      <category>Self Signed Certificate</category>
      <category>ssl certificate problem</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2637</guid>
      <comments>https://xzio.tistory.com/2637#entry2637comment</comments>
      <pubDate>Fri, 31 Jan 2025 11:07:23 +0900</pubDate>
    </item>
    <item>
      <title>.gitignore 정상적으로 작동 안될 때</title>
      <link>https://xzio.tistory.com/2636</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;.gitignore이란 ?&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Project에 원하지 않는 파일들을(컴파일 된 파일, .gradle, .idea 등등) git에서 제외시키기 위해 필요한 파일&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;&lt;b&gt;.gitignore의 파일 위치는 ?&lt;/b&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;프로젝트 최상단 디렉토리에 위치해야한다. 예를들어 git init 명령어를 실행했던 디렉토리에 .gitignore 폴더가 위치하게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;intellij에서 자동으로 추가되는 .gitignore&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1736964658542&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;HELP.md
.gradle
build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/

### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/

### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
out/
!**/src/main/**/out/
!**/src/test/**/out/

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/

### VS Code ###
.vscode/&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;b&gt;근데 .gitignore를 추가했는데 파일들이 제외되지 않는 경우&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;git에 커밋을 한 후 뒤늦게 .gitignore파일을 생성하였는데 &lt;/span&gt;&lt;span&gt;.gradle 파일이 계속해서 제외되지 않는 형상이 발생했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;해결을 위해 나는 아래의 명령어를 사용해 보았다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;bash&quot; style=&quot;background-color: #eff0f1; color: #242729;&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;git rm --cached .gradle -r&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그래도 .gitignore에서 선언된 파일들이 제외되지 않는다면 캐시를 날리고 .gitignore를 다시 생성하여 push&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;bash&quot; style=&quot;background-color: #f7f7f7; color: #4d4d4c; text-align: justify;&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;git rm -r --cached&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>형상관리/Git</category>
      <category>.gitignore</category>
      <category>.gradle</category>
      <category>.idea</category>
      <category>GIT</category>
      <category>gitignore</category>
      <category>Gradle</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2636</guid>
      <comments>https://xzio.tistory.com/2636#entry2636comment</comments>
      <pubDate>Thu, 16 Jan 2025 03:14:14 +0900</pubDate>
    </item>
    <item>
      <title>REST API 사용을 위한 인증 방법 4가지</title>
      <link>https://xzio.tistory.com/2634</link>
      <description>&lt;h1 style=&quot;color: #000000;&quot;&gt;REST API 사용을 위한 인증 방법 4가지&lt;/h1&gt;
&lt;div style=&quot;background-color: color(srgb 1 1 1); color: color(srgb 0.120353 0.120353 0.120353); text-align: start;&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Stateless 한 REST API 를 사용하기 위해서는 4가지의 인증방법이 있다. Basic Authentication, Token Authentication, API Key &amp;amp; Secret Authentication, OAuth2.0(Open Authorization) 이 그것이다.&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;1. Basic Authentication&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HTTP 표준 사양에 따라 매 요청시 헤더의 Authorization 필드에 아이디와 패스워드를 넘겨주는 방식으로 사용자를 인증하는 방식이다.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방식은 보안상 매우 취약하고 탈취가 쉽다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 SAP 방식에서는 자바스크립트 코드가 그대로 드러나기 때문에 더 위험하다.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;2. API Token Based Authentication&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;프로세스&lt;/div&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;API 클라이언트는 사용자의 아이디와 비밀번호로 로그인을 하여 API 토큰을 요청한다.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;API 인증서버는 사용자의 아이디와 비밀번호를 바탕으로 사용자를 인증한다.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인증된 사용자에 대해서 유효시간이 정해진 API 토큰을 발급한다.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;API 클라이언트는 매 API 호출시마다 해당 토큰을 포함하여 요청한다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;API 서버는 토큰이 유효한지 토큰관리서버에 문의하고 유효할 경우에만 API 호출을 허용한다.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유효하지 않으면 다시 토큰을 발급받도록 처리한다.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;특징&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;API Key 방식보다 보안적으로 뛰어나다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아이디와 비밀번호가 노출되지 않으므로 토큰이 탈취당하더라도 사용자의 정보는 안전하다.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;토큰에는 짧은 유효기간이 있기 때문에 탈취당한 토큰 마저도 일정 시간 이후에는 무효화된다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보통 토큰에 날자와 시간을 함께 인코딩하여 특정 시간 이후로 사용 불가하게 한다.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Stateless 하다. 서버에서 세션 등 상태를 기억하지 않으므로 클라이언트에서 오는 요청만 처리한다. 클라이언트와 서버가 완전히 때문에 확장성이 높아지게 된다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모바일 어플리케이션은 쿠키나 세션 등의 인증시스템을 사용할 수 없는데, 토큰 인증 방식은 이를 간단하게 해결할 수 있다.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대표적으로 JSON Web Token(JWT)가 있다. key-value 페어로 이루어지고 claims 라고 불린다.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;3. API Key &amp;amp; Secret Authentication&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;프로세스&lt;/div&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;API 제공자로부터 임의의 문자열을 발급받는다.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;API 요청시 해당 문자열을 포함하여 요청한다.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서버는 메시지 내부의 API 키를 읽어서 누가 호출한 API인지를 확인한다.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 Key의 인증과 인가에 따라 사용자에게 응답한다.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;특징&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클라이언트가 API에 접근하기 위해서 API 에 가입하는 과정이 필요하다.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가입하면 API 서버가 Key와 Secret 을 각각의 가입된 클라이언트에게 부여한다. 이 부여된 Secret 으로 클라이언트는 서버에 접근할 수 있다.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구현이 간단하다.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보안상 취약하다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹, 모바일 등 모든 클라이언트가 같은 API 키를 공유하기 때문에 한번 API 키가 노출되면, 전체 API가 뚫려버린다. 높은 인증이 필요할 때는 권장하지 않는다.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;통신구간이 암호화가 잘 되어있더라도 Key 가 유출될 경우 대비하기 힘들다.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 방지하기 위해 주기적으로 key도 업데이트 해야하는 번거로움이 있다.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그마저 클라이언트와 서버의 Key 업데이트 싱크가 맞지 않으면 서로 매치가 안되는 등 예기치 못한 상황이 발생할 수도 있다.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 클라이언트에게 매번 부여하기가 어렵다. 즉, 고정된 키이다.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;4. OAuth2.0(Open Authorization)&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;프로세스&lt;/div&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;은행에 접근해서 아이디를 제출한다.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;은행은 해당 아이디의 리소스 접근 권한이 필요하다고 요청한다.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;은행은 다른 권한 제공 업체를 통해 엑세스 토큰을 마이크에게 제공한다.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마이크는 은행에 해당 엑세스 토큰과 함께 아이디를 다시 제공한다.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;은행은 해당 토큰과 아이디로 마이크의 접근을 허용한다. 그리고 이를 권한 제공 업체가 보증한다.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;특징&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;API Key 방식이나 API Token 방식에 비해 보안상 안전하다.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;참고&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://medium.com/@lys0333/api-authentication-%EC%A0%84%EB%9E%B5-%EC%A2%85%EB%A5%98-2b949ad45047&quot;&gt;https://medium.com/@lys0333/api-authentication-%EC%A0%84%EB%9E%B5-%EC%A2%85%EB%A5%98-2b949ad45047&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://coder-in-war.tistory.com/entry/WEB-08-%EB%8B%A4%EC%96%91%ED%95%9C-%EC%9D%B8%EC%A6%9D%EB%B0%A9%EC%8B%9D-Authentication-Authorization&quot;&gt;https://coder-in-war.tistory.com/entry/WEB-08-%EB%8B%A4%EC%96%91%ED%95%9C-%EC%9D%B8%EC%A6%9D%EB%B0%A9%EC%8B%9D-Authentication-Authorization&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출처 : &lt;a href=&quot;https://wiki.mhson.world/cs/basic-knowledge/rest-api-4&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://wiki.mhson.world/cs/basic-knowledge/rest-api-4&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</description>
      <category>해킹과 보안/보안 관련</category>
      <category>Authentication</category>
      <category>OAuth2.0</category>
      <category>Token</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2634</guid>
      <comments>https://xzio.tistory.com/2634#entry2634comment</comments>
      <pubDate>Tue, 29 Oct 2024 17:48:58 +0900</pubDate>
    </item>
    <item>
      <title>Test 코드에서 @Slf4j 사용하기</title>
      <link>https://xzio.tistory.com/2578</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로 스프링 부트로 개발을 할 때 lombok 라이브러리는 거의 필수입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;@Slf4j를 쉽게 어노테이션 형식으로 사용합니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;(@Slf4j는&lt;span&gt;&amp;nbsp;&lt;/span&gt;Simple Logging Facade for Java의 줄임말)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;사용법은 간단합니다. 일반 클래스에서는 아래 코드와 같이 사용합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1724397159999&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Slf4j
@RequiredArgsConstructor
@RequestMapping(&quot;/v1/api/members&quot;)
@RestController
public class MemberController {

    @PostMapping
    public String createMember(@RequestBody @Validated MemberRequest memberRequest) {
        log.info(&quot;정보 확인 -&amp;gt;{}&quot;, memberRequest);
        return &quot;success&quot;;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;프로젝트 경로에서 test 내부에 테스트 코드를 만들고 일반적인 서버에서 사용하듯 클래스 최상위에 동일하게 작성하면 됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1724397177524&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Slf4j
@SpringBootTest
class MemberControllerTest {&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;그런데 기본 세팅에서는 테스트코드에서는 @Slf4j라고 쓴다고 해서 바로 사용할 수 없습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;gradle설정이 추가로 필요&lt;/b&gt;합니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;build.gradle 파일에 dependencies 항목에 다음과 같이 추가해야 사용 가능합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1724397190698&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;testCompileOnly 'org.projectlombok:lombok'
testAnnotationProcessor 'org.projectlombok:lombok'&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>테스트 코드/JUnit</category>
      <category>slf4j</category>
      <category>로깅</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2578</guid>
      <comments>https://xzio.tistory.com/2578#entry2578comment</comments>
      <pubDate>Fri, 23 Aug 2024 16:16:37 +0900</pubDate>
    </item>
    <item>
      <title>[JSP, HTML] 소스로 사용자 브라우져 캐시 삭제 또는 초기화하기</title>
      <link>https://xzio.tistory.com/2509</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;화면을 수정했는데, 클라이언트의 브라우져에 캐시가 남아서 이전 화면이 나오는 경우가 있다.&lt;br /&gt;직접 브라우져 설정 들어가서 캐시를 지워달라고 요청 할 수도 있지만, 그게 한두번이 아니게 되니 코드에서 캐시를 지울수 없는지 찾아보았다.&lt;br /&gt;이럴수가...&lt;br /&gt;크게 어렵지도 않지만, html한정으로 이게 꼭 필요한 화면이 아니면 아래 설정은 가급적 안 하는게 좋을 것 같다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ensp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;HTML 메타태그 이용하기&lt;/h2&gt;
&lt;pre class=&quot;xml&quot; style=&quot;background-color: #fafafa; color: #000000; text-align: start;&quot;&gt;&lt;code&gt;    &amp;lt;!-- 1990년 이후 이 페이지의 캐시를 만료시킴. --&amp;gt;
    &amp;lt;meta http-equiv=&quot;Expires&quot; content=&quot;Mon, 06 Jan 1990 00:00:01 GMT&quot; /&amp;gt;

    &amp;lt;!-- 캐시를 바로 만료시킴. --&amp;gt;
    &amp;lt;meta http-equiv=&quot;Expires&quot; content=&quot;-1&quot; /&amp;gt;

    &amp;lt;!-- 페이지 로드시마다 페이지를 캐싱하지 않음. (HTTP 1.0) --&amp;gt;
    &amp;lt;meta http-equiv=&quot;Pragma&quot; content=&quot;no-cache&quot; /&amp;gt;

    &amp;lt;!-- 페이지 로드시마다 페이지를 캐싱하지 않음. (HTTP 1.1) --&amp;gt;
    &amp;lt;meta http-equiv=&quot;Cache-Control&quot; content=&quot;no-cache&quot; /&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ensp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;JSP, Java 사용시&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;자바 코드 지만 html과 같음.&lt;/p&gt;
&lt;pre class=&quot;sql&quot; style=&quot;background-color: #fafafa; color: #000000; text-align: start;&quot;&gt;&lt;code&gt;    response.setHeader( &quot;Pragma&quot;, &quot;no-cache&quot; );
    response.setDateHeader( &quot;Expires&quot;, -1 );
    response.setHeader( &quot;Cache-Control&quot;, &quot;no-cache&quot; );&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ensp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;JS, CSS 파일 캐시 사용 방지&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;js나 css등 정적파일도 종종 변경을 해도 캐시문제로 적용이 되지 않는 경우가 많다.&lt;br /&gt;그럴 경우 파일의 url 뒤에&lt;span&gt;&amp;nbsp;&lt;/span&gt;?timestamp&lt;span&gt;&amp;nbsp;&lt;/span&gt;형태를 넣어준다.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot; style=&quot;background-color: #fafafa; color: #000000; text-align: start;&quot;&gt;&lt;code&gt;  &amp;lt;link rel=&quot;stylesheet&quot; href=&quot;/css/common.css?20210512&quot; /&amp;gt;
  &amp;lt;script type=&quot;text/javascript&quot; src=&quot;/js/common.js?20210512&quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출처 : &lt;a href=&quot;https://jeaha.dev/114&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://jeaha.dev/114&lt;/a&gt;&lt;/p&gt;</description>
      <category>Java 관련/JSTL, EL</category>
      <category>EL</category>
      <category>JSP</category>
      <category>JSTL</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2509</guid>
      <comments>https://xzio.tistory.com/2509#entry2509comment</comments>
      <pubDate>Tue, 9 Apr 2024 11:12:41 +0900</pubDate>
    </item>
    <item>
      <title>[JSP, JSTL] fn function 정리 - 2</title>
      <link>https://xzio.tistory.com/2508</link>
      <description>&lt;h1 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;jstl 내장함수&lt;/h1&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;JSTL functions은 JSTL에서 제공하는 각종 함수를 사용해서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;문자열&lt;/b&gt;이나,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;컬렉션&lt;/b&gt;들을 처리함.&lt;br /&gt;fn태그는 단독으로 사용할 수 없고 EL 표현식 내에서 사용해야함.&lt;br /&gt;like&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;${fn:length(...)}&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;jsp 페이지 시작점에 다음 태그로 선언 해줘야 사용 할 수 있음.&lt;/p&gt;
&lt;pre class=&quot;gcode&quot; style=&quot;background-color: #fafafa; color: #000000; text-align: start;&quot;&gt;&lt;code&gt;  &amp;lt;%@ taglib prefix=&quot;fn&quot; uri=&quot;http://java.sun.com/jsp/jstl/functions&quot; %&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;boolean&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;contains&lt;/b&gt;(String sting, String substring)&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;string이 substring을 포함하면 return true.&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;boolean&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;containsIgnoreCase&lt;/b&gt;(String string, String substring)&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;대소문자에 관계없이, string이 substring을 포함하면 return true.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;rust&quot; style=&quot;background-color: #fafafa; color: #000000; text-align: start;&quot;&gt;&lt;code&gt;  ${fn:contains(&quot;helloworld&quot;, &quot;world&quot;)} // true

  ${fn:containsIgnoreCase(&quot;hello world!&quot;, &quot;WoRLd&quot;)} // true&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;boolean&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;startsWith&lt;/b&gt;(String string, String prefix)&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;string이 prefix로 시작하면 return true.&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;boolean&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;endsWith&lt;/b&gt;(String string, String substring)&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;string이 suffix로 끝나면 return true.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;rust&quot; style=&quot;background-color: #fafafa; color: #000000; text-align: start;&quot;&gt;&lt;code&gt;  ${fn:startsWith(&quot;hello world!&quot;, &quot;ld!&quot;)} // false

  ${fn:endsWith(&quot;hello world!&quot;, &quot;ld!&quot;)} // true&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;String&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;escapeXml&lt;/b&gt;(String string)&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;string에서 XML, HTML의 &amp;lt; &amp;gt;&amp;amp; ' &quot; 문자들을 각각 &amp;lt; &amp;gt; &amp;amp; ' &quot;로 치환하여 리턴.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;kotlin&quot; style=&quot;background-color: #fafafa; color: #000000; text-align: start;&quot;&gt;&lt;code&gt;  &amp;lt;c:out value=&quot;${fn:escapeXml('&amp;lt;&amp;gt;')}&quot;/&amp;gt; // &amp;amp;lt;&amp;amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;int&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;indexOf&lt;/b&gt;(String string, String substring)&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;string에서 substring이 처음으로 나타나는 인덱스 리턴.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;rust&quot; style=&quot;background-color: #fafafa; color: #000000; text-align: start;&quot;&gt;&lt;code&gt;  ${fn:indexOf(&quot;abcdefg&quot;, &quot;f&quot;)} // 5&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;String[]&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;split&lt;/b&gt;(String string, String separator)&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;string 내의 문자열을 separator에 따라 잘라내서 잘려진 문자열들을 배열로 리턴.&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;String&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;join&lt;/b&gt;(String[] strings, String separator)&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;배열 요소들을 separator를 구분자로 하여 모두 연결해서 리턴.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;kotlin&quot; style=&quot;background-color: #fafafa; color: #000000; text-align: start;&quot;&gt;&lt;code&gt;// 예시를 위한 배열 생성
&amp;lt;c:set var=&quot;texts&quot; value=&quot;${fn:split('Hi My name is waldo', ' ')}&quot;/&amp;gt;
&amp;lt;c:out value=&quot;${fn:join(texts, '-')}&quot;/&amp;gt; // Hi-My-name-is-waldo&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;int&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;length&lt;/b&gt;(Object item)&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;item이 배열이나 컬렉션이면 요소의 개수를, 문자열이면 문자의 개수를 리턴.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;stata&quot; style=&quot;background-color: #fafafa; color: #000000; text-align: start;&quot;&gt;&lt;code&gt;&amp;lt;c:set var=&quot;texts&quot; value=&quot;${fn:split('Hi My name is waldo', ' ')}&quot;/&amp;gt;

${fn:length(texts)} // 5

${fn:length(&quot;123456&quot;)} // 6&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;String&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;replace&lt;/b&gt;(String string, String before, String after)&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;string 내에 있는 before 문자열을 after 문자열로 모두 바꿔서 리턴.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;rust&quot; style=&quot;background-color: #fafafa; color: #000000; text-align: start;&quot;&gt;&lt;code&gt;${fn:replace(&quot;hi hello&quot;, &quot;hello&quot;, &quot;hi&quot;)} // hi hi

// replace 함수는 HTML에서 공백과 줄바꿈을 표현할 때 사용할 수 있다.
${fn:replace(&quot;hell            o          o       ~&quot;, &quot; &quot;, &quot;&amp;amp;nbsp;&quot;)} // hell            o          o       ~

&amp;lt;% pageContext.setAttribute(&quot;enter&quot;,&quot;\n&quot;); %&amp;gt;
${fn:replace(info.text, enter, '&amp;lt;br/&amp;gt;') // 엔터처리

&amp;lt;% pageContext.setAttribute(&quot;enter&quot;,&quot;\n&quot;); %&amp;gt;
${fn:replace(fn:replace(fn:escapeXml(info.content_txt), enter, '&amp;lt;br/&amp;gt;') , ' ', '&amp;amp;nbsp;')} // 엔터와 공백 처리&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;String&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;substring&lt;/b&gt;(String string, int begin, int end)&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;string에서 begin 인덱스에서 시작해서 end 인덱스에 끝나는 부분의 문자열을 리턴.&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;String&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;substringAfter&lt;/b&gt;(String string, String substring)&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;string에서 substring이 나타나는 이후의 부분에 있는 문자열을 리턴.&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;String&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;substringBefore&lt;/b&gt;(String string, String substring)&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;string에서 substring이 나타나기 이전의 부분에 있는 문자열을 리턴.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;xquery&quot; style=&quot;background-color: #fafafa; color: #000000; text-align: start;&quot;&gt;&lt;code&gt;${fn:substring(text, 3, 19)} // My name is waldo

${fn:substringAfter(text, &quot;Hi &quot;)} // My name is waldo

${fn:substringBefore(text, &quot;waldo&quot;)} // Hi My name is&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;String&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;toLowerCase&lt;/b&gt;(String string)&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;string을 모두 소문자로 치환.&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;String&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;toUpperCase&lt;/b&gt;(String string)&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;string을 모두 대문자로 치환.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;pgsql&quot; style=&quot;background-color: #fafafa; color: #000000; text-align: start;&quot;&gt;&lt;code&gt;&amp;lt;c:set var=&quot;text&quot; value=&quot;Hi My name is waldo&quot;/&amp;gt;

${fn:toLowerCase(text)} // hi my name is waldo

${fn:toUpperCase(text)} // HI MY NAME IS WALDO&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;String&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;trim&lt;/b&gt;(String string)&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;string 앞뒤의 공백을 모두 제거.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;stata&quot; style=&quot;background-color: #fafafa; color: #000000; text-align: start;&quot;&gt;&lt;code&gt;&amp;lt;c:set var=&quot;text&quot; value=&quot;          blank spcae          &quot;/&amp;gt;
${fn:length(text)}  // 31

&amp;lt;c:set var=&quot;text&quot; value=&quot;${fn:trim(text)}&quot;/&amp;gt;
${fn:length(text)}  // 11&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출처 : &lt;a href=&quot;https://jeaha.dev/79&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://jeaha.dev/79&lt;/a&gt;&lt;/p&gt;</description>
      <category>Java 관련/JSTL, EL</category>
      <category>EL</category>
      <category>JSP</category>
      <category>JSTL</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2508</guid>
      <comments>https://xzio.tistory.com/2508#entry2508comment</comments>
      <pubDate>Tue, 9 Apr 2024 11:11:02 +0900</pubDate>
    </item>
    <item>
      <title>[JSP, JSTL] fn function 정리</title>
      <link>https://xzio.tistory.com/2507</link>
      <description>&lt;h1 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;[JSP, JSTL] fn function 정리&lt;/h1&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;jstl function (jstl fn) 정리&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;jsp 파일 최 생단에 다음과 같이 jstl functions를 사용하겠다고 선언 해야 함.&lt;/p&gt;
&lt;pre class=&quot;gcode&quot; style=&quot;background-color: #fafafa; color: #000000; text-align: start;&quot;&gt;&lt;code&gt;  &amp;lt;%@ taglib prefix=&quot;fn&quot; uri=&quot;http://java.sun.com/jsp/jstl/functions&quot; %&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;함수들은 단독으로 사용할 수 없고 EL 표현식과 함께 사용해야 함.&lt;/p&gt;
&lt;pre class=&quot;rust&quot; style=&quot;background-color: #fafafa; color: #000000; text-align: start;&quot;&gt;&lt;code&gt;  ${fn:length(list)}
  ${fn:contains(str, str)}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;fn:contains(string, substr)&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;string이 substr을 포함하면 return true&lt;/p&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;fn:containsIgnoreCase(string, substr)&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;대소문자 관계없이 string이 substr을 포함하면 return true&lt;/p&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;fn:startsWith(string, prefix)&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;string이 prefix로 시작하면 return True&lt;/p&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;fn:endsWith(string, suffix)&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;string이 suffix로 끝나면 return True&lt;/p&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;fn:escapeXml(string)&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;string에 XML과 HTML에서 &amp;lt; &amp;gt;&amp;amp; ' &quot; 문자들이 있으면, XML엔티티 코드로 바꿔준뒤 문자열 반환&lt;/p&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;fn:indexOf(string, substr)&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;string에서 substr이 처음으로 나타나는 인덱스 반환&lt;/p&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;fn:split(string, separator)&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;string내의 문자열 separetor에 따라 나눈 배열로 반환&lt;/p&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;fn:join(array, separator)&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;array요소들을 separator를 구분자로 하여 연결해서 반환&lt;/p&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;fn:length(item)&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;item이 배열이나 컬렉션이면 요소의 개수를 문자열이면 문자의 개수를 반환&lt;/p&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;fn:replace(string, before, after)&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;string내에 있는 before 문자열을 after 문자열로 모두 변경해서 반환&lt;/p&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;fn:substring(string, begin, end)&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;string에서 begin인덱스에서 시작해서 end인덱스에 끝나는 부분의 문자열 반환&lt;/p&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;fn:substringAfter(string, substr)&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;string에서 substr이 나타나는 이후의 문자열 반환&lt;/p&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;fn:substringBefore(string, substr)&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;string에서 substr이 나타나는 이전의 문자열 반환&lt;/p&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;fn:toLowerCase(string)&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;string을 모두 소문자로 변경 후 리턴&lt;/p&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;fn:toUpperCase(string)&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;string을 모두 대문자로 변경 후 리턴&lt;/p&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;fn:trim(string)&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;string앞뒤의 공백을 모두 제거한 후 반환&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;출처 : &lt;a href=&quot;https://jeaha.dev/71&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://jeaha.dev/71&lt;/a&gt;&lt;/p&gt;</description>
      <category>Java 관련/JSTL, EL</category>
      <category>EL</category>
      <category>JSP</category>
      <category>JSTL</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2507</guid>
      <comments>https://xzio.tistory.com/2507#entry2507comment</comments>
      <pubDate>Tue, 9 Apr 2024 11:08:34 +0900</pubDate>
    </item>
    <item>
      <title>[JSP, JSTL] forEach 잘 사용하기</title>
      <link>https://xzio.tistory.com/2506</link>
      <description>&lt;h1 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;&lt;b&gt;[JSP, JSTL] forEach 잘 사용하기&lt;/b&gt;&lt;/h1&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Spring 개발을 하다 보면 jstl 의 forEach 를 많이 사용하게 된다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;간단하지만 varStatus 속성 사용을 잘 하면 보다 편하게 개발할 수 있는것 같아서 남겨본다.&lt;/p&gt;
&lt;pre class=&quot;java&quot; style=&quot;background-color: #fafafa; color: #000000; text-align: start;&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;&amp;lt;c:forEach items=&quot;${list}&quot; var=&quot;item&quot; varStatu=&quot;i&quot;&amp;gt;
  current (현재 객체)       : ${i.current}&amp;lt;br/&amp;gt;
  index (0부터의 순서)      : ${i.index}&amp;lt;br/&amp;gt;
  count (1부터의 순서)      : ${i.count}&amp;lt;br/&amp;gt;
  first (루프의 처음인가)   : ${i.first}&amp;lt;br/&amp;gt;
  last (루프의 마지막인가)  : ${i.last}&amp;lt;br/&amp;gt;
  begin (루프의 시작값)     : ${i.begin}&amp;lt;br/&amp;gt;
  end (끝값)                : ${i.end}&amp;lt;br/&amp;gt;
  step (증가값)             : ${i.step}&amp;lt;br/&amp;gt;
&amp;lt;/c:forEach\&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출처 : &lt;a href=&quot;https://jeaha.dev/70&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://jeaha.dev/70&lt;/a&gt;&lt;/p&gt;</description>
      <category>Java 관련/JSTL, EL</category>
      <category>JSP</category>
      <category>JSTL</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2506</guid>
      <comments>https://xzio.tistory.com/2506#entry2506comment</comments>
      <pubDate>Tue, 9 Apr 2024 11:07:13 +0900</pubDate>
    </item>
    <item>
      <title>[JSP, HTML] 코드로 사용자 브라우저 캐시 삭제</title>
      <link>https://xzio.tistory.com/2425</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;화면을 수정했는데, 클라이언트의 브라우져에 캐시가 남아서 이전 화면이 나오는 경우가 있다.&lt;br /&gt;직접 브라우져 설정 들어가서 캐시를 지워달라고&lt;span&gt;&amp;nbsp;&lt;/span&gt;요청 할 수도 있지만, 그게 한두번이 아니게 되니 코드에서 캐시를 지울수 없는지 찾아보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;HTML 메타태그 이용하기&lt;/h2&gt;
&lt;pre class=&quot;html xml&quot; style=&quot;background-color: #fafafa; color: #000000; text-align: start;&quot; data-ke-language=&quot;html&quot;&gt;&lt;code&gt;    &amp;lt;!-- 1990년 이후 이 페이지의 캐시를 만료시킴. --&amp;gt;
    &amp;lt;meta http-equiv=&quot;Expires&quot; content=&quot;Mon, 06 Jan 1990 00:00:01 GMT&quot; /&amp;gt;

    &amp;lt;!-- 캐시를 바로 만료시킴. --&amp;gt;
    &amp;lt;meta http-equiv=&quot;Expires&quot; content=&quot;-1&quot; /&amp;gt;

    &amp;lt;!-- 페이지 로드시마다 페이지를 캐싱하지 않음. (HTTP 1.0) --&amp;gt;
    &amp;lt;meta http-equiv=&quot;Pragma&quot; content=&quot;no-cache&quot; /&amp;gt;

    &amp;lt;!-- 페이지 로드시마다 페이지를 캐싱하지 않음. (HTTP 1.1) --&amp;gt;
    &amp;lt;meta http-equiv=&quot;Cache-Control&quot; content=&quot;no-cache&quot; /&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ensp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;JSP, Java 사용시&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;자바 코드 지만 html과 같음.&lt;/p&gt;
&lt;pre class=&quot;java&quot; style=&quot;background-color: #fafafa; color: #000000; text-align: start;&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;    response.setHeader( &quot;Pragma&quot;, &quot;no-cache&quot; );
    response.setDateHeader( &quot;Expires&quot;, -1 );
    response.setHeader( &quot;Cache-Control&quot;, &quot;no-cache&quot; );&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ensp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;JS, CSS 파일 캐시 사용 방지&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;js나 css등 정적파일도&lt;span&gt;&amp;nbsp;&lt;/span&gt;종종 변경을 해도 캐시문제로 적용이 되지 않는 경우가 많다.&lt;br /&gt;그럴 경우 파일의 url 뒤에&lt;span&gt;&amp;nbsp;&lt;/span&gt;?timestamp&lt;span&gt;&amp;nbsp;&lt;/span&gt;형태를 넣어준다.&lt;/p&gt;
&lt;pre class=&quot;html xml&quot; style=&quot;background-color: #fafafa; color: #000000; text-align: start;&quot; data-ke-language=&quot;html&quot;&gt;&lt;code&gt;  &amp;lt;link rel=&quot;stylesheet&quot; href=&quot;/css/common.css?20210512&quot; /&amp;gt;
  &amp;lt;script type=&quot;text/javascript&quot; src=&quot;/js/common.js?20210512&quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출처 : &lt;a href=&quot;https://jeaha.dev/114&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://jeaha.dev/114&lt;/a&gt;&lt;/p&gt;</description>
      <category>Web Programing/기본 정보</category>
      <category>HTML</category>
      <category>JSP</category>
      <category>캐시</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2425</guid>
      <comments>https://xzio.tistory.com/2425#entry2425comment</comments>
      <pubDate>Thu, 21 Mar 2024 17:49:04 +0900</pubDate>
    </item>
    <item>
      <title>IntelliJ 초기설정</title>
      <link>https://xzio.tistory.com/2424</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;집, 회사, 노트북 인텔리J가 설치가 되어 있지만 모두 세팅이 조금씩 다르다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;세팅을 Export 해보기도 했지만 폰트가 설정이 안되거나 플러그인도 조금씩 에러가 있어서 블로그에 세팅 관련 글을 적어야 겠다고 생각했다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style8&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;▣&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;IntelliJ&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;프로젝트 SDK 설정&lt;/b&gt;&lt;/h3&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;291&quot; data-origin-height=&quot;430&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eCOZ65/btsFYsBeLep/2DKcR3JOL5NGFmmtM1WoY1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eCOZ65/btsFYsBeLep/2DKcR3JOL5NGFmmtM1WoY1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eCOZ65/btsFYsBeLep/2DKcR3JOL5NGFmmtM1WoY1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeCOZ65%2FbtsFYsBeLep%2F2DKcR3JOL5NGFmmtM1WoY1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;291&quot; height=&quot;430&quot; data-origin-width=&quot;291&quot; data-origin-height=&quot;430&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;797&quot; data-origin-height=&quot;433&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d6cwnH/btsFXbUA3dU/fG9RnkUwKRKTG1oqBv5Jhk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d6cwnH/btsFXbUA3dU/fG9RnkUwKRKTG1oqBv5Jhk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d6cwnH/btsFXbUA3dU/fG9RnkUwKRKTG1oqBv5Jhk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd6cwnH%2FbtsFXbUA3dU%2FfG9RnkUwKRKTG1oqBv5Jhk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;797&quot; height=&quot;433&quot; data-origin-width=&quot;797&quot; data-origin-height=&quot;433&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;이미지 5.jpg&quot; data-origin-width=&quot;980&quot; data-origin-height=&quot;271&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QHeQv/btsFWlJ6QQA/hZMk5RWNqDnO89jt3wyRWK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QHeQv/btsFWlJ6QQA/hZMk5RWNqDnO89jt3wyRWK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QHeQv/btsFWlJ6QQA/hZMk5RWNqDnO89jt3wyRWK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQHeQv%2FbtsFWlJ6QQA%2FhZMk5RWNqDnO89jt3wyRWK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;980&quot; height=&quot;271&quot; data-filename=&quot;이미지 5.jpg&quot; data-origin-width=&quot;980&quot; data-origin-height=&quot;271&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;| 필자는 openJDK를 사용하고 있으며 openJDK는 하단의 링크에서 다운로드 받을 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;▶ File - Project Structure - Project Settings의 Project에서 Project SDK란을 설정하면 된다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;JDK home path가 설정이 안되어서 인텔리j가 JDK 위치를 모르면 Platform Settings에서 추가하면 된다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;&lt;a style=&quot;color: #0070d1;&quot; href=&quot;https://github.com/ojdkbuild/ojdkbuild&quot;&gt;&amp;lt; openJDK 다운로드 페이지 이동 &amp;gt;&lt;/a&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style8&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;▣ 개발자 폰트 추천&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- D2 Coding&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a style=&quot;color: #0070d1;&quot; href=&quot;https://github.com/naver/d2codingfont&quot;&gt;github.com/naver/d2codingfont&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1710926267484&quot; style=&quot;color: #333333; text-align: start;&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/blSEZK/hyJaoXFwNX/nXoTEEXUdVFrGZJNrOEKA0/img.png?width=150&amp;amp;height=150&amp;amp;face=0_0_150_150,https://scrap.kakaocdn.net/dn/tis5O/hyJacv8T2G/0P6TA9WsbI5FZlMqa4EGd0/img.png?width=1878&amp;amp;height=666&amp;amp;face=0_0_1878_666,https://scrap.kakaocdn.net/dn/bq7qe1/hyJacQud0r/kNlDmSpP9kjd0SblvGXsH1/img.png?width=888&amp;amp;height=350&amp;amp;face=0_0_888_350&quot; data-og-url=&quot;https://github.com/naver/d2codingfont&quot; data-og-source-url=&quot;https://github.com/naver/d2codingfont&quot; data-og-host=&quot;github.com&quot; data-og-description=&quot;D2 Coding 글꼴. Contribute to naver/d2codingfont development by creating an account on GitHub.&quot; data-og-title=&quot;naver/d2codingfont&quot; data-og-type=&quot;object&quot; data-ke-type=&quot;opengraph&quot;&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://github.com/naver/d2codingfont&quot; data-source-url=&quot;https://github.com/naver/d2codingfont&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/blSEZK/hyJaoXFwNX/nXoTEEXUdVFrGZJNrOEKA0/img.png?width=150&amp;amp;height=150&amp;amp;face=0_0_150_150,https://scrap.kakaocdn.net/dn/tis5O/hyJacv8T2G/0P6TA9WsbI5FZlMqa4EGd0/img.png?width=1878&amp;amp;height=666&amp;amp;face=0_0_1878_666,https://scrap.kakaocdn.net/dn/bq7qe1/hyJacQud0r/kNlDmSpP9kjd0SblvGXsH1/img.png?width=888&amp;amp;height=350&amp;amp;face=0_0_888_350');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; style=&quot;color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;naver/d2codingfont&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; style=&quot;color: #909090;&quot; data-ke-size=&quot;size16&quot;&gt;D2 Coding 글꼴. Contribute to naver/d2codingfont development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; style=&quot;color: #909090;&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;| 다양한 폰트를 사용해 보았지만 돌고 돌아서 결국 D2 Coding 폰트를 선택하게 되었다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;영어 + 한글 조합에서는 개인적으로 최고라고 생각한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style8&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;▣ 자동 import (추천) - Auto Import&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;이미지 1.jpg&quot; data-origin-width=&quot;986&quot; data-origin-height=&quot;708&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JSF5I/btsFX4N9vrC/4BqekMUk2FQq8WUjk7GALk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JSF5I/btsFX4N9vrC/4BqekMUk2FQq8WUjk7GALk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JSF5I/btsFX4N9vrC/4BqekMUk2FQq8WUjk7GALk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJSF5I%2FbtsFX4N9vrC%2F4BqekMUk2FQq8WUjk7GALk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;986&quot; height=&quot;708&quot; data-filename=&quot;이미지 1.jpg&quot; data-origin-width=&quot;986&quot; data-origin-height=&quot;708&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;| import를 자동으로 해주지 않을때 설정하면 좋다. 해당 설정을 하게 된다면 자동으로 찾아서 import 해주며, 만약 이름이 같을 경우 자동으로 하지 않고 사람이 직접 선택할 수 있어서 좋다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;▶ Editor - General - Auto Import&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Optimize imports on thr fly 체크&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;▣ 대소문자 가리지 않는 자동완성 설정 (추천) - Code Completion&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;이미지 2.jpg&quot; data-origin-width=&quot;984&quot; data-origin-height=&quot;704&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d86aMW/btsFW9WNrfp/IkMI799ZF4TceOp9n8qf30/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d86aMW/btsFW9WNrfp/IkMI799ZF4TceOp9n8qf30/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d86aMW/btsFW9WNrfp/IkMI799ZF4TceOp9n8qf30/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd86aMW%2FbtsFW9WNrfp%2FIkMI799ZF4TceOp9n8qf30%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;984&quot; height=&quot;704&quot; data-filename=&quot;이미지 2.jpg&quot; data-origin-width=&quot;984&quot; data-origin-height=&quot;704&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;| 인텔리j 에서는 system이라고 하면 자동완성이 안되고 System이라고 해야 자동완성이 나오는데 대소문자를 구별한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;생각보다 귀찮기 때문에 대소문자를 구별하지 않게 설정하면 좀 더 개발하기 편하다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;▶ Editor - General - Code Completion&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Match case 체크 해제&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;▣ IntelliJ 한 줄 표시 해체(One-line Methods)&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;화면 캡처 2022-08-20 170341.png&quot; data-origin-width=&quot;987&quot; data-origin-height=&quot;715&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJaacm/btsFV5HBIha/kgXOBZ6DzCHtio2PNGdtYK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJaacm/btsFV5HBIha/kgXOBZ6DzCHtio2PNGdtYK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJaacm/btsFV5HBIha/kgXOBZ6DzCHtio2PNGdtYK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJaacm%2FbtsFV5HBIha%2FkgXOBZ6DzCHtio2PNGdtYK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;987&quot; height=&quot;715&quot; data-filename=&quot;화면 캡처 2022-08-20 170341.png&quot; data-origin-width=&quot;987&quot; data-origin-height=&quot;715&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;| 초기에 메소드 라인이 1줄이라면 심플하게 표시하기 위해 인텔리J에서 한줄로 표기하는데 익숙하지 않거나 저처럼 그냥 다 보여주는게 좋을 때 해당 옵션을 해제하면 된다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;▶ Setting - Editor - Code Folding&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;One-line methods 체크 해제&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;▣ IntelliJ 실행시 최근 프로젝트가 아닌, 프로젝트 목록으로 첫 화면 변경하기&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;987&quot; data-origin-height=&quot;728&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ddwgYz/btsFXKvDnSa/kHkumjUaBkp4pArgjUn1Tk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ddwgYz/btsFXKvDnSa/kHkumjUaBkp4pArgjUn1Tk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ddwgYz/btsFXKvDnSa/kHkumjUaBkp4pArgjUn1Tk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FddwgYz%2FbtsFXKvDnSa%2FkHkumjUaBkp4pArgjUn1Tk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;987&quot; height=&quot;728&quot; data-origin-width=&quot;987&quot; data-origin-height=&quot;728&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;| IntelliJ를 실행하면 처음 세팅은 마지막으로 열었던 프로젝트를 다시 열게 되어 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;여러 프로젝트가 있을 경우 불편하기 때문에 프로젝트 목록으로 변경한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;▶ File - Settings - Appearance &amp;amp; Behavior - System Settings&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Reopen projects on startup : 체크 해제&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Open project in : Ask&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;▣&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;Line별 Commit History - 협업시 강추&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1063&quot; data-origin-height=&quot;825&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/srynG/btsFWjZOfZx/cryKAOJXYlLa80Fety1MsK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/srynG/btsFWjZOfZx/cryKAOJXYlLa80Fety1MsK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/srynG/btsFWjZOfZx/cryKAOJXYlLa80Fety1MsK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsrynG%2FbtsFWjZOfZx%2FcryKAOJXYlLa80Fety1MsK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1063&quot; height=&quot;825&quot; data-origin-width=&quot;1063&quot; data-origin-height=&quot;825&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2023-05-06 15 07 38.png&quot; data-origin-width=&quot;1046&quot; data-origin-height=&quot;853&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IsDCK/btsFU7ZRW9Y/GE61ER6UcJMHtrP3qPIIW1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IsDCK/btsFU7ZRW9Y/GE61ER6UcJMHtrP3qPIIW1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IsDCK/btsFU7ZRW9Y/GE61ER6UcJMHtrP3qPIIW1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIsDCK%2FbtsFU7ZRW9Y%2FGE61ER6UcJMHtrP3qPIIW1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1046&quot; height=&quot;853&quot; data-filename=&quot;2023-05-06 15 07 38.png&quot; data-origin-width=&quot;1046&quot; data-origin-height=&quot;853&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;| 여러분들이 다른 사람이랑 Git을 함께 사용하고 있을 때 누가 라인을 변경했는지 알고 싶을 때 유용하다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;특히 회사에서 생각보다 잘 사용하고 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;* 해당 날짜를 클릭하면 commit history를 보여주기 때문에 누가,언제,무엇을 commit했는지 확인할 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;(추궁도가능하다)&lt;/s&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;▶ Keymap&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Version Control Systems &amp;gt; Annotate 우클릭 &amp;gt; Keyboard Shorcut &amp;gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;b&gt;키 설정&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;저는 ctrl + alt + shift + \ 사용중입니다.&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;▣&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;IntelliJ&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;세로줄 없애기(가이드 라인 없애기)&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;987&quot; data-origin-height=&quot;726&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Th8yJ/btsFXIYSwAt/CvDeZDLd8pedRHIKxZzkCk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Th8yJ/btsFXIYSwAt/CvDeZDLd8pedRHIKxZzkCk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Th8yJ/btsFXIYSwAt/CvDeZDLd8pedRHIKxZzkCk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTh8yJ%2FbtsFXIYSwAt%2FCvDeZDLd8pedRHIKxZzkCk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;987&quot; height=&quot;726&quot; data-origin-width=&quot;987&quot; data-origin-height=&quot;726&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;| Setting - Editor - General - Appearance에서&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Show hard warp and visual guides(configured in Code Style options)&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;체크 해제&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;986&quot; data-origin-height=&quot;723&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KCRBu/btsFUIlKrGK/y8f3NoE9bUpAfKhKZe8qd1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KCRBu/btsFUIlKrGK/y8f3NoE9bUpAfKhKZe8qd1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KCRBu/btsFUIlKrGK/y8f3NoE9bUpAfKhKZe8qd1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKCRBu%2FbtsFUIlKrGK%2Fy8f3NoE9bUpAfKhKZe8qd1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;986&quot; height=&quot;723&quot; data-origin-width=&quot;986&quot; data-origin-height=&quot;723&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;▶ 만약 가이드라인선은 유지한채 범위를 줄이거나, 늘리고 싶으면&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Setting - Editor - Code Style를 120에서 줄이거나 늘리면 된다. 단,&lt;span&gt;&amp;nbsp;&lt;/span&gt;Show hard warp and visual guides(configured in Code Style options) 옵션은 체크해야 합니다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;▣&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;IntelliJ&lt;/b&gt;&amp;nbsp;터미널 Window CMD에서 Git Bash로 변경하기&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;이미지 7.jpg&quot; data-origin-width=&quot;1125&quot; data-origin-height=&quot;826&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7ybyh/btsFVTf06KP/Cul1qoX8cBtNmBh3U5h030/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7ybyh/btsFVTf06KP/Cul1qoX8cBtNmBh3U5h030/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7ybyh/btsFVTf06KP/Cul1qoX8cBtNmBh3U5h030/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7ybyh%2FbtsFVTf06KP%2FCul1qoX8cBtNmBh3U5h030%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1125&quot; height=&quot;826&quot; data-filename=&quot;이미지 7.jpg&quot; data-origin-width=&quot;1125&quot; data-origin-height=&quot;826&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;| 해당 설정을 하는 이유는 개인적으로 리눅스를 많이 사용하다 보니 cmd 명령어에 익숙치 않기 때문도 있지만 Bash 명령어를 사용할 수 있다는 장점도 있습니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;▶ Settings - Tools - Terminal&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Shell path&lt;/p&gt;
&lt;pre id=&quot;code_1710926267487&quot; class=&quot;java&quot; style=&quot;background-color: #000000; color: #000000; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;&quot;C:\Program Files\Git\bin\sh.exe&quot; -login -i&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;git/bin/sh.exe 파일이 있는 곳을 path로 잡아주면 된다. 기본적으로 경로는 변경하지 않으면 해당 폴더에 가면 sh.exe.가 보일것이다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;출처 : &lt;a href=&quot;https://adg0609.tistory.com/20&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://adg0609.tistory.com/20&lt;/a&gt;&lt;/p&gt;</description>
      <category>IDE Tool/IntelliJ IDEA</category>
      <category>Lombok</category>
      <category>인텔리J</category>
      <category>인텔리j설정</category>
      <category>인텔리j초기설정</category>
      <category>인텔리j플러그인</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2424</guid>
      <comments>https://xzio.tistory.com/2424#entry2424comment</comments>
      <pubDate>Wed, 20 Mar 2024 18:20:11 +0900</pubDate>
    </item>
    <item>
      <title>IntelliJ 함수가 한줄로 보일때</title>
      <link>https://xzio.tistory.com/2423</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;467&quot; data-origin-height=&quot;117&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bd2jVe/btsFU7S6qMa/wJZ8SDQv3iKUqPEUezqlP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bd2jVe/btsFU7S6qMa/wJZ8SDQv3iKUqPEUezqlP1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bd2jVe/btsFU7S6qMa/wJZ8SDQv3iKUqPEUezqlP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbd2jVe%2FbtsFU7S6qMa%2FwJZ8SDQv3iKUqPEUezqlP1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;467&quot; height=&quot;117&quot; data-origin-width=&quot;467&quot; data-origin-height=&quot;117&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;IntelliJ 에서 사진처럼 한줄로 보여주는 기능이 있다.&lt;br /&gt;개인적으로 가독성이 떨어져서 별로인데 설정에서 off 할수있다.&lt;/p&gt;
&lt;blockquote style=&quot;color: #212529; text-align: start;&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Setting &amp;gt; Editor &amp;gt; General &amp;gt; Code Folding &amp;gt; One-line methods 체크 해제&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;974&quot; data-origin-height=&quot;717&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xKIAL/btsFWL9FGVp/cLyzxVEv0kBm4ggf46dy4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xKIAL/btsFWL9FGVp/cLyzxVEv0kBm4ggf46dy4k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xKIAL/btsFWL9FGVp/cLyzxVEv0kBm4ggf46dy4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxKIAL%2FbtsFWL9FGVp%2FcLyzxVEv0kBm4ggf46dy4k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;974&quot; height=&quot;717&quot; data-origin-width=&quot;974&quot; data-origin-height=&quot;717&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>IDE Tool/IntelliJ IDEA</category>
      <category>IntelliJ</category>
      <category>ONE-LINE</category>
      <category>인텔리제이</category>
      <category>한줄</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2423</guid>
      <comments>https://xzio.tistory.com/2423#entry2423comment</comments>
      <pubDate>Wed, 20 Mar 2024 18:03:03 +0900</pubDate>
    </item>
    <item>
      <title>intellij 프로젝트 이름변경</title>
      <link>https://xzio.tistory.com/2408</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;# 프로젝트명 변경&lt;/b&gt;&lt;br /&gt;1. [File] &amp;gt; [Project Structure] &amp;gt; [Project] &amp;gt; (Project name) 이름을 변경한다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #5c5c5c; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;2. IntelliJ 를 종료한다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #5c5c5c; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;3. 프로젝트 root 디렉토리로 이동하여 아래 파일을 열어 프로젝트명을 동일하게 수정한다.&lt;br /&gt;&amp;nbsp; &amp;nbsp;/settings.gradle&lt;/p&gt;
&lt;pre id=&quot;code_1706594324991&quot; class=&quot;java&quot; style=&quot;background-color: #f6f7f8; color: #5c5c5c; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;rootProject.name = 'api-project'&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #5c5c5c; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;/.idea/.name&amp;nbsp; ( 파일 내용에 프로젝트명과 다르게 저장되어 있다면 수정 )&lt;/p&gt;
&lt;pre id=&quot;code_1706594324991&quot; class=&quot;java&quot; style=&quot;background-color: #f6f7f8; color: #5c5c5c; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;api-project&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #5c5c5c; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;4.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;IntelliJ&lt;span&gt;&amp;nbsp; 를 다시 실행하고 Gradle 프로젝트를 Refresh 한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>IDE Tool/IntelliJ IDEA</category>
      <category>IntelliJ</category>
      <category>변경</category>
      <category>프로젝트</category>
      <category>프로젝트명</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2408</guid>
      <comments>https://xzio.tistory.com/2408#entry2408comment</comments>
      <pubDate>Tue, 30 Jan 2024 15:00:06 +0900</pubDate>
    </item>
    <item>
      <title>관습적인 추상화 Service와 ServiceImpl 구조에 대해서</title>
      <link>https://xzio.tistory.com/2344</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;스프링에 대해 공부하면서 그리고 프로젝트를 진행해보고 여러 예제 코드들을 접해보면서 느낀 것은 관습적으로 브릿지 패턴을 이용한 추상화를 사용하고 있다는 점입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;관습적인 추상화&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;계층화된 아키텍처인 &lt;i&gt;&lt;b&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;MVC&lt;/span&gt;&lt;/b&gt;&lt;/i&gt; 패턴을 적용한 대부분의 프로젝트에서는 그 중에서도 &lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;i&gt;&lt;b&gt;Service&lt;/b&gt;&lt;/i&gt;&lt;/span&gt; 계층에서는 &lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;i&gt;&lt;b&gt;MemberService&lt;/b&gt;&lt;/i&gt;&lt;/span&gt; 와 같이 서비스를 인터페이스로 생성하고 &lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;i&gt;&lt;b&gt;MemberServiceImpl&lt;/b&gt;&lt;/i&gt;&lt;/span&gt; 이라는 구현체를 생성해서 사용하는 방식으로 대부분의 설계가 이루어집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;토비의 스프링이나 여러 객체지향과 스프링 관련 책들을 보면 이와 같은 패턴으로 설계를 해야하는 이유에 대해서 잘 설명하고 있습니다. 인터페이스와 구현체의 분리를 통해 특정 기술이나 외부환경에 독립적으로 보다 자유로운 확장이 가능해진다는 OCP 원칙에 입각한 분명한 장점이 존재합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-origin-height=&quot;0&quot; data-origin-width=&quot;0&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cMqyK2/btqQXB3CR5C/svupFTkMF276ITX1anqu0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcMqyK2%2FbtqQXB3CR5C%2FsvupFTkMF276ITX1anqu0k%2Fimg.png&quot; width=&quot;728&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-origin-height=&quot;0&quot; data-origin-width=&quot;0&quot; /&gt;
&lt;figcaption&gt;https://ko.wikipedia.org/wiki/브릿지_패턴&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 실제로 대부분의 프로젝트나 예제 코드를 보면 인터페이스와 구현체 클래스 사이의 관계가 1:1로 구성되어 실질적으로 인터페이스를 사용하는 것에 대한 이점을 전혀가져가지 못함에도 불구하고 관습적으로 이러한 추상화 패턴을 적용하고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 관습적인 추상화의 장점과 단점은 무엇일까요? 맹목적으로 이러한 추상화 방식을 프로젝트에 적용하는 것이 올바른 설계 방법일까요? 이러한 질문들에 초점을 맞추어 한번 고민을 해보았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;관습적인 추상화의 장점과 단점&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 추상화 방식은 브릿지 패턴이 가지고 있는 장점과 단점과 같다고 생각해도 무방할 것 같습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞서 언급했듯이 인터페이스와 구현체 클래스를 분리함으로써 구현체를 독립적으로 확장할 수 있으며, 구현체 클래스를 변경하거나 확장해도 이를 사용하는 클라이언트의 코드에는 영향을 주지 않습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추상화를 통한 구현방식은 객체지향의 특징 중 하나인 다형성과 객체지향의 다섯가지 원칙 중 하나인 OCP 원칙을 가장 잘 실현해주는 설계방식이라고 할 수 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-origin-height=&quot;0&quot; data-origin-width=&quot;0&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dSrFMR/btqQXBWShgJ/zWvvk9JmVj03vXPq9D5lkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdSrFMR%2FbtqQXBWShgJ%2FzWvvk9JmVj03vXPq9D5lkk%2Fimg.png&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-origin-height=&quot;0&quot; data-origin-width=&quot;0&quot; /&gt;
&lt;figcaption&gt;https://www.journaldev.com/1491/bridge-design-pattern-java&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;관습적인 추상화의 많은 장점에도 불구하고 이러한 설계 방식은 구조가 복잡해진다는 단점을 가지고 있습니다. 복잡화된 구조인 만큼 코드를 분석하고 확인하는 과정에서도 인터페이스를 거쳐서 다시 그 인터페이스의 구현체들을 확인하는 단계가 추가되면서 가지는 불편함도 분명 존재할 것 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 제가 생각했을 때의 가장 큰 단점은 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;인터페이스와 구현체가 &lt;b&gt;1:1&lt;/b&gt; 관계로 이루어지는 설계에서는 이러한 장점들을 잘 살리지 못한다는 것입니다.&lt;/span&gt; 그럼에도 불구하고 반드시 관습적인 추상화를 적용해야 할까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;관습적인 추상화를 통한 설계 방식을 꼭 적용해야 할까?&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이와 관련해서는 크게 두 가지 의견으로 나누어지는 것 같습니다. 먼저 이러한 관습적인 추상화를 적용해야 한다는 입장에서의 의견은 토비의 스프링에 잘 나와있습니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;세상에 변하는 것과 변하지 않는 것이 있지만, 객체지향의 세계에서는 모든 것이 변한다. 여기서 변한다는 것은 오브젝트에 대한 설계와 이를 구현한 코드가 변한다는 의미이다. 소프트웨어 개발에서의 끝이란 개념은 없고 사용자의 비즈니스 프로세스와 그에 따른 요구사항은 끊임없이 바뀌고 발전한다. 그래서 개발자가 객체를 설계할 때 가장 염두에 두어야 할 사항은 미래를 어떻게 대비할 것인가이다.&lt;br /&gt;&lt;br /&gt;-토비의 스프링 3.1&amp;nbsp; 1장 중-&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;책에 잘 나와있는 것 처럼 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;객체는 변화하며 개발자는 끊임없이 이에 대비해야 합니다. 미래를 위한 설계를 통해 변화에 효과적으로 대처할 수 있다는 것입니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런 점에 있어서 우리가 설계한 인터페이스와 구현체 클래스가 당장에 &lt;b&gt;1:1 &lt;/b&gt;관계를 맺고있을지 모르지만 서비스가 커지고 변화함에 따라서 얼마든지 구현체 클래스는 확장될 가능성을 가지고 있습니다. 그렇기 때문에 인터페이스와 구현체를 분리한 설계를 통해 미래의 변화에 유연하게 대처할 수 있어야 한다는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면에 반대의 입장을 가지고 있는 의견은 &lt;a href=&quot;https://multifrontgarden.tistory.com/97&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;LichKing님의 블로그&lt;/a&gt;의 글을 참고할 수 있었습니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;서비스를 인터페이스로 만들었던건 관례로 굳어지게 되었는데 개발은 Transaction Script 형식으로 진행하다 보니까 관례는 관례대로 남고 애초에 그렇게 하자고 했던 이유는 사라져버리게 된 것이다. 그래서 내린 결론은 한 메서드에서 모든 역할을 다하는 이런 절차지향적인 코드에서는 사실 서비스를 인터페이스로 할 필요는 없다는 것이다. 물론 인터페이스를 만들지 말자 보다는 애초에 인터페이스를 만들었던 이유를 잘 살리는 것이 바람직 하다는 것이다.&lt;br /&gt;&lt;br /&gt;-LichKing 블로그 중-&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 반대의 입장이라기 보다는 정확히 그 의미를 잘 알고서 사용해야한다는 의미에 가깝습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;관습적으로 그냥 원래 이렇게 해왔으니까?&quot;, &quot;예제에 그냥 이렇게 나와있던데?&quot;, &quot;이렇게 하래요&quot; 와 같은 무책임한 말이 아니라 이러한 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;인터페이스와 구현체를 분리한 설계를 통한 이점들과 이유와 근거에 대해서 설계를 한 개발자 당사자는 명확히 이해&lt;/span&gt;하고 있어야 한다는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 가지 글에서 알 수 있듯이 이러한 추상화 방법이 가지고 있는 장점들은 명확하게 존재합니다. 하지만 대부분이 관습적으로 이를 프로젝트에 적용하면서도 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;&quot;왜?&quot; 사용하는지에 대한 이유에 대해서 잘 인지하고 있지 못하고 있습니다.&lt;/span&gt; 그렇기 떄문에 이러한 추상화를 통한 설계방식을 적용한 이유와 장단점에 대해서 명확히 알고 사용하는 것이 중요할 것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;추상화를 통한 설계 방식의 네이밍 컨벤션에 대해서&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 또 한가지 고민해볼 수 있는 점은 바로 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;i&gt;&lt;b&gt;Service&lt;/b&gt;&lt;/i&gt;&lt;/span&gt; 와 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;&lt;i&gt;ServiceImpl&lt;/i&gt;&lt;/b&gt;&lt;/span&gt; 의 네이밍 컨벤션에 관한 문제입니다. 보통의 경우 인터페이스에는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;&lt;i&gt;Service&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;를 그리고 이를 구현한 구현체 클래스에는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;&lt;i&gt;ServiceImpl&lt;/i&gt;&lt;/b&gt;&lt;/span&gt; 이라는 접미사를 붙인 네이밍을 사용하거나 접두사에 인터페이스임을 명시하기 위해 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;i&gt;&lt;b&gt;I&lt;/b&gt;&lt;/i&gt;&lt;/span&gt; 라는 접두어를 사용하고 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;과연 이러한 네이밍 방식은 적절한 방법일까요? 우리가 흔히 말하는 읽기 좋은 코드 클린 코드에 부합하는 네이밍 일까요?&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Java에서 직접적으로 이러한 설계에 대해 네이밍을 적용하고 있는지 알 수 있는 대표적인 사례로 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;i&gt;&lt;b&gt;Collection&lt;/b&gt;&lt;/i&gt;&lt;/span&gt; 프레임워크를 들 수 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;i&gt;&lt;b&gt;Collection&lt;/b&gt;&lt;/i&gt;&lt;/span&gt; 프레임워크 중에서 &lt;i&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;List&lt;/span&gt;&lt;/b&gt;&lt;/i&gt; 의 구조에 대해서 간단하게 살펴보면, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;i&gt;&lt;b&gt;List&lt;/b&gt;&lt;/i&gt;&lt;/span&gt; 인터페이스와 이를 구현한 하위 구현체들에는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;i&gt;&lt;b&gt;ArrayListImpl&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;i&gt;&lt;b&gt;LinkedListImpl&lt;/b&gt;&lt;/i&gt;&lt;/span&gt; 등이 아니라 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;i&gt;&lt;b&gt;ArrayList&lt;/b&gt;&lt;/i&gt;&lt;/span&gt; 와 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;i&gt;&lt;b&gt;LinkedList&lt;/b&gt;&lt;/i&gt;&lt;/span&gt; 라는 네이밍으로 표현하고 있는 것을 볼 수 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 네이밍에서 Impl 을 접미사로 붙여서 사용하는 것은 불필요하고 무의미한 네이밍을 반복해서 사용하고 있을 뿐임을 잘 나타내 주고 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 이러한 점에 있어서 단순히 클래스 이름을 고유하게 만들기 위해 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;i&gt;&lt;b&gt;Impl&lt;/b&gt;&lt;/i&gt;&lt;/span&gt; 을 접미사로 붙이는 것이 전부라면 인터페이스를 갖는 것에 대해 다시 한번 생각해볼 필요가 있는 것 같습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 문제가 발생하는 원인은 인터페이스와 구현체 사이의 &lt;b&gt;1:1 &lt;/b&gt;관계에 있습니다. 즉, 인터페이스가 딱히 구현에 있어서 필요하지 않지만 설계 패턴을 만족시키기 위해서 위와 같은 네이밍을 사용하고 있기 때문에 발생하는 문제 입니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;때문에 어떠한 방법이 옳다라고 딱 잘라서 정의내릴 수는 없지만, 이러한 점들을 고려해서 어떠한 방법으로 네이밍을 하는 것이 더 좋은 방법으로 코드를 작성하는 것인가에 대해서는 고민해볼 필요가 있을 것 같습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;프로젝트에 추상화 제대로 적용해봅시다&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞선 내용들을 통해서 프로젝트에 이러한 추상화를 적용하기 전에 고려할 두 가지 숙제가 주어졌습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;인터페이스와 구현 클래스가 &lt;b&gt;1:1 &lt;/b&gt;관계를 가지고 있는 프로젝트 구조에서 추상화를 적용해야하는가&lt;/li&gt;
&lt;li&gt;추상화를 적용한다면 네이밍을 어떻게 가져갈 것인가&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 고민들에 있어서 어떻게 프로젝트에 적용하는 것이 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;스프링을 스프링 답게 사용하면서도 읽기 좋은 코드, 객체지향적 특징을 잘 살릴 수 있는 코드가 될까? &lt;/span&gt;라는 측면에서 답을 찾고자 노력했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;당근마켓이라는 서비스는 일반 사용자도 존재하지만 지역 게시판에 자신의 가게를 홍보할 수 있는 사장님이라는 권한을 가진 사용자도 존재합니다. 떄문에 사용자 서비스는 일반 사용자들에 대한 서비스와 사장님으로 등록된 사용자들에 대한 서비스 등으로 구현을 달리 할 수 있으며, 서비스가 확장됨에 따라서 사용자의 유형도 얼마든지 확장될 가능성이 존재한다고 판단했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자 서비스는 사용자의 유형에 따라서 얼마든지 확장될 가능성을 가지고 있기 때문에 지금의 프로젝트가 &lt;b&gt;1:1 &lt;/b&gt;관계를 가지고 있다고 하지만 얼마든지 &lt;b&gt;1:N &lt;/b&gt;관계를 갖는 서비스로 확장될 수 있습니다. 또한 이러한 확장에 있어서 사용자 유형이라는 고유의 특징을 구현체마다 가지고 있기 때문에 다음과 같이 구조를 변경할 수 있을 것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;i&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;MemberService&lt;/span&gt;&lt;/i&gt;&lt;/b&gt; : 회원 서비스 인터페이스
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;i&gt;GeneralMemberService&lt;/i&gt;&lt;/span&gt;&lt;/b&gt; : 일반 회원 서비스 구현체 클래스&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;i&gt;CeoMemberService&lt;/i&gt;&lt;/span&gt;&lt;/b&gt; : 사장님 회원 서비스 구현체 클래스&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드에 정답이 존재하는 것은 아닙니다. 물론 제가 적용한 방법보다 좀 더 의미적으로 명확하고 좋은 방법들이 존재할 것입니다. 하지만 이러한 구조로 설계를 변경하면서 기존에 &lt;b&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;i&gt;MemberService&lt;/i&gt;&lt;/span&gt;&lt;/b&gt; 와 &lt;b&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;i&gt;MemberServiceImpl&lt;/i&gt;&lt;/span&gt;&lt;/b&gt; 로 설계했을 때 보다 누가봐도 충분히 이름만 가지고 동작과 역할이 유추가능한 클래스 이름을 가지고 있으며, 기존에 추상화를 사용함으로써 얻을 수 있는 장점을 그대로 유지할 수 있는 구조로 개선할 수 있게 되었습니다.&lt;/p&gt;</description>
      <category>Spring Framework/Spring MVC</category>
      <category>Bridge Pattern</category>
      <category>Interface</category>
      <category>OOP</category>
      <category>service</category>
      <category>serviceimpl</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2344</guid>
      <comments>https://xzio.tistory.com/2344#entry2344comment</comments>
      <pubDate>Tue, 26 Dec 2023 18:48:57 +0900</pubDate>
    </item>
    <item>
      <title>K&amp;amp;R, BSD, GNU 코딩스타일</title>
      <link>https://xzio.tistory.com/2343</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #666666; text-align: start;&quot; data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;BSD, K&amp;amp;R 코딩 스타일&lt;/b&gt;&lt;/blockquote&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;bsd와 k&amp;amp;r의 가장큰 차이는 중괄호( {} )의 위치입니다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. K&amp;amp;R 코딩 스타일&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;여는 블록을 조건에 한 줄로 같은 행에 배치합니다. 코드 줄 수를 절약하여 한눈에 많은 코드를 작성할 수 있습니다.&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;BSD 스타일로 작성한 코드를 K&amp;amp;R 스타일로 동일하게 작성해 보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1703583733221&quot; class=&quot;stylus&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;if(조건){
   처리 로직
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;예시)&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1703583733222&quot; class=&quot;stylus&quot; style=&quot;color: #555555; text-align: start;&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;if(d == 1){	
   if(b == 1){
      처리로직	
   }else{
      처리로직
   }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. BSD 스타일&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;BSD는 줄간격이 한눈에 들어오지만 단점은 코드가 길어진다는 단점이 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1703583643359&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;if(조건)
{
   처리로직
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;예시)&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1703583617611&quot; class=&quot;java&quot; style=&quot;color: #555555; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;if(d == 1)
{	
   if(b == 1)
   {
      처리로직	
   }
   else
   {
      처리로직
   }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. GNU 코딩 스타일&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;블록을 조건문 아래에 작성합니다. 블록이 속한 블록임을 분명히 표시하여 구조가 잘 보입니다. 하지만 들여 쓰기를 많이 해서 처리하기에 수평으로 많은 코드를 작성할 수 없습니다.&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;위에서 작성한 동일한 코드를 예시로 들어 보겠습니다.&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 개인적으로 많은 사람들의 코드를 보아왔지만 이런 스타일로 작성하는 분은 아직 못 봤습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1703583703582&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;if(조건)
    {
      처리 로직
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;예시)&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1703583617613&quot; class=&quot;java&quot; style=&quot;color: #555555; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;if(d == 1)
    {	
      if(b == 1)
         {
           처리로직	
         }
         else
         {
           처리로직
         }
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고 :&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://namu.wiki/w/%EC%BD%94%EB%94%A9%20%EC%8A%A4%ED%83%80%EC%9D%BC&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://namu.wiki/w/%EC%BD%94%EB%94%A9%20%EC%8A%A4%ED%83%80%EC%9D%BC&lt;/a&gt;&lt;/p&gt;</description>
      <category>기타 정보/ETC</category>
      <category>BSD</category>
      <category>GNU</category>
      <category>K&amp;amp;R</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2343</guid>
      <comments>https://xzio.tistory.com/2343#entry2343comment</comments>
      <pubDate>Tue, 26 Dec 2023 18:43:10 +0900</pubDate>
    </item>
    <item>
      <title>아톰 필수 플러그인 추천</title>
      <link>https://xzio.tistory.com/2340</link>
      <description>&lt;div id=&quot;SE-e37d7e35-13a3-11e9-8c37-2bbb27bb60a9&quot; style=&quot;background-color: #ffffff; color: #888888; text-align: left;&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;h2 id=&quot;SE-e37d7e34-13a3-11e9-8c37-d1b0cc6a87d8&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #0076c8;&quot;&gt;1. atom-beautify&lt;/span&gt;&lt;/h2&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;SE-60BAD437-8212-4E51-B738-C70825B39E7A&quot; style=&quot;background-color: #ffffff; color: #888888; text-align: left;&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p id=&quot;SE-AF7B7CC2-4F28-45DA-A796-2261258ECA60&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #f12f22;&quot;&gt;&lt;b&gt;(19.1.8 수정 deprecated 되었습니다)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;SE-e37d7e36-13a3-11e9-8c37-ed1f4ee397ba&quot; style=&quot;background-color: #ffffff; color: #888888; text-align: left;&quot;&gt;
&lt;div&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;443&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZTrLI/btsCuP1X1ZO/nsiSlbdwec8GBok93X3wI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZTrLI/btsCuP1X1ZO/nsiSlbdwec8GBok93X3wI0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZTrLI/btsCuP1X1ZO/nsiSlbdwec8GBok93X3wI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZTrLI%2FbtsCuP1X1ZO%2FnsiSlbdwec8GBok93X3wI0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;966&quot; height=&quot;443&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;443&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;SE-e37d7e46-13a3-11e9-8c37-9766d1309438&quot; style=&quot;background-color: #ffffff; color: #888888; text-align: left;&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p id=&quot;SE-e37d7e38-13a3-11e9-8c37-6db55f496fe6&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;아톰 필수 플러그인중 하나인 atom-beautify &lt;/span&gt;&lt;span&gt;저기 다운로드 수 보이시죠??&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-e37d7e3c-13a3-11e9-8c37-1b083a6cda53&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;5백만이 넘는 사람이 다운한걸보면 확실히 필수가 맞는것 같아요.&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-e37d7e3e-13a3-11e9-8c37-73870eaa248f&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;atom-beautify 플러그인은&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-e37d7e40-13a3-11e9-8c37-83c9bd02a383&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이름 그대로 이쁘게 만들어주는 플러그인입니다&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-e37d7e42-13a3-11e9-8c37-61f1ee08963a&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;인덴테이션(indentation)을 예쁘게 만들어줘서 보기좋게 합니다&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-e37d7e44-13a3-11e9-8c37-0ff47b724362&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;코딩할때 indentation 깔끔하게 하는건 필수인거 아시죠???&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div id=&quot;SE-e37d7e49-13a3-11e9-8c37-e3c64550b9bc&quot; style=&quot;background-color: #ffffff; color: #888888; text-align: left;&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;h2 id=&quot;SE-e37d7e48-13a3-11e9-8c37-3b5578e01466&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #0076c8;&quot;&gt;2. auto close-html&lt;/span&gt;&lt;/h2&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;SE-e37d7e4a-13a3-11e9-8c37-071f01ee8075&quot; style=&quot;background-color: #ffffff; color: #888888; text-align: left;&quot;&gt;
&lt;div&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;396&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beAdj8/btsCtEl7hPm/LiSD2kESJYh5Sdf5fKYy10/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/beAdj8/btsCtEl7hPm/LiSD2kESJYh5Sdf5fKYy10/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/beAdj8/btsCtEl7hPm/LiSD2kESJYh5Sdf5fKYy10/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbeAdj8%2FbtsCtEl7hPm%2FLiSD2kESJYh5Sdf5fKYy10%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;966&quot; height=&quot;396&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;396&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;SE-e37d7e4d-13a3-11e9-8c37-033e322f7ca5&quot; style=&quot;background-color: #ffffff; color: #888888; text-align: left;&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p id=&quot;SE-5AF41D57-1991-4DAD-9E89-B9AB8E8991CA&quot; style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;​&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;SE-e37d7e50-13a3-11e9-8c37-d9af0db019b9&quot; style=&quot;background-color: #ffffff; color: #888888; text-align: left;&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;h2 id=&quot;SE-e37d7e4f-13a3-11e9-8c37-af26cbbf3c67&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #0076c8;&quot;&gt;3. code-peek&lt;/span&gt;&lt;/h2&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;SE-e37d7e51-13a3-11e9-8c37-d104dde4479d&quot; style=&quot;background-color: #ffffff; color: #888888; text-align: left;&quot;&gt;
&lt;div&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;417&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cZyjB1/btsCtHJS3x0/xyCAfNJUno735xiQVcTyH0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cZyjB1/btsCtHJS3x0/xyCAfNJUno735xiQVcTyH0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cZyjB1/btsCtHJS3x0/xyCAfNJUno735xiQVcTyH0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcZyjB1%2FbtsCtHJS3x0%2FxyCAfNJUno735xiQVcTyH0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;966&quot; height=&quot;417&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;417&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;SE-e37da569-13a3-11e9-8c37-6f39c3c333ee&quot; style=&quot;background-color: #ffffff; color: #888888; text-align: left;&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p id=&quot;SE-e37d7e53-13a3-11e9-8c37-3d1c3dd7b873&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;code-peek 플러그인은 함수를 구현하다가 보면 다른&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-e37da565-13a3-11e9-8c37-a30ff7707192&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;파일에서 함수를 따로 구현할 경우가 있는데요&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-e37da567-13a3-11e9-8c37-471cf8e358c7&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그럴 경우 함수가 정의되어있는 파일을 자동으로 열어서 보게해줍니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;SE-e37da56c-13a3-11e9-8c37-41c1ca4a433a&quot; style=&quot;background-color: #ffffff; color: #888888; text-align: left;&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;h2 id=&quot;SE-e37da56b-13a3-11e9-8c37-8b2b6f2b468e&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #0076c8;&quot;&gt;4. color-picker&lt;/span&gt;&lt;/h2&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;SE-e37da56d-13a3-11e9-8c37-f7c8ed4a0313&quot; style=&quot;background-color: #ffffff; color: #888888; text-align: left;&quot;&gt;
&lt;div&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;421&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVQ8Ou/btsCu2mDGe6/pbUcKYBat85ifkxZPdrRZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVQ8Ou/btsCu2mDGe6/pbUcKYBat85ifkxZPdrRZK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVQ8Ou/btsCu2mDGe6/pbUcKYBat85ifkxZPdrRZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVQ8Ou%2FbtsCu2mDGe6%2FpbUcKYBat85ifkxZPdrRZK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;966&quot; height=&quot;421&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;421&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;SE-e37da575-13a3-11e9-8c37-93c525e97963&quot; style=&quot;background-color: #ffffff; color: #888888; text-align: left;&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p id=&quot;SE-e37da56f-13a3-11e9-8c37-5d2c11266a45&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;html 태그 이름만 입력해도 자동으로 시작 및 종료 태그를&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-e37da571-13a3-11e9-8c37-0b935eb6417a&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;알아서 붙여주는 플러그인이에요.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #0076c8;&quot;&gt;5. emmet&lt;/span&gt;&lt;/h2&gt;
&lt;div id=&quot;SE-e37da57e-13a3-11e9-8c37-679c7da81f5a&quot; style=&quot;background-color: #ffffff; color: #888888; text-align: left;&quot;&gt;
&lt;div&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;360&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjJF3d/btsCuOvccKr/vgTkaFRkrcWBALAXaNfTyK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjJF3d/btsCuOvccKr/vgTkaFRkrcWBALAXaNfTyK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjJF3d/btsCuOvccKr/vgTkaFRkrcWBALAXaNfTyK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjJF3d%2FbtsCuOvccKr%2FvgTkaFRkrcWBALAXaNfTyK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;966&quot; height=&quot;360&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;360&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;SE-e37da588-13a3-11e9-8c37-c7e21115fc50&quot; style=&quot;background-color: #ffffff; color: #888888; text-align: left;&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p id=&quot;SE-e37da580-13a3-11e9-8c37-b5d1fe3ae867&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;html, CSS 파일들을 작성하기 쉽게 해주는 플러그인이에요&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-e37da582-13a3-11e9-8c37-658c7c7fbd42&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;웹을 작성한다면 필수로 쓰이는 플러그인이라고 할 수있죠&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-e37da584-13a3-11e9-8c37-c9cae066d12c&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;저는 아직 html이랑 CSS쪽 개발은 해보지 않았지만&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-e37da586-13a3-11e9-8c37-03d95299874e&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;우선 깔아두었어요!!&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-e37da58a-13a3-11e9-8c37-79cc6d07178a&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;위 처럼 이렇게 밑에 자동완성 기능도 있어서&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-e37da58c-13a3-11e9-8c37-0f13cdfe1efd&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;태그를 쉽게 완성하는걸 볼 수 있어요 완전 편함...&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-e37da58e-13a3-11e9-8c37-0f86dc4adb49&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;안드로이드 xml 개발때 태그를 썼었는데&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-e37da590-13a3-11e9-8c37-8daba5c89c96&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;아톰이 더 이쁘고 편한것 같네요.&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;SE-e37da597-13a3-11e9-8c37-2742564f2d5f&quot; style=&quot;background-color: #ffffff; color: #888888; text-align: left;&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;h2 id=&quot;SE-e37da596-13a3-11e9-8c37-cd0a5d3cbefb&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #0076c8;&quot;&gt;6. highlight-selected&lt;/span&gt;&lt;/h2&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;SE-e37da598-13a3-11e9-8c37-eb6b5126503b&quot; style=&quot;background-color: #ffffff; color: #888888; text-align: left;&quot;&gt;
&lt;div&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;393&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QVNBa/btsCv6vEktq/3Q6aj5OsQ64xngOPkxuSEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QVNBa/btsCv6vEktq/3Q6aj5OsQ64xngOPkxuSEK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QVNBa/btsCv6vEktq/3Q6aj5OsQ64xngOPkxuSEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQVNBa%2FbtsCv6vEktq%2F3Q6aj5OsQ64xngOPkxuSEK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;966&quot; height=&quot;393&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;393&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;SE-e37da5a4-13a3-11e9-8c37-97652bbc9bbb&quot; style=&quot;background-color: #ffffff; color: #888888; text-align: left;&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p id=&quot;SE-e37da59a-13a3-11e9-8c37-7b2ab516a49d&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이것도 나름 많은 사람들이 받은 플러그인이에요&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-e37da59c-13a3-11e9-8c37-25b86b0da368&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;간단하지만 있으면 나름 보기 좋아요&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-e37da59e-13a3-11e9-8c37-dfdbc15e4978&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;현재 자신이 편집하고 잇는 코드의 행을 밝게 보여주는 기능이에요&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-e37da5a0-13a3-11e9-8c37-ed59cd5c22f3&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;코딩하다보면서 별로 느끼지 못했을 수도 있지만&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-e37da5a2-13a3-11e9-8c37-bf67eac1878e&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이게 없으면 또 이상할거에요.&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div id=&quot;SE-e37dccbc-13a3-11e9-8c37-a38bffe7b744&quot; style=&quot;background-color: #ffffff; color: #888888; text-align: left;&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;h2 id=&quot;SE-e37dccbb-13a3-11e9-8c37-7baa31cf60e0&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #0076c8;&quot;&gt;7. minimap&lt;/span&gt;&lt;/h2&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;SE-e37dccbd-13a3-11e9-8c37-9b9ada48a1d8&quot; style=&quot;background-color: #ffffff; color: #888888; text-align: left;&quot;&gt;
&lt;div&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;401&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BoHdQ/btsCw6ICrdQ/rDGZs8713rTRvX26NPCkx1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BoHdQ/btsCw6ICrdQ/rDGZs8713rTRvX26NPCkx1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BoHdQ/btsCw6ICrdQ/rDGZs8713rTRvX26NPCkx1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBoHdQ%2FbtsCw6ICrdQ%2FrDGZs8713rTRvX26NPCkx1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;966&quot; height=&quot;401&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;401&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;SE-e37dccc9-13a3-11e9-8c37-61ae80bc887e&quot; style=&quot;background-color: #ffffff; color: #888888; text-align: left;&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p id=&quot;SE-e37dccbf-13a3-11e9-8c37-316dc1b390ce&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;아톰(atom) 필수 플러그인들 중 하나인 minimap이에요&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-e37dccc1-13a3-11e9-8c37-f1ad2ae48835&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이름그대로 mimimap을 보여주는 기능이에요&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-e37dccc3-13a3-11e9-8c37-c11c740faf3b&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;안드로이드 스튜디오에도 있었던 기능인것 같은데&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-e37dccc5-13a3-11e9-8c37-b397f301ff1a&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;코드가 만약 엄청~~~~길때 지금 코드의 위치가 현재 어디인지&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-e37dccc7-13a3-11e9-8c37-19335215972e&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;minimap을 통해 확인 할 수 있어요&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;SE-e37dccca-13a3-11e9-8c37-358267a73f3d&quot; style=&quot;background-color: #ffffff; color: #888888; text-align: left;&quot;&gt;
&lt;div&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;533&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWDDiZ/btsCr98ewmC/nmPTusxVQBhsHedSkY7UqK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWDDiZ/btsCr98ewmC/nmPTusxVQBhsHedSkY7UqK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWDDiZ/btsCr98ewmC/nmPTusxVQBhsHedSkY7UqK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWDDiZ%2FbtsCr98ewmC%2FnmPTusxVQBhsHedSkY7UqK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;966&quot; height=&quot;533&quot; data-origin-width=&quot;966&quot; data-origin-height=&quot;533&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;SE-e37dccf6-13a3-11e9-8c37-f3fd0f9e7e91&quot; style=&quot;background-color: #ffffff; color: #888888; text-align: left;&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p id=&quot;SE-e37dcccc-13a3-11e9-8c37-efd07afd2b2b&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이렇게 코드를 작성하게 되면 오른쪽에 minimap이 나와서&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-e37dccce-13a3-11e9-8c37-870480cf2fed&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;쉽게 확인 할 수 있어요.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;출처 : &lt;a href=&quot;https://blog.naver.com/wlgh325/221399860316&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://blog.naver.com/wlgh325/221399860316&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>Editor Tool/Atom</category>
      <category>ATOM</category>
      <category>ATOM에디터</category>
      <category>아톰</category>
      <category>아톰에디터</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2340</guid>
      <comments>https://xzio.tistory.com/2340#entry2340comment</comments>
      <pubDate>Fri, 22 Dec 2023 15:20:16 +0900</pubDate>
    </item>
    <item>
      <title>맥(Mac)에서 모든 창 최소화 하는 방법</title>
      <link>https://xzio.tistory.com/2338</link>
      <description>&lt;pre id=&quot;code_1703152026467&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Command + Option + H, M&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;윈도우를 사용할 때는 아주 오래전부터 [윈도우 키 + M]으로 모든 창 최소화를 하여 열려있는 모든 윈도우를 숨겼습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바탕화면에 있는 아이콘을 클릭하기 위해서나 알트탭(Alt + Tab)보다 극단적으로 모든 창을 내리기 위한 수단이었는데&lt;br /&gt;당연히 익숙한 동작이였기에 맥에서도 이러한 기능이 필요했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 방법을 찾았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #0593d3;&quot;&gt;&lt;b&gt;Command&amp;nbsp;+&amp;nbsp;Option&amp;nbsp;누른&amp;nbsp;채로&amp;nbsp;H&amp;nbsp;누르고&amp;nbsp;다시&amp;nbsp;M&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정확하게는, cmd+option+h가 전면에 있는 앱을 제외한 나머지 앱을 모두 가리고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기에 cmd+m 해서 전면에 있는 앱을 최소화하는 것입니다.&lt;/p&gt;</description>
      <category>OS/Mac OS</category>
      <category>Mac</category>
      <category>최소화</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2338</guid>
      <comments>https://xzio.tistory.com/2338#entry2338comment</comments>
      <pubDate>Thu, 21 Dec 2023 18:50:25 +0900</pubDate>
    </item>
    <item>
      <title>[IntelliJ] Google Java Code Style 적용</title>
      <link>https://xzio.tistory.com/2337</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;1. Code Style(Google Style) 다운로드&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/google/styleguide&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/google/styleguide&lt;/a&gt;&amp;nbsp;에서&amp;nbsp;intellij-java-google-style.xml를&amp;nbsp;다운로드&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;903&quot; data-origin-height=&quot;124&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bq8pWP/btsCof1Atbz/bK1jd8BNMfdprlUSAqxHJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bq8pWP/btsCof1Atbz/bK1jd8BNMfdprlUSAqxHJk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bq8pWP/btsCof1Atbz/bK1jd8BNMfdprlUSAqxHJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbq8pWP%2FbtsCof1Atbz%2FbK1jd8BNMfdprlUSAqxHJk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;903&quot; height=&quot;124&quot; data-origin-width=&quot;903&quot; data-origin-height=&quot;124&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. File &amp;gt; Settings(mac : command + , / Windows : Ctrl + Alt + S)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Editor &amp;gt; Code Style &amp;gt; Scheme 편집 &amp;gt; Import Scheme &amp;gt; IntelliJ IDEA code style XML을 선택&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;979&quot; data-origin-height=&quot;710&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbOSPI/btsCseNB35w/EAtPn9SS8SJ1jIrFW2SGok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbOSPI/btsCseNB35w/EAtPn9SS8SJ1jIrFW2SGok/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbOSPI/btsCseNB35w/EAtPn9SS8SJ1jIrFW2SGok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbOSPI%2FbtsCseNB35w%2FEAtPn9SS8SJ1jIrFW2SGok%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;979&quot; height=&quot;710&quot; data-origin-width=&quot;979&quot; data-origin-height=&quot;710&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 다운로드 받은 intellij-java-google-style.xml를 선택&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. Apply 클릭&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;894&quot; data-origin-height=&quot;694&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhJHFx/btsCsg5KT2L/5KelxNN3wtf0Kl8CXKNH61/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhJHFx/btsCsg5KT2L/5KelxNN3wtf0Kl8CXKNH61/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhJHFx/btsCsg5KT2L/5KelxNN3wtf0Kl8CXKNH61/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbhJHFx%2FbtsCsg5KT2L%2F5KelxNN3wtf0Kl8CXKNH61%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;894&quot; height=&quot;694&quot; data-origin-width=&quot;894&quot; data-origin-height=&quot;694&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. Edittor &amp;gt; Code Style &amp;gt; Java 에서 Tab&amp;nbsp;Size와&amp;nbsp;Indent를&amp;nbsp;4로&amp;nbsp;수정한&amp;nbsp;후&amp;nbsp;Apply&amp;nbsp;버튼을&amp;nbsp;클릭&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;894&quot; data-origin-height=&quot;694&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cg64gg/btsCoHQTuHO/TgOY5uXlfnEsS2BcCNqcv0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cg64gg/btsCoHQTuHO/TgOY5uXlfnEsS2BcCNqcv0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cg64gg/btsCoHQTuHO/TgOY5uXlfnEsS2BcCNqcv0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcg64gg%2FbtsCoHQTuHO%2FTgOY5uXlfnEsS2BcCNqcv0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;894&quot; height=&quot;694&quot; data-origin-width=&quot;894&quot; data-origin-height=&quot;694&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 적용완료&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;맥 기준으로 Cmd&amp;nbsp;+&amp;nbsp;Option&amp;nbsp;+&amp;nbsp;L&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;윈도우 기준으로 Ctrl + Alt+ L&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;누르면 자동으로 코드 스타일이 정리&lt;/p&gt;</description>
      <category>IDE Tool/IntelliJ IDEA 내 설정</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2337</guid>
      <comments>https://xzio.tistory.com/2337#entry2337comment</comments>
      <pubDate>Thu, 21 Dec 2023 17:29:09 +0900</pubDate>
    </item>
    <item>
      <title>macOS에서 java(open jdk) 설치</title>
      <link>https://xzio.tistory.com/2336</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;mac 사용자들은 대부분 homebrew를 통해 jdk를 설치하지만&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;직접 다운로드하여 설정하는 방법을 알아 보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jdk.java.net/archive/&quot;&gt;https://jdk.java.net/archive/&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에서 원하는 버전의 jdk를 os에 맞게 다운로드&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다운로드 받은 파일의 압축 해제&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;/Library/Java/JavaVirtualMachines/&lt;span&gt;&amp;nbsp;&lt;/span&gt;아래에 디렉토리 이동&lt;/p&gt;
&lt;pre id=&quot;code_1702270696598&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo mv jdk-17.0.2.jdk /Library/Java/JavaVirtualMachines&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;터미널에서&amp;nbsp;java -version&amp;nbsp;명령어를 통해 설치 확인&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;아래와 같이 출력되면 설치 성공&lt;/p&gt;
&lt;pre class=&quot;bash&quot; style=&quot;color: #000000; text-align: left;&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;openjdk version &quot;17.0.2&quot; 2022-01-18
OpenJDK Runtime Environment (build 17.0.2+8-86)
OpenJDK 64-Bit Server VM (build 17.0.2+8-86, mixed mode, sharing)&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;설치된 jdk 목록 출력&lt;/p&gt;
&lt;pre class=&quot;bash&quot; style=&quot;color: #000000; text-align: left;&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;/usr/libexec/java_home -V&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;865&quot; data-origin-height=&quot;99&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ccih1p/btsBGFsuhy1/cOdWDDP84hBkH4DPkFcYQ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ccih1p/btsBGFsuhy1/cOdWDDP84hBkH4DPkFcYQ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ccih1p/btsBGFsuhy1/cOdWDDP84hBkH4DPkFcYQ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fccih1p%2FbtsBGFsuhy1%2FcOdWDDP84hBkH4DPkFcYQ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;865&quot; height=&quot;99&quot; data-origin-width=&quot;865&quot; data-origin-height=&quot;99&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;설치된 jdk 목록을 확인한 후 원하는 jdk 버전을 아래 명령어를 통해 설정&lt;br /&gt;예시에서는 17.0.2로 설정&lt;/p&gt;
&lt;pre class=&quot;bash&quot; style=&quot;color: #000000; text-align: left;&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;export JAVA_HOME=`/usr/libexec/java_home -v 17.0.2`&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;다시&lt;span&gt;&amp;nbsp;&lt;/span&gt;java -version&lt;span&gt;&amp;nbsp;&lt;/span&gt;을 통해 잘 설정되었는지 확인&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;잘 되었으면 버전설정 명령어를&lt;span&gt;&amp;nbsp;&lt;/span&gt;$HOME/.bashrc&lt;span&gt;&amp;nbsp;&lt;/span&gt;나&lt;span&gt;&amp;nbsp;&lt;/span&gt;$HOME/.zshrc&lt;span&gt;&amp;nbsp;&lt;/span&gt;등에 작성&lt;/p&gt;</description>
      <category>JAVA/Java Release Note</category>
      <category>Java</category>
      <category>OpenJDK</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2336</guid>
      <comments>https://xzio.tistory.com/2336#entry2336comment</comments>
      <pubDate>Mon, 11 Dec 2023 14:06:27 +0900</pubDate>
    </item>
    <item>
      <title>[JAVA] 빌더 패턴(Builder Pattern)을 사용해야 하는 이유</title>
      <link>https://xzio.tistory.com/2325</link>
      <description>&lt;h3 id=&quot;1-빌더-패턴builder-pattern을-사용해야-하는-이유&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;1. 빌더 패턴(Builder Pattern)을 사용해야 하는 이유&lt;/h3&gt;
&lt;h4 id=&quot;빌더-패턴-장점&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;빌더 패턴 장점&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;필요한 데이터만 설정할 수 있음&lt;/li&gt;
&lt;li&gt;유연성을 확보할 수 있음&lt;/li&gt;
&lt;li&gt;가독성을 높일 수 있음&lt;/li&gt;
&lt;li&gt;불변성을 확보할 수 있음&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&quot;1-필요한-데이터만-설정할-수-있음&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;1. 필요한 데이터만 설정할 수 있음&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 User 객체를 생성하는데 age라는 parameter가 필요 없는 상황이라고 가정.&lt;br /&gt;생성자나 정적 메소드를 이용하는 경우라면 우리는 age에 더미 값을 넣어주거나 age가 없는 생성자를 새로 만들어주어야 한다.&lt;/p&gt;
&lt;pre class=&quot;java&quot; style=&quot;color: #212529; text-align: start;&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;// 1. 더미 값
User user = new User(&quot;테스트&quot;, 0, 181, 121);

// 2. 생성자 또는 정적 메소드를 추가하는 방법
@NoArgsConstructor
@AllArgsConstrctor
public class User{
	private String name;
    private int age;
    private int height;
    private int iq;
    
    public User(String name, int height, int iq){
    	this.name = name;
        this.height = height;
        this.iq = iq;
    }
    
    public User static of(String name, int height, int iq){
    	return new User(name, 0, 181, 121);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이러한 작업이 한두번이면 괜찮지만 반복적인 경우 시간 낭비로 이어지게 된다. 하지만 빌더를 이용하면 동적으로 이를 처리할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;java&quot; style=&quot;color: #212529; text-align: start;&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;User user = User.builder()
			.name(&quot;테스트&quot;)
            .heihgt(181)
            .iq(121).build();&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 이렇게 필요한 데이터만 설정할 수 있는 빌더의 장점은 생성자 또는 정적 메소드와 비교하여 테스트용 객체를 생성할 때 용이하게 해주고 불필요한 코드의 양을 줄이는 등의 이점을 안겨준다.&lt;/p&gt;
&lt;h4 id=&quot;2-유연성을-확보할-수-있음&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;2. 유연성을 확보할 수 있음&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 User 클래스에 몸무게를 나타내는 새로운 변수 weight를 추가해야 한다고 하자. 하지만 이미 생성자로 객체를 만드는 코드가 있다고 가정&lt;/p&gt;
&lt;pre class=&quot;java&quot; style=&quot;color: #212529; text-align: start;&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;// ASIS
User user = new User(&quot;테스트&quot;, 19, 181, 121);

// TOBE
User user = new User(&quot;테스트&quot;, 19, 181, 121, 79);&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그러면 우리는 새롭게 추가되는 변수 때문에 기존의 모든 코드를 수정해야 하는 상황에 직면하게 된다. 하지만 빌더 패턴을 이용하면 새로운 변수가 추가되는 등의 상황에 직면하여도 기존의 코드에 영향을 주지 않을 수 있다.&lt;/p&gt;
&lt;h4 id=&quot;3-가독성을-높일-수-있음&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;3. 가독성을 높일 수 있음&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;빌더 패턴을 사용하면 매개변수가 많아져도 가독성을 높일 수 있다. 생성자로 객체를 생성하는 경우에는 매개변수가 많아질수록 코드 리딩이 급격하게 떨어진다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;User user = new User(&quot;테스트&quot;, 19, 181, 121);&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;19, 181, 121이 무엇을 의미하는지 바로 파악하기 힘들고 파라미터의 개수가 많아질수록 코드를 읽기 더 힘들어진다. 하지만 다음과 같이 빌더 패턴을 적용하면 가독성을 높일 수 있고 직관적인 데이터를 파악할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;java&quot; style=&quot;color: #212529; text-align: start;&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;User user = User.builder()
			.name(&quot;테스트&quot;)
            .age(19)
            .height(181)
            .iq(121).build();&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;4-불변성을-확보할-수-있음&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;4. 불변성을 확보할 수 있음&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;많은 개발자들이 수정자 패턴(Setter)를 흔히 사용한다. 하지만 Setter를 구현하다는 것은 불필요하게 확장 가능성을 열어두는 것이다. 이는 Open-Closed 법칙에 위배되고 불필요한 코드 리딩 등을 유발한다. 그렇기 때문에 클래스 변수를 final로 선언하고 객체의 생성은 빌더에 맡기는 것이 좋다.&lt;/p&gt;
&lt;pre class=&quot;java&quot; style=&quot;color: #212529; text-align: start;&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;@RequiredArgsConstructor
@Builder
public class User{
	private final String name;
    private final int age;
    private final int height;
    private final int iq;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출처 : &lt;a href=&quot;https://velog.io/@bey1548/JAVA-%EB%B9%8C%EB%8D%94-%ED%8C%A8%ED%84%B4Builder-Pattern%EC%9D%84-%EC%82%AC%EC%9A%A9%ED%95%B4%EC%95%BC-%ED%95%98%EB%8A%94-%EC%9D%B4%EC%9C%A0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://velog.io/@bey1548/JAVA-%EB%B9%8C%EB%8D%94-%ED%8C%A8%ED%84%B4Builder-Pattern%EC%9D%84-%EC%82%AC%EC%9A%A9%ED%95%B4%EC%95%BC-%ED%95%98%EB%8A%94-%EC%9D%B4%EC%9C%A0&lt;/a&gt;&lt;/p&gt;</description>
      <category>JAVA/Lombok</category>
      <category>builder</category>
      <category>Java</category>
      <category>Lombok</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2325</guid>
      <comments>https://xzio.tistory.com/2325#entry2325comment</comments>
      <pubDate>Tue, 28 Nov 2023 16:14:20 +0900</pubDate>
    </item>
    <item>
      <title>git 명령어</title>
      <link>https://xzio.tistory.com/2324</link>
      <description>&lt;h3 id=&quot;A5a2.명령어-용어&quot; style=&quot;background-color: #ffffff; color: #172b4d; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;용어&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #172b4d; text-align: left;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Committed: 데이터가 로컬 데이터베이스에 안전하게 저장됐다는 것을 의미&lt;/li&gt;
&lt;li&gt;Modified: 수정한 데이터를 아직 로컬 데이터베이스에 커밋하지 않은 것을 의미&lt;/li&gt;
&lt;li&gt;Staged: 수정한 파일을 곧 커밋한 것이라고 표시한 상태를 의미&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;A5a2.명령어-설정&quot; style=&quot;background-color: #ffffff; color: #172b4d; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;설정&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #172b4d; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;설정 정보는 3가지 형태로 관리가 되며, 우선순위는 local &amp;gt; global &amp;gt; system 순입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #172b4d; text-align: left;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;system: /etc/gitconfig 파일에 저장되며 git config --system 명령으로 수정 가능&lt;/li&gt;
&lt;li&gt;global: ~/.gitconfig, ~/.config/git/config 파일에 저장되며 git config --global 명령으로 수정 가능&lt;/li&gt;
&lt;li&gt;local: 프로젝트 .git/config 파일에 저장되며 git config --local 명령으로 수정 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;background-color: #ffffff; color: #172b4d; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Git은 Commit을 할때 사용자 정보를 추가 합니다. 다음 명령으로 사용자 정보를 변경할 수 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #172b4d; text-align: left;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;git config --global&lt;span&gt;&amp;nbsp;&lt;/span&gt;user.name&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;{이름}&quot;&lt;/li&gt;
&lt;li&gt;git config --global user.email &quot;{이메일}&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;A5a2.명령어-상태&quot; style=&quot;background-color: #ffffff; color: #172b4d; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;상태&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #172b4d; text-align: left;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;git status: 파일 상태 확인.- --ignored 옵션을 이용해서 제외된 파일 확인 가능&lt;/li&gt;
&lt;li&gt;git status -s: 파일 상태를 간략히 표시&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;A5a2.명령어-로그&quot; style=&quot;background-color: #ffffff; color: #172b4d; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;로그&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #172b4d; text-align: left;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;git log: commit 로그를 확인 합니다.&lt;/li&gt;
&lt;li&gt;git log --oneline --graph: commit 정보를 1줄로 표현하고, 커밋 그래프를 보여줍니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;A5a2.명령어-비교&quot; style=&quot;background-color: #ffffff; color: #172b4d; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;비교&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #172b4d; text-align: left;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;git diff: Committed 와 Modified 상태를 비교 합니다.&lt;/li&gt;
&lt;li&gt;git diff --cached: Committed와 Staged 상태를 비교 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;A5a2.명령어-병합&quot; style=&quot;background-color: #ffffff; color: #172b4d; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;병합&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #172b4d; text-align: left;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;git merge&amp;nbsp;{Branch Name}&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;feat-forward merge: 서로 다른 브랜치중 1개가 다른 브랜치 base와 같을때 발생하며 별다른 커밋이 생성되지 않고 단지 브랜치 위치만 변경한다.&lt;/li&gt;
&lt;li&gt;3-way merge: 서로 다른 브랜치가 공통된 커밋(base)가 있으며 공통된 커밋으로 부터 각자 커밋을 생성하였을 때 발생한다. 커밋 후에는 새로운 브랜치가 생성이 되고 자동 병합을 진행한다. 자동 병합이 실패한 변경에 내용에는 충돌(conflict)이 발생을 하며, 수동으로 수정을 한 후에 다시 커밋을 해야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;A5a2.명령어-cherry-pick&quot; style=&quot;background-color: #ffffff; color: #172b4d; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;cherry-pick&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #172b4d; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;다른 브랜치 커밋 이력중 특정 커밋의 변경 내용을 가져와 현재 커밋에 추가 합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #172b4d; text-align: left;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;git cherry-pick&amp;nbsp;{commit ...&amp;nbsp;}&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;A5a2.명령어-stash&quot; style=&quot;background-color: #ffffff; color: #172b4d; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;stash&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #172b4d; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;진행하고 있는 업무를 commit 없이 잠시 스택에 임시적으로 저장하여 다른 브랜치에서 작업을 할 수 있도록 합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #172b4d; text-align: left;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;git stash: 작업 내용은 스택에 넣어 임시 저장 한다&lt;/li&gt;
&lt;li&gt;git stash list: stash 목록을 확인한다&lt;/li&gt;
&lt;li&gt;git stash apply&amp;nbsp;{stash 이름}: 스택에 있는 작업을 가져와 적용한다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;git stash drop&amp;nbsp;{stash 이름}: 스택에 저장되어 있는 작업 내역을 삭제 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;A5a2.명령어-Rebase&quot; style=&quot;background-color: #ffffff; color: #172b4d; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;Rebase&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #172b4d; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;두 브랜치를 합치는 방법으로 이름에서 알 수 있듯이 두 브랜치의 공통 커밋(base)부터 작업 브랜치 까지 변경 내용을 기록하여 대상 브랜치에 동일한 순서대로 적용하는 방법 입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #172b4d; text-align: left;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;git rebase&amp;nbsp;{branch name}&lt;/li&gt;
&lt;li&gt;git rebase -i&amp;nbsp;{branch name}&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;A5a2.명령어-Bisect&quot; style=&quot;background-color: #ffffff; color: #172b4d; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;Bisect&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #172b4d; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;버그를 검색하는 방법으로 이진 탐색으로 오류가 있는 커밋을 찾습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #172b4d; text-align: left;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;git bisect start: 이진 탐색을 시작 합니다.&lt;/li&gt;
&lt;li&gt;git bisect bad: 이동한 커밋에 버그가 있을 경우 사용하는 명령입니다. 이후 찾을 커밋이 없을 경우 .. is first bad commit 메시지를 노출한다.&lt;/li&gt;
&lt;li&gt;git bisect good: 이동한 커밋에 버그가 없을 경우 사용하는 명령입니다.&lt;/li&gt;
&lt;li&gt;git bisect reset: 이진 탐색을 종료하고 start 명령을 사용한 커밋으로 이동합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;A5a2.명령어-Blame&quot; style=&quot;background-color: #ffffff; color: #172b4d; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;Blame&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #172b4d; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;특정 파일에 줄단위로 수정자 정보를 노출 합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #172b4d; text-align: left;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;git blame&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>형상관리/Git</category>
      <category>GIT</category>
      <category>git명령어</category>
      <category>명령어</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2324</guid>
      <comments>https://xzio.tistory.com/2324#entry2324comment</comments>
      <pubDate>Tue, 28 Nov 2023 11:00:02 +0900</pubDate>
    </item>
    <item>
      <title>[GitHub] GitHub Pages 사용하기</title>
      <link>https://xzio.tistory.com/2323</link>
      <description>&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://sg-choi.tistory.com/242#%EB%93%A4%EC%96%B4%EA%B0%80%EA%B8%B0-%EC%A0%84&quot;&gt;들어가기 전&lt;/a&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;GitHub Pages : github를 활용하여 정적(jpg, html과 같은) 파일을 서비스하는 방법&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://sg-choi.tistory.com/242#repository-%EC%83%9D%EC%84%B1&quot;&gt;repository 생성&lt;/a&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;루트 페이지로 생성시
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;repository 이름 : &amp;lt;username&amp;gt;.github.io&lt;/li&gt;
&lt;li&gt;Root URL : http://&amp;lt;username&amp;gt;.github.io&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;하위 프로젝트로 생성시
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;repository 이름 : &amp;lt;프로젝트명&amp;gt;&lt;/li&gt;
&lt;li&gt;Root URL : http://&amp;lt;username&amp;gt;.github.io/&amp;lt;프로젝트명&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://sg-choi.tistory.com/242#github-pages-%ED%99%9C%EC%84%B1%ED%99%94&quot;&gt;GitHub Pages 활성화&lt;/a&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로젝트 &amp;gt; Settings&lt;/li&gt;
&lt;li&gt;GitHub Pages &amp;gt; Source : 서비스할 브랜치를 지정하면&lt;span&gt;&amp;nbsp;&lt;/span&gt;자동으로&lt;span&gt;&amp;nbsp;&lt;/span&gt;활성화&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://sg-choi.tistory.com/242#%EC%84%9C%EB%B9%84%EC%8A%A4%ED%95%A0-%EC%A0%95%EC%A0%81-%ED%8C%8C%EC%9D%BC-%EC%B6%94%EA%B0%80&quot;&gt;서비스할 정적 파일 추가&lt;/a&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로젝트 루트에 index.html 파일 추가&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1700730631195&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&quot;en&quot;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&quot;UTF-8&quot;&amp;gt;
    &amp;lt;title&amp;gt;GitHub Pages&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    Hello World
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://sg-choi.tistory.com/242#%ED%8E%98%EC%9D%B4%EC%A7%80-%EC%A0%91%EC%86%8D-%EB%B0%8F-%ED%99%95%EC%9D%B8&quot;&gt;페이지 접속 및 확인&lt;/a&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;루트 페이지로 생성한 경우 : http://&amp;lt;username&amp;gt;.github.io/index.html&lt;/li&gt;
&lt;li&gt;하위 프로젝트로 생성한 경우 : http://&amp;lt;username&amp;gt;.github.io/&amp;lt;프로젝트명&amp;gt;/index.html&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://sg-choi.tistory.com/242#%EC%B0%B8%EA%B3%A0&quot;&gt;참고&lt;/a&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://dreamgonfly.github.io/2018/01/27/jekyll-remote-theme.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://dreamgonfly.github.io/2018/01/27/jekyll-remote-theme.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출처 : &lt;a href=&quot;https://sg-choi.tistory.com/242&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://sg-choi.tistory.com/242&lt;/a&gt;&lt;/p&gt;</description>
      <category>형상관리/GitHub</category>
      <category>Github</category>
      <category>Pages</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2323</guid>
      <comments>https://xzio.tistory.com/2323#entry2323comment</comments>
      <pubDate>Thu, 23 Nov 2023 18:10:38 +0900</pubDate>
    </item>
    <item>
      <title>[백준허브] 백준, 프로그래머스 문제 GitHub 로 자동 커밋</title>
      <link>https://xzio.tistory.com/2312</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;백준허브는 Leetcode의 제출 코드를 자동 푸시해주는 LeetHub라는 프로젝트를 포크하여 만든 익스텐션으로, 백준, 프로그래머스, SWEA 문제를 해결하면 등록한 Github Repository에 자동으로 코드와 문제 요약을 푸시합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;백준허브는 내가 푼 문제가 정답일 경우 해당 코드뿐만 아니라 성능과 메모리, 구체적으로 어떤 문제였는지 까지 같이 커밋합니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;1.%20%ED%81%AC%EB%A1%AC%20%ED%99%95%EC%9E%A5%20%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8%20%EC%84%A4%EC%B9%98-1&quot; style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;1. 크롬 확장 프로그램 설치&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;크롬 웹스토어에서 백준허브 확장 프로그램을 설치합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1041&quot; data-origin-height=&quot;831&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvei8D/btsyMrXfQhT/c9JVPkSlOpuBwyf90JFac0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvei8D/btsyMrXfQhT/c9JVPkSlOpuBwyf90JFac0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvei8D/btsyMrXfQhT/c9JVPkSlOpuBwyf90JFac0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbvei8D%2FbtsyMrXfQhT%2Fc9JVPkSlOpuBwyf90JFac0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1041&quot; height=&quot;831&quot; data-origin-width=&quot;1041&quot; data-origin-height=&quot;831&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://chrome.google.com/webstore/detail/%EB%B0%B1%EC%A4%80%ED%97%88%EB%B8%8Cbaekjoonhub/ccammcjdkpgjmcpijpahlehmapgmphmk?hl=ko&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://chrome.google.com/webstore/detail/%EB%B0%B1%EC%A4%80%ED%97%88%EB%B8%8Cbaekjoonhub/ccammcjdkpgjmcpijpahlehmapgmphmk?hl=ko&lt;/a&gt;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 id=&quot;2.%20%EA%B9%83%ED%97%88%EB%B8%8C%20%EC%97%B0%EB%8F%99-1&quot; style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;2. 깃허브 연동&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-01-27 오후 7.56.35.png&quot; data-origin-width=&quot;347&quot; data-origin-height=&quot;316&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cL8pUf/btsyMNFLxSN/6imZkk0IGDzkMlt7Ex1HE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cL8pUf/btsyMNFLxSN/6imZkk0IGDzkMlt7Ex1HE0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cL8pUf/btsyMNFLxSN/6imZkk0IGDzkMlt7Ex1HE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcL8pUf%2FbtsyMNFLxSN%2F6imZkk0IGDzkMlt7Ex1HE0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;347&quot; height=&quot;316&quot; data-filename=&quot;스크린샷 2023-01-27 오후 7.56.35.png&quot; data-origin-width=&quot;347&quot; data-origin-height=&quot;316&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;크롬 확장 프로그램에서 백준허브 아이콘을 눌러&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;Authenticate&lt;/b&gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;버튼을 클릭하여 깃허브 연동을 진행합니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;3.%20%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8%20%EB%AC%B8%EC%A0%9C(%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98)%20%EB%A0%88%ED%8C%8C%EC%A7%80%ED%86%A0%EB%A6%AC%20%EC%83%9D%EC%84%B1-1&quot; style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;3. 코딩테스트 문제(알고리즘) 레파지토리 생성&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;edited_edited_4.알고리즘레파지토리만들기.jpg&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;543&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwrok1/btsyJNfGAz4/EZ5Ala0Hjatu039LAOC1LK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwrok1/btsyJNfGAz4/EZ5Ala0Hjatu039LAOC1LK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwrok1/btsyJNfGAz4/EZ5Ala0Hjatu039LAOC1LK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbwrok1%2FbtsyJNfGAz4%2FEZ5Ala0Hjatu039LAOC1LK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;543&quot; data-filename=&quot;edited_edited_4.알고리즘레파지토리만들기.jpg&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;543&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;Pick an Option&lt;/b&gt;&lt;/span&gt;에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;Create a new Private Repository&lt;/b&gt;&lt;/span&gt;를 선택하였고, 새로운 레파지토리를 생성하였습니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;Get Started&lt;/b&gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;버튼을 클릭하여 시작&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;edited_edited_5.완료.jpg&quot; data-origin-width=&quot;799&quot; data-origin-height=&quot;539&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bt9ET6/btsyHBmOX6N/fkbl2VEvEAU5Db4kUuCUE1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bt9ET6/btsyHBmOX6N/fkbl2VEvEAU5Db4kUuCUE1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bt9ET6/btsyHBmOX6N/fkbl2VEvEAU5Db4kUuCUE1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbt9ET6%2FbtsyHBmOX6N%2Ffkbl2VEvEAU5Db4kUuCUE1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;799&quot; height=&quot;539&quot; data-filename=&quot;edited_edited_5.완료.jpg&quot; data-origin-width=&quot;799&quot; data-origin-height=&quot;539&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;위와 같은 화면이 보인다면 repository가 생성되었고, 백준허브 연동이 최종적으로 완료&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;4.%20%ED%99%95%EC%9D%B8-1&quot; style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;4.&amp;nbsp; 코딩테스트 시작&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1238&quot; data-origin-height=&quot;627&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MMKYc/btsyMK3lsvq/mt9y0OYmiUqmnT2QOT5q41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MMKYc/btsyMK3lsvq/mt9y0OYmiUqmnT2QOT5q41/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MMKYc/btsyMK3lsvq/mt9y0OYmiUqmnT2QOT5q41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMMKYc%2FbtsyMK3lsvq%2Fmt9y0OYmiUqmnT2QOT5q41%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1238&quot; height=&quot;627&quot; data-origin-width=&quot;1238&quot; data-origin-height=&quot;627&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;프로그래머스에서 문제를 풀고 제출한 답이 정답일 경우, 위와 같은 알림창에서 초록색 V가 뜨는 것을 확인 가능합니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;위와 같이 초록색 체크가 뜬다면 GitHub 커밋이 완료되었다는 뜻입니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1238&quot; data-origin-height=&quot;323&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bz9JnN/btsyIKjgOWf/7goVsBFdrKWZDOAxmBQLJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bz9JnN/btsyIKjgOWf/7goVsBFdrKWZDOAxmBQLJk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bz9JnN/btsyIKjgOWf/7goVsBFdrKWZDOAxmBQLJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbz9JnN%2FbtsyIKjgOWf%2F7goVsBFdrKWZDOAxmBQLJk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1238&quot; height=&quot;323&quot; data-origin-width=&quot;1238&quot; data-origin-height=&quot;323&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;프로그래머스에서 문제를 풀었을 경우 프로그래머스 폴더에, 백준에서 풀었을 경우 백준 폴더가 별도 생성되고 각 문제를 클릭해 보면 작성한 정답과 함께 문제, 성능, 소요 시간 등을 commit message에 입력되었습니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>형상관리/GitHub</category>
      <category>Github</category>
      <category>깃허브</category>
      <category>백준허브</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2312</guid>
      <comments>https://xzio.tistory.com/2312#entry2312comment</comments>
      <pubDate>Wed, 18 Oct 2023 19:21:18 +0900</pubDate>
    </item>
    <item>
      <title>플레이 프레임워크 2.0 소개</title>
      <link>https://xzio.tistory.com/2298</link>
      <description>&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;들어 있는 내용&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: circle;&quot;&gt;&lt;span style=&quot;color: #0000cd;&quot;&gt;Play 2.0을 소개합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: circle;&quot;&gt;&lt;span style=&quot;color: #0000cd;&quot;&gt;비동기 방식의 프로그래밍을 위해 만들었어요!&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: circle;&quot;&gt;&lt;span style=&quot;color: #0000cd;&quot;&gt;타입 안전성을 중요하게 여깁니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: circle;&quot;&gt;&lt;span style=&quot;color: #0000cd;&quot;&gt;자바와 스칼라를 네이티브 방식으로 지원합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: circle;&quot;&gt;&lt;span style=&quot;color: #0000cd;&quot;&gt;강력한 빌드 시스템을 제공합니다!&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: circle;&quot;&gt;&lt;span style=&quot;color: #0000cd;&quot;&gt;데이터 저장과 모델 통합&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Play 2.0를 소개합니다.&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;2007년부터 자바 웹 어플리케이션 개발을 쉽게 만들기 위해 연구해 와습니다.&lt;br /&gt;&lt;br /&gt;플레이 프레임워크는 Zenexity의 내부 프로젝트로 개발하기 시작했습니다.&lt;br /&gt;플레이 프레임워크는 우리가 웹 프로젝트를 수행하는 방식에 영향을 많이 받았습니다.&lt;br /&gt;&lt;br /&gt;우리의 웹프로젝트&amp;nbsp; 수행방식의 특성에는 다음과 같은 것이 있습니다 :&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: circle;&quot;&gt;개발자의 생산성을 중요시하고,&lt;/li&gt;
&lt;li style=&quot;list-style-type: circle;&quot;&gt;웹 아키텍쳐를 존중하며,&lt;/li&gt;
&lt;li style=&quot;list-style-type: circle;&quot;&gt;JEE에서 사용하는 최고의 관행을 깨뜨리는 등 패키징에 관해 완전히 새로운 접근법을 시도합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;2009년에 우리는 이러한 생각들을 커뮤니티에 공유하기로 결심했고, 오픈소스 프로젝트로 진행하기 시작했어요.&lt;br /&gt;&lt;br /&gt;커뮤니티에서는 즉각적으로 매우 긍정적인 반응이 왔고, 프로젝트는 박차를 가하게 되었어요.&lt;br /&gt;&lt;br /&gt;플레이 프레임워크를 개발한 지 어느덧 2년이 되어가는 지금, 버전도 여러 개가 있고, 4000명의 회원이 참여하는 활기찬 커뮤니티도 생겼습니다. 그리고 제작에 사용되는 어플리케이션의 수는 전 세계적으로 계속 증가하고 있어요.&lt;br /&gt;&lt;br /&gt;프로젝트를 전 세계에 공개하자 매우 많은 피드백을 받았습니다.&lt;br /&gt;또한 새로운 사용예에 대해서도 알게 되었습니다.&lt;br /&gt;새로운 사용예에 따르면 새로운 기능이 추가로 필요하기도 하고, 몰랐던 버그도 알게 되었습니다. 이러한 기능이나 버그는 초기에 설계할 당시에는 고려하지 않았던 부분들이죠.&lt;br /&gt;&lt;br /&gt;2년동안 플레이 프레임워크를 오픈소스 프로젝트로 작업하는 동안, 우리는 이런 종류의 이슈들을 처리해왔고, 다양한 사용 시나리오를 위해 새로운 기능들을 통합해 왔습니다.&lt;br /&gt;&lt;br /&gt;프로젝트가 커지면서, 우리는 커뮤니티로부터, 그리고 그간의 경험으로부터 많은 것을 배웠습니다. 더욱 복잡하고 다양한 프로젝트에 플레이 프레임워크를 사용하면서 말이죠.&lt;br /&gt;&lt;br /&gt;그동안에 웹 기술은 지속적으로 발달해 왔습니다.&amp;nbsp; 웹은 모든 어플리케이션의 핵심이 되었어요.&lt;br /&gt;HTML, CSS 와 자바스크립트 기술은 빠르게 발전했습니다. &amp;nbsp;&lt;br /&gt;&lt;br /&gt;서버사이드 프레임워크가 따라잡기에 거의 불가능할 정도였죠.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;웹 아키텍쳐는 실시간 처리를 하는 방향으로 빠르게 바뀌고 있습니다.&lt;br /&gt;또한 요즘에는 프로젝트에 대한 요구사항이 많아져서, 데이터 저장기술로 SQL만 쓴다는 것은 옛날 얘기가 되었습니다.&lt;br /&gt;&lt;br /&gt;프로그래밍 언어부문에서도 실로 놀라운 변화가 있었습니다. Scala 를 포함한 몇몇 JVM 언어가 인기를 얻고 있죠.&lt;br /&gt;&lt;br /&gt;이처럼 새로운 시대가 왔기 때문에, 이에 걸맞는 새로운 웹 프레임워크인 플레이 2.0을 만들었습니다.&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;비동기방식의 프로그래밍을 위해 만들었어요!&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;오늘날 웹 어플리케이션에서는 병렬 실시간 데이터를 더욱더 많이 다룹니다.&lt;br /&gt;그래서 웹 프레임워크에서는 비동기 HTTP 프로그래밍 모델을 전폭 지원해주어야 합니다.&lt;br /&gt;&lt;br /&gt;&amp;lsquo;플레이&amp;rsquo;는 원래 고전적인 웹 어플리케이션을 다루도록 설계되었어요. 고전적인 웹 어플리케이션에서는 HTTP 요청이 대부분 잠깐 동안만 유지되었었죠.&lt;br /&gt;&lt;br /&gt;하지만 요즘에 이벤트 모델은 지속적인 연결을 사용하는 방식을 씁니다. Comet과 롱 폴링, 웹 소켓 등에서요.&lt;br /&gt;&lt;br /&gt;플레이 2.0은 모든 요청이 오랫동안 지속된다는 가정 하에 처음부터 다시 개발되었습니다.&lt;br /&gt;&lt;br /&gt;그러나 그것이 전부가 아니었습니다. 우리는 오랫동안 실행되는 작업을 스케쥴하고 실행하기 위한 강력한 방법이 필요했습니다.&lt;br /&gt;&lt;br /&gt;액터(Actor)에 기반한 모델은 고도의 병렬 시스템을 다루는데 있어서 오늘날 의심할 여지없는 최고의 모델입니다.&lt;br /&gt;&lt;br /&gt;플레이 2.0은 플레이로 만든 어플리케이션을 위해서 네이티브하게 Akka를 지원합니다. 이러한 Akka의 지원은&amp;nbsp; 고도의 분산화된 시스템을 만들수 있게 해줍니다.&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;플레이 프레임워크는 타입 안전성을 중요하게 여깁니다.&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;(역자주 : 타입 안정성 - 타입의 오류를 막거나 방지하는 정도 &lt;a href=&quot;http://en.wikipedia.org/wiki/Type_safety)&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://en.wikipedia.org/wiki/Type_safety)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;플레이 어플리케이션을 작성할 때 정적 프로그래밍 언어를 사용하면 한 가지 장점이 있는데요, 컴파일러가 코드의 자료형을 검사할 수 있다는 것입니다. (역자주: 정적 프로그래밍 언어: 컴파일 단계에서 자료형에 대한 검사를 수행하는 언어)&lt;br /&gt;&lt;br /&gt;정적 프로그래밍 언어를 사용하면, 개발 진행 초기에 실수를 발견할 수 있어서 좋습니다. 뿐만 아니라 개발자들이 많이 참여하는 대형 프로젝트를 수행하기가 훨씬 수월합니다.&lt;br /&gt;&lt;br /&gt;플레이 2.0에서 Scala를 추가적으로 지원하면서 컴파일러가 자료형을 더 확실하게 검사해준다는 장점이 분명 있습니다. 하지만 이것만으로는 충분하지 않죠.&lt;br /&gt;&lt;br /&gt;플레이 1.x에서 템플릿 시스템은 동적이었습니다. 그리고 그루비 언어 기반이었기 때문에 컴파일러가 해줄 수 있는 게 별로 없었어요. (역자주 : Groovy Language : &lt;a href=&quot;http://groovy.codehaus.org)&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://groovy.codehaus.org)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;결과적으로 템플릿에서의 오류는 런타임시에만 발견될 뿐입니다.&lt;br /&gt;&lt;br /&gt;마찬가지로 glue code with controllers의 오류도 런타임시에야 발견됩니다. (역자주: * Glue Code : &lt;a href=&quot;http://en.wikipedia.org/wiki/Glue_code)&quot;&gt;http://en.wikipedia.org/wiki/Glue_code)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;우리는 버전 2.0에서는 플레이가 대부분의 코드를 컴파일 타임에 검사할 수 있도록 하는 아이디어를 꼭 적용하고 싶었습니다.&lt;br /&gt;&lt;br /&gt;그래서 플레이 어플리케이션을 위해서 Scala에 기반한 템플릿 엔진을 기본으로 사용하기로 했습니다. 심지어 자바를 주 언어로 사용하는 개발자들에게까지 말이죠.&lt;br /&gt;&lt;br /&gt;그렇다고 해서 플레이 2.0에서 템플릿을 작성하려면 Scala 전문가가 되어야 하는 것은 아닙니다. 마치, 플레이 1.x에서 템플릿을 작성하기 위해 Groovy를 잘 알 필요는 없었던 것처럼 말이죠.&lt;br /&gt;&lt;br /&gt;템플릿에서는, 여러분의 오브젝트 그래프(object graph)를 탐색하는데에 주로 스칼라가 쓰입니다. 자바의 문법과 매우 비슷하게 관련된 정보를 보여주죠.&lt;br /&gt;&lt;br /&gt;하지만, advanced templates abstraction을 쓰는 데에, 스칼라의 강력함을 제대로 사용하려면, 스칼라가 템플릿 엔진에 얼마나 완벽한지 얼른 이해하시는 게 좋을 거에요. Scala is expression-oriented and functional.&lt;br /&gt;&lt;br /&gt;템플릿 엔진의 경우에만 그런게 아닙니다.&lt;br /&gt;routing system도 자료형을 모두 체크해주는 방식으로 돌아갑니다.&lt;br /&gt;&lt;br /&gt;플레이 2.0에서는 경로 기술한 것을 확인해서, 모든 것이 일관적인지, reverse routing part까지도 일관적인지를 검증합니다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;이처럼 플레이 2.0에서 완전하게 컴파일 해주기 때문에 생겨나는 부수적인 이점이 있는데요, 템플릿과 경로 파일(route files)을 더욱 쉽게 패키지하고 재사용할 수 있다는 점입니다.&lt;br /&gt;&lt;br /&gt;이런 부분 때문에 실행(run-time)할 때의 성능도 훨씬 더 좋아집니다.&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;자바와 스칼라를 네이티브 방식으로 지원(native support)합니다.&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;플레이 프레임워크 프로젝트 초기에 이미, 플레이 어플리케이션을 작성하는 언어로 스칼라를 사용하는 것에 대해서 고려하였습니다.&lt;br /&gt;&lt;br /&gt;처음에는 스칼라를 외부 모듈로 사용했습니다. 이렇게 하면 프레임워크 전체에 영향을 주지 않으면서도 자유롭게 실험해볼 수 있었죠.&lt;br /&gt;&lt;br /&gt;스칼라를 자바기반 프레임워크에 제대로 통합하는 것은 쉬운 일이 아닙니다.&lt;br /&gt;&lt;br /&gt;스칼라가 자바와 호환성이 좋으니까, 자바 문법대신 스칼라의 문법을 사용해서 시험삼아 시도를 해볼 순 있겠죠.&lt;br /&gt;&lt;br /&gt;하지만, 이것은 언어를 사용하는 최적의 방법은 분명 아닙니다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;스칼라는 진정한 객체기반언어와 함수적 언어의그래밍의 특징을 모두 가지고 있습니다.&lt;br /&gt;&lt;br /&gt;스칼라의 힘을 극대화하려면 프레임워크 API를 거의 모두 다시 생각해봐야합니다.&lt;br /&gt;&lt;br /&gt;얼마 지나지 않아서 별도의 모듈로 제공되는 Scala 지원을 갖고 할 수 있는 것에는 한계가 있다는 것을 알게 되었습니다.&lt;br /&gt;&lt;br /&gt;Play 1.x 버전 때에는 자바 리플렉션 API와 바이트코드 조작(byte code manipulation)에 심하게 의존했습니다. 이때 설계한 방식 때문에, Play 내부의 핵심적인 부분들을 뒤집어어 엎어야만 진행할 수 있었습니다.&lt;br /&gt;&lt;br /&gt;(역자주: Java Reflection API는 임의의 자바 클래스를 읽어 들이고 조사하고 실행시킬 수 있는 방법을 제공하는 API. 어떤 클래스를 이용할 지 개발 시점에는 알 필요가 없으므로, 임의의 코드를 실행해야 하는 프레임워크나 개발 및 테스트 도구를 개발할 때 유용하나, 성능이 떨어지고 보안상 문제를 초래할 수 있음&lt;br /&gt;&lt;br /&gt;(역자주 : 바이트코드조작은 바이트코드로 컴파일된 자바 클래스를 실행시간에 직접 조작하는 것)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;한편, 우리는 스칼라 모듈 용으로 멋진 컴포넌트를 몇 개 만들었습니다. 이를테면, 자료형을 자동으로 검사해주는 템플릿 엔진(type-safe template engine)을 새로 만들었고요, SQL 엑세스 콤포넌트인 Anorm을 완전히 새로이 만들었어요.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;그래서 우리는 이렇게 판단했습니다. 플레이 프레임워크 내에서 스칼라의 강력함을 제대로 활용하기 위해서는, 별도의 모듈로 스칼라를 지원하는게 아니라, 플레이 2.0의 핵심으로서 지원해야 한다고요. 그래서 플레이 2.0을 설계할 때, 프로그래밍 언어로서 스칼라를 네이티브 방식으로 지원하도록 설계하였습니다. (역자주 : 네이티브 방식 지원 : 인터프리터나 컨버터를 사용하지 않고 스칼라 언어를 그대로 사용할 수 있도록 지원하는 것)&lt;br /&gt;&lt;br /&gt;한편, 플레이 2.0에서 자바를 덜 지원한다는 의미는 절대 아닙니다. 오히려 그 반대죠.&lt;br /&gt;&lt;br /&gt;자바 개발자가 플레이 2.0의 빌드를 사용하면, 개발을 할 때 새로운 경험을 하실 수 있습니다.&lt;br /&gt;&lt;br /&gt;자바의 장점들을 모두 고려한 진정한 자바 API를 사용할 수 있습니다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;강력한 빌드 시스템을 제공합니다!&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;플레이 프로젝트를 시작하면서, 플레이 애플리케이션 실행 및 컴파일 그리고 배포를 하기 위한 새로운 방식을 선택하였습니다.&lt;br /&gt;&lt;br /&gt;이러한 방식은 처음에는 난해하게 보일 수도 있습니다.&lt;br /&gt;히지만 표준 서블릿 API가 아닌 비동기 HTTP API를 제공하는데 있어서 이러한 방식이 꼭 필요했습니다. 또한 실시간 컴파일을 통해 피드백 주기를 짧게 하기 위해서도 필요했습니다. 그리고 개발하는 동안 소스 코드를 새로 불러오는 것을 제공하기 위해서도 필요했습니다. 마지막으로 새로운 패키징 방식을 추진하기 위해서도 필요한 선택이었습니다.&lt;br /&gt;&lt;br /&gt;그 결과, 표준 JEE 규약을 따르도록 플레이를 만들기가 어려웠습니다.&lt;br /&gt;&lt;br /&gt;오늘날에는 컨테이너 없이 배포한다는 아이디어가 자바 세상에서 점점 더 받아 들여지고 있습니다.&lt;br /&gt;&lt;br /&gt;이렇게 설계한 덕분에 플레이 프레임워크는 Heroku 같은 플랫폼에서 네이티브한 방식으로 돌아갈 수 있었습니다. Heroku는 신축적인 PaaS 플램폿에 자바 어플리케이션을 배포하는 것의 미래를 감안한 모델을 도입하였고요.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;그러나 기존의 자바 빌드 시스템은 유연하지 않아서, 이런 새로운 접근 방법을 지원하지 못했습니다.&lt;br /&gt;&lt;br /&gt;플레이 어플리케이션을 쉽게 실행하고 배포할 수 있도록, 플레이 1.x에서는 파이썬 스크립트 모음(collection)을 제작해서 빌드와 배포작업을 하도록 했습니다. &amp;nbsp;&lt;br /&gt;&lt;br /&gt;한편, 기업의 프로젝트처럼 큰 규모의 프로젝트를 진행할 때 플레이를 사용하는 개발자들은 좀 난처해졌죠. 왜냐하면 기업용 프로젝트에서는 빌드 프로세스를 조정할 수 있어야 하고(build process customization), 회사에서 기존에 쓰는 빌드 시스템하고 통합도 할 수 있어야 하거든요.&lt;br /&gt;&lt;br /&gt;플레이 1.x에서 제공하는 파이썬 스크립트는 모든 기능이 다 갖춰진&amp;nbsp; 빌드 시스템(fully-featured build system)하고는 거리가 멉니다. 그리고 조정(customize)하기에도 쉽지 않고요.&lt;br /&gt;&lt;br /&gt;그래서 플레이 2.0에서는 좀 더 강력한 빌드 시스템을 제공하기로 했습니다..&lt;br /&gt;&lt;br /&gt;우리에게는 현대적인 빌드 도구가 필요했습니다. 현대적인 빌드 도구는 플레이의 원래방식을 지원해줄 수 있도록 유연해야 하고, 자바와 스칼라 프로젝트를 빌드할 수도 있어야 했습니다. 그래서 우리는 플레이 2.0에 sbt를 통합시키기로 결정하였습니다.&lt;br /&gt;&lt;br /&gt;하지만 플레이 빌드가 간편하다는 이유로 만족하시는 기존의 플레이 유저 분들은, 이 결정 때문에 겁내시지 않아도 됩니다. &amp;nbsp;&lt;br /&gt;&lt;br /&gt;우리는 이전과 같은 단순한 플레이 생성, 실행, 시작 경험을 확장된 모델의 위에 영향을 받도록 하였습니다다. 플레이 2.0에는 미리 설정된 빌드 스크립트가 포함되어 있는데요, 대부분의 사용자들에게는 아주 매끄럽게 작동합니다.&lt;br /&gt;&lt;br /&gt;반면에&amp;nbsp; 어플리케이션을 빌드하고 배포하는 방법을 바꿔야 하는 경우에는, 플레이 프로젝트가 sbt 프로젝트라는 사실이 유용할 것입니다. 빌드하고 배포하는 방법을 커스터마이징할 수 있기 때문입니다.&lt;br /&gt;&lt;br /&gt;이러한 사실은 메이븐 프로젝트와 특별히 더 나은 통합을 할 수 있다는 것을 뜻합니다. 어떠한 저장소에도 간단히 JAR 파일들을 패키징하고 배포할 수 있는 능력과 배포 시점에 의존적인 프로젝트를 컴파일하고 다시 로딩할 수 있는 능력에 있어서 말입니다.&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;데이터저장과 모델 통합&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;lsquo;데이터 저장&amp;rsquo;이라고 하면 예전에는 &amp;lsquo;SQL 데이터베이스&amp;rsquo;를 떠올리는 게 당연했는데요, 최근에는 새롭고 흥미로운 데이터 저장 모델이 인기를 얻고 있습니다. 이들은 여러 가지 가능한 상황에 적절한 다양한 속성을 각기 제공합니다.&lt;br /&gt;&lt;br /&gt;그래서 플레이 같은 웹프레임워크로서는 개발자들이 어떤 종류의 데이터 저장방식(데이터베이스)을 사용하는지 가정하기가 어려워 졌습니다.&lt;br /&gt;&lt;br /&gt;플레이 프레임워크의 일반적인 모델 개념(generic model concept)은 더 이상 유효하지 않습니다. 왜냐하면 단 하나의 API만으로 이 모든 종류의 (data store) 기술을 모두 다루기란 불가능하기 때문입니다.&lt;br /&gt;&lt;br /&gt;플레이 2.0에서는 데이터 저장 드라이버나, ORM, 또는 다른 데이터 베이스 접근 라이브러리를 아주 사용하기 쉽게 만들고 싶었습니다. 플레이 2.0하고 특별히 통합시키지 않고서도 쉽게 사용할 수 있게 만들고 싶었습니다.&lt;br /&gt;&lt;br /&gt;connection bounds를 관리하는 것 같은 흔한 기술적 이슈를 다루는 최소한의 헬퍼를 제공하고 싶습니다. (역자주 : 헬퍼 - 도와주는 역할을 하는 클래스, 모듈, 코드 등. 예를 들어 사용하기 어려운 클래스의 경우, 한꺼풀 더 씌워서 사용하기 편하게 만든 클래스)&lt;br /&gt;&lt;br /&gt;또한, 플레이 2.0을&amp;nbsp; 풀 스택 방식으로 유지하기 위해 고전적 데이터베이스에 접근할 수 있는 기본적인 도구들을 제공하기로 했습니다. 그래서 플레이 2.0에 Ebean, JPA, Anorm 같은 관계형 데이터베이스를 엑세스할 수 있는 라이브러리가 포함되어 있습니다. 데이터베이스에 관해 특별한 요구사항이 있는 경우가 아니라면 기본 라이브러리를 사용하면 됩니다.&lt;br /&gt;&lt;br /&gt;(역자주 : full-stack: 프레임워크 내에 기본적으로 필요한 기반 라이브러리가 다 포함된 형태로 배포가 되면 full-stack이라고 부릅니다.)&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;출처 : &lt;a href=&quot;https://opentutorials.org/module/123/1606&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://opentutorials.org/module/123/1606&lt;/a&gt;&lt;/p&gt;</description>
      <category>Java ETC Framework/Play Framework</category>
      <category>Play framework</category>
      <category>플레이 프레임워크</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2298</guid>
      <comments>https://xzio.tistory.com/2298#entry2298comment</comments>
      <pubDate>Tue, 10 Oct 2023 17:06:17 +0900</pubDate>
    </item>
    <item>
      <title>[IntelliJ] 테스트 코드 단축키 설정</title>
      <link>https://xzio.tistory.com/2297</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;IntelliJ 테스트 코드 작성 시, 주로 given / when / then 패턴을 사용 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;매번 반복 작업하기 번거로우니, 단축키를 만들어보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;LiveTemplate 활용&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. MacOS에서는 preferences, Windows에서는 Settings&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;250&quot; data-origin-height=&quot;250&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/np6Pm/btswpY5tu44/mabBm12whcwTrF5qgFLzL1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/np6Pm/btswpY5tu44/mabBm12whcwTrF5qgFLzL1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/np6Pm/btswpY5tu44/mabBm12whcwTrF5qgFLzL1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fnp6Pm%2FbtswpY5tu44%2FmabBm12whcwTrF5qgFLzL1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;250&quot; height=&quot;250&quot; data-origin-width=&quot;250&quot; data-origin-height=&quot;250&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot;&gt;2. Editor -&amp;gt; Live Templates을 클릭한 후, Java를 선택한 다음 + 버튼을 누르면 Live Template&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;755&quot; data-origin-height=&quot;654&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/q5xXT/btsw8kL8xkp/kkyyrhYnbGgAWFk8kNV8K1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/q5xXT/btsw8kL8xkp/kkyyrhYnbGgAWFk8kNV8K1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/q5xXT/btsw8kL8xkp/kkyyrhYnbGgAWFk8kNV8K1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fq5xXT%2Fbtsw8kL8xkp%2FkkyyrhYnbGgAWFk8kNV8K1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;755&quot; height=&quot;654&quot; data-origin-width=&quot;755&quot; data-origin-height=&quot;654&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. &lt;span style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot;&gt;Abbreviation에 tdd라고 입력&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1386&quot; data-origin-height=&quot;844&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bl1K5M/btswPXkmsZp/u6aJmzEpiAnaDY7KmysyWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bl1K5M/btswPXkmsZp/u6aJmzEpiAnaDY7KmysyWk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bl1K5M/btswPXkmsZp/u6aJmzEpiAnaDY7KmysyWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbl1K5M%2FbtswPXkmsZp%2Fu6aJmzEpiAnaDY7KmysyWk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1386&quot; height=&quot;844&quot; data-origin-width=&quot;1386&quot; data-origin-height=&quot;844&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. Template text에 given / when / then 템플릿 입력&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$END$&amp;nbsp;의 의미는 해당 위치에 커서 이동&lt;/p&gt;
&lt;pre id=&quot;code_1696475670397&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Test
@DisplayName(&quot;&quot;)
void $END$() {
    //given
    
    //when
    
    //then
    
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. Define 버튼을 누르고, Java 선택&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;383&quot; data-origin-height=&quot;521&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DYKiy/btswcObir6a/nuZg2FkOrD3ZDRqm4rb0m1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DYKiy/btswcObir6a/nuZg2FkOrD3ZDRqm4rb0m1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DYKiy/btswcObir6a/nuZg2FkOrD3ZDRqm4rb0m1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDYKiy%2FbtswcObir6a%2FnuZg2FkOrD3ZDRqm4rb0m1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;383&quot; height=&quot;521&quot; data-origin-width=&quot;383&quot; data-origin-height=&quot;521&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. tdd라고 입력하면, 템플릿을 사용하여 테스트 코드 작성&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;537&quot; data-origin-height=&quot;69&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1fLgV/btswpWfvLLJ/42217LsQZpPgPdoBuinq7K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1fLgV/btswpWfvLLJ/42217LsQZpPgPdoBuinq7K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1fLgV/btswpWfvLLJ/42217LsQZpPgPdoBuinq7K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1fLgV%2FbtswpWfvLLJ%2F42217LsQZpPgPdoBuinq7K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;537&quot; height=&quot;69&quot; data-origin-width=&quot;537&quot; data-origin-height=&quot;69&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;7. test 템플릿도 동일하게 작성&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;967&quot; data-origin-height=&quot;492&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2167K/btswJBaMJY1/EeEdAK4aaBp9IlMpaxYGf1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2167K/btswJBaMJY1/EeEdAK4aaBp9IlMpaxYGf1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2167K/btswJBaMJY1/EeEdAK4aaBp9IlMpaxYGf1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2167K%2FbtswJBaMJY1%2FEeEdAK4aaBp9IlMpaxYGf1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;967&quot; height=&quot;492&quot; data-origin-width=&quot;967&quot; data-origin-height=&quot;492&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. test 입력 및 확인&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;575&quot; data-origin-height=&quot;143&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dcXhyF/btsw686d1Nr/pzDgdO0plIcIh9PrZiBk0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dcXhyF/btsw686d1Nr/pzDgdO0plIcIh9PrZiBk0k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dcXhyF/btsw686d1Nr/pzDgdO0plIcIh9PrZiBk0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdcXhyF%2Fbtsw686d1Nr%2FpzDgdO0plIcIh9PrZiBk0k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;575&quot; height=&quot;143&quot; data-origin-width=&quot;575&quot; data-origin-height=&quot;143&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;181&quot; data-origin-height=&quot;232&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cAENo5/btswgVOO9Mn/ZfXL6gQkDlI3sAEOKCrMLk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cAENo5/btswgVOO9Mn/ZfXL6gQkDlI3sAEOKCrMLk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cAENo5/btswgVOO9Mn/ZfXL6gQkDlI3sAEOKCrMLk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcAENo5%2FbtswgVOO9Mn%2FZfXL6gQkDlI3sAEOKCrMLk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;181&quot; height=&quot;232&quot; data-origin-width=&quot;181&quot; data-origin-height=&quot;232&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>IDE Tool/IntelliJ IDEA</category>
      <category>@Test</category>
      <category>IntelliJ</category>
      <category>JUnit</category>
      <category>live templates</category>
      <category>TDD</category>
      <category>단축키</category>
      <category>약어</category>
      <author>Wings of Freedom</author>
      <guid isPermaLink="true">https://xzio.tistory.com/2297</guid>
      <comments>https://xzio.tistory.com/2297#entry2297comment</comments>
      <pubDate>Thu, 5 Oct 2023 12:25:47 +0900</pubDate>
    </item>
  </channel>
</rss>